diff --git a/main.js b/main.js index c6e4f44..c8c7351 100644 --- a/main.js +++ b/main.js @@ -1,100 +1,103 @@ -"use strict";var Vn=Object.create;var ti=Object.defineProperty;var Wn=Object.getOwnPropertyDescriptor;var Xn=Object.getOwnPropertyNames;var Zn=Object.getPrototypeOf,_n=Object.prototype.hasOwnProperty;var le=(h,A)=>()=>(h&&(A=h(h=0)),A);var $n=(h,A)=>()=>(A||h((A={exports:{}}).exports,A),A.exports),ei=(h,A)=>{for(var t in A)ti(h,t,{get:A[t],enumerable:!0})},Ns=(h,A,t,e)=>{if(A&&typeof A=="object"||typeof A=="function")for(let i of Xn(A))!_n.call(h,i)&&i!==t&&ti(h,i,{get:()=>A[i],enumerable:!(e=Wn(A,i))||e.enumerable});return h};var jn=(h,A,t)=>(t=h!=null?Vn(Zn(h)):{},Ns(A||!h||!h.__esModule?ti(t,"default",{value:h,enumerable:!0}):t,h)),to=h=>Ns(ti({},"__esModule",{value:!0}),h);function Wi(h){return Array.isArray(h)?h.filter(A=>typeof A=="string"):typeof h=="string"?h.split(/[,\s]+/).filter(Boolean):[]}function ee(h,A){let t=A.replace(/^#/,"");return Wi(h?.tags).some(e=>e.replace(/^#/,"")===t)}function Xi(h,A){let t=A.replace(/^#/,""),e=Wi(h.tags);e.some(i=>i.replace(/^#/,"")===t)||e.push(t),h.tags=e}function Zi(h,A){let t=A.replace(/^#/,""),e=Wi(h.tags).filter(i=>i.replace(/^#/,"")!==t);e.length?h.tags=e:delete h.tags}function de(h){return h.split("/").some(A=>Ne.has(A))}function xs(h){return h.split("/").some(A=>A==="_archive"||A===".archive")}function ie(h){let A=(h??"").trim();return!A||/^\[\[.*\]\]$/.test(A)?A:`[[${A}]]`}function he(h){let A=(h??"").trim(),t=A.match(/^\[\[(.*)\]\]$/);return t&&(A=t[1]),A.split("|")[0].split("#")[0].split("^")[0].trim()}function Ms(h){let A=h.match(/\.([^./]+)$/);return!!A&&eo.has(A[1].toLowerCase())}function Hs(h,A){if(!Array.isArray(A))return!1;for(let t of A){let e=(t??"").trim();if(e){if(e.length>2&&e.startsWith("/")&&e.endsWith("/"))try{if(new RegExp(e.slice(1,-1)).test(h))return!0}catch{}else if(h===e||h.startsWith(e.endsWith("/")?e:e+"/"))return!0}}return!1}function Us(h,A){let t=h.toLowerCase().split(/\s+/).filter(Boolean);if(t.length===0)return!0;let e=A.toLowerCase();return t.every(i=>e.includes(i))}function xe(h){if(typeof h!="string")return null;let A=h.replace(/^\[\[/,"").replace(/\]\]$/,""),[t,e]=A.split("|"),i=t.match(/_authors\/(.+?)-([a-z0-9]{4,12})(?:\.md)?$/i);if(!i)return null;let s=i[2],n=(e??"").trim()||i[1].replace(/-/g," ").trim();return{id:s,name:n}}function Me(h){let A=h?.assignedTo,t=Array.isArray(A)?A:A!=null?[A]:[],e=[];for(let i of t){let s=xe(i);s&&e.push(s)}return e}var ut,Yt,te,G,zt,Ne,eo,yt=le(()=>{"use strict";ut="stashpad-view",Yt="stashpad-panels",te="stashpad-detail",G="__root__";zt=["id","parent","created","modified","attachments","position","author","contributors","parentLink","children","due","assignedTo","assignedBy"],Ne=new Set(["_attachments","_authors","_exports","_imports","_processed","_archive",".archive"]);eo=new Set(["edtz"])});function io(h,A){return h>12?h>=24?0:h:A==="am"?h===12?0:h:h===12?12:h+12}function si(h,A){h.addClass("stashpad-when-pop-time");let t=A.seedPeriod,e=h.createDiv({cls:"stashpad-when-time-display"}),i=e.createEl("input",{cls:"stashpad-when-time-field",attr:{type:"text",inputmode:"numeric",maxlength:"2"}});i.value=String(A.seedH),e.createSpan({cls:"stashpad-when-time-colon",text:":"});let s=e.createEl("input",{cls:"stashpad-when-time-field",attr:{type:"text",inputmode:"numeric",maxlength:"2"}});s.value=String(A.seedM).padStart(2,"0");let n=e.createDiv({cls:"stashpad-when-time-period"}),o=n.createEl("button",{cls:"stashpad-when-time-ampm",text:"AM"});o.type="button";let a=n.createEl("button",{cls:"stashpad-when-time-ampm",text:"PM"});a.type="button";let r=()=>{o.toggleClass("is-active",t==="am"),a.toggleClass("is-active",t==="pm")};r(),o.addEventListener("mousedown",E=>E.preventDefault()),a.addEventListener("mousedown",E=>E.preventDefault()),o.addEventListener("click",E=>{E.preventDefault(),t="am",r()}),a.addEventListener("click",E=>{E.preventDefault(),t="pm",r()});let c=i;i.addEventListener("focus",()=>{c=i,i.select()}),s.addEventListener("focus",()=>{c=s,s.select()});let l=()=>{let y=(parseInt(i.value||"0",10)||0)>12;o.toggleClass("is-disabled",y),a.toggleClass("is-disabled",y),o.disabled=y,a.disabled=y},d=E=>{let y=E.value.replace(/\D/g,"").slice(0,2);if(y===""){E.value="",E===i&&l();return}let v=parseInt(y,10);E===i?v>24&&(v=24):v>59&&(v=59),E.value=String(v),E===i&&l()};for(let E of[i,s])E.addEventListener("input",()=>d(E));l();let I=()=>{let E=parseInt(i.value||"12",10)||12,y=parseInt(s.value||"0",10)||0,v=E>12;A.onFinalize({hours24:io(E,t),minutes:y,raw:{hh:E,mm:y,period:t,is24:v}}),A.close()};A.setOnEnter?.(I);let g=[i,s,o,a],p=(E,y)=>{let v=g.indexOf(E);if(v===-1)return;let k=(v+y+g.length)%g.length;g[k].focus()},u=E=>{E.addEventListener("keydown",y=>{y.key==="Enter"?(y.preventDefault(),y.stopPropagation(),I()):y.key==="Escape"?(y.preventDefault(),y.stopPropagation(),A.close()):y.key==="Tab"&&(y.preventDefault(),y.stopPropagation(),p(E,y.shiftKey?-1:1))})},f=h.createDiv({cls:"stashpad-when-time-pad"}),B=["1","2","3","4","5","6","7","8","9","backspace","0","insert"],Q=null;for(let E of B){let y=f.createEl("button",{cls:"stashpad-when-time-padbtn"});y.type="button",E==="backspace"?(0,Ps.setIcon)(y,"delete"):E==="insert"?(y.setText("OK"),Q=y):y.setText(E),E==="insert"&&y.addClass("is-go"),y.addEventListener("mousedown",v=>v.preventDefault()),y.addEventListener("click",v=>{if(v.preventDefault(),E==="insert"){I();return}if(E==="backspace"){c.value=c.value.slice(0,-1),d(c),c.focus();return}let k=c.selectionStart===0&&c.selectionEnd===c.value.length&&c.value.length>0,b=2,R=k||c.value.length>=b?E:c.value+E;c.value=R,d(c),c.focus(),c.setSelectionRange(c.value.length,c.value.length),c===i&&c.value.length>=b&&(s.focus(),s.select())})}Q&&g.push(Q);for(let E of g)u(E);i.focus(),i.select()}function Ls(h){let{hh:A,mm:t,period:e,is24:i}=h.raw;return i?`${A}:${String(t).padStart(2,"0")}`:`${A}:${String(t).padStart(2,"0")}${e}`}var Ps,_i=le(()=>{"use strict";Ps=require("obsidian")});var ni={};ei(ni,{newId:()=>mt});function mt(h=6){let A="",t=new Uint8Array(h);crypto.getRandomValues(t);for(let e=0;e{"use strict";Js="abcdefghijkmnpqrstuvwxyz23456789"});var qe={};ei(qe,{AssignModal:()=>Re,ColorPickerModal:()=>ae,ConfirmDeleteModal:()=>Ie,ConfirmModal:()=>Dt,CustomColorModal:()=>oi,DueDatePickerModal:()=>Pe,ExportStashModal:()=>Te,ImportDupChoiceModal:()=>Je,ImportLogModal:()=>$i,LogModal:()=>ge,NotificationHistoryModal:()=>Le,SplitNoteModal:()=>Ue,StashPasswordModal:()=>Ge,buildAssigneePicker:()=>ji});function ji(h,A){let t=[...A.initial],e=A.knownAuthors,i=h.createDiv({cls:"stashpad-assign"});i.createDiv({cls:"stashpad-assign-label",text:"Assign to"});let s=i.createDiv({cls:"stashpad-assign-chips"}),n=i.createDiv({cls:"stashpad-assign-input-wrap"}),o=n.createEl("input",{type:"text",cls:"stashpad-assign-input",attr:{placeholder:"Add a person \u2014 type a name\u2026"}}),a=n.createDiv({cls:"stashpad-assign-suggest"});a.style.display="none";let r=()=>A.onChange([...t]),c=()=>{s.empty(),t.length===0&&s.createSpan({cls:"stashpad-assign-empty",text:"No one yet"});for(let I of t){let g=s.createSpan({cls:"stashpad-assign-chip"});g.createSpan({cls:"stashpad-assign-chip-name",text:I.name});let p=g.createSpan({cls:"stashpad-assign-chip-x",text:"\xD7"});p.title=`Remove ${I.name}`,p.onclick=()=>{t=t.filter(u=>u.id!==I.id),r(),c()}}},l=I=>{I.name.trim()&&(t.some(g=>g.id===I.id)||t.push(I),o.value="",a.style.display="none",r(),c(),o.focus())},d=()=>{let I=o.value.trim();a.empty();let g=new Set(t.map(f=>f.id)),u=e.filter(f=>!g.has(f.id)&&Us(I,f.name)).slice(0,6).map(f=>({label:f.name,onPick:()=>l(f)}));if(I&&!e.some(f=>f.name.toLowerCase()===I.toLowerCase())&&u.push({label:`Create \u201C${I}\u201D`,onPick:()=>l({id:mt(6),name:I})}),u.length===0){a.style.display="none";return}a.style.display="";for(let f of u){let B=a.createDiv({cls:"stashpad-assign-suggest-item",text:f.label});B.onmousedown=Q=>{Q.preventDefault(),f.onPick()}}};o.addEventListener("input",d),o.addEventListener("focus",d),o.addEventListener("keydown",I=>{if(I.key==="Enter"){I.preventDefault();let g=a.querySelector(".stashpad-assign-suggest-item");g&&g.dispatchEvent(new MouseEvent("mousedown"))}else I.key==="Escape"&&a.style.display!=="none"&&(I.stopPropagation(),a.style.display="none")}),o.addEventListener("blur",()=>{window.setTimeout(()=>{a.style.display="none"},120)}),c()}var lt,ne,ge,Ie,Ue,Te,Ge,oi,He,ae,Dt,Re,Pe,oe,Le,$i,Je,Mt=le(()=>{"use strict";lt=require("obsidian");_i();yt();Tt();ne=class ne extends lt.Modal{constructor(t,e,i){super(t);this.text=e;this.jsonlPath=i;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 r of this.text.trim().split(/\r?\n/))if(r)try{this.events.push(JSON.parse(r))}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 i=t.createEl("button",{text:"Open in default app"});i.onclick=()=>this.shellAct("open");let s=t.createEl("button",{text:"Copy raw JSONL"}),n=null;s.onclick=async()=>{await navigator.clipboard.writeText(this.text),s.setText("Copied"),n!=null&&window.clearTimeout(n),n=window.setTimeout(()=>{s.setText("Copy raw JSONL"),n=null},1500)};let o=t.createEl("button",{text:"Export copy"});o.onclick=()=>this.exportCopy();let a=t.createEl("button",{cls:"mod-warning",text:"Clear log"});a.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(ne.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 i=[...e.entries()].sort((n,o)=>o[1]-n[1]||n[0].localeCompare(o[0])),s=t.createEl("option",{text:`All types (${this.events.length})`});s.value="";for(let[n,o]of i){let a=t.createEl("option",{text:`${n} (${o})`});a.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 i=this.shownCount;i{this.appendMore(ne.PAGE),this.renderFooter()},t>ne.PAGE){let i=this.footerEl.createEl("button",{text:`Load all (${t})`});i.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:i}=window.require("electron");t==="reveal"?i.showItemInFolder(e):i.openPath(e)}catch(e){new lt.Notice(`Couldn't ${t}: ${e.message}`)}}async exportCopy(){try{let t=(0,lt.moment)().format("YYYY-MM-DD_HHmmss"),e=this.jsonlPath.replace(/\/[^/]+$/,"")||"",i=e?`${e}/${t}-log.jsonl`:`${t}-log.jsonl`;return await this.app.vault.adapter.write(i,this.text),new lt.Notice(`Exported log \u2192 ${i}`),i}catch(t){return new lt.Notice(`Export failed: ${t.message}`),null}}clearLog(){new Dt(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(i){new lt.Notice(`Clear failed: ${i.message}`);return}this.text="",this.events=[],this.typeFilter=null,this.shownCount=0,this.refreshTypeFilter(),this.refreshList(),this.footerEl&&this.footerEl.empty(),new lt.Notice("Log cleared.")}}).open()}renderEvent(t){let e=document.createElement("div");e.className=`stashpad-log-row stashpad-log-${t.type}`;let i=(0,lt.moment)(t.ts).isValid()?(0,lt.moment)(t.ts).format("YYYY-MM-DD HH:mm:ss"):t.ts,s=document.createElement("span");s.className="stashpad-log-ts",s.textContent=i,e.appendChild(s);let n=document.createElement("span");n.className="stashpad-log-type",n.textContent=t.type,e.appendChild(n);let o=document.createElement("span");o.className="stashpad-log-author",o.textContent=t.author?t.author:"\u2014",t.author||o.classList.add("is-empty"),e.appendChild(o);let a=document.createElement("span");return a.className="stashpad-log-msg",a.textContent=this.describe(t),e.appendChild(a),e}describe(t){let e=t.payload??{};switch(t.type){case"create":return`Created "${e.path??t.id}" under ${e.parent??"?"}`;case"delete":{let i=Array.isArray(e.attachmentsRemoved)?e.attachmentsRemoved.length:0,s=e.mergedInto?` (merged into ${e.mergedInto})`:"";return`Deleted ${t.id}${s}${i?` \u2014 also removed ${i} attachment${i===1?"":"s"}`:""}`}case"missing":return`Missing: ${e.lastPath??t.id}`;case"parent_change":{let i=e.reason?` (${e.reason})`:"";return`Moved ${t.id} from ${e.from??"null"} \u2192 ${e.to??"null"}${i}`}case"rename":return`Renamed ${e.from??"?"} \u2192 ${e.to??"?"}`;case"reorder":{let i=e.count??1,s=e.dir??"?",n=e.parent??t.id??"?";return`Reordered ${i} note${i===1?"":"s"} (${s}) under ${n}`}case"complete":{let i=e.count??1,s=e.undo?" (undo)":e.redo?" (redo)":"";return`Marked ${i} note${i===1?"":"s"} complete${s}`}case"uncomplete":{let i=e.count??1,s=e.undo?" (undo)":e.redo?" (redo)":"";return`Unmarked ${i} note${i===1?"":"s"}${s}`}case"stash_export":{let i=e.noteCount??"?";return`Exported ${i} note${i===1?"":"s"} \u2192 ${e.path??"?"}`}case"stash_import":{let i=e.noteCount??"?",s=[];e.attachmentsWritten&&s.push(`${e.attachmentsWritten} attachment${e.attachmentsWritten===1?"":"s"}`),e.collisionsRenamed&&s.push(`${e.collisionsRenamed} renamed`);let n=s.length?` (${s.join(", ")})`:"";return`Imported ${i} note${i===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()}};ne.PAGE=100;ge=ne,Ie=class extends lt.Modal{constructor(t,e,i,s,n,o){super(t);this.noteTitle=e;this.descendantCount=i;this.attachmentCount=s;this.offerAttachmentDelete=n;this.onChoose=o}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 o=this.contentEl.createEl("label",{cls:"stashpad-modal-check"}),a=o.createEl("input",{type:"checkbox"});a.checked=e,a.onchange=()=>{e=a.checked},o.createSpan({text:" Also delete attachments"})}let i=this.contentEl.createDiv({cls:"stashpad-modal-btns"}),s=i.createEl("button",{text:"Cancel"});s.onclick=()=>this.close();let n=i.createEl("button",{cls:"mod-warning",text:"Delete"});n.onclick=()=>{this.close(),this.onChoose(e)}}onClose(){this.contentEl.empty()}},Ue=class extends lt.Modal{constructor(t,e,i,s){super(t);this.body=e;this.onSplitAtLine=i;this.onSplitAtChar=s;this.mode="line";this.cursorTextarea=null;this.lines=e.replace(/\r\n/g,` +"use strict";var lo=Object.create;var ai=Object.defineProperty;var ho=Object.getOwnPropertyDescriptor;var go=Object.getOwnPropertyNames;var po=Object.getPrototypeOf,Io=Object.prototype.hasOwnProperty;var se=(d,A)=>()=>(d&&(A=d(d=0)),A);var uo=(d,A)=>()=>(A||d((A={exports:{}}).exports,A),A.exports),ri=(d,A)=>{for(var t in A)ai(d,t,{get:A[t],enumerable:!0})},Ks=(d,A,t,e)=>{if(A&&typeof A=="object"||typeof A=="function")for(let i of go(A))!Io.call(d,i)&&i!==t&&ai(d,i,{get:()=>A[i],enumerable:!(e=ho(A,i))||e.enumerable});return d};var fo=(d,A,t)=>(t=d!=null?lo(po(d)):{},Ks(A||!d||!d.__esModule?ai(t,"default",{value:d,enumerable:!0}):t,d)),Co=d=>Ks(ai({},"__esModule",{value:!0}),d);function ss(d){return Array.isArray(d)?d.filter(A=>typeof A=="string"):typeof d=="string"?d.split(/[,\s]+/).filter(Boolean):[]}function pe(d,A){let t=A.replace(/^#/,"");return ss(d?.tags).some(e=>e.replace(/^#/,"")===t)}function ns(d,A){let t=A.replace(/^#/,""),e=ss(d.tags);e.some(i=>i.replace(/^#/,"")===t)||e.push(t),d.tags=e}function os(d,A){let t=A.replace(/^#/,""),e=ss(d.tags).filter(i=>i.replace(/^#/,"")!==t);e.length?d.tags=e:delete d.tags}function Ie(d){return d.split("/").some(A=>Te.has(A))}function Ys(d){return d.split("/").some(A=>A==="_archive"||A===".archive")}function Gt(d){let A=(d??"").trim();return!A||/^\[\[.*\]\]$/.test(A)?A:`[[${A}]]`}function oe(d){let A=(d??"").trim(),t=A.match(/^\[\[(.*)\]\]$/);return t&&(A=t[1]),A.split("|")[0].split("#")[0].split("^")[0].trim()}function zs(d){let A=d.match(/\.([^./]+)$/);return!!A&&Bo.has(A[1].toLowerCase())}function Vs(d,A){if(!Array.isArray(A))return!1;for(let t of A){let e=(t??"").trim();if(e){if(e.length>2&&e.startsWith("/")&&e.endsWith("/"))try{if(new RegExp(e.slice(1,-1)).test(d))return!0}catch{}else if(d===e||d.startsWith(e.endsWith("/")?e:e+"/"))return!0}}return!1}function Ai(d,A){let t=d.toLowerCase().split(/\s+/).filter(Boolean);if(t.length===0)return!0;let e=A.toLowerCase();return t.every(i=>e.includes(i))}function Xt(d){if(typeof d!="string")return null;let A=d.replace(/^\[\[/,"").replace(/\]\]$/,""),[t,e]=A.split("|"),i=t.match(/_authors\/(.+?)-([a-z0-9]{4,12})(?:\.md)?$/i);if(!i)return null;let s=i[2],n=(e??"").trim()||i[1].replace(/-/g," ").trim();return{id:s,name:n}}function Ue(d){let A=d?.assignedTo,t=Array.isArray(A)?A:A!=null?[A]:[],e=[];for(let i of t){let s=Xt(i);s&&e.push(s)}return e}var gt,Vt,ge,ne,G,Wt,Te,Bo,wt=se(()=>{"use strict";gt="stashpad-view",Vt="stashpad-panels",ge="stashpad-folder-panel",ne="stashpad-detail",G="__root__";Wt=["id","parent","created","modified","attachments","position","author","contributors","parentLink","children","due","assignedTo","assignedBy","pinned","pinnedAt","imported"],Te=new Set(["_attachments","_authors","_exports","_imports","_processed","_archive",".archive"]);Bo=new Set(["edtz"])});function mo(d,A){return d>12?d>=24?0:d:A==="am"?d===12?0:d:d===12?12:d+12}function li(d,A){d.addClass("stashpad-when-pop-time");let t=A.seedPeriod,e=d.createDiv({cls:"stashpad-when-time-display"}),i=e.createEl("input",{cls:"stashpad-when-time-field",attr:{type:"text",inputmode:"numeric",maxlength:"2"}});i.value=String(A.seedH),e.createSpan({cls:"stashpad-when-time-colon",text:":"});let s=e.createEl("input",{cls:"stashpad-when-time-field",attr:{type:"text",inputmode:"numeric",maxlength:"2"}});s.value=String(A.seedM).padStart(2,"0");let n=e.createDiv({cls:"stashpad-when-time-period"}),o=n.createEl("button",{cls:"stashpad-when-time-ampm",text:"AM"});o.type="button";let r=n.createEl("button",{cls:"stashpad-when-time-ampm",text:"PM"});r.type="button";let a=()=>{o.toggleClass("is-active",t==="am"),r.toggleClass("is-active",t==="pm")};a(),o.addEventListener("mousedown",E=>E.preventDefault()),r.addEventListener("mousedown",E=>E.preventDefault()),o.addEventListener("click",E=>{E.preventDefault(),t="am",a()}),r.addEventListener("click",E=>{E.preventDefault(),t="pm",a()});let c=i;i.addEventListener("focus",()=>{c=i,i.select()}),s.addEventListener("focus",()=>{c=s,s.select()});let l=()=>{let y=(parseInt(i.value||"0",10)||0)>12;o.toggleClass("is-disabled",y),r.toggleClass("is-disabled",y),o.disabled=y,r.disabled=y},p=E=>{let y=E.value.replace(/\D/g,"").slice(0,2);if(y===""){E.value="",E===i&&l();return}let w=parseInt(y,10);E===i?w>24&&(w=24):w>59&&(w=59),E.value=String(w),E===i&&l()};for(let E of[i,s])E.addEventListener("input",()=>p(E));l();let g=()=>{let E=parseInt(i.value||"12",10)||12,y=parseInt(s.value||"0",10)||0,w=E>12;A.onFinalize({hours24:mo(E,t),minutes:y,raw:{hh:E,mm:y,period:t,is24:w}}),A.close()};A.setOnEnter?.(g);let h=[i,s,o,r],I=(E,y)=>{let w=h.indexOf(E);if(w===-1)return;let v=(w+y+h.length)%h.length;h[v].focus()},u=E=>{E.addEventListener("keydown",y=>{y.key==="Enter"?(y.preventDefault(),y.stopPropagation(),g()):y.key==="Escape"?(y.preventDefault(),y.stopPropagation(),A.close()):y.key==="Tab"&&(y.preventDefault(),y.stopPropagation(),I(E,y.shiftKey?-1:1))})},f=d.createDiv({cls:"stashpad-when-time-pad"}),C=["1","2","3","4","5","6","7","8","9","backspace","0","insert"],m=null;for(let E of C){let y=f.createEl("button",{cls:"stashpad-when-time-padbtn"});y.type="button",E==="backspace"?(0,$s.setIcon)(y,"delete"):E==="insert"?(y.setText("OK"),m=y):y.setText(E),E==="insert"&&y.addClass("is-go"),y.addEventListener("mousedown",w=>w.preventDefault()),y.addEventListener("click",w=>{if(w.preventDefault(),E==="insert"){g();return}if(E==="backspace"){c.value=c.value.slice(0,-1),p(c),c.focus();return}let v=c.selectionStart===0&&c.selectionEnd===c.value.length&&c.value.length>0,D=2,L=v||c.value.length>=D?E:c.value+E;c.value=L,p(c),c.focus(),c.setSelectionRange(c.value.length,c.value.length),c===i&&c.value.length>=D&&(s.focus(),s.select())})}m&&h.push(m);for(let E of h)u(E);i.focus(),i.select()}function _s(d){let{hh:A,mm:t,period:e,is24:i}=d.raw;return i?`${A}:${String(t).padStart(2,"0")}`:`${A}:${String(t).padStart(2,"0")}${e}`}var $s,as=se(()=>{"use strict";$s=require("obsidian")});function tn(d){let A=Math.floor(4294967296/d)*d,t=new Uint32Array(1),e;do crypto.getRandomValues(t),e=t[0];while(e>=A);return e%d}function en(d=5){let A=[];for(let t=0;t=1&&s.every(r=>/^[a-zA-Z]+$/.test(r))&&(i=Math.min(i,s.length*11)),Qo.has(d.toLowerCase())&&(i=Math.min(i,12));let n=i<36?0:i<56?1:i<76?2:3,o=["Weak \u2014 easily guessed","Fair","Good","Strong"][n];return{bits:i,level:n,label:o}}function Eo(d){let A=2166136261;for(let t=0;t>>0).toString(16).padStart(8,"0")}function Ge(d){let A="stashpad-",t=Eo(d),e=64-A.length-1-t.length,i=d.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,Math.max(0,e)).replace(/-+$/g,"");return`${A}${i}-${t}`}var js,Qo,di=se(()=>{"use strict";js="able acid acorn actor adept agile alarm album alert algae amber amble anchor angle ankle apple april arbor arc arctic arena armor arrow ascot aspen atlas atom attic auburn audio autumn award axis bacon badge bagel baker balmy bamboo banjo barge basil basin batch beach beam bean bear beaver begin belt bench berry birch bison black blade blaze bliss bloom blue board boat bold bolt bonus boost booth borax bother bottle boulder bounce bovine bowl brave bread breeze brick bridge brisk broad bronze brook broom brown brush bubble bucket bug bulb bundle burst cabin cable cacao cactus camel cameo candle canoe canvas canyon cargo carol carrot castle catch cedar cello chalk charm chart cheese cherry chess chime chirp cider cinder circle citrus clamp clay clever cliff cloak clock cloud clover coast cobra cocoa comet coral cosmos cotton couch cougar crane crater cream crest cricket crisp crown crumb crystal cube cumin curio dagger daisy dapper dawn deck deer delta denim depot desert dial diamond dingo ditch dock dodge dolphin domino donut draft dragon drift drum dune dusk eagle early earth easel ebony echo eclipse edge eel eagle elbow elder ember emboss emerald ember emu engine ermine ether ever fable falcon fancy farm fawn feather felt fennel fern ferry fiber fiddle field fig finch flame flask flax fleet flint float flock flora flute focus foam forest fossil fox frame frost fudge garden gecko ginger glacier glade glass glide globe glory glove gnat goat golden gopher gourd grape grass gravel grove guava gull hammer hamlet harbor hatch hazel heron hickory hippo honey hornet hostel ivory ivy jade jaguar jasmine jelly jetty jewel jolly jungle juniper kayak kelp kettle kiwi koala ladle lagoon lamp lantern larch lark lasso lava ledge lemon lentil leopard lever lilac lime linen lizard llama lobby locket lodge lotus lunar lupine lynx maple marble marsh meadow medal melon mellow mentor mesa metro mimic mint mirror mocha morsel moss mottle mural muslin nacho nectar nest noble nomad noodle nougat nutmeg oasis oat ocean ochre olive onyx opal orbit orca otter oval owl oxide oyster pace paddle palm panda pantry papaya parka parsley pasta pearl pebble pelican pepper pewter phantom piano picnic pigeon pilot pine pixel plank plaza plum pocket pollen pond poplar poppy portal potato pottery prairie prism puffin pumice quail quartz quill quilt quince rabbit radish raft rapid raven reed reef relish ribbon ridge rind ripple river robin rocket rope rover ruby rudder rust saffron sage salmon sandal sash satin sauce scout sedge sequin shadow shale shark shell shore shrub silk silo silver siren sketch slate sleet slope sloth smoke snail sonar sorrel spark sparrow spice spire sprig spruce squid stable stamp starling steam stem stilt stone stork storm stove straw stream stucco summit sundae sunset swan sweater syrup tabby talon tango tapir tassel tawny teal tempo thicket thimble thistle thorn thunder tidal tiger timber toffee token topaz torch totem trail tulip tundra turtle tusk twig umber unicorn valley vanilla velvet vermil violet viper vista vivid vortex waffle walnut warbler wasp water weasel wharf wheat whisk willow window winter wisp wombat wonder woven yam yarn yeast yew yodel yonder zebra zenith zephyr zigzag zinc zircon".split(/\s+/).filter(Boolean);Qo=new Set(["password","passw0rd","password1","123456","12345678","123456789","qwerty","abc123","letmein","welcome","admin","iloveyou","monkey","dragon","sunshine","princess","football","baseball","trustno1","000000","111111","secret"])});var hi={};ri(hi,{newId:()=>Et});function Et(d=6){let A="",t=new Uint8Array(d);crypto.getRandomValues(t);for(let e=0;e{"use strict";nn="abcdefghijkmnpqrstuvwxyz23456789"});var ze={};ri(ze,{AssignModal:()=>qe,ColorPickerModal:()=>ce,ConfirmDeleteModal:()=>fe,ConfirmModal:()=>vt,CustomColorModal:()=>gi,DueDatePickerModal:()=>Oe,ExportStashModal:()=>Le,ImportDupChoiceModal:()=>Ye,ImportLogModal:()=>rs,LogModal:()=>ue,NotificationHistoryModal:()=>Ke,SplitNoteModal:()=>Pe,StashPasswordModal:()=>Je,buildAssigneePicker:()=>As});function As(d,A){let t=[...A.initial],e=A.knownAuthors,i=d.createDiv({cls:"stashpad-assign"});i.createDiv({cls:"stashpad-assign-label",text:"Assign to"});let s=i.createDiv({cls:"stashpad-assign-chips"}),n=i.createDiv({cls:"stashpad-assign-input-wrap"}),o=n.createEl("input",{type:"text",cls:"stashpad-assign-input",attr:{placeholder:"Add a person \u2014 type a name\u2026"}}),r=n.createDiv({cls:"stashpad-assign-suggest"});r.style.display="none";let a=()=>A.onChange([...t]),c=()=>{s.empty(),t.length===0&&s.createSpan({cls:"stashpad-assign-empty",text:"No one yet"});for(let g of t){let h=s.createSpan({cls:"stashpad-assign-chip"});h.createSpan({cls:"stashpad-assign-chip-name",text:g.name});let I=h.createSpan({cls:"stashpad-assign-chip-x",text:"\xD7"});I.title=`Remove ${g.name}`,I.onclick=()=>{t=t.filter(u=>u.id!==g.id),a(),c()}}},l=g=>{g.name.trim()&&(t.some(h=>h.id===g.id)||t.push(g),o.value="",r.style.display="none",a(),c(),o.focus())},p=()=>{let g=o.value.trim();r.empty();let h=new Set(t.map(f=>f.id)),u=e.filter(f=>!h.has(f.id)&&Ai(g,f.name)).slice(0,6).map(f=>({label:f.name,onPick:()=>l(f)}));if(g&&!e.some(f=>f.name.toLowerCase()===g.toLowerCase())&&u.push({label:`Create \u201C${g}\u201D`,onPick:()=>l({id:Et(6),name:g})}),u.length===0){r.style.display="none";return}r.style.display="";for(let f of u){let C=r.createDiv({cls:"stashpad-assign-suggest-item",text:f.label});C.onmousedown=m=>{m.preventDefault(),f.onPick()}}};o.addEventListener("input",p),o.addEventListener("focus",p),o.addEventListener("keydown",g=>{if(g.key==="Enter"){g.preventDefault();let h=r.querySelector(".stashpad-assign-suggest-item");h&&h.dispatchEvent(new MouseEvent("mousedown"))}else g.key==="Escape"&&r.style.display!=="none"&&(g.stopPropagation(),r.style.display="none")}),o.addEventListener("blur",()=>{window.setTimeout(()=>{r.style.display="none"},120)}),c()}var ct,re,ue,fe,Pe,Le,Je,gi,Re,ce,vt,qe,Oe,Ae,Ke,rs,Ye,Mt=se(()=>{"use strict";ct=require("obsidian");as();wt();di();Rt();re=class re extends ct.Modal{constructor(t,e,i){super(t);this.text=e;this.jsonlPath=i;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 i=t.createEl("button",{text:"Open in default app"});i.onclick=()=>this.shellAct("open");let s=t.createEl("button",{text:"Copy raw JSONL"}),n=null;s.onclick=async()=>{await navigator.clipboard.writeText(this.text),s.setText("Copied"),n!=null&&window.clearTimeout(n),n=window.setTimeout(()=>{s.setText("Copy raw JSONL"),n=null},1500)};let o=t.createEl("button",{text:"Export copy"});o.onclick=()=>this.exportCopy();let r=t.createEl("button",{cls:"mod-warning",text:"Clear log"});r.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(re.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 i=[...e.entries()].sort((n,o)=>o[1]-n[1]||n[0].localeCompare(o[0])),s=t.createEl("option",{text:`All types (${this.events.length})`});s.value="";for(let[n,o]of i){let r=t.createEl("option",{text:`${n} (${o})`});r.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 i=this.shownCount;i{this.appendMore(re.PAGE),this.renderFooter()},t>re.PAGE){let i=this.footerEl.createEl("button",{text:`Load all (${t})`});i.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:i}=window.require("electron");t==="reveal"?i.showItemInFolder(e):i.openPath(e)}catch(e){new ct.Notice(`Couldn't ${t}: ${e.message}`)}}async exportCopy(){try{let t=(0,ct.moment)().format("YYYY-MM-DD_HHmmss"),e=this.jsonlPath.replace(/\/[^/]+$/,"")||"",i=e?`${e}/${t}-log.jsonl`:`${t}-log.jsonl`;return await this.app.vault.adapter.write(i,this.text),new ct.Notice(`Exported log \u2192 ${i}`),i}catch(t){return new ct.Notice(`Export failed: ${t.message}`),null}}clearLog(){new vt(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(i){new ct.Notice(`Clear failed: ${i.message}`);return}this.text="",this.events=[],this.typeFilter=null,this.shownCount=0,this.refreshTypeFilter(),this.refreshList(),this.footerEl&&this.footerEl.empty(),new ct.Notice("Log cleared.")}}).open()}renderEvent(t){let e=document.createElement("div");e.className=`stashpad-log-row stashpad-log-${t.type}`;let i=(0,ct.moment)(t.ts).isValid()?(0,ct.moment)(t.ts).format("YYYY-MM-DD HH:mm:ss"):t.ts,s=document.createElement("span");s.className="stashpad-log-ts",s.textContent=i,e.appendChild(s);let n=document.createElement("span");n.className="stashpad-log-type",n.textContent=t.type,e.appendChild(n);let o=document.createElement("span");o.className="stashpad-log-author",o.textContent=t.author?t.author:"\u2014",t.author||o.classList.add("is-empty"),e.appendChild(o);let r=document.createElement("span");return r.className="stashpad-log-msg",r.textContent=this.describe(t),e.appendChild(r),e}describe(t){let e=t.payload??{};switch(t.type){case"create":return`Created "${e.path??t.id}" under ${e.parent??"?"}`;case"delete":{let i=Array.isArray(e.attachmentsRemoved)?e.attachmentsRemoved.length:0,s=e.mergedInto?` (merged into ${e.mergedInto})`:"";return`Deleted ${t.id}${s}${i?` \u2014 also removed ${i} attachment${i===1?"":"s"}`:""}`}case"missing":return`Missing: ${e.lastPath??t.id}`;case"parent_change":{let i=e.reason?` (${e.reason})`:"";return`Moved ${t.id} from ${e.from??"null"} \u2192 ${e.to??"null"}${i}`}case"rename":return`Renamed ${e.from??"?"} \u2192 ${e.to??"?"}`;case"reorder":{let i=e.count??1,s=e.dir??"?",n=e.parent??t.id??"?";return`Reordered ${i} note${i===1?"":"s"} (${s}) under ${n}`}case"complete":{let i=e.count??1,s=e.undo?" (undo)":e.redo?" (redo)":"";return`Marked ${i} note${i===1?"":"s"} complete${s}`}case"uncomplete":{let i=e.count??1,s=e.undo?" (undo)":e.redo?" (redo)":"";return`Unmarked ${i} note${i===1?"":"s"}${s}`}case"stash_export":{let i=e.noteCount??"?";return`Exported ${i} note${i===1?"":"s"} \u2192 ${e.path??"?"}`}case"stash_import":{let i=e.noteCount??"?",s=[];e.attachmentsWritten&&s.push(`${e.attachmentsWritten} attachment${e.attachmentsWritten===1?"":"s"}`),e.collisionsRenamed&&s.push(`${e.collisionsRenamed} renamed`);let n=s.length?` (${s.join(", ")})`:"";return`Imported ${i} note${i===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()}};re.PAGE=100;ue=re,fe=class extends ct.Modal{constructor(t,e,i,s,n,o){super(t);this.noteTitle=e;this.descendantCount=i;this.attachmentCount=s;this.offerAttachmentDelete=n;this.onChoose=o}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 o=this.contentEl.createEl("label",{cls:"stashpad-modal-check"}),r=o.createEl("input",{type:"checkbox"});r.checked=e,r.onchange=()=>{e=r.checked},o.createSpan({text:" Also delete attachments"})}let i=this.contentEl.createDiv({cls:"stashpad-modal-btns"}),s=i.createEl("button",{text:"Cancel"});s.onclick=()=>this.close();let n=i.createEl("button",{cls:"mod-warning",text:"Delete"});n.onclick=()=>{this.close(),this.onChoose(e)}}onClose(){this.contentEl.empty()}},Pe=class extends ct.Modal{constructor(t,e,i,s){super(t);this.body=e;this.onSplitAtLine=i;this.onSplitAtChar=s;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 lt.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 i=t.createEl("button",{text:"Split",cls:"stashpad-split-confirm-btn mod-cta"});i.onmousedown=n=>n.preventDefault(),i.onclick=()=>{this.mode==="line"?this.commitLine():this.commitCursor()},this.mode==="line"?this.renderLineMode():this.renderCursorMode();let s=this.contentEl.createDiv({cls:"stashpad-split-help"});lt.Platform.isMobile?s.setText(this.mode==="line"?"Tap a line to position the divider, then Split.":"Tap inside the text to position the cursor, then Split."):s.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 s=Math.max(1,Math.min(this.lines.length-1,e));s!==this.lineCursorIdx&&(this.lineCursorIdx=s,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 i=parseFloat(getComputedStyle(e).lineHeight)||22,s=lt.Platform.isMobile?3:12,n=2,o=()=>{e.style.height="auto";let a=Math.min(e.scrollHeight,i*s+16);e.style.height=`${Math.max(a,i*n+16)}px`};requestAnimationFrame(()=>{o();let a=Math.floor(e.value.length/2);e.focus(),e.setSelectionRange(a,a)}),e.addEventListener("input",o)}onClose(){this.cursorTextarea=null,this.contentEl.empty()}},Te=class extends lt.Modal{constructor(t,e,i,s){super(t);this.defaultBaseName=e;this.noteCount=i;this.onConfirm=s;this.delivered=!1}onOpen(){this.contentEl.empty(),this.titleEl.setText("Export to .stash"),this.modalEl.addClass("stashpad-export-modal"),this.contentEl.createEl("p",{cls:"stashpad-export-desc",text:`${this.noteCount} note${this.noteCount===1?"":"s"} will be bundled into a single .stash file.`});let t=this.contentEl.createDiv({cls:"stashpad-export-field"});t.createEl("label",{cls:"stashpad-export-label",text:"File name"});let e=t.createEl("input",{type:"text"});e.addClass("stashpad-export-name"),e.value=this.defaultBaseName;let i=this.contentEl.createEl("div",{cls:"stashpad-export-preview"}),s=this.contentEl.createDiv({cls:"stashpad-export-encrypt"}),n=s.createDiv({cls:"stashpad-export-toggle"}),o=n.createEl("input",{type:"checkbox"});o.id="stashpad-export-encrypt-cb";let a=n.createEl("label",{text:"Encrypt with a password"});a.htmlFor=o.id;let r=s.createDiv({cls:"stashpad-export-pw-area"});r.style.display="none";let c=r.createEl("input",{type:"password"});c.addClass("stashpad-export-name"),c.placeholder="Password";let l=r.createEl("input",{type:"password"});l.addClass("stashpad-export-name"),l.placeholder="Confirm password";let d=r.createEl("div",{cls:"stashpad-export-pw-hint"});r.createEl("div",{cls:"stashpad-export-pw-suite",text:"Encryption: Argon2id + AES-256-GCM (strongest). Falls back to PBKDF2 only if Argon2 can't run on this device."});let I=()=>{let Q=e.value.trim()||this.defaultBaseName;return o.checked?`${Q}-encrypted`:Q},g=()=>i.setText(`Saves as: ${I()}-.stash`);e.oninput=g;let p=this.contentEl.createDiv({cls:"stashpad-export-footer"}),u=p.createEl("button",{text:"Cancel"});u.onclick=()=>this.close();let f=p.createEl("button",{cls:"mod-cta",text:"Export"}),B=()=>{let Q=o.checked;r.style.display=Q?"":"none";let E=!0;Q&&(c.value?c.value!==l.value?(d.setText("Passwords don't match."),d.addClass("is-error"),E=!1):(d.setText("\u26A0\uFE0F If you lose this password, the export can't be recovered."),d.removeClass("is-error")):(d.setText("Enter a password to encrypt this export."),d.removeClass("is-error"),E=!1)),f.disabled=!E,f.toggleClass("is-disabled",!E),g()};o.onchange=B,c.oninput=B,l.oninput=B,B(),f.onclick=()=>this.commit(I(),o.checked?c.value:null),this.scope.register([],"Enter",Q=>{Q.preventDefault(),f.disabled||this.commit(I(),o.checked?c.value:null)}),requestAnimationFrame(()=>{e.focus(),e.select()})}commit(t,e){let i=t.trim()||this.defaultBaseName;this.delivered=!0,this.close(),this.onConfirm(i,e&&e.length?e:null)}onClose(){this.contentEl.empty()}},Ge=class extends lt.Modal{constructor(t,e,i,s){super(t);this.errorMsg=e;this.allowLater=i;this.onResult=s;this.delivered=!1}onOpen(){this.contentEl.empty(),this.titleEl.setText("Encrypted .stash"),this.modalEl.addClass("stashpad-export-modal"),this.contentEl.createEl("p",{cls:"stashpad-export-desc",text:"This export is password-protected. Enter its password to import it."}),this.errorMsg&&this.contentEl.createEl("div",{cls:"stashpad-export-error",text:this.errorMsg});let t=this.contentEl.createEl("input",{type:"password"});t.addClass("stashpad-export-name"),t.placeholder="Password";let e=this.contentEl.createDiv({cls:"stashpad-export-footer"});if(e.createEl("button",{text:"Cancel"}).onclick=()=>this.close(),this.allowLater){let s=e.createEl("button",{text:"Remind me later"});s.title="Don't import now \u2014 surface the reminder again later.",s.onclick=()=>this.finish({kind:"later"})}let i=e.createEl("button",{cls:"mod-cta",text:"Decrypt & import"});i.onclick=()=>this.submit(t.value),this.scope.register([],"Enter",s=>{s.preventDefault(),this.submit(t.value)}),requestAnimationFrame(()=>t.focus())}submit(t){t&&this.finish({kind:"password",value:t})}finish(t){this.delivered=!0,this.close(),this.onResult(t)}onClose(){this.delivered||(this.delivered=!0,this.onResult({kind:"cancel"})),this.contentEl.empty()}},oi=class extends lt.Modal{constructor(t,e,i){super(t);this.onResult=i;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 i=t.createEl("input",{type:"color"});i.value=this.value,i.addClass("stashpad-custom-color-wheel"),e.onclick=()=>i.click();let s=t.createEl("input",{type:"text"});s.addClass("stashpad-custom-color-hex"),s.placeholder="#RRGGBB",s.value=this.value,s.maxLength=7;let n=l=>{let d=l.startsWith("#")?l:"#"+l;/^#[0-9a-f]{6}$/i.test(d)&&(this.value=d,e.style.background=d,i.value=d,s.value!==d&&(s.value=d))};i.oninput=()=>n(i.value),s.oninput=()=>n(s.value);let o=this.contentEl.createDiv({cls:"stashpad-color-footer"}),a=o.createEl("button",{text:"Cancel"});a.onclick=()=>{this.delivered=!0,this.close()};let r=o.createEl("button",{cls:"mod-cta",text:"Save"});r.title="Apply this color to the selection (without adding to your palette).",r.onclick=()=>this.commit({addToPalette:!1});let c=o.createEl("button",{cls:"mod-cta",text:"Add to palette"});c.title="Apply and save this color so it appears as a tile next time.",c.onclick=()=>this.commit({addToPalette:!0}),this.scope.register([],"Enter",l=>{l.preventDefault(),this.commit({addToPalette:!1})}),this.scope.register(["Mod"],"Enter",l=>{l.preventDefault(),this.commit({addToPalette:!0})}),requestAnimationFrame(()=>s.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()}},He=class He extends lt.Modal{constructor(t,e,i,s,n){super(t);this.currentColor=e;this.customPalette=i;this.onPick=s;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 i=[...He.DEFAULT_PALETTE,...this.customPalette];for(let a of i){let r=t.createDiv({cls:"stashpad-color-tile"});r.style.background=a,r.title=a;let c=!He.DEFAULT_PALETTE.some(d=>d.toLowerCase()===a.toLowerCase()),l=this.items.length;if(r.onclick=()=>this.activate(l),c&&this.onDeleteCustom){let d=r.createSpan({cls:"stashpad-color-tile-del",text:"\xD7"});d.title="Remove from palette",d.onclick=I=>{I.stopPropagation(),this.handleDelete(a)}}this.items.push({kind:c?"custom":"preset",color:a,el:r})}let s=t.createDiv({cls:"stashpad-color-tile stashpad-color-add"});s.title="Custom color\u2026";let n=this.items.length;s.onclick=()=>this.activate(n),this.items.push({kind:"add",color:null,el:s});let o=this.items.findIndex(a=>this.currentColor===null?a.kind==="none":this.currentColor?a.color!==null&&a.color.toLowerCase()===this.currentColor.toLowerCase():!1);this.focusIdx=o>=0?o:0,this.refreshActive(),this.scope.register([],"ArrowRight",a=>{a.preventDefault(),this.moveFocus(1)}),this.scope.register([],"ArrowLeft",a=>{a.preventDefault(),this.moveFocus(-1)}),this.scope.register([],"ArrowDown",a=>{a.preventDefault(),this.moveFocus(this.columns())}),this.scope.register([],"ArrowUp",a=>{a.preventDefault(),this.moveFocus(-this.columns())}),this.scope.register([],"Enter",a=>{a.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 oi(this.app,this.currentColor,(i,s)=>{this.onPick(i,s)}).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(),i=this.items[0].el.getBoundingClientRect();if(i.width<=0)return 1;let s=i.top,n=0;for(let o of this.items){let a=o.el.getBoundingClientRect();if(Math.abs(a.top-s)<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(i=>i.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 s=e.createEl("button",{cls:"mod-cta",text:this.confirmText});s.onclick=()=>{this.didChoose=!0,this.close(),this.onChoose(!0)},requestAnimationFrame(()=>s.focus())}onClose(){this.contentEl.empty(),this.didChoose||(this.didChoose=!0,this.onChoose(!1))}};Re=class extends lt.Modal{constructor(t,e,i){super(t);this.opts=e;this.onPick=i;this.didChoose=!1;this.assignees=[];this.assignees=[...e.currentAssignees]}onOpen(){this.modalEl?.addClass("stashpad-compact-modal"),this.contentEl.empty(),this.titleEl.setText("Assign task");let t=this.contentEl.createDiv({cls:"stashpad-due-picker"});ji(t,{knownAuthors:this.opts.knownAuthors,initial:this.assignees,onChange:n=>{this.assignees=n}});let e=this.contentEl.createDiv({cls:"stashpad-modal-btns"}),i=e.createEl("button",{text:"Cancel"});i.onclick=()=>{this.didChoose=!0,this.close()};let s=e.createEl("button",{cls:"mod-cta",text:"Save"});s.onclick=()=>{this.didChoose=!0,this.close(),this.onPick(this.assignees)}}onClose(){this.contentEl.empty(),this.didChoose}},Pe=class extends lt.Modal{constructor(t,e,i,s={}){super(t);this.current=e;this.onPick=i;this.opts=s;this.didChoose=!1;this.assignees=[];this.tinyClosePopover=null;this.assignees=[...s.currentAssignees??[]]}onOpen(){this.modalEl?.addClass("stashpad-compact-modal"),this.contentEl.empty(),this.titleEl.setText("Set due date");let t=null;if(this.current){let f=Date.parse(this.current);Number.isNaN(f)||(t=new Date(f))}let e=this.contentEl.createDiv({cls:"stashpad-due-picker"}),i=e.createDiv({cls:"stashpad-due-fields"}),s=i.createDiv({cls:"stashpad-due-field"}),n=s.createSpan({cls:"stashpad-due-field-icon"});(0,lt.setIcon)(n,"calendar");let o=s.createEl("input",{type:"date",cls:"stashpad-due-date"}),a=i.createDiv({cls:"stashpad-due-field"}),r=a.createSpan({cls:"stashpad-due-field-icon"});(0,lt.setIcon)(r,"clock");let c=a.createEl("input",{type:"time",cls:"stashpad-due-time"});n.onclick=()=>{try{o.showPicker?.()}catch{}},r.onclick=()=>this.openTimeNumpad(r,c),t&&(o.value=this.toDateValue(t),c.value=this.toTimeValue(t)),this.renderAssignSection(e);let l=e.createDiv({cls:"stashpad-due-grid"}),d=(f,B)=>{let Q=l.createEl("button",{cls:"stashpad-due-btn stashpad-due-preset",text:f});Q.onclick=()=>{let E=B();o.value=this.toDateValue(E),c.value||(c.value=this.toTimeValue(E))}},I=f=>(f.setHours(9,0,0,0),f);d("Today",()=>I(this.startOfTodayLocal())),d("Tomorrow",()=>{let f=this.startOfTodayLocal();return f.setDate(f.getDate()+1),I(f)}),d("Next week",()=>{let f=this.startOfTodayLocal();return f.setDate(f.getDate()+7),I(f)});let g=l.createEl("button",{cls:"stashpad-due-btn",text:"Clear"});g.onclick=()=>{o.value="",c.value="",o.focus()};let p=l.createEl("button",{cls:"stashpad-due-btn",text:"Cancel"});p.onclick=()=>{this.didChoose=!0,this.close()};let u=l.createEl("button",{cls:"stashpad-due-btn mod-cta",text:"Set"});u.onclick=()=>{if(!o.value){this.didChoose=!0,this.close(),this.onPick({iso:null,assignees:this.assignees});return}let[f,B,Q]=o.value.split("-").map(k=>parseInt(k,10)),E=9,y=0;if(c.value){let[k,b]=c.value.split(":").map(R=>parseInt(R,10));E=k,y=b}let v=new Date(f,B-1,Q,E,y,0,0);this.didChoose=!0,this.close(),this.onPick({iso:v.toISOString(),assignees:this.assignees})},requestAnimationFrame(()=>o.focus())}onClose(){this.tinyClosePopover?.(),this.contentEl.empty(),this.didChoose}renderAssignSection(t){ji(t,{knownAuthors:this.opts.knownAuthors??[],initial:this.assignees,onChange:e=>{this.assignees=e}})}openTimeNumpad(t,e){this.tinyClosePopover?.();let i=9,s=0;if(e.value){let[g,p]=e.value.split(":").map(u=>parseInt(u,10));Number.isFinite(g)&&(i=g),Number.isFinite(p)&&(s=p)}else{let g=new Date;i=g.getHours(),s=g.getMinutes()}let n=i>=12?"pm":"am",o=i===0?12:i>12?i-12:i,a=document.body.createDiv({cls:"stashpad-when-popover stashpad-due-time-pop"});a.style.position="fixed",a.style.zIndex="9999";let r=null,c=()=>{a.remove(),document.removeEventListener("mousedown",l,!0),document.removeEventListener("keydown",d,!0),this.tinyClosePopover===c&&(this.tinyClosePopover=null)},l=g=>{!a.contains(g.target)&&g.target!==t&&!t.contains(g.target)&&c()},d=g=>{g.key==="Escape"?(g.preventDefault(),g.stopPropagation(),c()):g.key==="Enter"&&r&&(g.preventDefault(),g.stopPropagation(),r())};this.tinyClosePopover=c,si(a,{seedH:o,seedM:s,seedPeriod:n,close:c,setOnEnter:g=>{r=g},onFinalize:g=>{e.value=`${String(g.hours24).padStart(2,"0")}:${String(g.minutes).padStart(2,"0")}`}});let I=t.getBoundingClientRect();a.style.left=`${Math.max(8,Math.min(I.left,window.innerWidth-220))}px`,a.style.top=`${I.bottom+4}px`,setTimeout(()=>{document.addEventListener("mousedown",l,!0),document.addEventListener("keydown",d,!0)},0)}startOfTodayLocal(){let t=new Date;return t.setHours(0,0,0,0),t}toDateValue(t){let e=t.getFullYear(),i=String(t.getMonth()+1).padStart(2,"0"),s=String(t.getDate()).padStart(2,"0");return`${e}-${i}-${s}`}toTimeValue(t){let e=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0");return`${e}:${i}`}},oe=class oe extends lt.Modal{constructor(t,e,i,s=null,n){super(t);this.service=e;this.openLog=i;this.currentAuthorId=s;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 i=t.createEl("button",{text:"Open log"});i.title="Open the per-folder Stashpad log for the most recent notification's folder.",i.onclick=()=>{let s=this.records.find(n=>!!n.folder);this.openLog?.(s?.folder)}}let e=t.createEl("button",{cls:"mod-warning",text:"Clear history"});e.onclick=()=>{new Dt(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",i=>{i&&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 s of this.records)s.authorId&&s.authorId!==this.currentAuthorId&&e.add(s.authorId);if(e.size>0){let s=t.createEl("option",{text:"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"});s.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 i of t.affectedAuthorIds??[])if(i&&i!==e)return!0;if(!this.getNoteAuthorIds)return!1;for(let i of t.affectedIds){let s=this.getNoteAuthorIds(i);for(let n of s)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 i=[...e.entries()].sort((n,o)=>o[1]-n[1]||n[0].localeCompare(o[0])),s=t.createEl("option",{text:`All categories (${this.records.length})`});s.value="";for(let[n,o]of i){let a=t.createEl("option",{text:`${n} (${o})`});a.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(oe.PAGE)}}appendMore(t){if(!this.listEl)return;let e=Math.min(this.visible.length,this.shownCount+t);for(let i=this.shownCount;i0){let c=i.createDiv({cls:"stashpad-notif-actions-snapshot"});for(let l of e.actionLabels){let d=c.createSpan({cls:"stashpad-notif-action-chip"});d.setText(l),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(oe.PAGE,t)} more`});if(e.onclick=()=>{this.appendMore(oe.PAGE),this.renderFooter()},t>oe.PAGE){let i=this.footerEl.createEl("button",{text:`Load all (${t})`});i.onclick=()=>{this.appendMore(t),this.renderFooter()}}}};oe.PAGE=100;Le=oe,$i=class extends lt.Modal{constructor(t,e){super(t);this.entries=e}onOpen(){if(this.contentEl.empty(),this.titleEl.setText("Stashpad import log"),this.entries.length===0){this.contentEl.createDiv({cls:"stashpad-log-empty",text:"Nothing imported yet."});return}let t=this.contentEl.createDiv({cls:"stashpad-import-log-list"});for(let e of this.entries){let i=t.createDiv({cls:"stashpad-import-log-row"}),s=(0,lt.moment)(e.ts).format("YYYY-MM-DD HH:mm");i.createSpan({cls:"stashpad-import-log-when",text:s});let n=e.kind==="folder"?"folder":e.kind==="md"?"note":"file";i.createSpan({cls:`stashpad-import-log-kind is-${e.kind}`,text:n}),i.createSpan({cls:"stashpad-import-log-name",text:e.originalName});let o=[e.folder.split("/").pop()||e.folder];e.notePaths.length>1&&o.push(`${e.notePaths.length} notes`),i.createSpan({cls:"stashpad-import-log-meta",text:o.join(" \xB7 ")})}}onClose(){this.contentEl.empty()}},Je=class extends lt.Modal{constructor(t,e,i){super(t);this.message=e;this.onChoose=i;this.chose=!1}onOpen(){this.modalEl?.addClass("stashpad-compact-modal"),this.contentEl.empty(),this.titleEl.setText("Possible duplicate import");let t=this.contentEl.createDiv({cls:"stashpad-confirm-body"});for(let o of this.message.split(` -`))t.createDiv({cls:"stashpad-confirm-line",text:o});let e=this.contentEl.createDiv({cls:"stashpad-modal-btns"}),i=e.createEl("button",{text:"Skip duplicates"});i.onclick=()=>{this.chose=!0,this.close(),this.onChoose("skip")};let s=e.createEl("button",{text:"Replace existing"});s.onclick=()=>{this.chose=!0,this.close(),this.onChoose("replace")};let n=e.createEl("button",{cls:"mod-cta",text:"Import anyway"});n.onclick=()=>{this.chose=!0,this.close(),this.onChoose("anyway")}}onClose(){this.chose||this.onChoose("skip"),this.contentEl.empty()}}});function kt(h,A=Gt){let t=A instanceof Set?A:new Set(A.map(o=>o.toLowerCase())),e=(h.split(/\r?\n/).find(o=>o.trim().length>0)??"").trim();if(!e)return"Untitled";let s=e.replace(/['‘-‛ʼ]/g,"").replace(/[^A-Za-z0-9\s]+/g," ").split(/\s+/).filter(o=>o&&!t.has(o.toLowerCase())).map(o=>o.length>=2&&/^[A-Z0-9]+$/.test(o)?o:o.charAt(0).toUpperCase()+o.slice(1).toLowerCase()),n="";for(let o of s){let a=n?`${n}-${o}`:o;if(a.length>50)break;n=a}return n||"Untitled"}function St(h,A){return`${h}-${A}.md`}function pe(h){let A=h.match(/-([a-z0-9]{4,12})$/);return A?A[1]:null}var Gt,ue=le(()=>{"use strict";Gt=["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 di={};ei(di,{JdBuildConfirmModal:()=>Oe,buildJdIndexNotes:()=>es,buildJdIndexPreview:()=>ci,buildJdPreviewNotice:()=>li,scanForJdNotes:()=>fe});function ts(h,A){if(/^\d+-\d+$/.test(h))return null;if(h.includes(".")){let e=h.split(".").slice(0,-1).join(".");return A.has(e)?e:ts(e,A)}if(/^\d+$/.test(h)){let t=parseInt(h,10);for(let e of A){let i=e.match(/^(\d+)-(\d+)$/);if(!i)continue;let s=parseInt(i[1],10),n=parseInt(i[2],10);if(t>=s&&t<=n)return e}return null}return null}function fe(h,A,t){let e=h.vault.getMarkdownFiles(),i=no(e,t),s=t.jdIndexIncludeStashpadFolders===!0,n=s?new Set:new Set(A.discoverStashpadFolders()),o=g=>s?!1:Array.from(n).some(p=>g===p||g.startsWith(p+"/")),a=[],r=[],c=[];for(let g of i){let p=g.parent?.path?.replace(/\/+$/,"")??"";if(o(p)){c.push(g);continue}let u=g.basename.match(qs);u?a.push({prefix:u[1],segments:u[1].split("."),title:u[2],file:g,folder:null}):r.push(g)}let l=(t.jdIndexScope??"vault")==="folder"?(t.jdIndexScopeFolder??"").trim().replace(/^\/+|\/+$/g,""):"",d=g=>{let p=g.path.replace(/\/+$/,"");if(!(l&&p&&p!==l&&!p.startsWith(l+"/"))){if(p&&!o(p)){let u=g.name.match(qs);u&&a.push({prefix:u[1],segments:u[1].split("."),title:u[2],file:null,folder:g})}}for(let u of g.children)u instanceof wt.TFolder&&d(u)};d(h.vault.getRoot());let I=t.jdIndexSort??"natural";return a.sort((g,p)=>oo(g,p,I)),{indexed:a,nonIndex:r,skippedStashpadNotes:c}}async function ci(h,A,t){let e=is(t.jdIndexStashpadFolder??"");if(!e)return{...fe(h,A,t),previewPath:null,error:"no-dest"};let i=fe(h,A,t),s=so(h,e);if(!s)return{...i,previewPath:null,error:"no-home"};let n=ao(i.indexed,i.nonIndex,i.skippedStashpadNotes),a=(await h.vault.read(s)).match(/^---\r?\n[\s\S]*?\r?\n---\r?\n/),r=a?`${a[0]}${n}`:n;return await h.vault.modify(s,r),{...i,previewPath:s.path}}function so(h,A){let t=h.vault.getAbstractFileByPath(A);if(!(t instanceof wt.TFolder))return null;for(let e of t.children){if(!(e instanceof wt.TFile)||e.extension!=="md")continue;if((h.metadataCache.getFileCache(e)?.frontmatter??{}).id===G)return e}return null}async function es(h,A,t){let e=is(t.jdIndexStashpadFolder??"");if(!e)return{created:0,updated:0,skipped:0,destFolder:"",error:"no-dest"};if(!new Set(A.discoverStashpadFolders()).has(e))return{created:0,updated:0,skipped:0,destFolder:e,error:"dest-not-stashpad"};let s=fe(h,A,t),n=new Map;for(let f of s.indexed)n.set(f.prefix,f);for(let f of s.indexed)if(f.prefix.includes("."))for(let B=1;B{r.push(f);for(let B of a.get(f)??[])c(B)};for(let f of o)c(f);let l=new Map,d=h.vault.getAbstractFileByPath(e);if(d instanceof wt.TFolder)for(let f of d.children){if(!(f instanceof wt.TFile)||f.extension!=="md")continue;let B=h.metadataCache.getFileCache(f)?.frontmatter??{};typeof B.jdPrefix=="string"&&l.set(B.jdPrefix,f)}let I=new Map,g=0,p=0,u=0;for(let f of r){let B=n.get(f)??null,Q=ts(f,new Set(n.keys())),E=Q?I.get(Q)??G:G,y=B?`${f} ${B.title}`:f,v=B?.file?`[[${B.file.basename}]]`:"",k=v?`${v} +`),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 ct.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 i=t.createEl("button",{text:"Split",cls:"stashpad-split-confirm-btn mod-cta"});i.onmousedown=n=>n.preventDefault(),i.onclick=()=>{this.mode==="line"?this.commitLine():this.commitCursor()},this.mode==="line"?this.renderLineMode():this.renderCursorMode();let s=this.contentEl.createDiv({cls:"stashpad-split-help"});ct.Platform.isMobile?s.setText(this.mode==="line"?"Tap a line to position the divider, then Split.":"Tap inside the text to position the cursor, then Split."):s.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 s=Math.max(1,Math.min(this.lines.length-1,e));s!==this.lineCursorIdx&&(this.lineCursorIdx=s,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 i=parseFloat(getComputedStyle(e).lineHeight)||22,s=ct.Platform.isMobile?3:12,n=2,o=()=>{e.style.height="auto";let r=Math.min(e.scrollHeight,i*s+16);e.style.height=`${Math.max(r,i*n+16)}px`};requestAnimationFrame(()=>{o();let r=Math.floor(e.value.length/2);e.focus(),e.setSelectionRange(r,r)}),e.addEventListener("input",o)}onClose(){this.cursorTextarea=null,this.contentEl.empty()}},Le=class extends ct.Modal{constructor(t,e,i,s,n){super(t);this.defaultBaseName=e;this.noteCount=i;this.onConfirm=s;this.kdfProbe=n;this.delivered=!1}onOpen(){this.contentEl.empty(),this.titleEl.setText("Export to .stash"),this.modalEl.addClass("stashpad-export-modal"),this.contentEl.createEl("p",{cls:"stashpad-export-desc",text:`${this.noteCount} note${this.noteCount===1?"":"s"} will be bundled into a single .stash file.`});let t=this.contentEl.createDiv({cls:"stashpad-export-field"});t.createEl("label",{cls:"stashpad-export-label",text:"File name"});let e=t.createEl("input",{type:"text"});e.addClass("stashpad-export-name"),e.value=this.defaultBaseName;let i=this.contentEl.createEl("div",{cls:"stashpad-export-preview"}),s=this.contentEl.createDiv({cls:"stashpad-export-encrypt"}),n=s.createDiv({cls:"stashpad-export-toggle"}),o=n.createEl("input",{type:"checkbox"});o.id="stashpad-export-encrypt-cb";let r=n.createEl("label",{text:"Encrypt with a password"});r.htmlFor=o.id;let a=s.createDiv({cls:"stashpad-export-pw-area"});a.style.display="none";let c=[],l=K=>{let z=a.createDiv({cls:"stashpad-export-pw-row"}),ot=z.createEl("input",{type:"password"});ot.addClass("stashpad-export-name"),ot.placeholder=K;let dt=z.createEl("button",{cls:"stashpad-export-copy"}),st=()=>{let at=ot.value.length===0;dt.setText(at?"Paste":"Copy"),dt.toggleClass("is-paste",at),dt.setAttr("aria-label",`${at?"Paste into":"Copy"} ${K.toLowerCase()}`)};return dt.onclick=async at=>{if(at.preventDefault(),ot.value.length===0)try{let At=(await navigator.clipboard?.readText())?.trim();if(!At){new ct.Notice("Clipboard is empty.");return}ot.value=At,ot.dispatchEvent(new Event("input")),new ct.Notice("Pasted from clipboard.")}catch{new ct.Notice("Couldn't read the clipboard.")}else navigator.clipboard?.writeText(ot.value).then(()=>new ct.Notice("Passphrase copied to clipboard."),()=>new ct.Notice("Couldn't access the clipboard."))},st(),c.push(st),ot},p=l("Password"),g=l("Confirm password"),h=a.createDiv({cls:"stashpad-export-strength"}),I=h.createDiv({cls:"stashpad-strength-bar"}),u=[0,1,2,3].map(()=>I.createDiv({cls:"stashpad-strength-seg"})),f=h.createEl("span",{cls:"stashpad-strength-label"}),C=a.createDiv({cls:"stashpad-export-genrow"}),m=C.createEl("button",{cls:"stashpad-export-gen",text:"Generate strong passphrase"}),E=C.createEl("button",{cls:"stashpad-export-show",text:"Show"}),y=a.createEl("div",{cls:"stashpad-export-pw-hint"}),w=a.createEl("div",{cls:"stashpad-export-pw-suite"});w.setText("Encryption: AES-256-GCM. Checking key-derivation suite for this device\u2026"),this.kdfProbe?this.kdfProbe().then(K=>{w.toggleClass("is-weak",!K),w.setText(K?"Encryption: Argon2id + AES-256-GCM \u2014 the strongest suite (used on this device).":"\u26A0\uFE0F Argon2id can't run on this device, so this export will use the weaker PBKDF2 (600k) + AES-256-GCM fallback.")}).catch(()=>{w.setText("Encryption: AES-256-GCM with a password-derived key.")}):w.setText("Encryption: Argon2id + AES-256-GCM (falls back to PBKDF2 if Argon2 can't run here).");let v=this.app.secretStorage,D=a.createDiv({cls:"stashpad-export-remember"}),L=D.createEl("input",{type:"checkbox"});L.id="stashpad-export-remember-cb";let S=D.createEl("label",{text:"Remember in this vault (this device) \u2014 skips the prompt when you re-import here."});S.htmlFor=L.id;let b=a.createDiv({cls:"stashpad-export-remember-note"});b.setText("Saved only in this device's keychain \u2014 it doesn't sync to your other devices and isn't shared with anyone you send this file to. Keep the passphrase somewhere safe if you'll open this export elsewhere."),b.style.display="none",L.onchange=()=>{b.style.display=L.checked?"":"none"},v||(D.style.display="none");let Q=()=>{let K=e.value.trim()||this.defaultBaseName;return o.checked?`${K}-encrypted`:K},H=()=>i.setText(`Saves as: ${Q()}-.stash`);e.oninput=H;let $=this.contentEl.createDiv({cls:"stashpad-export-footer"}),M=$.createEl("button",{text:"Cancel"});M.onclick=()=>this.close();let T=$.createEl("button",{cls:"mod-cta",text:"Export"}),J=()=>{let K=sn(p.value);h.style.visibility=p.value?"visible":"hidden",u.forEach((z,ot)=>z.toggleClass("is-on",p.value!==""&&ot<=K.level)),I.dataset.level=String(K.level),f.setText(K.label)},Z=()=>{let K=o.checked;a.style.display=K?"":"none";let z=!0;K&&(p.value?p.value!==g.value?(y.setText("Passwords don't match."),y.addClass("is-error"),z=!1):(y.setText("\u26A0\uFE0F If you lose this password, the export can't be recovered."),y.removeClass("is-error")):(y.setText("Enter a password to encrypt this export."),y.removeClass("is-error"),z=!1)),J(),c.forEach(ot=>ot()),T.disabled=!z,T.toggleClass("is-disabled",!z),H()},U=!1,N=K=>{U=K,p.type=g.type=K?"text":"password",E.setText(K?"Hide":"Show")};E.onclick=K=>{K.preventDefault(),N(!U)},m.onclick=K=>{K.preventDefault(),p.value=g.value=en(),N(!1),new ct.Notice("Passphrase generated (hidden) \u2014 Show to view, or Copy to save it."),Z()},o.onchange=Z,p.oninput=Z,g.oninput=Z,Z();let j=()=>this.commit(Q(),o.checked?p.value:null,o.checked&&L.checked);T.onclick=j,this.scope.register([],"Enter",K=>{K.preventDefault(),T.disabled||j()}),requestAnimationFrame(()=>{e.focus(),e.select()})}commit(t,e,i){let s=t.trim()||this.defaultBaseName,n=e&&e.length?e:null;this.delivered=!0,this.close(),this.onConfirm(s,n,!!n&&i)}onClose(){this.contentEl.empty()}},Je=class extends ct.Modal{constructor(t,e,i,s){super(t);this.errorMsg=e;this.allowLater=i;this.onResult=s;this.delivered=!1}onOpen(){this.contentEl.empty(),this.titleEl.setText("Encrypted .stash"),this.modalEl.addClass("stashpad-export-modal"),this.contentEl.createEl("p",{cls:"stashpad-export-desc",text:"This export is password-protected. Enter its password to import it."}),this.errorMsg&&this.contentEl.createEl("div",{cls:"stashpad-export-error",text:this.errorMsg});let t=this.contentEl.createEl("input",{type:"password"});t.addClass("stashpad-export-name"),t.placeholder="Password";let e=this.contentEl.createDiv({cls:"stashpad-export-footer"});if(e.createEl("button",{text:"Cancel"}).onclick=()=>this.close(),this.allowLater){let s=e.createEl("button",{text:"Remind me later"});s.title="Don't import now \u2014 surface the reminder again later.",s.onclick=()=>this.finish({kind:"later"})}let i=e.createEl("button",{cls:"mod-cta",text:"Decrypt & import"});i.onclick=()=>this.submit(t.value),this.scope.register([],"Enter",s=>{s.preventDefault(),this.submit(t.value)}),requestAnimationFrame(()=>t.focus())}submit(t){t&&this.finish({kind:"password",value:t})}finish(t){this.delivered=!0,this.close(),this.onResult(t)}onClose(){this.delivered||(this.delivered=!0,this.onResult({kind:"cancel"})),this.contentEl.empty()}},gi=class extends ct.Modal{constructor(t,e,i){super(t);this.onResult=i;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 i=t.createEl("input",{type:"color"});i.value=this.value,i.addClass("stashpad-custom-color-wheel"),e.onclick=()=>i.click();let s=t.createEl("input",{type:"text"});s.addClass("stashpad-custom-color-hex"),s.placeholder="#RRGGBB",s.value=this.value,s.maxLength=7;let n=l=>{let p=l.startsWith("#")?l:"#"+l;/^#[0-9a-f]{6}$/i.test(p)&&(this.value=p,e.style.background=p,i.value=p,s.value!==p&&(s.value=p))};i.oninput=()=>n(i.value),s.oninput=()=>n(s.value);let o=this.contentEl.createDiv({cls:"stashpad-color-footer"}),r=o.createEl("button",{text:"Cancel"});r.onclick=()=>{this.delivered=!0,this.close()};let a=o.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 c=o.createEl("button",{cls:"mod-cta",text:"Add to palette"});c.title="Apply and save this color so it appears as a tile next time.",c.onclick=()=>this.commit({addToPalette:!0}),this.scope.register([],"Enter",l=>{l.preventDefault(),this.commit({addToPalette:!1})}),this.scope.register(["Mod"],"Enter",l=>{l.preventDefault(),this.commit({addToPalette:!0})}),requestAnimationFrame(()=>s.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()}},Re=class Re extends ct.Modal{constructor(t,e,i,s,n){super(t);this.currentColor=e;this.customPalette=i;this.onPick=s;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 i=[...Re.DEFAULT_PALETTE,...this.customPalette];for(let r of i){let a=t.createDiv({cls:"stashpad-color-tile"});a.style.background=r,a.title=r;let c=!Re.DEFAULT_PALETTE.some(p=>p.toLowerCase()===r.toLowerCase()),l=this.items.length;if(a.onclick=()=>this.activate(l),c&&this.onDeleteCustom){let p=a.createSpan({cls:"stashpad-color-tile-del",text:"\xD7"});p.title="Remove from palette",p.onclick=g=>{g.stopPropagation(),this.handleDelete(r)}}this.items.push({kind:c?"custom":"preset",color:r,el:a})}let s=t.createDiv({cls:"stashpad-color-tile stashpad-color-add"});s.title="Custom color\u2026";let n=this.items.length;s.onclick=()=>this.activate(n),this.items.push({kind:"add",color:null,el:s});let o=this.items.findIndex(r=>this.currentColor===null?r.kind==="none":this.currentColor?r.color!==null&&r.color.toLowerCase()===this.currentColor.toLowerCase():!1);this.focusIdx=o>=0?o:0,this.refreshActive(),this.scope.register([],"ArrowRight",r=>{r.preventDefault(),this.moveFocus(1)}),this.scope.register([],"ArrowLeft",r=>{r.preventDefault(),this.moveFocus(-1)}),this.scope.register([],"ArrowDown",r=>{r.preventDefault(),this.moveFocus(this.columns())}),this.scope.register([],"ArrowUp",r=>{r.preventDefault(),this.moveFocus(-this.columns())}),this.scope.register([],"Enter",r=>{r.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 gi(this.app,this.currentColor,(i,s)=>{this.onPick(i,s)}).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(),i=this.items[0].el.getBoundingClientRect();if(i.width<=0)return 1;let s=i.top,n=0;for(let o of this.items){let r=o.el.getBoundingClientRect();if(Math.abs(r.top-s)<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(i=>i.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 s=e.createEl("button",{cls:"mod-cta",text:this.confirmText});s.onclick=()=>{this.didChoose=!0,this.close(),this.onChoose(!0)},requestAnimationFrame(()=>s.focus())}onClose(){this.contentEl.empty(),this.didChoose||(this.didChoose=!0,this.onChoose(!1))}};qe=class extends ct.Modal{constructor(t,e,i){super(t);this.opts=e;this.onPick=i;this.didChoose=!1;this.assignees=[];this.assignees=[...e.currentAssignees]}onOpen(){this.modalEl?.addClass("stashpad-compact-modal"),this.contentEl.empty(),this.titleEl.setText("Assign task");let t=this.contentEl.createDiv({cls:"stashpad-due-picker"});As(t,{knownAuthors:this.opts.knownAuthors,initial:this.assignees,onChange:n=>{this.assignees=n}});let e=this.contentEl.createDiv({cls:"stashpad-modal-btns"}),i=e.createEl("button",{text:"Cancel"});i.onclick=()=>{this.didChoose=!0,this.close()};let s=e.createEl("button",{cls:"mod-cta",text:"Save"});s.onclick=()=>{this.didChoose=!0,this.close(),this.onPick(this.assignees)}}onClose(){this.contentEl.empty(),this.didChoose}},Oe=class extends ct.Modal{constructor(t,e,i,s={}){super(t);this.current=e;this.onPick=i;this.opts=s;this.didChoose=!1;this.assignees=[];this.tinyClosePopover=null;this.assignees=[...s.currentAssignees??[]]}onOpen(){this.modalEl?.addClass("stashpad-compact-modal"),this.contentEl.empty(),this.titleEl.setText("Set due date");let t=null;if(this.current){let f=Date.parse(this.current);Number.isNaN(f)||(t=new Date(f))}let e=this.contentEl.createDiv({cls:"stashpad-due-picker"}),i=e.createDiv({cls:"stashpad-due-fields"}),s=i.createDiv({cls:"stashpad-due-field"}),n=s.createSpan({cls:"stashpad-due-field-icon"});(0,ct.setIcon)(n,"calendar");let o=s.createEl("input",{type:"date",cls:"stashpad-due-date"}),r=i.createDiv({cls:"stashpad-due-field"}),a=r.createSpan({cls:"stashpad-due-field-icon"});(0,ct.setIcon)(a,"clock");let c=r.createEl("input",{type:"time",cls:"stashpad-due-time"});n.onclick=()=>{try{o.showPicker?.()}catch{}},a.onclick=()=>this.openTimeNumpad(a,c),t&&(o.value=this.toDateValue(t),c.value=this.toTimeValue(t)),this.renderAssignSection(e);let l=e.createDiv({cls:"stashpad-due-grid"}),p=(f,C)=>{let m=l.createEl("button",{cls:"stashpad-due-btn stashpad-due-preset",text:f});m.onclick=()=>{let E=C();o.value=this.toDateValue(E),c.value||(c.value=this.toTimeValue(E))}},g=f=>(f.setHours(9,0,0,0),f);p("Today",()=>g(this.startOfTodayLocal())),p("Tomorrow",()=>{let f=this.startOfTodayLocal();return f.setDate(f.getDate()+1),g(f)}),p("Next week",()=>{let f=this.startOfTodayLocal();return f.setDate(f.getDate()+7),g(f)});let h=l.createEl("button",{cls:"stashpad-due-btn",text:"Clear"});h.onclick=()=>{o.value="",c.value="",o.focus()};let I=l.createEl("button",{cls:"stashpad-due-btn",text:"Cancel"});I.onclick=()=>{this.didChoose=!0,this.close()};let u=l.createEl("button",{cls:"stashpad-due-btn mod-cta",text:"Set"});u.onclick=()=>{if(!o.value){this.didChoose=!0,this.close(),this.onPick({iso:null,assignees:this.assignees});return}let[f,C,m]=o.value.split("-").map(v=>parseInt(v,10)),E=9,y=0;if(c.value){let[v,D]=c.value.split(":").map(L=>parseInt(L,10));E=v,y=D}let w=new Date(f,C-1,m,E,y,0,0);this.didChoose=!0,this.close(),this.onPick({iso:w.toISOString(),assignees:this.assignees})},requestAnimationFrame(()=>o.focus())}onClose(){this.tinyClosePopover?.(),this.contentEl.empty(),this.didChoose}renderAssignSection(t){As(t,{knownAuthors:this.opts.knownAuthors??[],initial:this.assignees,onChange:e=>{this.assignees=e}})}openTimeNumpad(t,e){this.tinyClosePopover?.();let i=9,s=0;if(e.value){let[h,I]=e.value.split(":").map(u=>parseInt(u,10));Number.isFinite(h)&&(i=h),Number.isFinite(I)&&(s=I)}else{let h=new Date;i=h.getHours(),s=h.getMinutes()}let n=i>=12?"pm":"am",o=i===0?12:i>12?i-12:i,r=document.body.createDiv({cls:"stashpad-when-popover stashpad-due-time-pop"});r.style.position="fixed",r.style.zIndex="9999";let a=null,c=()=>{r.remove(),document.removeEventListener("mousedown",l,!0),document.removeEventListener("keydown",p,!0),this.tinyClosePopover===c&&(this.tinyClosePopover=null)},l=h=>{!r.contains(h.target)&&h.target!==t&&!t.contains(h.target)&&c()},p=h=>{h.key==="Escape"?(h.preventDefault(),h.stopPropagation(),c()):h.key==="Enter"&&a&&(h.preventDefault(),h.stopPropagation(),a())};this.tinyClosePopover=c,li(r,{seedH:o,seedM:s,seedPeriod:n,close:c,setOnEnter:h=>{a=h},onFinalize:h=>{e.value=`${String(h.hours24).padStart(2,"0")}:${String(h.minutes).padStart(2,"0")}`}});let g=t.getBoundingClientRect();r.style.left=`${Math.max(8,Math.min(g.left,window.innerWidth-220))}px`,r.style.top=`${g.bottom+4}px`,setTimeout(()=>{document.addEventListener("mousedown",l,!0),document.addEventListener("keydown",p,!0)},0)}startOfTodayLocal(){let t=new Date;return t.setHours(0,0,0,0),t}toDateValue(t){let e=t.getFullYear(),i=String(t.getMonth()+1).padStart(2,"0"),s=String(t.getDate()).padStart(2,"0");return`${e}-${i}-${s}`}toTimeValue(t){let e=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0");return`${e}:${i}`}},Ae=class Ae extends ct.Modal{constructor(t,e,i,s=null,n){super(t);this.service=e;this.openLog=i;this.currentAuthorId=s;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 i=t.createEl("button",{text:"Open log"});i.title="Open the per-folder Stashpad log for the most recent notification's folder.",i.onclick=()=>{let s=this.records.find(n=>!!n.folder);this.openLog?.(s?.folder)}}let e=t.createEl("button",{cls:"mod-warning",text:"Clear history"});e.onclick=()=>{new vt(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",i=>{i&&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 s of this.records)s.authorId&&s.authorId!==this.currentAuthorId&&e.add(s.authorId);if(e.size>0){let s=t.createEl("option",{text:"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"});s.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 i of t.affectedAuthorIds??[])if(i&&i!==e)return!0;if(!this.getNoteAuthorIds)return!1;for(let i of t.affectedIds){let s=this.getNoteAuthorIds(i);for(let n of s)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 i=[...e.entries()].sort((n,o)=>o[1]-n[1]||n[0].localeCompare(o[0])),s=t.createEl("option",{text:`All categories (${this.records.length})`});s.value="";for(let[n,o]of i){let r=t.createEl("option",{text:`${n} (${o})`});r.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(Ae.PAGE)}}appendMore(t){if(!this.listEl)return;let e=Math.min(this.visible.length,this.shownCount+t);for(let i=this.shownCount;i0){let c=i.createDiv({cls:"stashpad-notif-actions-snapshot"});for(let l of e.actionLabels){let p=c.createSpan({cls:"stashpad-notif-action-chip"});p.setText(l),p.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(Ae.PAGE,t)} more`});if(e.onclick=()=>{this.appendMore(Ae.PAGE),this.renderFooter()},t>Ae.PAGE){let i=this.footerEl.createEl("button",{text:`Load all (${t})`});i.onclick=()=>{this.appendMore(t),this.renderFooter()}}}};Ae.PAGE=100;Ke=Ae,rs=class extends ct.Modal{constructor(t,e){super(t);this.entries=e}onOpen(){if(this.contentEl.empty(),this.titleEl.setText("Stashpad import log"),this.entries.length===0){this.contentEl.createDiv({cls:"stashpad-log-empty",text:"Nothing imported yet."});return}let t=this.contentEl.createDiv({cls:"stashpad-import-log-list"});for(let e of this.entries){let i=t.createDiv({cls:"stashpad-import-log-row"}),s=(0,ct.moment)(e.ts).format("YYYY-MM-DD HH:mm");i.createSpan({cls:"stashpad-import-log-when",text:s});let n=e.kind==="folder"?"folder":e.kind==="md"?"note":"file";i.createSpan({cls:`stashpad-import-log-kind is-${e.kind}`,text:n}),i.createSpan({cls:"stashpad-import-log-name",text:e.originalName});let o=[e.folder.split("/").pop()||e.folder];e.notePaths.length>1&&o.push(`${e.notePaths.length} notes`),i.createSpan({cls:"stashpad-import-log-meta",text:o.join(" \xB7 ")})}}onClose(){this.contentEl.empty()}},Ye=class extends ct.Modal{constructor(t,e,i){super(t);this.message=e;this.onChoose=i;this.chose=!1}onOpen(){this.modalEl?.addClass("stashpad-compact-modal"),this.contentEl.empty(),this.titleEl.setText("Possible duplicate import");let t=this.contentEl.createDiv({cls:"stashpad-confirm-body"});for(let o of this.message.split(` +`))t.createDiv({cls:"stashpad-confirm-line",text:o});let e=this.contentEl.createDiv({cls:"stashpad-modal-btns"}),i=e.createEl("button",{text:"Skip duplicates"});i.onclick=()=>{this.chose=!0,this.close(),this.onChoose("skip")};let s=e.createEl("button",{text:"Replace existing"});s.onclick=()=>{this.chose=!0,this.close(),this.onChoose("replace")};let n=e.createEl("button",{cls:"mod-cta",text:"Import anyway"});n.onclick=()=>{this.chose=!0,this.close(),this.onChoose("anyway")}}onClose(){this.chose||this.onChoose("skip"),this.contentEl.empty()}}});function Dt(d,A=Pt){let t=A instanceof Set?A:new Set(A.map(o=>o.toLowerCase())),e=(d.split(/\r?\n/).find(o=>o.trim().length>0)??"").trim();if(!e)return"Untitled";let s=e.replace(/['‘-‛ʼ]/g,"").replace(/[^A-Za-z0-9\s]+/g," ").split(/\s+/).filter(o=>o&&!t.has(o.toLowerCase())).map(o=>o.length>=2&&/^[A-Z0-9]+$/.test(o)?o:o.charAt(0).toUpperCase()+o.slice(1).toLowerCase()),n="";for(let o of s){let r=n?`${n}-${o}`:o;if(r.length>50)break;n=r}return n||"Untitled"}function bt(d,A){return`${d}-${A}.md`}function Ce(d){let A=d.match(/-([a-z0-9]{4,12})$/);return A?A[1]:null}var Pt,Be=se(()=>{"use strict";Pt=["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 Bi={};ri(Bi,{JdBuildConfirmModal:()=>We,buildJdIndexNotes:()=>ls,buildJdIndexPreview:()=>fi,buildJdPreviewNotice:()=>Ci,scanForJdNotes:()=>me});function cs(d,A){if(/^\d+-\d+$/.test(d))return null;if(d.includes(".")){let e=d.split(".").slice(0,-1).join(".");return A.has(e)?e:cs(e,A)}if(/^\d+$/.test(d)){let t=parseInt(d,10);for(let e of A){let i=e.match(/^(\d+)-(\d+)$/);if(!i)continue;let s=parseInt(i[1],10),n=parseInt(i[2],10);if(t>=s&&t<=n)return e}return null}return null}function me(d,A,t){let e=d.vault.getMarkdownFiles(),i=wo(e,t),s=t.jdIndexIncludeStashpadFolders===!0,n=s?new Set:new Set(A.discoverStashpadFolders()),o=h=>s?!1:Array.from(n).some(I=>h===I||h.startsWith(I+"/")),r=[],a=[],c=[];for(let h of i){let I=h.parent?.path?.replace(/\/+$/,"")??"";if(o(I)){c.push(h);continue}let u=h.basename.match(on);u?r.push({prefix:u[1],segments:u[1].split("."),title:u[2],file:h,folder:null}):a.push(h)}let l=(t.jdIndexScope??"vault")==="folder"?(t.jdIndexScopeFolder??"").trim().replace(/^\/+|\/+$/g,""):"",p=h=>{let I=h.path.replace(/\/+$/,"");if(!(l&&I&&I!==l&&!I.startsWith(l+"/"))){if(I&&!o(I)){let u=h.name.match(on);u&&r.push({prefix:u[1],segments:u[1].split("."),title:u[2],file:null,folder:h})}}for(let u of h.children)u instanceof Ft.TFolder&&p(u)};p(d.vault.getRoot());let g=t.jdIndexSort??"natural";return r.sort((h,I)=>Fo(h,I,g)),{indexed:r,nonIndex:a,skippedStashpadNotes:c}}async function fi(d,A,t){let e=ds(t.jdIndexStashpadFolder??"");if(!e)return{...me(d,A,t),previewPath:null,error:"no-dest"};let i=me(d,A,t),s=yo(d,e);if(!s)return{...i,previewPath:null,error:"no-home"};let n=vo(i.indexed,i.nonIndex,i.skippedStashpadNotes),r=(await d.vault.read(s)).match(/^---\r?\n[\s\S]*?\r?\n---\r?\n/),a=r?`${r[0]}${n}`:n;return await d.vault.modify(s,a),{...i,previewPath:s.path}}function yo(d,A){let t=d.vault.getAbstractFileByPath(A);if(!(t instanceof Ft.TFolder))return null;for(let e of t.children){if(!(e instanceof Ft.TFile)||e.extension!=="md")continue;if((d.metadataCache.getFileCache(e)?.frontmatter??{}).id===G)return e}return null}async function ls(d,A,t){let e=ds(t.jdIndexStashpadFolder??"");if(!e)return{created:0,updated:0,skipped:0,destFolder:"",error:"no-dest"};if(!new Set(A.discoverStashpadFolders()).has(e))return{created:0,updated:0,skipped:0,destFolder:e,error:"dest-not-stashpad"};let s=me(d,A,t),n=new Map;for(let f of s.indexed)n.set(f.prefix,f);for(let f of s.indexed)if(f.prefix.includes("."))for(let C=1;C{a.push(f);for(let C of r.get(f)??[])c(C)};for(let f of o)c(f);let l=new Map,p=d.vault.getAbstractFileByPath(e);if(p instanceof Ft.TFolder)for(let f of p.children){if(!(f instanceof Ft.TFile)||f.extension!=="md")continue;let C=d.metadataCache.getFileCache(f)?.frontmatter??{};typeof C.jdPrefix=="string"&&l.set(C.jdPrefix,f)}let g=new Map,h=0,I=0,u=0;for(let f of a){let C=n.get(f)??null,m=cs(f,new Set(n.keys())),E=m?g.get(m)??G:G,y=C?`${f} ${C.title}`:f,w=C?.file?`[[${C.file.basename}]]`:"",v=w?`${w} `:`${y} -`,b=l.get(f);if(b){try{let R=null;await h.fileManager.processFrontMatter(b,M=>{M.jdPrefix=f,E&&(M.parent=E),(!M.id||typeof M.id!="string")&&(M.id=mt()),M.created||(M.created=new Date().toISOString()),M.attachments||(M.attachments=[]),R=M.id});let D=(await h.vault.read(b)).match(/^---\r?\n[\s\S]*?\r?\n---\r?\n/),m=D?`${D[0]}${k}`:k;await h.vault.modify(b,m),R&&I.set(f,R),p++}catch(R){console.error("[stashpad] buildJdIndexNotes: update failed",R),u++}continue}try{let R=mt();I.set(f,R);let w=kt(y,t.slugStopWords),D=St(w,R),m=`${e}/${D}`,M=["---",`id: ${R}`,`parent: ${E}`,`created: "${new Date().toISOString()}"`,"attachments: []",`jdPrefix: "${f}"`,"---",""].join(` -`);await h.vault.create(m,M+k),g++}catch(R){console.error("[stashpad] buildJdIndexNotes: create failed for",f,R),u++}}return{created:g,updated:p,skipped:u,destFolder:e}}function is(h){return(h||"").trim().replace(/^\/+|\/+$/g,"")}function no(h,A){if((A.jdIndexScope??"vault")==="vault")return h;let t=is(A.jdIndexScopeFolder??"");return t?h.filter(e=>{let i=e.parent?.path?.replace(/\/+$/,"")??"";return i===t||i.startsWith(t+"/")}):h}function oo(h,A,t){if(t==="created"){let e=h.file.stat?.ctime??0,i=A.file.stat?.ctime??0;if(e!==i)return e-i}return Os(h.segments,A.segments)}function Ks(h,A){let t=h.match(/^(\d+)-(\d+)$/),e=A.match(/^(\d+)-(\d+)$/),i=t?[t[1]]:h.split("."),s=e?[e[1]]:A.split(".");return Os(i,s)}function Os(h,A){let t=Math.min(h.length,A.length);for(let e=0;e{s.set(o,a);for(let r of e.get(o)??[])n(r,a+1)};for(let o of i)n(o,0);return{roots:i,childrenOf:e,depthOf:s}}function ao(h,A,t){let e=[],i=s=>"#".repeat(Math.min(s+1,6));if(e.push("# Indexed"),e.push(""),h.length===0){let s=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(s)}else{let s=new Map;for(let c of h)s.set(c.prefix,c);for(let c of h)if(c.prefix.includes("."))for(let l=1;l{let l=s.get(c),d=a.get(c)??0,I=" ".repeat(d),g=i(d),p=l?.folder?` ${l.title} _(folder)_`:(l?.file,"");l?.file?e.push(`${I}- ${g} [[${l.file.basename}|${l.prefix} ${l.title}]]`):l?.folder?e.push(`${I}- ${g} ${l.prefix}${p}`):e.push(`${I}- ${g} ${c}`);for(let u of o.get(c)??[])r(u)};for(let c of n)r(c)}if(A.length>0){e.push(""),e.push(`# Non-indexed (${A.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 s of A)e.push(`- # [[${s.basename}]] \xB7 \`${s.path}\``)}if(t.length>0){let s=new Map;for(let o of t){let a=o.parent?.path?.replace(/\/+$/,"")??"";s.set(a,(s.get(a)??0)+1)}let n=Array.from(s.entries()).sort((o,a)=>o[0].localeCompare(a[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[o,a]of n)e.push(`- # All ${a} file${a===1?"":"s"} in \`${o||"(vault root)"}\``)}return e.join(` +`,D=l.get(f);if(D){try{let L=null;await d.fileManager.processFrontMatter(D,H=>{H.jdPrefix=f,E&&(H.parent=E),(!H.id||typeof H.id!="string")&&(H.id=Et()),H.created||(H.created=new Date().toISOString()),H.attachments||(H.attachments=[]),L=H.id});let b=(await d.vault.read(D)).match(/^---\r?\n[\s\S]*?\r?\n---\r?\n/),Q=b?`${b[0]}${v}`:v;await d.vault.modify(D,Q),L&&g.set(f,L),I++}catch(L){console.error("[stashpad] buildJdIndexNotes: update failed",L),u++}continue}try{let L=Et();g.set(f,L);let S=Dt(y,t.slugStopWords),b=bt(S,L),Q=`${e}/${b}`,H=["---",`id: ${L}`,`parent: ${E}`,`created: "${new Date().toISOString()}"`,"attachments: []",`jdPrefix: "${f}"`,"---",""].join(` +`);await d.vault.create(Q,H+v),h++}catch(L){console.error("[stashpad] buildJdIndexNotes: create failed for",f,L),u++}}return{created:h,updated:I,skipped:u,destFolder:e}}function ds(d){return(d||"").trim().replace(/^\/+|\/+$/g,"")}function wo(d,A){if((A.jdIndexScope??"vault")==="vault")return d;let t=ds(A.jdIndexScopeFolder??"");return t?d.filter(e=>{let i=e.parent?.path?.replace(/\/+$/,"")??"";return i===t||i.startsWith(t+"/")}):d}function Fo(d,A,t){if(t==="created"){let e=d.file.stat?.ctime??0,i=A.file.stat?.ctime??0;if(e!==i)return e-i}return rn(d.segments,A.segments)}function an(d,A){let t=d.match(/^(\d+)-(\d+)$/),e=A.match(/^(\d+)-(\d+)$/),i=t?[t[1]]:d.split("."),s=e?[e[1]]:A.split(".");return rn(i,s)}function rn(d,A){let t=Math.min(d.length,A.length);for(let e=0;e<t;e++){let i=d[e],s=A[e],n=/^\d+$/.test(i),o=/^\d+$/.test(s);if(n&&o){let r=parseInt(i,10)-parseInt(s,10);if(r!==0)return r}else{if(n&&!o)return-1;if(!n&&o)return 1;{let r=i.localeCompare(s,void 0,{numeric:!0,sensitivity:"base"});if(r!==0)return r}}}return d.length-A.length}function An(d){let A=new Set(d.keys()),t=new Map,e=new Map;for(let o of A){let r=cs(o,A);if(t.set(o,r),r!==null){let a=e.get(r)??[];a.push(o),e.set(r,a)}}let i=[];for(let o of A)t.get(o)===null&&i.push(o);i.sort(an);for(let o of e.values())o.sort(an);let s=new Map,n=(o,r)=>{s.set(o,r);for(let a of e.get(o)??[])n(a,r+1)};for(let o of i)n(o,0);return{roots:i,childrenOf:e,depthOf:s}}function vo(d,A,t){let e=[],i=s=>"#".repeat(Math.min(s+1,6));if(e.push("# Indexed"),e.push(""),d.length===0){let s=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(s)}else{let s=new Map;for(let c of d)s.set(c.prefix,c);for(let c of d)if(c.prefix.includes("."))for(let l=1;l<c.segments.length;l++){let p=c.segments.slice(0,l).join(".");s.has(p)||s.set(p,null)}let{roots:n,childrenOf:o,depthOf:r}=An(s),a=c=>{let l=s.get(c),p=r.get(c)??0,g=" ".repeat(p),h=i(p),I=l?.folder?` ${l.title} _(folder)_`:(l?.file,"");l?.file?e.push(`${g}- ${h} [[${l.file.basename}|${l.prefix} ${l.title}]]`):l?.folder?e.push(`${g}- ${h} ${l.prefix}${I}`):e.push(`${g}- ${h} ${c}`);for(let u of o.get(c)??[])a(u)};for(let c of n)a(c)}if(A.length>0){e.push(""),e.push(`# Non-indexed (${A.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 s of A)e.push(`- # [[${s.basename}]] \xB7 \`${s.path}\``)}if(t.length>0){let s=new Map;for(let o of t){let r=o.parent?.path?.replace(/\/+$/,"")??"";s.set(r,(s.get(r)??0)+1)}let n=Array.from(s.entries()).sort((o,r)=>o[0].localeCompare(r[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[o,r]of n)e.push(`- # All ${r} file${r===1?"":"s"} in \`${o||"(vault root)"}\``)}return e.join(` `)+` -`}function li(h,A){let t=document.createDocumentFragment(),e=t.createEl("div",{text:"Home note updated"});e.style.fontWeight="600",e.style.marginBottom="6px";let i=t.createEl("ul");i.style.margin="0 0 8px 0",i.style.paddingLeft="18px",i.createEl("li",{text:`${A.indexed.length} indexed`}),i.createEl("li",{text:`${A.nonIndex.length+A.skippedStashpadNotes.length} excluded`});let s=t.createEl("button",{text:"Open",cls:"mod-cta"});s.style.padding="2px 10px",s.style.fontSize="var(--font-ui-smaller)";let n;return s.onclick=async o=>{if(o.stopPropagation(),A.previewPath){let a=h.vault.getAbstractFileByPath(A.previewPath);a instanceof wt.TFile&&await h.workspace.getLeaf("tab").openFile(a)}n?.hide()},n=new wt.Notice(t,0),n}var wt,qs,Oe,Ye=le(()=>{"use strict";wt=require("obsidian");Tt();ue();yt();qs=/^(\d+-\d+|\d+|[A-Za-z0-9]+(?:\.[A-Za-z0-9]+)+)\s+(.+)$/;Oe=class extends wt.Modal{constructor(t,e,i,s,n){super(t);this.plugin=e;this.settings=i;this.indexedCount=s;this.onBuild=n;this.LARGE_BUILD=50;this.previewRan=!1;this.previewPath=null}onOpen(){let{contentEl:t,titleEl:e}=this,i=!this.settings.jdIndexHasBuilt,s=this.indexedCount>this.LARGE_BUILD;e.setText(i?"Build JD index \u2014 first time?":"Build JD index");let n=this.settings.jdIndexStashpadFolder,o=t.createEl("p"),a=`${this.indexedCount} note${this.indexedCount===1?"":"s"}`;i?(o.appendText(`Stashpad is about to create ${a} (plus synthetic parents as needed) inside "`),o.createEl("code",{text:n}),o.appendText('". Existing notes with the same '),o.createEl("code",{text:"jdPrefix"}),o.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.")):s?(o.appendText(`You're about to create ${this.indexedCount} notes in "`),o.createEl("code",{text:n}),o.appendText(`". That's a big batch \u2014 if anything looks off, Preview the single-file output first.`)):(o.appendText('Build the JD index into "'),o.createEl("code",{text:n}),o.appendText(`"? Stashpad will create / update ${a}. Existing notes with matching `),o.createEl("code",{text:"jdPrefix"}),o.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 r=new wt.Setting(t);(i||s)&&r.addButton(c=>{c.setButtonText(this.previewRan?"Re-run preview":"Run preview first"),c.setCta(),c.onClick(async()=>{try{let l=await ci(this.app,this.plugin,this.settings);if(l.error==="no-dest"){new wt.Notice("Set a Designated Stashpad folder for Index first.",5e3),this.close();return}if(l.error==="no-home"){new wt.Notice(`"${this.settings.jdIndexStashpadFolder}" has no Stashpad home note. Open the folder in Stashpad first.`,7e3),this.close();return}this.previewRan=!0,this.previewPath=l.previewPath,li(this.app,l),this.contentEl.empty(),this.titleEl.empty(),this.onOpen()}catch(l){new wt.Notice(`Preview failed: ${l?.message??l}`,8e3)}})}),r.addButton(c=>{c.setButtonText(i?"Build anyway":"Build"),!i&&!s&&c.setCta(),c.onClick(async()=>{this.close(),await this.onBuild()})}),r.addButton(c=>{c.setButtonText("Cancel"),c.onClick(()=>this.close())})}onClose(){this.contentEl.empty()}}});var un=$n((pn,ps)=>{(function(h){typeof pn=="object"&&typeof ps<"u"?ps.exports=h():typeof define=="function"&&define.amd?define([],h):(typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:this).JSZip=h()})(function(){return function h(A,t,e){function i(o,a){if(!t[o]){if(!A[o]){var r=typeof require=="function"&&require;if(!a&&r)return r(o,!0);if(s)return s(o,!0);var c=new Error("Cannot find module '"+o+"'");throw c.code="MODULE_NOT_FOUND",c}var l=t[o]={exports:{}};A[o][0].call(l.exports,function(d){var I=A[o][1][d];return i(I||d)},l,l.exports,h,A,t,e)}return t[o].exports}for(var s=typeof require=="function"&&require,n=0;n<e.length;n++)i(e[n]);return i}({1:[function(h,A,t){"use strict";var e=h("./utils"),i=h("./support"),s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";t.encode=function(n){for(var o,a,r,c,l,d,I,g=[],p=0,u=n.length,f=u,B=e.getTypeOf(n)!=="string";p<n.length;)f=u-p,r=B?(o=n[p++],a=p<u?n[p++]:0,p<u?n[p++]:0):(o=n.charCodeAt(p++),a=p<u?n.charCodeAt(p++):0,p<u?n.charCodeAt(p++):0),c=o>>2,l=(3&o)<<4|a>>4,d=1<f?(15&a)<<2|r>>6:64,I=2<f?63&r:64,g.push(s.charAt(c)+s.charAt(l)+s.charAt(d)+s.charAt(I));return g.join("")},t.decode=function(n){var o,a,r,c,l,d,I=0,g=0,p="data:";if(n.substr(0,p.length)===p)throw new Error("Invalid base64 input, it looks like a data url.");var u,f=3*(n=n.replace(/[^A-Za-z0-9+/=]/g,"")).length/4;if(n.charAt(n.length-1)===s.charAt(64)&&f--,n.charAt(n.length-2)===s.charAt(64)&&f--,f%1!=0)throw new Error("Invalid base64 input, bad content length.");for(u=i.uint8array?new Uint8Array(0|f):new Array(0|f);I<n.length;)o=s.indexOf(n.charAt(I++))<<2|(c=s.indexOf(n.charAt(I++)))>>4,a=(15&c)<<4|(l=s.indexOf(n.charAt(I++)))>>2,r=(3&l)<<6|(d=s.indexOf(n.charAt(I++))),u[g++]=o,l!==64&&(u[g++]=a),d!==64&&(u[g++]=r);return u}},{"./support":30,"./utils":32}],2:[function(h,A,t){"use strict";var e=h("./external"),i=h("./stream/DataWorker"),s=h("./stream/Crc32Probe"),n=h("./stream/DataLengthProbe");function o(a,r,c,l,d){this.compressedSize=a,this.uncompressedSize=r,this.crc32=c,this.compression=l,this.compressedContent=d}o.prototype={getContentWorker:function(){var a=new i(e.Promise.resolve(this.compressedContent)).pipe(this.compression.uncompressWorker()).pipe(new n("data_length")),r=this;return a.on("end",function(){if(this.streamInfo.data_length!==r.uncompressedSize)throw new Error("Bug : uncompressed data size mismatch")}),a},getCompressedWorker:function(){return new i(e.Promise.resolve(this.compressedContent)).withStreamInfo("compressedSize",this.compressedSize).withStreamInfo("uncompressedSize",this.uncompressedSize).withStreamInfo("crc32",this.crc32).withStreamInfo("compression",this.compression)}},o.createWorkerFrom=function(a,r,c){return a.pipe(new s).pipe(new n("uncompressedSize")).pipe(r.compressWorker(c)).pipe(new n("compressedSize")).withStreamInfo("compression",r)},A.exports=o},{"./external":6,"./stream/Crc32Probe":25,"./stream/DataLengthProbe":26,"./stream/DataWorker":27}],3:[function(h,A,t){"use strict";var e=h("./stream/GenericWorker");t.STORE={magic:"\0\0",compressWorker:function(){return new e("STORE compression")},uncompressWorker:function(){return new e("STORE decompression")}},t.DEFLATE=h("./flate")},{"./flate":7,"./stream/GenericWorker":28}],4:[function(h,A,t){"use strict";var e=h("./utils"),i=function(){for(var s,n=[],o=0;o<256;o++){s=o;for(var a=0;a<8;a++)s=1&s?3988292384^s>>>1:s>>>1;n[o]=s}return n}();A.exports=function(s,n){return s!==void 0&&s.length?e.getTypeOf(s)!=="string"?function(o,a,r,c){var l=i,d=c+r;o^=-1;for(var I=c;I<d;I++)o=o>>>8^l[255&(o^a[I])];return-1^o}(0|n,s,s.length,0):function(o,a,r,c){var l=i,d=c+r;o^=-1;for(var I=c;I<d;I++)o=o>>>8^l[255&(o^a.charCodeAt(I))];return-1^o}(0|n,s,s.length,0):0}},{"./utils":32}],5:[function(h,A,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(h,A,t){"use strict";var e=null;e=typeof Promise<"u"?Promise:h("lie"),A.exports={Promise:e}},{lie:37}],7:[function(h,A,t){"use strict";var e=typeof Uint8Array<"u"&&typeof Uint16Array<"u"&&typeof Uint32Array<"u",i=h("pako"),s=h("./utils"),n=h("./stream/GenericWorker"),o=e?"uint8array":"array";function a(r,c){n.call(this,"FlateWorker/"+r),this._pako=null,this._pakoAction=r,this._pakoOptions=c,this.meta={}}t.magic="\b\0",s.inherits(a,n),a.prototype.processChunk=function(r){this.meta=r.meta,this._pako===null&&this._createPako(),this._pako.push(s.transformTo(o,r.data),!1)},a.prototype.flush=function(){n.prototype.flush.call(this),this._pako===null&&this._createPako(),this._pako.push([],!0)},a.prototype.cleanUp=function(){n.prototype.cleanUp.call(this),this._pako=null},a.prototype._createPako=function(){this._pako=new i[this._pakoAction]({raw:!0,level:this._pakoOptions.level||-1});var r=this;this._pako.onData=function(c){r.push({data:c,meta:r.meta})}},t.compressWorker=function(r){return new a("Deflate",r)},t.uncompressWorker=function(){return new a("Inflate",{})}},{"./stream/GenericWorker":28,"./utils":32,pako:38}],8:[function(h,A,t){"use strict";function e(l,d){var I,g="";for(I=0;I<d;I++)g+=String.fromCharCode(255&l),l>>>=8;return g}function i(l,d,I,g,p,u){var f,B,Q=l.file,E=l.compression,y=u!==o.utf8encode,v=s.transformTo("string",u(Q.name)),k=s.transformTo("string",o.utf8encode(Q.name)),b=Q.comment,R=s.transformTo("string",u(b)),w=s.transformTo("string",o.utf8encode(b)),D=k.length!==Q.name.length,m=w.length!==b.length,M="",_="",O="",J=Q.dir,q=Q.date,j={crc32:0,compressedSize:0,uncompressedSize:0};d&&!I||(j.crc32=l.crc32,j.compressedSize=l.compressedSize,j.uncompressedSize=l.uncompressedSize);var H=0;d&&(H|=8),y||!D&&!m||(H|=2048);var N=0,$=0;J&&(N|=16),p==="UNIX"?($=798,N|=function(z,ct){var gt=z;return z||(gt=ct?16893:33204),(65535>)<<16}(Q.unixPermissions,J)):($=20,N|=function(z){return 63&(z||0)}(Q.dosPermissions)),f=q.getUTCHours(),f<<=6,f|=q.getUTCMinutes(),f<<=5,f|=q.getUTCSeconds()/2,B=q.getUTCFullYear()-1980,B<<=4,B|=q.getUTCMonth()+1,B<<=5,B|=q.getUTCDate(),D&&(_=e(1,1)+e(a(v),4)+k,M+="up"+e(_.length,2)+_),m&&(O=e(1,1)+e(a(R),4)+w,M+="uc"+e(O.length,2)+O);var V="";return V+=` -\0`,V+=e(H,2),V+=E.magic,V+=e(f,2),V+=e(B,2),V+=e(j.crc32,4),V+=e(j.compressedSize,4),V+=e(j.uncompressedSize,4),V+=e(v.length,2),V+=e(M.length,2),{fileRecord:r.LOCAL_FILE_HEADER+V+v+M,dirRecord:r.CENTRAL_FILE_HEADER+e($,2)+V+e(R.length,2)+"\0\0\0\0"+e(N,4)+e(g,4)+v+M+R}}var s=h("../utils"),n=h("../stream/GenericWorker"),o=h("../utf8"),a=h("../crc32"),r=h("../signature");function c(l,d,I,g){n.call(this,"ZipFileWorker"),this.bytesWritten=0,this.zipComment=d,this.zipPlatform=I,this.encodeFileName=g,this.streamFiles=l,this.accumulate=!1,this.contentBuffer=[],this.dirRecords=[],this.currentSourceOffset=0,this.entriesCount=0,this.currentFile=null,this._sources=[]}s.inherits(c,n),c.prototype.push=function(l){var d=l.meta.percent||0,I=this.entriesCount,g=this._sources.length;this.accumulate?this.contentBuffer.push(l):(this.bytesWritten+=l.data.length,n.prototype.push.call(this,{data:l.data,meta:{currentFile:this.currentFile,percent:I?(d+100*(I-g-1))/I:100}}))},c.prototype.openedSource=function(l){this.currentSourceOffset=this.bytesWritten,this.currentFile=l.file.name;var d=this.streamFiles&&!l.file.dir;if(d){var I=i(l,d,!1,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);this.push({data:I.fileRecord,meta:{percent:0}})}else this.accumulate=!0},c.prototype.closedSource=function(l){this.accumulate=!1;var d=this.streamFiles&&!l.file.dir,I=i(l,d,!0,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);if(this.dirRecords.push(I.dirRecord),d)this.push({data:function(g){return r.DATA_DESCRIPTOR+e(g.crc32,4)+e(g.compressedSize,4)+e(g.uncompressedSize,4)}(l),meta:{percent:100}});else for(this.push({data:I.fileRecord,meta:{percent:0}});this.contentBuffer.length;)this.push(this.contentBuffer.shift());this.currentFile=null},c.prototype.flush=function(){for(var l=this.bytesWritten,d=0;d<this.dirRecords.length;d++)this.push({data:this.dirRecords[d],meta:{percent:100}});var I=this.bytesWritten-l,g=function(p,u,f,B,Q){var E=s.transformTo("string",Q(B));return r.CENTRAL_DIRECTORY_END+"\0\0\0\0"+e(p,2)+e(p,2)+e(u,4)+e(f,4)+e(E.length,2)+E}(this.dirRecords.length,I,l,this.zipComment,this.encodeFileName);this.push({data:g,meta:{percent:100}})},c.prototype.prepareNextSource=function(){this.previous=this._sources.shift(),this.openedSource(this.previous.streamInfo),this.isPaused?this.previous.pause():this.previous.resume()},c.prototype.registerPrevious=function(l){this._sources.push(l);var d=this;return l.on("data",function(I){d.processChunk(I)}),l.on("end",function(){d.closedSource(d.previous.streamInfo),d._sources.length?d.prepareNextSource():d.end()}),l.on("error",function(I){d.error(I)}),this},c.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))},c.prototype.error=function(l){var d=this._sources;if(!n.prototype.error.call(this,l))return!1;for(var I=0;I<d.length;I++)try{d[I].error(l)}catch{}return!0},c.prototype.lock=function(){n.prototype.lock.call(this);for(var l=this._sources,d=0;d<l.length;d++)l[d].lock()},A.exports=c},{"../crc32":4,"../signature":23,"../stream/GenericWorker":28,"../utf8":31,"../utils":32}],9:[function(h,A,t){"use strict";var e=h("../compressions"),i=h("./ZipFileWorker");t.generateWorker=function(s,n,o){var a=new i(n.streamFiles,o,n.platform,n.encodeFileName),r=0;try{s.forEach(function(c,l){r++;var d=function(u,f){var B=u||f,Q=e[B];if(!Q)throw new Error(B+" is not a valid compression method !");return Q}(l.options.compression,n.compression),I=l.options.compressionOptions||n.compressionOptions||{},g=l.dir,p=l.date;l._compressWorker(d,I).withStreamInfo("file",{name:c,dir:g,date:p,comment:l.comment||"",unixPermissions:l.unixPermissions,dosPermissions:l.dosPermissions}).pipe(a)}),a.entriesCount=r}catch(c){a.error(c)}return a}},{"../compressions":3,"./ZipFileWorker":8}],10:[function(h,A,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 i=new e;for(var s in this)typeof this[s]!="function"&&(i[s]=this[s]);return i}}(e.prototype=h("./object")).loadAsync=h("./load"),e.support=h("./support"),e.defaults=h("./defaults"),e.version="3.10.1",e.loadAsync=function(i,s){return new e().loadAsync(i,s)},e.external=h("./external"),A.exports=e},{"./defaults":5,"./external":6,"./load":11,"./object":15,"./support":30}],11:[function(h,A,t){"use strict";var e=h("./utils"),i=h("./external"),s=h("./utf8"),n=h("./zipEntries"),o=h("./stream/Crc32Probe"),a=h("./nodejsUtils");function r(c){return new i.Promise(function(l,d){var I=c.decompressed.getContentWorker().pipe(new o);I.on("error",function(g){d(g)}).on("end",function(){I.streamInfo.crc32!==c.decompressed.crc32?d(new Error("Corrupted zip : CRC32 mismatch")):l()}).resume()})}A.exports=function(c,l){var d=this;return l=e.extend(l||{},{base64:!1,checkCRC32:!1,optimizedBinaryString:!1,createFolders:!1,decodeFileName:s.utf8decode}),a.isNode&&a.isStream(c)?i.Promise.reject(new Error("JSZip can't accept a stream when loading a zip file.")):e.prepareContent("the loaded zip file",c,!0,l.optimizedBinaryString,l.base64).then(function(I){var g=new n(l);return g.load(I),g}).then(function(I){var g=[i.Promise.resolve(I)],p=I.files;if(l.checkCRC32)for(var u=0;u<p.length;u++)g.push(r(p[u]));return i.Promise.all(g)}).then(function(I){for(var g=I.shift(),p=g.files,u=0;u<p.length;u++){var f=p[u],B=f.fileNameStr,Q=e.resolve(f.fileNameStr);d.file(Q,f.decompressed,{binary:!0,optimizedBinaryString:!0,date:f.date,dir:f.dir,comment:f.fileCommentStr.length?f.fileCommentStr:null,unixPermissions:f.unixPermissions,dosPermissions:f.dosPermissions,createFolders:l.createFolders}),f.dir||(d.file(Q).unsafeOriginalName=B)}return g.zipComment.length&&(d.comment=g.zipComment),d})}},{"./external":6,"./nodejsUtils":14,"./stream/Crc32Probe":25,"./utf8":31,"./utils":32,"./zipEntries":33}],12:[function(h,A,t){"use strict";var e=h("../utils"),i=h("../stream/GenericWorker");function s(n,o){i.call(this,"Nodejs stream input adapter for "+n),this._upstreamEnded=!1,this._bindStream(o)}e.inherits(s,i),s.prototype._bindStream=function(n){var o=this;(this._stream=n).pause(),n.on("data",function(a){o.push({data:a,meta:{percent:0}})}).on("error",function(a){o.isPaused?this.generatedError=a:o.error(a)}).on("end",function(){o.isPaused?o._upstreamEnded=!0:o.end()})},s.prototype.pause=function(){return!!i.prototype.pause.call(this)&&(this._stream.pause(),!0)},s.prototype.resume=function(){return!!i.prototype.resume.call(this)&&(this._upstreamEnded?this.end():this._stream.resume(),!0)},A.exports=s},{"../stream/GenericWorker":28,"../utils":32}],13:[function(h,A,t){"use strict";var e=h("readable-stream").Readable;function i(s,n,o){e.call(this,n),this._helper=s;var a=this;s.on("data",function(r,c){a.push(r)||a._helper.pause(),o&&o(c)}).on("error",function(r){a.emit("error",r)}).on("end",function(){a.push(null)})}h("../utils").inherits(i,e),i.prototype._read=function(){this._helper.resume()},A.exports=i},{"../utils":32,"readable-stream":16}],14:[function(h,A,t){"use strict";A.exports={isNode:typeof Buffer<"u",newBufferFrom:function(e,i){if(Buffer.from&&Buffer.from!==Uint8Array.from)return Buffer.from(e,i);if(typeof e=="number")throw new Error('The "data" argument must not be a number');return new Buffer(e,i)},allocBuffer:function(e){if(Buffer.alloc)return Buffer.alloc(e);var i=new Buffer(e);return i.fill(0),i},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(h,A,t){"use strict";function e(Q,E,y){var v,k=s.getTypeOf(E),b=s.extend(y||{},a);b.date=b.date||new Date,b.compression!==null&&(b.compression=b.compression.toUpperCase()),typeof b.unixPermissions=="string"&&(b.unixPermissions=parseInt(b.unixPermissions,8)),b.unixPermissions&&16384&b.unixPermissions&&(b.dir=!0),b.dosPermissions&&16&b.dosPermissions&&(b.dir=!0),b.dir&&(Q=p(Q)),b.createFolders&&(v=g(Q))&&u.call(this,v,!0);var R=k==="string"&&b.binary===!1&&b.base64===!1;y&&y.binary!==void 0||(b.binary=!R),(E instanceof r&&E.uncompressedSize===0||b.dir||!E||E.length===0)&&(b.base64=!1,b.binary=!0,E="",b.compression="STORE",k="string");var w=null;w=E instanceof r||E instanceof n?E:d.isNode&&d.isStream(E)?new I(Q,E):s.prepareContent(Q,E,b.binary,b.optimizedBinaryString,b.base64);var D=new c(Q,w,b);this.files[Q]=D}var i=h("./utf8"),s=h("./utils"),n=h("./stream/GenericWorker"),o=h("./stream/StreamHelper"),a=h("./defaults"),r=h("./compressedObject"),c=h("./zipObject"),l=h("./generate"),d=h("./nodejsUtils"),I=h("./nodejs/NodejsStreamInputAdapter"),g=function(Q){Q.slice(-1)==="/"&&(Q=Q.substring(0,Q.length-1));var E=Q.lastIndexOf("/");return 0<E?Q.substring(0,E):""},p=function(Q){return Q.slice(-1)!=="/"&&(Q+="/"),Q},u=function(Q,E){return E=E!==void 0?E:a.createFolders,Q=p(Q),this.files[Q]||e.call(this,Q,null,{dir:!0,createFolders:E}),this.files[Q]};function f(Q){return Object.prototype.toString.call(Q)==="[object RegExp]"}var B={load:function(){throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.")},forEach:function(Q){var E,y,v;for(E in this.files)v=this.files[E],(y=E.slice(this.root.length,E.length))&&E.slice(0,this.root.length)===this.root&&Q(y,v)},filter:function(Q){var E=[];return this.forEach(function(y,v){Q(y,v)&&E.push(v)}),E},file:function(Q,E,y){if(arguments.length!==1)return Q=this.root+Q,e.call(this,Q,E,y),this;if(f(Q)){var v=Q;return this.filter(function(b,R){return!R.dir&&v.test(b)})}var k=this.files[this.root+Q];return k&&!k.dir?k:null},folder:function(Q){if(!Q)return this;if(f(Q))return this.filter(function(k,b){return b.dir&&Q.test(k)});var E=this.root+Q,y=u.call(this,E),v=this.clone();return v.root=y.name,v},remove:function(Q){Q=this.root+Q;var E=this.files[Q];if(E||(Q.slice(-1)!=="/"&&(Q+="/"),E=this.files[Q]),E&&!E.dir)delete this.files[Q];else for(var y=this.filter(function(k,b){return b.name.slice(0,Q.length)===Q}),v=0;v<y.length;v++)delete this.files[y[v].name];return this},generate:function(){throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.")},generateInternalStream:function(Q){var E,y={};try{if((y=s.extend(Q||{},{streamFiles:!1,compression:"STORE",compressionOptions:null,type:"",platform:"DOS",comment:null,mimeType:"application/zip",encodeFileName:i.utf8encode})).type=y.type.toLowerCase(),y.compression=y.compression.toUpperCase(),y.type==="binarystring"&&(y.type="string"),!y.type)throw new Error("No output type specified.");s.checkSupport(y.type),y.platform!=="darwin"&&y.platform!=="freebsd"&&y.platform!=="linux"&&y.platform!=="sunos"||(y.platform="UNIX"),y.platform==="win32"&&(y.platform="DOS");var v=y.comment||this.comment||"";E=l.generateWorker(this,y,v)}catch(k){(E=new n("error")).error(k)}return new o(E,y.type||"string",y.mimeType)},generateAsync:function(Q,E){return this.generateInternalStream(Q).accumulate(E)},generateNodeStream:function(Q,E){return(Q=Q||{}).type||(Q.type="nodebuffer"),this.generateInternalStream(Q).toNodejsStream(E)}};A.exports=B},{"./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(h,A,t){"use strict";A.exports=h("stream")},{stream:void 0}],17:[function(h,A,t){"use strict";var e=h("./DataReader");function i(s){e.call(this,s);for(var n=0;n<this.data.length;n++)s[n]=255&s[n]}h("../utils").inherits(i,e),i.prototype.byteAt=function(s){return this.data[this.zero+s]},i.prototype.lastIndexOfSignature=function(s){for(var n=s.charCodeAt(0),o=s.charCodeAt(1),a=s.charCodeAt(2),r=s.charCodeAt(3),c=this.length-4;0<=c;--c)if(this.data[c]===n&&this.data[c+1]===o&&this.data[c+2]===a&&this.data[c+3]===r)return c-this.zero;return-1},i.prototype.readAndCheckSignature=function(s){var n=s.charCodeAt(0),o=s.charCodeAt(1),a=s.charCodeAt(2),r=s.charCodeAt(3),c=this.readData(4);return n===c[0]&&o===c[1]&&a===c[2]&&r===c[3]},i.prototype.readData=function(s){if(this.checkOffset(s),s===0)return[];var n=this.data.slice(this.zero+this.index,this.zero+this.index+s);return this.index+=s,n},A.exports=i},{"../utils":32,"./DataReader":18}],18:[function(h,A,t){"use strict";var e=h("../utils");function i(s){this.data=s,this.length=s.length,this.index=0,this.zero=0}i.prototype={checkOffset:function(s){this.checkIndex(this.index+s)},checkIndex:function(s){if(this.length<this.zero+s||s<0)throw new Error("End of data reached (data length = "+this.length+", asked index = "+s+"). Corrupted zip ?")},setIndex:function(s){this.checkIndex(s),this.index=s},skip:function(s){this.setIndex(this.index+s)},byteAt:function(){},readInt:function(s){var n,o=0;for(this.checkOffset(s),n=this.index+s-1;n>=this.index;n--)o=(o<<8)+this.byteAt(n);return this.index+=s,o},readString:function(s){return e.transformTo("string",this.readData(s))},readData:function(){},lastIndexOfSignature:function(){},readAndCheckSignature:function(){},readDate:function(){var s=this.readInt(4);return new Date(Date.UTC(1980+(s>>25&127),(s>>21&15)-1,s>>16&31,s>>11&31,s>>5&63,(31&s)<<1))}},A.exports=i},{"../utils":32}],19:[function(h,A,t){"use strict";var e=h("./Uint8ArrayReader");function i(s){e.call(this,s)}h("../utils").inherits(i,e),i.prototype.readData=function(s){this.checkOffset(s);var n=this.data.slice(this.zero+this.index,this.zero+this.index+s);return this.index+=s,n},A.exports=i},{"../utils":32,"./Uint8ArrayReader":21}],20:[function(h,A,t){"use strict";var e=h("./DataReader");function i(s){e.call(this,s)}h("../utils").inherits(i,e),i.prototype.byteAt=function(s){return this.data.charCodeAt(this.zero+s)},i.prototype.lastIndexOfSignature=function(s){return this.data.lastIndexOf(s)-this.zero},i.prototype.readAndCheckSignature=function(s){return s===this.readData(4)},i.prototype.readData=function(s){this.checkOffset(s);var n=this.data.slice(this.zero+this.index,this.zero+this.index+s);return this.index+=s,n},A.exports=i},{"../utils":32,"./DataReader":18}],21:[function(h,A,t){"use strict";var e=h("./ArrayReader");function i(s){e.call(this,s)}h("../utils").inherits(i,e),i.prototype.readData=function(s){if(this.checkOffset(s),s===0)return new Uint8Array(0);var n=this.data.subarray(this.zero+this.index,this.zero+this.index+s);return this.index+=s,n},A.exports=i},{"../utils":32,"./ArrayReader":17}],22:[function(h,A,t){"use strict";var e=h("../utils"),i=h("../support"),s=h("./ArrayReader"),n=h("./StringReader"),o=h("./NodeBufferReader"),a=h("./Uint8ArrayReader");A.exports=function(r){var c=e.getTypeOf(r);return e.checkSupport(c),c!=="string"||i.uint8array?c==="nodebuffer"?new o(r):i.uint8array?new a(e.transformTo("uint8array",r)):new s(e.transformTo("array",r)):new n(r)}},{"../support":30,"../utils":32,"./ArrayReader":17,"./NodeBufferReader":19,"./StringReader":20,"./Uint8ArrayReader":21}],23:[function(h,A,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(h,A,t){"use strict";var e=h("./GenericWorker"),i=h("../utils");function s(n){e.call(this,"ConvertWorker to "+n),this.destType=n}i.inherits(s,e),s.prototype.processChunk=function(n){this.push({data:i.transformTo(this.destType,n.data),meta:n.meta})},A.exports=s},{"../utils":32,"./GenericWorker":28}],25:[function(h,A,t){"use strict";var e=h("./GenericWorker"),i=h("../crc32");function s(){e.call(this,"Crc32Probe"),this.withStreamInfo("crc32",0)}h("../utils").inherits(s,e),s.prototype.processChunk=function(n){this.streamInfo.crc32=i(n.data,this.streamInfo.crc32||0),this.push(n)},A.exports=s},{"../crc32":4,"../utils":32,"./GenericWorker":28}],26:[function(h,A,t){"use strict";var e=h("../utils"),i=h("./GenericWorker");function s(n){i.call(this,"DataLengthProbe for "+n),this.propName=n,this.withStreamInfo(n,0)}e.inherits(s,i),s.prototype.processChunk=function(n){if(n){var o=this.streamInfo[this.propName]||0;this.streamInfo[this.propName]=o+n.data.length}i.prototype.processChunk.call(this,n)},A.exports=s},{"../utils":32,"./GenericWorker":28}],27:[function(h,A,t){"use strict";var e=h("../utils"),i=h("./GenericWorker");function s(n){i.call(this,"DataWorker");var o=this;this.dataIsReady=!1,this.index=0,this.max=0,this.data=null,this.type="",this._tickScheduled=!1,n.then(function(a){o.dataIsReady=!0,o.data=a,o.max=a&&a.length||0,o.type=e.getTypeOf(a),o.isPaused||o._tickAndRepeat()},function(a){o.error(a)})}e.inherits(s,i),s.prototype.cleanUp=function(){i.prototype.cleanUp.call(this),this.data=null},s.prototype.resume=function(){return!!i.prototype.resume.call(this)&&(!this._tickScheduled&&this.dataIsReady&&(this._tickScheduled=!0,e.delay(this._tickAndRepeat,[],this)),!0)},s.prototype._tickAndRepeat=function(){this._tickScheduled=!1,this.isPaused||this.isFinished||(this._tick(),this.isFinished||(e.delay(this._tickAndRepeat,[],this),this._tickScheduled=!0))},s.prototype._tick=function(){if(this.isPaused||this.isFinished)return!1;var n=null,o=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,o);break;case"uint8array":n=this.data.subarray(this.index,o);break;case"array":case"nodebuffer":n=this.data.slice(this.index,o)}return this.index=o,this.push({data:n,meta:{percent:this.max?this.index/this.max*100:0}})},A.exports=s},{"../utils":32,"./GenericWorker":28}],28:[function(h,A,t){"use strict";function e(i){this.name=i||"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(i){this.emit("data",i)},end:function(){if(this.isFinished)return!1;this.flush();try{this.emit("end"),this.cleanUp(),this.isFinished=!0}catch(i){this.emit("error",i)}return!0},error:function(i){return!this.isFinished&&(this.isPaused?this.generatedError=i:(this.isFinished=!0,this.emit("error",i),this.previous&&this.previous.error(i),this.cleanUp()),!0)},on:function(i,s){return this._listeners[i].push(s),this},cleanUp:function(){this.streamInfo=this.generatedError=this.extraStreamInfo=null,this._listeners=[]},emit:function(i,s){if(this._listeners[i])for(var n=0;n<this._listeners[i].length;n++)this._listeners[i][n].call(this,s)},pipe:function(i){return i.registerPrevious(this)},registerPrevious:function(i){if(this.isLocked)throw new Error("The stream '"+this+"' has already been used.");this.streamInfo=i.streamInfo,this.mergeStreamInfo(),this.previous=i;var s=this;return i.on("data",function(n){s.processChunk(n)}),i.on("end",function(){s.end()}),i.on("error",function(n){s.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 i=this.isPaused=!1;return this.generatedError&&(this.error(this.generatedError),i=!0),this.previous&&this.previous.resume(),!i},flush:function(){},processChunk:function(i){this.push(i)},withStreamInfo:function(i,s){return this.extraStreamInfo[i]=s,this.mergeStreamInfo(),this},mergeStreamInfo:function(){for(var i in this.extraStreamInfo)Object.prototype.hasOwnProperty.call(this.extraStreamInfo,i)&&(this.streamInfo[i]=this.extraStreamInfo[i])},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 i="Worker "+this.name;return this.previous?this.previous+" -> "+i:i}},A.exports=e},{}],29:[function(h,A,t){"use strict";var e=h("../utils"),i=h("./ConvertWorker"),s=h("./GenericWorker"),n=h("../base64"),o=h("../support"),a=h("../external"),r=null;if(o.nodestream)try{r=h("../nodejs/NodejsStreamOutputAdapter")}catch{}function c(d,I){return new a.Promise(function(g,p){var u=[],f=d._internalType,B=d._outputType,Q=d._mimeType;d.on("data",function(E,y){u.push(E),I&&I(y)}).on("error",function(E){u=[],p(E)}).on("end",function(){try{var E=function(y,v,k){switch(y){case"blob":return e.newBlob(e.transformTo("arraybuffer",v),k);case"base64":return n.encode(v);default:return e.transformTo(y,v)}}(B,function(y,v){var k,b=0,R=null,w=0;for(k=0;k<v.length;k++)w+=v[k].length;switch(y){case"string":return v.join("");case"array":return Array.prototype.concat.apply([],v);case"uint8array":for(R=new Uint8Array(w),k=0;k<v.length;k++)R.set(v[k],b),b+=v[k].length;return R;case"nodebuffer":return Buffer.concat(v);default:throw new Error("concat : unsupported type '"+y+"'")}}(f,u),Q);g(E)}catch(y){p(y)}u=[]}).resume()})}function l(d,I,g){var p=I;switch(I){case"blob":case"arraybuffer":p="uint8array";break;case"base64":p="string"}try{this._internalType=p,this._outputType=I,this._mimeType=g,e.checkSupport(p),this._worker=d.pipe(new i(p)),d.lock()}catch(u){this._worker=new s("error"),this._worker.error(u)}}l.prototype={accumulate:function(d){return c(this,d)},on:function(d,I){var g=this;return d==="data"?this._worker.on(d,function(p){I.call(g,p.data,p.meta)}):this._worker.on(d,function(){e.delay(I,arguments,g)}),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 r(this,{objectMode:this._outputType!=="nodebuffer"},d)}},A.exports=l},{"../base64":1,"../external":6,"../nodejs/NodejsStreamOutputAdapter":13,"../support":30,"../utils":32,"./ConvertWorker":24,"./GenericWorker":28}],30:[function(h,A,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 i=new(self.BlobBuilder||self.WebKitBlobBuilder||self.MozBlobBuilder||self.MSBlobBuilder);i.append(e),t.blob=i.getBlob("application/zip").size===0}catch{t.blob=!1}}}try{t.nodestream=!!h("readable-stream").Readable}catch{t.nodestream=!1}},{"readable-stream":16}],31:[function(h,A,t){"use strict";for(var e=h("./utils"),i=h("./support"),s=h("./nodejsUtils"),n=h("./stream/GenericWorker"),o=new Array(256),a=0;a<256;a++)o[a]=252<=a?6:248<=a?5:240<=a?4:224<=a?3:192<=a?2:1;o[254]=o[254]=1;function r(){n.call(this,"utf-8 decode"),this.leftOver=null}function c(){n.call(this,"utf-8 encode")}t.utf8encode=function(l){return i.nodebuffer?s.newBufferFrom(l,"utf-8"):function(d){var I,g,p,u,f,B=d.length,Q=0;for(u=0;u<B;u++)(64512&(g=d.charCodeAt(u)))==55296&&u+1<B&&(64512&(p=d.charCodeAt(u+1)))==56320&&(g=65536+(g-55296<<10)+(p-56320),u++),Q+=g<128?1:g<2048?2:g<65536?3:4;for(I=i.uint8array?new Uint8Array(Q):new Array(Q),u=f=0;f<Q;u++)(64512&(g=d.charCodeAt(u)))==55296&&u+1<B&&(64512&(p=d.charCodeAt(u+1)))==56320&&(g=65536+(g-55296<<10)+(p-56320),u++),g<128?I[f++]=g:(g<2048?I[f++]=192|g>>>6:(g<65536?I[f++]=224|g>>>12:(I[f++]=240|g>>>18,I[f++]=128|g>>>12&63),I[f++]=128|g>>>6&63),I[f++]=128|63&g);return I}(l)},t.utf8decode=function(l){return i.nodebuffer?e.transformTo("nodebuffer",l).toString("utf-8"):function(d){var I,g,p,u,f=d.length,B=new Array(2*f);for(I=g=0;I<f;)if((p=d[I++])<128)B[g++]=p;else if(4<(u=o[p]))B[g++]=65533,I+=u-1;else{for(p&=u===2?31:u===3?15:7;1<u&&I<f;)p=p<<6|63&d[I++],u--;1<u?B[g++]=65533:p<65536?B[g++]=p:(p-=65536,B[g++]=55296|p>>10&1023,B[g++]=56320|1023&p)}return B.length!==g&&(B.subarray?B=B.subarray(0,g):B.length=g),e.applyFromCharCode(B)}(l=e.transformTo(i.uint8array?"uint8array":"array",l))},e.inherits(r,n),r.prototype.processChunk=function(l){var d=e.transformTo(i.uint8array?"uint8array":"array",l.data);if(this.leftOver&&this.leftOver.length){if(i.uint8array){var I=d;(d=new Uint8Array(I.length+this.leftOver.length)).set(this.leftOver,0),d.set(I,this.leftOver.length)}else d=this.leftOver.concat(d);this.leftOver=null}var g=function(u,f){var B;for((f=f||u.length)>u.length&&(f=u.length),B=f-1;0<=B&&(192&u[B])==128;)B--;return B<0||B===0?f:B+o[u[B]]>f?B:f}(d),p=d;g!==d.length&&(i.uint8array?(p=d.subarray(0,g),this.leftOver=d.subarray(g,d.length)):(p=d.slice(0,g),this.leftOver=d.slice(g,d.length))),this.push({data:t.utf8decode(p),meta:l.meta})},r.prototype.flush=function(){this.leftOver&&this.leftOver.length&&(this.push({data:t.utf8decode(this.leftOver),meta:{}}),this.leftOver=null)},t.Utf8DecodeWorker=r,e.inherits(c,n),c.prototype.processChunk=function(l){this.push({data:t.utf8encode(l.data),meta:l.meta})},t.Utf8EncodeWorker=c},{"./nodejsUtils":14,"./stream/GenericWorker":28,"./support":30,"./utils":32}],32:[function(h,A,t){"use strict";var e=h("./support"),i=h("./base64"),s=h("./nodejsUtils"),n=h("./external");function o(I){return I}function a(I,g){for(var p=0;p<I.length;++p)g[p]=255&I.charCodeAt(p);return g}h("setimmediate"),t.newBlob=function(I,g){t.checkSupport("blob");try{return new Blob([I],{type:g})}catch{try{var p=new(self.BlobBuilder||self.WebKitBlobBuilder||self.MozBlobBuilder||self.MSBlobBuilder);return p.append(I),p.getBlob(g)}catch{throw new Error("Bug : can't construct the Blob.")}}};var r={stringifyByChunk:function(I,g,p){var u=[],f=0,B=I.length;if(B<=p)return String.fromCharCode.apply(null,I);for(;f<B;)g==="array"||g==="nodebuffer"?u.push(String.fromCharCode.apply(null,I.slice(f,Math.min(f+p,B)))):u.push(String.fromCharCode.apply(null,I.subarray(f,Math.min(f+p,B)))),f+=p;return u.join("")},stringifyByChar:function(I){for(var g="",p=0;p<I.length;p++)g+=String.fromCharCode(I[p]);return g},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,s.allocBuffer(1)).length===1}catch{return!1}}()}};function c(I){var g=65536,p=t.getTypeOf(I),u=!0;if(p==="uint8array"?u=r.applyCanBeUsed.uint8array:p==="nodebuffer"&&(u=r.applyCanBeUsed.nodebuffer),u)for(;1<g;)try{return r.stringifyByChunk(I,p,g)}catch{g=Math.floor(g/2)}return r.stringifyByChar(I)}function l(I,g){for(var p=0;p<I.length;p++)g[p]=I[p];return g}t.applyFromCharCode=c;var d={};d.string={string:o,array:function(I){return a(I,new Array(I.length))},arraybuffer:function(I){return d.string.uint8array(I).buffer},uint8array:function(I){return a(I,new Uint8Array(I.length))},nodebuffer:function(I){return a(I,s.allocBuffer(I.length))}},d.array={string:c,array:o,arraybuffer:function(I){return new Uint8Array(I).buffer},uint8array:function(I){return new Uint8Array(I)},nodebuffer:function(I){return s.newBufferFrom(I)}},d.arraybuffer={string:function(I){return c(new Uint8Array(I))},array:function(I){return l(new Uint8Array(I),new Array(I.byteLength))},arraybuffer:o,uint8array:function(I){return new Uint8Array(I)},nodebuffer:function(I){return s.newBufferFrom(new Uint8Array(I))}},d.uint8array={string:c,array:function(I){return l(I,new Array(I.length))},arraybuffer:function(I){return I.buffer},uint8array:o,nodebuffer:function(I){return s.newBufferFrom(I)}},d.nodebuffer={string:c,array:function(I){return l(I,new Array(I.length))},arraybuffer:function(I){return d.nodebuffer.uint8array(I).buffer},uint8array:function(I){return l(I,new Uint8Array(I.length))},nodebuffer:o},t.transformTo=function(I,g){if(g=g||"",!I)return g;t.checkSupport(I);var p=t.getTypeOf(g);return d[p][I](g)},t.resolve=function(I){for(var g=I.split("/"),p=[],u=0;u<g.length;u++){var f=g[u];f==="."||f===""&&u!==0&&u!==g.length-1||(f===".."?p.pop():p.push(f))}return p.join("/")},t.getTypeOf=function(I){return typeof I=="string"?"string":Object.prototype.toString.call(I)==="[object Array]"?"array":e.nodebuffer&&s.isBuffer(I)?"nodebuffer":e.uint8array&&I instanceof Uint8Array?"uint8array":e.arraybuffer&&I instanceof ArrayBuffer?"arraybuffer":void 0},t.checkSupport=function(I){if(!e[I.toLowerCase()])throw new Error(I+" is not supported by this platform")},t.MAX_VALUE_16BITS=65535,t.MAX_VALUE_32BITS=-1,t.pretty=function(I){var g,p,u="";for(p=0;p<(I||"").length;p++)u+="\\x"+((g=I.charCodeAt(p))<16?"0":"")+g.toString(16).toUpperCase();return u},t.delay=function(I,g,p){setImmediate(function(){I.apply(p||null,g||[])})},t.inherits=function(I,g){function p(){}p.prototype=g.prototype,I.prototype=new p},t.extend=function(){var I,g,p={};for(I=0;I<arguments.length;I++)for(g in arguments[I])Object.prototype.hasOwnProperty.call(arguments[I],g)&&p[g]===void 0&&(p[g]=arguments[I][g]);return p},t.prepareContent=function(I,g,p,u,f){return n.Promise.resolve(g).then(function(B){return e.blob&&(B instanceof Blob||["[object File]","[object Blob]"].indexOf(Object.prototype.toString.call(B))!==-1)&&typeof FileReader<"u"?new n.Promise(function(Q,E){var y=new FileReader;y.onload=function(v){Q(v.target.result)},y.onerror=function(v){E(v.target.error)},y.readAsArrayBuffer(B)}):B}).then(function(B){var Q=t.getTypeOf(B);return Q?(Q==="arraybuffer"?B=t.transformTo("uint8array",B):Q==="string"&&(f?B=i.decode(B):p&&u!==!0&&(B=function(E){return a(E,e.uint8array?new Uint8Array(E.length):new Array(E.length))}(B))),B):n.Promise.reject(new Error("Can't read the data of '"+I+"'. Is it in a supported JavaScript type (String, Blob, ArrayBuffer, etc) ?"))})}},{"./base64":1,"./external":6,"./nodejsUtils":14,"./support":30,setimmediate:54}],33:[function(h,A,t){"use strict";var e=h("./reader/readerFor"),i=h("./utils"),s=h("./signature"),n=h("./zipEntry"),o=h("./support");function a(r){this.files=[],this.loadOptions=r}a.prototype={checkSignature:function(r){if(!this.reader.readAndCheckSignature(r)){this.reader.index-=4;var c=this.reader.readString(4);throw new Error("Corrupted zip or bug: unexpected signature ("+i.pretty(c)+", expected "+i.pretty(r)+")")}},isSignature:function(r,c){var l=this.reader.index;this.reader.setIndex(r);var d=this.reader.readString(4)===c;return this.reader.setIndex(l),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 r=this.reader.readData(this.zipCommentLength),c=o.uint8array?"uint8array":"array",l=i.transformTo(c,r);this.zipComment=this.loadOptions.decodeFileName(l)},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 r,c,l,d=this.zip64EndOfCentralSize-44;0<d;)r=this.reader.readInt(2),c=this.reader.readInt(4),l=this.reader.readData(c),this.zip64ExtensibleData[r]={id:r,length:c,value:l}},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 r,c;for(r=0;r<this.files.length;r++)c=this.files[r],this.reader.setIndex(c.localHeaderOffset),this.checkSignature(s.LOCAL_FILE_HEADER),c.readLocalPart(this.reader),c.handleUTF8(),c.processAttributes()},readCentralDir:function(){var r;for(this.reader.setIndex(this.centralDirOffset);this.reader.readAndCheckSignature(s.CENTRAL_FILE_HEADER);)(r=new n({zip64:this.zip64},this.loadOptions)).readCentralPart(this.reader),this.files.push(r);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 r=this.reader.lastIndexOfSignature(s.CENTRAL_DIRECTORY_END);if(r<0)throw this.isSignature(0,s.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(r);var c=r;if(this.checkSignature(s.CENTRAL_DIRECTORY_END),this.readBlockEndOfCentral(),this.diskNumber===i.MAX_VALUE_16BITS||this.diskWithCentralDirStart===i.MAX_VALUE_16BITS||this.centralDirRecordsOnThisDisk===i.MAX_VALUE_16BITS||this.centralDirRecords===i.MAX_VALUE_16BITS||this.centralDirSize===i.MAX_VALUE_32BITS||this.centralDirOffset===i.MAX_VALUE_32BITS){if(this.zip64=!0,(r=this.reader.lastIndexOfSignature(s.ZIP64_CENTRAL_DIRECTORY_LOCATOR))<0)throw new Error("Corrupted zip: can't find the ZIP64 end of central directory locator");if(this.reader.setIndex(r),this.checkSignature(s.ZIP64_CENTRAL_DIRECTORY_LOCATOR),this.readBlockZip64EndOfCentralLocator(),!this.isSignature(this.relativeOffsetEndOfZip64CentralDir,s.ZIP64_CENTRAL_DIRECTORY_END)&&(this.relativeOffsetEndOfZip64CentralDir=this.reader.lastIndexOfSignature(s.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(s.ZIP64_CENTRAL_DIRECTORY_END),this.readBlockZip64EndOfCentral()}var l=this.centralDirOffset+this.centralDirSize;this.zip64&&(l+=20,l+=12+this.zip64EndOfCentralSize);var d=c-l;if(0<d)this.isSignature(c,s.CENTRAL_FILE_HEADER)||(this.reader.zero=d);else if(d<0)throw new Error("Corrupted zip: missing "+Math.abs(d)+" bytes.")},prepareReader:function(r){this.reader=e(r)},load:function(r){this.prepareReader(r),this.readEndOfCentral(),this.readCentralDir(),this.readLocalFiles()}},A.exports=a},{"./reader/readerFor":22,"./signature":23,"./support":30,"./utils":32,"./zipEntry":34}],34:[function(h,A,t){"use strict";var e=h("./reader/readerFor"),i=h("./utils"),s=h("./compressedObject"),n=h("./crc32"),o=h("./utf8"),a=h("./compressions"),r=h("./support");function c(l,d){this.options=l,this.loadOptions=d}c.prototype={isEncrypted:function(){return(1&this.bitFlag)==1},useUTF8:function(){return(2048&this.bitFlag)==2048},readLocalPart:function(l){var d,I;if(l.skip(22),this.fileNameLength=l.readInt(2),I=l.readInt(2),this.fileName=l.readData(this.fileNameLength),l.skip(I),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(g){for(var p in a)if(Object.prototype.hasOwnProperty.call(a,p)&&a[p].magic===g)return a[p];return null}(this.compressionMethod))===null)throw new Error("Corrupted zip : compression "+i.pretty(this.compressionMethod)+" unknown (inner file : "+i.transformTo("string",this.fileName)+")");this.decompressed=new s(this.compressedSize,this.uncompressedSize,this.crc32,d,l.readData(this.compressedSize))},readCentralPart:function(l){this.versionMadeBy=l.readInt(2),l.skip(2),this.bitFlag=l.readInt(2),this.compressionMethod=l.readString(2),this.date=l.readDate(),this.crc32=l.readInt(4),this.compressedSize=l.readInt(4),this.uncompressedSize=l.readInt(4);var d=l.readInt(2);if(this.extraFieldsLength=l.readInt(2),this.fileCommentLength=l.readInt(2),this.diskNumberStart=l.readInt(2),this.internalFileAttributes=l.readInt(2),this.externalFileAttributes=l.readInt(4),this.localHeaderOffset=l.readInt(4),this.isEncrypted())throw new Error("Encrypted zip are not supported");l.skip(d),this.readExtraFields(l),this.parseZIP64ExtraField(l),this.fileComment=l.readData(this.fileCommentLength)},processAttributes:function(){this.unixPermissions=null,this.dosPermissions=null;var l=this.versionMadeBy>>8;this.dir=!!(16&this.externalFileAttributes),l==0&&(this.dosPermissions=63&this.externalFileAttributes),l==3&&(this.unixPermissions=this.externalFileAttributes>>16&65535),this.dir||this.fileNameStr.slice(-1)!=="/"||(this.dir=!0)},parseZIP64ExtraField:function(){if(this.extraFields[1]){var l=e(this.extraFields[1].value);this.uncompressedSize===i.MAX_VALUE_32BITS&&(this.uncompressedSize=l.readInt(8)),this.compressedSize===i.MAX_VALUE_32BITS&&(this.compressedSize=l.readInt(8)),this.localHeaderOffset===i.MAX_VALUE_32BITS&&(this.localHeaderOffset=l.readInt(8)),this.diskNumberStart===i.MAX_VALUE_32BITS&&(this.diskNumberStart=l.readInt(4))}},readExtraFields:function(l){var d,I,g,p=l.index+this.extraFieldsLength;for(this.extraFields||(this.extraFields={});l.index+4<p;)d=l.readInt(2),I=l.readInt(2),g=l.readData(I),this.extraFields[d]={id:d,length:I,value:g};l.setIndex(p)},handleUTF8:function(){var l=r.uint8array?"uint8array":"array";if(this.useUTF8())this.fileNameStr=o.utf8decode(this.fileName),this.fileCommentStr=o.utf8decode(this.fileComment);else{var d=this.findExtraFieldUnicodePath();if(d!==null)this.fileNameStr=d;else{var I=i.transformTo(l,this.fileName);this.fileNameStr=this.loadOptions.decodeFileName(I)}var g=this.findExtraFieldUnicodeComment();if(g!==null)this.fileCommentStr=g;else{var p=i.transformTo(l,this.fileComment);this.fileCommentStr=this.loadOptions.decodeFileName(p)}}},findExtraFieldUnicodePath:function(){var l=this.extraFields[28789];if(l){var d=e(l.value);return d.readInt(1)!==1||n(this.fileName)!==d.readInt(4)?null:o.utf8decode(d.readData(l.length-5))}return null},findExtraFieldUnicodeComment:function(){var l=this.extraFields[25461];if(l){var d=e(l.value);return d.readInt(1)!==1||n(this.fileComment)!==d.readInt(4)?null:o.utf8decode(d.readData(l.length-5))}return null}},A.exports=c},{"./compressedObject":2,"./compressions":3,"./crc32":4,"./reader/readerFor":22,"./support":30,"./utf8":31,"./utils":32}],35:[function(h,A,t){"use strict";function e(d,I,g){this.name=d,this.dir=g.dir,this.date=g.date,this.comment=g.comment,this.unixPermissions=g.unixPermissions,this.dosPermissions=g.dosPermissions,this._data=I,this._dataBinary=g.binary,this.options={compression:g.compression,compressionOptions:g.compressionOptions}}var i=h("./stream/StreamHelper"),s=h("./stream/DataWorker"),n=h("./utf8"),o=h("./compressedObject"),a=h("./stream/GenericWorker");e.prototype={internalStream:function(d){var I=null,g="string";try{if(!d)throw new Error("No output type specified.");var p=(g=d.toLowerCase())==="string"||g==="text";g!=="binarystring"&&g!=="text"||(g="string"),I=this._decompressWorker();var u=!this._dataBinary;u&&!p&&(I=I.pipe(new n.Utf8EncodeWorker)),!u&&p&&(I=I.pipe(new n.Utf8DecodeWorker))}catch(f){(I=new a("error")).error(f)}return new i(I,g,"")},async:function(d,I){return this.internalStream(d).accumulate(I)},nodeStream:function(d,I){return this.internalStream(d||"nodebuffer").toNodejsStream(I)},_compressWorker:function(d,I){if(this._data instanceof o&&this._data.compression.magic===d.magic)return this._data.getCompressedWorker();var g=this._decompressWorker();return this._dataBinary||(g=g.pipe(new n.Utf8EncodeWorker)),o.createWorkerFrom(g,d,I)},_decompressWorker:function(){return this._data instanceof o?this._data.getContentWorker():this._data instanceof a?this._data:new s(this._data)}};for(var r=["asText","asBinary","asNodeBuffer","asUint8Array","asArrayBuffer"],c=function(){throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.")},l=0;l<r.length;l++)e.prototype[r[l]]=c;A.exports=e},{"./compressedObject":2,"./stream/DataWorker":27,"./stream/GenericWorker":28,"./stream/StreamHelper":29,"./utf8":31}],36:[function(h,A,t){(function(e){"use strict";var i,s,n=e.MutationObserver||e.WebKitMutationObserver;if(n){var o=0,a=new n(d),r=e.document.createTextNode("");a.observe(r,{characterData:!0}),i=function(){r.data=o=++o%2}}else if(e.setImmediate||e.MessageChannel===void 0)i="document"in e&&"onreadystatechange"in e.document.createElement("script")?function(){var I=e.document.createElement("script");I.onreadystatechange=function(){d(),I.onreadystatechange=null,I.parentNode.removeChild(I),I=null},e.document.documentElement.appendChild(I)}:function(){setTimeout(d,0)};else{var c=new e.MessageChannel;c.port1.onmessage=d,i=function(){c.port2.postMessage(0)}}var l=[];function d(){var I,g;s=!0;for(var p=l.length;p;){for(g=l,l=[],I=-1;++I<p;)g[I]();p=l.length}s=!1}A.exports=function(I){l.push(I)!==1||s||i()}}).call(this,typeof global<"u"?global:typeof self<"u"?self:typeof window<"u"?window:{})},{}],37:[function(h,A,t){"use strict";var e=h("immediate");function i(){}var s={},n=["REJECTED"],o=["FULFILLED"],a=["PENDING"];function r(p){if(typeof p!="function")throw new TypeError("resolver must be a function");this.state=a,this.queue=[],this.outcome=void 0,p!==i&&I(this,p)}function c(p,u,f){this.promise=p,typeof u=="function"&&(this.onFulfilled=u,this.callFulfilled=this.otherCallFulfilled),typeof f=="function"&&(this.onRejected=f,this.callRejected=this.otherCallRejected)}function l(p,u,f){e(function(){var B;try{B=u(f)}catch(Q){return s.reject(p,Q)}B===p?s.reject(p,new TypeError("Cannot resolve promise with itself")):s.resolve(p,B)})}function d(p){var u=p&&p.then;if(p&&(typeof p=="object"||typeof p=="function")&&typeof u=="function")return function(){u.apply(p,arguments)}}function I(p,u){var f=!1;function B(y){f||(f=!0,s.reject(p,y))}function Q(y){f||(f=!0,s.resolve(p,y))}var E=g(function(){u(Q,B)});E.status==="error"&&B(E.value)}function g(p,u){var f={};try{f.value=p(u),f.status="success"}catch(B){f.status="error",f.value=B}return f}(A.exports=r).prototype.finally=function(p){if(typeof p!="function")return this;var u=this.constructor;return this.then(function(f){return u.resolve(p()).then(function(){return f})},function(f){return u.resolve(p()).then(function(){throw f})})},r.prototype.catch=function(p){return this.then(null,p)},r.prototype.then=function(p,u){if(typeof p!="function"&&this.state===o||typeof u!="function"&&this.state===n)return this;var f=new this.constructor(i);return this.state!==a?l(f,this.state===o?p:u,this.outcome):this.queue.push(new c(f,p,u)),f},c.prototype.callFulfilled=function(p){s.resolve(this.promise,p)},c.prototype.otherCallFulfilled=function(p){l(this.promise,this.onFulfilled,p)},c.prototype.callRejected=function(p){s.reject(this.promise,p)},c.prototype.otherCallRejected=function(p){l(this.promise,this.onRejected,p)},s.resolve=function(p,u){var f=g(d,u);if(f.status==="error")return s.reject(p,f.value);var B=f.value;if(B)I(p,B);else{p.state=o,p.outcome=u;for(var Q=-1,E=p.queue.length;++Q<E;)p.queue[Q].callFulfilled(u)}return p},s.reject=function(p,u){p.state=n,p.outcome=u;for(var f=-1,B=p.queue.length;++f<B;)p.queue[f].callRejected(u);return p},r.resolve=function(p){return p instanceof this?p:s.resolve(new this(i),p)},r.reject=function(p){var u=new this(i);return s.reject(u,p)},r.all=function(p){var u=this;if(Object.prototype.toString.call(p)!=="[object Array]")return this.reject(new TypeError("must be an array"));var f=p.length,B=!1;if(!f)return this.resolve([]);for(var Q=new Array(f),E=0,y=-1,v=new this(i);++y<f;)k(p[y],y);return v;function k(b,R){u.resolve(b).then(function(w){Q[R]=w,++E!==f||B||(B=!0,s.resolve(v,Q))},function(w){B||(B=!0,s.reject(v,w))})}},r.race=function(p){var u=this;if(Object.prototype.toString.call(p)!=="[object Array]")return this.reject(new TypeError("must be an array"));var f=p.length,B=!1;if(!f)return this.resolve([]);for(var Q=-1,E=new this(i);++Q<f;)y=p[Q],u.resolve(y).then(function(v){B||(B=!0,s.resolve(E,v))},function(v){B||(B=!0,s.reject(E,v))});var y;return E}},{immediate:36}],38:[function(h,A,t){"use strict";var e={};(0,h("./lib/utils/common").assign)(e,h("./lib/deflate"),h("./lib/inflate"),h("./lib/zlib/constants")),A.exports=e},{"./lib/deflate":39,"./lib/inflate":40,"./lib/utils/common":41,"./lib/zlib/constants":44}],39:[function(h,A,t){"use strict";var e=h("./zlib/deflate"),i=h("./utils/common"),s=h("./utils/strings"),n=h("./zlib/messages"),o=h("./zlib/zstream"),a=Object.prototype.toString,r=0,c=-1,l=0,d=8;function I(p){if(!(this instanceof I))return new I(p);this.options=i.assign({level:c,method:d,chunkSize:16384,windowBits:15,memLevel:8,strategy:l,to:""},p||{});var u=this.options;u.raw&&0<u.windowBits?u.windowBits=-u.windowBits:u.gzip&&0<u.windowBits&&u.windowBits<16&&(u.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new o,this.strm.avail_out=0;var f=e.deflateInit2(this.strm,u.level,u.method,u.windowBits,u.memLevel,u.strategy);if(f!==r)throw new Error(n[f]);if(u.header&&e.deflateSetHeader(this.strm,u.header),u.dictionary){var B;if(B=typeof u.dictionary=="string"?s.string2buf(u.dictionary):a.call(u.dictionary)==="[object ArrayBuffer]"?new Uint8Array(u.dictionary):u.dictionary,(f=e.deflateSetDictionary(this.strm,B))!==r)throw new Error(n[f]);this._dict_set=!0}}function g(p,u){var f=new I(u);if(f.push(p,!0),f.err)throw f.msg||n[f.err];return f.result}I.prototype.push=function(p,u){var f,B,Q=this.strm,E=this.options.chunkSize;if(this.ended)return!1;B=u===~~u?u:u===!0?4:0,typeof p=="string"?Q.input=s.string2buf(p):a.call(p)==="[object ArrayBuffer]"?Q.input=new Uint8Array(p):Q.input=p,Q.next_in=0,Q.avail_in=Q.input.length;do{if(Q.avail_out===0&&(Q.output=new i.Buf8(E),Q.next_out=0,Q.avail_out=E),(f=e.deflate(Q,B))!==1&&f!==r)return this.onEnd(f),!(this.ended=!0);Q.avail_out!==0&&(Q.avail_in!==0||B!==4&&B!==2)||(this.options.to==="string"?this.onData(s.buf2binstring(i.shrinkBuf(Q.output,Q.next_out))):this.onData(i.shrinkBuf(Q.output,Q.next_out)))}while((0<Q.avail_in||Q.avail_out===0)&&f!==1);return B===4?(f=e.deflateEnd(this.strm),this.onEnd(f),this.ended=!0,f===r):B!==2||(this.onEnd(r),!(Q.avail_out=0))},I.prototype.onData=function(p){this.chunks.push(p)},I.prototype.onEnd=function(p){p===r&&(this.options.to==="string"?this.result=this.chunks.join(""):this.result=i.flattenChunks(this.chunks)),this.chunks=[],this.err=p,this.msg=this.strm.msg},t.Deflate=I,t.deflate=g,t.deflateRaw=function(p,u){return(u=u||{}).raw=!0,g(p,u)},t.gzip=function(p,u){return(u=u||{}).gzip=!0,g(p,u)}},{"./utils/common":41,"./utils/strings":42,"./zlib/deflate":46,"./zlib/messages":51,"./zlib/zstream":53}],40:[function(h,A,t){"use strict";var e=h("./zlib/inflate"),i=h("./utils/common"),s=h("./utils/strings"),n=h("./zlib/constants"),o=h("./zlib/messages"),a=h("./zlib/zstream"),r=h("./zlib/gzheader"),c=Object.prototype.toString;function l(I){if(!(this instanceof l))return new l(I);this.options=i.assign({chunkSize:16384,windowBits:0,to:""},I||{});var g=this.options;g.raw&&0<=g.windowBits&&g.windowBits<16&&(g.windowBits=-g.windowBits,g.windowBits===0&&(g.windowBits=-15)),!(0<=g.windowBits&&g.windowBits<16)||I&&I.windowBits||(g.windowBits+=32),15<g.windowBits&&g.windowBits<48&&!(15&g.windowBits)&&(g.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new a,this.strm.avail_out=0;var p=e.inflateInit2(this.strm,g.windowBits);if(p!==n.Z_OK)throw new Error(o[p]);this.header=new r,e.inflateGetHeader(this.strm,this.header)}function d(I,g){var p=new l(g);if(p.push(I,!0),p.err)throw p.msg||o[p.err];return p.result}l.prototype.push=function(I,g){var p,u,f,B,Q,E,y=this.strm,v=this.options.chunkSize,k=this.options.dictionary,b=!1;if(this.ended)return!1;u=g===~~g?g:g===!0?n.Z_FINISH:n.Z_NO_FLUSH,typeof I=="string"?y.input=s.binstring2buf(I):c.call(I)==="[object ArrayBuffer]"?y.input=new Uint8Array(I):y.input=I,y.next_in=0,y.avail_in=y.input.length;do{if(y.avail_out===0&&(y.output=new i.Buf8(v),y.next_out=0,y.avail_out=v),(p=e.inflate(y,n.Z_NO_FLUSH))===n.Z_NEED_DICT&&k&&(E=typeof k=="string"?s.string2buf(k):c.call(k)==="[object ArrayBuffer]"?new Uint8Array(k):k,p=e.inflateSetDictionary(this.strm,E)),p===n.Z_BUF_ERROR&&b===!0&&(p=n.Z_OK,b=!1),p!==n.Z_STREAM_END&&p!==n.Z_OK)return this.onEnd(p),!(this.ended=!0);y.next_out&&(y.avail_out!==0&&p!==n.Z_STREAM_END&&(y.avail_in!==0||u!==n.Z_FINISH&&u!==n.Z_SYNC_FLUSH)||(this.options.to==="string"?(f=s.utf8border(y.output,y.next_out),B=y.next_out-f,Q=s.buf2string(y.output,f),y.next_out=B,y.avail_out=v-B,B&&i.arraySet(y.output,y.output,f,B,0),this.onData(Q)):this.onData(i.shrinkBuf(y.output,y.next_out)))),y.avail_in===0&&y.avail_out===0&&(b=!0)}while((0<y.avail_in||y.avail_out===0)&&p!==n.Z_STREAM_END);return p===n.Z_STREAM_END&&(u=n.Z_FINISH),u===n.Z_FINISH?(p=e.inflateEnd(this.strm),this.onEnd(p),this.ended=!0,p===n.Z_OK):u!==n.Z_SYNC_FLUSH||(this.onEnd(n.Z_OK),!(y.avail_out=0))},l.prototype.onData=function(I){this.chunks.push(I)},l.prototype.onEnd=function(I){I===n.Z_OK&&(this.options.to==="string"?this.result=this.chunks.join(""):this.result=i.flattenChunks(this.chunks)),this.chunks=[],this.err=I,this.msg=this.strm.msg},t.Inflate=l,t.inflate=d,t.inflateRaw=function(I,g){return(g=g||{}).raw=!0,d(I,g)},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(h,A,t){"use strict";var e=typeof Uint8Array<"u"&&typeof Uint16Array<"u"&&typeof Int32Array<"u";t.assign=function(n){for(var o=Array.prototype.slice.call(arguments,1);o.length;){var a=o.shift();if(a){if(typeof a!="object")throw new TypeError(a+"must be non-object");for(var r in a)a.hasOwnProperty(r)&&(n[r]=a[r])}}return n},t.shrinkBuf=function(n,o){return n.length===o?n:n.subarray?n.subarray(0,o):(n.length=o,n)};var i={arraySet:function(n,o,a,r,c){if(o.subarray&&n.subarray)n.set(o.subarray(a,a+r),c);else for(var l=0;l<r;l++)n[c+l]=o[a+l]},flattenChunks:function(n){var o,a,r,c,l,d;for(o=r=0,a=n.length;o<a;o++)r+=n[o].length;for(d=new Uint8Array(r),o=c=0,a=n.length;o<a;o++)l=n[o],d.set(l,c),c+=l.length;return d}},s={arraySet:function(n,o,a,r,c){for(var l=0;l<r;l++)n[c+l]=o[a+l]},flattenChunks:function(n){return[].concat.apply([],n)}};t.setTyped=function(n){n?(t.Buf8=Uint8Array,t.Buf16=Uint16Array,t.Buf32=Int32Array,t.assign(t,i)):(t.Buf8=Array,t.Buf16=Array,t.Buf32=Array,t.assign(t,s))},t.setTyped(e)},{}],42:[function(h,A,t){"use strict";var e=h("./common"),i=!0,s=!0;try{String.fromCharCode.apply(null,[0])}catch{i=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch{s=!1}for(var n=new e.Buf8(256),o=0;o<256;o++)n[o]=252<=o?6:248<=o?5:240<=o?4:224<=o?3:192<=o?2:1;function a(r,c){if(c<65537&&(r.subarray&&s||!r.subarray&&i))return String.fromCharCode.apply(null,e.shrinkBuf(r,c));for(var l="",d=0;d<c;d++)l+=String.fromCharCode(r[d]);return l}n[254]=n[254]=1,t.string2buf=function(r){var c,l,d,I,g,p=r.length,u=0;for(I=0;I<p;I++)(64512&(l=r.charCodeAt(I)))==55296&&I+1<p&&(64512&(d=r.charCodeAt(I+1)))==56320&&(l=65536+(l-55296<<10)+(d-56320),I++),u+=l<128?1:l<2048?2:l<65536?3:4;for(c=new e.Buf8(u),I=g=0;g<u;I++)(64512&(l=r.charCodeAt(I)))==55296&&I+1<p&&(64512&(d=r.charCodeAt(I+1)))==56320&&(l=65536+(l-55296<<10)+(d-56320),I++),l<128?c[g++]=l:(l<2048?c[g++]=192|l>>>6:(l<65536?c[g++]=224|l>>>12:(c[g++]=240|l>>>18,c[g++]=128|l>>>12&63),c[g++]=128|l>>>6&63),c[g++]=128|63&l);return c},t.buf2binstring=function(r){return a(r,r.length)},t.binstring2buf=function(r){for(var c=new e.Buf8(r.length),l=0,d=c.length;l<d;l++)c[l]=r.charCodeAt(l);return c},t.buf2string=function(r,c){var l,d,I,g,p=c||r.length,u=new Array(2*p);for(l=d=0;l<p;)if((I=r[l++])<128)u[d++]=I;else if(4<(g=n[I]))u[d++]=65533,l+=g-1;else{for(I&=g===2?31:g===3?15:7;1<g&&l<p;)I=I<<6|63&r[l++],g--;1<g?u[d++]=65533:I<65536?u[d++]=I:(I-=65536,u[d++]=55296|I>>10&1023,u[d++]=56320|1023&I)}return a(u,d)},t.utf8border=function(r,c){var l;for((c=c||r.length)>r.length&&(c=r.length),l=c-1;0<=l&&(192&r[l])==128;)l--;return l<0||l===0?c:l+n[r[l]]>c?l:c}},{"./common":41}],43:[function(h,A,t){"use strict";A.exports=function(e,i,s,n){for(var o=65535&e|0,a=e>>>16&65535|0,r=0;s!==0;){for(s-=r=2e3<s?2e3:s;a=a+(o=o+i[n++]|0)|0,--r;);o%=65521,a%=65521}return o|a<<16|0}},{}],44:[function(h,A,t){"use strict";A.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(h,A,t){"use strict";var e=function(){for(var i,s=[],n=0;n<256;n++){i=n;for(var o=0;o<8;o++)i=1&i?3988292384^i>>>1:i>>>1;s[n]=i}return s}();A.exports=function(i,s,n,o){var a=e,r=o+n;i^=-1;for(var c=o;c<r;c++)i=i>>>8^a[255&(i^s[c])];return-1^i}},{}],46:[function(h,A,t){"use strict";var e,i=h("../utils/common"),s=h("./trees"),n=h("./adler32"),o=h("./crc32"),a=h("./messages"),r=0,c=4,l=0,d=-2,I=-1,g=4,p=2,u=8,f=9,B=286,Q=30,E=19,y=2*B+1,v=15,k=3,b=258,R=b+k+1,w=42,D=113,m=1,M=2,_=3,O=4;function J(C,P){return C.msg=a[P],P}function q(C){return(C<<1)-(4<C?9:0)}function j(C){for(var P=C.length;0<=--P;)C[P]=0}function H(C){var P=C.state,T=P.pending;T>C.avail_out&&(T=C.avail_out),T!==0&&(i.arraySet(C.output,P.pending_buf,P.pending_out,T,C.next_out),C.next_out+=T,P.pending_out+=T,C.total_out+=T,C.avail_out-=T,P.pending-=T,P.pending===0&&(P.pending_out=0))}function N(C,P){s._tr_flush_block(C,0<=C.block_start?C.block_start:-1,C.strstart-C.block_start,P),C.block_start=C.strstart,H(C.strm)}function $(C,P){C.pending_buf[C.pending++]=P}function V(C,P){C.pending_buf[C.pending++]=P>>>8&255,C.pending_buf[C.pending++]=255&P}function z(C,P){var T,S,F=C.max_chain_length,x=C.strstart,K=C.prev_length,Y=C.nice_match,U=C.strstart>C.w_size-R?C.strstart-(C.w_size-R):0,W=C.window,tt=C.w_mask,X=C.prev,it=C.strstart+b,It=W[x+K-1],At=W[x+K];C.prev_length>=C.good_match&&(F>>=2),Y>C.lookahead&&(Y=C.lookahead);do if(W[(T=P)+K]===At&&W[T+K-1]===It&&W[T]===W[x]&&W[++T]===W[x+1]){x+=2,T++;do;while(W[++x]===W[++T]&&W[++x]===W[++T]&&W[++x]===W[++T]&&W[++x]===W[++T]&&W[++x]===W[++T]&&W[++x]===W[++T]&&W[++x]===W[++T]&&W[++x]===W[++T]&&x<it);if(S=b-(it-x),x=it-b,K<S){if(C.match_start=P,Y<=(K=S))break;It=W[x+K-1],At=W[x+K]}}while((P=X[P&tt])>U&&--F!=0);return K<=C.lookahead?K:C.lookahead}function ct(C){var P,T,S,F,x,K,Y,U,W,tt,X=C.w_size;do{if(F=C.window_size-C.lookahead-C.strstart,C.strstart>=X+(X-R)){for(i.arraySet(C.window,C.window,X,X,0),C.match_start-=X,C.strstart-=X,C.block_start-=X,P=T=C.hash_size;S=C.head[--P],C.head[P]=X<=S?S-X:0,--T;);for(P=T=X;S=C.prev[--P],C.prev[P]=X<=S?S-X:0,--T;);F+=X}if(C.strm.avail_in===0)break;if(K=C.strm,Y=C.window,U=C.strstart+C.lookahead,W=F,tt=void 0,tt=K.avail_in,W<tt&&(tt=W),T=tt===0?0:(K.avail_in-=tt,i.arraySet(Y,K.input,K.next_in,tt,U),K.state.wrap===1?K.adler=n(K.adler,Y,tt,U):K.state.wrap===2&&(K.adler=o(K.adler,Y,tt,U)),K.next_in+=tt,K.total_in+=tt,tt),C.lookahead+=T,C.lookahead+C.insert>=k)for(x=C.strstart-C.insert,C.ins_h=C.window[x],C.ins_h=(C.ins_h<<C.hash_shift^C.window[x+1])&C.hash_mask;C.insert&&(C.ins_h=(C.ins_h<<C.hash_shift^C.window[x+k-1])&C.hash_mask,C.prev[x&C.w_mask]=C.head[C.ins_h],C.head[C.ins_h]=x,x++,C.insert--,!(C.lookahead+C.insert<k)););}while(C.lookahead<R&&C.strm.avail_in!==0)}function gt(C,P){for(var T,S;;){if(C.lookahead<R){if(ct(C),C.lookahead<R&&P===r)return m;if(C.lookahead===0)break}if(T=0,C.lookahead>=k&&(C.ins_h=(C.ins_h<<C.hash_shift^C.window[C.strstart+k-1])&C.hash_mask,T=C.prev[C.strstart&C.w_mask]=C.head[C.ins_h],C.head[C.ins_h]=C.strstart),T!==0&&C.strstart-T<=C.w_size-R&&(C.match_length=z(C,T)),C.match_length>=k)if(S=s._tr_tally(C,C.strstart-C.match_start,C.match_length-k),C.lookahead-=C.match_length,C.match_length<=C.max_lazy_match&&C.lookahead>=k){for(C.match_length--;C.strstart++,C.ins_h=(C.ins_h<<C.hash_shift^C.window[C.strstart+k-1])&C.hash_mask,T=C.prev[C.strstart&C.w_mask]=C.head[C.ins_h],C.head[C.ins_h]=C.strstart,--C.match_length!=0;);C.strstart++}else C.strstart+=C.match_length,C.match_length=0,C.ins_h=C.window[C.strstart],C.ins_h=(C.ins_h<<C.hash_shift^C.window[C.strstart+1])&C.hash_mask;else S=s._tr_tally(C,0,C.window[C.strstart]),C.lookahead--,C.strstart++;if(S&&(N(C,!1),C.strm.avail_out===0))return m}return C.insert=C.strstart<k-1?C.strstart:k-1,P===c?(N(C,!0),C.strm.avail_out===0?_:O):C.last_lit&&(N(C,!1),C.strm.avail_out===0)?m:M}function nt(C,P){for(var T,S,F;;){if(C.lookahead<R){if(ct(C),C.lookahead<R&&P===r)return m;if(C.lookahead===0)break}if(T=0,C.lookahead>=k&&(C.ins_h=(C.ins_h<<C.hash_shift^C.window[C.strstart+k-1])&C.hash_mask,T=C.prev[C.strstart&C.w_mask]=C.head[C.ins_h],C.head[C.ins_h]=C.strstart),C.prev_length=C.match_length,C.prev_match=C.match_start,C.match_length=k-1,T!==0&&C.prev_length<C.max_lazy_match&&C.strstart-T<=C.w_size-R&&(C.match_length=z(C,T),C.match_length<=5&&(C.strategy===1||C.match_length===k&&4096<C.strstart-C.match_start)&&(C.match_length=k-1)),C.prev_length>=k&&C.match_length<=C.prev_length){for(F=C.strstart+C.lookahead-k,S=s._tr_tally(C,C.strstart-1-C.prev_match,C.prev_length-k),C.lookahead-=C.prev_length-1,C.prev_length-=2;++C.strstart<=F&&(C.ins_h=(C.ins_h<<C.hash_shift^C.window[C.strstart+k-1])&C.hash_mask,T=C.prev[C.strstart&C.w_mask]=C.head[C.ins_h],C.head[C.ins_h]=C.strstart),--C.prev_length!=0;);if(C.match_available=0,C.match_length=k-1,C.strstart++,S&&(N(C,!1),C.strm.avail_out===0))return m}else if(C.match_available){if((S=s._tr_tally(C,0,C.window[C.strstart-1]))&&N(C,!1),C.strstart++,C.lookahead--,C.strm.avail_out===0)return m}else C.match_available=1,C.strstart++,C.lookahead--}return C.match_available&&(S=s._tr_tally(C,0,C.window[C.strstart-1]),C.match_available=0),C.insert=C.strstart<k-1?C.strstart:k-1,P===c?(N(C,!0),C.strm.avail_out===0?_:O):C.last_lit&&(N(C,!1),C.strm.avail_out===0)?m:M}function at(C,P,T,S,F){this.good_length=C,this.max_lazy=P,this.nice_length=T,this.max_chain=S,this.func=F}function rt(){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=u,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 i.Buf16(2*y),this.dyn_dtree=new i.Buf16(2*(2*Q+1)),this.bl_tree=new i.Buf16(2*(2*E+1)),j(this.dyn_ltree),j(this.dyn_dtree),j(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new i.Buf16(v+1),this.heap=new i.Buf16(2*B+1),j(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new i.Buf16(2*B+1),j(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(C){var P;return C&&C.state?(C.total_in=C.total_out=0,C.data_type=p,(P=C.state).pending=0,P.pending_out=0,P.wrap<0&&(P.wrap=-P.wrap),P.status=P.wrap?w:D,C.adler=P.wrap===2?0:1,P.last_flush=r,s._tr_init(P),l):J(C,d)}function Ct(C){var P=st(C);return P===l&&function(T){T.window_size=2*T.w_size,j(T.head),T.max_lazy_match=e[T.level].max_lazy,T.good_match=e[T.level].good_length,T.nice_match=e[T.level].nice_length,T.max_chain_length=e[T.level].max_chain,T.strstart=0,T.block_start=0,T.lookahead=0,T.insert=0,T.match_length=T.prev_length=k-1,T.match_available=0,T.ins_h=0}(C.state),P}function pt(C,P,T,S,F,x){if(!C)return d;var K=1;if(P===I&&(P=6),S<0?(K=0,S=-S):15<S&&(K=2,S-=16),F<1||f<F||T!==u||S<8||15<S||P<0||9<P||x<0||g<x)return J(C,d);S===8&&(S=9);var Y=new rt;return(C.state=Y).strm=C,Y.wrap=K,Y.gzhead=null,Y.w_bits=S,Y.w_size=1<<Y.w_bits,Y.w_mask=Y.w_size-1,Y.hash_bits=F+7,Y.hash_size=1<<Y.hash_bits,Y.hash_mask=Y.hash_size-1,Y.hash_shift=~~((Y.hash_bits+k-1)/k),Y.window=new i.Buf8(2*Y.w_size),Y.head=new i.Buf16(Y.hash_size),Y.prev=new i.Buf16(Y.w_size),Y.lit_bufsize=1<<F+6,Y.pending_buf_size=4*Y.lit_bufsize,Y.pending_buf=new i.Buf8(Y.pending_buf_size),Y.d_buf=1*Y.lit_bufsize,Y.l_buf=3*Y.lit_bufsize,Y.level=P,Y.strategy=x,Y.method=T,Ct(C)}e=[new at(0,0,0,0,function(C,P){var T=65535;for(T>C.pending_buf_size-5&&(T=C.pending_buf_size-5);;){if(C.lookahead<=1){if(ct(C),C.lookahead===0&&P===r)return m;if(C.lookahead===0)break}C.strstart+=C.lookahead,C.lookahead=0;var S=C.block_start+T;if((C.strstart===0||C.strstart>=S)&&(C.lookahead=C.strstart-S,C.strstart=S,N(C,!1),C.strm.avail_out===0)||C.strstart-C.block_start>=C.w_size-R&&(N(C,!1),C.strm.avail_out===0))return m}return C.insert=0,P===c?(N(C,!0),C.strm.avail_out===0?_:O):(C.strstart>C.block_start&&(N(C,!1),C.strm.avail_out),m)}),new at(4,4,8,4,gt),new at(4,5,16,8,gt),new at(4,6,32,32,gt),new at(4,4,16,16,nt),new at(8,16,32,32,nt),new at(8,16,128,128,nt),new at(8,32,128,256,nt),new at(32,128,258,1024,nt),new at(32,258,258,4096,nt)],t.deflateInit=function(C,P){return pt(C,P,u,15,8,0)},t.deflateInit2=pt,t.deflateReset=Ct,t.deflateResetKeep=st,t.deflateSetHeader=function(C,P){return C&&C.state?C.state.wrap!==2?d:(C.state.gzhead=P,l):d},t.deflate=function(C,P){var T,S,F,x;if(!C||!C.state||5<P||P<0)return C?J(C,d):d;if(S=C.state,!C.output||!C.input&&C.avail_in!==0||S.status===666&&P!==c)return J(C,C.avail_out===0?-5:d);if(S.strm=C,T=S.last_flush,S.last_flush=P,S.status===w)if(S.wrap===2)C.adler=0,$(S,31),$(S,139),$(S,8),S.gzhead?($(S,(S.gzhead.text?1:0)+(S.gzhead.hcrc?2:0)+(S.gzhead.extra?4:0)+(S.gzhead.name?8:0)+(S.gzhead.comment?16:0)),$(S,255&S.gzhead.time),$(S,S.gzhead.time>>8&255),$(S,S.gzhead.time>>16&255),$(S,S.gzhead.time>>24&255),$(S,S.level===9?2:2<=S.strategy||S.level<2?4:0),$(S,255&S.gzhead.os),S.gzhead.extra&&S.gzhead.extra.length&&($(S,255&S.gzhead.extra.length),$(S,S.gzhead.extra.length>>8&255)),S.gzhead.hcrc&&(C.adler=o(C.adler,S.pending_buf,S.pending,0)),S.gzindex=0,S.status=69):($(S,0),$(S,0),$(S,0),$(S,0),$(S,0),$(S,S.level===9?2:2<=S.strategy||S.level<2?4:0),$(S,3),S.status=D);else{var K=u+(S.w_bits-8<<4)<<8;K|=(2<=S.strategy||S.level<2?0:S.level<6?1:S.level===6?2:3)<<6,S.strstart!==0&&(K|=32),K+=31-K%31,S.status=D,V(S,K),S.strstart!==0&&(V(S,C.adler>>>16),V(S,65535&C.adler)),C.adler=1}if(S.status===69)if(S.gzhead.extra){for(F=S.pending;S.gzindex<(65535&S.gzhead.extra.length)&&(S.pending!==S.pending_buf_size||(S.gzhead.hcrc&&S.pending>F&&(C.adler=o(C.adler,S.pending_buf,S.pending-F,F)),H(C),F=S.pending,S.pending!==S.pending_buf_size));)$(S,255&S.gzhead.extra[S.gzindex]),S.gzindex++;S.gzhead.hcrc&&S.pending>F&&(C.adler=o(C.adler,S.pending_buf,S.pending-F,F)),S.gzindex===S.gzhead.extra.length&&(S.gzindex=0,S.status=73)}else S.status=73;if(S.status===73)if(S.gzhead.name){F=S.pending;do{if(S.pending===S.pending_buf_size&&(S.gzhead.hcrc&&S.pending>F&&(C.adler=o(C.adler,S.pending_buf,S.pending-F,F)),H(C),F=S.pending,S.pending===S.pending_buf_size)){x=1;break}x=S.gzindex<S.gzhead.name.length?255&S.gzhead.name.charCodeAt(S.gzindex++):0,$(S,x)}while(x!==0);S.gzhead.hcrc&&S.pending>F&&(C.adler=o(C.adler,S.pending_buf,S.pending-F,F)),x===0&&(S.gzindex=0,S.status=91)}else S.status=91;if(S.status===91)if(S.gzhead.comment){F=S.pending;do{if(S.pending===S.pending_buf_size&&(S.gzhead.hcrc&&S.pending>F&&(C.adler=o(C.adler,S.pending_buf,S.pending-F,F)),H(C),F=S.pending,S.pending===S.pending_buf_size)){x=1;break}x=S.gzindex<S.gzhead.comment.length?255&S.gzhead.comment.charCodeAt(S.gzindex++):0,$(S,x)}while(x!==0);S.gzhead.hcrc&&S.pending>F&&(C.adler=o(C.adler,S.pending_buf,S.pending-F,F)),x===0&&(S.status=103)}else S.status=103;if(S.status===103&&(S.gzhead.hcrc?(S.pending+2>S.pending_buf_size&&H(C),S.pending+2<=S.pending_buf_size&&($(S,255&C.adler),$(S,C.adler>>8&255),C.adler=0,S.status=D)):S.status=D),S.pending!==0){if(H(C),C.avail_out===0)return S.last_flush=-1,l}else if(C.avail_in===0&&q(P)<=q(T)&&P!==c)return J(C,-5);if(S.status===666&&C.avail_in!==0)return J(C,-5);if(C.avail_in!==0||S.lookahead!==0||P!==r&&S.status!==666){var Y=S.strategy===2?function(U,W){for(var tt;;){if(U.lookahead===0&&(ct(U),U.lookahead===0)){if(W===r)return m;break}if(U.match_length=0,tt=s._tr_tally(U,0,U.window[U.strstart]),U.lookahead--,U.strstart++,tt&&(N(U,!1),U.strm.avail_out===0))return m}return U.insert=0,W===c?(N(U,!0),U.strm.avail_out===0?_:O):U.last_lit&&(N(U,!1),U.strm.avail_out===0)?m:M}(S,P):S.strategy===3?function(U,W){for(var tt,X,it,It,At=U.window;;){if(U.lookahead<=b){if(ct(U),U.lookahead<=b&&W===r)return m;if(U.lookahead===0)break}if(U.match_length=0,U.lookahead>=k&&0<U.strstart&&(X=At[it=U.strstart-1])===At[++it]&&X===At[++it]&&X===At[++it]){It=U.strstart+b;do;while(X===At[++it]&&X===At[++it]&&X===At[++it]&&X===At[++it]&&X===At[++it]&&X===At[++it]&&X===At[++it]&&X===At[++it]&&it<It);U.match_length=b-(It-it),U.match_length>U.lookahead&&(U.match_length=U.lookahead)}if(U.match_length>=k?(tt=s._tr_tally(U,1,U.match_length-k),U.lookahead-=U.match_length,U.strstart+=U.match_length,U.match_length=0):(tt=s._tr_tally(U,0,U.window[U.strstart]),U.lookahead--,U.strstart++),tt&&(N(U,!1),U.strm.avail_out===0))return m}return U.insert=0,W===c?(N(U,!0),U.strm.avail_out===0?_:O):U.last_lit&&(N(U,!1),U.strm.avail_out===0)?m:M}(S,P):e[S.level].func(S,P);if(Y!==_&&Y!==O||(S.status=666),Y===m||Y===_)return C.avail_out===0&&(S.last_flush=-1),l;if(Y===M&&(P===1?s._tr_align(S):P!==5&&(s._tr_stored_block(S,0,0,!1),P===3&&(j(S.head),S.lookahead===0&&(S.strstart=0,S.block_start=0,S.insert=0))),H(C),C.avail_out===0))return S.last_flush=-1,l}return P!==c?l:S.wrap<=0?1:(S.wrap===2?($(S,255&C.adler),$(S,C.adler>>8&255),$(S,C.adler>>16&255),$(S,C.adler>>24&255),$(S,255&C.total_in),$(S,C.total_in>>8&255),$(S,C.total_in>>16&255),$(S,C.total_in>>24&255)):(V(S,C.adler>>>16),V(S,65535&C.adler)),H(C),0<S.wrap&&(S.wrap=-S.wrap),S.pending!==0?l:1)},t.deflateEnd=function(C){var P;return C&&C.state?(P=C.state.status)!==w&&P!==69&&P!==73&&P!==91&&P!==103&&P!==D&&P!==666?J(C,d):(C.state=null,P===D?J(C,-3):l):d},t.deflateSetDictionary=function(C,P){var T,S,F,x,K,Y,U,W,tt=P.length;if(!C||!C.state||(x=(T=C.state).wrap)===2||x===1&&T.status!==w||T.lookahead)return d;for(x===1&&(C.adler=n(C.adler,P,tt,0)),T.wrap=0,tt>=T.w_size&&(x===0&&(j(T.head),T.strstart=0,T.block_start=0,T.insert=0),W=new i.Buf8(T.w_size),i.arraySet(W,P,tt-T.w_size,T.w_size,0),P=W,tt=T.w_size),K=C.avail_in,Y=C.next_in,U=C.input,C.avail_in=tt,C.next_in=0,C.input=P,ct(T);T.lookahead>=k;){for(S=T.strstart,F=T.lookahead-(k-1);T.ins_h=(T.ins_h<<T.hash_shift^T.window[S+k-1])&T.hash_mask,T.prev[S&T.w_mask]=T.head[T.ins_h],T.head[T.ins_h]=S,S++,--F;);T.strstart=S,T.lookahead=k-1,ct(T)}return T.strstart+=T.lookahead,T.block_start=T.strstart,T.insert=T.lookahead,T.lookahead=0,T.match_length=T.prev_length=k-1,T.match_available=0,C.next_in=Y,C.input=U,C.avail_in=K,T.wrap=x,l},t.deflateInfo="pako deflate (from Nodeca project)"},{"../utils/common":41,"./adler32":43,"./crc32":45,"./messages":51,"./trees":52}],47:[function(h,A,t){"use strict";A.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(h,A,t){"use strict";A.exports=function(e,i){var s,n,o,a,r,c,l,d,I,g,p,u,f,B,Q,E,y,v,k,b,R,w,D,m,M;s=e.state,n=e.next_in,m=e.input,o=n+(e.avail_in-5),a=e.next_out,M=e.output,r=a-(i-e.avail_out),c=a+(e.avail_out-257),l=s.dmax,d=s.wsize,I=s.whave,g=s.wnext,p=s.window,u=s.hold,f=s.bits,B=s.lencode,Q=s.distcode,E=(1<<s.lenbits)-1,y=(1<<s.distbits)-1;t:do{f<15&&(u+=m[n++]<<f,f+=8,u+=m[n++]<<f,f+=8),v=B[u&E];e:for(;;){if(u>>>=k=v>>>24,f-=k,(k=v>>>16&255)===0)M[a++]=65535&v;else{if(!(16&k)){if(!(64&k)){v=B[(65535&v)+(u&(1<<k)-1)];continue e}if(32&k){s.mode=12;break t}e.msg="invalid literal/length code",s.mode=30;break t}b=65535&v,(k&=15)&&(f<k&&(u+=m[n++]<<f,f+=8),b+=u&(1<<k)-1,u>>>=k,f-=k),f<15&&(u+=m[n++]<<f,f+=8,u+=m[n++]<<f,f+=8),v=Q[u&y];i:for(;;){if(u>>>=k=v>>>24,f-=k,!(16&(k=v>>>16&255))){if(!(64&k)){v=Q[(65535&v)+(u&(1<<k)-1)];continue i}e.msg="invalid distance code",s.mode=30;break t}if(R=65535&v,f<(k&=15)&&(u+=m[n++]<<f,(f+=8)<k&&(u+=m[n++]<<f,f+=8)),l<(R+=u&(1<<k)-1)){e.msg="invalid distance too far back",s.mode=30;break t}if(u>>>=k,f-=k,(k=a-r)<R){if(I<(k=R-k)&&s.sane){e.msg="invalid distance too far back",s.mode=30;break t}if(D=p,(w=0)===g){if(w+=d-k,k<b){for(b-=k;M[a++]=p[w++],--k;);w=a-R,D=M}}else if(g<k){if(w+=d+g-k,(k-=g)<b){for(b-=k;M[a++]=p[w++],--k;);if(w=0,g<b){for(b-=k=g;M[a++]=p[w++],--k;);w=a-R,D=M}}}else if(w+=g-k,k<b){for(b-=k;M[a++]=p[w++],--k;);w=a-R,D=M}for(;2<b;)M[a++]=D[w++],M[a++]=D[w++],M[a++]=D[w++],b-=3;b&&(M[a++]=D[w++],1<b&&(M[a++]=D[w++]))}else{for(w=a-R;M[a++]=M[w++],M[a++]=M[w++],M[a++]=M[w++],2<(b-=3););b&&(M[a++]=M[w++],1<b&&(M[a++]=M[w++]))}break}}break}}while(n<o&&a<c);n-=b=f>>3,u&=(1<<(f-=b<<3))-1,e.next_in=n,e.next_out=a,e.avail_in=n<o?o-n+5:5-(n-o),e.avail_out=a<c?c-a+257:257-(a-c),s.hold=u,s.bits=f}},{}],49:[function(h,A,t){"use strict";var e=h("../utils/common"),i=h("./adler32"),s=h("./crc32"),n=h("./inffast"),o=h("./inftrees"),a=1,r=2,c=0,l=-2,d=1,I=852,g=592;function p(w){return(w>>>24&255)+(w>>>8&65280)+((65280&w)<<8)+((255&w)<<24)}function u(){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 f(w){var D;return w&&w.state?(D=w.state,w.total_in=w.total_out=D.total=0,w.msg="",D.wrap&&(w.adler=1&D.wrap),D.mode=d,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(I),D.distcode=D.distdyn=new e.Buf32(g),D.sane=1,D.back=-1,c):l}function B(w){var D;return w&&w.state?((D=w.state).wsize=0,D.whave=0,D.wnext=0,f(w)):l}function Q(w,D){var m,M;return w&&w.state?(M=w.state,D<0?(m=0,D=-D):(m=1+(D>>4),D<48&&(D&=15)),D&&(D<8||15<D)?l:(M.window!==null&&M.wbits!==D&&(M.window=null),M.wrap=m,M.wbits=D,B(w))):l}function E(w,D){var m,M;return w?(M=new u,(w.state=M).window=null,(m=Q(w,D))!==c&&(w.state=null),m):l}var y,v,k=!0;function b(w){if(k){var D;for(y=new e.Buf32(512),v=new e.Buf32(32),D=0;D<144;)w.lens[D++]=8;for(;D<256;)w.lens[D++]=9;for(;D<280;)w.lens[D++]=7;for(;D<288;)w.lens[D++]=8;for(o(a,w.lens,0,288,y,0,w.work,{bits:9}),D=0;D<32;)w.lens[D++]=5;o(r,w.lens,0,32,v,0,w.work,{bits:5}),k=!1}w.lencode=y,w.lenbits=9,w.distcode=v,w.distbits=5}function R(w,D,m,M){var _,O=w.state;return O.window===null&&(O.wsize=1<<O.wbits,O.wnext=0,O.whave=0,O.window=new e.Buf8(O.wsize)),M>=O.wsize?(e.arraySet(O.window,D,m-O.wsize,O.wsize,0),O.wnext=0,O.whave=O.wsize):(M<(_=O.wsize-O.wnext)&&(_=M),e.arraySet(O.window,D,m-M,_,O.wnext),(M-=_)?(e.arraySet(O.window,D,m-M,M,0),O.wnext=M,O.whave=O.wsize):(O.wnext+=_,O.wnext===O.wsize&&(O.wnext=0),O.whave<O.wsize&&(O.whave+=_))),0}t.inflateReset=B,t.inflateReset2=Q,t.inflateResetKeep=f,t.inflateInit=function(w){return E(w,15)},t.inflateInit2=E,t.inflate=function(w,D){var m,M,_,O,J,q,j,H,N,$,V,z,ct,gt,nt,at,rt,st,Ct,pt,C,P,T,S,F=0,x=new e.Buf8(4),K=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];if(!w||!w.state||!w.output||!w.input&&w.avail_in!==0)return l;(m=w.state).mode===12&&(m.mode=13),J=w.next_out,_=w.output,j=w.avail_out,O=w.next_in,M=w.input,q=w.avail_in,H=m.hold,N=m.bits,$=q,V=j,P=c;t:for(;;)switch(m.mode){case d:if(m.wrap===0){m.mode=13;break}for(;N<16;){if(q===0)break t;q--,H+=M[O++]<<N,N+=8}if(2&m.wrap&&H===35615){x[m.check=0]=255&H,x[1]=H>>>8&255,m.check=s(m.check,x,2,0),N=H=0,m.mode=2;break}if(m.flags=0,m.head&&(m.head.done=!1),!(1&m.wrap)||(((255&H)<<8)+(H>>8))%31){w.msg="incorrect header check",m.mode=30;break}if((15&H)!=8){w.msg="unknown compression method",m.mode=30;break}if(N-=4,C=8+(15&(H>>>=4)),m.wbits===0)m.wbits=C;else if(C>m.wbits){w.msg="invalid window size",m.mode=30;break}m.dmax=1<<C,w.adler=m.check=1,m.mode=512&H?10:12,N=H=0;break;case 2:for(;N<16;){if(q===0)break t;q--,H+=M[O++]<<N,N+=8}if(m.flags=H,(255&m.flags)!=8){w.msg="unknown compression method",m.mode=30;break}if(57344&m.flags){w.msg="unknown header flags set",m.mode=30;break}m.head&&(m.head.text=H>>8&1),512&m.flags&&(x[0]=255&H,x[1]=H>>>8&255,m.check=s(m.check,x,2,0)),N=H=0,m.mode=3;case 3:for(;N<32;){if(q===0)break t;q--,H+=M[O++]<<N,N+=8}m.head&&(m.head.time=H),512&m.flags&&(x[0]=255&H,x[1]=H>>>8&255,x[2]=H>>>16&255,x[3]=H>>>24&255,m.check=s(m.check,x,4,0)),N=H=0,m.mode=4;case 4:for(;N<16;){if(q===0)break t;q--,H+=M[O++]<<N,N+=8}m.head&&(m.head.xflags=255&H,m.head.os=H>>8),512&m.flags&&(x[0]=255&H,x[1]=H>>>8&255,m.check=s(m.check,x,2,0)),N=H=0,m.mode=5;case 5:if(1024&m.flags){for(;N<16;){if(q===0)break t;q--,H+=M[O++]<<N,N+=8}m.length=H,m.head&&(m.head.extra_len=H),512&m.flags&&(x[0]=255&H,x[1]=H>>>8&255,m.check=s(m.check,x,2,0)),N=H=0}else m.head&&(m.head.extra=null);m.mode=6;case 6:if(1024&m.flags&&(q<(z=m.length)&&(z=q),z&&(m.head&&(C=m.head.extra_len-m.length,m.head.extra||(m.head.extra=new Array(m.head.extra_len)),e.arraySet(m.head.extra,M,O,z,C)),512&m.flags&&(m.check=s(m.check,M,z,O)),q-=z,O+=z,m.length-=z),m.length))break t;m.length=0,m.mode=7;case 7:if(2048&m.flags){if(q===0)break t;for(z=0;C=M[O+z++],m.head&&C&&m.length<65536&&(m.head.name+=String.fromCharCode(C)),C&&z<q;);if(512&m.flags&&(m.check=s(m.check,M,z,O)),q-=z,O+=z,C)break t}else m.head&&(m.head.name=null);m.length=0,m.mode=8;case 8:if(4096&m.flags){if(q===0)break t;for(z=0;C=M[O+z++],m.head&&C&&m.length<65536&&(m.head.comment+=String.fromCharCode(C)),C&&z<q;);if(512&m.flags&&(m.check=s(m.check,M,z,O)),q-=z,O+=z,C)break t}else m.head&&(m.head.comment=null);m.mode=9;case 9:if(512&m.flags){for(;N<16;){if(q===0)break t;q--,H+=M[O++]<<N,N+=8}if(H!==(65535&m.check)){w.msg="header crc mismatch",m.mode=30;break}N=H=0}m.head&&(m.head.hcrc=m.flags>>9&1,m.head.done=!0),w.adler=m.check=0,m.mode=12;break;case 10:for(;N<32;){if(q===0)break t;q--,H+=M[O++]<<N,N+=8}w.adler=m.check=p(H),N=H=0,m.mode=11;case 11:if(m.havedict===0)return w.next_out=J,w.avail_out=j,w.next_in=O,w.avail_in=q,m.hold=H,m.bits=N,2;w.adler=m.check=1,m.mode=12;case 12:if(D===5||D===6)break t;case 13:if(m.last){H>>>=7&N,N-=7&N,m.mode=27;break}for(;N<3;){if(q===0)break t;q--,H+=M[O++]<<N,N+=8}switch(m.last=1&H,N-=1,3&(H>>>=1)){case 0:m.mode=14;break;case 1:if(b(m),m.mode=20,D!==6)break;H>>>=2,N-=2;break t;case 2:m.mode=17;break;case 3:w.msg="invalid block type",m.mode=30}H>>>=2,N-=2;break;case 14:for(H>>>=7&N,N-=7&N;N<32;){if(q===0)break t;q--,H+=M[O++]<<N,N+=8}if((65535&H)!=(H>>>16^65535)){w.msg="invalid stored block lengths",m.mode=30;break}if(m.length=65535&H,N=H=0,m.mode=15,D===6)break t;case 15:m.mode=16;case 16:if(z=m.length){if(q<z&&(z=q),j<z&&(z=j),z===0)break t;e.arraySet(_,M,O,z,J),q-=z,O+=z,j-=z,J+=z,m.length-=z;break}m.mode=12;break;case 17:for(;N<14;){if(q===0)break t;q--,H+=M[O++]<<N,N+=8}if(m.nlen=257+(31&H),H>>>=5,N-=5,m.ndist=1+(31&H),H>>>=5,N-=5,m.ncode=4+(15&H),H>>>=4,N-=4,286<m.nlen||30<m.ndist){w.msg="too many length or distance symbols",m.mode=30;break}m.have=0,m.mode=18;case 18:for(;m.have<m.ncode;){for(;N<3;){if(q===0)break t;q--,H+=M[O++]<<N,N+=8}m.lens[K[m.have++]]=7&H,H>>>=3,N-=3}for(;m.have<19;)m.lens[K[m.have++]]=0;if(m.lencode=m.lendyn,m.lenbits=7,T={bits:m.lenbits},P=o(0,m.lens,0,19,m.lencode,0,m.work,T),m.lenbits=T.bits,P){w.msg="invalid code lengths set",m.mode=30;break}m.have=0,m.mode=19;case 19:for(;m.have<m.nlen+m.ndist;){for(;at=(F=m.lencode[H&(1<<m.lenbits)-1])>>>16&255,rt=65535&F,!((nt=F>>>24)<=N);){if(q===0)break t;q--,H+=M[O++]<<N,N+=8}if(rt<16)H>>>=nt,N-=nt,m.lens[m.have++]=rt;else{if(rt===16){for(S=nt+2;N<S;){if(q===0)break t;q--,H+=M[O++]<<N,N+=8}if(H>>>=nt,N-=nt,m.have===0){w.msg="invalid bit length repeat",m.mode=30;break}C=m.lens[m.have-1],z=3+(3&H),H>>>=2,N-=2}else if(rt===17){for(S=nt+3;N<S;){if(q===0)break t;q--,H+=M[O++]<<N,N+=8}N-=nt,C=0,z=3+(7&(H>>>=nt)),H>>>=3,N-=3}else{for(S=nt+7;N<S;){if(q===0)break t;q--,H+=M[O++]<<N,N+=8}N-=nt,C=0,z=11+(127&(H>>>=nt)),H>>>=7,N-=7}if(m.have+z>m.nlen+m.ndist){w.msg="invalid bit length repeat",m.mode=30;break}for(;z--;)m.lens[m.have++]=C}}if(m.mode===30)break;if(m.lens[256]===0){w.msg="invalid code -- missing end-of-block",m.mode=30;break}if(m.lenbits=9,T={bits:m.lenbits},P=o(a,m.lens,0,m.nlen,m.lencode,0,m.work,T),m.lenbits=T.bits,P){w.msg="invalid literal/lengths set",m.mode=30;break}if(m.distbits=6,m.distcode=m.distdyn,T={bits:m.distbits},P=o(r,m.lens,m.nlen,m.ndist,m.distcode,0,m.work,T),m.distbits=T.bits,P){w.msg="invalid distances set",m.mode=30;break}if(m.mode=20,D===6)break t;case 20:m.mode=21;case 21:if(6<=q&&258<=j){w.next_out=J,w.avail_out=j,w.next_in=O,w.avail_in=q,m.hold=H,m.bits=N,n(w,V),J=w.next_out,_=w.output,j=w.avail_out,O=w.next_in,M=w.input,q=w.avail_in,H=m.hold,N=m.bits,m.mode===12&&(m.back=-1);break}for(m.back=0;at=(F=m.lencode[H&(1<<m.lenbits)-1])>>>16&255,rt=65535&F,!((nt=F>>>24)<=N);){if(q===0)break t;q--,H+=M[O++]<<N,N+=8}if(at&&!(240&at)){for(st=nt,Ct=at,pt=rt;at=(F=m.lencode[pt+((H&(1<<st+Ct)-1)>>st)])>>>16&255,rt=65535&F,!(st+(nt=F>>>24)<=N);){if(q===0)break t;q--,H+=M[O++]<<N,N+=8}H>>>=st,N-=st,m.back+=st}if(H>>>=nt,N-=nt,m.back+=nt,m.length=rt,at===0){m.mode=26;break}if(32&at){m.back=-1,m.mode=12;break}if(64&at){w.msg="invalid literal/length code",m.mode=30;break}m.extra=15&at,m.mode=22;case 22:if(m.extra){for(S=m.extra;N<S;){if(q===0)break t;q--,H+=M[O++]<<N,N+=8}m.length+=H&(1<<m.extra)-1,H>>>=m.extra,N-=m.extra,m.back+=m.extra}m.was=m.length,m.mode=23;case 23:for(;at=(F=m.distcode[H&(1<<m.distbits)-1])>>>16&255,rt=65535&F,!((nt=F>>>24)<=N);){if(q===0)break t;q--,H+=M[O++]<<N,N+=8}if(!(240&at)){for(st=nt,Ct=at,pt=rt;at=(F=m.distcode[pt+((H&(1<<st+Ct)-1)>>st)])>>>16&255,rt=65535&F,!(st+(nt=F>>>24)<=N);){if(q===0)break t;q--,H+=M[O++]<<N,N+=8}H>>>=st,N-=st,m.back+=st}if(H>>>=nt,N-=nt,m.back+=nt,64&at){w.msg="invalid distance code",m.mode=30;break}m.offset=rt,m.extra=15&at,m.mode=24;case 24:if(m.extra){for(S=m.extra;N<S;){if(q===0)break t;q--,H+=M[O++]<<N,N+=8}m.offset+=H&(1<<m.extra)-1,H>>>=m.extra,N-=m.extra,m.back+=m.extra}if(m.offset>m.dmax){w.msg="invalid distance too far back",m.mode=30;break}m.mode=25;case 25:if(j===0)break t;if(z=V-j,m.offset>z){if((z=m.offset-z)>m.whave&&m.sane){w.msg="invalid distance too far back",m.mode=30;break}ct=z>m.wnext?(z-=m.wnext,m.wsize-z):m.wnext-z,z>m.length&&(z=m.length),gt=m.window}else gt=_,ct=J-m.offset,z=m.length;for(j<z&&(z=j),j-=z,m.length-=z;_[J++]=gt[ct++],--z;);m.length===0&&(m.mode=21);break;case 26:if(j===0)break t;_[J++]=m.length,j--,m.mode=21;break;case 27:if(m.wrap){for(;N<32;){if(q===0)break t;q--,H|=M[O++]<<N,N+=8}if(V-=j,w.total_out+=V,m.total+=V,V&&(w.adler=m.check=m.flags?s(m.check,_,V,J-V):i(m.check,_,V,J-V)),V=j,(m.flags?H:p(H))!==m.check){w.msg="incorrect data check",m.mode=30;break}N=H=0}m.mode=28;case 28:if(m.wrap&&m.flags){for(;N<32;){if(q===0)break t;q--,H+=M[O++]<<N,N+=8}if(H!==(4294967295&m.total)){w.msg="incorrect length check",m.mode=30;break}N=H=0}m.mode=29;case 29:P=1;break t;case 30:P=-3;break t;case 31:return-4;case 32:default:return l}return w.next_out=J,w.avail_out=j,w.next_in=O,w.avail_in=q,m.hold=H,m.bits=N,(m.wsize||V!==w.avail_out&&m.mode<30&&(m.mode<27||D!==4))&&R(w,w.output,w.next_out,V-w.avail_out)?(m.mode=31,-4):($-=w.avail_in,V-=w.avail_out,w.total_in+=$,w.total_out+=V,m.total+=V,m.wrap&&V&&(w.adler=m.check=m.flags?s(m.check,_,V,w.next_out-V):i(m.check,_,V,w.next_out-V)),w.data_type=m.bits+(m.last?64:0)+(m.mode===12?128:0)+(m.mode===20||m.mode===15?256:0),($==0&&V===0||D===4)&&P===c&&(P=-5),P)},t.inflateEnd=function(w){if(!w||!w.state)return l;var D=w.state;return D.window&&(D.window=null),w.state=null,c},t.inflateGetHeader=function(w,D){var m;return w&&w.state&&2&(m=w.state).wrap?((m.head=D).done=!1,c):l},t.inflateSetDictionary=function(w,D){var m,M=D.length;return w&&w.state?(m=w.state).wrap!==0&&m.mode!==11?l:m.mode===11&&i(1,D,M,0)!==m.check?-3:R(w,D,M,M)?(m.mode=31,-4):(m.havedict=1,c):l},t.inflateInfo="pako inflate (from Nodeca project)"},{"../utils/common":41,"./adler32":43,"./crc32":45,"./inffast":48,"./inftrees":50}],50:[function(h,A,t){"use strict";var e=h("../utils/common"),i=[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],s=[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],o=[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];A.exports=function(a,r,c,l,d,I,g,p){var u,f,B,Q,E,y,v,k,b,R=p.bits,w=0,D=0,m=0,M=0,_=0,O=0,J=0,q=0,j=0,H=0,N=null,$=0,V=new e.Buf16(16),z=new e.Buf16(16),ct=null,gt=0;for(w=0;w<=15;w++)V[w]=0;for(D=0;D<l;D++)V[r[c+D]]++;for(_=R,M=15;1<=M&&V[M]===0;M--);if(M<_&&(_=M),M===0)return d[I++]=20971520,d[I++]=20971520,p.bits=1,0;for(m=1;m<M&&V[m]===0;m++);for(_<m&&(_=m),w=q=1;w<=15;w++)if(q<<=1,(q-=V[w])<0)return-1;if(0<q&&(a===0||M!==1))return-1;for(z[1]=0,w=1;w<15;w++)z[w+1]=z[w]+V[w];for(D=0;D<l;D++)r[c+D]!==0&&(g[z[r[c+D]]++]=D);if(y=a===0?(N=ct=g,19):a===1?(N=i,$-=257,ct=s,gt-=257,256):(N=n,ct=o,-1),w=m,E=I,J=D=H=0,B=-1,Q=(j=1<<(O=_))-1,a===1&&852<j||a===2&&592<j)return 1;for(;;){for(v=w-J,b=g[D]<y?(k=0,g[D]):g[D]>y?(k=ct[gt+g[D]],N[$+g[D]]):(k=96,0),u=1<<w-J,m=f=1<<O;d[E+(H>>J)+(f-=u)]=v<<24|k<<16|b|0,f!==0;);for(u=1<<w-1;H&u;)u>>=1;if(u!==0?(H&=u-1,H+=u):H=0,D++,--V[w]==0){if(w===M)break;w=r[c+g[D]]}if(_<w&&(H&Q)!==B){for(J===0&&(J=_),E+=m,q=1<<(O=w-J);O+J<M&&!((q-=V[O+J])<=0);)O++,q<<=1;if(j+=1<<O,a===1&&852<j||a===2&&592<j)return 1;d[B=H&Q]=_<<24|O<<16|E-I|0}}return H!==0&&(d[E+H]=w-J<<24|64<<16|0),p.bits=_,0}},{"../utils/common":41}],51:[function(h,A,t){"use strict";A.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(h,A,t){"use strict";var e=h("../utils/common"),i=0,s=1;function n(F){for(var x=F.length;0<=--x;)F[x]=0}var o=0,a=29,r=256,c=r+1+a,l=30,d=19,I=2*c+1,g=15,p=16,u=7,f=256,B=16,Q=17,E=18,y=[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],v=[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],k=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],b=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],R=new Array(2*(c+2));n(R);var w=new Array(2*l);n(w);var D=new Array(512);n(D);var m=new Array(256);n(m);var M=new Array(a);n(M);var _,O,J,q=new Array(l);function j(F,x,K,Y,U){this.static_tree=F,this.extra_bits=x,this.extra_base=K,this.elems=Y,this.max_length=U,this.has_stree=F&&F.length}function H(F,x){this.dyn_tree=F,this.max_code=0,this.stat_desc=x}function N(F){return F<256?D[F]:D[256+(F>>>7)]}function $(F,x){F.pending_buf[F.pending++]=255&x,F.pending_buf[F.pending++]=x>>>8&255}function V(F,x,K){F.bi_valid>p-K?(F.bi_buf|=x<<F.bi_valid&65535,$(F,F.bi_buf),F.bi_buf=x>>p-F.bi_valid,F.bi_valid+=K-p):(F.bi_buf|=x<<F.bi_valid&65535,F.bi_valid+=K)}function z(F,x,K){V(F,K[2*x],K[2*x+1])}function ct(F,x){for(var K=0;K|=1&F,F>>>=1,K<<=1,0<--x;);return K>>>1}function gt(F,x,K){var Y,U,W=new Array(g+1),tt=0;for(Y=1;Y<=g;Y++)W[Y]=tt=tt+K[Y-1]<<1;for(U=0;U<=x;U++){var X=F[2*U+1];X!==0&&(F[2*U]=ct(W[X]++,X))}}function nt(F){var x;for(x=0;x<c;x++)F.dyn_ltree[2*x]=0;for(x=0;x<l;x++)F.dyn_dtree[2*x]=0;for(x=0;x<d;x++)F.bl_tree[2*x]=0;F.dyn_ltree[2*f]=1,F.opt_len=F.static_len=0,F.last_lit=F.matches=0}function at(F){8<F.bi_valid?$(F,F.bi_buf):0<F.bi_valid&&(F.pending_buf[F.pending++]=F.bi_buf),F.bi_buf=0,F.bi_valid=0}function rt(F,x,K,Y){var U=2*x,W=2*K;return F[U]<F[W]||F[U]===F[W]&&Y[x]<=Y[K]}function st(F,x,K){for(var Y=F.heap[K],U=K<<1;U<=F.heap_len&&(U<F.heap_len&&rt(x,F.heap[U+1],F.heap[U],F.depth)&&U++,!rt(x,Y,F.heap[U],F.depth));)F.heap[K]=F.heap[U],K=U,U<<=1;F.heap[K]=Y}function Ct(F,x,K){var Y,U,W,tt,X=0;if(F.last_lit!==0)for(;Y=F.pending_buf[F.d_buf+2*X]<<8|F.pending_buf[F.d_buf+2*X+1],U=F.pending_buf[F.l_buf+X],X++,Y===0?z(F,U,x):(z(F,(W=m[U])+r+1,x),(tt=y[W])!==0&&V(F,U-=M[W],tt),z(F,W=N(--Y),K),(tt=v[W])!==0&&V(F,Y-=q[W],tt)),X<F.last_lit;);z(F,f,x)}function pt(F,x){var K,Y,U,W=x.dyn_tree,tt=x.stat_desc.static_tree,X=x.stat_desc.has_stree,it=x.stat_desc.elems,It=-1;for(F.heap_len=0,F.heap_max=I,K=0;K<it;K++)W[2*K]!==0?(F.heap[++F.heap_len]=It=K,F.depth[K]=0):W[2*K+1]=0;for(;F.heap_len<2;)W[2*(U=F.heap[++F.heap_len]=It<2?++It:0)]=1,F.depth[U]=0,F.opt_len--,X&&(F.static_len-=tt[2*U+1]);for(x.max_code=It,K=F.heap_len>>1;1<=K;K--)st(F,W,K);for(U=it;K=F.heap[1],F.heap[1]=F.heap[F.heap_len--],st(F,W,1),Y=F.heap[1],F.heap[--F.heap_max]=K,F.heap[--F.heap_max]=Y,W[2*U]=W[2*K]+W[2*Y],F.depth[U]=(F.depth[K]>=F.depth[Y]?F.depth[K]:F.depth[Y])+1,W[2*K+1]=W[2*Y+1]=U,F.heap[1]=U++,st(F,W,1),2<=F.heap_len;);F.heap[--F.heap_max]=F.heap[1],function(At,Nt){var Se,Ut,De,Qt,$e,Vi,Rt=Nt.dyn_tree,Ds=Nt.max_code,On=Nt.stat_desc.static_tree,Yn=Nt.stat_desc.has_stree,zn=Nt.stat_desc.extra_bits,bs=Nt.stat_desc.extra_base,be=Nt.stat_desc.max_length,je=0;for(Qt=0;Qt<=g;Qt++)At.bl_count[Qt]=0;for(Rt[2*At.heap[At.heap_max]+1]=0,Se=At.heap_max+1;Se<I;Se++)be<(Qt=Rt[2*Rt[2*(Ut=At.heap[Se])+1]+1]+1)&&(Qt=be,je++),Rt[2*Ut+1]=Qt,Ds<Ut||(At.bl_count[Qt]++,$e=0,bs<=Ut&&($e=zn[Ut-bs]),Vi=Rt[2*Ut],At.opt_len+=Vi*(Qt+$e),Yn&&(At.static_len+=Vi*(On[2*Ut+1]+$e)));if(je!==0){do{for(Qt=be-1;At.bl_count[Qt]===0;)Qt--;At.bl_count[Qt]--,At.bl_count[Qt+1]+=2,At.bl_count[be]--,je-=2}while(0<je);for(Qt=be;Qt!==0;Qt--)for(Ut=At.bl_count[Qt];Ut!==0;)Ds<(De=At.heap[--Se])||(Rt[2*De+1]!==Qt&&(At.opt_len+=(Qt-Rt[2*De+1])*Rt[2*De],Rt[2*De+1]=Qt),Ut--)}}(F,x),gt(W,It,F.bl_count)}function C(F,x,K){var Y,U,W=-1,tt=x[1],X=0,it=7,It=4;for(tt===0&&(it=138,It=3),x[2*(K+1)+1]=65535,Y=0;Y<=K;Y++)U=tt,tt=x[2*(Y+1)+1],++X<it&&U===tt||(X<It?F.bl_tree[2*U]+=X:U!==0?(U!==W&&F.bl_tree[2*U]++,F.bl_tree[2*B]++):X<=10?F.bl_tree[2*Q]++:F.bl_tree[2*E]++,W=U,It=(X=0)===tt?(it=138,3):U===tt?(it=6,3):(it=7,4))}function P(F,x,K){var Y,U,W=-1,tt=x[1],X=0,it=7,It=4;for(tt===0&&(it=138,It=3),Y=0;Y<=K;Y++)if(U=tt,tt=x[2*(Y+1)+1],!(++X<it&&U===tt)){if(X<It)for(;z(F,U,F.bl_tree),--X!=0;);else U!==0?(U!==W&&(z(F,U,F.bl_tree),X--),z(F,B,F.bl_tree),V(F,X-3,2)):X<=10?(z(F,Q,F.bl_tree),V(F,X-3,3)):(z(F,E,F.bl_tree),V(F,X-11,7));W=U,It=(X=0)===tt?(it=138,3):U===tt?(it=6,3):(it=7,4)}}n(q);var T=!1;function S(F,x,K,Y){V(F,(o<<1)+(Y?1:0),3),function(U,W,tt,X){at(U),X&&($(U,tt),$(U,~tt)),e.arraySet(U.pending_buf,U.window,W,tt,U.pending),U.pending+=tt}(F,x,K,!0)}t._tr_init=function(F){T||(function(){var x,K,Y,U,W,tt=new Array(g+1);for(U=Y=0;U<a-1;U++)for(M[U]=Y,x=0;x<1<<y[U];x++)m[Y++]=U;for(m[Y-1]=U,U=W=0;U<16;U++)for(q[U]=W,x=0;x<1<<v[U];x++)D[W++]=U;for(W>>=7;U<l;U++)for(q[U]=W<<7,x=0;x<1<<v[U]-7;x++)D[256+W++]=U;for(K=0;K<=g;K++)tt[K]=0;for(x=0;x<=143;)R[2*x+1]=8,x++,tt[8]++;for(;x<=255;)R[2*x+1]=9,x++,tt[9]++;for(;x<=279;)R[2*x+1]=7,x++,tt[7]++;for(;x<=287;)R[2*x+1]=8,x++,tt[8]++;for(gt(R,c+1,tt),x=0;x<l;x++)w[2*x+1]=5,w[2*x]=ct(x,5);_=new j(R,y,r+1,c,g),O=new j(w,v,0,l,g),J=new j(new Array(0),k,0,d,u)}(),T=!0),F.l_desc=new H(F.dyn_ltree,_),F.d_desc=new H(F.dyn_dtree,O),F.bl_desc=new H(F.bl_tree,J),F.bi_buf=0,F.bi_valid=0,nt(F)},t._tr_stored_block=S,t._tr_flush_block=function(F,x,K,Y){var U,W,tt=0;0<F.level?(F.strm.data_type===2&&(F.strm.data_type=function(X){var it,It=4093624447;for(it=0;it<=31;it++,It>>>=1)if(1&It&&X.dyn_ltree[2*it]!==0)return i;if(X.dyn_ltree[18]!==0||X.dyn_ltree[20]!==0||X.dyn_ltree[26]!==0)return s;for(it=32;it<r;it++)if(X.dyn_ltree[2*it]!==0)return s;return i}(F)),pt(F,F.l_desc),pt(F,F.d_desc),tt=function(X){var it;for(C(X,X.dyn_ltree,X.l_desc.max_code),C(X,X.dyn_dtree,X.d_desc.max_code),pt(X,X.bl_desc),it=d-1;3<=it&&X.bl_tree[2*b[it]+1]===0;it--);return X.opt_len+=3*(it+1)+5+5+4,it}(F),U=F.opt_len+3+7>>>3,(W=F.static_len+3+7>>>3)<=U&&(U=W)):U=W=K+5,K+4<=U&&x!==-1?S(F,x,K,Y):F.strategy===4||W===U?(V(F,2+(Y?1:0),3),Ct(F,R,w)):(V(F,4+(Y?1:0),3),function(X,it,It,At){var Nt;for(V(X,it-257,5),V(X,It-1,5),V(X,At-4,4),Nt=0;Nt<At;Nt++)V(X,X.bl_tree[2*b[Nt]+1],3);P(X,X.dyn_ltree,it-1),P(X,X.dyn_dtree,It-1)}(F,F.l_desc.max_code+1,F.d_desc.max_code+1,tt+1),Ct(F,F.dyn_ltree,F.dyn_dtree)),nt(F),Y&&at(F)},t._tr_tally=function(F,x,K){return F.pending_buf[F.d_buf+2*F.last_lit]=x>>>8&255,F.pending_buf[F.d_buf+2*F.last_lit+1]=255&x,F.pending_buf[F.l_buf+F.last_lit]=255&K,F.last_lit++,x===0?F.dyn_ltree[2*K]++:(F.matches++,x--,F.dyn_ltree[2*(m[K]+r+1)]++,F.dyn_dtree[2*N(x)]++),F.last_lit===F.lit_bufsize-1},t._tr_align=function(F){V(F,2,3),z(F,f,R),function(x){x.bi_valid===16?($(x,x.bi_buf),x.bi_buf=0,x.bi_valid=0):8<=x.bi_valid&&(x.pending_buf[x.pending++]=255&x.bi_buf,x.bi_buf>>=8,x.bi_valid-=8)}(F)}},{"../utils/common":41}],53:[function(h,A,t){"use strict";A.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(h,A,t){(function(e){(function(i,s){"use strict";if(!i.setImmediate){var n,o,a,r,c=1,l={},d=!1,I=i.document,g=Object.getPrototypeOf&&Object.getPrototypeOf(i);g=g&&g.setTimeout?g:i,n={}.toString.call(i.process)==="[object process]"?function(B){process.nextTick(function(){u(B)})}:function(){if(i.postMessage&&!i.importScripts){var B=!0,Q=i.onmessage;return i.onmessage=function(){B=!1},i.postMessage("","*"),i.onmessage=Q,B}}()?(r="setImmediate$"+Math.random()+"$",i.addEventListener?i.addEventListener("message",f,!1):i.attachEvent("onmessage",f),function(B){i.postMessage(r+B,"*")}):i.MessageChannel?((a=new MessageChannel).port1.onmessage=function(B){u(B.data)},function(B){a.port2.postMessage(B)}):I&&"onreadystatechange"in I.createElement("script")?(o=I.documentElement,function(B){var Q=I.createElement("script");Q.onreadystatechange=function(){u(B),Q.onreadystatechange=null,o.removeChild(Q),Q=null},o.appendChild(Q)}):function(B){setTimeout(u,0,B)},g.setImmediate=function(B){typeof B!="function"&&(B=new Function(""+B));for(var Q=new Array(arguments.length-1),E=0;E<Q.length;E++)Q[E]=arguments[E+1];var y={callback:B,args:Q};return l[c]=y,n(c),c++},g.clearImmediate=p}function p(B){delete l[B]}function u(B){if(d)setTimeout(u,0,B);else{var Q=l[B];if(Q){d=!0;try{(function(E){var y=E.callback,v=E.args;switch(v.length){case 0:y();break;case 1:y(v[0]);break;case 2:y(v[0],v[1]);break;case 3:y(v[0],v[1],v[2]);break;default:y.apply(s,v)}})(Q)}finally{p(B),d=!1}}}}function f(B){B.source===i&&typeof B.data=="string"&&B.data.indexOf(r)===0&&u(+B.data.slice(r.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 aa={};ei(aa,{default:()=>zi});module.exports=to(aa);var et=require("obsidian");yt();var Ft=require("obsidian");var Et=require("obsidian");yt();function ii(h){let A=(h.dateDisplayTimezone||"").trim();return A?{timeZone:A}:{}}function Pt(h,A){try{return new Intl.DateTimeFormat(void 0,A).format(new Date(h))}catch{let{timeZone:t,...e}=A;return new Intl.DateTimeFormat(void 0,e).format(new Date(h))}}function se(h,A){let t=ii(A);switch(A.dateDisplayFormat??"locale"){case"iso":return Rs(h,A,!0);case"us":return Pt(h,{...t,month:"numeric",day:"numeric",year:"numeric",hour:"numeric",minute:"2-digit"});case"eu":return Pt(h,{...t,day:"numeric",month:"numeric",year:"numeric",hour:"2-digit",minute:"2-digit",hourCycle:"h23"});case"long":return Pt(h,{...t,dateStyle:"full",timeStyle:"short"});case"locale":default:return Pt(h,{...t,dateStyle:"medium",timeStyle:"short"})}}function Ts(h,A){let t=ii(A);switch(A.dateDisplayFormat??"locale"){case"iso":return Rs(h,A,!1);case"us":return Pt(h,{...t,month:"numeric",day:"numeric",year:"numeric"});case"eu":return Pt(h,{...t,day:"numeric",month:"numeric",year:"numeric"});case"long":return Pt(h,{...t,dateStyle:"full"});case"locale":default:{let e=new Date,i=new Date(h).getFullYear()===e.getFullYear();return Pt(h,i?{...t,month:"short",day:"numeric"}:{...t,month:"short",day:"numeric",year:"numeric"})}}}function Gs(h,A){let t=ii(A),e=A.dateDisplayFormat==="iso"||A.dateDisplayFormat==="eu";return Pt(h,{...t,hour:e?"2-digit":"numeric",minute:"2-digit",...e?{hourCycle:"h23"}:{}})}function Rs(h,A,t){let e=ii(A),i=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(h)),s=o=>i.find(a=>a.type===o)?.value??"",n=`${s("year")}-${s("month")}-${s("day")}`;return t?`${n} ${s("hour")}:${s("minute")}`:n}function ai(h,A,t){let e=h.createSpan({cls:"stashpad-count-badge"});t&&e.addClass("is-expanded"),e.setText(A>99?"99+":String(A))}var Ke={pinned:{label:"Pinned",icon:"pin"},shared:{label:"Shared",icon:"users"},tasks:{label:"Tasks",icon:"check-circle-2"}},ri=class extends Et.ItemView{constructor(t,e){super(t);this.plugin=e;this.activePanel="pinned";this.taskFilter="all";this.taskAssignFilter="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 Yt}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()===ut&&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"}),i=e.createEl("button",{cls:"stashpad-panels-global-btn"});(0,Et.setIcon)(i.createSpan({cls:"stashpad-panels-global-btn-icon"}),"search"),i.createSpan({cls:"stashpad-panels-global-btn-text",text:"Search"}),i.onclick=()=>this.openSearchFromPanel();let s=e.createEl("button",{cls:"stashpad-panels-global-btn"});(0,Et.setIcon)(s.createSpan({cls:"stashpad-panels-global-btn-icon"}),"folder-tree"),s.createSpan({cls:"stashpad-panels-global-btn-text",text:"Folder Switcher"}),s.onclick=()=>this.plugin.openFolderPicker();let n=e.createDiv({cls:"stashpad-panels-globals-row"}),o=n.createEl("button",{cls:"stashpad-panels-global-btn"});(0,Et.setIcon)(o.createSpan({cls:"stashpad-panels-global-btn-icon"}),"scroll-text"),o.createSpan({cls:"stashpad-panels-global-btn-text",text:"Log"}),o.onclick=()=>this.openLogFromPanel();let a=n.createEl("button",{cls:"stashpad-panels-global-btn"});(0,Et.setIcon)(a.createSpan({cls:"stashpad-panels-global-btn-icon"}),"bell"),a.createSpan({cls:"stashpad-panels-global-btn-text",text:"Notifications"}),a.onclick=()=>this.openNotificationsFromPanel();let r=t.createDiv({cls:"stashpad-panels-bar"});for(let l of Object.keys(Ke)){let d=Ke[l],I=r.createEl("button",{cls:"stashpad-panels-bar-btn"});(0,Et.setIcon)(I.createSpan({cls:"stashpad-panels-bar-btn-icon"}),d.icon),I.createSpan({cls:"stashpad-panels-bar-btn-text",text:d.label}),this.activePanel===l&&I.addClass("is-active"),I.onclick=()=>{this.activePanel!==l&&(this.activePanel=l,this.render())}}let c=t.createDiv({cls:"stashpad-panels-body"});this.activePanel==="pinned"?this.renderPinnedPanel(c):this.activePanel==="shared"?this.renderSharedPanel(c):this.activePanel==="tasks"&&this.renderTasksPanel(c)}renderPinnedPanel(t){let e=t.createDiv({cls:"stashpad-panel-pinned"}),i=e.createEl("button",{cls:"stashpad-pinned-row stashpad-pinned-home"}),s=i.createSpan({cls:"stashpad-pinned-icon"});(0,Et.setIcon)(s,"home"),i.createSpan({cls:"stashpad-pinned-label",text:"Home"}),i.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 o=new Map;n.forEach((c,l)=>{let d=o.get(c.folder);d||(d=[],o.set(c.folder,d)),d.push({pin:c,idx:l})});let a=this.plugin.lastActiveStashpadLeaf?.view?.noteFolder,r=Array.from(o.keys());a&&o.has(a)&&(r.splice(r.indexOf(a),1),r.unshift(a));for(let c of r){let l=c.split("/").pop()||c,d=e.createDiv({cls:"stashpad-pinned-group-header"});c===a&&d.addClass("is-active-folder"),d.createSpan({cls:"stashpad-pinned-group-name",text:l});let I=o.get(c)??[];for(let{pin:g,idx:p}of I)this.renderPinnedRow(e,g,p)}}renderPinnedRow(t,e,i){let s=this.findFileFor(e);if(!s)return;let n=this.app.metadataCache.getFileCache(s)?.frontmatter??{},o=this.titleFromFile(s),a=typeof n.color=="string"?n.color:null,r=n.completed===!0,c=this.childrenOf(e.folder,e.id).length,l=c>0,d=this.expanded.has(`${e.folder}|${e.id}`),I=t.createDiv({cls:"stashpad-pinned-row"});a&&I.addClass("has-color"),r&&I.addClass("is-completed"),I.draggable=!0,I.dataset.pinIdx=String(i),I.addEventListener("dragstart",B=>{B.dataTransfer?.setData("text/plain",String(i)),B.dataTransfer&&(B.dataTransfer.effectAllowed="move"),I.addClass("is-dragging")}),I.addEventListener("dragend",()=>I.removeClass("is-dragging")),I.addEventListener("dragover",B=>{B.preventDefault(),B.dataTransfer&&(B.dataTransfer.dropEffect="move");let Q=I.getBoundingClientRect(),E=B.clientY-Q.top<Q.height/2;I.toggleClass("drop-before",E),I.toggleClass("drop-after",!E)}),I.addEventListener("dragleave",()=>{I.removeClass("drop-before"),I.removeClass("drop-after")}),I.addEventListener("drop",B=>{B.preventDefault(),I.removeClass("drop-before"),I.removeClass("drop-after");let Q=parseInt(B.dataTransfer?.getData("text/plain")??"",10);if(!Number.isFinite(Q)||Q===i)return;let E=I.getBoundingClientRect(),y=B.clientY-E.top<E.height/2;this.reorderPin(Q,y?i:i+1)});let g=I.createSpan({cls:"stashpad-pinned-toggle"});l&&(ai(g,c,d),g.onclick=B=>{B.stopPropagation();let Q=`${e.folder}|${e.id}`;this.expanded.has(Q)?this.expanded.delete(Q):this.expanded.add(Q),this.render()});let p=I.createSpan({cls:"stashpad-pinned-icon"});(0,Et.setIcon)(p,l?"folder-tree":"file-text"),a&&(p.style.color=a);let u=I.createSpan({cls:"stashpad-pinned-label",text:o});u.onclick=()=>this.openPinFromPanel(e);let f=e.folder.split("/").pop()||e.folder;if(I.createSpan({cls:"stashpad-pinned-folder",text:f}),I.oncontextmenu=B=>{B.preventDefault();let Q=new Et.Menu;Q.addItem(E=>E.setTitle("Unpin from sidebar").setIcon("pin-off").onClick(()=>{this.plugin.unpinNote(e)})),Q.showAtMouseEvent(B)},l&&d){let B=t.createDiv({cls:"stashpad-pinned-children"});this.renderPinnedSubtree(B,e.folder,e.id,1)}}async reorderPin(t,e){let i=(this.plugin.settings.pinnedNotes??[]).slice();if(t<0||t>=i.length)return;let[s]=i.splice(t,1),n=e>t?e-1:e;i.splice(Math.max(0,Math.min(n,i.length)),0,s),this.plugin.settings.pinnedNotes=i,await this.plugin.saveSettings(),this.render()}renderPinnedSubtree(t,e,i,s){let n=this.childrenOf(e,i);for(let o of n){let a=this.app.metadataCache.getFileCache(o)?.frontmatter??{},r=typeof a.id=="string"?a.id:null;if(!r)continue;let c=typeof a.color=="string"?a.color:null,l=a.completed===!0,d=this.childrenOf(e,r).length,I=d>0,g=this.expanded.has(`${e}|${r}`),p=t.createDiv({cls:"stashpad-pinned-subrow"});l&&p.addClass("is-completed"),p.style.paddingLeft=`${s*16}px`;let u=p.createSpan({cls:"stashpad-pinned-toggle"});I&&(ai(u,d,g),u.onclick=Q=>{Q.stopPropagation();let E=`${e}|${r}`;this.expanded.has(E)?this.expanded.delete(E):this.expanded.add(E),this.render()});let f=p.createSpan({cls:"stashpad-pinned-icon"});(0,Et.setIcon)(f,"file-text"),c&&(f.style.color=c);let B=p.createSpan({cls:"stashpad-pinned-label",text:this.titleFromFile(o)});B.onclick=()=>this.openPinFromPanel({folder:e,id:r}),I&&g&&this.renderPinnedSubtree(t,e,r,s+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 i=[];for(let s of this.app.vault.getMarkdownFiles()){if((s.parent?.path?.replace(/\/+$/,"")??"")!==t)continue;let o=this.app.metadataCache.getFileCache(s)?.frontmatter;if(!o||typeof o.id!="string")continue;let a=o.parent;if(a===e||e===G&&(a==null||a===G)){if(o.id===G)continue;i.push(s)}}return i.sort((s,n)=>{let o=this.app.metadataCache.getFileCache(s)?.frontmatter,a=this.app.metadataCache.getFileCache(n)?.frontmatter,r=o?.created??"",c=a?.created??"";return r.localeCompare(c)}),i}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 Et.Notice("No log yet \u2014 make some changes first.");return}let i=await t.read(e),{LogModal:s}=await Promise.resolve().then(()=>(Mt(),qe));new s(this.app,i,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(G)}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()===ut)return this.app.workspace.revealLeaf(t),t.view;let e=this.findActiveStashpad();if(e)return e;let i=this.app.workspace.getLeavesOfType(ut);return i.length>0?(this.app.workspace.revealLeaf(i[0]),i[0].view):(await this.plugin.activateView({reveal:!0}),this.findActiveStashpad())}findActiveStashpad(){let t=this.app.workspace.activeLeaf;return t&&t.view.getViewType()===ut?t.view:null}renderSharedPanel(t){let e=t.createDiv({cls:"stashpad-panel-shared"}),i=(this.plugin.settings.authorId??"").trim();if(!i){e.createDiv({cls:"stashpad-shared-empty"}).setText("Set an author name in Stashpad settings to populate Shared.");return}let s=this.collectSharedNotes(i),n=new Map;for(let l of s){let d=l.authorId;d&&!n.has(d)&&n.set(d,l.authorDisplay||d)}let o=e.createDiv({cls:"stashpad-shared-filters"}),a=(l,d,I)=>{let g=o.createEl("button",{cls:"stashpad-shared-chip",text:l});return d&&g.addClass("is-active"),g.onclick=I,g};if(a("All",this.sharedAuthorFilter==="all",()=>{this.sharedAuthorFilter="all",this.render()}),a("Mine",this.sharedAuthorFilter==="mine",()=>{this.sharedAuthorFilter="mine",this.render()}),a("Others",this.sharedAuthorFilter==="others",()=>{this.sharedAuthorFilter="others",this.render()}),n.size>1){let l=o.createEl("select",{cls:"stashpad-shared-author-select"}),d=l.createEl("option",{text:"Any author"});d.value="__any__";for(let[g,p]of n){let u=l.createEl("option",{text:p});u.value=g}let I=["all","mine","others"].includes(this.sharedAuthorFilter)?"__any__":this.sharedAuthorFilter;l.value=I,l.onchange=()=>{let g=l.value;g==="__any__"?this.sharedAuthorFilter="all":this.sharedAuthorFilter=g,this.render()}}let r=o.createEl("button",{cls:"stashpad-shared-chip",text:"Has contributors"});this.sharedContribOnly&&r.addClass("is-active"),r.onclick=()=>{this.sharedContribOnly=!this.sharedContribOnly,this.render()};let c=s.filter(l=>{if(this.sharedContribOnly&&l.contributorCount===0)return!1;switch(this.sharedAuthorFilter){case"all":return!0;case"mine":return l.authorId===i;case"others":return l.authorId!==i;default:return l.authorId===this.sharedAuthorFilter}});if(c.length===0){e.createDiv({cls:"stashpad-shared-empty"}).setText("No shared notes match the current filters.");return}for(let l of c){let d=e.createDiv({cls:"stashpad-pinned-row stashpad-shared-row"}),I=d.createSpan({cls:"stashpad-pinned-icon"});(0,Et.setIcon)(I,"users"),l.color&&(I.style.color=l.color);let g=d.createSpan({cls:"stashpad-pinned-label",text:l.title});g.onclick=()=>this.openSharedFromPanel(l.folder,l.id);let p=l.folder.split("/").pop()||l.folder;d.createSpan({cls:"stashpad-pinned-folder",text:p}),l.authorDisplay&&d.createSpan({cls:"stashpad-shared-meta"}).setText(l.authorId===i?`you \xB7 ${l.contributorCount} contributor${l.contributorCount===1?"":"s"}`:`by ${l.authorDisplay}${l.contributorCount>0?` \xB7 ${l.contributorCount} contributor${l.contributorCount===1?"":"s"}`:""}`)}}collectSharedNotes(t){let e=this.plugin.discoverStashpadFolders(),i=new Set(e),s=new Map;for(let o of this.app.vault.getMarkdownFiles()){let a=o.parent?.path?.replace(/\/+$/,"")??"";if(!i.has(a))continue;let r=this.app.metadataCache.getFileCache(o)?.frontmatter??{};r.id===G&&s.set(a,this.extractAuthorId(r.author))}let n=[];for(let o of this.app.vault.getMarkdownFiles()){let a=o.parent?.path?.replace(/\/+$/,"")??"";if(!i.has(a)||a.endsWith("/_authors")||o.path.includes("/_authors/"))continue;let r=this.app.metadataCache.getFileCache(o)?.frontmatter??{};if(typeof r.id!="string"||r.id===G)continue;let c=this.extractAuthorId(r.author),l=Array.isArray(r.contributors)?r.contributors.filter(Q=>typeof Q=="string"):[],d=s.get(a)??null;if(!(l.length>0||d===t&&(c!==null&&c!==t)))continue;let f=this.titleFromFile(o),B=typeof r.color=="string"?r.color:null;n.push({file:o,folder:a,id:r.id,title:f,color:B,authorId:c,authorDisplay:this.extractAuthorDisplay(r.author)||(c??""),contributorCount:l.length})}return n.sort((o,a)=>{let r=this.app.metadataCache.getFileCache(o.file)?.frontmatter??{},c=this.app.metadataCache.getFileCache(a.file)?.frontmatter??{},l=r.modified??r.created??"";return(c.modified??c.created??"").localeCompare(l)}),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 i=t.match(/_authors\/([^\]|]+)-[a-z0-9]{4,12}/i);return i?i[1].replace(/[-_]/g," ").trim():""}async openSharedFromPanel(t,e){await this.plugin.activateViewForFolder(t);let i=this.plugin.lastActiveStashpadLeaf?.view??this.findActiveStashpad();i&&typeof i.navigateTo=="function"&&i.navigateTo(e)}renderTasksPanel(t){let e=t.createDiv({cls:"stashpad-panel-tasks"}),i=this.collectTasks();if(i.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 s=(this.plugin.settings.authorId??"").trim(),n=w=>!!s&&w.assignedTo.some(D=>D.id===s),o=w=>{let D=this.taskAssignFilter;if(D.startsWith("person:")){let m=D.slice(7);return w.assignedTo.some(M=>M.id===m)}switch(D){case"mine":return n(w);case"others":return w.assignedTo.length>0&&!n(w);case"byme":return!!s&&w.assignedBy?.id===s;case"unassigned":return w.assignedTo.length===0;default:return!0}},a=new Map;for(let w of i){for(let D of w.assignedTo)D.id!==s&&a.set(D.id,D.name);w.assignedBy&&w.assignedBy.id!==s&&a.set(w.assignedBy.id,w.assignedBy.name)}let r=[...a.entries()].map(([w,D])=>({id:w,name:D})).sort((w,D)=>w.name.localeCompare(D.name)),c=e.createDiv({cls:"stashpad-task-assign-bar"});c.createSpan({cls:"stashpad-task-assign-label",text:"Assignment"});let l=c.createEl("select",{cls:"stashpad-task-assign-select"}),d=w=>{let D={all:"Everyone",mine:"Assigned to me",others:"Assigned to others",byme:"Assigned by me",unassigned:"Unassigned"};return w.startsWith("person:")?a.get(w.slice(7))??"Person":D[w]??w},I=w=>{let D=l.createEl("option",{text:d(w),value:w});this.taskAssignFilter===w&&(D.selected=!0)};for(let w of["all","mine","others","byme","unassigned"])I(w);if(r.length>0){let w=l.createEl("optgroup");w.setAttr("label","By person");for(let D of r){let m=w.createEl("option",{text:D.name,value:`person:${D.id}`});this.taskAssignFilter===`person:${D.id}`&&(m.selected=!0)}}l.onchange=()=>{this.taskAssignFilter=l.value,this.render()};let g=i.filter(o);if(g.length===0){e.createDiv({cls:"stashpad-tasks-empty"}).setText(`No tasks match "${d(this.taskAssignFilter)}".`);return}let p=new Date;p.setHours(0,0,0,0);let u=p.getTime(),f=u+24*60*60*1e3,B={overdue:[],today:[],upcoming:[],nodate:[],completed:[]};for(let w of g){if(w.completed){B.completed.push(w);continue}if(w.due==null){B.nodate.push(w);continue}w.due<u?B.overdue.push(w):w.due<f?B.today.push(w):B.upcoming.push(w)}let Q=(w,D)=>w.due==null&&D.due==null?w.title.localeCompare(D.title):w.due==null?1:D.due==null?-1:w.due-D.due,E=[{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"}],y=e.createDiv({cls:"stashpad-task-filters"}),v=g.length,k=(w,D,m)=>{let M=y.createEl("button",{cls:"stashpad-task-filter"});this.taskFilter===w&&M.addClass("is-active"),M.createSpan({cls:"stashpad-task-filter-label",text:D}),M.createSpan({cls:"stashpad-task-filter-count",text:String(m)}),M.onclick=()=>{this.taskFilter=w,this.render()}};k("all","All",v),k("overdue","Overdue",B.overdue.length),k("today","Today",B.today.length),k("upcoming","Upcoming",B.upcoming.length),k("nodate","No date",B.nodate.length),k("completed","Done",B.completed.length);let b=this.taskFilter==="all"?E:E.filter(w=>w.key===this.taskFilter),R=!1;for(let w of b){let D=B[w.key];if(D.length!==0){if(R=!0,D.sort(w.key==="completed"?(m,M)=>Q(M,m):Q),this.taskFilter==="all"){let m=e.createDiv({cls:`stashpad-task-section-header is-${w.key}`});(0,Et.setIcon)(m.createSpan({cls:"stashpad-task-section-icon"}),w.icon),m.createSpan({cls:"stashpad-task-section-name",text:w.label}),m.createSpan({cls:"stashpad-task-section-count",text:String(D.length)})}for(let m of D)this.renderTaskRow(e,m,w.key==="today")}}if(!R&&this.taskFilter!=="all"){e.createDiv({cls:"stashpad-tasks-empty"}).setText(`Nothing in "${b[0]?.label??this.taskFilter}".`);return}R||e.createDiv({cls:"stashpad-tasks-empty"}).setText("No tasks to show.")}renderTaskRow(t,e,i){let s=t.createDiv({cls:"stashpad-pinned-row stashpad-task-row"});e.color&&s.addClass("has-color"),e.completed&&s.addClass("is-completed");let n=s.createSpan({cls:"stashpad-pinned-icon stashpad-task-checkbox"});(0,Et.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=a=>{a.stopPropagation(),this.toggleTaskCompleted(e)};let o=s.createSpan({cls:"stashpad-pinned-label",text:e.title});if(o.onclick=()=>this.openTaskFromPanel(e.folder,e.id),s.createSpan({cls:"stashpad-task-folder",text:e.folder.split("/").pop()||e.folder}),e.due!=null){let a=s.createSpan({cls:"stashpad-task-due",text:this.formatDueShort(e.due,i)});e.due<Date.now()&&!e.completed&&a.addClass("is-overdue")}else e.dueRaw&&s.createSpan({cls:"stashpad-task-due",text:e.dueRaw});if(e.assignedTo.length>0){let a=(this.plugin.settings.authorId??"").trim(),r=s.createSpan({cls:"stashpad-task-assignees"});for(let c of e.assignedTo){let l=r.createSpan({cls:"stashpad-task-assignee"});a&&c.id===a&&l.addClass("is-me"),l.setText(this.initials(c.name)),l.title=a&&c.id===a?`${c.name} (you)`:c.name}}s.oncontextmenu=a=>{a.preventDefault();let r=new Et.Menu;r.addItem(c=>c.setTitle("Open").setIcon("arrow-right").onClick(()=>{this.openTaskFromPanel(e.folder,e.id)})),r.showAtMouseEvent(a)}}formatDueShort(t,e){return e?Gs(t,this.plugin.settings):Ts(t,this.plugin.settings)}async openTaskFromPanel(t,e){await this.plugin.activateViewForFolder(t);let i=this.plugin.lastActiveStashpadLeaf?.view??this.findActiveStashpad();i&&typeof i.navigateTo=="function"&&i.navigateTo(e)}async toggleTaskCompleted(t){try{await this.app.fileManager.processFrontMatter(t.file,e=>{e.completed=e.completed!==!0})}catch(e){new Et.Notice(`Couldn't update task: ${e.message}`);return}this.scheduleRender()}initials(t){let e=t.trim().split(/\s+/).filter(Boolean);return e.length===0?"?":e.length===1?e[0].slice(0,2).toUpperCase():(e[0][0]+e[e.length-1][0]).toUpperCase()}collectTasks(){let t=this.plugin.discoverStashpadFolders(),e=new Set(t),i=[];for(let s of this.app.vault.getMarkdownFiles()){let n=s.parent?.path?.replace(/\/+$/,"")??"";if(!e.has(n))continue;let o=this.app.metadataCache.getFileCache(s)?.frontmatter??{},a=typeof o.id=="string"?o.id:null;if(!a||a===G)continue;let r=o.completed===!0,c=ee(o,"task")||o.task===!0||o.completed!==void 0,l=typeof o.due=="string"||typeof o.due=="number"?String(o.due):null,d=null;if(l){let I=Date.parse(l);Number.isNaN(I)||(d=I)}!c&&!r&&d==null&&!l||i.push({file:s,folder:n,id:a,title:this.titleFromFile(s),task:c,completed:r,due:d,dueRaw:l,color:typeof o.color=="string"?o.color:null,assignedTo:Me(o),assignedBy:xe(o.assignedBy)})}return i}};async function Ai(h){let A=h.workspace.getLeavesOfType(Yt);if(A.length>0){h.workspace.revealLeaf(A[0]);return}let t=h.workspace.getLeftLeaf(!1);if(!t){new Et.Notice("Stashpad: couldn't open the panels view.");return}await t.setViewState({type:Yt,active:!0}),h.workspace.revealLeaf(t)}var $s=require("obsidian");yt();var Z=require("obsidian");Ye();var hi=require("obsidian");yt();var Be=class extends hi.AbstractInputSuggest{constructor(t,e){super(t,e);this.inputEl=e}getSuggestions(t){let e=t.toLowerCase().split(/\s+/).filter(Boolean),i=o=>e.every(a=>o.toLowerCase().includes(a)),s=[],n=o=>{if(!(o.path!=="/"&&Ne.has(o.name))){o.path!=="/"&&i(o.path)&&s.push(o);for(let a of o.children)a instanceof hi.TFolder&&n(a)}};return n(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()}};yt();Mt();var re=require("obsidian"),ss={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."}},ro={info:4e3,success:4e3,warning:6e3,error:1e4},zs=5e3,gi=class{constructor(A){this.app=A;this.history=[];this.nextId=1;this.historyLimit=zs;this.changeListeners=new Set;this.muted=new Set;this.defaultAuthorId=null}setDefaultAuthorId(A){this.defaultAuthorId=A||null}show(A){let t=A.kind??"info",e=A.category??"system",i={id:this.nextId++,ts:Date.now(),message:A.message,kind:t,category:e,authorId:A.authorId??this.defaultAuthorId??void 0,affectedIds:A.affectedIds?A.affectedIds.slice():[],affectedPaths:A.affectedPaths?A.affectedPaths.slice():[],affectedAuthorIds:A.affectedAuthorIds?A.affectedAuthorIds.slice():[],folder:A.folder,actionLabels:(A.actions??[]).map(o=>o.label)};if(this.pushHistory(i),this.muted.has(e))return null;let s=this.buildContent(A,t),n=A.duration??ro[t];return new re.Notice(s,n)}onChange(A){return this.changeListeners.add(A),()=>this.changeListeners.delete(A)}recent(){return this.history.slice().reverse()}clearHistory(){this.history=[],this.emit()}setMuted(A,t){t?this.muted.add(A):this.muted.delete(A)}isMuted(A){return this.muted.has(A)}loadMutedFromList(A){this.muted=new Set(A)}mutedList(){return Array.from(this.muted)}loadHistory(A){let t=this.applyLimit(A.slice());this.history=t;let e=0;for(let i of t)i.id>e&&(e=i.id);this.nextId=Math.max(this.nextId,e+1),this.emit()}setHistoryLimit(A){this.historyLimit=Number.isFinite(A)?A:zs,this.history=this.applyLimit(this.history),this.emit()}applyLimit(A){return this.historyLimit<=0||A.length<=this.historyLimit?A:A.slice(A.length-this.historyLimit)}pushHistory(A){this.history.push(A),this.history=this.applyLimit(this.history),this.emit()}emit(){for(let A of this.changeListeners)try{A()}catch(t){console.warn("[Stashpad] notification listener failed",t)}}buildContent(A,t){let e=document.createDocumentFragment(),i=document.createElement("div");i.className=`stashpad-notice stashpad-notice-${t}`;let s=document.createElement("div");s.className="stashpad-notice-message";let n=A.message.split(/(`[^`\n]+`)/);for(let o of n)if(o.length>1&&o.startsWith("`")&&o.endsWith("`")){let a=document.createElement("code");a.textContent=o.slice(1,-1),s.appendChild(a)}else o.length>0&&s.appendChild(document.createTextNode(o));if(i.appendChild(s),A.actions&&A.actions.length>0){let o=document.createElement("div");o.className="stashpad-notice-actions";for(let a of A.actions){let r=document.createElement("button");r.className="stashpad-notice-action",r.textContent=a.label,r.addEventListener("click",c=>{if(c.stopPropagation(),Promise.resolve().then(()=>a.onClick()).catch(l=>console.warn("[Stashpad] notification action failed",l)),!a.keepOpen){let l=r.closest(".notice");l&&l.parentElement&&l.parentElement.removeChild(l)}}),o.appendChild(r)}i.appendChild(o)}return e.appendChild(i),e}};function Ii(h,A,t){let e=h.vault.getAbstractFileByPath(A);if(!(e instanceof re.TFile))return[];let i=[{label:"Reveal",keepOpen:!0,onClick:()=>{let s=h.workspace.getLeavesOfType("file-explorer")[0];if(!s)return;h.workspace.revealLeaf(s),s.view?.revealInFolder?.(e)}}];if(!t){let s=re.Platform.isMacOS?"Finder":re.Platform.isWin?"File Explorer":"file manager";i.push({label:`Show in ${s}`,keepOpen:!0,onClick:()=>{try{let n=window.require?.("electron")?.shell,a=h.vault.adapter?.getFullPath?.(A);a&&n?.showItemInFolder&&n.showItemInFolder(a)}catch(n){console.warn("[Stashpad] showItemInFolder failed",n)}}})}return i}var ns=(()=>{try{return typeof navigator<"u"&&/Mac|iPhone|iPad|iPod/i.test(navigator.platform||navigator.userAgent||"")}catch{return!1}})();function os(h){if(!h)return"(none)";let A=h.replace(/\bMod\b/g,ns?"Cmd":"Ctrl");return ns&&(A=A.replace(/\bAlt\b/g,"Option")),A}function Vs(h,A,t={allowSingleKey:!0}){let e=h.placeholder,i=h.value;h.placeholder="Press a key\u2026 (Backspace to cancel)",h.value="",h.classList.add("is-recording");let s=!1,n=()=>{h.placeholder=e,h.classList.remove("is-recording"),s||(h.value=i),h.removeEventListener("keydown",o,!0),h.removeEventListener("blur",a)},o=r=>{if(r.key==="Control"||r.key==="Shift"||r.key==="Alt"||r.key==="Meta"||r.key==="OS")return;let c=!!r.code&&(/^Key[A-Z]$/.test(r.code)||/^Digit\d$/.test(r.code));if((r.key==="Dead"||r.key==="Process"||r.key==="Unidentified")&&!c)return;if(r.preventDefault(),r.stopPropagation(),r.key==="Backspace"&&!r.metaKey&&!r.ctrlKey&&!r.altKey&&!r.shiftKey){n();return}let l=[];ns?(r.metaKey&&l.push("Mod"),r.ctrlKey&&l.push("Ctrl")):r.ctrlKey&&l.push("Mod"),r.altKey&&l.push("Alt"),r.shiftKey&&l.push("Shift");let d=Ao(r.key,r.code);if(!d||l.length===0&&!t.allowSingleKey)return;l.push(d);let I=l.join("+");s=!0,n(),A(I)},a=()=>n();return h.addEventListener("keydown",o,!0),h.addEventListener("blur",a),n}function Ao(h,A){if(!h)return"";if(A){let t=/^Key([A-Z])$/.exec(A);if(t)return t[1];let e=/^Digit(\d)$/.exec(A);if(e)return e[1]}return h.length===1?h.toUpperCase():h}ue();Tt();var ze=null,pi=new Set;function ui(h){if(ze!==h){ze=h;for(let A of pi)A()}}function Lt(){return ze}function Ws(h){if(ze===h){ze=null;for(let A of pi)A()}}function Xs(h){return pi.add(h),()=>pi.delete(h)}function co(){return Z.Platform.isMacOS?"Finder":Z.Platform.isWin?"File Explorer":"file manager"}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"},{id:"jumpToTop",label:"Jump to top of list",desc:"Default: Home \u2014 move the cursor to the first note in the current list.",defaultPrimary:"Home"},{id:"jumpToBottom",label:"Jump to bottom of list",desc:"Default: End \u2014 move the cursor to the last note in the current list.",defaultPrimary:"End"}];function rs(){let h={};for(let A of Ve)h[A.id]={primary:A.defaultPrimary,secondary:"",preferRight:!1};return h}var Vt={folder:"Stashpad",importDropFolder:"",exportFolder:"_exports",autoImport:!1,inheritObsidianExclusions:!0,enablePerfProfiling:!1,writeRecoveryLinks:!0,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:{},attachmentsOnlyNotes:{},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:rs()},Zs=JSON.parse(JSON.stringify(Vt)),as=new Set;function Bt(){return Zs}function As(h){Zs=h;for(let A of as)A()}function _s(h){return as.add(h),()=>as.delete(h)}function Ci(h){try{let A=h.internalPlugins?.plugins?.templates;if(!A?.enabled)return null;let t=A.instance?.options??{};return{dateFormat:t.dateFormat||"YYYY-MM-DD",timeFormat:t.timeFormat||"HH:mm"}}catch{return null}}var fi=[{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"}],Bi=class extends Z.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 i=t.createDiv({cls:"stashpad-settings-search-wrap"}).createEl("input",{type:"text",placeholder:"Search settings\u2026",cls:"stashpad-settings-search-input"});i.value=this.searchQuery;let s=this.searchQuery.trim().length>0,n=t.createDiv({cls:"stashpad-settings-tabs"});s&&n.addClass("is-search-mode");for(let r of fi){let c=n.createEl("button",{cls:"stashpad-settings-tab",text:r.label});!s&&this.activeTab===r.id&&c.addClass("is-active"),c.onclick=()=>{this.searchQuery="",this.activeTab=r.id,this.display()}}let o=t.createDiv({cls:"stashpad-settings-body"});if(s){for(let r of fi){let c=o.createDiv({cls:"stashpad-settings-search-group"});c.createEl("h3",{text:r.label,cls:"stashpad-settings-search-group-header"});let l=c.createDiv();this.renderTabContent(l,r.id)}this.applySearchFilter(o)}else this.renderTabContent(o,this.activeTab);let a=s;i.oninput=()=>{this.searchQuery=i.value;let r=this.searchQuery.trim().length>0;if(r!==a){let c=i.selectionStart??i.value.length;this.display();let l=t.querySelector(".stashpad-settings-search-input");l&&(l.focus(),l.setSelectionRange(c,c));return}r&&this.applySearchFilter(o)},this.searchQuery&&setTimeout(()=>{i.focus(),i.setSelectionRange(i.value.length,i.value.length)},0)}applySearchFilter(t){let e=this.searchQuery.trim().toLowerCase();if(!e)return;let i=e.split(/\s+/).filter(Boolean),s=o=>i.every(a=>o.includes(a));t.querySelectorAll(".setting-item").forEach(o=>{let a=o.querySelector(".setting-item-name")?.textContent?.toLowerCase()??"",r=o.querySelector(".setting-item-description")?.textContent?.toLowerCase()??"";o.style.display=s(`${a} ${r}`)?"":"none"}),t.querySelectorAll(".stashpad-settings-search-group").forEach(o=>{let a=Array.from(o.querySelectorAll(".setting-item")).some(r=>r.style.display!=="none");o.style.display=a?"":"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 Z.Setting(t).setName("Write recovery navigation links").setDesc("Maintain the redundant parentLink/children frontmatter so you can walk the hierarchy from raw Markdown if the index ever breaks. On a slow / network drive this is a big per-move cost (several round-trips each); turn it off there for snappier moves \u2014 Rebootstrap rebuilds the fields on demand, and your notes' canonical structure (id/parent) is unaffected either way.").addToggle(o=>o.setValue(this.plugin.settings.writeRecoveryLinks).onChange(async a=>{this.plugin.settings.writeRecoveryLinks=a,await this.plugin.saveSettings()})),new Z.Setting(t).setName("Performance profiling").setDesc("Record timing for list rendering, body reads, and file writes. Turn on, use Stashpad normally (especially the slow operations), then run \u201CDump performance profile\u201D from the command palette and share the result. Off = zero overhead.").addToggle(o=>o.setValue(this.plugin.settings.enablePerfProfiling).onChange(async a=>{this.plugin.settings.enablePerfProfiling=a,await this.plugin.saveSettings()})),new Z.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(o=>o.setButtonText("Open log").onClick(async()=>{let a=this.app.vault.adapter,r=this.plugin.pluginPrivatePath("log.jsonl");if(!await a.exists(r)){new Z.Notice("No log yet \u2014 make some changes first.");return}let c=await a.read(r);new ge(this.app,c,r).open()})),new Z.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(o=>o.setValue(String(this.plugin.settings.notificationHistoryLimit??5e3)).setPlaceholder("5000").onChange(async a=>{let r=parseInt(a,10);Number.isFinite(r)&&(this.plugin.settings.notificationHistoryLimit=r,this.plugin.notifications.setHistoryLimit(r),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 s=new Set(this.plugin.settings.mutedNotificationCategories??[]),n=Object.keys(ss);for(let o of n){let a=ss[o];new Z.Setting(e).setName(a.label).setDesc(a.desc).addToggle(r=>r.setValue(!s.has(o)).onChange(async c=>{let l=!c;l?s.add(o):s.delete(o),this.plugin.settings.mutedNotificationCategories=Array.from(s),this.plugin.notifications.setMuted(o,l),await this.plugin.saveSettings()}))}new Z.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(o=>o.setButtonText("View notification history").onClick(()=>{new Le(this.app,this.plugin.notifications,async a=>{let r=this.app.vault.adapter,c=this.plugin.pluginPrivatePath("log.jsonl");if(!await r.exists(c)){new Z.Notice("No log yet \u2014 make some changes first.");return}let l=await r.read(c);new ge(this.app,l,c).open()},this.plugin.settings.authorId||null,a=>this.plugin.lookupNoteAuthorIds(a)).open()}))}renderGeneralTab(t){new Z.Setting(t).setName("Stashpad notes folder").setDesc("Vault-relative folder where Stashpad stores its notes and attachments. Created on demand.").addText(s=>{new Be(this.app,s.inputEl),s.setValue(this.plugin.settings.folder).setPlaceholder("Stashpad").onChange(async n=>{let o=(n||"").trim().replace(/^\/+|\/+$/g,"")||Vt.folder,a=o.split("/").filter(Boolean).pop()??"";if(new Set([this.plugin.settings.importDropFolder,this.plugin.settings.exportFolder,"_attachments","_processed"].map(c=>(c??"").trim().replace(/^\/+|\/+$/g,"")).filter(Boolean)).has(a)){new Z.Notice(`"${o}" uses a reserved Stashpad subfolder name. Pick something else.`);return}this.plugin.settings.folder=o,await this.plugin.saveSettings()})}),new Z.Setting(t).setName("Auto-import dropped files").setDesc("When on, any file you drop directly into a Stashpad folder is imported automatically: markdown becomes a note (the original is archived to .archive); other files move to _attachments with a note that links to them. Large drops ask for confirmation first.").addToggle(s=>s.setValue(this.plugin.settings.autoImport).onChange(async n=>{this.plugin.settings.autoImport=n,await this.plugin.saveSettings()})),new Z.Setting(t).setName("Inherit Obsidian's excluded files").setDesc("Also hide files matching Obsidian's \u201CExcluded files\u201D list (Settings \u2192 Files & Links) from Stashpad's link autocomplete and file surfaces \u2014 so you manage exclusions in one place. Plugin-internal formats like .edtz are always excluded regardless.").addToggle(s=>s.setValue(this.plugin.settings.inheritObsidianExclusions).onChange(async n=>{this.plugin.settings.inheritObsidianExclusions=n,await this.plugin.saveSettings()})),new Z.Setting(t).setName("Dedicated import subfolder (optional)").setDesc("Optional. A subfolder (relative to each Stashpad folder) where dropped .stash files auto-import. Leave blank to just drop files into the Stashpad folder itself (recommended). Suggested name: _imports.").addText(s=>s.setValue(this.plugin.settings.importDropFolder).setPlaceholder("_imports (leave blank to use the folder root)").onChange(async n=>{this.plugin.settings.importDropFolder=(n||"").trim().replace(/^\/+|\/+$/g,""),await this.plugin.saveSettings()})),new Z.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(s=>s.setValue(this.plugin.settings.exportFolder).setPlaceholder("_exports").onChange(async n=>{let o=(n||"").trim().replace(/^\/+|\/+$/g,"")||Vt.exportFolder;this.plugin.settings.exportFolder=o,await this.plugin.saveSettings()})),new Z.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(s=>s.setButtonText("Rebootstrap now").onClick(async()=>{s.setDisabled(!0).setButtonText("Working\u2026");try{let{touched:n,fmChecked:o,fmWritten:a,slugsRenamed:r,authors:c,imported:l,attachmentsLinked:d}=await this.plugin.rebootstrapAllFolders(),I=[];I.push(`rebootstrapped ${n.length} folder${n.length===1?"":"s"}`),l>0&&I.push(`imported ${l} loose file${l===1?"":"s"}`),d>0&&I.push(`linked attachments on ${d} note${d===1?"":"s"}`),a>0?I.push(`updated frontmatter on ${a} of ${o} notes`):o>0&&I.push(`frontmatter already in sync (${o} notes checked)`),r>0&&I.push(`renamed ${r} note${r===1?"":"s"} to match body`),c>0&&I.push(`rebuilt author registry (${c} author${c===1?"":"s"})`),new Z.Notice(`Stashpad: ${I.join("; ")}.`)}catch(n){new Z.Notice(`Stashpad: rebootstrap failed (${n.message})`)}finally{s.setDisabled(!1).setButtonText("Rebootstrap now")}})),new Z.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(s=>s.setValue(this.plugin.settings.useTemplatesFormat).onChange(async n=>{this.plugin.settings.useTemplatesFormat=n,await this.plugin.saveSettings()}));let e=Ci(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 s=null,n=()=>{if(!s)return;let o=Date.now(),a=se(o,this.plugin.settings);s.setText(`Sample: ${a}`)};new Z.Setting(t).setName("Date display format").setDesc("How due dates and created/modified times are shown in the Tasks and detail panels.").addDropdown(o=>{o.addOption("locale","Locale, short (Mar 5, 9:00 AM)"),o.addOption("long","Locale, long (Thursday, March 5\u2026)"),o.addOption("iso","ISO (2026-03-05 09:00)"),o.addOption("us","US (3/5/2026, 9:00 AM)"),o.addOption("eu","EU (5/3/2026, 09:00)"),o.setValue(this.plugin.settings.dateDisplayFormat??"locale"),o.onChange(async a=>{this.plugin.settings.dateDisplayFormat=a,await this.plugin.saveSettings(),n()})}),new Z.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(o=>{o.setPlaceholder("(system timezone)"),o.setValue(this.plugin.settings.dateDisplayTimezone??""),o.onChange(async a=>{this.plugin.settings.dateDisplayTimezone=(a||"").trim(),await this.plugin.saveSettings(),n()})}),s=t.createDiv({cls:"setting-item-description stashpad-settings-note"}),n()}new Z.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(s=>s.setValue(this.plugin.settings.autoNavOnMoveIn).onChange(async n=>{this.plugin.settings.autoNavOnMoveIn=n,await this.plugin.saveSettings()})),new Z.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(s=>s.setValue(this.plugin.settings.autoNavOnMoveOut).onChange(async n=>{this.plugin.settings.autoNavOnMoveOut=n,await this.plugin.saveSettings()})),new Z.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(s=>s.setValue(this.plugin.settings.doubleClickToFocus).onChange(async n=>{this.plugin.settings.doubleClickToFocus=n,await this.plugin.saveSettings()})),new Z.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(s=>s.setValue(this.plugin.settings.autoOpenDetailPanel).onChange(async n=>{this.plugin.settings.autoOpenDetailPanel=n,await this.plugin.saveSettings()})),new Z.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(s=>s.setValue(this.plugin.settings.autoExpandCursorRow).onChange(async n=>{this.plugin.settings.autoExpandCursorRow=n,await this.plugin.saveSettings()})),new Z.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(s=>s.setValue(this.plugin.settings.confirmCrossParentDrag).onChange(async n=>{this.plugin.settings.confirmCrossParentDrag=n,await this.plugin.saveSettings()})),new Z.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(s=>s.setValue(this.plugin.settings.confirmBulkDelete).onChange(async n=>{this.plugin.settings.confirmBulkDelete=n,await this.plugin.saveSettings()})),new Z.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(s=>s.setValue(this.plugin.settings.confirmAttachmentDelete).onChange(async n=>{this.plugin.settings.confirmAttachmentDelete=n,await this.plugin.saveSettings()}));{let s=null,n=(this.plugin.settings.slugStopWords?.length?this.plugin.settings.slugStopWords:Gt).join(` -`);new Z.Setting(t).setName("Slug stop-words").setDesc("Words removed from auto-generated note titles (filenames). One per line.").addTextArea(o=>{o.setValue(n),s=o.inputEl,s.rows=6,s.style.fontFamily="var(--font-monospace)",o.onChange(async a=>{let r=(a||"").split(/\r?\n/).map(c=>c.trim().toLowerCase()).filter(Boolean);this.plugin.settings.slugStopWords=r,await this.plugin.saveSettings()})}).addExtraButton(o=>o.setIcon("rotate-ccw").setTooltip("Reset to defaults").onClick(async()=>{this.plugin.settings.slugStopWords=[...Gt],s&&(s.value=Gt.join(` -`)),await this.plugin.saveSettings()}))}{let s=this.plugin.discoverStashpadFolders();if(new Z.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."),s.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 o=t.createDiv({cls:"stashpad-folder-list"});for(let a of s)this.renderFolderScopeRow(o,a)}let n=null;new Z.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(o=>{o.setPlaceholder("my-stashpad"),n=o.inputEl}).addButton(o=>o.setButtonText("Create").setCta().onClick(async()=>{let a=(n?.value??"").trim().replace(/^\/+|\/+$/g,"");if(!a){new Z.Notice("Enter a folder name first.");return}try{await this.plugin.createNewStashpad(a),new Z.Notice(`Created Stashpad "${a}".`),n&&(n.value=""),await this.plugin.waitForStashpadFolder(a,2e3),this.display()}catch(r){new Z.Notice(`Couldn't create: ${r.message}`)}}))}new Z.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(s=>s.setValue(this.plugin.settings.autofocusComposerAfterSend).onChange(async n=>{this.plugin.settings.autofocusComposerAfterSend=n,await this.plugin.saveSettings()})),new Z.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(s=>s.setValue(this.plugin.settings.popoutDuplicates).onChange(async n=>{this.plugin.settings.popoutDuplicates=n,await this.plugin.saveSettings()})),new Z.Setting(t).setName("Prefix timestamps when copying").setDesc("Include each note's timestamp before its body when copying with C or Y.").addToggle(s=>s.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 i=t.createEl("p",{cls:"setting-item-description"});i.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 s=this.plugin.discoverStashpadFolders();new Z.Setting(t).setName("Scope").setDesc("Scan the whole vault, or restrict to a single folder + its descendants.").addDropdown(r=>{r.addOption("vault","Entire vault"),r.addOption("folder","Single folder"),r.setValue(this.plugin.settings.jdIndexScope??"vault"),r.onChange(async c=>{this.plugin.settings.jdIndexScope=c==="folder"?"folder":"vault",await this.plugin.saveSettings(),this.display()})}),(this.plugin.settings.jdIndexScope??"vault")==="folder"&&new Z.Setting(t).setName("Scope folder").setDesc("Vault-relative path. Leave empty to fall back to the entire vault.").addText(r=>{new Be(this.app,r.inputEl),r.setPlaceholder("Path/To/Folder"),r.setValue(this.plugin.settings.jdIndexScopeFolder??""),r.onChange(async c=>{this.plugin.settings.jdIndexScopeFolder=(c||"").trim().replace(/^\/+|\/+$/g,""),await this.plugin.saveSettings()})}),new Z.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(r=>{r.setValue(this.plugin.settings.jdIndexIncludeStashpadFolders===!0),r.onChange(async c=>{this.plugin.settings.jdIndexIncludeStashpadFolders=c,await this.plugin.saveSettings(),this.display()})}),new Z.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(r=>{new Be(this.app,r.inputEl),r.setPlaceholder(s[0]??"(pick a Stashpad folder)"),r.setValue(this.plugin.settings.jdIndexStashpadFolder??""),r.onChange(async c=>{this.plugin.settings.jdIndexStashpadFolder=(c||"").trim().replace(/^\/+|\/+$/g,""),await this.plugin.saveSettings()})}),new Z.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(r=>{r.addOption("natural","Natural (numeric \u2192 alphabetical)"),r.addOption("created","By creation time"),r.setValue(this.plugin.settings.jdIndexSort??"natural"),r.onChange(async c=>{this.plugin.settings.jdIndexSort=c==="created"?"created":"natural",await this.plugin.saveSettings()})});let n=fe(this.app,this.plugin,this.plugin.settings),o=t.createEl("p",{cls:"setting-item-description"}),a=n.skippedStashpadNotes.length>0?` (${n.skippedStashpadNotes.length} Stashpad-folder note${n.skippedStashpadNotes.length===1?"":"s"} excluded by default)`:"";o.setText(`Preview: ${n.indexed.length} note${n.indexed.length===1?"":"s"} would be indexed, ${n.nonIndex.length} would NOT be indexed${a}.`),new Z.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(r=>{r.setButtonText("Preview"),r.setTooltip("Overwrites the designated Stashpad folder's HOME note body with the preview."),r.onClick(async()=>{try{let c=await ci(this.app,this.plugin,this.plugin.settings);if(c.error==="no-dest"){new Z.Notice("Set a Designated Stashpad folder for Index first.",5e3);return}if(c.error==="no-home"){new Z.Notice(`"${this.plugin.settings.jdIndexStashpadFolder}" doesn't have a Stashpad home note. Open the folder in Stashpad first (it creates one automatically).`,7e3);return}li(this.app,c),this.display()}catch(c){console.error("[stashpad] preview failed",c),new Z.Notice(`Preview failed: ${c?.message??c}`,8e3)}})}).addButton(r=>{r.setButtonText("Build Stashpad notes"),r.setCta(),r.setTooltip("Create the Stashpad-note hierarchy. Existing notes with matching jdPrefix are updated."),r.onClick(()=>{if(!(this.plugin.settings.jdIndexStashpadFolder??"").trim().replace(/^\/+|\/+$/g,"")){new Z.Notice("Set a Designated Stashpad folder for Index first.",5e3);return}new Oe(this.app,this.plugin,this.plugin.settings,n.indexed.length,async()=>{try{let d=await es(this.app,this.plugin,this.plugin.settings);if(d.error==="no-dest"){new Z.Notice("Set a Designated Stashpad folder for Index first.",5e3);return}if(d.error==="dest-not-stashpad"){new Z.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 Z.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 Z.Notice(`Build failed: ${d?.message??d}`,8e3)}}).open()})}).addButton(r=>{r.setButtonText(`Reveal in ${co()}`),r.setTooltip("Open the designated Stashpad folder in your OS file browser."),r.onClick(async()=>{let c=(this.plugin.settings.jdIndexStashpadFolder??"").trim().replace(/^\/+|\/+$/g,"");if(!c){new Z.Notice("Set a Designated Stashpad folder for Index first.",5e3);return}if(!this.app.vault.getAbstractFileByPath(c)){new Z.Notice(`Folder "${c}" doesn't exist yet.`,5e3);return}try{let d=this.app.vault.adapter.basePath;if(d){let{shell:I}=window.require?.("electron")??{},g=`${d}/${c}`;I?.openPath?.(g)}else new Z.Notice("Reveal in file system not supported on this platform.",4e3)}catch(d){new Z.Notice(`Couldn't open folder: ${d?.message??d}`,5e3)}})})}renderColorAliasesSection(t){let e=this.plugin.discoverStashpadFolders();if(e.length===0){new Z.Setting(t).setName("Color Aliases per Stashpad").setDesc("No Stashpads discovered yet \u2014 create one above first.");return}let i=(()=>{let o=Lt()?.noteFolder;return o&&e.includes(o)?o:e[0]})();new Z.Setting(t).setName("Color Aliases per Stashpad").setDesc("Which Stashpad's colors to label.").addDropdown(o=>{for(let a of e)o.addOption(a,a);o.setValue(i),o.onChange(a=>{i=a,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 s=t.createDiv({cls:"stashpad-color-aliases-list"}),n=()=>{s.empty();let o=this.plugin.collectColorsInFolder(i),a=new Map(o.map(d=>[d.hex,d.count])),r=this.plugin.settings.colorAliases?.[i.replace(/\/+$/,"")]??{},c=new Set([...a.keys(),...Object.keys(r)]);if(c.size===0){s.createEl("p",{cls:"setting-item-description",text:`No colors used or aliased in "${i}" yet. Set a per-note color (Shift+: or right-click \u2192 Set color) and it'll appear here.`});return}let l=[...c].map(d=>({hex:d,count:a.get(d)??0}));l.sort((d,I)=>I.count-d.count||d.hex.localeCompare(I.hex));for(let d of l)this.renderColorAliasRow(s,i,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 Z.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(i=>{i.setValue(this.plugin.settings.authorName).onChange(async s=>{this.plugin.settings.authorName=s.trim(),this.plugin.settings.authorName&&!this.plugin.settings.authorId&&(this.plugin.settings.authorId=mt()),await this.plugin.saveSettings(),await this.plugin.syncAuthorFilesToName()})}),new Z.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(i=>{i.setValue(this.plugin.settings.authorId).setDisabled(!0)}),new Z.Setting(t).setName("Title / role").setDesc('Optional. Shown on your author page (e.g. "Engineer", "PM", "Designer").').addText(i=>{i.setValue(this.plugin.settings.authorRole).onChange(async s=>{this.plugin.settings.authorRole=s.trim(),await this.plugin.saveSettings(),await this.plugin.syncAuthorFilesToName()})}),new Z.Setting(t).setName("Department / team").setDesc('Optional. Shown on your author page (e.g. "Engineering", "Growth").').addText(i=>{i.setValue(this.plugin.settings.authorDepartment).onChange(async s=>{this.plugin.settings.authorDepartment=s.trim(),await this.plugin.saveSettings(),await this.plugin.syncAuthorFilesToName()})}),new Z.Setting(t).setName("Show author in note footer").addToggle(i=>i.setValue(this.plugin.settings.showAuthor).onChange(async s=>{this.plugin.settings.showAuthor=s,await this.plugin.saveSettings()})),new Z.Setting(t).setName("Show contributors in note footer").addToggle(i=>i.setValue(this.plugin.settings.showContributors).onChange(async s=>{this.plugin.settings.showContributors=s,await this.plugin.saveSettings()})),new Z.Setting(t).setName("Show last edit time in note footer").addToggle(i=>i.setValue(this.plugin.settings.showLastEdit).onChange(async s=>{this.plugin.settings.showLastEdit=s,await this.plugin.saveSettings()}));let e=this.plugin.collectAuthoredFolders();if(e.length>0){t.createEl("h4",{text:"Folders you've worked in"});let i=t.createDiv({cls:"stashpad-authored-folders-list"});for(let s of e){let n=i.createDiv({cls:"stashpad-authored-folder-row"}),o=n.createEl("a",{cls:"stashpad-authored-folder-link",text:s.folder});o.onclick=r=>{r.preventDefault(),this.plugin.activateViewForFolder(s.folder)};let a=[];s.authored>0&&a.push(`authored ${s.authored}`),s.contributed>0&&a.push(`contributed to ${s.contributed}`),n.createSpan({cls:"stashpad-authored-folder-counts",text:` \xB7 ${a.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 Z.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(s=>s.setButtonText("Rebuild").onClick(async()=>{s.setDisabled(!0).setButtonText("Rebuilding\u2026");try{let n=await this.plugin.rebuildAuthorRegistry();new Z.Notice(`Author registry rebuilt: ${n.total} author(s).`)}catch(n){new Z.Notice(`Rebuild failed: ${n.message}`)}s.setDisabled(!1).setButtonText("Rebuild"),this.display()})).addButton(s=>s.setButtonText("Restore missing pages").onClick(async()=>{s.setDisabled(!0).setButtonText("Restoring\u2026");try{let n=await this.plugin.restoreMissingAuthorStubs();new Z.Notice(n.created>0?`Restored ${n.created} author page(s).`:"No missing author pages.")}catch(n){new Z.Notice(`Restore failed: ${n.message}`)}s.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 i=t.createDiv({cls:"stashpad-known-authors-list"});for(let s of e){let n=i.createDiv({cls:"stashpad-known-author-row"}),o=n.createDiv({cls:"stashpad-known-author-main"});o.createSpan({cls:"stashpad-known-author-name",text:s.name||"(unnamed)"});let a=[];if(s.role&&a.push(s.role),s.department&&a.push(s.department),a.push(`id ${s.id}`),o.createSpan({cls:"stashpad-known-author-meta",text:` \xB7 ${a.join(" \xB7 ")}`}),s.renames&&s.renames.length>0){let r=n.createDiv({cls:"stashpad-known-author-history"}),c=s.renames.map(l=>`${l.from} \u2192 ${l.to}`).join(", ");r.setText(`Renamed: ${c}`)}}}renderNoteTemplatesSection(t){let e=this.plugin.discoverStashpadFolders();if(e.length===0)return;new Z.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 i=t.createDiv({cls:"stashpad-note-templates-list"}),s=n=>{let o=n.replace(/\/+$/,""),a=i.createDiv({cls:"stashpad-note-template-row"});a.createSpan({cls:"stashpad-note-template-folder"}).setText(n);let c=a.createDiv({cls:"stashpad-note-template-input-wrap"}),l=c.createEl("input",{type:"text",cls:"stashpad-note-template-input",attr:{placeholder:"path/to/template.md (leave blank to disable)"}});l.value=(this.plugin.settings.noteTemplates??{})[o]??"";let d=c.createDiv({cls:"stashpad-note-template-suggest"});d.style.display="none";let I=a.createDiv({cls:"stashpad-note-template-warn"});I.style.display="none";let g=()=>this.app.vault.getMarkdownFiles().map(B=>B.path).filter(B=>!/\/(_imports|_exports|_attachments|\.stashpad)\//.test(B)).sort(),p=()=>{d.empty();let B=l.value.trim().toLowerCase().split(/\s+/).filter(Boolean),Q=y=>{let v=y.toLowerCase();return B.every(k=>v.includes(k))},E=g().filter(y=>Q(y)).slice(0,12);if(E.length===0){d.style.display="none";return}d.style.display="";for(let y of E)d.createDiv({cls:"stashpad-note-template-suggest-item",text:y}).addEventListener("mousedown",async k=>{k.preventDefault(),l.value=y,await u(),d.style.display="none"})},u=async()=>{let B=l.value.trim(),Q={...this.plugin.settings.noteTemplates??{}};B?Q[o]=B:delete Q[o],this.plugin.settings.noteTemplates=Q,await this.plugin.saveSettings(),f()},f=()=>{I.empty(),I.style.display="none";let B=l.value.trim();if(!B)return;let Q=this.app.vault.getAbstractFileByPath(B);if(!Q||Q.extension!=="md"){I.style.display="",I.setText(`\u26A0 "${B}" is not a markdown file in this vault.`);return}let E=this.app.metadataCache.getFileCache(Q)?.frontmatter??{},v=zt.filter(k=>{let b=E[k];return!(b==null||typeof b=="string"&&b.trim()===""||Array.isArray(b)&&b.length===0)});v.length!==0&&(I.style.display="",I.setText(`\u26A0 Template defines ${v.join(", ")} \u2014 Stashpad always sets ${v.length===1?"this":"these"} on new notes, so the template value${v.length===1?"":"s"} will be ignored.`))};l.addEventListener("focus",p),l.addEventListener("input",p),l.addEventListener("blur",()=>{setTimeout(()=>{d.style.display="none"},150)}),l.addEventListener("change",()=>{u()}),f()};for(let n of e)s(n)}renderColorAliasRow(t,e,i,s,n){let o=t.createDiv({cls:"stashpad-color-alias-row"});s===0&&o.addClass("is-unused");let a=o.createSpan({cls:"stashpad-color-alias-swatch"});a.style.background=i,a.title="Click to bulk-recolor every note of this color in this Stashpad",a.onclick=()=>{let d=this.plugin.settings.customPalette??[];new ae(this.app,i,d,async I=>{if((I??null)===null&&s===0){await this.plugin.setColorAlias(e,i,""),n();return}if(I&&I.toLowerCase()===i){n();return}let g=await this.plugin.recolorAllInFolder(e,i,I??null);if(g>0)new Z.Notice(`Recolored ${g} note${g===1?"":"s"}.`);else if(s===0){let p=this.plugin.getColorAlias(e,i);p&&(await this.plugin.setColorAlias(e,i,""),I&&await this.plugin.setColorAlias(e,I,p))}n()},async I=>{let g=(this.plugin.settings.customPalette??[]).filter(p=>p.toLowerCase()!==I.toLowerCase());return this.plugin.settings.customPalette=g,await this.plugin.saveSettings(),g}).open()};let r=o.createDiv({cls:"stashpad-color-alias-meta"});r.createSpan({cls:"stashpad-color-alias-hex",text:i}),r.createSpan({cls:"stashpad-color-alias-count",text:s===0?"\xB7 unused":`\xB7 ${s} note${s===1?"":"s"}`});let c=o.createEl("input",{type:"text",cls:"stashpad-color-alias-input",attr:{placeholder:"Alias (optional)"}});c.value=this.plugin.getColorAlias(e,i)??"",c.onchange=async()=>{await this.plugin.setColorAlias(e,i,c.value),!c.value.trim()&&s===0&&n()};let l=o.createEl("button",{cls:"stashpad-color-alias-del",text:"\xD7",attr:{title:"Delete alias"}});c.value||(l.style.visibility="hidden"),l.onclick=async()=>{await this.plugin.setColorAlias(e,i,""),s===0?n():(c.value="",l.style.visibility="hidden")}}renderFolderScopeRow(t,e){let i=t.createDiv({cls:"stashpad-folder-row"});i.createSpan({cls:"stashpad-folder-row-label",text:e});let s=i.createSpan({cls:"stashpad-folder-row-state"}),n=i.createDiv({cls:"stashpad-binding-pill"});n.setAttribute("role","switch"),n.setAttribute("tabindex","0");let o=n.createDiv({cls:"stashpad-binding-pill-knob"}),a=()=>(this.plugin.settings.searchExcludedFolders??[]).includes(e),r=()=>{let l=a();n.toggleClass("is-right",l),n.setAttribute("aria-checked",String(l)),o.setText(l?"X":"\u2713"),s.setText(l?"Excluded":"Included"),s.toggleClass("is-excluded",l),n.title=l?"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."},c=async()=>{let l=new Set(this.plugin.settings.searchExcludedFolders??[]);l.has(e)?l.delete(e):l.add(e),this.plugin.settings.searchExcludedFolders=[...l].sort(),r(),await this.plugin.saveSettings()};n.onclick=()=>void c(),n.onkeydown=l=>{(l.key===" "||l.key==="Enter")&&(l.preventDefault(),c())},r()}renderBindingRow(t,e){let i=new Z.Setting(t).setName(e.label).setDesc(e.desc),s=()=>this.plugin.settings.bindings[e.id],n,o,a=()=>{},r=p=>{let u=i.controlEl.createDiv({cls:"stashpad-binding-slot"}),f=u.createEl("input",{type:"text"});f.readOnly=!0,f.placeholder="Click & press a key",f.value=os(s()[p]),f.classList.add("stashpad-binding-input");let B=()=>{f.size=Math.max(3,f.value.length||f.placeholder.length)};B(),f.onclick=()=>{Vs(f,async E=>{this.plugin.settings.bindings[e.id][p]=E,f.value=os(E),B(),await this.plugin.saveSettings(),a()})};let Q=u.createEl("button",{cls:"stashpad-binding-clear",text:"\xD7"});return Q.title="Clear this slot",Q.onclick=async()=>{this.plugin.settings.bindings[e.id][p]="",f.value="",B(),await this.plugin.saveSettings(),a()},f};n=r("primary"),o=r("secondary");let c=i.controlEl.createDiv({cls:"stashpad-binding-pill"});c.setAttribute("role","switch"),c.setAttribute("tabindex","0");let l=c.createDiv({cls:"stashpad-binding-pill-knob"}),d=i.controlEl.createDiv({cls:"stashpad-binding-useboth"}),I=d.createEl("input",{type:"checkbox"});I.title="Use both bindings simultaneously (overrides the L/R toggle)",d.createSpan({text:"Use both"}),I.onchange=async()=>{this.plugin.settings.bindings[e.id].useBoth=I.checked,await this.plugin.saveSettings(),a()},a=()=>{let p=s(),u=!!(p.primary&&p.secondary);I.checked=!!p.useBoth,I.disabled=!u,d.toggleClass("is-disabled",!u);let f=!!p.useBoth&&u;c.toggleClass("is-disabled",!u||f),c.toggleClass("is-right",p.preferRight),c.setAttribute("aria-checked",String(p.preferRight)),c.setAttribute("aria-disabled",String(!u||f)),l.setText(p.preferRight?"R":"L"),c.title=u?f?'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 g=async()=>{let p=s();!p.primary||!p.secondary||(this.plugin.settings.bindings[e.id].preferRight=!p.preferRight,a(),await this.plugin.saveSettings())};c.onclick=()=>void g(),c.onkeydown=p=>{(p.key===" "||p.key==="Enter")&&(p.preventDefault(),g())},a()}};var Ce=class{constructor(A,t){this.app=A;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 A=this.detectTrigger();if(!A){this.close();return}this.openFor(A)};this.onBlur=()=>{setTimeout(()=>this.close(),120)};this.onDocEscape=A=>{A.key==="Escape"&&(!this.state||!this.items.length||(A.preventDefault(),A.stopPropagation(),A.stopImmediatePropagation(),this.close()))};this.onKeyDown=A=>{!this.state||!this.items.length||(A.key==="ArrowDown"?(A.preventDefault(),this.activeIdx=(this.activeIdx+1)%this.items.length,this.refreshActive()):A.key==="ArrowUp"?(A.preventDefault(),this.activeIdx=(this.activeIdx-1+this.items.length)%this.items.length,this.refreshActive()):A.key==="Enter"||A.key==="Tab"?(A.preventDefault(),A.stopPropagation(),this.commit()):A.key==="Escape"&&(A.preventDefault(),A.stopPropagation(),A.stopImmediatePropagation(),this.close()))}}attach(){this.ta.addEventListener("input",this.onInput),this.ta.addEventListener("keydown",this.onKeyDown,!0),this.ta.addEventListener("blur",this.onBlur);let A=this.ta.ownerDocument??document;A.addEventListener("keydown",this.onDocEscape,!0),this.vaultListeners.push(()=>A.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 A of this.vaultListeners)A();this.vaultListeners=[]}buildIndex(){if(this.indexBuilt)return;let A=Bt().inheritObsidianExclusions,t=A?this.app.vault.getConfig?.("userIgnoreFilters"):void 0;this.fileIndex=this.app.vault.getFiles().filter(i=>!xs(i.path)&&!Ms(i.path)&&!(A&&Hs(i.path,t))).map(i=>{let s=i.extension==="md",n=s?i.basename:i.name,o=s?i.basename:i.name;return{label:n,lower:n.toLowerCase(),insertText:o,file:i}});let e=this.app.metadataCache.getTags?.()??{};this.tagIndex=Object.keys(e).sort((i,s)=>(e[s]||0)-(e[i]||0)),this.indexBuilt=!0}detectTrigger(){let A=this.ta.value,t=this.ta.selectionStart;if(t==null)return null;let e=A.slice(0,t),i=e.match(/\[\[([^\]\[\n]*)$/);if(i){let n=i[1];return{kind:"link",query:n,replaceStart:t-n.length-2,replaceEnd:t}}let s=e.match(/(^|\s)#([A-Za-z0-9_/\-]+)$/);if(s){let n=s[2];return{kind:"tag",query:n,replaceStart:t-n.length-1,replaceEnd:t}}return null}buildItems(A){this.buildIndex();let t=A.query.toLowerCase().trim(),e=t?t.split(/\s+/).filter(Boolean):[],i=s=>{if(!e.length)return!0;for(let n of e)if(!s.includes(n))return!1;return!0};return A.kind==="link"?this.fileIndex.filter(n=>i(n.lower)).slice(0,50).map(n=>({label:n.label,insert:`[[${n.insertText}]]`,subtitle:n.file.path})):this.tagIndex.filter(n=>i(n.toLowerCase())).slice(0,30).map(n=>({label:n,insert:n,subtitle:""}))}openFor(A){if(this.state=A,this.items=this.buildItems(A),this.activeIdx=0,!this.items.length){this.close();return}this.renderPopup(),this.pushScope()}pushScope(){if(this.scope)return;let A=new $s.Scope(this.app.scope);A.register([],"Escape",t=>(t.preventDefault(),this.close(),!1)),this.scope=A,this.app.keymap?.pushScope(A)}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 A=this.popupEl;A.empty();for(let t=0;t<this.items.length;t++){let e=this.items[t],i=A.createDiv({cls:"stashpad-composer-suggest-row"});t===this.activeIdx&&i.addClass("is-active"),i.createSpan({cls:"stashpad-composer-suggest-label",text:e.label}),e.subtitle&&i.createSpan({cls:"stashpad-composer-suggest-sub",text:e.subtitle}),i.onmousedown=s=>{s.preventDefault(),this.activeIdx=t,this.commit()}}this.position()}refreshActive(){if(!this.popupEl)return;let A=this.popupEl.children;for(let e=0;e<A.length;e++)A[e].toggleClass("is-active",e===this.activeIdx);let t=A[this.activeIdx];t&&t.scrollIntoView({block:"nearest"})}position(){if(!this.popupEl)return;let A=this.ta.getBoundingClientRect(),t=this.popupEl.offsetHeight||200,e=A.top-t-4,i=A.left;this.popupEl.style.left=`${Math.max(8,i)}px`,this.popupEl.style.top=`${Math.max(8,e)}px`,this.popupEl.style.minWidth=`${Math.min(360,A.width)}px`}commit(){if(!this.state||!this.items.length)return;let A=this.items[this.activeIdx];if(!A)return;let t=this.ta.value.slice(0,this.state.replaceStart),e=this.ta.value.slice(this.state.replaceEnd),i=A.insert;this.ta.value=t+i+e;let s=t.length+i.length;this.ta.setSelectionRange(s,s),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()}};yt();var Qi=class extends Ft.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 te}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?.()===ut&&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?.()===ut&&e.tree?.get){let i=e.tree.get(this.displayedId);if(i?.file)return{folder:e.noteFolder,id:this.displayedId,file:i.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,i=this.composerInputEl?.selectionStart??null;this.composerAutocomplete?.detach(),this.composerAutocomplete=null,this.composerInputEl=null,t.empty(),t.addClass("stashpad-detail-root");let s=this.resolveDisplayed();if(!s){this.displayedPath=null;let g=t.createDiv({cls:"stashpad-detail-empty"});(0,Ft.setIcon)(g.createSpan({cls:"stashpad-detail-empty-icon"}),"panel-right"),g.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=s.file;this.displayedPath=n.path;let o=this.app.metadataCache.getFileCache(n)?.frontmatter??{},a=t.createDiv({cls:"stashpad-detail-scroll"}),r=a.createDiv({cls:"stashpad-detail-header"}),c=r.createDiv({cls:"stashpad-detail-titlerow"});c.createDiv({cls:"stashpad-detail-title",text:this.titleFor(n)});let l=c.createEl("button",{cls:"stashpad-detail-open-btn",attr:{"aria-label":"Open in Stashpad tab"}});(0,Ft.setIcon)(l,"arrow-up-right"),l.title="Open this note in a new Stashpad tab",l.onclick=()=>{this.openInStashpad(s.folder,s.id)};let d=r.createDiv({cls:"stashpad-detail-metarow"});if(s.folder&&d.createSpan({cls:"stashpad-detail-meta-chip",text:s.folder.split("/").pop()||s.folder}),typeof o.color=="string"&&o.color){let g=d.createSpan({cls:"stashpad-detail-meta-color"});g.style.background=o.color,g.title=o.color}if(o.completed===!0&&d.createSpan({cls:"stashpad-detail-meta-chip is-completed",text:"\u2713 completed"}),typeof o.due=="string"||typeof o.due=="number"){let g=Date.parse(String(o.due)),p=Number.isNaN(g)?String(o.due):se(g,this.plugin.settings);d.createSpan({cls:"stashpad-detail-meta-chip is-due",text:`due ${p}`})}if(Array.isArray(o.tags))for(let g of o.tags.filter(p=>typeof p=="string"))d.createSpan({cls:"stashpad-detail-meta-tag",text:`#${g.replace(/^#/,"")}`});let I=a.createDiv({cls:"stashpad-detail-body"});try{let g=await this.app.vault.cachedRead(n),p=this.stripFrontmatter(g);await Ft.MarkdownRenderer.render(this.app,p,I,n.path,this)}catch(g){I.createDiv({cls:"stashpad-detail-error",text:`Couldn't read \`${n.path}\`: ${g.message}`})}if(this.renderFooterMeta(a,n,o,s),this.renderChildren(a,s.folder,s.id),this.renderComposer(t,s),e&&this.composerInputEl&&(this.composerInputEl.focus(),i!=null)){let g=Math.min(i,this.composerInputEl.value.length);try{this.composerInputEl.setSelectionRange(g,g)}catch{}}}renderComposer(t,e){let i=t.createDiv({cls:"stashpad-detail-composer"}),s=i.createEl("textarea",{cls:"stashpad-detail-composer-input",attr:{placeholder:"Add a child note\u2026",rows:"2"}});this.composerInputEl=s,this.composerDraftForId===e.id?s.value=this.composerDraft:(this.composerDraft="",this.composerDraftForId=e.id),s.addEventListener("input",()=>{this.composerDraft=s.value,this.composerDraftForId=e.id}),s.addEventListener("keydown",o=>{if(o.key==="Enter"&&!o.shiftKey&&!o.isComposing){if(this.composerAutocomplete?.isOpen?.())return;o.preventDefault(),this.submitComposer(e)}});let n=i.createEl("button",{cls:"stashpad-detail-composer-send",attr:{"aria-label":"Add child note"}});(0,Ft.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 Ce(this.app,s),this.composerAutocomplete.attach()}async submitComposer(t){let e=(this.composerInputEl?.value??"").trim();if(!e)return;let i=this.plugin.lastActiveStashpadLeaf?.view;if(!i||i.getViewType?.()!==ut||typeof i.createNoteUnder!="function"){new Ft.Notice("Open a Stashpad view to add notes.");return}try{await i.createNoteUnder(e,t.id)}catch(s){new Ft.Notice(`Couldn't add note: ${s.message}`);return}this.composerDraft="",this.composerDraftForId=t.id,this.composerInputEl&&(this.composerInputEl.value=""),await this.render(),setTimeout(()=>this.composerInputEl?.focus(),0)}renderChildren(t,e,i){let s=this.plugin.lastActiveStashpadLeaf?.view;if(!s||s.getViewType?.()!==ut)return;let n=s.tree;if(!n?.getChildren)return;let o=n.getChildren(i);if(!o||o.length===0)return;let a=t.createDiv({cls:"stashpad-detail-children"});a.createDiv({cls:"stashpad-detail-children-header",text:`Children (${o.length})`});let r=a.createDiv({cls:"stashpad-detail-children-list"});for(let c of o)c.file&&this.renderDetailChildRow(r,s,n,e,c,0)}renderDetailChildRow(t,e,i,s,n,o){if(!n.file)return;let a=this.app.metadataCache.getFileCache(n.file)?.frontmatter??{},r=typeof a.color=="string"?a.color:null,c=a.completed===!0,l=i.getChildren(n.id),d=l.length>0,I=`${s}|${n.id}`,g=this.expanded.has(I),p=t.createDiv({cls:"stashpad-detail-child-row"});c&&p.addClass("is-completed"),o>0&&(p.style.paddingLeft=`${o*16}px`),p.draggable=!0,p.dataset.id=n.id,p.addEventListener("dragstart",E=>{E.dataTransfer?.setData("text/plain",n.id),E.dataTransfer&&(E.dataTransfer.effectAllowed="move"),p.addClass("is-dragging")}),p.addEventListener("dragend",()=>p.removeClass("is-dragging")),p.addEventListener("dragover",E=>{E.preventDefault(),E.dataTransfer&&(E.dataTransfer.dropEffect="move");let y=p.getBoundingClientRect(),v=E.clientY-y.top<y.height/2;p.toggleClass("drop-before",v),p.toggleClass("drop-after",!v)}),p.addEventListener("dragleave",()=>{p.removeClass("drop-before"),p.removeClass("drop-after")}),p.addEventListener("drop",E=>{E.preventDefault(),p.removeClass("drop-before"),p.removeClass("drop-after");let y=E.dataTransfer?.getData("text/plain");if(!y||y===n.id)return;let v=p.getBoundingClientRect(),k=E.clientY-v.top<v.height/2;typeof e.reorderToTarget=="function"&&e.reorderToTarget([y],n.id,k?"before":"after")}),p.oncontextmenu=E=>{E.preventDefault();let y=i.get(n.id);y&&typeof e.openNoteMenu=="function"&&e.openNoteMenu(E,y)};let u=p.createSpan({cls:"stashpad-detail-child-toggle"});if(d&&(ai(u,l.length,g),u.onclick=E=>{E.stopPropagation(),this.expanded.has(I)?this.expanded.delete(I):this.expanded.add(I),this.render()}),ee(a,"task")||a.task===!0||a.completed!==void 0){let E=p.createSpan({cls:"stashpad-detail-child-checkbox"});(0,Ft.setIcon)(E,c?"check-square":"square"),E.title=c?"Mark not done":"Mark done",E.addEventListener("mousedown",y=>y.stopPropagation()),E.addEventListener("dblclick",y=>{y.preventDefault(),y.stopPropagation()}),E.onclick=y=>{y.preventDefault(),y.stopPropagation();let v=i.get(n.id);v&&typeof e.toggleCompletedForNode=="function"&&e.toggleCompletedForNode(v)}}let B=p.createSpan({cls:"stashpad-detail-child-icon"});(0,Ft.setIcon)(B,d?"folder-tree":"file-text"),r&&(B.style.color=r);let Q=p.createSpan({cls:"stashpad-detail-child-title",text:this.titleFor(n.file)});if(Q.onclick=()=>{e?.navigateTo&&e.navigateTo(n.id)},d&&g)for(let E of l)this.renderDetailChildRow(t,e,i,s,E,o+1)}renderFooterMeta(t,e,i,s){let n=t.createDiv({cls:"stashpad-detail-footer-meta"}),o=[];if(typeof i.author=="string"&&i.author&&o.push({label:"Author",value:this.stripWikiLink(i.author)}),Array.isArray(i.contributors)){let a=i.contributors.filter(r=>typeof r=="string").map(r=>this.stripWikiLink(r));a.length>0&&o.push({label:"Contributors",value:a.join(", ")})}if(typeof i.modified=="string"&&o.push({label:"Modified",value:this.formatTime(i.modified)}),typeof i.created=="string"&&o.push({label:"Created",value:this.formatTime(i.created)}),o.push({label:"Path",value:e.path}),o.push({label:"ID",value:s.id}),o.length===0){n.remove();return}for(let a of o){let r=n.createDiv({cls:"stashpad-detail-meta-line"});r.createSpan({cls:"stashpad-detail-meta-key",text:a.label}),r.createSpan({cls:"stashpad-detail-meta-val",text:a.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)?se(e,this.plugin.settings):t}async openInStashpad(t,e){try{await this.plugin.activateViewForFolder(t);let i=this.plugin.lastActiveStashpadLeaf?.view;i?.navigateTo&&e!==G&&i.navigateTo(e)}catch(i){new Ft.Notice(`Couldn't open: ${i.message}`)}}};async function mi(h){let A=h.workspace.getLeavesOfType(te);if(A.length>0){h.workspace.revealLeaf(A[0]);return}let t=h.workspace.getRightLeaf(!1);if(!t){new Ft.Notice("Stashpad: couldn't open the detail panel.");return}await t.setViewState({type:te,active:!0}),h.workspace.revealLeaf(t)}var L=require("obsidian");yt();var Wt=require("obsidian");yt();function lo(h,A){let t=h.vault.getAbstractFileByPath(A);if(!(t instanceof Wt.TFolder))return[];let e=[],i=[t];for(;i.length;){let s=i.pop();for(let n of s.children)n instanceof Wt.TFile?n.extension==="md"&&e.push(n):n instanceof Wt.TFolder&&(Ne.has(n.name)||i.push(n))}return e}var Ei=class{constructor(A){this.app=A;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(G,{id:G,parent:null,children:[],file:null,created:""})}setOrderProvider(A){this.orderProvider=A}onChange(A){return this.listeners.add(A),()=>this.listeners.delete(A)}emit(){for(let A of this.listeners)A()}rebuild(A){A!==void 0&&(this.currentFolder=A);let t=this.currentFolder,e=this.byPath,i=this.nodes;this.nodes=new Map,this.byPath=new Map,this.nodes.set(G,{id:G,parent:null,children:[],file:null,created:""});let s=t?lo(this.app,t):this.app.vault.getMarkdownFiles();for(let n of s){let o=this.app.metadataCache.getFileCache(n)?.frontmatter,a=o?.id;if(!a){let c=e.get(n.path),l=c?i.get(c):void 0,d=this.synthetic.get(n.path),I=l??d;I&&(this.nodes.set(I.id,{...I,children:[],file:n}),this.byPath.set(n.path,I.id));continue}if(this.synthetic.delete(n.path),a===G){let c=this.nodes.get(G);c.file=n,c.created=o?.created??"",this.byPath.set(n.path,G);continue}let r=o?.parent??null;r===a&&(r=null),this.nodes.set(a,{id:a,parent:r??G,children:[],file:n,created:o?.created??""}),this.byPath.set(n.path,a)}for(let n of this.nodes.values()){if(n.id===G)continue;let o=n.parent??G;(this.nodes.get(o)??this.nodes.get(G)).children.push(n.id)}for(let n of this.nodes.values())if(n.children.sort((o,a)=>{let r=this.nodes.get(o),c=this.nodes.get(a);return(r.created||"").localeCompare(c.created||"")}),this.orderProvider){let o=this.orderProvider(n.id);if(o.length>0){let a=new Map;o.forEach((r,c)=>a.set(r,c)),n.children.sort((r,c)=>{let l=a.has(r)?a.get(r):1/0,d=a.has(c)?a.get(c):1/0;return l===d?0:l-d})}}this.emit()}insertSynthetic(A){if(!A.file)return;let t=A.file.path;this.synthetic.set(t,A),this.nodes.set(A.id,A),this.byPath.set(t,A.id);let e=A.parent??G,i=this.nodes.get(e);i&&!i.children.includes(A.id)&&i.children.push(A.id),this.emit()}get(A){return this.nodes.get(A)}getRoot(){return this.nodes.get(G)}getChildren(A){let t=this.nodes.get(A);return t?t.children.map(e=>this.nodes.get(e)).filter(e=>!!e):[]}fileBackedCount(){let A=0;for(let t of this.nodes.values())t.file&&A++;return A}pathTo(A){let t=[],e=new Set,i=this.nodes.get(A);for(;i&&i.id!==G&&!e.has(i.id);)e.add(i.id),t.unshift(i),i=i.parent?this.nodes.get(i.parent):void 0;return t}idForPath(A){return this.byPath.get(A)}snapshot(){let A={};for(let t of this.nodes.values())t.id===G||!t.file||(A[t.id]={parent:t.parent===G?null:t.parent,path:t.file.path});return A}hookMetadataCache(A){let t=r=>{let c=this.currentFolder;return c?typeof r!="string"?!1:r===c||r.startsWith(c+"/"):!0},e=!1,i=()=>{e=!0,this.coalesceTimer==null&&(this.coalesceTimer=window.setTimeout(()=>{this.coalesceTimer=null,e&&(e=!1,this.emit(),A())},16))},s=r=>{r instanceof Wt.TFile&&t(r.path)&&r.extension==="md"&&(this.applyChange(r),i())},n=r=>{r instanceof Wt.TFile&&t(r.path)&&r.extension==="md"&&this.applyChange(r)&&i()},o=r=>{let c=r?.path;typeof c=="string"&&t(c)&&this.applyDelete(c)&&i()},a=(r,c)=>{if(!(r instanceof Wt.TFile))return;let l=typeof c=="string"?c:null;!t(r.path)&&!t(l)||this.applyRename(r,l??"")&&i()};return this.app.metadataCache.on("changed",s),this.app.vault.on("create",n),this.app.vault.on("delete",o),this.app.vault.on("rename",a),()=>{this.app.metadataCache.off("changed",s),this.app.vault.off("create",n),this.app.vault.off("delete",o),this.app.vault.off("rename",a),this.coalesceTimer!=null&&(window.clearTimeout(this.coalesceTimer),this.coalesceTimer=null)}}applyChange(A){if(de(A.path))return this.byPath.has(A.path)?this.applyDelete(A.path):!1;let t=this.app.metadataCache.getFileCache(A)?.frontmatter,e=t?.id,i=this.byPath.get(A.path);if(!e){if(i){let c=this.nodes.get(i);if(c&&c.file!==A)return c.file=A,!0}return!1}if(this.synthetic.delete(A.path),e===G){let c=this.nodes.get(G),l=t?.created??"",d=!1;return c.file!==A&&(c.file=A,d=!0),c.created!==l&&(c.created=l,d=!0),this.byPath.get(A.path)!==G&&(this.byPath.set(A.path,G),d=!0),d}let s=t?.parent??G,n=t?.created??"";if(!(s===G||this.nodes.has(s)))return this.rebuild(),!0;if(i&&i!==e)return this.rebuild(),!0;let a=this.nodes.get(e);if(!a){let c={id:e,parent:s,children:[],file:A,created:n};return this.nodes.set(e,c),this.byPath.set(A.path,e),this.attachToParent(c),this.resortChildrenOf(s),!0}let r=!1;if(a.file!==A&&(a.file=A,r=!0),a.created!==n&&(a.created=n,this.resortChildrenOf(a.parent??G),r=!0),a.parent!==s){let c=a.parent??G;this.detachFromParent(a),a.parent=s,this.attachToParent(a),this.resortChildrenOf(c),this.resortChildrenOf(s),r=!0}return r}applyDelete(A){let t=this.byPath.get(A);if(!t)return!1;let e=this.nodes.get(t);if(!e)return this.byPath.delete(A),this.synthetic.delete(A),!0;this.detachFromParent(e);let i=this.nodes.get(G);for(let s of e.children){let n=this.nodes.get(s);n&&(n.parent=G,i.children.includes(s)||i.children.push(s))}return e.children.length>0&&this.resortChildrenOf(G),this.nodes.delete(t),this.byPath.delete(A),this.synthetic.delete(A),!0}applyRename(A,t){let e=this.currentFolder,i=!e||t===e||t.startsWith(e+"/"),s=!e||A.path===e||A.path.startsWith(e+"/");if(!i&&!s)return!1;if(i&&!s)return this.applyDelete(t);if(!i&&s)return this.applyChange(A);if(de(A.path))return this.byPath.has(t)?this.applyDelete(t):!1;let n=this.byPath.get(t);if(!n)return this.applyChange(A);this.byPath.delete(t),this.byPath.set(A.path,n);let o=this.nodes.get(n);return o&&(o.file=A),!0}detachFromParent(A){let t=this.nodes.get(A.parent??G);if(!t)return;let e=t.children.indexOf(A.id);e>=0&&t.children.splice(e,1)}attachToParent(A){let t=this.nodes.get(A.parent??G);t||(t=this.nodes.get(G)),t.children.includes(A.id)||t.children.push(A.id)}resortChildrenOf(A){let t=this.nodes.get(A);if(t&&(t.children.sort((e,i)=>{let s=this.nodes.get(e),n=this.nodes.get(i);return(s.created||"").localeCompare(n.created||"")}),this.orderProvider)){let e=this.orderProvider(A);if(e.length>0){let i=new Map;e.forEach((s,n)=>i.set(s,n)),t.children.sort((s,n)=>{let o=i.has(s)?i.get(s):1/0,a=i.has(n)?i.get(n):1/0;return o===a?0:o-a})}}}};var cs=class{constructor(){this.enabled=!1;this.buckets=new Map}record(A,t){if(!this.enabled)return;let e=this.buckets.get(A);e||(e={count:0,total:0,max:0},this.buckets.set(A,e)),e.count+=1,e.total+=t,t>e.max&&(e.max=t)}time(A,t){if(!this.enabled)return t();let e=performance.now();try{return t()}finally{this.record(A,performance.now()-e)}}async timeAsync(A,t){if(!this.enabled)return t();let e=performance.now();try{return await t()}finally{this.record(A,performance.now()-e)}}reset(){this.buckets.clear()}hasData(){return this.buckets.size>0}report(){let A=[...this.buckets.entries()].map(([e,i])=>({label:e,...i,avg:i.total/i.count})).sort((e,i)=>i.total-e.total);if(A.length===0)return"Stashpad perf: no samples (enable profiling, then use the app).";let t=["**Stashpad performance profile**","","| label | count | total (ms) | avg (ms) | max (ms) |","| --- | ---: | ---: | ---: | ---: |"];for(let e of A)t.push(`| \`${e.label}\` | ${e.count} | ${e.total.toFixed(0)} | ${e.avg.toFixed(1)} | ${e.max.toFixed(0)} |`);return t.join(` -`)}},vt=new cs;var js=".stashpad-order.json",yi=class{constructor(A){this.app=A;this.cache=new Map;this.pendingTimers=new Map;this.writeInFlight=new Map}async load(A){if(this.cache.has(A))return this.cache.get(A);let t=`${A}/${js}`,e=this.app.vault.adapter,i={};try{if(await e.exists(t)){let s=await e.read(t),n=JSON.parse(s);if(n&&typeof n=="object"&&!Array.isArray(n))for(let[o,a]of Object.entries(n))Array.isArray(a)&&a.every(r=>typeof r=="string")&&(i[o]=a)}}catch(s){console.warn("Stashpad: order load failed",s)}return this.cache.set(A,i),i}async save(A){this.scheduleWrite(A)}async flush(A){let t=this.pendingTimers.get(A);t!=null&&(window.clearTimeout(t),this.pendingTimers.delete(A)),await this.writeNow(A)}scheduleWrite(A){let t=this.pendingTimers.get(A);t!=null&&window.clearTimeout(t);let e=window.setTimeout(()=>{this.pendingTimers.delete(A),this.writeNow(A)},150);this.pendingTimers.set(A,e)}async writeNow(A){let e=(this.writeInFlight.get(A)??Promise.resolve()).then(()=>this.doWrite(A));this.writeInFlight.set(A,e);try{await e}finally{this.writeInFlight.get(A)===e&&this.writeInFlight.delete(A)}}async doWrite(A){let t=this.cache.get(A)??{},e={};for(let[n,o]of Object.entries(t))o.length>0&&(e[n]=o);this.cache.set(A,e);let i=`${A}/${js}`,s=this.app.vault.adapter;try{if(Object.keys(e).length===0)try{await s.remove(i)}catch{}else await s.write(i,JSON.stringify(e,null,2))}catch(n){console.warn("Stashpad: order save failed",n)}}getOrder(A,t){return this.cache.get(A)?.[t]?.slice()??[]}setOrder(A,t,e){let i=this.cache.get(A)??{};i[t]=e.slice(),this.cache.set(A,i)}appendChild(A,t,e){let i=this.cache.get(A)??{},s=i[t]??[];s.includes(e)||s.push(e),i[t]=s,this.cache.set(A,i)}removeChild(A,t){let e=this.cache.get(A);if(e)for(let i of Object.values(e)){let s=i.indexOf(t);s>=0&&i.splice(s,1)}}invalidate(A){this.cache.delete(A)}};var We={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"},ls=["manual","created-asc","created-desc","modified-asc","modified-desc","title-az","title-za"],ho=new Set(ls),tn=".stashpad-sort.json",wi=class{constructor(A){this.app=A;this.cache=new Map;this.pendingTimers=new Map;this.writeInFlight=new Map}async load(A){if(this.cache.has(A))return this.cache.get(A);let t=`${A}/${tn}`,e=this.app.vault.adapter,i={};try{if(await e.exists(t)){let s=JSON.parse(await e.read(t));if(s&&typeof s=="object"&&!Array.isArray(s))for(let[n,o]of Object.entries(s))typeof o=="string"&&ho.has(o)&&(i[n]=o)}}catch(s){console.warn("Stashpad: sort load failed",s)}return this.cache.set(A,i),i}async save(A){this.scheduleWrite(A)}async flush(A){let t=this.pendingTimers.get(A);t!=null&&(window.clearTimeout(t),this.pendingTimers.delete(A)),await this.writeNow(A)}scheduleWrite(A){let t=this.pendingTimers.get(A);t!=null&&window.clearTimeout(t);let e=window.setTimeout(()=>{this.pendingTimers.delete(A),this.writeNow(A)},150);this.pendingTimers.set(A,e)}async writeNow(A){let e=(this.writeInFlight.get(A)??Promise.resolve()).then(()=>this.doWrite(A));this.writeInFlight.set(A,e);try{await e}finally{this.writeInFlight.get(A)===e&&this.writeInFlight.delete(A)}}async doWrite(A){let t=this.cache.get(A)??{},e=`${A}/${tn}`,i=this.app.vault.adapter;try{if(Object.keys(t).length===0)try{await i.remove(e)}catch{}else await i.write(e,JSON.stringify(t,null,2))}catch(s){console.warn("Stashpad: sort save failed",s)}}getMode(A,t){return this.cache.get(A)?.[t]??"manual"}setMode(A,t,e){let i=this.cache.get(A)??{};e==="manual"?delete i[t]:i[t]=e,this.cache.set(A,i)}removeParent(A,t){let e=this.cache.get(A);e&&delete e[t]}invalidate(A){this.cache.delete(A)}};yt();var Xt="parentLink",Qe="children";var ki=class ki{constructor(A,t){this.app=A;this.getTree=t;this.pending=new Set;this.timer=null;this.activityListeners=new Set;this.errorListeners=new Set}onActivity(A){return this.activityListeners.add(A),()=>this.activityListeners.delete(A)}emitActivity(){let A=this.pending.size;for(let t of this.activityListeners)try{t(A)}catch(e){console.warn("[Stashpad] fmSync activity listener failed",e)}}schedule(A){if(!A||!Bt().writeRecoveryLinks)return;let t=this.pending.size;this.pending.add(A),this.pending.size!==t&&this.emitActivity(),this.kick()}scheduleParentChange(A,t,e){this.schedule(A),t&&this.schedule(t),this.schedule(e)}scheduleSubtree(A){let t=this.getTree(),e=i=>{this.schedule(i);for(let s of t.getChildren(i))e(s.id)};e(A)}scheduleParentOfDeleted(A){A&&this.schedule(A)}async flush(){for(this.timer!=null&&(window.clearTimeout(this.timer),this.timer=null);this.pending.size>0;){let A=this.pending.values().next().value;if(A===void 0)break;this.pending.delete(A),this.emitActivity(),await this.syncOne(A)}}pendingCount(){return this.pending.size}onError(A){return this.errorListeners.add(A),()=>this.errorListeners.delete(A)}emitError(A,t){for(let e of this.errorListeners)try{e(A,t)}catch(i){console.warn("[Stashpad] fmSync error listener failed",i)}}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(),ki.PACING_MS))}async tick(){this.timer=null;let A=this.pending.values().next().value;if(A!==void 0){this.pending.delete(A),this.emitActivity();try{await this.syncOne(A)}catch(t){console.warn("[Stashpad] frontmatter sync tick failed",t)}this.pending.size>0&&this.kick()}}wouldWrite(A){let e=this.getTree().get(A);if(!e||!e.file)return!1;let i=this.computeParentLink(e),s=this.computeChildrenLinks(e),n=this.app.metadataCache.getFileCache(e.file)?.frontmatter,o=n&&typeof n[Xt]=="string"?n[Xt]:null,a=n?.[Qe],r=Array.isArray(a)?a.filter(c=>typeof c=="string"):[];if((o??null)!==(i??null)||r.length!==s.length)return!0;for(let c=0;c<r.length;c++)if(r[c]!==s[c])return!0;return!1}async syncOne(A){let e=this.getTree().get(A);if(!e||!e.file||!this.wouldWrite(A))return;let i=this.computeParentLink(e),s=this.computeChildrenLinks(e);try{await vt.timeAsync("write.fmSync",()=>this.app.fileManager.processFrontMatter(e.file,n=>{i?n[Xt]=i:delete n[Xt],s.length>0?n[Qe]=s:delete n[Qe]}))}catch(n){console.warn("[Stashpad] frontmatter sync failed",e.file?.path,n),this.emitError(e.file.path,n)}}computeParentLink(A){if(A.id===G)return null;let t=this.getTree();if(!A.parent||A.parent===G){let i=t.getRoot();return i&&i.id!==A.id&&i.file?Fi(i.file.path):null}let e=t.get(A.parent);return e?.file?Fi(e.file.path):null}computeChildrenLinks(A){return this.getTree().getChildren(A.id).filter(e=>!!e.file).map(e=>Fi(e.file.path))}};ki.PACING_MS=100;var vi=ki;async function en(h,A){let t=A.endsWith("/")?A:A+"/",e=new Map,i=new Map;for(let c of h.vault.getMarkdownFiles()){if(c.path!==A&&!c.path.startsWith(t))continue;let l=h.metadataCache.getFileCache(c)?.frontmatter,d=typeof l?.id=="string"?l.id:null;if(!d)continue;let I=typeof l?.parent=="string"?l.parent:G;e.set(d,{file:c,id:d,parent:I});let g=i.get(I)??[];g.push(d),i.set(I,g)}let s=c=>Fi(c.file.path),n=c=>{if(c.id===G)return null;if(c.parent===G||!c.parent){let d=e.get(G);return d?s(d):null}let l=e.get(c.parent);return l?s(l):null},o=c=>{let l=i.get(c.id)??[],d=[];for(let I of l){let g=e.get(I);g&&d.push(s(g))}return d},a=0,r=0;for(let c of e.values()){a+=1;let l=n(c),d=o(c),I=h.metadataCache.getFileCache(c.file)?.frontmatter,g=I&&typeof I[Xt]=="string"?I[Xt]:null,p=I?.[Qe],u=Array.isArray(p)?p.filter(Q=>typeof Q=="string"):[],f=(g??null)===(l??null),B=u.length===d.length&&u.every((Q,E)=>Q===d[E]);if(!(f&&B))try{await h.fileManager.processFrontMatter(c.file,Q=>{l?Q[Xt]=l:delete Q[Xt],d.length>0?Q[Qe]=d:delete Q[Qe]}),r+=1,await new Promise(Q=>setTimeout(Q,50))}catch(Q){console.warn("[Stashpad] rebootstrap fm sync failed",c.file.path,Q)}}return{checked:a,written:r}}function Fi(h){return`[[${h.replace(/\.md$/i,"")}]]`}Tt();ue();var Si=class{constructor(A,t){this.tree=A;this.log=t}async sweep(A){let t=await this.log.readState(),e=this.tree.snapshot(),i=n=>{if(!A)return!0;let o=A.replace(/\/+$/,"");return n===o||n.startsWith(o+"/")};for(let[n,o]of Object.entries(e)){let a=t[n];a?a.parent!==o.parent?await this.log.append({type:"parent_change",id:n,payload:{from:a.parent,to:o.parent}}):a.path!==o.path&&await this.log.append({type:"rename",id:n,payload:{from:a.path,to:o.path}}):await this.log.append({type:"create",id:n,payload:{path:o.path,parent:o.parent}})}for(let[n,o]of Object.entries(t))!e[n]&&i(o.path)&&await this.log.append({type:"missing",id:n,payload:{lastPath:o.path}});let s={};for(let[n,o]of Object.entries(t))i(o.path)||(s[n]=o);for(let[n,o]of Object.entries(e))s[n]=o;await this.log.writeState(s)}};var dt=require("obsidian");yt();_i();function ds(h){let A=h.trim().toLowerCase();if(!A)return null;let t=Date.now(),e=p=>(0,dt.moment)(p).startOf("day").valueOf(),i=/\b(\d{1,2})(?::(\d{2}))?\s*(am|pm)?\b/,s=0,n=!1,o=A,a=i.exec(A);if(a&&(a[3]||a[2])){let p=parseInt(a[1],10),u=a[2]?parseInt(a[2],10):0,f=a[3];f==="pm"&&p<12&&(p+=12),f==="am"&&p===12&&(p=0),p>=0&&p<24&&u>=0&&u<60&&(s=(p*3600+u*60)*1e3,n=!0,o=A.replace(a[0]," ").replace(/\s+/g," ").trim())}let r=p=>n?p+s:p;if(o===""||o==="today")return r(e(t));if(o==="yesterday")return r(e(t)-864e5);if(o==="tomorrow")return r(e(t)+864e5);let c=["sunday","monday","tuesday","wednesday","thursday","friday","saturday"],l=["sun","mon","tue","wed","thu","fri","sat"],d=c.indexOf(o)>=0?c.indexOf(o):l.indexOf(o);if(d>=0){let p=(0,dt.moment)().startOf("day"),f=(p.day()-d+7)%7;return r(p.subtract(f,"days").valueOf())}let I=/^(\d+)\s*([dwmy])$/.exec(o);if(I){let p=parseInt(I[1],10),u={d:"days",w:"weeks",m:"months",y:"years"}[I[2]];return r((0,dt.moment)().subtract(p,u).startOf("day").valueOf())}let g=(0,dt.moment)(o,["YYYY-MM-DD","YYYY/MM/DD","MM-DD-YYYY","MM/DD/YYYY","M-D-YYYY","M/D/YYYY"],!0);return g.isValid()?r(g.startOf("day").valueOf()):null}function sn(h){let A={text:[],filters:{}},t=(h||"").trim();if(!t)return A;let e=/\b(in|before|after|on):\s*(?:\[([^\]]*)\]|([^]*?)(?=\s+(?:in|before|after|on):|$))/gi,i=t,s;for(;(s=e.exec(t))!=null;){let n=s[1].toLowerCase(),o=(s[2]!==void 0?s[2]:s[3]??"").trim();if(o){if(n==="in")A.filters.in=o.toLowerCase();else if(n==="before"){let a=ds(o);a!=null&&(A.filters.before=a)}else if(n==="after"){let a=ds(o);a!=null&&(A.filters.after=a)}else if(n==="on"){let a=ds(o);if(a!=null)if(/\b\d{1,2}:\d{2}\b|\b\d{1,2}\s*(?:am|pm)\b/i.test(o))A.filters.on={start:a-6e4,end:a+6e4};else{let c=(0,dt.moment)(a).startOf("day").valueOf();A.filters.on={start:c,end:c+864e5}}}i=i.replace(s[0]," ")}}for(let n of i.split(/\s+/))n&&A.text.push(n.toLowerCase());return A}var Jt=class h extends dt.SuggestModal{constructor(t,e,i,s){super(t);this.tree=e;this.titleFn=i;this.opts=s;this.notes=[];this.pendingCleanups=[];this.crossFolderIndex=null;this.whenBuilderEl=null;this.whenMode="on";this.whenSingleText="";this.whenBetweenEndText="";this.setPlaceholder(s.placeholder??(s.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=(i,s)=>{let n=this.tree.get(i);n?.file&&i!==G?this.notes.push({node:n,title:`${" ".repeat(s)}${this.titleFn(n)}`,body:""}):n?.file&&i===G&&this.notes.push({node:n,title:"Home",body:""});for(let o of this.tree.getChildren(i))t(o.id,s+1)},e=this.tree.getRoot();e.file&&this.notes.push({node:e,title:"Home",body:""});for(let i of this.tree.getChildren(G))t(i.id,1);for(let i of this.notes)i.node?.file&&this.app.vault.cachedRead(i.node.file).then(s=>{i.body=this.stripFm(s)});if(this.opts.crossFolderNotes){let i=this.opts.crossFolderNotes();for(let s of i)this.notes.push({node:null,title:s.title,body:s.body,cross:s});for(let s of this.notes)!s.cross||s.body||s.cross.file&&this.app.vault.cachedRead(s.cross.file).then(n=>{s.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(),i=sn(t),s=i.text;console.log("[Stashpad] search query parsed",{query:t,text:i.text,filters:i.filters});let n=B=>{if(!s.length)return!0;for(let Q of s)if(!B.includes(Q))return!1;return!0},o=null,a=null;if(i.filters.in){let B=i.filters.in.split(/\s+/).filter(Boolean);o=new Set,a=new Map;let Q=v=>B.every(k=>v.toLowerCase().includes(k)),E=v=>{if(!o.has(v)){o.add(v);for(let k of this.tree.getChildren(v))E(k.id)}};for(let v of this.notes)!v.node||v.cross||Q(v.title)&&E(v.node.id);let y=new Map;for(let v of this.notes){if(!v.cross)continue;let k=y.get(v.cross.folder)??[];k.push(v),y.set(v.cross.folder,k)}for(let[v,k]of y){let b=new Map;for(let D of k){let m=D.cross?.parentId??null;if(!m)continue;let M=b.get(m)??[];M.push(D.cross.id),b.set(m,M)}let R=new Set;a.set(v,R);let w=D=>{if(!R.has(D)){R.add(D);for(let m of b.get(D)??[])w(m)}};for(let D of k)Q(D.title)&&w(D.cross.id)}}let r=B=>{let Q=i.filters;if(o||a)if(B.cross){let E=a?.get(B.cross.folder);if(!E||!E.has(B.cross.id))return!1}else if(B.node){if(!o||!o.has(B.node.id))return!1}else return!1;if(Q.before||Q.after||Q.on){let E=this.createdMsFor(B);if(E==null||Q.before!=null&&E>=Q.before||Q.after!=null&&E<=Q.after||Q.on&&(E<Q.on.start||E>=Q.on.end))return!1}return!0},c=B=>n(B.toLowerCase()),l=this.notes.filter(B=>!B.cross),d=this.notes.filter(B=>B.cross),I=(B,Q)=>({id:B.cross?`cross:${B.cross.id}`:B.node.id,label:B.title,node:B.node,kind:"note",bodyPreview:this.previewFromBody(B.body,Q),matchLine:Q,crossFolder:B.cross?.folder,crossFile:B.cross?.file}),g=B=>{let Q=[];for(let E of B)if(r(E))if(this.opts.mode==="search"){if(!e){Q.push(I(E,-1));continue}let y=n(E.title.toLowerCase()),v=E.body.split(/\r?\n/),k=[];for(let R=0;R<v.length;R++)c(v[R])&&k.push(R);let b=k.length>0||n(E.body.toLowerCase());if(!y&&!b)continue;if(k.length===0)Q.push(I(E,-1));else{let R=[],w=-100;for(let m of k)m-w>5&&R.push(m),w=m;let D=5;for(let m of R.slice(0,D))Q.push(I(E,m))}}else{if(e&&!n(E.title.toLowerCase())&&!n(E.body.toLowerCase()))continue;Q.push(I(E,-1))}return Q},p=g(l),u=[...p];if(this.opts.mode==="search"?e?!0:p.length<10:!!e){let B=g(d);this.opts.mode==="search"&&!e&&(u.length=Math.min(u.length,50)),u.push(...B)}if(this.opts.folderResults){let B=this.opts.folderResults(),Q=!e||B.some(E=>{let y=E.split("/").pop()??E;return n(`${E.toLowerCase()} ${y.toLowerCase()}`)});if(B.length>0&&Q){let E={id:"__folder_picker__",label:"Open folder in a new tab\u2026",node:null,kind:"folder-open"};Object.keys(i.filters).length>0?u.push(E):u.unshift(E)}}return this.opts.allowCreate&&e&&!u.some(B=>B.label.trim().toLowerCase()===e)&&u.push({id:"__create__",label:`Create new: "${t}"`,node:null,kind:"create"}),u}previewFromBody(t,e){let i=t.split(/\r?\n/);if(e<0)return i.filter(a=>a.trim().length>0).slice(0,3).join(` +`}function Ci(d,A){let t=document.createDocumentFragment(),e=t.createEl("div",{text:"Home note updated"});e.style.fontWeight="600",e.style.marginBottom="6px";let i=t.createEl("ul");i.style.margin="0 0 8px 0",i.style.paddingLeft="18px",i.createEl("li",{text:`${A.indexed.length} indexed`}),i.createEl("li",{text:`${A.nonIndex.length+A.skippedStashpadNotes.length} excluded`});let s=t.createEl("button",{text:"Open",cls:"mod-cta"});s.style.padding="2px 10px",s.style.fontSize="var(--font-ui-smaller)";let n;return s.onclick=async o=>{if(o.stopPropagation(),A.previewPath){let r=d.vault.getAbstractFileByPath(A.previewPath);r instanceof Ft.TFile&&await d.workspace.getLeaf("tab").openFile(r)}n?.hide()},n=new Ft.Notice(t,0),n}var Ft,on,We,Xe=se(()=>{"use strict";Ft=require("obsidian");Rt();Be();wt();on=/^(\d+-\d+|\d+|[A-Za-z0-9]+(?:\.[A-Za-z0-9]+)+)\s+(.+)$/;We=class extends Ft.Modal{constructor(t,e,i,s,n){super(t);this.plugin=e;this.settings=i;this.indexedCount=s;this.onBuild=n;this.LARGE_BUILD=50;this.previewRan=!1;this.previewPath=null}onOpen(){let{contentEl:t,titleEl:e}=this,i=!this.settings.jdIndexHasBuilt,s=this.indexedCount>this.LARGE_BUILD;e.setText(i?"Build JD index \u2014 first time?":"Build JD index");let n=this.settings.jdIndexStashpadFolder,o=t.createEl("p"),r=`${this.indexedCount} note${this.indexedCount===1?"":"s"}`;i?(o.appendText(`Stashpad is about to create ${r} (plus synthetic parents as needed) inside "`),o.createEl("code",{text:n}),o.appendText('". Existing notes with the same '),o.createEl("code",{text:"jdPrefix"}),o.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.")):s?(o.appendText(`You're about to create ${this.indexedCount} notes in "`),o.createEl("code",{text:n}),o.appendText(`". That's a big batch \u2014 if anything looks off, Preview the single-file output first.`)):(o.appendText('Build the JD index into "'),o.createEl("code",{text:n}),o.appendText(`"? Stashpad will create / update ${r}. Existing notes with matching `),o.createEl("code",{text:"jdPrefix"}),o.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 Ft.Setting(t);(i||s)&&a.addButton(c=>{c.setButtonText(this.previewRan?"Re-run preview":"Run preview first"),c.setCta(),c.onClick(async()=>{try{let l=await fi(this.app,this.plugin,this.settings);if(l.error==="no-dest"){new Ft.Notice("Set a Designated Stashpad folder for Index first.",5e3),this.close();return}if(l.error==="no-home"){new Ft.Notice(`"${this.settings.jdIndexStashpadFolder}" has no Stashpad home note. Open the folder in Stashpad first.`,7e3),this.close();return}this.previewRan=!0,this.previewPath=l.previewPath,Ci(this.app,l),this.contentEl.empty(),this.titleEl.empty(),this.onOpen()}catch(l){new Ft.Notice(`Preview failed: ${l?.message??l}`,8e3)}})}),a.addButton(c=>{c.setButtonText(i?"Build anyway":"Build"),!i&&!s&&c.setCta(),c.onClick(async()=>{this.close(),await this.onBuild()})}),a.addButton(c=>{c.setButtonText("Cancel"),c.onClick(()=>this.close())})}onClose(){this.contentEl.empty()}}});var xn=uo((Nn,ws)=>{(function(d){typeof Nn=="object"&&typeof ws<"u"?ws.exports=d():typeof define=="function"&&define.amd?define([],d):(typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:this).JSZip=d()})(function(){return function d(A,t,e){function i(o,r){if(!t[o]){if(!A[o]){var a=typeof require=="function"&&require;if(!r&&a)return a(o,!0);if(s)return s(o,!0);var c=new Error("Cannot find module '"+o+"'");throw c.code="MODULE_NOT_FOUND",c}var l=t[o]={exports:{}};A[o][0].call(l.exports,function(p){var g=A[o][1][p];return i(g||p)},l,l.exports,d,A,t,e)}return t[o].exports}for(var s=typeof require=="function"&&require,n=0;n<e.length;n++)i(e[n]);return i}({1:[function(d,A,t){"use strict";var e=d("./utils"),i=d("./support"),s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";t.encode=function(n){for(var o,r,a,c,l,p,g,h=[],I=0,u=n.length,f=u,C=e.getTypeOf(n)!=="string";I<n.length;)f=u-I,a=C?(o=n[I++],r=I<u?n[I++]:0,I<u?n[I++]:0):(o=n.charCodeAt(I++),r=I<u?n.charCodeAt(I++):0,I<u?n.charCodeAt(I++):0),c=o>>2,l=(3&o)<<4|r>>4,p=1<f?(15&r)<<2|a>>6:64,g=2<f?63&a:64,h.push(s.charAt(c)+s.charAt(l)+s.charAt(p)+s.charAt(g));return h.join("")},t.decode=function(n){var o,r,a,c,l,p,g=0,h=0,I="data:";if(n.substr(0,I.length)===I)throw new Error("Invalid base64 input, it looks like a data url.");var u,f=3*(n=n.replace(/[^A-Za-z0-9+/=]/g,"")).length/4;if(n.charAt(n.length-1)===s.charAt(64)&&f--,n.charAt(n.length-2)===s.charAt(64)&&f--,f%1!=0)throw new Error("Invalid base64 input, bad content length.");for(u=i.uint8array?new Uint8Array(0|f):new Array(0|f);g<n.length;)o=s.indexOf(n.charAt(g++))<<2|(c=s.indexOf(n.charAt(g++)))>>4,r=(15&c)<<4|(l=s.indexOf(n.charAt(g++)))>>2,a=(3&l)<<6|(p=s.indexOf(n.charAt(g++))),u[h++]=o,l!==64&&(u[h++]=r),p!==64&&(u[h++]=a);return u}},{"./support":30,"./utils":32}],2:[function(d,A,t){"use strict";var e=d("./external"),i=d("./stream/DataWorker"),s=d("./stream/Crc32Probe"),n=d("./stream/DataLengthProbe");function o(r,a,c,l,p){this.compressedSize=r,this.uncompressedSize=a,this.crc32=c,this.compression=l,this.compressedContent=p}o.prototype={getContentWorker:function(){var r=new i(e.Promise.resolve(this.compressedContent)).pipe(this.compression.uncompressWorker()).pipe(new n("data_length")),a=this;return r.on("end",function(){if(this.streamInfo.data_length!==a.uncompressedSize)throw new Error("Bug : uncompressed data size mismatch")}),r},getCompressedWorker:function(){return new i(e.Promise.resolve(this.compressedContent)).withStreamInfo("compressedSize",this.compressedSize).withStreamInfo("uncompressedSize",this.uncompressedSize).withStreamInfo("crc32",this.crc32).withStreamInfo("compression",this.compression)}},o.createWorkerFrom=function(r,a,c){return r.pipe(new s).pipe(new n("uncompressedSize")).pipe(a.compressWorker(c)).pipe(new n("compressedSize")).withStreamInfo("compression",a)},A.exports=o},{"./external":6,"./stream/Crc32Probe":25,"./stream/DataLengthProbe":26,"./stream/DataWorker":27}],3:[function(d,A,t){"use strict";var e=d("./stream/GenericWorker");t.STORE={magic:"\0\0",compressWorker:function(){return new e("STORE compression")},uncompressWorker:function(){return new e("STORE decompression")}},t.DEFLATE=d("./flate")},{"./flate":7,"./stream/GenericWorker":28}],4:[function(d,A,t){"use strict";var e=d("./utils"),i=function(){for(var s,n=[],o=0;o<256;o++){s=o;for(var r=0;r<8;r++)s=1&s?3988292384^s>>>1:s>>>1;n[o]=s}return n}();A.exports=function(s,n){return s!==void 0&&s.length?e.getTypeOf(s)!=="string"?function(o,r,a,c){var l=i,p=c+a;o^=-1;for(var g=c;g<p;g++)o=o>>>8^l[255&(o^r[g])];return-1^o}(0|n,s,s.length,0):function(o,r,a,c){var l=i,p=c+a;o^=-1;for(var g=c;g<p;g++)o=o>>>8^l[255&(o^r.charCodeAt(g))];return-1^o}(0|n,s,s.length,0):0}},{"./utils":32}],5:[function(d,A,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(d,A,t){"use strict";var e=null;e=typeof Promise<"u"?Promise:d("lie"),A.exports={Promise:e}},{lie:37}],7:[function(d,A,t){"use strict";var e=typeof Uint8Array<"u"&&typeof Uint16Array<"u"&&typeof Uint32Array<"u",i=d("pako"),s=d("./utils"),n=d("./stream/GenericWorker"),o=e?"uint8array":"array";function r(a,c){n.call(this,"FlateWorker/"+a),this._pako=null,this._pakoAction=a,this._pakoOptions=c,this.meta={}}t.magic="\b\0",s.inherits(r,n),r.prototype.processChunk=function(a){this.meta=a.meta,this._pako===null&&this._createPako(),this._pako.push(s.transformTo(o,a.data),!1)},r.prototype.flush=function(){n.prototype.flush.call(this),this._pako===null&&this._createPako(),this._pako.push([],!0)},r.prototype.cleanUp=function(){n.prototype.cleanUp.call(this),this._pako=null},r.prototype._createPako=function(){this._pako=new i[this._pakoAction]({raw:!0,level:this._pakoOptions.level||-1});var a=this;this._pako.onData=function(c){a.push({data:c,meta:a.meta})}},t.compressWorker=function(a){return new r("Deflate",a)},t.uncompressWorker=function(){return new r("Inflate",{})}},{"./stream/GenericWorker":28,"./utils":32,pako:38}],8:[function(d,A,t){"use strict";function e(l,p){var g,h="";for(g=0;g<p;g++)h+=String.fromCharCode(255&l),l>>>=8;return h}function i(l,p,g,h,I,u){var f,C,m=l.file,E=l.compression,y=u!==o.utf8encode,w=s.transformTo("string",u(m.name)),v=s.transformTo("string",o.utf8encode(m.name)),D=m.comment,L=s.transformTo("string",u(D)),S=s.transformTo("string",o.utf8encode(D)),b=v.length!==m.name.length,Q=S.length!==D.length,H="",$="",M="",T=m.dir,J=m.date,Z={crc32:0,compressedSize:0,uncompressedSize:0};p&&!g||(Z.crc32=l.crc32,Z.compressedSize=l.compressedSize,Z.uncompressedSize=l.uncompressedSize);var U=0;p&&(U|=8),y||!b&&!Q||(U|=2048);var N=0,j=0;T&&(N|=16),I==="UNIX"?(j=798,N|=function(z,ot){var dt=z;return z||(dt=ot?16893:33204),(65535&dt)<<16}(m.unixPermissions,T)):(j=20,N|=function(z){return 63&(z||0)}(m.dosPermissions)),f=J.getUTCHours(),f<<=6,f|=J.getUTCMinutes(),f<<=5,f|=J.getUTCSeconds()/2,C=J.getUTCFullYear()-1980,C<<=4,C|=J.getUTCMonth()+1,C<<=5,C|=J.getUTCDate(),b&&($=e(1,1)+e(r(w),4)+v,H+="up"+e($.length,2)+$),Q&&(M=e(1,1)+e(r(L),4)+S,H+="uc"+e(M.length,2)+M);var K="";return K+=` +\0`,K+=e(U,2),K+=E.magic,K+=e(f,2),K+=e(C,2),K+=e(Z.crc32,4),K+=e(Z.compressedSize,4),K+=e(Z.uncompressedSize,4),K+=e(w.length,2),K+=e(H.length,2),{fileRecord:a.LOCAL_FILE_HEADER+K+w+H,dirRecord:a.CENTRAL_FILE_HEADER+e(j,2)+K+e(L.length,2)+"\0\0\0\0"+e(N,4)+e(h,4)+w+H+L}}var s=d("../utils"),n=d("../stream/GenericWorker"),o=d("../utf8"),r=d("../crc32"),a=d("../signature");function c(l,p,g,h){n.call(this,"ZipFileWorker"),this.bytesWritten=0,this.zipComment=p,this.zipPlatform=g,this.encodeFileName=h,this.streamFiles=l,this.accumulate=!1,this.contentBuffer=[],this.dirRecords=[],this.currentSourceOffset=0,this.entriesCount=0,this.currentFile=null,this._sources=[]}s.inherits(c,n),c.prototype.push=function(l){var p=l.meta.percent||0,g=this.entriesCount,h=this._sources.length;this.accumulate?this.contentBuffer.push(l):(this.bytesWritten+=l.data.length,n.prototype.push.call(this,{data:l.data,meta:{currentFile:this.currentFile,percent:g?(p+100*(g-h-1))/g:100}}))},c.prototype.openedSource=function(l){this.currentSourceOffset=this.bytesWritten,this.currentFile=l.file.name;var p=this.streamFiles&&!l.file.dir;if(p){var g=i(l,p,!1,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);this.push({data:g.fileRecord,meta:{percent:0}})}else this.accumulate=!0},c.prototype.closedSource=function(l){this.accumulate=!1;var p=this.streamFiles&&!l.file.dir,g=i(l,p,!0,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);if(this.dirRecords.push(g.dirRecord),p)this.push({data:function(h){return a.DATA_DESCRIPTOR+e(h.crc32,4)+e(h.compressedSize,4)+e(h.uncompressedSize,4)}(l),meta:{percent:100}});else for(this.push({data:g.fileRecord,meta:{percent:0}});this.contentBuffer.length;)this.push(this.contentBuffer.shift());this.currentFile=null},c.prototype.flush=function(){for(var l=this.bytesWritten,p=0;p<this.dirRecords.length;p++)this.push({data:this.dirRecords[p],meta:{percent:100}});var g=this.bytesWritten-l,h=function(I,u,f,C,m){var E=s.transformTo("string",m(C));return a.CENTRAL_DIRECTORY_END+"\0\0\0\0"+e(I,2)+e(I,2)+e(u,4)+e(f,4)+e(E.length,2)+E}(this.dirRecords.length,g,l,this.zipComment,this.encodeFileName);this.push({data:h,meta:{percent:100}})},c.prototype.prepareNextSource=function(){this.previous=this._sources.shift(),this.openedSource(this.previous.streamInfo),this.isPaused?this.previous.pause():this.previous.resume()},c.prototype.registerPrevious=function(l){this._sources.push(l);var p=this;return l.on("data",function(g){p.processChunk(g)}),l.on("end",function(){p.closedSource(p.previous.streamInfo),p._sources.length?p.prepareNextSource():p.end()}),l.on("error",function(g){p.error(g)}),this},c.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))},c.prototype.error=function(l){var p=this._sources;if(!n.prototype.error.call(this,l))return!1;for(var g=0;g<p.length;g++)try{p[g].error(l)}catch{}return!0},c.prototype.lock=function(){n.prototype.lock.call(this);for(var l=this._sources,p=0;p<l.length;p++)l[p].lock()},A.exports=c},{"../crc32":4,"../signature":23,"../stream/GenericWorker":28,"../utf8":31,"../utils":32}],9:[function(d,A,t){"use strict";var e=d("../compressions"),i=d("./ZipFileWorker");t.generateWorker=function(s,n,o){var r=new i(n.streamFiles,o,n.platform,n.encodeFileName),a=0;try{s.forEach(function(c,l){a++;var p=function(u,f){var C=u||f,m=e[C];if(!m)throw new Error(C+" is not a valid compression method !");return m}(l.options.compression,n.compression),g=l.options.compressionOptions||n.compressionOptions||{},h=l.dir,I=l.date;l._compressWorker(p,g).withStreamInfo("file",{name:c,dir:h,date:I,comment:l.comment||"",unixPermissions:l.unixPermissions,dosPermissions:l.dosPermissions}).pipe(r)}),r.entriesCount=a}catch(c){r.error(c)}return r}},{"../compressions":3,"./ZipFileWorker":8}],10:[function(d,A,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 i=new e;for(var s in this)typeof this[s]!="function"&&(i[s]=this[s]);return i}}(e.prototype=d("./object")).loadAsync=d("./load"),e.support=d("./support"),e.defaults=d("./defaults"),e.version="3.10.1",e.loadAsync=function(i,s){return new e().loadAsync(i,s)},e.external=d("./external"),A.exports=e},{"./defaults":5,"./external":6,"./load":11,"./object":15,"./support":30}],11:[function(d,A,t){"use strict";var e=d("./utils"),i=d("./external"),s=d("./utf8"),n=d("./zipEntries"),o=d("./stream/Crc32Probe"),r=d("./nodejsUtils");function a(c){return new i.Promise(function(l,p){var g=c.decompressed.getContentWorker().pipe(new o);g.on("error",function(h){p(h)}).on("end",function(){g.streamInfo.crc32!==c.decompressed.crc32?p(new Error("Corrupted zip : CRC32 mismatch")):l()}).resume()})}A.exports=function(c,l){var p=this;return l=e.extend(l||{},{base64:!1,checkCRC32:!1,optimizedBinaryString:!1,createFolders:!1,decodeFileName:s.utf8decode}),r.isNode&&r.isStream(c)?i.Promise.reject(new Error("JSZip can't accept a stream when loading a zip file.")):e.prepareContent("the loaded zip file",c,!0,l.optimizedBinaryString,l.base64).then(function(g){var h=new n(l);return h.load(g),h}).then(function(g){var h=[i.Promise.resolve(g)],I=g.files;if(l.checkCRC32)for(var u=0;u<I.length;u++)h.push(a(I[u]));return i.Promise.all(h)}).then(function(g){for(var h=g.shift(),I=h.files,u=0;u<I.length;u++){var f=I[u],C=f.fileNameStr,m=e.resolve(f.fileNameStr);p.file(m,f.decompressed,{binary:!0,optimizedBinaryString:!0,date:f.date,dir:f.dir,comment:f.fileCommentStr.length?f.fileCommentStr:null,unixPermissions:f.unixPermissions,dosPermissions:f.dosPermissions,createFolders:l.createFolders}),f.dir||(p.file(m).unsafeOriginalName=C)}return h.zipComment.length&&(p.comment=h.zipComment),p})}},{"./external":6,"./nodejsUtils":14,"./stream/Crc32Probe":25,"./utf8":31,"./utils":32,"./zipEntries":33}],12:[function(d,A,t){"use strict";var e=d("../utils"),i=d("../stream/GenericWorker");function s(n,o){i.call(this,"Nodejs stream input adapter for "+n),this._upstreamEnded=!1,this._bindStream(o)}e.inherits(s,i),s.prototype._bindStream=function(n){var o=this;(this._stream=n).pause(),n.on("data",function(r){o.push({data:r,meta:{percent:0}})}).on("error",function(r){o.isPaused?this.generatedError=r:o.error(r)}).on("end",function(){o.isPaused?o._upstreamEnded=!0:o.end()})},s.prototype.pause=function(){return!!i.prototype.pause.call(this)&&(this._stream.pause(),!0)},s.prototype.resume=function(){return!!i.prototype.resume.call(this)&&(this._upstreamEnded?this.end():this._stream.resume(),!0)},A.exports=s},{"../stream/GenericWorker":28,"../utils":32}],13:[function(d,A,t){"use strict";var e=d("readable-stream").Readable;function i(s,n,o){e.call(this,n),this._helper=s;var r=this;s.on("data",function(a,c){r.push(a)||r._helper.pause(),o&&o(c)}).on("error",function(a){r.emit("error",a)}).on("end",function(){r.push(null)})}d("../utils").inherits(i,e),i.prototype._read=function(){this._helper.resume()},A.exports=i},{"../utils":32,"readable-stream":16}],14:[function(d,A,t){"use strict";A.exports={isNode:typeof Buffer<"u",newBufferFrom:function(e,i){if(Buffer.from&&Buffer.from!==Uint8Array.from)return Buffer.from(e,i);if(typeof e=="number")throw new Error('The "data" argument must not be a number');return new Buffer(e,i)},allocBuffer:function(e){if(Buffer.alloc)return Buffer.alloc(e);var i=new Buffer(e);return i.fill(0),i},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(d,A,t){"use strict";function e(m,E,y){var w,v=s.getTypeOf(E),D=s.extend(y||{},r);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&&(m=I(m)),D.createFolders&&(w=h(m))&&u.call(this,w,!0);var L=v==="string"&&D.binary===!1&&D.base64===!1;y&&y.binary!==void 0||(D.binary=!L),(E instanceof a&&E.uncompressedSize===0||D.dir||!E||E.length===0)&&(D.base64=!1,D.binary=!0,E="",D.compression="STORE",v="string");var S=null;S=E instanceof a||E instanceof n?E:p.isNode&&p.isStream(E)?new g(m,E):s.prepareContent(m,E,D.binary,D.optimizedBinaryString,D.base64);var b=new c(m,S,D);this.files[m]=b}var i=d("./utf8"),s=d("./utils"),n=d("./stream/GenericWorker"),o=d("./stream/StreamHelper"),r=d("./defaults"),a=d("./compressedObject"),c=d("./zipObject"),l=d("./generate"),p=d("./nodejsUtils"),g=d("./nodejs/NodejsStreamInputAdapter"),h=function(m){m.slice(-1)==="/"&&(m=m.substring(0,m.length-1));var E=m.lastIndexOf("/");return 0<E?m.substring(0,E):""},I=function(m){return m.slice(-1)!=="/"&&(m+="/"),m},u=function(m,E){return E=E!==void 0?E:r.createFolders,m=I(m),this.files[m]||e.call(this,m,null,{dir:!0,createFolders:E}),this.files[m]};function f(m){return Object.prototype.toString.call(m)==="[object RegExp]"}var C={load:function(){throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.")},forEach:function(m){var E,y,w;for(E in this.files)w=this.files[E],(y=E.slice(this.root.length,E.length))&&E.slice(0,this.root.length)===this.root&&m(y,w)},filter:function(m){var E=[];return this.forEach(function(y,w){m(y,w)&&E.push(w)}),E},file:function(m,E,y){if(arguments.length!==1)return m=this.root+m,e.call(this,m,E,y),this;if(f(m)){var w=m;return this.filter(function(D,L){return!L.dir&&w.test(D)})}var v=this.files[this.root+m];return v&&!v.dir?v:null},folder:function(m){if(!m)return this;if(f(m))return this.filter(function(v,D){return D.dir&&m.test(v)});var E=this.root+m,y=u.call(this,E),w=this.clone();return w.root=y.name,w},remove:function(m){m=this.root+m;var E=this.files[m];if(E||(m.slice(-1)!=="/"&&(m+="/"),E=this.files[m]),E&&!E.dir)delete this.files[m];else for(var y=this.filter(function(v,D){return D.name.slice(0,m.length)===m}),w=0;w<y.length;w++)delete this.files[y[w].name];return this},generate:function(){throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.")},generateInternalStream:function(m){var E,y={};try{if((y=s.extend(m||{},{streamFiles:!1,compression:"STORE",compressionOptions:null,type:"",platform:"DOS",comment:null,mimeType:"application/zip",encodeFileName:i.utf8encode})).type=y.type.toLowerCase(),y.compression=y.compression.toUpperCase(),y.type==="binarystring"&&(y.type="string"),!y.type)throw new Error("No output type specified.");s.checkSupport(y.type),y.platform!=="darwin"&&y.platform!=="freebsd"&&y.platform!=="linux"&&y.platform!=="sunos"||(y.platform="UNIX"),y.platform==="win32"&&(y.platform="DOS");var w=y.comment||this.comment||"";E=l.generateWorker(this,y,w)}catch(v){(E=new n("error")).error(v)}return new o(E,y.type||"string",y.mimeType)},generateAsync:function(m,E){return this.generateInternalStream(m).accumulate(E)},generateNodeStream:function(m,E){return(m=m||{}).type||(m.type="nodebuffer"),this.generateInternalStream(m).toNodejsStream(E)}};A.exports=C},{"./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(d,A,t){"use strict";A.exports=d("stream")},{stream:void 0}],17:[function(d,A,t){"use strict";var e=d("./DataReader");function i(s){e.call(this,s);for(var n=0;n<this.data.length;n++)s[n]=255&s[n]}d("../utils").inherits(i,e),i.prototype.byteAt=function(s){return this.data[this.zero+s]},i.prototype.lastIndexOfSignature=function(s){for(var n=s.charCodeAt(0),o=s.charCodeAt(1),r=s.charCodeAt(2),a=s.charCodeAt(3),c=this.length-4;0<=c;--c)if(this.data[c]===n&&this.data[c+1]===o&&this.data[c+2]===r&&this.data[c+3]===a)return c-this.zero;return-1},i.prototype.readAndCheckSignature=function(s){var n=s.charCodeAt(0),o=s.charCodeAt(1),r=s.charCodeAt(2),a=s.charCodeAt(3),c=this.readData(4);return n===c[0]&&o===c[1]&&r===c[2]&&a===c[3]},i.prototype.readData=function(s){if(this.checkOffset(s),s===0)return[];var n=this.data.slice(this.zero+this.index,this.zero+this.index+s);return this.index+=s,n},A.exports=i},{"../utils":32,"./DataReader":18}],18:[function(d,A,t){"use strict";var e=d("../utils");function i(s){this.data=s,this.length=s.length,this.index=0,this.zero=0}i.prototype={checkOffset:function(s){this.checkIndex(this.index+s)},checkIndex:function(s){if(this.length<this.zero+s||s<0)throw new Error("End of data reached (data length = "+this.length+", asked index = "+s+"). Corrupted zip ?")},setIndex:function(s){this.checkIndex(s),this.index=s},skip:function(s){this.setIndex(this.index+s)},byteAt:function(){},readInt:function(s){var n,o=0;for(this.checkOffset(s),n=this.index+s-1;n>=this.index;n--)o=(o<<8)+this.byteAt(n);return this.index+=s,o},readString:function(s){return e.transformTo("string",this.readData(s))},readData:function(){},lastIndexOfSignature:function(){},readAndCheckSignature:function(){},readDate:function(){var s=this.readInt(4);return new Date(Date.UTC(1980+(s>>25&127),(s>>21&15)-1,s>>16&31,s>>11&31,s>>5&63,(31&s)<<1))}},A.exports=i},{"../utils":32}],19:[function(d,A,t){"use strict";var e=d("./Uint8ArrayReader");function i(s){e.call(this,s)}d("../utils").inherits(i,e),i.prototype.readData=function(s){this.checkOffset(s);var n=this.data.slice(this.zero+this.index,this.zero+this.index+s);return this.index+=s,n},A.exports=i},{"../utils":32,"./Uint8ArrayReader":21}],20:[function(d,A,t){"use strict";var e=d("./DataReader");function i(s){e.call(this,s)}d("../utils").inherits(i,e),i.prototype.byteAt=function(s){return this.data.charCodeAt(this.zero+s)},i.prototype.lastIndexOfSignature=function(s){return this.data.lastIndexOf(s)-this.zero},i.prototype.readAndCheckSignature=function(s){return s===this.readData(4)},i.prototype.readData=function(s){this.checkOffset(s);var n=this.data.slice(this.zero+this.index,this.zero+this.index+s);return this.index+=s,n},A.exports=i},{"../utils":32,"./DataReader":18}],21:[function(d,A,t){"use strict";var e=d("./ArrayReader");function i(s){e.call(this,s)}d("../utils").inherits(i,e),i.prototype.readData=function(s){if(this.checkOffset(s),s===0)return new Uint8Array(0);var n=this.data.subarray(this.zero+this.index,this.zero+this.index+s);return this.index+=s,n},A.exports=i},{"../utils":32,"./ArrayReader":17}],22:[function(d,A,t){"use strict";var e=d("../utils"),i=d("../support"),s=d("./ArrayReader"),n=d("./StringReader"),o=d("./NodeBufferReader"),r=d("./Uint8ArrayReader");A.exports=function(a){var c=e.getTypeOf(a);return e.checkSupport(c),c!=="string"||i.uint8array?c==="nodebuffer"?new o(a):i.uint8array?new r(e.transformTo("uint8array",a)):new s(e.transformTo("array",a)):new n(a)}},{"../support":30,"../utils":32,"./ArrayReader":17,"./NodeBufferReader":19,"./StringReader":20,"./Uint8ArrayReader":21}],23:[function(d,A,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(d,A,t){"use strict";var e=d("./GenericWorker"),i=d("../utils");function s(n){e.call(this,"ConvertWorker to "+n),this.destType=n}i.inherits(s,e),s.prototype.processChunk=function(n){this.push({data:i.transformTo(this.destType,n.data),meta:n.meta})},A.exports=s},{"../utils":32,"./GenericWorker":28}],25:[function(d,A,t){"use strict";var e=d("./GenericWorker"),i=d("../crc32");function s(){e.call(this,"Crc32Probe"),this.withStreamInfo("crc32",0)}d("../utils").inherits(s,e),s.prototype.processChunk=function(n){this.streamInfo.crc32=i(n.data,this.streamInfo.crc32||0),this.push(n)},A.exports=s},{"../crc32":4,"../utils":32,"./GenericWorker":28}],26:[function(d,A,t){"use strict";var e=d("../utils"),i=d("./GenericWorker");function s(n){i.call(this,"DataLengthProbe for "+n),this.propName=n,this.withStreamInfo(n,0)}e.inherits(s,i),s.prototype.processChunk=function(n){if(n){var o=this.streamInfo[this.propName]||0;this.streamInfo[this.propName]=o+n.data.length}i.prototype.processChunk.call(this,n)},A.exports=s},{"../utils":32,"./GenericWorker":28}],27:[function(d,A,t){"use strict";var e=d("../utils"),i=d("./GenericWorker");function s(n){i.call(this,"DataWorker");var o=this;this.dataIsReady=!1,this.index=0,this.max=0,this.data=null,this.type="",this._tickScheduled=!1,n.then(function(r){o.dataIsReady=!0,o.data=r,o.max=r&&r.length||0,o.type=e.getTypeOf(r),o.isPaused||o._tickAndRepeat()},function(r){o.error(r)})}e.inherits(s,i),s.prototype.cleanUp=function(){i.prototype.cleanUp.call(this),this.data=null},s.prototype.resume=function(){return!!i.prototype.resume.call(this)&&(!this._tickScheduled&&this.dataIsReady&&(this._tickScheduled=!0,e.delay(this._tickAndRepeat,[],this)),!0)},s.prototype._tickAndRepeat=function(){this._tickScheduled=!1,this.isPaused||this.isFinished||(this._tick(),this.isFinished||(e.delay(this._tickAndRepeat,[],this),this._tickScheduled=!0))},s.prototype._tick=function(){if(this.isPaused||this.isFinished)return!1;var n=null,o=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,o);break;case"uint8array":n=this.data.subarray(this.index,o);break;case"array":case"nodebuffer":n=this.data.slice(this.index,o)}return this.index=o,this.push({data:n,meta:{percent:this.max?this.index/this.max*100:0}})},A.exports=s},{"../utils":32,"./GenericWorker":28}],28:[function(d,A,t){"use strict";function e(i){this.name=i||"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(i){this.emit("data",i)},end:function(){if(this.isFinished)return!1;this.flush();try{this.emit("end"),this.cleanUp(),this.isFinished=!0}catch(i){this.emit("error",i)}return!0},error:function(i){return!this.isFinished&&(this.isPaused?this.generatedError=i:(this.isFinished=!0,this.emit("error",i),this.previous&&this.previous.error(i),this.cleanUp()),!0)},on:function(i,s){return this._listeners[i].push(s),this},cleanUp:function(){this.streamInfo=this.generatedError=this.extraStreamInfo=null,this._listeners=[]},emit:function(i,s){if(this._listeners[i])for(var n=0;n<this._listeners[i].length;n++)this._listeners[i][n].call(this,s)},pipe:function(i){return i.registerPrevious(this)},registerPrevious:function(i){if(this.isLocked)throw new Error("The stream '"+this+"' has already been used.");this.streamInfo=i.streamInfo,this.mergeStreamInfo(),this.previous=i;var s=this;return i.on("data",function(n){s.processChunk(n)}),i.on("end",function(){s.end()}),i.on("error",function(n){s.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 i=this.isPaused=!1;return this.generatedError&&(this.error(this.generatedError),i=!0),this.previous&&this.previous.resume(),!i},flush:function(){},processChunk:function(i){this.push(i)},withStreamInfo:function(i,s){return this.extraStreamInfo[i]=s,this.mergeStreamInfo(),this},mergeStreamInfo:function(){for(var i in this.extraStreamInfo)Object.prototype.hasOwnProperty.call(this.extraStreamInfo,i)&&(this.streamInfo[i]=this.extraStreamInfo[i])},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 i="Worker "+this.name;return this.previous?this.previous+" -> "+i:i}},A.exports=e},{}],29:[function(d,A,t){"use strict";var e=d("../utils"),i=d("./ConvertWorker"),s=d("./GenericWorker"),n=d("../base64"),o=d("../support"),r=d("../external"),a=null;if(o.nodestream)try{a=d("../nodejs/NodejsStreamOutputAdapter")}catch{}function c(p,g){return new r.Promise(function(h,I){var u=[],f=p._internalType,C=p._outputType,m=p._mimeType;p.on("data",function(E,y){u.push(E),g&&g(y)}).on("error",function(E){u=[],I(E)}).on("end",function(){try{var E=function(y,w,v){switch(y){case"blob":return e.newBlob(e.transformTo("arraybuffer",w),v);case"base64":return n.encode(w);default:return e.transformTo(y,w)}}(C,function(y,w){var v,D=0,L=null,S=0;for(v=0;v<w.length;v++)S+=w[v].length;switch(y){case"string":return w.join("");case"array":return Array.prototype.concat.apply([],w);case"uint8array":for(L=new Uint8Array(S),v=0;v<w.length;v++)L.set(w[v],D),D+=w[v].length;return L;case"nodebuffer":return Buffer.concat(w);default:throw new Error("concat : unsupported type '"+y+"'")}}(f,u),m);h(E)}catch(y){I(y)}u=[]}).resume()})}function l(p,g,h){var I=g;switch(g){case"blob":case"arraybuffer":I="uint8array";break;case"base64":I="string"}try{this._internalType=I,this._outputType=g,this._mimeType=h,e.checkSupport(I),this._worker=p.pipe(new i(I)),p.lock()}catch(u){this._worker=new s("error"),this._worker.error(u)}}l.prototype={accumulate:function(p){return c(this,p)},on:function(p,g){var h=this;return p==="data"?this._worker.on(p,function(I){g.call(h,I.data,I.meta)}):this._worker.on(p,function(){e.delay(g,arguments,h)}),this},resume:function(){return e.delay(this._worker.resume,[],this._worker),this},pause:function(){return this._worker.pause(),this},toNodejsStream:function(p){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"},p)}},A.exports=l},{"../base64":1,"../external":6,"../nodejs/NodejsStreamOutputAdapter":13,"../support":30,"../utils":32,"./ConvertWorker":24,"./GenericWorker":28}],30:[function(d,A,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 i=new(self.BlobBuilder||self.WebKitBlobBuilder||self.MozBlobBuilder||self.MSBlobBuilder);i.append(e),t.blob=i.getBlob("application/zip").size===0}catch{t.blob=!1}}}try{t.nodestream=!!d("readable-stream").Readable}catch{t.nodestream=!1}},{"readable-stream":16}],31:[function(d,A,t){"use strict";for(var e=d("./utils"),i=d("./support"),s=d("./nodejsUtils"),n=d("./stream/GenericWorker"),o=new Array(256),r=0;r<256;r++)o[r]=252<=r?6:248<=r?5:240<=r?4:224<=r?3:192<=r?2:1;o[254]=o[254]=1;function a(){n.call(this,"utf-8 decode"),this.leftOver=null}function c(){n.call(this,"utf-8 encode")}t.utf8encode=function(l){return i.nodebuffer?s.newBufferFrom(l,"utf-8"):function(p){var g,h,I,u,f,C=p.length,m=0;for(u=0;u<C;u++)(64512&(h=p.charCodeAt(u)))==55296&&u+1<C&&(64512&(I=p.charCodeAt(u+1)))==56320&&(h=65536+(h-55296<<10)+(I-56320),u++),m+=h<128?1:h<2048?2:h<65536?3:4;for(g=i.uint8array?new Uint8Array(m):new Array(m),u=f=0;f<m;u++)(64512&(h=p.charCodeAt(u)))==55296&&u+1<C&&(64512&(I=p.charCodeAt(u+1)))==56320&&(h=65536+(h-55296<<10)+(I-56320),u++),h<128?g[f++]=h:(h<2048?g[f++]=192|h>>>6:(h<65536?g[f++]=224|h>>>12:(g[f++]=240|h>>>18,g[f++]=128|h>>>12&63),g[f++]=128|h>>>6&63),g[f++]=128|63&h);return g}(l)},t.utf8decode=function(l){return i.nodebuffer?e.transformTo("nodebuffer",l).toString("utf-8"):function(p){var g,h,I,u,f=p.length,C=new Array(2*f);for(g=h=0;g<f;)if((I=p[g++])<128)C[h++]=I;else if(4<(u=o[I]))C[h++]=65533,g+=u-1;else{for(I&=u===2?31:u===3?15:7;1<u&&g<f;)I=I<<6|63&p[g++],u--;1<u?C[h++]=65533:I<65536?C[h++]=I:(I-=65536,C[h++]=55296|I>>10&1023,C[h++]=56320|1023&I)}return C.length!==h&&(C.subarray?C=C.subarray(0,h):C.length=h),e.applyFromCharCode(C)}(l=e.transformTo(i.uint8array?"uint8array":"array",l))},e.inherits(a,n),a.prototype.processChunk=function(l){var p=e.transformTo(i.uint8array?"uint8array":"array",l.data);if(this.leftOver&&this.leftOver.length){if(i.uint8array){var g=p;(p=new Uint8Array(g.length+this.leftOver.length)).set(this.leftOver,0),p.set(g,this.leftOver.length)}else p=this.leftOver.concat(p);this.leftOver=null}var h=function(u,f){var C;for((f=f||u.length)>u.length&&(f=u.length),C=f-1;0<=C&&(192&u[C])==128;)C--;return C<0||C===0?f:C+o[u[C]]>f?C:f}(p),I=p;h!==p.length&&(i.uint8array?(I=p.subarray(0,h),this.leftOver=p.subarray(h,p.length)):(I=p.slice(0,h),this.leftOver=p.slice(h,p.length))),this.push({data:t.utf8decode(I),meta:l.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(c,n),c.prototype.processChunk=function(l){this.push({data:t.utf8encode(l.data),meta:l.meta})},t.Utf8EncodeWorker=c},{"./nodejsUtils":14,"./stream/GenericWorker":28,"./support":30,"./utils":32}],32:[function(d,A,t){"use strict";var e=d("./support"),i=d("./base64"),s=d("./nodejsUtils"),n=d("./external");function o(g){return g}function r(g,h){for(var I=0;I<g.length;++I)h[I]=255&g.charCodeAt(I);return h}d("setimmediate"),t.newBlob=function(g,h){t.checkSupport("blob");try{return new Blob([g],{type:h})}catch{try{var I=new(self.BlobBuilder||self.WebKitBlobBuilder||self.MozBlobBuilder||self.MSBlobBuilder);return I.append(g),I.getBlob(h)}catch{throw new Error("Bug : can't construct the Blob.")}}};var a={stringifyByChunk:function(g,h,I){var u=[],f=0,C=g.length;if(C<=I)return String.fromCharCode.apply(null,g);for(;f<C;)h==="array"||h==="nodebuffer"?u.push(String.fromCharCode.apply(null,g.slice(f,Math.min(f+I,C)))):u.push(String.fromCharCode.apply(null,g.subarray(f,Math.min(f+I,C)))),f+=I;return u.join("")},stringifyByChar:function(g){for(var h="",I=0;I<g.length;I++)h+=String.fromCharCode(g[I]);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,s.allocBuffer(1)).length===1}catch{return!1}}()}};function c(g){var h=65536,I=t.getTypeOf(g),u=!0;if(I==="uint8array"?u=a.applyCanBeUsed.uint8array:I==="nodebuffer"&&(u=a.applyCanBeUsed.nodebuffer),u)for(;1<h;)try{return a.stringifyByChunk(g,I,h)}catch{h=Math.floor(h/2)}return a.stringifyByChar(g)}function l(g,h){for(var I=0;I<g.length;I++)h[I]=g[I];return h}t.applyFromCharCode=c;var p={};p.string={string:o,array:function(g){return r(g,new Array(g.length))},arraybuffer:function(g){return p.string.uint8array(g).buffer},uint8array:function(g){return r(g,new Uint8Array(g.length))},nodebuffer:function(g){return r(g,s.allocBuffer(g.length))}},p.array={string:c,array:o,arraybuffer:function(g){return new Uint8Array(g).buffer},uint8array:function(g){return new Uint8Array(g)},nodebuffer:function(g){return s.newBufferFrom(g)}},p.arraybuffer={string:function(g){return c(new Uint8Array(g))},array:function(g){return l(new Uint8Array(g),new Array(g.byteLength))},arraybuffer:o,uint8array:function(g){return new Uint8Array(g)},nodebuffer:function(g){return s.newBufferFrom(new Uint8Array(g))}},p.uint8array={string:c,array:function(g){return l(g,new Array(g.length))},arraybuffer:function(g){return g.buffer},uint8array:o,nodebuffer:function(g){return s.newBufferFrom(g)}},p.nodebuffer={string:c,array:function(g){return l(g,new Array(g.length))},arraybuffer:function(g){return p.nodebuffer.uint8array(g).buffer},uint8array:function(g){return l(g,new Uint8Array(g.length))},nodebuffer:o},t.transformTo=function(g,h){if(h=h||"",!g)return h;t.checkSupport(g);var I=t.getTypeOf(h);return p[I][g](h)},t.resolve=function(g){for(var h=g.split("/"),I=[],u=0;u<h.length;u++){var f=h[u];f==="."||f===""&&u!==0&&u!==h.length-1||(f===".."?I.pop():I.push(f))}return I.join("/")},t.getTypeOf=function(g){return typeof g=="string"?"string":Object.prototype.toString.call(g)==="[object Array]"?"array":e.nodebuffer&&s.isBuffer(g)?"nodebuffer":e.uint8array&&g instanceof Uint8Array?"uint8array":e.arraybuffer&&g instanceof ArrayBuffer?"arraybuffer":void 0},t.checkSupport=function(g){if(!e[g.toLowerCase()])throw new Error(g+" is not supported by this platform")},t.MAX_VALUE_16BITS=65535,t.MAX_VALUE_32BITS=-1,t.pretty=function(g){var h,I,u="";for(I=0;I<(g||"").length;I++)u+="\\x"+((h=g.charCodeAt(I))<16?"0":"")+h.toString(16).toUpperCase();return u},t.delay=function(g,h,I){setImmediate(function(){g.apply(I||null,h||[])})},t.inherits=function(g,h){function I(){}I.prototype=h.prototype,g.prototype=new I},t.extend=function(){var g,h,I={};for(g=0;g<arguments.length;g++)for(h in arguments[g])Object.prototype.hasOwnProperty.call(arguments[g],h)&&I[h]===void 0&&(I[h]=arguments[g][h]);return I},t.prepareContent=function(g,h,I,u,f){return n.Promise.resolve(h).then(function(C){return e.blob&&(C instanceof Blob||["[object File]","[object Blob]"].indexOf(Object.prototype.toString.call(C))!==-1)&&typeof FileReader<"u"?new n.Promise(function(m,E){var y=new FileReader;y.onload=function(w){m(w.target.result)},y.onerror=function(w){E(w.target.error)},y.readAsArrayBuffer(C)}):C}).then(function(C){var m=t.getTypeOf(C);return m?(m==="arraybuffer"?C=t.transformTo("uint8array",C):m==="string"&&(f?C=i.decode(C):I&&u!==!0&&(C=function(E){return r(E,e.uint8array?new Uint8Array(E.length):new Array(E.length))}(C))),C):n.Promise.reject(new Error("Can't read the data of '"+g+"'. Is it in a supported JavaScript type (String, Blob, ArrayBuffer, etc) ?"))})}},{"./base64":1,"./external":6,"./nodejsUtils":14,"./support":30,setimmediate:54}],33:[function(d,A,t){"use strict";var e=d("./reader/readerFor"),i=d("./utils"),s=d("./signature"),n=d("./zipEntry"),o=d("./support");function r(a){this.files=[],this.loadOptions=a}r.prototype={checkSignature:function(a){if(!this.reader.readAndCheckSignature(a)){this.reader.index-=4;var c=this.reader.readString(4);throw new Error("Corrupted zip or bug: unexpected signature ("+i.pretty(c)+", expected "+i.pretty(a)+")")}},isSignature:function(a,c){var l=this.reader.index;this.reader.setIndex(a);var p=this.reader.readString(4)===c;return this.reader.setIndex(l),p},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),c=o.uint8array?"uint8array":"array",l=i.transformTo(c,a);this.zipComment=this.loadOptions.decodeFileName(l)},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,c,l,p=this.zip64EndOfCentralSize-44;0<p;)a=this.reader.readInt(2),c=this.reader.readInt(4),l=this.reader.readData(c),this.zip64ExtensibleData[a]={id:a,length:c,value:l}},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,c;for(a=0;a<this.files.length;a++)c=this.files[a],this.reader.setIndex(c.localHeaderOffset),this.checkSignature(s.LOCAL_FILE_HEADER),c.readLocalPart(this.reader),c.handleUTF8(),c.processAttributes()},readCentralDir:function(){var a;for(this.reader.setIndex(this.centralDirOffset);this.reader.readAndCheckSignature(s.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(s.CENTRAL_DIRECTORY_END);if(a<0)throw this.isSignature(0,s.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 c=a;if(this.checkSignature(s.CENTRAL_DIRECTORY_END),this.readBlockEndOfCentral(),this.diskNumber===i.MAX_VALUE_16BITS||this.diskWithCentralDirStart===i.MAX_VALUE_16BITS||this.centralDirRecordsOnThisDisk===i.MAX_VALUE_16BITS||this.centralDirRecords===i.MAX_VALUE_16BITS||this.centralDirSize===i.MAX_VALUE_32BITS||this.centralDirOffset===i.MAX_VALUE_32BITS){if(this.zip64=!0,(a=this.reader.lastIndexOfSignature(s.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(s.ZIP64_CENTRAL_DIRECTORY_LOCATOR),this.readBlockZip64EndOfCentralLocator(),!this.isSignature(this.relativeOffsetEndOfZip64CentralDir,s.ZIP64_CENTRAL_DIRECTORY_END)&&(this.relativeOffsetEndOfZip64CentralDir=this.reader.lastIndexOfSignature(s.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(s.ZIP64_CENTRAL_DIRECTORY_END),this.readBlockZip64EndOfCentral()}var l=this.centralDirOffset+this.centralDirSize;this.zip64&&(l+=20,l+=12+this.zip64EndOfCentralSize);var p=c-l;if(0<p)this.isSignature(c,s.CENTRAL_FILE_HEADER)||(this.reader.zero=p);else if(p<0)throw new Error("Corrupted zip: missing "+Math.abs(p)+" bytes.")},prepareReader:function(a){this.reader=e(a)},load:function(a){this.prepareReader(a),this.readEndOfCentral(),this.readCentralDir(),this.readLocalFiles()}},A.exports=r},{"./reader/readerFor":22,"./signature":23,"./support":30,"./utils":32,"./zipEntry":34}],34:[function(d,A,t){"use strict";var e=d("./reader/readerFor"),i=d("./utils"),s=d("./compressedObject"),n=d("./crc32"),o=d("./utf8"),r=d("./compressions"),a=d("./support");function c(l,p){this.options=l,this.loadOptions=p}c.prototype={isEncrypted:function(){return(1&this.bitFlag)==1},useUTF8:function(){return(2048&this.bitFlag)==2048},readLocalPart:function(l){var p,g;if(l.skip(22),this.fileNameLength=l.readInt(2),g=l.readInt(2),this.fileName=l.readData(this.fileNameLength),l.skip(g),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((p=function(h){for(var I in r)if(Object.prototype.hasOwnProperty.call(r,I)&&r[I].magic===h)return r[I];return null}(this.compressionMethod))===null)throw new Error("Corrupted zip : compression "+i.pretty(this.compressionMethod)+" unknown (inner file : "+i.transformTo("string",this.fileName)+")");this.decompressed=new s(this.compressedSize,this.uncompressedSize,this.crc32,p,l.readData(this.compressedSize))},readCentralPart:function(l){this.versionMadeBy=l.readInt(2),l.skip(2),this.bitFlag=l.readInt(2),this.compressionMethod=l.readString(2),this.date=l.readDate(),this.crc32=l.readInt(4),this.compressedSize=l.readInt(4),this.uncompressedSize=l.readInt(4);var p=l.readInt(2);if(this.extraFieldsLength=l.readInt(2),this.fileCommentLength=l.readInt(2),this.diskNumberStart=l.readInt(2),this.internalFileAttributes=l.readInt(2),this.externalFileAttributes=l.readInt(4),this.localHeaderOffset=l.readInt(4),this.isEncrypted())throw new Error("Encrypted zip are not supported");l.skip(p),this.readExtraFields(l),this.parseZIP64ExtraField(l),this.fileComment=l.readData(this.fileCommentLength)},processAttributes:function(){this.unixPermissions=null,this.dosPermissions=null;var l=this.versionMadeBy>>8;this.dir=!!(16&this.externalFileAttributes),l==0&&(this.dosPermissions=63&this.externalFileAttributes),l==3&&(this.unixPermissions=this.externalFileAttributes>>16&65535),this.dir||this.fileNameStr.slice(-1)!=="/"||(this.dir=!0)},parseZIP64ExtraField:function(){if(this.extraFields[1]){var l=e(this.extraFields[1].value);this.uncompressedSize===i.MAX_VALUE_32BITS&&(this.uncompressedSize=l.readInt(8)),this.compressedSize===i.MAX_VALUE_32BITS&&(this.compressedSize=l.readInt(8)),this.localHeaderOffset===i.MAX_VALUE_32BITS&&(this.localHeaderOffset=l.readInt(8)),this.diskNumberStart===i.MAX_VALUE_32BITS&&(this.diskNumberStart=l.readInt(4))}},readExtraFields:function(l){var p,g,h,I=l.index+this.extraFieldsLength;for(this.extraFields||(this.extraFields={});l.index+4<I;)p=l.readInt(2),g=l.readInt(2),h=l.readData(g),this.extraFields[p]={id:p,length:g,value:h};l.setIndex(I)},handleUTF8:function(){var l=a.uint8array?"uint8array":"array";if(this.useUTF8())this.fileNameStr=o.utf8decode(this.fileName),this.fileCommentStr=o.utf8decode(this.fileComment);else{var p=this.findExtraFieldUnicodePath();if(p!==null)this.fileNameStr=p;else{var g=i.transformTo(l,this.fileName);this.fileNameStr=this.loadOptions.decodeFileName(g)}var h=this.findExtraFieldUnicodeComment();if(h!==null)this.fileCommentStr=h;else{var I=i.transformTo(l,this.fileComment);this.fileCommentStr=this.loadOptions.decodeFileName(I)}}},findExtraFieldUnicodePath:function(){var l=this.extraFields[28789];if(l){var p=e(l.value);return p.readInt(1)!==1||n(this.fileName)!==p.readInt(4)?null:o.utf8decode(p.readData(l.length-5))}return null},findExtraFieldUnicodeComment:function(){var l=this.extraFields[25461];if(l){var p=e(l.value);return p.readInt(1)!==1||n(this.fileComment)!==p.readInt(4)?null:o.utf8decode(p.readData(l.length-5))}return null}},A.exports=c},{"./compressedObject":2,"./compressions":3,"./crc32":4,"./reader/readerFor":22,"./support":30,"./utf8":31,"./utils":32}],35:[function(d,A,t){"use strict";function e(p,g,h){this.name=p,this.dir=h.dir,this.date=h.date,this.comment=h.comment,this.unixPermissions=h.unixPermissions,this.dosPermissions=h.dosPermissions,this._data=g,this._dataBinary=h.binary,this.options={compression:h.compression,compressionOptions:h.compressionOptions}}var i=d("./stream/StreamHelper"),s=d("./stream/DataWorker"),n=d("./utf8"),o=d("./compressedObject"),r=d("./stream/GenericWorker");e.prototype={internalStream:function(p){var g=null,h="string";try{if(!p)throw new Error("No output type specified.");var I=(h=p.toLowerCase())==="string"||h==="text";h!=="binarystring"&&h!=="text"||(h="string"),g=this._decompressWorker();var u=!this._dataBinary;u&&!I&&(g=g.pipe(new n.Utf8EncodeWorker)),!u&&I&&(g=g.pipe(new n.Utf8DecodeWorker))}catch(f){(g=new r("error")).error(f)}return new i(g,h,"")},async:function(p,g){return this.internalStream(p).accumulate(g)},nodeStream:function(p,g){return this.internalStream(p||"nodebuffer").toNodejsStream(g)},_compressWorker:function(p,g){if(this._data instanceof o&&this._data.compression.magic===p.magic)return this._data.getCompressedWorker();var h=this._decompressWorker();return this._dataBinary||(h=h.pipe(new n.Utf8EncodeWorker)),o.createWorkerFrom(h,p,g)},_decompressWorker:function(){return this._data instanceof o?this._data.getContentWorker():this._data instanceof r?this._data:new s(this._data)}};for(var a=["asText","asBinary","asNodeBuffer","asUint8Array","asArrayBuffer"],c=function(){throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.")},l=0;l<a.length;l++)e.prototype[a[l]]=c;A.exports=e},{"./compressedObject":2,"./stream/DataWorker":27,"./stream/GenericWorker":28,"./stream/StreamHelper":29,"./utf8":31}],36:[function(d,A,t){(function(e){"use strict";var i,s,n=e.MutationObserver||e.WebKitMutationObserver;if(n){var o=0,r=new n(p),a=e.document.createTextNode("");r.observe(a,{characterData:!0}),i=function(){a.data=o=++o%2}}else if(e.setImmediate||e.MessageChannel===void 0)i="document"in e&&"onreadystatechange"in e.document.createElement("script")?function(){var g=e.document.createElement("script");g.onreadystatechange=function(){p(),g.onreadystatechange=null,g.parentNode.removeChild(g),g=null},e.document.documentElement.appendChild(g)}:function(){setTimeout(p,0)};else{var c=new e.MessageChannel;c.port1.onmessage=p,i=function(){c.port2.postMessage(0)}}var l=[];function p(){var g,h;s=!0;for(var I=l.length;I;){for(h=l,l=[],g=-1;++g<I;)h[g]();I=l.length}s=!1}A.exports=function(g){l.push(g)!==1||s||i()}}).call(this,typeof global<"u"?global:typeof self<"u"?self:typeof window<"u"?window:{})},{}],37:[function(d,A,t){"use strict";var e=d("immediate");function i(){}var s={},n=["REJECTED"],o=["FULFILLED"],r=["PENDING"];function a(I){if(typeof I!="function")throw new TypeError("resolver must be a function");this.state=r,this.queue=[],this.outcome=void 0,I!==i&&g(this,I)}function c(I,u,f){this.promise=I,typeof u=="function"&&(this.onFulfilled=u,this.callFulfilled=this.otherCallFulfilled),typeof f=="function"&&(this.onRejected=f,this.callRejected=this.otherCallRejected)}function l(I,u,f){e(function(){var C;try{C=u(f)}catch(m){return s.reject(I,m)}C===I?s.reject(I,new TypeError("Cannot resolve promise with itself")):s.resolve(I,C)})}function p(I){var u=I&&I.then;if(I&&(typeof I=="object"||typeof I=="function")&&typeof u=="function")return function(){u.apply(I,arguments)}}function g(I,u){var f=!1;function C(y){f||(f=!0,s.reject(I,y))}function m(y){f||(f=!0,s.resolve(I,y))}var E=h(function(){u(m,C)});E.status==="error"&&C(E.value)}function h(I,u){var f={};try{f.value=I(u),f.status="success"}catch(C){f.status="error",f.value=C}return f}(A.exports=a).prototype.finally=function(I){if(typeof I!="function")return this;var u=this.constructor;return this.then(function(f){return u.resolve(I()).then(function(){return f})},function(f){return u.resolve(I()).then(function(){throw f})})},a.prototype.catch=function(I){return this.then(null,I)},a.prototype.then=function(I,u){if(typeof I!="function"&&this.state===o||typeof u!="function"&&this.state===n)return this;var f=new this.constructor(i);return this.state!==r?l(f,this.state===o?I:u,this.outcome):this.queue.push(new c(f,I,u)),f},c.prototype.callFulfilled=function(I){s.resolve(this.promise,I)},c.prototype.otherCallFulfilled=function(I){l(this.promise,this.onFulfilled,I)},c.prototype.callRejected=function(I){s.reject(this.promise,I)},c.prototype.otherCallRejected=function(I){l(this.promise,this.onRejected,I)},s.resolve=function(I,u){var f=h(p,u);if(f.status==="error")return s.reject(I,f.value);var C=f.value;if(C)g(I,C);else{I.state=o,I.outcome=u;for(var m=-1,E=I.queue.length;++m<E;)I.queue[m].callFulfilled(u)}return I},s.reject=function(I,u){I.state=n,I.outcome=u;for(var f=-1,C=I.queue.length;++f<C;)I.queue[f].callRejected(u);return I},a.resolve=function(I){return I instanceof this?I:s.resolve(new this(i),I)},a.reject=function(I){var u=new this(i);return s.reject(u,I)},a.all=function(I){var u=this;if(Object.prototype.toString.call(I)!=="[object Array]")return this.reject(new TypeError("must be an array"));var f=I.length,C=!1;if(!f)return this.resolve([]);for(var m=new Array(f),E=0,y=-1,w=new this(i);++y<f;)v(I[y],y);return w;function v(D,L){u.resolve(D).then(function(S){m[L]=S,++E!==f||C||(C=!0,s.resolve(w,m))},function(S){C||(C=!0,s.reject(w,S))})}},a.race=function(I){var u=this;if(Object.prototype.toString.call(I)!=="[object Array]")return this.reject(new TypeError("must be an array"));var f=I.length,C=!1;if(!f)return this.resolve([]);for(var m=-1,E=new this(i);++m<f;)y=I[m],u.resolve(y).then(function(w){C||(C=!0,s.resolve(E,w))},function(w){C||(C=!0,s.reject(E,w))});var y;return E}},{immediate:36}],38:[function(d,A,t){"use strict";var e={};(0,d("./lib/utils/common").assign)(e,d("./lib/deflate"),d("./lib/inflate"),d("./lib/zlib/constants")),A.exports=e},{"./lib/deflate":39,"./lib/inflate":40,"./lib/utils/common":41,"./lib/zlib/constants":44}],39:[function(d,A,t){"use strict";var e=d("./zlib/deflate"),i=d("./utils/common"),s=d("./utils/strings"),n=d("./zlib/messages"),o=d("./zlib/zstream"),r=Object.prototype.toString,a=0,c=-1,l=0,p=8;function g(I){if(!(this instanceof g))return new g(I);this.options=i.assign({level:c,method:p,chunkSize:16384,windowBits:15,memLevel:8,strategy:l,to:""},I||{});var u=this.options;u.raw&&0<u.windowBits?u.windowBits=-u.windowBits:u.gzip&&0<u.windowBits&&u.windowBits<16&&(u.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new o,this.strm.avail_out=0;var f=e.deflateInit2(this.strm,u.level,u.method,u.windowBits,u.memLevel,u.strategy);if(f!==a)throw new Error(n[f]);if(u.header&&e.deflateSetHeader(this.strm,u.header),u.dictionary){var C;if(C=typeof u.dictionary=="string"?s.string2buf(u.dictionary):r.call(u.dictionary)==="[object ArrayBuffer]"?new Uint8Array(u.dictionary):u.dictionary,(f=e.deflateSetDictionary(this.strm,C))!==a)throw new Error(n[f]);this._dict_set=!0}}function h(I,u){var f=new g(u);if(f.push(I,!0),f.err)throw f.msg||n[f.err];return f.result}g.prototype.push=function(I,u){var f,C,m=this.strm,E=this.options.chunkSize;if(this.ended)return!1;C=u===~~u?u:u===!0?4:0,typeof I=="string"?m.input=s.string2buf(I):r.call(I)==="[object ArrayBuffer]"?m.input=new Uint8Array(I):m.input=I,m.next_in=0,m.avail_in=m.input.length;do{if(m.avail_out===0&&(m.output=new i.Buf8(E),m.next_out=0,m.avail_out=E),(f=e.deflate(m,C))!==1&&f!==a)return this.onEnd(f),!(this.ended=!0);m.avail_out!==0&&(m.avail_in!==0||C!==4&&C!==2)||(this.options.to==="string"?this.onData(s.buf2binstring(i.shrinkBuf(m.output,m.next_out))):this.onData(i.shrinkBuf(m.output,m.next_out)))}while((0<m.avail_in||m.avail_out===0)&&f!==1);return C===4?(f=e.deflateEnd(this.strm),this.onEnd(f),this.ended=!0,f===a):C!==2||(this.onEnd(a),!(m.avail_out=0))},g.prototype.onData=function(I){this.chunks.push(I)},g.prototype.onEnd=function(I){I===a&&(this.options.to==="string"?this.result=this.chunks.join(""):this.result=i.flattenChunks(this.chunks)),this.chunks=[],this.err=I,this.msg=this.strm.msg},t.Deflate=g,t.deflate=h,t.deflateRaw=function(I,u){return(u=u||{}).raw=!0,h(I,u)},t.gzip=function(I,u){return(u=u||{}).gzip=!0,h(I,u)}},{"./utils/common":41,"./utils/strings":42,"./zlib/deflate":46,"./zlib/messages":51,"./zlib/zstream":53}],40:[function(d,A,t){"use strict";var e=d("./zlib/inflate"),i=d("./utils/common"),s=d("./utils/strings"),n=d("./zlib/constants"),o=d("./zlib/messages"),r=d("./zlib/zstream"),a=d("./zlib/gzheader"),c=Object.prototype.toString;function l(g){if(!(this instanceof l))return new l(g);this.options=i.assign({chunkSize:16384,windowBits:0,to:""},g||{});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)||g&&g.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 r,this.strm.avail_out=0;var I=e.inflateInit2(this.strm,h.windowBits);if(I!==n.Z_OK)throw new Error(o[I]);this.header=new a,e.inflateGetHeader(this.strm,this.header)}function p(g,h){var I=new l(h);if(I.push(g,!0),I.err)throw I.msg||o[I.err];return I.result}l.prototype.push=function(g,h){var I,u,f,C,m,E,y=this.strm,w=this.options.chunkSize,v=this.options.dictionary,D=!1;if(this.ended)return!1;u=h===~~h?h:h===!0?n.Z_FINISH:n.Z_NO_FLUSH,typeof g=="string"?y.input=s.binstring2buf(g):c.call(g)==="[object ArrayBuffer]"?y.input=new Uint8Array(g):y.input=g,y.next_in=0,y.avail_in=y.input.length;do{if(y.avail_out===0&&(y.output=new i.Buf8(w),y.next_out=0,y.avail_out=w),(I=e.inflate(y,n.Z_NO_FLUSH))===n.Z_NEED_DICT&&v&&(E=typeof v=="string"?s.string2buf(v):c.call(v)==="[object ArrayBuffer]"?new Uint8Array(v):v,I=e.inflateSetDictionary(this.strm,E)),I===n.Z_BUF_ERROR&&D===!0&&(I=n.Z_OK,D=!1),I!==n.Z_STREAM_END&&I!==n.Z_OK)return this.onEnd(I),!(this.ended=!0);y.next_out&&(y.avail_out!==0&&I!==n.Z_STREAM_END&&(y.avail_in!==0||u!==n.Z_FINISH&&u!==n.Z_SYNC_FLUSH)||(this.options.to==="string"?(f=s.utf8border(y.output,y.next_out),C=y.next_out-f,m=s.buf2string(y.output,f),y.next_out=C,y.avail_out=w-C,C&&i.arraySet(y.output,y.output,f,C,0),this.onData(m)):this.onData(i.shrinkBuf(y.output,y.next_out)))),y.avail_in===0&&y.avail_out===0&&(D=!0)}while((0<y.avail_in||y.avail_out===0)&&I!==n.Z_STREAM_END);return I===n.Z_STREAM_END&&(u=n.Z_FINISH),u===n.Z_FINISH?(I=e.inflateEnd(this.strm),this.onEnd(I),this.ended=!0,I===n.Z_OK):u!==n.Z_SYNC_FLUSH||(this.onEnd(n.Z_OK),!(y.avail_out=0))},l.prototype.onData=function(g){this.chunks.push(g)},l.prototype.onEnd=function(g){g===n.Z_OK&&(this.options.to==="string"?this.result=this.chunks.join(""):this.result=i.flattenChunks(this.chunks)),this.chunks=[],this.err=g,this.msg=this.strm.msg},t.Inflate=l,t.inflate=p,t.inflateRaw=function(g,h){return(h=h||{}).raw=!0,p(g,h)},t.ungzip=p},{"./utils/common":41,"./utils/strings":42,"./zlib/constants":44,"./zlib/gzheader":47,"./zlib/inflate":49,"./zlib/messages":51,"./zlib/zstream":53}],41:[function(d,A,t){"use strict";var e=typeof Uint8Array<"u"&&typeof Uint16Array<"u"&&typeof Int32Array<"u";t.assign=function(n){for(var o=Array.prototype.slice.call(arguments,1);o.length;){var r=o.shift();if(r){if(typeof r!="object")throw new TypeError(r+"must be non-object");for(var a in r)r.hasOwnProperty(a)&&(n[a]=r[a])}}return n},t.shrinkBuf=function(n,o){return n.length===o?n:n.subarray?n.subarray(0,o):(n.length=o,n)};var i={arraySet:function(n,o,r,a,c){if(o.subarray&&n.subarray)n.set(o.subarray(r,r+a),c);else for(var l=0;l<a;l++)n[c+l]=o[r+l]},flattenChunks:function(n){var o,r,a,c,l,p;for(o=a=0,r=n.length;o<r;o++)a+=n[o].length;for(p=new Uint8Array(a),o=c=0,r=n.length;o<r;o++)l=n[o],p.set(l,c),c+=l.length;return p}},s={arraySet:function(n,o,r,a,c){for(var l=0;l<a;l++)n[c+l]=o[r+l]},flattenChunks:function(n){return[].concat.apply([],n)}};t.setTyped=function(n){n?(t.Buf8=Uint8Array,t.Buf16=Uint16Array,t.Buf32=Int32Array,t.assign(t,i)):(t.Buf8=Array,t.Buf16=Array,t.Buf32=Array,t.assign(t,s))},t.setTyped(e)},{}],42:[function(d,A,t){"use strict";var e=d("./common"),i=!0,s=!0;try{String.fromCharCode.apply(null,[0])}catch{i=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch{s=!1}for(var n=new e.Buf8(256),o=0;o<256;o++)n[o]=252<=o?6:248<=o?5:240<=o?4:224<=o?3:192<=o?2:1;function r(a,c){if(c<65537&&(a.subarray&&s||!a.subarray&&i))return String.fromCharCode.apply(null,e.shrinkBuf(a,c));for(var l="",p=0;p<c;p++)l+=String.fromCharCode(a[p]);return l}n[254]=n[254]=1,t.string2buf=function(a){var c,l,p,g,h,I=a.length,u=0;for(g=0;g<I;g++)(64512&(l=a.charCodeAt(g)))==55296&&g+1<I&&(64512&(p=a.charCodeAt(g+1)))==56320&&(l=65536+(l-55296<<10)+(p-56320),g++),u+=l<128?1:l<2048?2:l<65536?3:4;for(c=new e.Buf8(u),g=h=0;h<u;g++)(64512&(l=a.charCodeAt(g)))==55296&&g+1<I&&(64512&(p=a.charCodeAt(g+1)))==56320&&(l=65536+(l-55296<<10)+(p-56320),g++),l<128?c[h++]=l:(l<2048?c[h++]=192|l>>>6:(l<65536?c[h++]=224|l>>>12:(c[h++]=240|l>>>18,c[h++]=128|l>>>12&63),c[h++]=128|l>>>6&63),c[h++]=128|63&l);return c},t.buf2binstring=function(a){return r(a,a.length)},t.binstring2buf=function(a){for(var c=new e.Buf8(a.length),l=0,p=c.length;l<p;l++)c[l]=a.charCodeAt(l);return c},t.buf2string=function(a,c){var l,p,g,h,I=c||a.length,u=new Array(2*I);for(l=p=0;l<I;)if((g=a[l++])<128)u[p++]=g;else if(4<(h=n[g]))u[p++]=65533,l+=h-1;else{for(g&=h===2?31:h===3?15:7;1<h&&l<I;)g=g<<6|63&a[l++],h--;1<h?u[p++]=65533:g<65536?u[p++]=g:(g-=65536,u[p++]=55296|g>>10&1023,u[p++]=56320|1023&g)}return r(u,p)},t.utf8border=function(a,c){var l;for((c=c||a.length)>a.length&&(c=a.length),l=c-1;0<=l&&(192&a[l])==128;)l--;return l<0||l===0?c:l+n[a[l]]>c?l:c}},{"./common":41}],43:[function(d,A,t){"use strict";A.exports=function(e,i,s,n){for(var o=65535&e|0,r=e>>>16&65535|0,a=0;s!==0;){for(s-=a=2e3<s?2e3:s;r=r+(o=o+i[n++]|0)|0,--a;);o%=65521,r%=65521}return o|r<<16|0}},{}],44:[function(d,A,t){"use strict";A.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(d,A,t){"use strict";var e=function(){for(var i,s=[],n=0;n<256;n++){i=n;for(var o=0;o<8;o++)i=1&i?3988292384^i>>>1:i>>>1;s[n]=i}return s}();A.exports=function(i,s,n,o){var r=e,a=o+n;i^=-1;for(var c=o;c<a;c++)i=i>>>8^r[255&(i^s[c])];return-1^i}},{}],46:[function(d,A,t){"use strict";var e,i=d("../utils/common"),s=d("./trees"),n=d("./adler32"),o=d("./crc32"),r=d("./messages"),a=0,c=4,l=0,p=-2,g=-1,h=4,I=2,u=8,f=9,C=286,m=30,E=19,y=2*C+1,w=15,v=3,D=258,L=D+v+1,S=42,b=113,Q=1,H=2,$=3,M=4;function T(B,O){return B.msg=r[O],O}function J(B){return(B<<1)-(4<B?9:0)}function Z(B){for(var O=B.length;0<=--O;)B[O]=0}function U(B){var O=B.state,P=O.pending;P>B.avail_out&&(P=B.avail_out),P!==0&&(i.arraySet(B.output,O.pending_buf,O.pending_out,P,B.next_out),B.next_out+=P,O.pending_out+=P,B.total_out+=P,B.avail_out-=P,O.pending-=P,O.pending===0&&(O.pending_out=0))}function N(B,O){s._tr_flush_block(B,0<=B.block_start?B.block_start:-1,B.strstart-B.block_start,O),B.block_start=B.strstart,U(B.strm)}function j(B,O){B.pending_buf[B.pending++]=O}function K(B,O){B.pending_buf[B.pending++]=O>>>8&255,B.pending_buf[B.pending++]=255&O}function z(B,O){var P,k,F=B.max_chain_length,x=B.strstart,Y=B.prev_length,V=B.nice_match,R=B.strstart>B.w_size-L?B.strstart-(B.w_size-L):0,W=B.window,tt=B.w_mask,X=B.prev,it=B.strstart+D,ut=W[x+Y-1],lt=W[x+Y];B.prev_length>=B.good_match&&(F>>=2),V>B.lookahead&&(V=B.lookahead);do if(W[(P=O)+Y]===lt&&W[P+Y-1]===ut&&W[P]===W[x]&&W[++P]===W[x+1]){x+=2,P++;do;while(W[++x]===W[++P]&&W[++x]===W[++P]&&W[++x]===W[++P]&&W[++x]===W[++P]&&W[++x]===W[++P]&&W[++x]===W[++P]&&W[++x]===W[++P]&&W[++x]===W[++P]&&x<it);if(k=D-(it-x),x=it-D,Y<k){if(B.match_start=O,V<=(Y=k))break;ut=W[x+Y-1],lt=W[x+Y]}}while((O=X[O&tt])>R&&--F!=0);return Y<=B.lookahead?Y:B.lookahead}function ot(B){var O,P,k,F,x,Y,V,R,W,tt,X=B.w_size;do{if(F=B.window_size-B.lookahead-B.strstart,B.strstart>=X+(X-L)){for(i.arraySet(B.window,B.window,X,X,0),B.match_start-=X,B.strstart-=X,B.block_start-=X,O=P=B.hash_size;k=B.head[--O],B.head[O]=X<=k?k-X:0,--P;);for(O=P=X;k=B.prev[--O],B.prev[O]=X<=k?k-X:0,--P;);F+=X}if(B.strm.avail_in===0)break;if(Y=B.strm,V=B.window,R=B.strstart+B.lookahead,W=F,tt=void 0,tt=Y.avail_in,W<tt&&(tt=W),P=tt===0?0:(Y.avail_in-=tt,i.arraySet(V,Y.input,Y.next_in,tt,R),Y.state.wrap===1?Y.adler=n(Y.adler,V,tt,R):Y.state.wrap===2&&(Y.adler=o(Y.adler,V,tt,R)),Y.next_in+=tt,Y.total_in+=tt,tt),B.lookahead+=P,B.lookahead+B.insert>=v)for(x=B.strstart-B.insert,B.ins_h=B.window[x],B.ins_h=(B.ins_h<<B.hash_shift^B.window[x+1])&B.hash_mask;B.insert&&(B.ins_h=(B.ins_h<<B.hash_shift^B.window[x+v-1])&B.hash_mask,B.prev[x&B.w_mask]=B.head[B.ins_h],B.head[B.ins_h]=x,x++,B.insert--,!(B.lookahead+B.insert<v)););}while(B.lookahead<L&&B.strm.avail_in!==0)}function dt(B,O){for(var P,k;;){if(B.lookahead<L){if(ot(B),B.lookahead<L&&O===a)return Q;if(B.lookahead===0)break}if(P=0,B.lookahead>=v&&(B.ins_h=(B.ins_h<<B.hash_shift^B.window[B.strstart+v-1])&B.hash_mask,P=B.prev[B.strstart&B.w_mask]=B.head[B.ins_h],B.head[B.ins_h]=B.strstart),P!==0&&B.strstart-P<=B.w_size-L&&(B.match_length=z(B,P)),B.match_length>=v)if(k=s._tr_tally(B,B.strstart-B.match_start,B.match_length-v),B.lookahead-=B.match_length,B.match_length<=B.max_lazy_match&&B.lookahead>=v){for(B.match_length--;B.strstart++,B.ins_h=(B.ins_h<<B.hash_shift^B.window[B.strstart+v-1])&B.hash_mask,P=B.prev[B.strstart&B.w_mask]=B.head[B.ins_h],B.head[B.ins_h]=B.strstart,--B.match_length!=0;);B.strstart++}else B.strstart+=B.match_length,B.match_length=0,B.ins_h=B.window[B.strstart],B.ins_h=(B.ins_h<<B.hash_shift^B.window[B.strstart+1])&B.hash_mask;else k=s._tr_tally(B,0,B.window[B.strstart]),B.lookahead--,B.strstart++;if(k&&(N(B,!1),B.strm.avail_out===0))return Q}return B.insert=B.strstart<v-1?B.strstart:v-1,O===c?(N(B,!0),B.strm.avail_out===0?$:M):B.last_lit&&(N(B,!1),B.strm.avail_out===0)?Q:H}function st(B,O){for(var P,k,F;;){if(B.lookahead<L){if(ot(B),B.lookahead<L&&O===a)return Q;if(B.lookahead===0)break}if(P=0,B.lookahead>=v&&(B.ins_h=(B.ins_h<<B.hash_shift^B.window[B.strstart+v-1])&B.hash_mask,P=B.prev[B.strstart&B.w_mask]=B.head[B.ins_h],B.head[B.ins_h]=B.strstart),B.prev_length=B.match_length,B.prev_match=B.match_start,B.match_length=v-1,P!==0&&B.prev_length<B.max_lazy_match&&B.strstart-P<=B.w_size-L&&(B.match_length=z(B,P),B.match_length<=5&&(B.strategy===1||B.match_length===v&&4096<B.strstart-B.match_start)&&(B.match_length=v-1)),B.prev_length>=v&&B.match_length<=B.prev_length){for(F=B.strstart+B.lookahead-v,k=s._tr_tally(B,B.strstart-1-B.prev_match,B.prev_length-v),B.lookahead-=B.prev_length-1,B.prev_length-=2;++B.strstart<=F&&(B.ins_h=(B.ins_h<<B.hash_shift^B.window[B.strstart+v-1])&B.hash_mask,P=B.prev[B.strstart&B.w_mask]=B.head[B.ins_h],B.head[B.ins_h]=B.strstart),--B.prev_length!=0;);if(B.match_available=0,B.match_length=v-1,B.strstart++,k&&(N(B,!1),B.strm.avail_out===0))return Q}else if(B.match_available){if((k=s._tr_tally(B,0,B.window[B.strstart-1]))&&N(B,!1),B.strstart++,B.lookahead--,B.strm.avail_out===0)return Q}else B.match_available=1,B.strstart++,B.lookahead--}return B.match_available&&(k=s._tr_tally(B,0,B.window[B.strstart-1]),B.match_available=0),B.insert=B.strstart<v-1?B.strstart:v-1,O===c?(N(B,!0),B.strm.avail_out===0?$:M):B.last_lit&&(N(B,!1),B.strm.avail_out===0)?Q:H}function at(B,O,P,k,F){this.good_length=B,this.max_lazy=O,this.nice_length=P,this.max_chain=k,this.func=F}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=u,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 i.Buf16(2*y),this.dyn_dtree=new i.Buf16(2*(2*m+1)),this.bl_tree=new i.Buf16(2*(2*E+1)),Z(this.dyn_ltree),Z(this.dyn_dtree),Z(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new i.Buf16(w+1),this.heap=new i.Buf16(2*C+1),Z(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new i.Buf16(2*C+1),Z(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 nt(B){var O;return B&&B.state?(B.total_in=B.total_out=0,B.data_type=I,(O=B.state).pending=0,O.pending_out=0,O.wrap<0&&(O.wrap=-O.wrap),O.status=O.wrap?S:b,B.adler=O.wrap===2?0:1,O.last_flush=a,s._tr_init(O),l):T(B,p)}function mt(B){var O=nt(B);return O===l&&function(P){P.window_size=2*P.w_size,Z(P.head),P.max_lazy_match=e[P.level].max_lazy,P.good_match=e[P.level].good_length,P.nice_match=e[P.level].nice_length,P.max_chain_length=e[P.level].max_chain,P.strstart=0,P.block_start=0,P.lookahead=0,P.insert=0,P.match_length=P.prev_length=v-1,P.match_available=0,P.ins_h=0}(B.state),O}function Ct(B,O,P,k,F,x){if(!B)return p;var Y=1;if(O===g&&(O=6),k<0?(Y=0,k=-k):15<k&&(Y=2,k-=16),F<1||f<F||P!==u||k<8||15<k||O<0||9<O||x<0||h<x)return T(B,p);k===8&&(k=9);var V=new At;return(B.state=V).strm=B,V.wrap=Y,V.gzhead=null,V.w_bits=k,V.w_size=1<<V.w_bits,V.w_mask=V.w_size-1,V.hash_bits=F+7,V.hash_size=1<<V.hash_bits,V.hash_mask=V.hash_size-1,V.hash_shift=~~((V.hash_bits+v-1)/v),V.window=new i.Buf8(2*V.w_size),V.head=new i.Buf16(V.hash_size),V.prev=new i.Buf16(V.w_size),V.lit_bufsize=1<<F+6,V.pending_buf_size=4*V.lit_bufsize,V.pending_buf=new i.Buf8(V.pending_buf_size),V.d_buf=1*V.lit_bufsize,V.l_buf=3*V.lit_bufsize,V.level=O,V.strategy=x,V.method=P,mt(B)}e=[new at(0,0,0,0,function(B,O){var P=65535;for(P>B.pending_buf_size-5&&(P=B.pending_buf_size-5);;){if(B.lookahead<=1){if(ot(B),B.lookahead===0&&O===a)return Q;if(B.lookahead===0)break}B.strstart+=B.lookahead,B.lookahead=0;var k=B.block_start+P;if((B.strstart===0||B.strstart>=k)&&(B.lookahead=B.strstart-k,B.strstart=k,N(B,!1),B.strm.avail_out===0)||B.strstart-B.block_start>=B.w_size-L&&(N(B,!1),B.strm.avail_out===0))return Q}return B.insert=0,O===c?(N(B,!0),B.strm.avail_out===0?$:M):(B.strstart>B.block_start&&(N(B,!1),B.strm.avail_out),Q)}),new at(4,4,8,4,dt),new at(4,5,16,8,dt),new at(4,6,32,32,dt),new at(4,4,16,16,st),new at(8,16,32,32,st),new at(8,16,128,128,st),new at(8,32,128,256,st),new at(32,128,258,1024,st),new at(32,258,258,4096,st)],t.deflateInit=function(B,O){return Ct(B,O,u,15,8,0)},t.deflateInit2=Ct,t.deflateReset=mt,t.deflateResetKeep=nt,t.deflateSetHeader=function(B,O){return B&&B.state?B.state.wrap!==2?p:(B.state.gzhead=O,l):p},t.deflate=function(B,O){var P,k,F,x;if(!B||!B.state||5<O||O<0)return B?T(B,p):p;if(k=B.state,!B.output||!B.input&&B.avail_in!==0||k.status===666&&O!==c)return T(B,B.avail_out===0?-5:p);if(k.strm=B,P=k.last_flush,k.last_flush=O,k.status===S)if(k.wrap===2)B.adler=0,j(k,31),j(k,139),j(k,8),k.gzhead?(j(k,(k.gzhead.text?1:0)+(k.gzhead.hcrc?2:0)+(k.gzhead.extra?4:0)+(k.gzhead.name?8:0)+(k.gzhead.comment?16:0)),j(k,255&k.gzhead.time),j(k,k.gzhead.time>>8&255),j(k,k.gzhead.time>>16&255),j(k,k.gzhead.time>>24&255),j(k,k.level===9?2:2<=k.strategy||k.level<2?4:0),j(k,255&k.gzhead.os),k.gzhead.extra&&k.gzhead.extra.length&&(j(k,255&k.gzhead.extra.length),j(k,k.gzhead.extra.length>>8&255)),k.gzhead.hcrc&&(B.adler=o(B.adler,k.pending_buf,k.pending,0)),k.gzindex=0,k.status=69):(j(k,0),j(k,0),j(k,0),j(k,0),j(k,0),j(k,k.level===9?2:2<=k.strategy||k.level<2?4:0),j(k,3),k.status=b);else{var Y=u+(k.w_bits-8<<4)<<8;Y|=(2<=k.strategy||k.level<2?0:k.level<6?1:k.level===6?2:3)<<6,k.strstart!==0&&(Y|=32),Y+=31-Y%31,k.status=b,K(k,Y),k.strstart!==0&&(K(k,B.adler>>>16),K(k,65535&B.adler)),B.adler=1}if(k.status===69)if(k.gzhead.extra){for(F=k.pending;k.gzindex<(65535&k.gzhead.extra.length)&&(k.pending!==k.pending_buf_size||(k.gzhead.hcrc&&k.pending>F&&(B.adler=o(B.adler,k.pending_buf,k.pending-F,F)),U(B),F=k.pending,k.pending!==k.pending_buf_size));)j(k,255&k.gzhead.extra[k.gzindex]),k.gzindex++;k.gzhead.hcrc&&k.pending>F&&(B.adler=o(B.adler,k.pending_buf,k.pending-F,F)),k.gzindex===k.gzhead.extra.length&&(k.gzindex=0,k.status=73)}else k.status=73;if(k.status===73)if(k.gzhead.name){F=k.pending;do{if(k.pending===k.pending_buf_size&&(k.gzhead.hcrc&&k.pending>F&&(B.adler=o(B.adler,k.pending_buf,k.pending-F,F)),U(B),F=k.pending,k.pending===k.pending_buf_size)){x=1;break}x=k.gzindex<k.gzhead.name.length?255&k.gzhead.name.charCodeAt(k.gzindex++):0,j(k,x)}while(x!==0);k.gzhead.hcrc&&k.pending>F&&(B.adler=o(B.adler,k.pending_buf,k.pending-F,F)),x===0&&(k.gzindex=0,k.status=91)}else k.status=91;if(k.status===91)if(k.gzhead.comment){F=k.pending;do{if(k.pending===k.pending_buf_size&&(k.gzhead.hcrc&&k.pending>F&&(B.adler=o(B.adler,k.pending_buf,k.pending-F,F)),U(B),F=k.pending,k.pending===k.pending_buf_size)){x=1;break}x=k.gzindex<k.gzhead.comment.length?255&k.gzhead.comment.charCodeAt(k.gzindex++):0,j(k,x)}while(x!==0);k.gzhead.hcrc&&k.pending>F&&(B.adler=o(B.adler,k.pending_buf,k.pending-F,F)),x===0&&(k.status=103)}else k.status=103;if(k.status===103&&(k.gzhead.hcrc?(k.pending+2>k.pending_buf_size&&U(B),k.pending+2<=k.pending_buf_size&&(j(k,255&B.adler),j(k,B.adler>>8&255),B.adler=0,k.status=b)):k.status=b),k.pending!==0){if(U(B),B.avail_out===0)return k.last_flush=-1,l}else if(B.avail_in===0&&J(O)<=J(P)&&O!==c)return T(B,-5);if(k.status===666&&B.avail_in!==0)return T(B,-5);if(B.avail_in!==0||k.lookahead!==0||O!==a&&k.status!==666){var V=k.strategy===2?function(R,W){for(var tt;;){if(R.lookahead===0&&(ot(R),R.lookahead===0)){if(W===a)return Q;break}if(R.match_length=0,tt=s._tr_tally(R,0,R.window[R.strstart]),R.lookahead--,R.strstart++,tt&&(N(R,!1),R.strm.avail_out===0))return Q}return R.insert=0,W===c?(N(R,!0),R.strm.avail_out===0?$:M):R.last_lit&&(N(R,!1),R.strm.avail_out===0)?Q:H}(k,O):k.strategy===3?function(R,W){for(var tt,X,it,ut,lt=R.window;;){if(R.lookahead<=D){if(ot(R),R.lookahead<=D&&W===a)return Q;if(R.lookahead===0)break}if(R.match_length=0,R.lookahead>=v&&0<R.strstart&&(X=lt[it=R.strstart-1])===lt[++it]&&X===lt[++it]&&X===lt[++it]){ut=R.strstart+D;do;while(X===lt[++it]&&X===lt[++it]&&X===lt[++it]&&X===lt[++it]&&X===lt[++it]&&X===lt[++it]&&X===lt[++it]&&X===lt[++it]&&it<ut);R.match_length=D-(ut-it),R.match_length>R.lookahead&&(R.match_length=R.lookahead)}if(R.match_length>=v?(tt=s._tr_tally(R,1,R.match_length-v),R.lookahead-=R.match_length,R.strstart+=R.match_length,R.match_length=0):(tt=s._tr_tally(R,0,R.window[R.strstart]),R.lookahead--,R.strstart++),tt&&(N(R,!1),R.strm.avail_out===0))return Q}return R.insert=0,W===c?(N(R,!0),R.strm.avail_out===0?$:M):R.last_lit&&(N(R,!1),R.strm.avail_out===0)?Q:H}(k,O):e[k.level].func(k,O);if(V!==$&&V!==M||(k.status=666),V===Q||V===$)return B.avail_out===0&&(k.last_flush=-1),l;if(V===H&&(O===1?s._tr_align(k):O!==5&&(s._tr_stored_block(k,0,0,!1),O===3&&(Z(k.head),k.lookahead===0&&(k.strstart=0,k.block_start=0,k.insert=0))),U(B),B.avail_out===0))return k.last_flush=-1,l}return O!==c?l:k.wrap<=0?1:(k.wrap===2?(j(k,255&B.adler),j(k,B.adler>>8&255),j(k,B.adler>>16&255),j(k,B.adler>>24&255),j(k,255&B.total_in),j(k,B.total_in>>8&255),j(k,B.total_in>>16&255),j(k,B.total_in>>24&255)):(K(k,B.adler>>>16),K(k,65535&B.adler)),U(B),0<k.wrap&&(k.wrap=-k.wrap),k.pending!==0?l:1)},t.deflateEnd=function(B){var O;return B&&B.state?(O=B.state.status)!==S&&O!==69&&O!==73&&O!==91&&O!==103&&O!==b&&O!==666?T(B,p):(B.state=null,O===b?T(B,-3):l):p},t.deflateSetDictionary=function(B,O){var P,k,F,x,Y,V,R,W,tt=O.length;if(!B||!B.state||(x=(P=B.state).wrap)===2||x===1&&P.status!==S||P.lookahead)return p;for(x===1&&(B.adler=n(B.adler,O,tt,0)),P.wrap=0,tt>=P.w_size&&(x===0&&(Z(P.head),P.strstart=0,P.block_start=0,P.insert=0),W=new i.Buf8(P.w_size),i.arraySet(W,O,tt-P.w_size,P.w_size,0),O=W,tt=P.w_size),Y=B.avail_in,V=B.next_in,R=B.input,B.avail_in=tt,B.next_in=0,B.input=O,ot(P);P.lookahead>=v;){for(k=P.strstart,F=P.lookahead-(v-1);P.ins_h=(P.ins_h<<P.hash_shift^P.window[k+v-1])&P.hash_mask,P.prev[k&P.w_mask]=P.head[P.ins_h],P.head[P.ins_h]=k,k++,--F;);P.strstart=k,P.lookahead=v-1,ot(P)}return P.strstart+=P.lookahead,P.block_start=P.strstart,P.insert=P.lookahead,P.lookahead=0,P.match_length=P.prev_length=v-1,P.match_available=0,B.next_in=V,B.input=R,B.avail_in=Y,P.wrap=x,l},t.deflateInfo="pako deflate (from Nodeca project)"},{"../utils/common":41,"./adler32":43,"./crc32":45,"./messages":51,"./trees":52}],47:[function(d,A,t){"use strict";A.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(d,A,t){"use strict";A.exports=function(e,i){var s,n,o,r,a,c,l,p,g,h,I,u,f,C,m,E,y,w,v,D,L,S,b,Q,H;s=e.state,n=e.next_in,Q=e.input,o=n+(e.avail_in-5),r=e.next_out,H=e.output,a=r-(i-e.avail_out),c=r+(e.avail_out-257),l=s.dmax,p=s.wsize,g=s.whave,h=s.wnext,I=s.window,u=s.hold,f=s.bits,C=s.lencode,m=s.distcode,E=(1<<s.lenbits)-1,y=(1<<s.distbits)-1;t:do{f<15&&(u+=Q[n++]<<f,f+=8,u+=Q[n++]<<f,f+=8),w=C[u&E];e:for(;;){if(u>>>=v=w>>>24,f-=v,(v=w>>>16&255)===0)H[r++]=65535&w;else{if(!(16&v)){if(!(64&v)){w=C[(65535&w)+(u&(1<<v)-1)];continue e}if(32&v){s.mode=12;break t}e.msg="invalid literal/length code",s.mode=30;break t}D=65535&w,(v&=15)&&(f<v&&(u+=Q[n++]<<f,f+=8),D+=u&(1<<v)-1,u>>>=v,f-=v),f<15&&(u+=Q[n++]<<f,f+=8,u+=Q[n++]<<f,f+=8),w=m[u&y];i:for(;;){if(u>>>=v=w>>>24,f-=v,!(16&(v=w>>>16&255))){if(!(64&v)){w=m[(65535&w)+(u&(1<<v)-1)];continue i}e.msg="invalid distance code",s.mode=30;break t}if(L=65535&w,f<(v&=15)&&(u+=Q[n++]<<f,(f+=8)<v&&(u+=Q[n++]<<f,f+=8)),l<(L+=u&(1<<v)-1)){e.msg="invalid distance too far back",s.mode=30;break t}if(u>>>=v,f-=v,(v=r-a)<L){if(g<(v=L-v)&&s.sane){e.msg="invalid distance too far back",s.mode=30;break t}if(b=I,(S=0)===h){if(S+=p-v,v<D){for(D-=v;H[r++]=I[S++],--v;);S=r-L,b=H}}else if(h<v){if(S+=p+h-v,(v-=h)<D){for(D-=v;H[r++]=I[S++],--v;);if(S=0,h<D){for(D-=v=h;H[r++]=I[S++],--v;);S=r-L,b=H}}}else if(S+=h-v,v<D){for(D-=v;H[r++]=I[S++],--v;);S=r-L,b=H}for(;2<D;)H[r++]=b[S++],H[r++]=b[S++],H[r++]=b[S++],D-=3;D&&(H[r++]=b[S++],1<D&&(H[r++]=b[S++]))}else{for(S=r-L;H[r++]=H[S++],H[r++]=H[S++],H[r++]=H[S++],2<(D-=3););D&&(H[r++]=H[S++],1<D&&(H[r++]=H[S++]))}break}}break}}while(n<o&&r<c);n-=D=f>>3,u&=(1<<(f-=D<<3))-1,e.next_in=n,e.next_out=r,e.avail_in=n<o?o-n+5:5-(n-o),e.avail_out=r<c?c-r+257:257-(r-c),s.hold=u,s.bits=f}},{}],49:[function(d,A,t){"use strict";var e=d("../utils/common"),i=d("./adler32"),s=d("./crc32"),n=d("./inffast"),o=d("./inftrees"),r=1,a=2,c=0,l=-2,p=1,g=852,h=592;function I(S){return(S>>>24&255)+(S>>>8&65280)+((65280&S)<<8)+((255&S)<<24)}function u(){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 f(S){var b;return S&&S.state?(b=S.state,S.total_in=S.total_out=b.total=0,S.msg="",b.wrap&&(S.adler=1&b.wrap),b.mode=p,b.last=0,b.havedict=0,b.dmax=32768,b.head=null,b.hold=0,b.bits=0,b.lencode=b.lendyn=new e.Buf32(g),b.distcode=b.distdyn=new e.Buf32(h),b.sane=1,b.back=-1,c):l}function C(S){var b;return S&&S.state?((b=S.state).wsize=0,b.whave=0,b.wnext=0,f(S)):l}function m(S,b){var Q,H;return S&&S.state?(H=S.state,b<0?(Q=0,b=-b):(Q=1+(b>>4),b<48&&(b&=15)),b&&(b<8||15<b)?l:(H.window!==null&&H.wbits!==b&&(H.window=null),H.wrap=Q,H.wbits=b,C(S))):l}function E(S,b){var Q,H;return S?(H=new u,(S.state=H).window=null,(Q=m(S,b))!==c&&(S.state=null),Q):l}var y,w,v=!0;function D(S){if(v){var b;for(y=new e.Buf32(512),w=new e.Buf32(32),b=0;b<144;)S.lens[b++]=8;for(;b<256;)S.lens[b++]=9;for(;b<280;)S.lens[b++]=7;for(;b<288;)S.lens[b++]=8;for(o(r,S.lens,0,288,y,0,S.work,{bits:9}),b=0;b<32;)S.lens[b++]=5;o(a,S.lens,0,32,w,0,S.work,{bits:5}),v=!1}S.lencode=y,S.lenbits=9,S.distcode=w,S.distbits=5}function L(S,b,Q,H){var $,M=S.state;return M.window===null&&(M.wsize=1<<M.wbits,M.wnext=0,M.whave=0,M.window=new e.Buf8(M.wsize)),H>=M.wsize?(e.arraySet(M.window,b,Q-M.wsize,M.wsize,0),M.wnext=0,M.whave=M.wsize):(H<($=M.wsize-M.wnext)&&($=H),e.arraySet(M.window,b,Q-H,$,M.wnext),(H-=$)?(e.arraySet(M.window,b,Q-H,H,0),M.wnext=H,M.whave=M.wsize):(M.wnext+=$,M.wnext===M.wsize&&(M.wnext=0),M.whave<M.wsize&&(M.whave+=$))),0}t.inflateReset=C,t.inflateReset2=m,t.inflateResetKeep=f,t.inflateInit=function(S){return E(S,15)},t.inflateInit2=E,t.inflate=function(S,b){var Q,H,$,M,T,J,Z,U,N,j,K,z,ot,dt,st,at,At,nt,mt,Ct,B,O,P,k,F=0,x=new e.Buf8(4),Y=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];if(!S||!S.state||!S.output||!S.input&&S.avail_in!==0)return l;(Q=S.state).mode===12&&(Q.mode=13),T=S.next_out,$=S.output,Z=S.avail_out,M=S.next_in,H=S.input,J=S.avail_in,U=Q.hold,N=Q.bits,j=J,K=Z,O=c;t:for(;;)switch(Q.mode){case p:if(Q.wrap===0){Q.mode=13;break}for(;N<16;){if(J===0)break t;J--,U+=H[M++]<<N,N+=8}if(2&Q.wrap&&U===35615){x[Q.check=0]=255&U,x[1]=U>>>8&255,Q.check=s(Q.check,x,2,0),N=U=0,Q.mode=2;break}if(Q.flags=0,Q.head&&(Q.head.done=!1),!(1&Q.wrap)||(((255&U)<<8)+(U>>8))%31){S.msg="incorrect header check",Q.mode=30;break}if((15&U)!=8){S.msg="unknown compression method",Q.mode=30;break}if(N-=4,B=8+(15&(U>>>=4)),Q.wbits===0)Q.wbits=B;else if(B>Q.wbits){S.msg="invalid window size",Q.mode=30;break}Q.dmax=1<<B,S.adler=Q.check=1,Q.mode=512&U?10:12,N=U=0;break;case 2:for(;N<16;){if(J===0)break t;J--,U+=H[M++]<<N,N+=8}if(Q.flags=U,(255&Q.flags)!=8){S.msg="unknown compression method",Q.mode=30;break}if(57344&Q.flags){S.msg="unknown header flags set",Q.mode=30;break}Q.head&&(Q.head.text=U>>8&1),512&Q.flags&&(x[0]=255&U,x[1]=U>>>8&255,Q.check=s(Q.check,x,2,0)),N=U=0,Q.mode=3;case 3:for(;N<32;){if(J===0)break t;J--,U+=H[M++]<<N,N+=8}Q.head&&(Q.head.time=U),512&Q.flags&&(x[0]=255&U,x[1]=U>>>8&255,x[2]=U>>>16&255,x[3]=U>>>24&255,Q.check=s(Q.check,x,4,0)),N=U=0,Q.mode=4;case 4:for(;N<16;){if(J===0)break t;J--,U+=H[M++]<<N,N+=8}Q.head&&(Q.head.xflags=255&U,Q.head.os=U>>8),512&Q.flags&&(x[0]=255&U,x[1]=U>>>8&255,Q.check=s(Q.check,x,2,0)),N=U=0,Q.mode=5;case 5:if(1024&Q.flags){for(;N<16;){if(J===0)break t;J--,U+=H[M++]<<N,N+=8}Q.length=U,Q.head&&(Q.head.extra_len=U),512&Q.flags&&(x[0]=255&U,x[1]=U>>>8&255,Q.check=s(Q.check,x,2,0)),N=U=0}else Q.head&&(Q.head.extra=null);Q.mode=6;case 6:if(1024&Q.flags&&(J<(z=Q.length)&&(z=J),z&&(Q.head&&(B=Q.head.extra_len-Q.length,Q.head.extra||(Q.head.extra=new Array(Q.head.extra_len)),e.arraySet(Q.head.extra,H,M,z,B)),512&Q.flags&&(Q.check=s(Q.check,H,z,M)),J-=z,M+=z,Q.length-=z),Q.length))break t;Q.length=0,Q.mode=7;case 7:if(2048&Q.flags){if(J===0)break t;for(z=0;B=H[M+z++],Q.head&&B&&Q.length<65536&&(Q.head.name+=String.fromCharCode(B)),B&&z<J;);if(512&Q.flags&&(Q.check=s(Q.check,H,z,M)),J-=z,M+=z,B)break t}else Q.head&&(Q.head.name=null);Q.length=0,Q.mode=8;case 8:if(4096&Q.flags){if(J===0)break t;for(z=0;B=H[M+z++],Q.head&&B&&Q.length<65536&&(Q.head.comment+=String.fromCharCode(B)),B&&z<J;);if(512&Q.flags&&(Q.check=s(Q.check,H,z,M)),J-=z,M+=z,B)break t}else Q.head&&(Q.head.comment=null);Q.mode=9;case 9:if(512&Q.flags){for(;N<16;){if(J===0)break t;J--,U+=H[M++]<<N,N+=8}if(U!==(65535&Q.check)){S.msg="header crc mismatch",Q.mode=30;break}N=U=0}Q.head&&(Q.head.hcrc=Q.flags>>9&1,Q.head.done=!0),S.adler=Q.check=0,Q.mode=12;break;case 10:for(;N<32;){if(J===0)break t;J--,U+=H[M++]<<N,N+=8}S.adler=Q.check=I(U),N=U=0,Q.mode=11;case 11:if(Q.havedict===0)return S.next_out=T,S.avail_out=Z,S.next_in=M,S.avail_in=J,Q.hold=U,Q.bits=N,2;S.adler=Q.check=1,Q.mode=12;case 12:if(b===5||b===6)break t;case 13:if(Q.last){U>>>=7&N,N-=7&N,Q.mode=27;break}for(;N<3;){if(J===0)break t;J--,U+=H[M++]<<N,N+=8}switch(Q.last=1&U,N-=1,3&(U>>>=1)){case 0:Q.mode=14;break;case 1:if(D(Q),Q.mode=20,b!==6)break;U>>>=2,N-=2;break t;case 2:Q.mode=17;break;case 3:S.msg="invalid block type",Q.mode=30}U>>>=2,N-=2;break;case 14:for(U>>>=7&N,N-=7&N;N<32;){if(J===0)break t;J--,U+=H[M++]<<N,N+=8}if((65535&U)!=(U>>>16^65535)){S.msg="invalid stored block lengths",Q.mode=30;break}if(Q.length=65535&U,N=U=0,Q.mode=15,b===6)break t;case 15:Q.mode=16;case 16:if(z=Q.length){if(J<z&&(z=J),Z<z&&(z=Z),z===0)break t;e.arraySet($,H,M,z,T),J-=z,M+=z,Z-=z,T+=z,Q.length-=z;break}Q.mode=12;break;case 17:for(;N<14;){if(J===0)break t;J--,U+=H[M++]<<N,N+=8}if(Q.nlen=257+(31&U),U>>>=5,N-=5,Q.ndist=1+(31&U),U>>>=5,N-=5,Q.ncode=4+(15&U),U>>>=4,N-=4,286<Q.nlen||30<Q.ndist){S.msg="too many length or distance symbols",Q.mode=30;break}Q.have=0,Q.mode=18;case 18:for(;Q.have<Q.ncode;){for(;N<3;){if(J===0)break t;J--,U+=H[M++]<<N,N+=8}Q.lens[Y[Q.have++]]=7&U,U>>>=3,N-=3}for(;Q.have<19;)Q.lens[Y[Q.have++]]=0;if(Q.lencode=Q.lendyn,Q.lenbits=7,P={bits:Q.lenbits},O=o(0,Q.lens,0,19,Q.lencode,0,Q.work,P),Q.lenbits=P.bits,O){S.msg="invalid code lengths set",Q.mode=30;break}Q.have=0,Q.mode=19;case 19:for(;Q.have<Q.nlen+Q.ndist;){for(;at=(F=Q.lencode[U&(1<<Q.lenbits)-1])>>>16&255,At=65535&F,!((st=F>>>24)<=N);){if(J===0)break t;J--,U+=H[M++]<<N,N+=8}if(At<16)U>>>=st,N-=st,Q.lens[Q.have++]=At;else{if(At===16){for(k=st+2;N<k;){if(J===0)break t;J--,U+=H[M++]<<N,N+=8}if(U>>>=st,N-=st,Q.have===0){S.msg="invalid bit length repeat",Q.mode=30;break}B=Q.lens[Q.have-1],z=3+(3&U),U>>>=2,N-=2}else if(At===17){for(k=st+3;N<k;){if(J===0)break t;J--,U+=H[M++]<<N,N+=8}N-=st,B=0,z=3+(7&(U>>>=st)),U>>>=3,N-=3}else{for(k=st+7;N<k;){if(J===0)break t;J--,U+=H[M++]<<N,N+=8}N-=st,B=0,z=11+(127&(U>>>=st)),U>>>=7,N-=7}if(Q.have+z>Q.nlen+Q.ndist){S.msg="invalid bit length repeat",Q.mode=30;break}for(;z--;)Q.lens[Q.have++]=B}}if(Q.mode===30)break;if(Q.lens[256]===0){S.msg="invalid code -- missing end-of-block",Q.mode=30;break}if(Q.lenbits=9,P={bits:Q.lenbits},O=o(r,Q.lens,0,Q.nlen,Q.lencode,0,Q.work,P),Q.lenbits=P.bits,O){S.msg="invalid literal/lengths set",Q.mode=30;break}if(Q.distbits=6,Q.distcode=Q.distdyn,P={bits:Q.distbits},O=o(a,Q.lens,Q.nlen,Q.ndist,Q.distcode,0,Q.work,P),Q.distbits=P.bits,O){S.msg="invalid distances set",Q.mode=30;break}if(Q.mode=20,b===6)break t;case 20:Q.mode=21;case 21:if(6<=J&&258<=Z){S.next_out=T,S.avail_out=Z,S.next_in=M,S.avail_in=J,Q.hold=U,Q.bits=N,n(S,K),T=S.next_out,$=S.output,Z=S.avail_out,M=S.next_in,H=S.input,J=S.avail_in,U=Q.hold,N=Q.bits,Q.mode===12&&(Q.back=-1);break}for(Q.back=0;at=(F=Q.lencode[U&(1<<Q.lenbits)-1])>>>16&255,At=65535&F,!((st=F>>>24)<=N);){if(J===0)break t;J--,U+=H[M++]<<N,N+=8}if(at&&!(240&at)){for(nt=st,mt=at,Ct=At;at=(F=Q.lencode[Ct+((U&(1<<nt+mt)-1)>>nt)])>>>16&255,At=65535&F,!(nt+(st=F>>>24)<=N);){if(J===0)break t;J--,U+=H[M++]<<N,N+=8}U>>>=nt,N-=nt,Q.back+=nt}if(U>>>=st,N-=st,Q.back+=st,Q.length=At,at===0){Q.mode=26;break}if(32&at){Q.back=-1,Q.mode=12;break}if(64&at){S.msg="invalid literal/length code",Q.mode=30;break}Q.extra=15&at,Q.mode=22;case 22:if(Q.extra){for(k=Q.extra;N<k;){if(J===0)break t;J--,U+=H[M++]<<N,N+=8}Q.length+=U&(1<<Q.extra)-1,U>>>=Q.extra,N-=Q.extra,Q.back+=Q.extra}Q.was=Q.length,Q.mode=23;case 23:for(;at=(F=Q.distcode[U&(1<<Q.distbits)-1])>>>16&255,At=65535&F,!((st=F>>>24)<=N);){if(J===0)break t;J--,U+=H[M++]<<N,N+=8}if(!(240&at)){for(nt=st,mt=at,Ct=At;at=(F=Q.distcode[Ct+((U&(1<<nt+mt)-1)>>nt)])>>>16&255,At=65535&F,!(nt+(st=F>>>24)<=N);){if(J===0)break t;J--,U+=H[M++]<<N,N+=8}U>>>=nt,N-=nt,Q.back+=nt}if(U>>>=st,N-=st,Q.back+=st,64&at){S.msg="invalid distance code",Q.mode=30;break}Q.offset=At,Q.extra=15&at,Q.mode=24;case 24:if(Q.extra){for(k=Q.extra;N<k;){if(J===0)break t;J--,U+=H[M++]<<N,N+=8}Q.offset+=U&(1<<Q.extra)-1,U>>>=Q.extra,N-=Q.extra,Q.back+=Q.extra}if(Q.offset>Q.dmax){S.msg="invalid distance too far back",Q.mode=30;break}Q.mode=25;case 25:if(Z===0)break t;if(z=K-Z,Q.offset>z){if((z=Q.offset-z)>Q.whave&&Q.sane){S.msg="invalid distance too far back",Q.mode=30;break}ot=z>Q.wnext?(z-=Q.wnext,Q.wsize-z):Q.wnext-z,z>Q.length&&(z=Q.length),dt=Q.window}else dt=$,ot=T-Q.offset,z=Q.length;for(Z<z&&(z=Z),Z-=z,Q.length-=z;$[T++]=dt[ot++],--z;);Q.length===0&&(Q.mode=21);break;case 26:if(Z===0)break t;$[T++]=Q.length,Z--,Q.mode=21;break;case 27:if(Q.wrap){for(;N<32;){if(J===0)break t;J--,U|=H[M++]<<N,N+=8}if(K-=Z,S.total_out+=K,Q.total+=K,K&&(S.adler=Q.check=Q.flags?s(Q.check,$,K,T-K):i(Q.check,$,K,T-K)),K=Z,(Q.flags?U:I(U))!==Q.check){S.msg="incorrect data check",Q.mode=30;break}N=U=0}Q.mode=28;case 28:if(Q.wrap&&Q.flags){for(;N<32;){if(J===0)break t;J--,U+=H[M++]<<N,N+=8}if(U!==(4294967295&Q.total)){S.msg="incorrect length check",Q.mode=30;break}N=U=0}Q.mode=29;case 29:O=1;break t;case 30:O=-3;break t;case 31:return-4;case 32:default:return l}return S.next_out=T,S.avail_out=Z,S.next_in=M,S.avail_in=J,Q.hold=U,Q.bits=N,(Q.wsize||K!==S.avail_out&&Q.mode<30&&(Q.mode<27||b!==4))&&L(S,S.output,S.next_out,K-S.avail_out)?(Q.mode=31,-4):(j-=S.avail_in,K-=S.avail_out,S.total_in+=j,S.total_out+=K,Q.total+=K,Q.wrap&&K&&(S.adler=Q.check=Q.flags?s(Q.check,$,K,S.next_out-K):i(Q.check,$,K,S.next_out-K)),S.data_type=Q.bits+(Q.last?64:0)+(Q.mode===12?128:0)+(Q.mode===20||Q.mode===15?256:0),(j==0&&K===0||b===4)&&O===c&&(O=-5),O)},t.inflateEnd=function(S){if(!S||!S.state)return l;var b=S.state;return b.window&&(b.window=null),S.state=null,c},t.inflateGetHeader=function(S,b){var Q;return S&&S.state&&2&(Q=S.state).wrap?((Q.head=b).done=!1,c):l},t.inflateSetDictionary=function(S,b){var Q,H=b.length;return S&&S.state?(Q=S.state).wrap!==0&&Q.mode!==11?l:Q.mode===11&&i(1,b,H,0)!==Q.check?-3:L(S,b,H,H)?(Q.mode=31,-4):(Q.havedict=1,c):l},t.inflateInfo="pako inflate (from Nodeca project)"},{"../utils/common":41,"./adler32":43,"./crc32":45,"./inffast":48,"./inftrees":50}],50:[function(d,A,t){"use strict";var e=d("../utils/common"),i=[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],s=[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],o=[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];A.exports=function(r,a,c,l,p,g,h,I){var u,f,C,m,E,y,w,v,D,L=I.bits,S=0,b=0,Q=0,H=0,$=0,M=0,T=0,J=0,Z=0,U=0,N=null,j=0,K=new e.Buf16(16),z=new e.Buf16(16),ot=null,dt=0;for(S=0;S<=15;S++)K[S]=0;for(b=0;b<l;b++)K[a[c+b]]++;for($=L,H=15;1<=H&&K[H]===0;H--);if(H<$&&($=H),H===0)return p[g++]=20971520,p[g++]=20971520,I.bits=1,0;for(Q=1;Q<H&&K[Q]===0;Q++);for($<Q&&($=Q),S=J=1;S<=15;S++)if(J<<=1,(J-=K[S])<0)return-1;if(0<J&&(r===0||H!==1))return-1;for(z[1]=0,S=1;S<15;S++)z[S+1]=z[S]+K[S];for(b=0;b<l;b++)a[c+b]!==0&&(h[z[a[c+b]]++]=b);if(y=r===0?(N=ot=h,19):r===1?(N=i,j-=257,ot=s,dt-=257,256):(N=n,ot=o,-1),S=Q,E=g,T=b=U=0,C=-1,m=(Z=1<<(M=$))-1,r===1&&852<Z||r===2&&592<Z)return 1;for(;;){for(w=S-T,D=h[b]<y?(v=0,h[b]):h[b]>y?(v=ot[dt+h[b]],N[j+h[b]]):(v=96,0),u=1<<S-T,Q=f=1<<M;p[E+(U>>T)+(f-=u)]=w<<24|v<<16|D|0,f!==0;);for(u=1<<S-1;U&u;)u>>=1;if(u!==0?(U&=u-1,U+=u):U=0,b++,--K[S]==0){if(S===H)break;S=a[c+h[b]]}if($<S&&(U&m)!==C){for(T===0&&(T=$),E+=Q,J=1<<(M=S-T);M+T<H&&!((J-=K[M+T])<=0);)M++,J<<=1;if(Z+=1<<M,r===1&&852<Z||r===2&&592<Z)return 1;p[C=U&m]=$<<24|M<<16|E-g|0}}return U!==0&&(p[E+U]=S-T<<24|64<<16|0),I.bits=$,0}},{"../utils/common":41}],51:[function(d,A,t){"use strict";A.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(d,A,t){"use strict";var e=d("../utils/common"),i=0,s=1;function n(F){for(var x=F.length;0<=--x;)F[x]=0}var o=0,r=29,a=256,c=a+1+r,l=30,p=19,g=2*c+1,h=15,I=16,u=7,f=256,C=16,m=17,E=18,y=[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],w=[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],v=[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],L=new Array(2*(c+2));n(L);var S=new Array(2*l);n(S);var b=new Array(512);n(b);var Q=new Array(256);n(Q);var H=new Array(r);n(H);var $,M,T,J=new Array(l);function Z(F,x,Y,V,R){this.static_tree=F,this.extra_bits=x,this.extra_base=Y,this.elems=V,this.max_length=R,this.has_stree=F&&F.length}function U(F,x){this.dyn_tree=F,this.max_code=0,this.stat_desc=x}function N(F){return F<256?b[F]:b[256+(F>>>7)]}function j(F,x){F.pending_buf[F.pending++]=255&x,F.pending_buf[F.pending++]=x>>>8&255}function K(F,x,Y){F.bi_valid>I-Y?(F.bi_buf|=x<<F.bi_valid&65535,j(F,F.bi_buf),F.bi_buf=x>>I-F.bi_valid,F.bi_valid+=Y-I):(F.bi_buf|=x<<F.bi_valid&65535,F.bi_valid+=Y)}function z(F,x,Y){K(F,Y[2*x],Y[2*x+1])}function ot(F,x){for(var Y=0;Y|=1&F,F>>>=1,Y<<=1,0<--x;);return Y>>>1}function dt(F,x,Y){var V,R,W=new Array(h+1),tt=0;for(V=1;V<=h;V++)W[V]=tt=tt+Y[V-1]<<1;for(R=0;R<=x;R++){var X=F[2*R+1];X!==0&&(F[2*R]=ot(W[X]++,X))}}function st(F){var x;for(x=0;x<c;x++)F.dyn_ltree[2*x]=0;for(x=0;x<l;x++)F.dyn_dtree[2*x]=0;for(x=0;x<p;x++)F.bl_tree[2*x]=0;F.dyn_ltree[2*f]=1,F.opt_len=F.static_len=0,F.last_lit=F.matches=0}function at(F){8<F.bi_valid?j(F,F.bi_buf):0<F.bi_valid&&(F.pending_buf[F.pending++]=F.bi_buf),F.bi_buf=0,F.bi_valid=0}function At(F,x,Y,V){var R=2*x,W=2*Y;return F[R]<F[W]||F[R]===F[W]&&V[x]<=V[Y]}function nt(F,x,Y){for(var V=F.heap[Y],R=Y<<1;R<=F.heap_len&&(R<F.heap_len&&At(x,F.heap[R+1],F.heap[R],F.depth)&&R++,!At(x,V,F.heap[R],F.depth));)F.heap[Y]=F.heap[R],Y=R,R<<=1;F.heap[Y]=V}function mt(F,x,Y){var V,R,W,tt,X=0;if(F.last_lit!==0)for(;V=F.pending_buf[F.d_buf+2*X]<<8|F.pending_buf[F.d_buf+2*X+1],R=F.pending_buf[F.l_buf+X],X++,V===0?z(F,R,x):(z(F,(W=Q[R])+a+1,x),(tt=y[W])!==0&&K(F,R-=H[W],tt),z(F,W=N(--V),Y),(tt=w[W])!==0&&K(F,V-=J[W],tt)),X<F.last_lit;);z(F,f,x)}function Ct(F,x){var Y,V,R,W=x.dyn_tree,tt=x.stat_desc.static_tree,X=x.stat_desc.has_stree,it=x.stat_desc.elems,ut=-1;for(F.heap_len=0,F.heap_max=g,Y=0;Y<it;Y++)W[2*Y]!==0?(F.heap[++F.heap_len]=ut=Y,F.depth[Y]=0):W[2*Y+1]=0;for(;F.heap_len<2;)W[2*(R=F.heap[++F.heap_len]=ut<2?++ut:0)]=1,F.depth[R]=0,F.opt_len--,X&&(F.static_len-=tt[2*R+1]);for(x.max_code=ut,Y=F.heap_len>>1;1<=Y;Y--)nt(F,W,Y);for(R=it;Y=F.heap[1],F.heap[1]=F.heap[F.heap_len--],nt(F,W,1),V=F.heap[1],F.heap[--F.heap_max]=Y,F.heap[--F.heap_max]=V,W[2*R]=W[2*Y]+W[2*V],F.depth[R]=(F.depth[Y]>=F.depth[V]?F.depth[Y]:F.depth[V])+1,W[2*Y+1]=W[2*V+1]=R,F.heap[1]=R++,nt(F,W,1),2<=F.heap_len;);F.heap[--F.heap_max]=F.heap[1],function(lt,xt){var xe,Ut,Me,Qt,ni,is,Lt=xt.dyn_tree,qs=xt.max_code,ro=xt.stat_desc.static_tree,Ao=xt.stat_desc.has_stree,co=xt.stat_desc.extra_bits,Os=xt.stat_desc.extra_base,He=xt.stat_desc.max_length,oi=0;for(Qt=0;Qt<=h;Qt++)lt.bl_count[Qt]=0;for(Lt[2*lt.heap[lt.heap_max]+1]=0,xe=lt.heap_max+1;xe<g;xe++)He<(Qt=Lt[2*Lt[2*(Ut=lt.heap[xe])+1]+1]+1)&&(Qt=He,oi++),Lt[2*Ut+1]=Qt,qs<Ut||(lt.bl_count[Qt]++,ni=0,Os<=Ut&&(ni=co[Ut-Os]),is=Lt[2*Ut],lt.opt_len+=is*(Qt+ni),Ao&&(lt.static_len+=is*(ro[2*Ut+1]+ni)));if(oi!==0){do{for(Qt=He-1;lt.bl_count[Qt]===0;)Qt--;lt.bl_count[Qt]--,lt.bl_count[Qt+1]+=2,lt.bl_count[He]--,oi-=2}while(0<oi);for(Qt=He;Qt!==0;Qt--)for(Ut=lt.bl_count[Qt];Ut!==0;)qs<(Me=lt.heap[--xe])||(Lt[2*Me+1]!==Qt&&(lt.opt_len+=(Qt-Lt[2*Me+1])*Lt[2*Me],Lt[2*Me+1]=Qt),Ut--)}}(F,x),dt(W,ut,F.bl_count)}function B(F,x,Y){var V,R,W=-1,tt=x[1],X=0,it=7,ut=4;for(tt===0&&(it=138,ut=3),x[2*(Y+1)+1]=65535,V=0;V<=Y;V++)R=tt,tt=x[2*(V+1)+1],++X<it&&R===tt||(X<ut?F.bl_tree[2*R]+=X:R!==0?(R!==W&&F.bl_tree[2*R]++,F.bl_tree[2*C]++):X<=10?F.bl_tree[2*m]++:F.bl_tree[2*E]++,W=R,ut=(X=0)===tt?(it=138,3):R===tt?(it=6,3):(it=7,4))}function O(F,x,Y){var V,R,W=-1,tt=x[1],X=0,it=7,ut=4;for(tt===0&&(it=138,ut=3),V=0;V<=Y;V++)if(R=tt,tt=x[2*(V+1)+1],!(++X<it&&R===tt)){if(X<ut)for(;z(F,R,F.bl_tree),--X!=0;);else R!==0?(R!==W&&(z(F,R,F.bl_tree),X--),z(F,C,F.bl_tree),K(F,X-3,2)):X<=10?(z(F,m,F.bl_tree),K(F,X-3,3)):(z(F,E,F.bl_tree),K(F,X-11,7));W=R,ut=(X=0)===tt?(it=138,3):R===tt?(it=6,3):(it=7,4)}}n(J);var P=!1;function k(F,x,Y,V){K(F,(o<<1)+(V?1:0),3),function(R,W,tt,X){at(R),X&&(j(R,tt),j(R,~tt)),e.arraySet(R.pending_buf,R.window,W,tt,R.pending),R.pending+=tt}(F,x,Y,!0)}t._tr_init=function(F){P||(function(){var x,Y,V,R,W,tt=new Array(h+1);for(R=V=0;R<r-1;R++)for(H[R]=V,x=0;x<1<<y[R];x++)Q[V++]=R;for(Q[V-1]=R,R=W=0;R<16;R++)for(J[R]=W,x=0;x<1<<w[R];x++)b[W++]=R;for(W>>=7;R<l;R++)for(J[R]=W<<7,x=0;x<1<<w[R]-7;x++)b[256+W++]=R;for(Y=0;Y<=h;Y++)tt[Y]=0;for(x=0;x<=143;)L[2*x+1]=8,x++,tt[8]++;for(;x<=255;)L[2*x+1]=9,x++,tt[9]++;for(;x<=279;)L[2*x+1]=7,x++,tt[7]++;for(;x<=287;)L[2*x+1]=8,x++,tt[8]++;for(dt(L,c+1,tt),x=0;x<l;x++)S[2*x+1]=5,S[2*x]=ot(x,5);$=new Z(L,y,a+1,c,h),M=new Z(S,w,0,l,h),T=new Z(new Array(0),v,0,p,u)}(),P=!0),F.l_desc=new U(F.dyn_ltree,$),F.d_desc=new U(F.dyn_dtree,M),F.bl_desc=new U(F.bl_tree,T),F.bi_buf=0,F.bi_valid=0,st(F)},t._tr_stored_block=k,t._tr_flush_block=function(F,x,Y,V){var R,W,tt=0;0<F.level?(F.strm.data_type===2&&(F.strm.data_type=function(X){var it,ut=4093624447;for(it=0;it<=31;it++,ut>>>=1)if(1&ut&&X.dyn_ltree[2*it]!==0)return i;if(X.dyn_ltree[18]!==0||X.dyn_ltree[20]!==0||X.dyn_ltree[26]!==0)return s;for(it=32;it<a;it++)if(X.dyn_ltree[2*it]!==0)return s;return i}(F)),Ct(F,F.l_desc),Ct(F,F.d_desc),tt=function(X){var it;for(B(X,X.dyn_ltree,X.l_desc.max_code),B(X,X.dyn_dtree,X.d_desc.max_code),Ct(X,X.bl_desc),it=p-1;3<=it&&X.bl_tree[2*D[it]+1]===0;it--);return X.opt_len+=3*(it+1)+5+5+4,it}(F),R=F.opt_len+3+7>>>3,(W=F.static_len+3+7>>>3)<=R&&(R=W)):R=W=Y+5,Y+4<=R&&x!==-1?k(F,x,Y,V):F.strategy===4||W===R?(K(F,2+(V?1:0),3),mt(F,L,S)):(K(F,4+(V?1:0),3),function(X,it,ut,lt){var xt;for(K(X,it-257,5),K(X,ut-1,5),K(X,lt-4,4),xt=0;xt<lt;xt++)K(X,X.bl_tree[2*D[xt]+1],3);O(X,X.dyn_ltree,it-1),O(X,X.dyn_dtree,ut-1)}(F,F.l_desc.max_code+1,F.d_desc.max_code+1,tt+1),mt(F,F.dyn_ltree,F.dyn_dtree)),st(F),V&&at(F)},t._tr_tally=function(F,x,Y){return F.pending_buf[F.d_buf+2*F.last_lit]=x>>>8&255,F.pending_buf[F.d_buf+2*F.last_lit+1]=255&x,F.pending_buf[F.l_buf+F.last_lit]=255&Y,F.last_lit++,x===0?F.dyn_ltree[2*Y]++:(F.matches++,x--,F.dyn_ltree[2*(Q[Y]+a+1)]++,F.dyn_dtree[2*N(x)]++),F.last_lit===F.lit_bufsize-1},t._tr_align=function(F){K(F,2,3),z(F,f,L),function(x){x.bi_valid===16?(j(x,x.bi_buf),x.bi_buf=0,x.bi_valid=0):8<=x.bi_valid&&(x.pending_buf[x.pending++]=255&x.bi_buf,x.bi_buf>>=8,x.bi_valid-=8)}(F)}},{"../utils/common":41}],53:[function(d,A,t){"use strict";A.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(d,A,t){(function(e){(function(i,s){"use strict";if(!i.setImmediate){var n,o,r,a,c=1,l={},p=!1,g=i.document,h=Object.getPrototypeOf&&Object.getPrototypeOf(i);h=h&&h.setTimeout?h:i,n={}.toString.call(i.process)==="[object process]"?function(C){process.nextTick(function(){u(C)})}:function(){if(i.postMessage&&!i.importScripts){var C=!0,m=i.onmessage;return i.onmessage=function(){C=!1},i.postMessage("","*"),i.onmessage=m,C}}()?(a="setImmediate$"+Math.random()+"$",i.addEventListener?i.addEventListener("message",f,!1):i.attachEvent("onmessage",f),function(C){i.postMessage(a+C,"*")}):i.MessageChannel?((r=new MessageChannel).port1.onmessage=function(C){u(C.data)},function(C){r.port2.postMessage(C)}):g&&"onreadystatechange"in g.createElement("script")?(o=g.documentElement,function(C){var m=g.createElement("script");m.onreadystatechange=function(){u(C),m.onreadystatechange=null,o.removeChild(m),m=null},o.appendChild(m)}):function(C){setTimeout(u,0,C)},h.setImmediate=function(C){typeof C!="function"&&(C=new Function(""+C));for(var m=new Array(arguments.length-1),E=0;E<m.length;E++)m[E]=arguments[E+1];var y={callback:C,args:m};return l[c]=y,n(c),c++},h.clearImmediate=I}function I(C){delete l[C]}function u(C){if(p)setTimeout(u,0,C);else{var m=l[C];if(m){p=!0;try{(function(E){var y=E.callback,w=E.args;switch(w.length){case 0:y();break;case 1:y(w[0]);break;case 2:y(w[0],w[1]);break;case 3:y(w[0],w[1],w[2]);break;default:y.apply(s,w)}})(m)}finally{I(C),p=!1}}}}function f(C){C.source===i&&typeof C.data=="string"&&C.data.indexOf(a)===0&&u(+C.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 Fa={};ri(Fa,{default:()=>es});module.exports=Co(Fa);var et=require("obsidian");wt();var kt=require("obsidian");var yt=require("obsidian");wt();function ci(d){let A=(d.dateDisplayTimezone||"").trim();return A?{timeZone:A}:{}}function Jt(d,A){try{return new Intl.DateTimeFormat(void 0,A).format(new Date(d))}catch{let{timeZone:t,...e}=A;return new Intl.DateTimeFormat(void 0,e).format(new Date(d))}}function ae(d,A){let t=ci(A);switch(A.dateDisplayFormat??"locale"){case"iso":return Zs(d,A,!0);case"us":return Jt(d,{...t,month:"numeric",day:"numeric",year:"numeric",hour:"numeric",minute:"2-digit"});case"eu":return Jt(d,{...t,day:"numeric",month:"numeric",year:"numeric",hour:"2-digit",minute:"2-digit",hourCycle:"h23"});case"long":return Jt(d,{...t,dateStyle:"full",timeStyle:"short"});case"locale":default:return Jt(d,{...t,dateStyle:"medium",timeStyle:"short"})}}function Ws(d,A){let t=ci(A);switch(A.dateDisplayFormat??"locale"){case"iso":return Zs(d,A,!1);case"us":return Jt(d,{...t,month:"numeric",day:"numeric",year:"numeric"});case"eu":return Jt(d,{...t,day:"numeric",month:"numeric",year:"numeric"});case"long":return Jt(d,{...t,dateStyle:"full"});case"locale":default:{let e=new Date,i=new Date(d).getFullYear()===e.getFullYear();return Jt(d,i?{...t,month:"short",day:"numeric"}:{...t,month:"short",day:"numeric",year:"numeric"})}}}function Xs(d,A){let t=ci(A),e=A.dateDisplayFormat==="iso"||A.dateDisplayFormat==="eu";return Jt(d,{...t,hour:e?"2-digit":"numeric",minute:"2-digit",...e?{hourCycle:"h23"}:{}})}function Zs(d,A,t){let e=ci(A),i=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(d)),s=o=>i.find(r=>r.type===o)?.value??"",n=`${s("year")}-${s("month")}-${s("day")}`;return t?`${n} ${s("hour")}:${s("minute")}`:n}function pi(d,A,t){let e=d.createSpan({cls:"stashpad-count-badge"});t&&e.addClass("is-expanded"),e.setText(A>99?"99+":String(A))}var Ve={pinned:{label:"Pinned",icon:"pin"},shared:{label:"Shared",icon:"users"},tasks:{label:"Tasks",icon:"check-circle-2"}},Ii=class extends yt.ItemView{constructor(t,e){super(t);this.plugin=e;this.activePanel="pinned";this.taskFilter="all";this.taskAssignFilter="all";this.taskFolderFilter="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 Vt}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()===gt&&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"}),i=e.createEl("button",{cls:"stashpad-panels-global-btn"});(0,yt.setIcon)(i.createSpan({cls:"stashpad-panels-global-btn-icon"}),"search"),i.createSpan({cls:"stashpad-panels-global-btn-text",text:"Search"}),i.onclick=()=>this.openSearchFromPanel();let s=e.createEl("button",{cls:"stashpad-panels-global-btn"});(0,yt.setIcon)(s.createSpan({cls:"stashpad-panels-global-btn-icon"}),"folder-tree"),s.createSpan({cls:"stashpad-panels-global-btn-text",text:"Folder Switcher"}),s.onclick=()=>this.plugin.openFolderPicker();let n=e.createDiv({cls:"stashpad-panels-globals-row"}),o=n.createEl("button",{cls:"stashpad-panels-global-btn"});(0,yt.setIcon)(o.createSpan({cls:"stashpad-panels-global-btn-icon"}),"scroll-text"),o.createSpan({cls:"stashpad-panels-global-btn-text",text:"Log"}),o.onclick=()=>this.openLogFromPanel();let r=n.createEl("button",{cls:"stashpad-panels-global-btn"});(0,yt.setIcon)(r.createSpan({cls:"stashpad-panels-global-btn-icon"}),"bell"),r.createSpan({cls:"stashpad-panels-global-btn-text",text:"Notifications"}),r.onclick=()=>this.openNotificationsFromPanel();let a=t.createDiv({cls:"stashpad-panels-bar"});for(let l of Object.keys(Ve)){let p=Ve[l],g=a.createEl("button",{cls:"stashpad-panels-bar-btn"});(0,yt.setIcon)(g.createSpan({cls:"stashpad-panels-bar-btn-icon"}),p.icon),g.createSpan({cls:"stashpad-panels-bar-btn-text",text:p.label}),this.activePanel===l&&g.addClass("is-active"),g.onclick=()=>{this.activePanel!==l&&(this.activePanel=l,this.render())}}let c=t.createDiv({cls:"stashpad-panels-body"});this.activePanel==="pinned"?this.renderPinnedPanel(c):this.activePanel==="shared"?this.renderSharedPanel(c):this.activePanel==="tasks"&&this.renderTasksPanel(c)}renderPinnedPanel(t){let e=t.createDiv({cls:"stashpad-panel-pinned"}),i=e.createEl("button",{cls:"stashpad-pinned-row stashpad-pinned-home"}),s=i.createSpan({cls:"stashpad-pinned-icon"});(0,yt.setIcon)(s,"home"),i.createSpan({cls:"stashpad-pinned-label",text:"Home"}),i.onclick=()=>this.openHomeFromPanel();let n=this.plugin.listPinnedNotes();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 o=new Map;n.forEach((c,l)=>{let p=o.get(c.folder);p||(p=[],o.set(c.folder,p)),p.push({pin:c,idx:l})});let r=this.plugin.lastActiveStashpadLeaf?.view?.noteFolder,a=Array.from(o.keys());r&&o.has(r)&&(a.splice(a.indexOf(r),1),a.unshift(r));for(let c of a){let l=c.split("/").pop()||c,p=e.createDiv({cls:"stashpad-pinned-group-header"});c===r&&p.addClass("is-active-folder"),p.createSpan({cls:"stashpad-pinned-group-name",text:l});let g=o.get(c)??[];for(let{pin:h,idx:I}of g)this.renderPinnedRow(e,h,I)}}renderPinnedRow(t,e,i){let s=this.findFileFor(e);if(!s)return;let n=this.app.metadataCache.getFileCache(s)?.frontmatter??{},o=this.titleFromFile(s),r=typeof n.color=="string"?n.color:null,a=n.completed===!0,c=this.childrenOf(e.folder,e.id).length,l=c>0,p=this.expanded.has(`${e.folder}|${e.id}`),g=t.createDiv({cls:"stashpad-pinned-row"});r&&g.addClass("has-color"),a&&g.addClass("is-completed"),g.draggable=!0,g.dataset.pinIdx=String(i),g.addEventListener("dragstart",C=>{C.dataTransfer?.setData("text/plain",String(i)),C.dataTransfer&&(C.dataTransfer.effectAllowed="move"),g.addClass("is-dragging")}),g.addEventListener("dragend",()=>g.removeClass("is-dragging")),g.addEventListener("dragover",C=>{C.preventDefault(),C.dataTransfer&&(C.dataTransfer.dropEffect="move");let m=g.getBoundingClientRect(),E=C.clientY-m.top<m.height/2;g.toggleClass("drop-before",E),g.toggleClass("drop-after",!E)}),g.addEventListener("dragleave",()=>{g.removeClass("drop-before"),g.removeClass("drop-after")}),g.addEventListener("drop",C=>{C.preventDefault(),g.removeClass("drop-before"),g.removeClass("drop-after");let m=parseInt(C.dataTransfer?.getData("text/plain")??"",10);if(!Number.isFinite(m)||m===i)return;let E=g.getBoundingClientRect(),y=C.clientY-E.top<E.height/2;this.reorderPin(m,y?i:i+1)});let h=g.createSpan({cls:"stashpad-pinned-toggle"});l&&(pi(h,c,p),h.onclick=C=>{C.stopPropagation();let m=`${e.folder}|${e.id}`;this.expanded.has(m)?this.expanded.delete(m):this.expanded.add(m),this.render()});let I=g.createSpan({cls:"stashpad-pinned-icon"});(0,yt.setIcon)(I,l?"folder-tree":"file-text"),r&&(I.style.color=r);let u=g.createSpan({cls:"stashpad-pinned-label",text:o});u.onclick=()=>this.openPinFromPanel(e);let f=e.folder.split("/").pop()||e.folder;if(g.createSpan({cls:"stashpad-pinned-folder",text:f}),g.oncontextmenu=C=>{C.preventDefault();let m=new yt.Menu;m.addItem(E=>E.setTitle("Unpin from sidebar").setIcon("pin-off").onClick(()=>{this.plugin.unpinNote(e)})),m.showAtMouseEvent(C)},l&&p){let C=t.createDiv({cls:"stashpad-pinned-children"});this.renderPinnedSubtree(C,e.folder,e.id,1)}}async reorderPin(t,e){let i=this.plugin.listPinnedNotes();if(t<0||t>=i.length)return;let s=i[t],n=i.filter((l,p)=>p!==t),o=Math.max(0,Math.min(e>t?e-1:e,n.length)),r=n[o-1],a=n[o],c;!r&&!a?c=Date.now():r?a?c=(r.pinnedAt+a.pinnedAt)/2:c=r.pinnedAt+1e3:c=a.pinnedAt-1e3;try{await this.app.fileManager.processFrontMatter(s.file,l=>{l.pinnedAt=c})}catch(l){console.warn("[Stashpad] pin reorder failed",l)}this.render()}renderPinnedSubtree(t,e,i,s){let n=this.childrenOf(e,i);for(let o of n){let r=this.app.metadataCache.getFileCache(o)?.frontmatter??{},a=typeof r.id=="string"?r.id:null;if(!a)continue;let c=typeof r.color=="string"?r.color:null,l=r.completed===!0,p=this.childrenOf(e,a).length,g=p>0,h=this.expanded.has(`${e}|${a}`),I=t.createDiv({cls:"stashpad-pinned-subrow"});l&&I.addClass("is-completed"),I.style.paddingLeft=`${s*16}px`;let u=I.createSpan({cls:"stashpad-pinned-toggle"});g&&(pi(u,p,h),u.onclick=m=>{m.stopPropagation();let E=`${e}|${a}`;this.expanded.has(E)?this.expanded.delete(E):this.expanded.add(E),this.render()});let f=I.createSpan({cls:"stashpad-pinned-icon"});(0,yt.setIcon)(f,"file-text"),c&&(f.style.color=c);let C=I.createSpan({cls:"stashpad-pinned-label",text:this.titleFromFile(o)});C.onclick=()=>this.openPinFromPanel({folder:e,id:a}),g&&h&&this.renderPinnedSubtree(t,e,a,s+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 i=[];for(let s of this.app.vault.getMarkdownFiles()){if((s.parent?.path?.replace(/\/+$/,"")??"")!==t)continue;let o=this.app.metadataCache.getFileCache(s)?.frontmatter;if(!o||typeof o.id!="string")continue;let r=o.parent;if(r===e||e===G&&(r==null||r===G)){if(o.id===G)continue;i.push(s)}}return i.sort((s,n)=>{let o=this.app.metadataCache.getFileCache(s)?.frontmatter,r=this.app.metadataCache.getFileCache(n)?.frontmatter,a=o?.created??"",c=r?.created??"";return a.localeCompare(c)}),i}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 i=await t.read(e),{LogModal:s}=await Promise.resolve().then(()=>(Mt(),ze));new s(this.app,i,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(G)}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()===gt)return this.app.workspace.revealLeaf(t),t.view;let e=this.findActiveStashpad();if(e)return e;let i=this.app.workspace.getLeavesOfType(gt);return i.length>0?(this.app.workspace.revealLeaf(i[0]),i[0].view):(await this.plugin.activateView({reveal:!0}),this.findActiveStashpad())}findActiveStashpad(){let t=this.app.workspace.activeLeaf;return t&&t.view.getViewType()===gt?t.view:null}renderSharedPanel(t){let e=t.createDiv({cls:"stashpad-panel-shared"}),i=(this.plugin.settings.authorId??"").trim();if(!i){e.createDiv({cls:"stashpad-shared-empty"}).setText("Set an author name in Stashpad settings to populate Shared.");return}let s=this.collectSharedNotes(i),n=new Map;for(let l of s){let p=l.authorId;p&&!n.has(p)&&n.set(p,l.authorDisplay||p)}let o=e.createDiv({cls:"stashpad-shared-filters"}),r=(l,p,g)=>{let h=o.createEl("button",{cls:"stashpad-shared-chip",text:l});return p&&h.addClass("is-active"),h.onclick=g,h};if(r("All",this.sharedAuthorFilter==="all",()=>{this.sharedAuthorFilter="all",this.render()}),r("Mine",this.sharedAuthorFilter==="mine",()=>{this.sharedAuthorFilter="mine",this.render()}),r("Others",this.sharedAuthorFilter==="others",()=>{this.sharedAuthorFilter="others",this.render()}),n.size>1){let l=o.createEl("select",{cls:"stashpad-shared-author-select"}),p=l.createEl("option",{text:"Any author"});p.value="__any__";for(let[h,I]of n){let u=l.createEl("option",{text:I});u.value=h}let g=["all","mine","others"].includes(this.sharedAuthorFilter)?"__any__":this.sharedAuthorFilter;l.value=g,l.onchange=()=>{let h=l.value;h==="__any__"?this.sharedAuthorFilter="all":this.sharedAuthorFilter=h,this.render()}}let a=o.createEl("button",{cls:"stashpad-shared-chip",text:"Has contributors"});this.sharedContribOnly&&a.addClass("is-active"),a.onclick=()=>{this.sharedContribOnly=!this.sharedContribOnly,this.render()};let c=s.filter(l=>{if(this.sharedContribOnly&&l.contributorCount===0)return!1;switch(this.sharedAuthorFilter){case"all":return!0;case"mine":return l.authorId===i;case"others":return l.authorId!==i;default:return l.authorId===this.sharedAuthorFilter}});if(c.length===0){e.createDiv({cls:"stashpad-shared-empty"}).setText("No shared notes match the current filters.");return}for(let l of c){let p=e.createDiv({cls:"stashpad-pinned-row stashpad-shared-row"}),g=p.createSpan({cls:"stashpad-pinned-icon"});(0,yt.setIcon)(g,"users"),l.color&&(g.style.color=l.color);let h=p.createSpan({cls:"stashpad-pinned-label",text:l.title});h.onclick=()=>this.openSharedFromPanel(l.folder,l.id);let I=l.folder.split("/").pop()||l.folder;p.createSpan({cls:"stashpad-pinned-folder",text:I}),l.authorDisplay&&p.createSpan({cls:"stashpad-shared-meta"}).setText(l.authorId===i?`you \xB7 ${l.contributorCount} contributor${l.contributorCount===1?"":"s"}`:`by ${l.authorDisplay}${l.contributorCount>0?` \xB7 ${l.contributorCount} contributor${l.contributorCount===1?"":"s"}`:""}`)}}collectSharedNotes(t){let e=this.plugin.discoverStashpadFolders(),i=new Set(e),s=new Map;for(let o of this.app.vault.getMarkdownFiles()){let r=o.parent?.path?.replace(/\/+$/,"")??"";if(!i.has(r))continue;let a=this.app.metadataCache.getFileCache(o)?.frontmatter??{};a.id===G&&s.set(r,this.extractAuthorId(a.author))}let n=[];for(let o of this.app.vault.getMarkdownFiles()){let r=o.parent?.path?.replace(/\/+$/,"")??"";if(!i.has(r)||r.endsWith("/_authors")||o.path.includes("/_authors/"))continue;let a=this.app.metadataCache.getFileCache(o)?.frontmatter??{};if(typeof a.id!="string"||a.id===G)continue;let c=this.extractAuthorId(a.author),l=Array.isArray(a.contributors)?a.contributors.filter(m=>typeof m=="string"):[],p=s.get(r)??null;if(!(l.length>0||p===t&&(c!==null&&c!==t)))continue;let f=this.titleFromFile(o),C=typeof a.color=="string"?a.color:null;n.push({file:o,folder:r,id:a.id,title:f,color:C,authorId:c,authorDisplay:this.extractAuthorDisplay(a.author)||(c??""),contributorCount:l.length})}return n.sort((o,r)=>{let a=this.app.metadataCache.getFileCache(o.file)?.frontmatter??{},c=this.app.metadataCache.getFileCache(r.file)?.frontmatter??{},l=a.modified??a.created??"";return(c.modified??c.created??"").localeCompare(l)}),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 i=t.match(/_authors\/([^\]|]+)-[a-z0-9]{4,12}/i);return i?i[1].replace(/[-_]/g," ").trim():""}async openSharedFromPanel(t,e){await this.plugin.activateViewForFolder(t);let i=this.plugin.lastActiveStashpadLeaf?.view??this.findActiveStashpad();i&&typeof i.navigateTo=="function"&&i.navigateTo(e)}renderTasksPanel(t){let e=t.createDiv({cls:"stashpad-panel-tasks"}),i=this.collectTasks();if(i.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 s=(this.plugin.settings.authorId??"").trim(),n=M=>!!s&&M.assignedTo.some(T=>T.id===s),o=M=>{let T=this.taskAssignFilter;if(T.startsWith("person:")){let J=T.slice(7);return M.assignedTo.some(Z=>Z.id===J)}switch(T){case"mine":return n(M);case"others":return M.assignedTo.length>0&&!n(M);case"byme":return!!s&&M.assignedBy?.id===s;case"unassigned":return M.assignedTo.length===0;default:return!0}},r=new Map;for(let M of i){for(let T of M.assignedTo)T.id!==s&&r.set(T.id,T.name);M.assignedBy&&M.assignedBy.id!==s&&r.set(M.assignedBy.id,M.assignedBy.name)}let a=[...r.entries()].map(([M,T])=>({id:M,name:T})).sort((M,T)=>M.name.localeCompare(T.name)),c=e.createDiv({cls:"stashpad-task-assign-bar"});c.createSpan({cls:"stashpad-task-assign-label",text:"Assignment"});let l=c.createEl("select",{cls:"stashpad-task-assign-select"}),p=M=>{let T={all:"Everyone",mine:"Assigned to me",others:"Assigned to others",byme:"Assigned by me",unassigned:"Unassigned"};return M.startsWith("person:")?r.get(M.slice(7))??"Person":T[M]??M},g=M=>{let T=l.createEl("option",{text:p(M),value:M});this.taskAssignFilter===M&&(T.selected=!0)};for(let M of["all","mine","others","byme","unassigned"])g(M);if(a.length>0){let M=l.createEl("optgroup");M.setAttr("label","By person");for(let T of a){let J=M.createEl("option",{text:T.name,value:`person:${T.id}`});this.taskAssignFilter===`person:${T.id}`&&(J.selected=!0)}}l.onchange=()=>{this.taskAssignFilter=l.value,this.render()};let h=[...new Set(i.map(M=>M.folder))].sort((M,T)=>M.localeCompare(T));this.taskFolderFilter!=="all"&&!h.includes(this.taskFolderFilter)&&(this.taskFolderFilter="all");let I=e.createDiv({cls:"stashpad-task-assign-bar"});I.createSpan({cls:"stashpad-task-assign-label",text:"Folder"});let u=I.createEl("select",{cls:"stashpad-task-assign-select"}),f=u.createEl("option",{text:"All folders",value:"all"});this.taskFolderFilter==="all"&&(f.selected=!0);for(let M of h){let T=u.createEl("option",{text:M.split("/").pop()||M,value:M});this.taskFolderFilter===M&&(T.selected=!0)}u.onchange=()=>{this.taskFolderFilter=u.value,this.render()};let C=M=>this.taskFolderFilter==="all"||M.folder===this.taskFolderFilter,m=i.filter(M=>o(M)&&C(M));if(m.length===0){e.createDiv({cls:"stashpad-tasks-empty"}).setText("No tasks match the current filters.");return}let E=new Date;E.setHours(0,0,0,0);let y=E.getTime(),w=y+24*60*60*1e3,v={overdue:[],today:[],upcoming:[],nodate:[],completed:[]};for(let M of m){if(M.completed){v.completed.push(M);continue}if(M.due==null){v.nodate.push(M);continue}M.due<y?v.overdue.push(M):M.due<w?v.today.push(M):v.upcoming.push(M)}let D=(M,T)=>M.due==null&&T.due==null?M.title.localeCompare(T.title):M.due==null?1:T.due==null?-1:M.due-T.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"}],S=e.createDiv({cls:"stashpad-task-filters"}),b=m.length,Q=(M,T,J)=>{let Z=S.createEl("button",{cls:"stashpad-task-filter"});this.taskFilter===M&&Z.addClass("is-active"),Z.createSpan({cls:"stashpad-task-filter-label",text:T}),Z.createSpan({cls:"stashpad-task-filter-count",text:String(J)}),Z.onclick=()=>{this.taskFilter=M,this.render()}};Q("all","All",b),Q("overdue","Overdue",v.overdue.length),Q("today","Today",v.today.length),Q("upcoming","Upcoming",v.upcoming.length),Q("nodate","No date",v.nodate.length),Q("completed","Done",v.completed.length);let H=this.taskFilter==="all"?L:L.filter(M=>M.key===this.taskFilter),$=!1;for(let M of H){let T=v[M.key];if(T.length!==0){if($=!0,T.sort(M.key==="completed"?(J,Z)=>D(Z,J):D),this.taskFilter==="all"){let J=e.createDiv({cls:`stashpad-task-section-header is-${M.key}`});(0,yt.setIcon)(J.createSpan({cls:"stashpad-task-section-icon"}),M.icon),J.createSpan({cls:"stashpad-task-section-name",text:M.label}),J.createSpan({cls:"stashpad-task-section-count",text:String(T.length)})}for(let J of T)this.renderTaskRow(e,J,M.key==="today")}}if(!$&&this.taskFilter!=="all"){e.createDiv({cls:"stashpad-tasks-empty"}).setText(`Nothing in "${H[0]?.label??this.taskFilter}".`);return}$||e.createDiv({cls:"stashpad-tasks-empty"}).setText("No tasks to show.")}renderTaskRow(t,e,i){let s=t.createDiv({cls:"stashpad-pinned-row stashpad-task-row"});e.color&&s.addClass("has-color"),e.completed&&s.addClass("is-completed");let n=s.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=r=>{r.stopPropagation(),this.toggleTaskCompleted(e)};let o=s.createSpan({cls:"stashpad-pinned-label",text:e.title});if(o.onclick=()=>this.openTaskFromPanel(e.folder,e.id),s.createSpan({cls:"stashpad-task-folder",text:e.folder.split("/").pop()||e.folder}),e.due!=null){let r=s.createSpan({cls:"stashpad-task-due",text:this.formatDueShort(e.due,i)});e.due<Date.now()&&!e.completed&&r.addClass("is-overdue")}else e.dueRaw&&s.createSpan({cls:"stashpad-task-due",text:e.dueRaw});if(e.assignedTo.length>0){let r=(this.plugin.settings.authorId??"").trim(),a=s.createSpan({cls:"stashpad-task-assignees"});for(let c of e.assignedTo){let l=a.createSpan({cls:"stashpad-task-assignee"});r&&c.id===r&&l.addClass("is-me"),l.setText(this.initials(c.name)),l.title=r&&c.id===r?`${c.name} (you)`:c.name}}s.oncontextmenu=r=>{r.preventDefault();let a=new yt.Menu;a.addItem(c=>c.setTitle("Open").setIcon("arrow-right").onClick(()=>{this.openTaskFromPanel(e.folder,e.id)})),a.showAtMouseEvent(r)}}formatDueShort(t,e){return e?Xs(t,this.plugin.settings):Ws(t,this.plugin.settings)}async openTaskFromPanel(t,e){await this.plugin.activateViewForFolder(t);let i=this.plugin.lastActiveStashpadLeaf?.view??this.findActiveStashpad();i&&typeof i.navigateTo=="function"&&i.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()}initials(t){let e=t.trim().split(/\s+/).filter(Boolean);return e.length===0?"?":e.length===1?e[0].slice(0,2).toUpperCase():(e[0][0]+e[e.length-1][0]).toUpperCase()}collectTasks(){let t=this.plugin.discoverStashpadFolders(),e=new Set(t),i=[];for(let s of this.app.vault.getMarkdownFiles()){let n=s.parent?.path?.replace(/\/+$/,"")??"";if(!e.has(n))continue;let o=this.app.metadataCache.getFileCache(s)?.frontmatter??{},r=typeof o.id=="string"?o.id:null;if(!r||r===G)continue;let a=o.completed===!0,c=pe(o,"task")||o.task===!0||o.completed!==void 0,l=typeof o.due=="string"||typeof o.due=="number"?String(o.due):null,p=null;if(l){let g=Date.parse(l);Number.isNaN(g)||(p=g)}!c&&!a&&p==null&&!l||i.push({file:s,folder:n,id:r,title:this.titleFromFile(s),task:c,completed:a,due:p,dueRaw:l,color:typeof o.color=="string"?o.color:null,assignedTo:Ue(o),assignedBy:Xt(o.assignedBy)})}return i}};async function ui(d){let A=d.workspace.getLeavesOfType(Vt);if(A.length>0){d.workspace.revealLeaf(A[0]);return}let t=d.workspace.getLeftLeaf(!1);if(!t){new yt.Notice("Stashpad: couldn't open the panels view.");return}await t.setViewState({type:Vt,active:!0}),d.workspace.revealLeaf(t)}var In=require("obsidian");wt();var _=require("obsidian");Xe();var mi=require("obsidian");wt();var Qe=class extends mi.AbstractInputSuggest{constructor(t,e){super(t,e);this.inputEl=e}getSuggestions(t){let e=t.toLowerCase().split(/\s+/).filter(Boolean),i=o=>e.every(r=>o.toLowerCase().includes(r)),s=[],n=o=>{if(!(o.path!=="/"&&Te.has(o.name))){o.path!=="/"&&i(o.path)&&s.push(o);for(let r of o.children)r instanceof mi.TFolder&&n(r)}};return n(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()}};wt();Mt();var le=require("obsidian"),hs={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."}},ko={info:4e3,success:4e3,warning:6e3,error:1e4},cn=5e3,Qi=class{constructor(A){this.app=A;this.history=[];this.nextId=1;this.historyLimit=cn;this.changeListeners=new Set;this.muted=new Set;this.defaultAuthorId=null}setDefaultAuthorId(A){this.defaultAuthorId=A||null}show(A){let t=A.kind??"info",e=A.category??"system",i={id:this.nextId++,ts:Date.now(),message:A.message,kind:t,category:e,authorId:A.authorId??this.defaultAuthorId??void 0,affectedIds:A.affectedIds?A.affectedIds.slice():[],affectedPaths:A.affectedPaths?A.affectedPaths.slice():[],affectedAuthorIds:A.affectedAuthorIds?A.affectedAuthorIds.slice():[],folder:A.folder,actionLabels:(A.actions??[]).map(o=>o.label)};if(this.pushHistory(i),this.muted.has(e))return null;let s=this.buildContent(A,t),n=A.duration??ko[t];return new le.Notice(s,n)}onChange(A){return this.changeListeners.add(A),()=>this.changeListeners.delete(A)}recent(){return this.history.slice().reverse()}clearHistory(){this.history=[],this.emit()}setMuted(A,t){t?this.muted.add(A):this.muted.delete(A)}isMuted(A){return this.muted.has(A)}loadMutedFromList(A){this.muted=new Set(A)}mutedList(){return Array.from(this.muted)}loadHistory(A){let t=this.applyLimit(A.slice());this.history=t;let e=0;for(let i of t)i.id>e&&(e=i.id);this.nextId=Math.max(this.nextId,e+1),this.emit()}setHistoryLimit(A){this.historyLimit=Number.isFinite(A)?A:cn,this.history=this.applyLimit(this.history),this.emit()}applyLimit(A){return this.historyLimit<=0||A.length<=this.historyLimit?A:A.slice(A.length-this.historyLimit)}pushHistory(A){this.history.push(A),this.history=this.applyLimit(this.history),this.emit()}emit(){for(let A of this.changeListeners)try{A()}catch(t){console.warn("[Stashpad] notification listener failed",t)}}buildContent(A,t){let e=document.createDocumentFragment(),i=document.createElement("div");i.className=`stashpad-notice stashpad-notice-${t}`;let s=document.createElement("div");s.className="stashpad-notice-message";let n=A.message.split(/(`[^`\n]+`)/);for(let o of n)if(o.length>1&&o.startsWith("`")&&o.endsWith("`")){let r=document.createElement("code");r.textContent=o.slice(1,-1),s.appendChild(r)}else o.length>0&&s.appendChild(document.createTextNode(o));if(i.appendChild(s),A.actions&&A.actions.length>0){let o=document.createElement("div");o.className="stashpad-notice-actions";for(let r of A.actions){let a=document.createElement("button");a.className="stashpad-notice-action",a.textContent=r.label,a.addEventListener("click",c=>{if(c.stopPropagation(),Promise.resolve().then(()=>r.onClick()).catch(l=>console.warn("[Stashpad] notification action failed",l)),!r.keepOpen){let l=a.closest(".notice");l&&l.parentElement&&l.parentElement.removeChild(l)}}),o.appendChild(a)}i.appendChild(o)}return e.appendChild(i),e}};function Ei(d,A,t){let e=d.vault.getAbstractFileByPath(A);if(!(e instanceof le.TFile))return[];let i=[{label:"Reveal",keepOpen:!0,onClick:()=>{let s=d.workspace.getLeavesOfType("file-explorer")[0];if(!s)return;d.workspace.revealLeaf(s),s.view?.revealInFolder?.(e)}}];if(!t){let s=le.Platform.isMacOS?"Finder":le.Platform.isWin?"File Explorer":"file manager";i.push({label:`Show in ${s}`,keepOpen:!0,onClick:()=>{try{let n=window.require?.("electron")?.shell,r=d.vault.adapter?.getFullPath?.(A);r&&n?.showItemInFolder&&n.showItemInFolder(r)}catch(n){console.warn("[Stashpad] showItemInFolder failed",n)}}})}return i}var gs=(()=>{try{return typeof navigator<"u"&&/Mac|iPhone|iPad|iPod/i.test(navigator.platform||navigator.userAgent||"")}catch{return!1}})();function ps(d){if(!d)return"(none)";let A=d.replace(/\bMod\b/g,gs?"Cmd":"Ctrl");return gs&&(A=A.replace(/\bAlt\b/g,"Option")),A}function ln(d,A,t={allowSingleKey:!0}){let e=d.placeholder,i=d.value;d.placeholder="Press a key\u2026 (Backspace to cancel)",d.value="",d.classList.add("is-recording");let s=!1,n=()=>{d.placeholder=e,d.classList.remove("is-recording"),s||(d.value=i),d.removeEventListener("keydown",o,!0),d.removeEventListener("blur",r)},o=a=>{if(a.key==="Control"||a.key==="Shift"||a.key==="Alt"||a.key==="Meta"||a.key==="OS")return;let c=!!a.code&&(/^Key[A-Z]$/.test(a.code)||/^Digit\d$/.test(a.code));if((a.key==="Dead"||a.key==="Process"||a.key==="Unidentified")&&!c)return;if(a.preventDefault(),a.stopPropagation(),a.key==="Backspace"&&!a.metaKey&&!a.ctrlKey&&!a.altKey&&!a.shiftKey){n();return}let l=[];gs?(a.metaKey&&l.push("Mod"),a.ctrlKey&&l.push("Ctrl")):a.ctrlKey&&l.push("Mod"),a.altKey&&l.push("Alt"),a.shiftKey&&l.push("Shift");let p=So(a.key,a.code);if(!p||l.length===0&&!t.allowSingleKey)return;l.push(p);let g=l.join("+");s=!0,n(),A(g)},r=()=>n();return d.addEventListener("keydown",o,!0),d.addEventListener("blur",r),n}function So(d,A){if(!d)return"";if(A){let t=/^Key([A-Z])$/.exec(A);if(t)return t[1];let e=/^Digit(\d)$/.exec(A);if(e)return e[1]}return d.length===1?d.toUpperCase():d}Be();Rt();var Ze=null,yi=new Set;function wi(d){if(Ze!==d){Ze=d;for(let A of yi)A()}}function qt(){return Ze}function dn(d){if(Ze===d){Ze=null;for(let A of yi)A()}}function hn(d){return yi.add(d),()=>yi.delete(d)}function Do(){return _.Platform.isMacOS?"Finder":_.Platform.isWin?"File Explorer":"file manager"}var $e=[{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"},{id:"jumpToTop",label:"Jump to top of list",desc:"Default: Home \u2014 move the cursor to the first note in the current list.",defaultPrimary:"Home"},{id:"jumpToBottom",label:"Jump to bottom of list",desc:"Default: End \u2014 move the cursor to the last note in the current list.",defaultPrimary:"End"},{id:"commandPalette",label:"Command palette (Stashpad only)",desc:"Default: Mod+K \u2014 open a command palette listing only Stashpad's commands, with Sift search.",defaultPrimary:"Mod+K"}];function us(){let d={};for(let A of $e)d[A.id]={primary:A.defaultPrimary,secondary:"",preferRight:!1};return d}var Zt={folder:"Stashpad",importDropFolder:"",exportFolder:"_exports",autoImport:!1,inheritObsidianExclusions:!0,folderPanelPinnedFraction:.5,enablePerfProfiling:!1,writeRecoveryLinks:!0,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:{},attachmentsOnlyNotes:{},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:us()},gn=JSON.parse(JSON.stringify(Zt)),Is=new Set;function ft(){return gn}function fs(d){gn=d;for(let A of Is)A()}function pn(d){return Is.add(d),()=>Is.delete(d)}function ki(d){try{let A=d.internalPlugins?.plugins?.templates;if(!A?.enabled)return null;let t=A.instance?.options??{};return{dateFormat:t.dateFormat||"YYYY-MM-DD",timeFormat:t.timeFormat||"HH:mm"}}catch{return null}}var Fi=[{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"}],vi=class extends _.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 i=t.createDiv({cls:"stashpad-settings-search-wrap"}).createEl("input",{type:"text",placeholder:"Search settings\u2026",cls:"stashpad-settings-search-input"});i.value=this.searchQuery;let s=this.searchQuery.trim().length>0,n=t.createDiv({cls:"stashpad-settings-tabs"});s&&n.addClass("is-search-mode");for(let a of Fi){let c=n.createEl("button",{cls:"stashpad-settings-tab",text:a.label});!s&&this.activeTab===a.id&&c.addClass("is-active"),c.onclick=()=>{this.searchQuery="",this.activeTab=a.id,this.display()}}let o=t.createDiv({cls:"stashpad-settings-body"});if(s){for(let a of Fi){let c=o.createDiv({cls:"stashpad-settings-search-group"});c.createEl("h3",{text:a.label,cls:"stashpad-settings-search-group-header"});let l=c.createDiv();this.renderTabContent(l,a.id)}this.applySearchFilter(o)}else this.renderTabContent(o,this.activeTab);let r=s;i.oninput=()=>{this.searchQuery=i.value;let a=this.searchQuery.trim().length>0;if(a!==r){let c=i.selectionStart??i.value.length;this.display();let l=t.querySelector(".stashpad-settings-search-input");l&&(l.focus(),l.setSelectionRange(c,c));return}a&&this.applySearchFilter(o)},this.searchQuery&&setTimeout(()=>{i.focus(),i.setSelectionRange(i.value.length,i.value.length)},0)}applySearchFilter(t){let e=this.searchQuery.trim().toLowerCase();if(!e)return;let i=e.split(/\s+/).filter(Boolean),s=o=>i.every(r=>o.includes(r));t.querySelectorAll(".setting-item").forEach(o=>{let r=o.querySelector(".setting-item-name")?.textContent?.toLowerCase()??"",a=o.querySelector(".setting-item-description")?.textContent?.toLowerCase()??"";o.style.display=s(`${r} ${a}`)?"":"none"}),t.querySelectorAll(".stashpad-settings-search-group").forEach(o=>{let r=Array.from(o.querySelectorAll(".setting-item")).some(a=>a.style.display!=="none");o.style.display=r?"":"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 _.Setting(t).setName("Write recovery navigation links").setDesc("Maintain the redundant parentLink/children frontmatter so you can walk the hierarchy from raw Markdown if the index ever breaks. On a slow / network drive this is a big per-move cost (several round-trips each); turn it off there for snappier moves \u2014 Rebootstrap rebuilds the fields on demand, and your notes' canonical structure (id/parent) is unaffected either way.").addToggle(o=>o.setValue(this.plugin.settings.writeRecoveryLinks).onChange(async r=>{this.plugin.settings.writeRecoveryLinks=r,await this.plugin.saveSettings()})),new _.Setting(t).setName("Performance profiling").setDesc("Record timing for list rendering, body reads, and file writes. Turn on, use Stashpad normally (especially the slow operations), then run \u201CDump performance profile\u201D from the command palette and share the result. Off = zero overhead.").addToggle(o=>o.setValue(this.plugin.settings.enablePerfProfiling).onChange(async r=>{this.plugin.settings.enablePerfProfiling=r,await this.plugin.saveSettings()})),new _.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(o=>o.setButtonText("Open log").onClick(async()=>{let r=this.app.vault.adapter,a=this.plugin.pluginPrivatePath("log.jsonl");if(!await r.exists(a)){new _.Notice("No log yet \u2014 make some changes first.");return}let c=await r.read(a);new ue(this.app,c,a).open()})),new _.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(o=>o.setValue(String(this.plugin.settings.notificationHistoryLimit??5e3)).setPlaceholder("5000").onChange(async r=>{let a=parseInt(r,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 s=new Set(this.plugin.settings.mutedNotificationCategories??[]),n=Object.keys(hs);for(let o of n){let r=hs[o];new _.Setting(e).setName(r.label).setDesc(r.desc).addToggle(a=>a.setValue(!s.has(o)).onChange(async c=>{let l=!c;l?s.add(o):s.delete(o),this.plugin.settings.mutedNotificationCategories=Array.from(s),this.plugin.notifications.setMuted(o,l),await this.plugin.saveSettings()}))}new _.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(o=>o.setButtonText("View notification history").onClick(()=>{new Ke(this.app,this.plugin.notifications,async r=>{let a=this.app.vault.adapter,c=this.plugin.pluginPrivatePath("log.jsonl");if(!await a.exists(c)){new _.Notice("No log yet \u2014 make some changes first.");return}let l=await a.read(c);new ue(this.app,l,c).open()},this.plugin.settings.authorId||null,r=>this.plugin.lookupNoteAuthorIds(r)).open()}))}renderGeneralTab(t){new _.Setting(t).setName("Stashpad notes folder").setDesc("Vault-relative folder where Stashpad stores its notes and attachments. Created on demand.").addText(s=>{new Qe(this.app,s.inputEl),s.setValue(this.plugin.settings.folder).setPlaceholder("Stashpad").onChange(async n=>{let o=(n||"").trim().replace(/^\/+|\/+$/g,"")||Zt.folder,r=o.split("/").filter(Boolean).pop()??"";if(new Set([this.plugin.settings.importDropFolder,this.plugin.settings.exportFolder,"_attachments","_processed"].map(c=>(c??"").trim().replace(/^\/+|\/+$/g,"")).filter(Boolean)).has(r)){new _.Notice(`"${o}" uses a reserved Stashpad subfolder name. Pick something else.`);return}this.plugin.settings.folder=o,await this.plugin.saveSettings()})}),new _.Setting(t).setName("Auto-import dropped files").setDesc("When on, any file you drop directly into a Stashpad folder is imported automatically: markdown becomes a note (the original is archived to .archive); other files move to _attachments with a note that links to them. Large drops ask for confirmation first.").addToggle(s=>s.setValue(this.plugin.settings.autoImport).onChange(async n=>{this.plugin.settings.autoImport=n,await this.plugin.saveSettings()})),new _.Setting(t).setName("Inherit Obsidian's excluded files").setDesc("Also hide files matching Obsidian's \u201CExcluded files\u201D list (Settings \u2192 Files & Links) from Stashpad's link autocomplete and file surfaces \u2014 so you manage exclusions in one place. Plugin-internal formats like .edtz are always excluded regardless.").addToggle(s=>s.setValue(this.plugin.settings.inheritObsidianExclusions).onChange(async n=>{this.plugin.settings.inheritObsidianExclusions=n,await this.plugin.saveSettings()})),new _.Setting(t).setName("Dedicated import subfolder (optional)").setDesc("Optional. A subfolder (relative to each Stashpad folder) where dropped .stash files auto-import. Leave blank to just drop files into the Stashpad folder itself (recommended). Suggested name: _imports.").addText(s=>s.setValue(this.plugin.settings.importDropFolder).setPlaceholder("_imports (leave blank to use the folder root)").onChange(async n=>{this.plugin.settings.importDropFolder=(n||"").trim().replace(/^\/+|\/+$/g,""),await this.plugin.saveSettings()})),new _.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(s=>s.setValue(this.plugin.settings.exportFolder).setPlaceholder("_exports").onChange(async n=>{let o=(n||"").trim().replace(/^\/+|\/+$/g,"")||Zt.exportFolder;this.plugin.settings.exportFolder=o,await this.plugin.saveSettings()})),new _.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(s=>s.setButtonText("Rebootstrap now").onClick(async()=>{s.setDisabled(!0).setButtonText("Working\u2026");try{let{touched:n,fmChecked:o,fmWritten:r,slugsRenamed:a,authors:c,imported:l,attachmentsLinked:p}=await this.plugin.rebootstrapAllFolders(),g=[];g.push(`rebootstrapped ${n.length} folder${n.length===1?"":"s"}`),l>0&&g.push(`imported ${l} loose file${l===1?"":"s"}`),p>0&&g.push(`linked attachments on ${p} note${p===1?"":"s"}`),r>0?g.push(`updated frontmatter on ${r} of ${o} notes`):o>0&&g.push(`frontmatter already in sync (${o} notes checked)`),a>0&&g.push(`renamed ${a} note${a===1?"":"s"} to match body`),c>0&&g.push(`rebuilt author registry (${c} author${c===1?"":"s"})`),new _.Notice(`Stashpad: ${g.join("; ")}.`)}catch(n){new _.Notice(`Stashpad: rebootstrap failed (${n.message})`)}finally{s.setDisabled(!1).setButtonText("Rebootstrap now")}})),new _.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(s=>s.setValue(this.plugin.settings.useTemplatesFormat).onChange(async n=>{this.plugin.settings.useTemplatesFormat=n,await this.plugin.saveSettings()}));let e=ki(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 s=null,n=()=>{if(!s)return;let o=Date.now(),r=ae(o,this.plugin.settings);s.setText(`Sample: ${r}`)};new _.Setting(t).setName("Date display format").setDesc("How due dates and created/modified times are shown in the Tasks and detail panels.").addDropdown(o=>{o.addOption("locale","Locale, short (Mar 5, 9:00 AM)"),o.addOption("long","Locale, long (Thursday, March 5\u2026)"),o.addOption("iso","ISO (2026-03-05 09:00)"),o.addOption("us","US (3/5/2026, 9:00 AM)"),o.addOption("eu","EU (5/3/2026, 09:00)"),o.setValue(this.plugin.settings.dateDisplayFormat??"locale"),o.onChange(async r=>{this.plugin.settings.dateDisplayFormat=r,await this.plugin.saveSettings(),n()})}),new _.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(o=>{o.setPlaceholder("(system timezone)"),o.setValue(this.plugin.settings.dateDisplayTimezone??""),o.onChange(async r=>{this.plugin.settings.dateDisplayTimezone=(r||"").trim(),await this.plugin.saveSettings(),n()})}),s=t.createDiv({cls:"setting-item-description stashpad-settings-note"}),n()}new _.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(s=>s.setValue(this.plugin.settings.autoNavOnMoveIn).onChange(async n=>{this.plugin.settings.autoNavOnMoveIn=n,await this.plugin.saveSettings()})),new _.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(s=>s.setValue(this.plugin.settings.autoNavOnMoveOut).onChange(async n=>{this.plugin.settings.autoNavOnMoveOut=n,await this.plugin.saveSettings()})),new _.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(s=>s.setValue(this.plugin.settings.doubleClickToFocus).onChange(async n=>{this.plugin.settings.doubleClickToFocus=n,await this.plugin.saveSettings()})),new _.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(s=>s.setValue(this.plugin.settings.autoOpenDetailPanel).onChange(async n=>{this.plugin.settings.autoOpenDetailPanel=n,await this.plugin.saveSettings()})),new _.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(s=>s.setValue(this.plugin.settings.autoExpandCursorRow).onChange(async n=>{this.plugin.settings.autoExpandCursorRow=n,await this.plugin.saveSettings()})),new _.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(s=>s.setValue(this.plugin.settings.confirmCrossParentDrag).onChange(async n=>{this.plugin.settings.confirmCrossParentDrag=n,await this.plugin.saveSettings()})),new _.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(s=>s.setValue(this.plugin.settings.confirmBulkDelete).onChange(async n=>{this.plugin.settings.confirmBulkDelete=n,await this.plugin.saveSettings()})),new _.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(s=>s.setValue(this.plugin.settings.confirmAttachmentDelete).onChange(async n=>{this.plugin.settings.confirmAttachmentDelete=n,await this.plugin.saveSettings()}));{let s=null,n=(this.plugin.settings.slugStopWords?.length?this.plugin.settings.slugStopWords:Pt).join(` +`);new _.Setting(t).setName("Slug stop-words").setDesc("Words removed from auto-generated note titles (filenames). One per line.").addTextArea(o=>{o.setValue(n),s=o.inputEl,s.rows=6,s.style.fontFamily="var(--font-monospace)",o.onChange(async r=>{let a=(r||"").split(/\r?\n/).map(c=>c.trim().toLowerCase()).filter(Boolean);this.plugin.settings.slugStopWords=a,await this.plugin.saveSettings()})}).addExtraButton(o=>o.setIcon("rotate-ccw").setTooltip("Reset to defaults").onClick(async()=>{this.plugin.settings.slugStopWords=[...Pt],s&&(s.value=Pt.join(` +`)),await this.plugin.saveSettings()}))}{let s=this.plugin.discoverStashpadFolders();if(new _.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."),s.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 o=t.createDiv({cls:"stashpad-folder-list"});for(let r of s)this.renderFolderScopeRow(o,r)}let n=null;new _.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(o=>{o.setPlaceholder("my-stashpad"),n=o.inputEl}).addButton(o=>o.setButtonText("Create").setCta().onClick(async()=>{let r=(n?.value??"").trim().replace(/^\/+|\/+$/g,"");if(!r){new _.Notice("Enter a folder name first.");return}try{await this.plugin.createNewStashpad(r),new _.Notice(`Created Stashpad "${r}".`),n&&(n.value=""),await this.plugin.waitForStashpadFolder(r,2e3),this.display()}catch(a){new _.Notice(`Couldn't create: ${a.message}`)}}))}new _.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(s=>s.setValue(this.plugin.settings.autofocusComposerAfterSend).onChange(async n=>{this.plugin.settings.autofocusComposerAfterSend=n,await this.plugin.saveSettings()})),new _.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(s=>s.setValue(this.plugin.settings.popoutDuplicates).onChange(async n=>{this.plugin.settings.popoutDuplicates=n,await this.plugin.saveSettings()})),new _.Setting(t).setName("Prefix timestamps when copying").setDesc("Include each note's timestamp before its body when copying with C or Y.").addToggle(s=>s.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 $e)this.renderBindingRow(t,e)}renderJdIndexSection(t){let e=t.createEl("h3",{text:"JD Index Builder"});e.id="stashpad-jd-index-section";let i=t.createEl("p",{cls:"setting-item-description"});i.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 s=this.plugin.discoverStashpadFolders();new _.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 c=>{this.plugin.settings.jdIndexScope=c==="folder"?"folder":"vault",await this.plugin.saveSettings(),this.display()})}),(this.plugin.settings.jdIndexScope??"vault")==="folder"&&new _.Setting(t).setName("Scope folder").setDesc("Vault-relative path. Leave empty to fall back to the entire vault.").addText(a=>{new Qe(this.app,a.inputEl),a.setPlaceholder("Path/To/Folder"),a.setValue(this.plugin.settings.jdIndexScopeFolder??""),a.onChange(async c=>{this.plugin.settings.jdIndexScopeFolder=(c||"").trim().replace(/^\/+|\/+$/g,""),await this.plugin.saveSettings()})}),new _.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 c=>{this.plugin.settings.jdIndexIncludeStashpadFolders=c,await this.plugin.saveSettings(),this.display()})}),new _.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 Qe(this.app,a.inputEl),a.setPlaceholder(s[0]??"(pick a Stashpad folder)"),a.setValue(this.plugin.settings.jdIndexStashpadFolder??""),a.onChange(async c=>{this.plugin.settings.jdIndexStashpadFolder=(c||"").trim().replace(/^\/+|\/+$/g,""),await this.plugin.saveSettings()})}),new _.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 c=>{this.plugin.settings.jdIndexSort=c==="created"?"created":"natural",await this.plugin.saveSettings()})});let n=me(this.app,this.plugin,this.plugin.settings),o=t.createEl("p",{cls:"setting-item-description"}),r=n.skippedStashpadNotes.length>0?` (${n.skippedStashpadNotes.length} Stashpad-folder note${n.skippedStashpadNotes.length===1?"":"s"} excluded by default)`:"";o.setText(`Preview: ${n.indexed.length} note${n.indexed.length===1?"":"s"} would be indexed, ${n.nonIndex.length} would NOT be indexed${r}.`),new _.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 c=await fi(this.app,this.plugin,this.plugin.settings);if(c.error==="no-dest"){new _.Notice("Set a Designated Stashpad folder for Index first.",5e3);return}if(c.error==="no-home"){new _.Notice(`"${this.plugin.settings.jdIndexStashpadFolder}" doesn't have a Stashpad home note. Open the folder in Stashpad first (it creates one automatically).`,7e3);return}Ci(this.app,c),this.display()}catch(c){console.error("[stashpad] preview failed",c),new _.Notice(`Preview failed: ${c?.message??c}`,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 _.Notice("Set a Designated Stashpad folder for Index first.",5e3);return}new We(this.app,this.plugin,this.plugin.settings,n.indexed.length,async()=>{try{let p=await ls(this.app,this.plugin,this.plugin.settings);if(p.error==="no-dest"){new _.Notice("Set a Designated Stashpad folder for Index first.",5e3);return}if(p.error==="dest-not-stashpad"){new _.Notice(`"${p.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 _.Notice(`Built: ${p.created} created, ${p.updated} updated, ${p.skipped} skipped \u2192 ${p.destFolder}`,6e3),this.display()}catch(p){console.error("[stashpad] build failed",p),new _.Notice(`Build failed: ${p?.message??p}`,8e3)}}).open()})}).addButton(a=>{a.setButtonText(`Reveal in ${Do()}`),a.setTooltip("Open the designated Stashpad folder in your OS file browser."),a.onClick(async()=>{let c=(this.plugin.settings.jdIndexStashpadFolder??"").trim().replace(/^\/+|\/+$/g,"");if(!c){new _.Notice("Set a Designated Stashpad folder for Index first.",5e3);return}if(!this.app.vault.getAbstractFileByPath(c)){new _.Notice(`Folder "${c}" doesn't exist yet.`,5e3);return}try{let p=this.app.vault.adapter.basePath;if(p){let{shell:g}=window.require?.("electron")??{},h=`${p}/${c}`;g?.openPath?.(h)}else new _.Notice("Reveal in file system not supported on this platform.",4e3)}catch(p){new _.Notice(`Couldn't open folder: ${p?.message??p}`,5e3)}})})}renderColorAliasesSection(t){let e=this.plugin.discoverStashpadFolders();if(e.length===0){new _.Setting(t).setName("Color Aliases per Stashpad").setDesc("No Stashpads discovered yet \u2014 create one above first.");return}let i=(()=>{let o=qt()?.noteFolder;return o&&e.includes(o)?o:e[0]})();new _.Setting(t).setName("Color Aliases per Stashpad").setDesc("Which Stashpad's colors to label.").addDropdown(o=>{for(let r of e)o.addOption(r,r);o.setValue(i),o.onChange(r=>{i=r,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 s=t.createDiv({cls:"stashpad-color-aliases-list"}),n=()=>{s.empty();let o=this.plugin.collectColorsInFolder(i),r=new Map(o.map(p=>[p.hex,p.count])),a=this.plugin.settings.colorAliases?.[i.replace(/\/+$/,"")]??{},c=new Set([...r.keys(),...Object.keys(a)]);if(c.size===0){s.createEl("p",{cls:"setting-item-description",text:`No colors used or aliased in "${i}" yet. Set a per-note color (Shift+: or right-click \u2192 Set color) and it'll appear here.`});return}let l=[...c].map(p=>({hex:p,count:r.get(p)??0}));l.sort((p,g)=>g.count-p.count||p.hex.localeCompare(g.hex));for(let p of l)this.renderColorAliasRow(s,i,p.hex,p.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 _.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(i=>{i.setValue(this.plugin.settings.authorName).onChange(async s=>{this.plugin.settings.authorName=s.trim(),this.plugin.settings.authorName&&!this.plugin.settings.authorId&&(this.plugin.settings.authorId=Et()),await this.plugin.saveSettings(),await this.plugin.syncAuthorFilesToName()})}),new _.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(i=>{i.setValue(this.plugin.settings.authorId).setDisabled(!0)}),new _.Setting(t).setName("Title / role").setDesc('Optional. Shown on your author page (e.g. "Engineer", "PM", "Designer").').addText(i=>{i.setValue(this.plugin.settings.authorRole).onChange(async s=>{this.plugin.settings.authorRole=s.trim(),await this.plugin.saveSettings(),await this.plugin.syncAuthorFilesToName()})}),new _.Setting(t).setName("Department / team").setDesc('Optional. Shown on your author page (e.g. "Engineering", "Growth").').addText(i=>{i.setValue(this.plugin.settings.authorDepartment).onChange(async s=>{this.plugin.settings.authorDepartment=s.trim(),await this.plugin.saveSettings(),await this.plugin.syncAuthorFilesToName()})}),new _.Setting(t).setName("Show author in note footer").addToggle(i=>i.setValue(this.plugin.settings.showAuthor).onChange(async s=>{this.plugin.settings.showAuthor=s,await this.plugin.saveSettings()})),new _.Setting(t).setName("Show contributors in note footer").addToggle(i=>i.setValue(this.plugin.settings.showContributors).onChange(async s=>{this.plugin.settings.showContributors=s,await this.plugin.saveSettings()})),new _.Setting(t).setName("Show last edit time in note footer").addToggle(i=>i.setValue(this.plugin.settings.showLastEdit).onChange(async s=>{this.plugin.settings.showLastEdit=s,await this.plugin.saveSettings()}));let e=this.plugin.collectAuthoredFolders();if(e.length>0){t.createEl("h4",{text:"Folders you've worked in"});let i=t.createDiv({cls:"stashpad-authored-folders-list"});for(let s of e){let n=i.createDiv({cls:"stashpad-authored-folder-row"}),o=n.createEl("a",{cls:"stashpad-authored-folder-link",text:s.folder});o.onclick=a=>{a.preventDefault(),this.plugin.activateViewForFolder(s.folder)};let r=[];s.authored>0&&r.push(`authored ${s.authored}`),s.contributed>0&&r.push(`contributed to ${s.contributed}`),n.createSpan({cls:"stashpad-authored-folder-counts",text:` \xB7 ${r.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 _.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(s=>s.setButtonText("Rebuild").onClick(async()=>{s.setDisabled(!0).setButtonText("Rebuilding\u2026");try{let n=await this.plugin.rebuildAuthorRegistry();new _.Notice(`Author registry rebuilt: ${n.total} author(s).`)}catch(n){new _.Notice(`Rebuild failed: ${n.message}`)}s.setDisabled(!1).setButtonText("Rebuild"),this.display()})).addButton(s=>s.setButtonText("Restore missing pages").onClick(async()=>{s.setDisabled(!0).setButtonText("Restoring\u2026");try{let n=await this.plugin.restoreMissingAuthorStubs();new _.Notice(n.created>0?`Restored ${n.created} author page(s).`:"No missing author pages.")}catch(n){new _.Notice(`Restore failed: ${n.message}`)}s.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 i=t.createDiv({cls:"stashpad-known-authors-list"});for(let s of e){let n=i.createDiv({cls:"stashpad-known-author-row"}),o=n.createDiv({cls:"stashpad-known-author-main"});o.createSpan({cls:"stashpad-known-author-name",text:s.name||"(unnamed)"});let r=[];if(s.role&&r.push(s.role),s.department&&r.push(s.department),r.push(`id ${s.id}`),o.createSpan({cls:"stashpad-known-author-meta",text:` \xB7 ${r.join(" \xB7 ")}`}),s.renames&&s.renames.length>0){let a=n.createDiv({cls:"stashpad-known-author-history"}),c=s.renames.map(l=>`${l.from} \u2192 ${l.to}`).join(", ");a.setText(`Renamed: ${c}`)}}}renderNoteTemplatesSection(t){let e=this.plugin.discoverStashpadFolders();if(e.length===0)return;new _.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 i=t.createDiv({cls:"stashpad-note-templates-list"}),s=n=>{let o=n.replace(/\/+$/,""),r=i.createDiv({cls:"stashpad-note-template-row"});r.createSpan({cls:"stashpad-note-template-folder"}).setText(n);let c=r.createDiv({cls:"stashpad-note-template-input-wrap"}),l=c.createEl("input",{type:"text",cls:"stashpad-note-template-input",attr:{placeholder:"path/to/template.md (leave blank to disable)"}});l.value=(this.plugin.settings.noteTemplates??{})[o]??"";let p=c.createDiv({cls:"stashpad-note-template-suggest"});p.style.display="none";let g=r.createDiv({cls:"stashpad-note-template-warn"});g.style.display="none";let h=()=>this.app.vault.getMarkdownFiles().map(C=>C.path).filter(C=>!/\/(_imports|_exports|_attachments|\.stashpad)\//.test(C)).sort(),I=()=>{p.empty();let C=l.value.trim().toLowerCase().split(/\s+/).filter(Boolean),m=y=>{let w=y.toLowerCase();return C.every(v=>w.includes(v))},E=h().filter(y=>m(y)).slice(0,12);if(E.length===0){p.style.display="none";return}p.style.display="";for(let y of E)p.createDiv({cls:"stashpad-note-template-suggest-item",text:y}).addEventListener("mousedown",async v=>{v.preventDefault(),l.value=y,await u(),p.style.display="none"})},u=async()=>{let C=l.value.trim(),m={...this.plugin.settings.noteTemplates??{}};C?m[o]=C:delete m[o],this.plugin.settings.noteTemplates=m,await this.plugin.saveSettings(),f()},f=()=>{g.empty(),g.style.display="none";let C=l.value.trim();if(!C)return;let m=this.app.vault.getAbstractFileByPath(C);if(!m||m.extension!=="md"){g.style.display="",g.setText(`\u26A0 "${C}" is not a markdown file in this vault.`);return}let E=this.app.metadataCache.getFileCache(m)?.frontmatter??{},w=Wt.filter(v=>{let D=E[v];return!(D==null||typeof D=="string"&&D.trim()===""||Array.isArray(D)&&D.length===0)});w.length!==0&&(g.style.display="",g.setText(`\u26A0 Template defines ${w.join(", ")} \u2014 Stashpad always sets ${w.length===1?"this":"these"} on new notes, so the template value${w.length===1?"":"s"} will be ignored.`))};l.addEventListener("focus",I),l.addEventListener("input",I),l.addEventListener("blur",()=>{setTimeout(()=>{p.style.display="none"},150)}),l.addEventListener("change",()=>{u()}),f()};for(let n of e)s(n)}renderColorAliasRow(t,e,i,s,n){let o=t.createDiv({cls:"stashpad-color-alias-row"});s===0&&o.addClass("is-unused");let r=o.createSpan({cls:"stashpad-color-alias-swatch"});r.style.background=i,r.title="Click to bulk-recolor every note of this color in this Stashpad",r.onclick=()=>{let p=this.plugin.settings.customPalette??[];new ce(this.app,i,p,async g=>{if((g??null)===null&&s===0){await this.plugin.setColorAlias(e,i,""),n();return}if(g&&g.toLowerCase()===i){n();return}let h=await this.plugin.recolorAllInFolder(e,i,g??null);if(h>0)new _.Notice(`Recolored ${h} note${h===1?"":"s"}.`);else if(s===0){let I=this.plugin.getColorAlias(e,i);I&&(await this.plugin.setColorAlias(e,i,""),g&&await this.plugin.setColorAlias(e,g,I))}n()},async g=>{let h=(this.plugin.settings.customPalette??[]).filter(I=>I.toLowerCase()!==g.toLowerCase());return this.plugin.settings.customPalette=h,await this.plugin.saveSettings(),h}).open()};let a=o.createDiv({cls:"stashpad-color-alias-meta"});a.createSpan({cls:"stashpad-color-alias-hex",text:i}),a.createSpan({cls:"stashpad-color-alias-count",text:s===0?"\xB7 unused":`\xB7 ${s} note${s===1?"":"s"}`});let c=o.createEl("input",{type:"text",cls:"stashpad-color-alias-input",attr:{placeholder:"Alias (optional)"}});c.value=this.plugin.getColorAlias(e,i)??"",c.onchange=async()=>{await this.plugin.setColorAlias(e,i,c.value),!c.value.trim()&&s===0&&n()};let l=o.createEl("button",{cls:"stashpad-color-alias-del",text:"\xD7",attr:{title:"Delete alias"}});c.value||(l.style.visibility="hidden"),l.onclick=async()=>{await this.plugin.setColorAlias(e,i,""),s===0?n():(c.value="",l.style.visibility="hidden")}}renderFolderScopeRow(t,e){let i=t.createDiv({cls:"stashpad-folder-row"});i.createSpan({cls:"stashpad-folder-row-label",text:e});let s=i.createSpan({cls:"stashpad-folder-row-state"}),n=i.createDiv({cls:"stashpad-binding-pill"});n.setAttribute("role","switch"),n.setAttribute("tabindex","0");let o=n.createDiv({cls:"stashpad-binding-pill-knob"}),r=()=>(this.plugin.settings.searchExcludedFolders??[]).includes(e),a=()=>{let l=r();n.toggleClass("is-right",l),n.setAttribute("aria-checked",String(l)),o.setText(l?"X":"\u2713"),s.setText(l?"Excluded":"Included"),s.toggleClass("is-excluded",l),n.title=l?"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."},c=async()=>{let l=new Set(this.plugin.settings.searchExcludedFolders??[]);l.has(e)?l.delete(e):l.add(e),this.plugin.settings.searchExcludedFolders=[...l].sort(),a(),await this.plugin.saveSettings()};n.onclick=()=>void c(),n.onkeydown=l=>{(l.key===" "||l.key==="Enter")&&(l.preventDefault(),c())},a()}renderBindingRow(t,e){let i=new _.Setting(t).setName(e.label).setDesc(e.desc),s=()=>this.plugin.settings.bindings[e.id],n,o,r=()=>{},a=I=>{let u=i.controlEl.createDiv({cls:"stashpad-binding-slot"}),f=u.createEl("input",{type:"text"});f.readOnly=!0,f.placeholder="Click & press a key",f.value=ps(s()[I]),f.classList.add("stashpad-binding-input");let C=()=>{f.size=Math.max(3,f.value.length||f.placeholder.length)};C(),f.onclick=()=>{ln(f,async E=>{this.plugin.settings.bindings[e.id][I]=E,f.value=ps(E),C(),await this.plugin.saveSettings(),r()})};let m=u.createEl("button",{cls:"stashpad-binding-clear",text:"\xD7"});return m.title="Clear this slot",m.onclick=async()=>{this.plugin.settings.bindings[e.id][I]="",f.value="",C(),await this.plugin.saveSettings(),r()},f};n=a("primary"),o=a("secondary");let c=i.controlEl.createDiv({cls:"stashpad-binding-pill"});c.setAttribute("role","switch"),c.setAttribute("tabindex","0");let l=c.createDiv({cls:"stashpad-binding-pill-knob"}),p=i.controlEl.createDiv({cls:"stashpad-binding-useboth"}),g=p.createEl("input",{type:"checkbox"});g.title="Use both bindings simultaneously (overrides the L/R toggle)",p.createSpan({text:"Use both"}),g.onchange=async()=>{this.plugin.settings.bindings[e.id].useBoth=g.checked,await this.plugin.saveSettings(),r()},r=()=>{let I=s(),u=!!(I.primary&&I.secondary);g.checked=!!I.useBoth,g.disabled=!u,p.toggleClass("is-disabled",!u);let f=!!I.useBoth&&u;c.toggleClass("is-disabled",!u||f),c.toggleClass("is-right",I.preferRight),c.setAttribute("aria-checked",String(I.preferRight)),c.setAttribute("aria-disabled",String(!u||f)),l.setText(I.preferRight?"R":"L"),c.title=u?f?'Overridden by "Use both"':I.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 I=s();!I.primary||!I.secondary||(this.plugin.settings.bindings[e.id].preferRight=!I.preferRight,r(),await this.plugin.saveSettings())};c.onclick=()=>void h(),c.onkeydown=I=>{(I.key===" "||I.key==="Enter")&&(I.preventDefault(),h())},r()}};var Ee=class{constructor(A,t){this.app=A;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 A=this.detectTrigger();if(!A){this.close();return}this.openFor(A)};this.onBlur=()=>{setTimeout(()=>this.close(),120)};this.onDocEscape=A=>{A.key==="Escape"&&(!this.state||!this.items.length||(A.preventDefault(),A.stopPropagation(),A.stopImmediatePropagation(),this.close()))};this.onKeyDown=A=>{!this.state||!this.items.length||(A.key==="ArrowDown"?(A.preventDefault(),this.activeIdx=(this.activeIdx+1)%this.items.length,this.refreshActive()):A.key==="ArrowUp"?(A.preventDefault(),this.activeIdx=(this.activeIdx-1+this.items.length)%this.items.length,this.refreshActive()):A.key==="Enter"||A.key==="Tab"?(A.preventDefault(),A.stopPropagation(),this.commit()):A.key==="Escape"&&(A.preventDefault(),A.stopPropagation(),A.stopImmediatePropagation(),this.close()))}}attach(){this.ta.addEventListener("input",this.onInput),this.ta.addEventListener("keydown",this.onKeyDown,!0),this.ta.addEventListener("blur",this.onBlur);let A=this.ta.ownerDocument??document;A.addEventListener("keydown",this.onDocEscape,!0),this.vaultListeners.push(()=>A.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 A of this.vaultListeners)A();this.vaultListeners=[]}buildIndex(){if(this.indexBuilt)return;let A=ft().inheritObsidianExclusions,t=A?this.app.vault.getConfig?.("userIgnoreFilters"):void 0;this.fileIndex=this.app.vault.getFiles().filter(i=>!Ys(i.path)&&!zs(i.path)&&!(A&&Vs(i.path,t))).map(i=>{let s=i.extension==="md",n=s?i.basename:i.name,o=s?i.basename:i.name;return{label:n,lower:n.toLowerCase(),insertText:o,file:i}});let e=this.app.metadataCache.getTags?.()??{};this.tagIndex=Object.keys(e).sort((i,s)=>(e[s]||0)-(e[i]||0)),this.indexBuilt=!0}detectTrigger(){let A=this.ta.value,t=this.ta.selectionStart;if(t==null)return null;let e=A.slice(0,t),i=e.match(/\[\[([^\]\[\n]*)$/);if(i){let n=i[1];return{kind:"link",query:n,replaceStart:t-n.length-2,replaceEnd:t}}let s=e.match(/(^|\s)#([A-Za-z0-9_/\-]+)$/);if(s){let n=s[2];return{kind:"tag",query:n,replaceStart:t-n.length-1,replaceEnd:t}}return null}buildItems(A){this.buildIndex();let t=A.query.toLowerCase().trim(),e=t?t.split(/\s+/).filter(Boolean):[],i=s=>{if(!e.length)return!0;for(let n of e)if(!s.includes(n))return!1;return!0};return A.kind==="link"?this.fileIndex.filter(n=>i(n.lower)).slice(0,50).map(n=>({label:n.label,insert:`[[${n.insertText}]]`,subtitle:n.file.path})):this.tagIndex.filter(n=>i(n.toLowerCase())).slice(0,30).map(n=>({label:n,insert:n,subtitle:""}))}openFor(A){if(this.state=A,this.items=this.buildItems(A),this.activeIdx=0,!this.items.length){this.close();return}this.renderPopup(),this.pushScope()}pushScope(){if(this.scope)return;let A=new In.Scope(this.app.scope);A.register([],"Escape",t=>(t.preventDefault(),this.close(),!1)),this.scope=A,this.app.keymap?.pushScope(A)}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 A=this.popupEl;A.empty();for(let t=0;t<this.items.length;t++){let e=this.items[t],i=A.createDiv({cls:"stashpad-composer-suggest-row"});t===this.activeIdx&&i.addClass("is-active"),i.createSpan({cls:"stashpad-composer-suggest-label",text:e.label}),e.subtitle&&i.createSpan({cls:"stashpad-composer-suggest-sub",text:e.subtitle}),i.onmousedown=s=>{s.preventDefault(),this.activeIdx=t,this.commit()}}this.position()}refreshActive(){if(!this.popupEl)return;let A=this.popupEl.children;for(let e=0;e<A.length;e++)A[e].toggleClass("is-active",e===this.activeIdx);let t=A[this.activeIdx];t&&t.scrollIntoView({block:"nearest"})}position(){if(!this.popupEl)return;let A=this.ta.getBoundingClientRect(),t=this.popupEl.offsetHeight||200,e=A.top-t-4,i=A.left;this.popupEl.style.left=`${Math.max(8,i)}px`,this.popupEl.style.top=`${Math.max(8,e)}px`,this.popupEl.style.minWidth=`${Math.min(360,A.width)}px`}commit(){if(!this.state||!this.items.length)return;let A=this.items[this.activeIdx];if(!A)return;let t=this.ta.value.slice(0,this.state.replaceStart),e=this.ta.value.slice(this.state.replaceEnd),i=A.insert;this.ta.value=t+i+e;let s=t.length+i.length;this.ta.setSelectionRange(s,s),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()}};wt();var Si=class extends kt.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 ne}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?.()===gt&&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?.()===gt&&e.tree?.get){let i=e.tree.get(this.displayedId);if(i?.file)return{folder:e.noteFolder,id:this.displayedId,file:i.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,i=this.composerInputEl?.selectionStart??null;this.composerAutocomplete?.detach(),this.composerAutocomplete=null,this.composerInputEl=null,t.empty(),t.addClass("stashpad-detail-root");let s=this.resolveDisplayed();if(!s){this.displayedPath=null;let h=t.createDiv({cls:"stashpad-detail-empty"});(0,kt.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=s.file;this.displayedPath=n.path;let o=this.app.metadataCache.getFileCache(n)?.frontmatter??{},r=t.createDiv({cls:"stashpad-detail-scroll"}),a=r.createDiv({cls:"stashpad-detail-header"}),c=a.createDiv({cls:"stashpad-detail-titlerow"});c.createDiv({cls:"stashpad-detail-title",text:this.titleFor(n)});let l=c.createEl("button",{cls:"stashpad-detail-open-btn",attr:{"aria-label":"Open in Stashpad tab"}});(0,kt.setIcon)(l,"arrow-up-right"),l.title="Open this note in a new Stashpad tab",l.onclick=()=>{this.openInStashpad(s.folder,s.id)};let p=a.createDiv({cls:"stashpad-detail-metarow"});if(s.folder&&p.createSpan({cls:"stashpad-detail-meta-chip",text:s.folder.split("/").pop()||s.folder}),typeof o.color=="string"&&o.color){let h=p.createSpan({cls:"stashpad-detail-meta-color"});h.style.background=o.color,h.title=o.color}if(o.completed===!0&&p.createSpan({cls:"stashpad-detail-meta-chip is-completed",text:"\u2713 completed"}),typeof o.due=="string"||typeof o.due=="number"){let h=Date.parse(String(o.due)),I=Number.isNaN(h)?String(o.due):ae(h,this.plugin.settings);p.createSpan({cls:"stashpad-detail-meta-chip is-due",text:`due ${I}`})}if(Array.isArray(o.tags))for(let h of o.tags.filter(I=>typeof I=="string"))p.createSpan({cls:"stashpad-detail-meta-tag",text:`#${h.replace(/^#/,"")}`});let g=r.createDiv({cls:"stashpad-detail-body"});try{let h=await this.app.vault.cachedRead(n),I=this.stripFrontmatter(h);await kt.MarkdownRenderer.render(this.app,I,g,n.path,this)}catch(h){g.createDiv({cls:"stashpad-detail-error",text:`Couldn't read \`${n.path}\`: ${h.message}`})}if(this.renderFooterMeta(r,n,o,s),this.renderChildren(r,s.folder,s.id),this.renderComposer(t,s),e&&this.composerInputEl&&(this.composerInputEl.focus(),i!=null)){let h=Math.min(i,this.composerInputEl.value.length);try{this.composerInputEl.setSelectionRange(h,h)}catch{}}}renderComposer(t,e){let i=t.createDiv({cls:"stashpad-detail-composer"}),s=i.createEl("textarea",{cls:"stashpad-detail-composer-input",attr:{placeholder:"Add a child note\u2026",rows:"2"}});this.composerInputEl=s,this.composerDraftForId===e.id?s.value=this.composerDraft:(this.composerDraft="",this.composerDraftForId=e.id),s.addEventListener("input",()=>{this.composerDraft=s.value,this.composerDraftForId=e.id}),s.addEventListener("keydown",o=>{if(o.key==="Enter"&&!o.shiftKey&&!o.isComposing){if(this.composerAutocomplete?.isOpen?.())return;o.preventDefault(),this.submitComposer(e)}});let n=i.createEl("button",{cls:"stashpad-detail-composer-send",attr:{"aria-label":"Add child note"}});(0,kt.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 Ee(this.app,s),this.composerAutocomplete.attach()}async submitComposer(t){let e=(this.composerInputEl?.value??"").trim();if(!e)return;let i=this.plugin.lastActiveStashpadLeaf?.view;if(!i||i.getViewType?.()!==gt||typeof i.createNoteUnder!="function"){new kt.Notice("Open a Stashpad view to add notes.");return}try{await i.createNoteUnder(e,t.id)}catch(s){new kt.Notice(`Couldn't add note: ${s.message}`);return}this.composerDraft="",this.composerDraftForId=t.id,this.composerInputEl&&(this.composerInputEl.value=""),await this.render(),setTimeout(()=>this.composerInputEl?.focus(),0)}renderChildren(t,e,i){let s=this.plugin.lastActiveStashpadLeaf?.view;if(!s||s.getViewType?.()!==gt)return;let n=s.tree;if(!n?.getChildren)return;let o=n.getChildren(i);if(!o||o.length===0)return;let r=t.createDiv({cls:"stashpad-detail-children"});r.createDiv({cls:"stashpad-detail-children-header",text:`Children (${o.length})`});let a=r.createDiv({cls:"stashpad-detail-children-list"});for(let c of o)c.file&&this.renderDetailChildRow(a,s,n,e,c,0)}renderDetailChildRow(t,e,i,s,n,o){if(!n.file)return;let r=this.app.metadataCache.getFileCache(n.file)?.frontmatter??{},a=typeof r.color=="string"?r.color:null,c=r.completed===!0,l=i.getChildren(n.id),p=l.length>0,g=`${s}|${n.id}`,h=this.expanded.has(g),I=t.createDiv({cls:"stashpad-detail-child-row"});c&&I.addClass("is-completed"),o>0&&(I.style.paddingLeft=`${o*16}px`),I.draggable=!0,I.dataset.id=n.id,I.addEventListener("dragstart",E=>{E.dataTransfer?.setData("text/plain",n.id),E.dataTransfer&&(E.dataTransfer.effectAllowed="move"),I.addClass("is-dragging")}),I.addEventListener("dragend",()=>I.removeClass("is-dragging")),I.addEventListener("dragover",E=>{E.preventDefault(),E.dataTransfer&&(E.dataTransfer.dropEffect="move");let y=I.getBoundingClientRect(),w=E.clientY-y.top<y.height/2;I.toggleClass("drop-before",w),I.toggleClass("drop-after",!w)}),I.addEventListener("dragleave",()=>{I.removeClass("drop-before"),I.removeClass("drop-after")}),I.addEventListener("drop",E=>{E.preventDefault(),I.removeClass("drop-before"),I.removeClass("drop-after");let y=E.dataTransfer?.getData("text/plain");if(!y||y===n.id)return;let w=I.getBoundingClientRect(),v=E.clientY-w.top<w.height/2;typeof e.reorderToTarget=="function"&&e.reorderToTarget([y],n.id,v?"before":"after")}),I.oncontextmenu=E=>{E.preventDefault();let y=i.get(n.id);y&&typeof e.openNoteMenu=="function"&&e.openNoteMenu(E,y)};let u=I.createSpan({cls:"stashpad-detail-child-toggle"});if(p&&(pi(u,l.length,h),u.onclick=E=>{E.stopPropagation(),this.expanded.has(g)?this.expanded.delete(g):this.expanded.add(g),this.render()}),pe(r,"task")||r.task===!0||r.completed!==void 0){let E=I.createSpan({cls:"stashpad-detail-child-checkbox"});(0,kt.setIcon)(E,c?"check-square":"square"),E.title=c?"Mark not done":"Mark done",E.addEventListener("mousedown",y=>y.stopPropagation()),E.addEventListener("dblclick",y=>{y.preventDefault(),y.stopPropagation()}),E.onclick=y=>{y.preventDefault(),y.stopPropagation();let w=i.get(n.id);w&&typeof e.toggleCompletedForNode=="function"&&e.toggleCompletedForNode(w)}}let C=I.createSpan({cls:"stashpad-detail-child-icon"});(0,kt.setIcon)(C,p?"folder-tree":"file-text"),a&&(C.style.color=a);let m=I.createSpan({cls:"stashpad-detail-child-title",text:this.titleFor(n.file)});if(m.onclick=()=>{e?.navigateTo&&e.navigateTo(n.id)},p&&h)for(let E of l)this.renderDetailChildRow(t,e,i,s,E,o+1)}renderFooterMeta(t,e,i,s){let n=t.createDiv({cls:"stashpad-detail-footer-meta"}),o=[];if(typeof i.author=="string"&&i.author&&o.push({label:"Author",value:this.stripWikiLink(i.author)}),Array.isArray(i.contributors)){let r=i.contributors.filter(a=>typeof a=="string").map(a=>this.stripWikiLink(a));r.length>0&&o.push({label:"Contributors",value:r.join(", ")})}if(typeof i.modified=="string"&&o.push({label:"Modified",value:this.formatTime(i.modified)}),typeof i.created=="string"&&o.push({label:"Created",value:this.formatTime(i.created)}),o.push({label:"Path",value:e.path}),o.push({label:"ID",value:s.id}),o.length===0){n.remove();return}for(let r of o){let a=n.createDiv({cls:"stashpad-detail-meta-line"});a.createSpan({cls:"stashpad-detail-meta-key",text:r.label}),a.createSpan({cls:"stashpad-detail-meta-val",text:r.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)?ae(e,this.plugin.settings):t}async openInStashpad(t,e){try{await this.plugin.activateViewForFolder(t);let i=this.plugin.lastActiveStashpadLeaf?.view;i?.navigateTo&&e!==G&&i.navigateTo(e)}catch(i){new kt.Notice(`Couldn't open: ${i.message}`)}}};async function Di(d){let A=d.workspace.getLeavesOfType(ne);if(A.length>0){d.workspace.revealLeaf(A[0]);return}let t=d.workspace.getRightLeaf(!1);if(!t){new kt.Notice("Stashpad: couldn't open the detail panel.");return}await t.setViewState({type:ne,active:!0}),d.workspace.revealLeaf(t)}var q=require("obsidian");wt();var $t=require("obsidian");wt();function bo(d,A){let t=d.vault.getAbstractFileByPath(A);if(!(t instanceof $t.TFolder))return[];let e=[],i=[t];for(;i.length;){let s=i.pop();for(let n of s.children)n instanceof $t.TFile?n.extension==="md"&&e.push(n):n instanceof $t.TFolder&&(Te.has(n.name)||i.push(n))}return e}var bi=class{constructor(A){this.app=A;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(G,{id:G,parent:null,children:[],file:null,created:""})}setOrderProvider(A){this.orderProvider=A}onChange(A){return this.listeners.add(A),()=>this.listeners.delete(A)}emit(){for(let A of this.listeners)A()}rebuild(A){A!==void 0&&(this.currentFolder=A);let t=this.currentFolder,e=this.byPath,i=this.nodes;this.nodes=new Map,this.byPath=new Map,this.nodes.set(G,{id:G,parent:null,children:[],file:null,created:""});let s=t?bo(this.app,t):this.app.vault.getMarkdownFiles();for(let n of s){let o=this.app.metadataCache.getFileCache(n)?.frontmatter,r=o?.id;if(!r){let c=e.get(n.path),l=c?i.get(c):void 0,p=this.synthetic.get(n.path),g=l??p;g&&(this.nodes.set(g.id,{...g,children:[],file:n}),this.byPath.set(n.path,g.id));continue}if(this.synthetic.delete(n.path),r===G){let c=this.nodes.get(G);c.file=n,c.created=o?.created??"",this.byPath.set(n.path,G);continue}let a=o?.parent??null;a===r&&(a=null),this.nodes.set(r,{id:r,parent:a??G,children:[],file:n,created:o?.created??""}),this.byPath.set(n.path,r)}for(let n of this.nodes.values()){if(n.id===G)continue;let o=n.parent??G;(this.nodes.get(o)??this.nodes.get(G)).children.push(n.id)}for(let n of this.nodes.values())if(n.children.sort((o,r)=>{let a=this.nodes.get(o),c=this.nodes.get(r);return(a.created||"").localeCompare(c.created||"")}),this.orderProvider){let o=this.orderProvider(n.id);if(o.length>0){let r=new Map;o.forEach((a,c)=>r.set(a,c)),n.children.sort((a,c)=>{let l=r.has(a)?r.get(a):1/0,p=r.has(c)?r.get(c):1/0;return l===p?0:l-p})}}this.emit()}insertSynthetic(A){if(!A.file)return;let t=A.file.path;this.synthetic.set(t,A),this.nodes.set(A.id,A),this.byPath.set(t,A.id);let e=A.parent??G,i=this.nodes.get(e);i&&!i.children.includes(A.id)&&i.children.push(A.id),this.emit()}get(A){return this.nodes.get(A)}getRoot(){return this.nodes.get(G)}getChildren(A){let t=this.nodes.get(A);return t?t.children.map(e=>this.nodes.get(e)).filter(e=>!!e):[]}fileBackedCount(){let A=0;for(let t of this.nodes.values())t.file&&A++;return A}pathTo(A){let t=[],e=new Set,i=this.nodes.get(A);for(;i&&i.id!==G&&!e.has(i.id);)e.add(i.id),t.unshift(i),i=i.parent?this.nodes.get(i.parent):void 0;return t}idForPath(A){return this.byPath.get(A)}snapshot(){let A={};for(let t of this.nodes.values())t.id===G||!t.file||(A[t.id]={parent:t.parent===G?null:t.parent,path:t.file.path});return A}hookMetadataCache(A){let t=a=>{let c=this.currentFolder;return c?typeof a!="string"?!1:a===c||a.startsWith(c+"/"):!0},e=!1,i=()=>{e=!0,this.coalesceTimer==null&&(this.coalesceTimer=window.setTimeout(()=>{this.coalesceTimer=null,e&&(e=!1,this.emit(),A())},16))},s=a=>{a instanceof $t.TFile&&t(a.path)&&a.extension==="md"&&(this.applyChange(a),i())},n=a=>{a instanceof $t.TFile&&t(a.path)&&a.extension==="md"&&this.applyChange(a)&&i()},o=a=>{let c=a?.path;typeof c=="string"&&t(c)&&this.applyDelete(c)&&i()},r=(a,c)=>{if(!(a instanceof $t.TFile))return;let l=typeof c=="string"?c:null;!t(a.path)&&!t(l)||this.applyRename(a,l??"")&&i()};return this.app.metadataCache.on("changed",s),this.app.vault.on("create",n),this.app.vault.on("delete",o),this.app.vault.on("rename",r),()=>{this.app.metadataCache.off("changed",s),this.app.vault.off("create",n),this.app.vault.off("delete",o),this.app.vault.off("rename",r),this.coalesceTimer!=null&&(window.clearTimeout(this.coalesceTimer),this.coalesceTimer=null)}}applyChange(A){if(Ie(A.path))return this.byPath.has(A.path)?this.applyDelete(A.path):!1;let t=this.app.metadataCache.getFileCache(A)?.frontmatter,e=t?.id,i=this.byPath.get(A.path);if(!e){if(i){let c=this.nodes.get(i);if(c&&c.file!==A)return c.file=A,!0}return!1}if(this.synthetic.delete(A.path),e===G){let c=this.nodes.get(G),l=t?.created??"",p=!1;return c.file!==A&&(c.file=A,p=!0),c.created!==l&&(c.created=l,p=!0),this.byPath.get(A.path)!==G&&(this.byPath.set(A.path,G),p=!0),p}let s=t?.parent??G,n=t?.created??"";if(!(s===G||this.nodes.has(s)))return this.rebuild(),!0;if(i&&i!==e)return this.rebuild(),!0;let r=this.nodes.get(e);if(!r){let c={id:e,parent:s,children:[],file:A,created:n};return this.nodes.set(e,c),this.byPath.set(A.path,e),this.attachToParent(c),this.resortChildrenOf(s),!0}let a=!1;if(r.file!==A&&(r.file=A,a=!0),r.created!==n&&(r.created=n,this.resortChildrenOf(r.parent??G),a=!0),r.parent!==s){let c=r.parent??G;this.detachFromParent(r),r.parent=s,this.attachToParent(r),this.resortChildrenOf(c),this.resortChildrenOf(s),a=!0}return a}applyDelete(A){let t=this.byPath.get(A);if(!t)return!1;let e=this.nodes.get(t);if(!e)return this.byPath.delete(A),this.synthetic.delete(A),!0;this.detachFromParent(e);let i=this.nodes.get(G);for(let s of e.children){let n=this.nodes.get(s);n&&(n.parent=G,i.children.includes(s)||i.children.push(s))}return e.children.length>0&&this.resortChildrenOf(G),this.nodes.delete(t),this.byPath.delete(A),this.synthetic.delete(A),!0}applyRename(A,t){let e=this.currentFolder,i=!e||t===e||t.startsWith(e+"/"),s=!e||A.path===e||A.path.startsWith(e+"/");if(!i&&!s)return!1;if(i&&!s)return this.applyDelete(t);if(!i&&s)return this.applyChange(A);if(Ie(A.path))return this.byPath.has(t)?this.applyDelete(t):!1;let n=this.byPath.get(t);if(!n)return this.applyChange(A);this.byPath.delete(t),this.byPath.set(A.path,n);let o=this.nodes.get(n);return o&&(o.file=A),!0}detachFromParent(A){let t=this.nodes.get(A.parent??G);if(!t)return;let e=t.children.indexOf(A.id);e>=0&&t.children.splice(e,1)}attachToParent(A){let t=this.nodes.get(A.parent??G);t||(t=this.nodes.get(G)),t.children.includes(A.id)||t.children.push(A.id)}resortChildrenOf(A){let t=this.nodes.get(A);if(t&&(t.children.sort((e,i)=>{let s=this.nodes.get(e),n=this.nodes.get(i);return(s.created||"").localeCompare(n.created||"")}),this.orderProvider)){let e=this.orderProvider(A);if(e.length>0){let i=new Map;e.forEach((s,n)=>i.set(s,n)),t.children.sort((s,n)=>{let o=i.has(s)?i.get(s):1/0,r=i.has(n)?i.get(n):1/0;return o===r?0:o-r})}}}};var Cs=class{constructor(){this.enabled=!1;this.buckets=new Map}record(A,t){if(!this.enabled)return;let e=this.buckets.get(A);e||(e={count:0,total:0,max:0},this.buckets.set(A,e)),e.count+=1,e.total+=t,t>e.max&&(e.max=t)}time(A,t){if(!this.enabled)return t();let e=performance.now();try{return t()}finally{this.record(A,performance.now()-e)}}async timeAsync(A,t){if(!this.enabled)return t();let e=performance.now();try{return await t()}finally{this.record(A,performance.now()-e)}}reset(){this.buckets.clear()}hasData(){return this.buckets.size>0}report(){let A=[...this.buckets.entries()].map(([e,i])=>({label:e,...i,avg:i.total/i.count})).sort((e,i)=>i.total-e.total);if(A.length===0)return"Stashpad perf: no samples (enable profiling, then use the app).";let t=["**Stashpad performance profile**","","| label | count | total (ms) | avg (ms) | max (ms) |","| --- | ---: | ---: | ---: | ---: |"];for(let e of A)t.push(`| \`${e.label}\` | ${e.count} | ${e.total.toFixed(0)} | ${e.avg.toFixed(1)} | ${e.max.toFixed(0)} |`);return t.join(` +`)}},St=new Cs;var un=".stashpad-order.json",Ni=class{constructor(A){this.app=A;this.cache=new Map;this.pendingTimers=new Map;this.writeInFlight=new Map}async load(A){if(this.cache.has(A))return this.cache.get(A);let t=`${A}/${un}`,e=this.app.vault.adapter,i={};try{if(await e.exists(t)){let s=await e.read(t),n=JSON.parse(s);if(n&&typeof n=="object"&&!Array.isArray(n))for(let[o,r]of Object.entries(n))Array.isArray(r)&&r.every(a=>typeof a=="string")&&(i[o]=r)}}catch(s){console.warn("Stashpad: order load failed",s)}return this.cache.set(A,i),i}async save(A){this.scheduleWrite(A)}async flush(A){let t=this.pendingTimers.get(A);t!=null&&(window.clearTimeout(t),this.pendingTimers.delete(A)),await this.writeNow(A)}scheduleWrite(A){let t=this.pendingTimers.get(A);t!=null&&window.clearTimeout(t);let e=window.setTimeout(()=>{this.pendingTimers.delete(A),this.writeNow(A)},150);this.pendingTimers.set(A,e)}async writeNow(A){let e=(this.writeInFlight.get(A)??Promise.resolve()).then(()=>this.doWrite(A));this.writeInFlight.set(A,e);try{await e}finally{this.writeInFlight.get(A)===e&&this.writeInFlight.delete(A)}}async doWrite(A){let t=this.cache.get(A)??{},e={};for(let[n,o]of Object.entries(t))o.length>0&&(e[n]=o);this.cache.set(A,e);let i=`${A}/${un}`,s=this.app.vault.adapter;try{if(Object.keys(e).length===0)try{await s.remove(i)}catch{}else await s.write(i,JSON.stringify(e,null,2))}catch(n){console.warn("Stashpad: order save failed",n)}}getOrder(A,t){return this.cache.get(A)?.[t]?.slice()??[]}setOrder(A,t,e){let i=this.cache.get(A)??{};i[t]=e.slice(),this.cache.set(A,i)}appendChild(A,t,e){let i=this.cache.get(A)??{},s=i[t]??[];s.includes(e)||s.push(e),i[t]=s,this.cache.set(A,i)}removeChild(A,t){let e=this.cache.get(A);if(e)for(let i of Object.values(e)){let s=i.indexOf(t);s>=0&&i.splice(s,1)}}invalidate(A){this.cache.delete(A)}};var _e={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"},Bs=["manual","created-asc","created-desc","modified-asc","modified-desc","title-az","title-za"],No=new Set(Bs),fn=".stashpad-sort.json",xi=class{constructor(A){this.app=A;this.cache=new Map;this.pendingTimers=new Map;this.writeInFlight=new Map}async load(A){if(this.cache.has(A))return this.cache.get(A);let t=`${A}/${fn}`,e=this.app.vault.adapter,i={};try{if(await e.exists(t)){let s=JSON.parse(await e.read(t));if(s&&typeof s=="object"&&!Array.isArray(s))for(let[n,o]of Object.entries(s))typeof o=="string"&&No.has(o)&&(i[n]=o)}}catch(s){console.warn("Stashpad: sort load failed",s)}return this.cache.set(A,i),i}async save(A){this.scheduleWrite(A)}async flush(A){let t=this.pendingTimers.get(A);t!=null&&(window.clearTimeout(t),this.pendingTimers.delete(A)),await this.writeNow(A)}scheduleWrite(A){let t=this.pendingTimers.get(A);t!=null&&window.clearTimeout(t);let e=window.setTimeout(()=>{this.pendingTimers.delete(A),this.writeNow(A)},150);this.pendingTimers.set(A,e)}async writeNow(A){let e=(this.writeInFlight.get(A)??Promise.resolve()).then(()=>this.doWrite(A));this.writeInFlight.set(A,e);try{await e}finally{this.writeInFlight.get(A)===e&&this.writeInFlight.delete(A)}}async doWrite(A){let t=this.cache.get(A)??{},e=`${A}/${fn}`,i=this.app.vault.adapter;try{if(Object.keys(t).length===0)try{await i.remove(e)}catch{}else await i.write(e,JSON.stringify(t,null,2))}catch(s){console.warn("Stashpad: sort save failed",s)}}getMode(A,t){return this.cache.get(A)?.[t]??"manual"}setMode(A,t,e){let i=this.cache.get(A)??{};e==="manual"?delete i[t]:i[t]=e,this.cache.set(A,i)}removeParent(A,t){let e=this.cache.get(A);e&&delete e[t]}invalidate(A){this.cache.delete(A)}};wt();var _t="parentLink",ye="children";var Ti=class Ti{constructor(A,t){this.app=A;this.getTree=t;this.pending=new Set;this.timer=null;this.activityListeners=new Set;this.errorListeners=new Set}onActivity(A){return this.activityListeners.add(A),()=>this.activityListeners.delete(A)}emitActivity(){let A=this.pending.size;for(let t of this.activityListeners)try{t(A)}catch(e){console.warn("[Stashpad] fmSync activity listener failed",e)}}schedule(A){if(!A||!ft().writeRecoveryLinks)return;let t=this.pending.size;this.pending.add(A),this.pending.size!==t&&this.emitActivity(),this.kick()}scheduleParentChange(A,t,e){this.schedule(A),t&&this.schedule(t),this.schedule(e)}scheduleSubtree(A){let t=this.getTree(),e=i=>{this.schedule(i);for(let s of t.getChildren(i))e(s.id)};e(A)}scheduleParentOfDeleted(A){A&&this.schedule(A)}async flush(){for(this.timer!=null&&(window.clearTimeout(this.timer),this.timer=null);this.pending.size>0;){let A=this.pending.values().next().value;if(A===void 0)break;this.pending.delete(A),this.emitActivity(),await this.syncOne(A)}}pendingCount(){return this.pending.size}onError(A){return this.errorListeners.add(A),()=>this.errorListeners.delete(A)}emitError(A,t){for(let e of this.errorListeners)try{e(A,t)}catch(i){console.warn("[Stashpad] fmSync error listener failed",i)}}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(),Ti.PACING_MS))}async tick(){this.timer=null;let A=this.pending.values().next().value;if(A!==void 0){this.pending.delete(A),this.emitActivity();try{await this.syncOne(A)}catch(t){console.warn("[Stashpad] frontmatter sync tick failed",t)}this.pending.size>0&&this.kick()}}wouldWrite(A){let e=this.getTree().get(A);if(!e||!e.file)return!1;let i=this.computeParentLink(e),s=this.computeChildrenLinks(e),n=this.app.metadataCache.getFileCache(e.file)?.frontmatter,o=n&&typeof n[_t]=="string"?n[_t]:null,r=n?.[ye],a=Array.isArray(r)?r.filter(c=>typeof c=="string"):[];if((o??null)!==(i??null)||a.length!==s.length)return!0;for(let c=0;c<a.length;c++)if(a[c]!==s[c])return!0;return!1}async syncOne(A){let e=this.getTree().get(A);if(!e||!e.file||!this.wouldWrite(A))return;let i=this.computeParentLink(e),s=this.computeChildrenLinks(e);try{await St.timeAsync("write.fmSync",()=>this.app.fileManager.processFrontMatter(e.file,n=>{i?n[_t]=i:delete n[_t],s.length>0?n[ye]=s:delete n[ye]}))}catch(n){console.warn("[Stashpad] frontmatter sync failed",e.file?.path,n),this.emitError(e.file.path,n)}}computeParentLink(A){if(A.id===G)return null;let t=this.getTree();if(!A.parent||A.parent===G){let i=t.getRoot();return i&&i.id!==A.id&&i.file?Mi(i.file.path):null}let e=t.get(A.parent);return e?.file?Mi(e.file.path):null}computeChildrenLinks(A){return this.getTree().getChildren(A.id).filter(e=>!!e.file).map(e=>Mi(e.file.path))}};Ti.PACING_MS=100;var Hi=Ti;async function we(d,A){let t=A.endsWith("/")?A:A+"/",e=new Map,i=new Map;for(let c of d.vault.getMarkdownFiles()){if(c.path!==A&&!c.path.startsWith(t))continue;let l=d.metadataCache.getFileCache(c)?.frontmatter,p=typeof l?.id=="string"?l.id:null;if(!p)continue;let g=typeof l?.parent=="string"?l.parent:G;e.set(p,{file:c,id:p,parent:g});let h=i.get(g)??[];h.push(p),i.set(g,h)}let s=c=>Mi(c.file.path),n=c=>{if(c.id===G)return null;if(c.parent===G||!c.parent){let p=e.get(G);return p?s(p):null}let l=e.get(c.parent);return l?s(l):null},o=c=>{let l=i.get(c.id)??[],p=[];for(let g of l){let h=e.get(g);h&&p.push(s(h))}return p},r=0,a=0;for(let c of e.values()){r+=1;let l=n(c),p=o(c),g=d.metadataCache.getFileCache(c.file)?.frontmatter,h=g&&typeof g[_t]=="string"?g[_t]:null,I=g?.[ye],u=Array.isArray(I)?I.filter(m=>typeof m=="string"):[],f=(h??null)===(l??null),C=u.length===p.length&&u.every((m,E)=>m===p[E]);if(!(f&&C))try{await d.fileManager.processFrontMatter(c.file,m=>{l?m[_t]=l:delete m[_t],p.length>0?m[ye]=p:delete m[ye]}),a+=1,await new Promise(m=>setTimeout(m,50))}catch(m){console.warn("[Stashpad] rebootstrap fm sync failed",c.file.path,m)}}return{checked:r,written:a}}function Mi(d){return`[[${d.replace(/\.md$/i,"")}]]`}Rt();Be();var Ui=class{constructor(A,t){this.tree=A;this.log=t}async sweep(A){let t=await this.log.readState(),e=this.tree.snapshot(),i=n=>{if(!A)return!0;let o=A.replace(/\/+$/,"");return n===o||n.startsWith(o+"/")};for(let[n,o]of Object.entries(e)){let r=t[n];r?r.parent!==o.parent?await this.log.append({type:"parent_change",id:n,payload:{from:r.parent,to:o.parent}}):r.path!==o.path&&await this.log.append({type:"rename",id:n,payload:{from:r.path,to:o.path}}):await this.log.append({type:"create",id:n,payload:{path:o.path,parent:o.parent}})}for(let[n,o]of Object.entries(t))!e[n]&&i(o.path)&&await this.log.append({type:"missing",id:n,payload:{lastPath:o.path}});let s={};for(let[n,o]of Object.entries(t))i(o.path)||(s[n]=o);for(let[n,o]of Object.entries(e))s[n]=o;await this.log.writeState(s)}};var ht=require("obsidian");wt();as();function ms(d){let A=d.trim().toLowerCase();if(!A)return null;let t=Date.now(),e=I=>(0,ht.moment)(I).startOf("day").valueOf(),i=/\b(\d{1,2})(?::(\d{2}))?\s*(am|pm)?\b/,s=0,n=!1,o=A,r=i.exec(A);if(r&&(r[3]||r[2])){let I=parseInt(r[1],10),u=r[2]?parseInt(r[2],10):0,f=r[3];f==="pm"&&I<12&&(I+=12),f==="am"&&I===12&&(I=0),I>=0&&I<24&&u>=0&&u<60&&(s=(I*3600+u*60)*1e3,n=!0,o=A.replace(r[0]," ").replace(/\s+/g," ").trim())}let a=I=>n?I+s:I;if(o===""||o==="today")return a(e(t));if(o==="yesterday")return a(e(t)-864e5);if(o==="tomorrow")return a(e(t)+864e5);let c=["sunday","monday","tuesday","wednesday","thursday","friday","saturday"],l=["sun","mon","tue","wed","thu","fri","sat"],p=c.indexOf(o)>=0?c.indexOf(o):l.indexOf(o);if(p>=0){let I=(0,ht.moment)().startOf("day"),f=(I.day()-p+7)%7;return a(I.subtract(f,"days").valueOf())}let g=/^(\d+)\s*([dwmy])$/.exec(o);if(g){let I=parseInt(g[1],10),u={d:"days",w:"weeks",m:"months",y:"years"}[g[2]];return a((0,ht.moment)().subtract(I,u).startOf("day").valueOf())}let h=(0,ht.moment)(o,["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 Cn(d){let A={text:[],filters:{}},t=(d||"").trim();if(!t)return A;let e=/\b(in|before|after|on):\s*(?:\[([^\]]*)\]|([^]*?)(?=\s+(?:in|before|after|on):|$))/gi,i=t,s;for(;(s=e.exec(t))!=null;){let n=s[1].toLowerCase(),o=(s[2]!==void 0?s[2]:s[3]??"").trim();if(o){if(n==="in")A.filters.in=o.toLowerCase();else if(n==="before"){let r=ms(o);r!=null&&(A.filters.before=r)}else if(n==="after"){let r=ms(o);r!=null&&(A.filters.after=r)}else if(n==="on"){let r=ms(o);if(r!=null)if(/\b\d{1,2}:\d{2}\b|\b\d{1,2}\s*(?:am|pm)\b/i.test(o))A.filters.on={start:r-6e4,end:r+6e4};else{let c=(0,ht.moment)(r).startOf("day").valueOf();A.filters.on={start:c,end:c+864e5}}}i=i.replace(s[0]," ")}}for(let n of i.split(/\s+/))n&&A.text.push(n.toLowerCase());return A}var Ot=class d extends ht.SuggestModal{constructor(t,e,i,s){super(t);this.tree=e;this.titleFn=i;this.opts=s;this.notes=[];this.pendingCleanups=[];this.crossFolderIndex=null;this.whenBuilderEl=null;this.whenMode="on";this.whenSingleText="";this.whenBetweenEndText="";this.setPlaceholder(s.placeholder??(s.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{}}try{this.opts.onClose?.()}catch{}}loadAll(){let t=this.tree.getRoot(),e=t.file?.parent?.name?.trim()??"",i=e?`Home \u2014 ${e}`:"Home",s=(n,o)=>{let r=this.tree.get(n);r?.file&&n!==G?this.notes.push({node:r,title:`${" ".repeat(o)}${this.titleFn(r)}`,body:""}):r?.file&&n===G&&this.notes.push({node:r,title:i,body:""});for(let a of this.tree.getChildren(n))s(a.id,o+1)};t.file&&this.notes.push({node:t,title:i,body:""});for(let n of this.tree.getChildren(G))s(n.id,1);for(let n of this.notes)n.node?.file&&this.app.vault.cachedRead(n.node.file).then(o=>{n.body=this.stripFm(o)});if(this.opts.crossFolderNotes){let n=this.opts.crossFolderNotes();for(let o of n)this.notes.push({node:null,title:o.title,body:o.body,cross:o});for(let o of this.notes)!o.cross||o.body||o.cross.file&&this.app.vault.cachedRead(o.cross.file).then(r=>{o.body=this.stripFm(r)})}}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(),i=Cn(t),s=i.text;console.log("[Stashpad] search query parsed",{query:t,text:i.text,filters:i.filters});let n=C=>{if(!s.length)return!0;for(let m of s)if(!C.includes(m))return!1;return!0},o=null,r=null;if(i.filters.in){let C=i.filters.in.split(/\s+/).filter(Boolean);o=new Set,r=new Map;let m=w=>C.every(v=>w.toLowerCase().includes(v)),E=w=>{if(!o.has(w)){o.add(w);for(let v of this.tree.getChildren(w))E(v.id)}};for(let w of this.notes)!w.node||w.cross||m(w.title)&&E(w.node.id);let y=new Map;for(let w of this.notes){if(!w.cross)continue;let v=y.get(w.cross.folder)??[];v.push(w),y.set(w.cross.folder,v)}for(let[w,v]of y){let D=new Map;for(let b of v){let Q=b.cross?.parentId??null;if(!Q)continue;let H=D.get(Q)??[];H.push(b.cross.id),D.set(Q,H)}let L=new Set;r.set(w,L);let S=b=>{if(!L.has(b)){L.add(b);for(let Q of D.get(b)??[])S(Q)}};for(let b of v)m(b.title)&&S(b.cross.id)}}let a=C=>{let m=i.filters;if(o||r)if(C.cross){let E=r?.get(C.cross.folder);if(!E||!E.has(C.cross.id))return!1}else if(C.node){if(!o||!o.has(C.node.id))return!1}else return!1;if(m.before||m.after||m.on){let E=this.createdMsFor(C);if(E==null||m.before!=null&&E>=m.before||m.after!=null&&E<=m.after||m.on&&(E<m.on.start||E>=m.on.end))return!1}return!0},c=C=>n(C.toLowerCase()),l=this.notes.filter(C=>!C.cross),p=this.notes.filter(C=>C.cross),g=(C,m)=>({id:C.cross?`cross:${C.cross.id}`:C.node.id,label:C.title,node:C.node,kind:"note",bodyPreview:this.previewFromBody(C.body,m),matchLine:m,crossFolder:C.cross?.folder,crossFile:C.cross?.file}),h=C=>{let m=[];for(let E of C)if(a(E))if(this.opts.mode==="search"){if(!e){m.push(g(E,-1));continue}let y=n(E.title.toLowerCase()),w=E.body.split(/\r?\n/),v=[];for(let L=0;L<w.length;L++)c(w[L])&&v.push(L);let D=v.length>0||n(E.body.toLowerCase());if(!y&&!D)continue;if(v.length===0)m.push(g(E,-1));else{let L=[],S=-100;for(let Q of v)Q-S>5&&L.push(Q),S=Q;let b=5;for(let Q of L.slice(0,b))m.push(g(E,Q))}}else{if(e&&!n(E.title.toLowerCase())&&!n(E.body.toLowerCase()))continue;m.push(g(E,-1))}return m},I=h(l),u=[...I];if(this.opts.mode==="search"?e?!0:I.length<10:!!e){let C=h(p);this.opts.mode==="search"&&!e&&(u.length=Math.min(u.length,50)),u.push(...C)}if(this.opts.folderResults){let C=this.opts.folderResults(),m={id:"__folder_picker__",label:"Open folder in a new tab\u2026",node:null,kind:"folder-open"};C.length>0&&(e?C.some(E=>{let y=E.split("/").pop()??E;return n(`${E.toLowerCase()} ${y.toLowerCase()}`)})&&u.push(m):u.unshift(m))}if(this.opts.allowCreate&&e&&!u.some(C=>C.label.trim().toLowerCase()===e)&&u.push({id:"__create__",label:`Create new: "${t}"`,node:null,kind:"create"}),i.text.join("").length>=3){let C=E=>E.kind==="note"&&(E.id===G||E.id===`cross:${G}`)&&n(E.label.toLowerCase()),m=u.filter(C);if(m.length>0){let E=u.filter(y=>!C(y));u.splice(0,u.length,...m,...E)}}return u}previewFromBody(t,e){let i=t.split(/\r?\n/);if(e<0)return i.filter(r=>r.trim().length>0).slice(0,3).join(` `);let s=Math.max(0,e-2),n=Math.min(i.length,e+3);return i.slice(s,n).filter(o=>o.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 i=e.createDiv({cls:"stashpad-suggest-body"}),s=this.notes.find(g=>t.crossFolder?g.cross?.id===t.id.replace(/^cross:/,""):g.node?.id===t.id),n=sn(this.inputEl?.value??"").text,o=this.firstLineOfBody(s?.body??"")||t.label.trim(),a=i.createDiv({cls:"stashpad-suggest-title"});this.highlightInto(a,o,n);let r=t.crossFolder??this.opts.localFolder??null;if(t.bodyPreview&&t.matchLine!=null&&t.matchLine>=0){let g=i.createDiv({cls:"stashpad-suggest-preview stashpad-suggest-snippet"});this.highlightInto(g,t.bodyPreview,n)}let c="";if(t.crossFolder?c=s?.cross?.parentBlurb??"":c=this.parentBlurbFor(t.node),c){let g=i.createDiv({cls:"stashpad-suggest-preview"});g.appendText("Parent: "),this.highlightInto(g,c,n)}let l=t.crossFolder?this.buildCrossBreadcrumb(t):this.buildLocalBreadcrumb(t.node),d=t.crossFolder??this.opts.localFolder??null;if(d||l){let g=i.createDiv({cls:"stashpad-suggest-breadcrumb"}),u=[d?d.split("/").pop()||d:"",l].filter(f=>f&&f.length>0).join(" \u203A ");u&&g.setText(u)}let I=s?this.createdMsFor(s):null;if(I!=null||r){let g=e.createDiv({cls:"stashpad-suggest-rail"});if(I!=null){let p=g.createDiv({cls:"stashpad-suggest-time"});p.setText(this.formatRelativeTime(I)),p.title=(0,dt.moment)(I).format("YYYY-MM-DD HH:mm")}r&&g.createDiv({cls:"stashpad-suggest-folder-badge",text:r.split("/").pop()||r})}}formatRelativeTime(t){let e=(0,dt.moment)(t),i=(0,dt.moment)().startOf("day").diff((0,dt.moment)(t).startOf("day"),"days");return i===0?e.format("h:mm a"):i===1?"yesterday":i>1&&i<7?`${i}d ago`:i>=7&&i<30?`${Math.floor(i/7)}w ago`:i>=30&&i<365?e.format("MMM D"):e.format("MMM D, YYYY")}highlightInto(t,e,i){if(!e)return;let s=i.filter(c=>c&&c.length>0);if(!s.length){t.appendText(e);return}let n=e.toLowerCase(),o=[];for(let c of s){let l=0;for(;(l=n.indexOf(c,l))!==-1;)o.push([l,l+c.length]),l+=c.length}if(!o.length){t.appendText(e);return}o.sort((c,l)=>c[0]-l[0]);let a=[];for(let c of o){let l=a[a.length-1];l&&c[0]<=l[1]?l[1]=Math.max(l[1],c[1]):a.push([c[0],c[1]])}let r=0;for(let[c,l]of a)c>r&&t.appendText(e.slice(r,c)),t.createSpan({cls:"stashpad-suggest-match",text:e.slice(c,l)}),r=l;r<e.length&&t.appendText(e.slice(r))}buildLocalBreadcrumb(t){if(!t||!t.parent||t.parent===G)return"";let e=[],i=new Set([t.id]),s=this.tree.get(t.parent);for(;s&&s.id!==G&&!i.has(s.id);)i.add(s.id),e.unshift(this.titleFn(s)),s=s.parent&&s.parent!==G?this.tree.get(s.parent):null;return e.join(" \u203A ")}buildCrossBreadcrumb(t){if(!t.crossFolder)return"";if(!this.crossFolderIndex){this.crossFolderIndex=new Map;for(let r of this.notes){if(!r.cross)continue;let c=this.crossFolderIndex.get(r.cross.folder);c||(c=new Map,this.crossFolderIndex.set(r.cross.folder,c)),c.set(r.cross.id,r.cross)}}let e=this.crossFolderIndex.get(t.crossFolder);if(!e)return"";let i=t.id.replace(/^cross:/,""),s=e.get(i);if(!s)return"";let n=[],o=new Set([s.id]),a=s.parentId?e.get(s.parentId):null;for(;a&&!o.has(a.id);)o.add(a.id),n.unshift(a.title),a=a.parentId?e.get(a.parentId):null;return n.join(" \u203A ")}firstLineOfBody(t){if(!t)return"";let e=t.split(/\r?\n/);for(let i of e){let s=i.trim();if(s)return s}return""}parentBlurbFor(t){if(!t||!t.parent||t.parent===G)return"";let e=this.tree.get(t.parent);if(!e||!e.file)return"";let i=this.notes.find(s=>s.node?.id===e.id);return i?this.firstLineOfBody(i.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",c=>{if(c.key==="["){c.preventDefault();let l=t.selectionStart??t.value.length,d=t.selectionEnd??l,I=t.value.slice(0,l),g=t.value.slice(l,d),p=t.value.slice(d);t.value=`${I}[${g}]${p}`;let u=l+1+g.length;t.setSelectionRange(u,u),t.dispatchEvent(new Event("input",{bubbles:!0}));return}if(c.key==="]"){let l=t.selectionStart??-1;l>=0&&t.value[l]==="]"&&(c.preventDefault(),t.setSelectionRange(l+1,l+1));return}if(c.key==="Backspace"&&!c.metaKey&&!c.ctrlKey&&!c.altKey&&t.selectionStart===t.selectionEnd){let l=t.selectionStart??-1;if(l>0&&t.value[l-1]==="["&&t.value[l]==="]"){c.preventDefault();let d=t.value.slice(0,l-1),I=t.value.slice(l+1);t.value=`${d}${I}`,t.setSelectionRange(l-1,l-1),t.dispatchEvent(new Event("input",{bubbles:!0}))}}});let i=document.createElement("div");i.className="stashpad-search-filter-row";let s=document.createElement("span");s.className="stashpad-search-filter-label",s.textContent="Filters:",i.appendChild(s);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",c=>{c.preventDefault()}),n.addEventListener("click",c=>{c.preventDefault(),this.appendFilterToInput(t,"in","")}),n.addEventListener("keydown",c=>{(c.key==="Enter"||c.key===" ")&&(c.preventDefault(),c.stopPropagation(),n.click())}),i.appendChild(n);let o=document.createElement("button");o.className="stashpad-search-filter-chip stashpad-search-filter-when",o.type="button",o.textContent="when:[date / day / timeframe]",o.title="Open the time-filter builder (Before / On / After / Between).",o.addEventListener("mousedown",c=>{c.preventDefault()}),o.addEventListener("click",c=>{c.preventDefault(),this.toggleWhenBuilder(t,i)}),o.addEventListener("keydown",c=>{(c.key==="Enter"||c.key===" ")&&(c.preventDefault(),c.stopPropagation(),o.click())}),i.appendChild(o),e.parentElement?.insertBefore(i,e);let a=new dt.Scope(this.scope),r=c=>{let l=document.activeElement;return l?.classList?.contains("stashpad-search-filter-chip")?(c.preventDefault(),l.click(),!1):c.key==="Enter"&&!c.isComposing?(c.preventDefault(),this.selectActiveSuggestion?.(c),!1):!0};a.register([],"Enter",r),a.register([]," ",r),a.register(["Mod"],"f",c=>{c.preventDefault();let l=this.inputEl;return l&&(l.focus(),l.select()),!1}),a.register([],"Tab",c=>{let l=this.modalEl,d=this.inputEl;if(!l)return!0;let I=Array.from(l.querySelectorAll('input, button, select, textarea, a[href], [tabindex]:not([tabindex="-1"])')).filter(u=>!u.hasAttribute("disabled")&&u.tabIndex!==-1&&u.offsetParent!==null);if(I.length===0)return!0;let g=document.activeElement,p=g?I.indexOf(g):-1;if(c.shiftKey){if(p<=0)return c.preventDefault(),I[I.length-1].focus(),!1}else if(p===I.length-1)return c.preventDefault(),(d??I[0]).focus(),!1;return!0}),this.app.keymap?.pushScope(a),this.pendingCleanups.push(()=>{try{this.app.keymap?.popScope(a)}catch{}})}appendFilterToInput(t,e,i){let s=t.value,o=`${s.length>0&&!/\s$/.test(s)?" ":""}${e}: [`,a="]",r=i;t.value=`${s}${o}${r}${a}`;let c=s.length+o.length+r.length;if(t.setSelectionRange(c,c+0),!r){let l=s.length+o.length;t.setSelectionRange(l,l)}t.focus(),t.dispatchEvent(new Event("input",{bubbles:!0}))}toggleWhenBuilder(t,e){let i=this.modalEl;if(this.whenBuilderEl){this.whenBuilderEl.remove(),this.whenBuilderEl=null,i?.removeClass("is-when-builder-open");return}i?.addClass("is-when-builder-open");let s=document.createElement("div");s.className="stashpad-when-builder";let n=document.createElement("div");n.className="stashpad-when-tabs";let o=[{id:"before",label:"Before"},{id:"on",label:"On"},{id:"after",label:"After"},{id:"between",label:"Between"}],a={};for(let u of o){let f=document.createElement("button");f.type="button",f.className="stashpad-when-tab",f.textContent=u.label,this.whenMode===u.id&&f.addClass("is-active"),f.addEventListener("mousedown",B=>B.preventDefault()),f.addEventListener("click",B=>{if(B.preventDefault(),this.whenMode===u.id)return;let Q=this.whenMode;Q!=="between"&&u.id==="between"?(this.whenBetweenEndText="",this.whenBetweenEndDate="",this.whenBetweenEndTime=""):Q==="between"&&u.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=u.id;for(let E in a)a[E].toggleClass("is-active",E===u.id);p()}),a[u.id]=f,n.appendChild(f)}s.appendChild(n);let r=document.createElement("div");r.className="stashpad-when-body",s.appendChild(r);let c=(u,f,B="single")=>{let Q=(0,dt.moment)().format("YYYY-MM-DD"),E=!f||f===Q;if(B==="betweenStart")return"00:00";if(B==="betweenEnd")return"23:59";switch(u){case"after":return"00:00";case"on":return E?(0,dt.moment)().format("HH:mm"):"23:59";case"before":return E?(0,dt.moment)().format("HH:mm"):"23:59";default:return"23:59"}},l=(u,f)=>{u.addEventListener("keydown",B=>{B.key==="Enter"?(B.preventDefault(),B.stopPropagation(),f()):B.key==="Escape"&&(B.preventDefault(),B.stopPropagation(),this.closeWhenBuilder())})},d=(u,f)=>{let B=u.selectionStart??u.value.length,Q=u.selectionEnd??u.value.length,y=`${B>0&&!/\s$/.test(u.value.slice(0,B))?" ":""}${f}`,v=u.value.slice(0,B)+y+u.value.slice(Q);u.value=v;let k=B+y.length;u.setSelectionRange(k,k),u.focus(),u.dispatchEvent(new Event("input",{bubbles:!0}))},I=(u,f)=>{let Q=u.slice(0,f).match(/(\d{4}-\d{2}-\d{2})(?!.*\d{4}-\d{2}-\d{2})/);return Q?Q[1]:null},g=(u,f,B,Q)=>{let E=r.createDiv({cls:"stashpad-when-input-wrap has-icons"}),y=E.createDiv({cls:"stashpad-when-icon-slot"}),v=y.createEl("button",{cls:"stashpad-when-icon stashpad-when-icon-cal"});v.type="button",v.title="Pick date",(0,dt.setIcon)(v,"calendar-days");let k=y.createEl("input",{cls:"stashpad-when-native",attr:{type:"date"}});k.tabIndex=-1;let b=E.createDiv({cls:"stashpad-when-icon-slot"}),R=b.createEl("button",{cls:"stashpad-when-icon stashpad-when-icon-clock"});R.type="button",R.title="Pick time",(0,dt.setIcon)(R,"clock");let w=E.createDiv({cls:"stashpad-when-icon-slot"}),D=w.createEl("button",{cls:"stashpad-when-icon stashpad-when-icon-day"});D.type="button",D.title="Pick day",(0,dt.setIcon)(D,"calendar");let m=E.createDiv({cls:"stashpad-when-icon-slot"}),M=m.createEl("button",{cls:"stashpad-when-icon stashpad-when-icon-tf"});M.type="button",M.title="Pick timeframe",(0,dt.setIcon)(M,"history");let _=E.createEl("input",{cls:"stashpad-when-input",attr:{type:"text",placeholder:u}});_.value=f(),_.addEventListener("input",()=>B(_.value));let O=E.createEl("button",{cls:"stashpad-when-clear"});O.type="button",O.textContent="\xD7",O.title="Clear";for(let N of[v,R,D,M,O])N.addEventListener("mousedown",$=>$.preventDefault());let J=null,q=(N,$)=>{J&&J();let V=N.createDiv({cls:"stashpad-when-popover"}),z=new dt.Scope(this.scope),ct=null,gt=st=>{ct=st},nt=!1,at=st=>{!V.contains(st.target)&&st.target!==N&&!N.contains(st.target)&&rt()},rt=()=>{if(!nt){nt=!0,V.remove(),document.removeEventListener("mousedown",at,!0);try{this.app.keymap?.popScope(z)}catch{}J===rt&&(J=null)}};J=rt,z.register([],"Escape",st=>(st.preventDefault(),rt(),!1)),z.register([],"Enter",st=>(st.preventDefault(),ct&&ct(),!1));try{$(V,rt,gt)}catch(st){console.error("[stashpad] popover fill threw:",st),V.remove(),J=null;return}this.app.keymap?.pushScope(z),this.pendingCleanups.push(rt),setTimeout(()=>document.addEventListener("mousedown",at,!0),0)};M.addEventListener("click",N=>{N.preventDefault(),q(m,($,V,z)=>{let ct=this.whenMode==="on",gt=(P,T)=>{if(!ct)return`${P}${T}`;let S={d:"days",w:"weeks",m:"months",y:"years"}[T];return(0,dt.moment)().subtract(P,S).format("YYYY-MM-DD")},nt=$.createDiv({cls:"stashpad-when-pop-row"}),at=[{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 P of at){let T=nt.createEl("button",{cls:"stashpad-when-pop-chip",text:P.label});T.type="button",T.addEventListener("mousedown",S=>S.preventDefault()),T.addEventListener("click",S=>{S.preventDefault(),d(_,gt(P.n,P.unit)),V()})}let rt=$.createDiv({cls:"stashpad-when-pop-row stashpad-when-pop-builder"});rt.createSpan({text:"Last",cls:"stashpad-when-pop-label"});let st=rt.createEl("input",{cls:"stashpad-when-pop-number",attr:{type:"number",min:"1",max:"999",value:"7"}}),Ct=rt.createEl("select",{cls:"stashpad-when-pop-unit"});for(let P of[{v:"d",label:"days"},{v:"w",label:"weeks"},{v:"m",label:"months"},{v:"y",label:"years"}]){let T=Ct.createEl("option",{text:P.label});T.value=P.v}let pt=rt.createEl("button",{cls:"stashpad-when-pop-chip stashpad-when-pop-go",text:"Insert"});pt.type="button";let C=()=>{let P=parseInt(st.value,10);!Number.isFinite(P)||P<1||(d(_,gt(P,Ct.value)),V())};pt.addEventListener("mousedown",P=>P.preventDefault()),pt.addEventListener("click",P=>{P.preventDefault(),C()}),z(C),st.focus(),st.select()})});let j=(N,$,V,z,ct)=>{q($,(gt,nt,at)=>{si(gt,{seedH:V,seedM:z,seedPeriod:ct,close:nt,setOnEnter:at,onFinalize:rt=>d(N,Ls(rt))})})};D.addEventListener("click",N=>{N.preventDefault(),q(w,($,V,z)=>{let ct=$.createDiv({cls:"stashpad-when-pop-row"});for(let st of["Today","Yesterday"]){let Ct=ct.createEl("button",{cls:"stashpad-when-pop-chip",text:st});Ct.type="button",Ct.addEventListener("mousedown",pt=>pt.preventDefault()),Ct.addEventListener("click",pt=>{pt.preventDefault(),d(_,st),V()})}let gt=$.createDiv({cls:"stashpad-when-pop-row stashpad-when-pop-days"}),nt=["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],rt=((0,dt.moment)().day()+6)%7;for(let st=0;st<nt.length;st++){let Ct=nt[st],pt=gt.createEl("button",{cls:"stashpad-when-pop-chip",text:Ct.slice(0,3)});pt.type="button",pt.title=Ct,st===rt&&pt.addClass("is-today"),pt.addEventListener("mousedown",C=>C.preventDefault()),pt.addEventListener("click",C=>{if(C.preventDefault(),Q==="betweenEnd"){let P=st,T=(0,dt.moment)().startOf("day"),S=(T.day()+6)%7,F=(P-S+7)%7;F===0&&(F=7);let x=T.clone().add(F,"days").format("YYYY-MM-DD");d(_,x)}else d(_,Ct);V()})}})});let H=(N,$)=>{N.value||(N.value=$);let V=N;if(typeof V.showPicker=="function")try{V.showPicker();return}catch{}N.focus(),N.click()};return v.addEventListener("click",N=>{N.preventDefault(),H(k,(0,dt.moment)().format("YYYY-MM-DD"))}),k.addEventListener("change",()=>{k.value&&d(_,k.value)}),R.addEventListener("click",N=>{N.preventDefault();let $=_.selectionStart??_.value.length,V=I(_.value,$),z=c(this.whenMode,V,Q),[ct,gt]=z.split(":"),nt=parseInt(ct,10),at=parseInt(gt,10),rt=nt%12;rt===0&&(rt=12);let st=nt>=12?"pm":"am";j(_,b,rt,at,st)}),O.addEventListener("click",N=>{N.preventDefault(),_.value="",B(""),_.focus()}),_},p=()=>{if(r.empty(),this.whenMode==="between"){let u=g("start (date / day / timeframe)",()=>this.whenSingleText,v=>{this.whenSingleText=v},"betweenStart"),f=g("end (date / day / timeframe)",()=>this.whenBetweenEndText,v=>{this.whenBetweenEndText=v},"betweenEnd"),B=r.createDiv({cls:"stashpad-when-actions"}),Q=B.createEl("button",{cls:"stashpad-when-insert",text:"Insert"});Q.type="button",Q.addEventListener("mousedown",v=>v.preventDefault());let E=()=>{let v=u.value.trim(),k=f.value.trim();v&&this.appendFilterToInput(t,"after",v),k&&this.appendFilterToInput(t,"before",k),this.closeWhenBuilder()};Q.addEventListener("click",v=>{v.preventDefault(),E()});let y=B.createEl("button",{cls:"stashpad-when-cancel",text:"Cancel"});y.type="button",y.addEventListener("mousedown",v=>v.preventDefault()),y.addEventListener("click",v=>{v.preventDefault(),this.closeWhenBuilder()}),l(u,E),l(f,E),u.focus(),u.setSelectionRange(u.value.length,u.value.length)}else{let u=g("date / day / timeframe",()=>this.whenSingleText,y=>{this.whenSingleText=y},"single"),f=r.createDiv({cls:"stashpad-when-actions"}),B=f.createEl("button",{cls:"stashpad-when-insert",text:"Insert"});B.type="button",B.addEventListener("mousedown",y=>y.preventDefault());let Q=()=>{let y=u.value.trim();y&&this.appendFilterToInput(t,this.whenMode,y),this.closeWhenBuilder()};B.addEventListener("click",y=>{y.preventDefault(),Q()});let E=f.createEl("button",{cls:"stashpad-when-cancel",text:"Cancel"});E.type="button",E.addEventListener("mousedown",y=>y.preventDefault()),E.addEventListener("click",y=>{y.preventDefault(),this.closeWhenBuilder()}),l(u,Q),u.focus(),u.setSelectionRange(u.value.length,u.value.length)}};p(),e.parentElement?.insertBefore(s,e.nextSibling),this.whenBuilderEl=s}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 i=this.inputEl?.value??"",s=!1,n=I=>{s=!0;let g=I.split("/").pop()??I;this.opts.onPick({id:`folder:${I}`,label:`Open folder \u201C${g}\u201D in a new tab`,node:null,kind:"folder-open",folder:I})},o=new hs(this.app,e,n),a=o.onClose.bind(o),r=this.tree,c=this.titleFn,l=this.opts,d=this.app;o.onClose=()=>{if(a(),!s){let I=new h(d,r,c,l);I.open(),setTimeout(()=>{let g=I.inputEl;g&&(i&&(g.value=i,g.dispatchEvent(new Event("input",{bubbles:!0}))),g.focus(),g.setSelectionRange(g.value.length,g.value.length))},0)}},o.open();return}this.opts.onPick(t)}},hs=class extends dt.FuzzySuggestModal{constructor(t,e,i){super(t);this.folders=e;this.onChosen=i;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)}};Mt();var gs=require("obsidian");function go(h,A){return!A||h.metaKey||h.ctrlKey||h.altKey?!1:h.key.toLowerCase()===A.toLowerCase()}function me(h,A){return A?A.includes("+")?Io(h,A):go(h,A):!1}function ot(h,A){if(!A)return!1;let{primary:t,secondary:e,preferRight:i,useBoth:s}=A;return t&&e?s?me(h,t)||me(h,e):i?me(h,e):me(h,t):me(h,t)||me(h,e)}function Di(h){if(!h)return"";let A=gs.Platform.isMacOS??navigator.platform.toLowerCase().includes("mac");return h.split("+").map(t=>{let e=t.trim();return e?e.toLowerCase()==="mod"?A?"Cmd":"Ctrl":e.toLowerCase()==="alt"?A?"Opt":"Alt":e.length===1?e.toUpperCase():e:""}).filter(Boolean).join("+")}function Io(h,A){if(!A)return!1;let t=A.split("+").map(d=>d.trim()).filter(Boolean);if(t.length<2)return!1;let e=t[t.length-1].toLowerCase(),i=new Set(t.slice(0,-1).map(d=>d.toLowerCase())),s=i.has("mod"),n=i.has("ctrl")||i.has("control"),o=i.has("cmd")||i.has("meta")||i.has("command"),a=i.has("alt")||i.has("option"),r=i.has("shift"),l=gs.Platform.isMacOS??navigator.platform.toLowerCase().includes("mac")?h.metaKey:h.ctrlKey;return s&&!l||n&&!h.ctrlKey||o&&!h.metaKey||a!==h.altKey||r!==h.shiftKey||!s&&(!n&&h.ctrlKey||!o&&h.metaKey)?!1:h.key.toLowerCase()===e}var Ae=require("obsidian");Mt();var xt=class xt{constructor(A){this.host=A;this.knownBodies=new Map;this.contribTimers=new Map;this.recentSelfWrites=new Map;this.lastExternalModify=new Map}dispose(){for(let A of this.contribTimers.values())clearTimeout(A);this.contribTimers.clear(),this.knownBodies.clear(),this.recentSelfWrites.clear(),this.lastExternalModify.clear()}currentAuthorLink(){let A=(this.host.plugin.settings.authorName??"").trim(),t=(this.host.plugin.settings.authorId??"").trim();if(!A||!t)return null;let e=A.replace(/[^\w\- ]+/g,"").trim().replace(/\s+/g,"-")||"author",i=`${this.host.noteFolder}/_authors/${e}-${t}.md`,s=A.replace(/[\[\]|]/g,"").trim()||e;return{link:`[[${i}|${s}]]`,path:i,name:A,id:t}}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 A=this.host.noteFolder.replace(/\/+$/,"");return this.host.app.vault.getMarkdownFiles().filter(t=>{let e=t.parent?.path?.replace(/\/+$/,"")??"";if(e!==A&&!e.startsWith(A+"/")||t.path.includes("/_authors/"))return!1;let i=this.host.app.metadataCache.getFileCache(t)?.frontmatter;return typeof i?.id=="string"&&!!i.id})}async pacedFrontmatter(A,t){for(let s=0;s<A.length;s++){let n=this.host.app.vault.getAbstractFileByPath(A[s]);if(n instanceof Ae.TFile){this.recentSelfWrites.set(n.path,Date.now());try{await this.host.app.fileManager.processFrontMatter(n,o=>t(o,A[s]))}catch(o){console.warn("[Stashpad] claim: frontmatter write failed",A[s],o)}}(s+1)%25===0&&await new Promise(o=>setTimeout(o,30))}}async claimAuthorship(A){let t=this.currentAuthorLink();if(!t){new Ae.Notice("Set your author name in Stashpad settings first.");return}let e=`-${t.id}`,i=A.scope==="selection"?this.host.getActionTargets().map(I=>I.file).filter(I=>!!I):this.fileBackedNotesInFolder();if(i.length===0){new Ae.Notice(A.scope==="selection"?"No notes selected.":"No notes in this folder.");return}let s=[],n=[];for(let I of i){let g=this.host.app.metadataCache.getFileCache(I)?.frontmatter,p=typeof g?.author=="string"?g.author:"";if(!p.trim()){s.push(I.path);continue}if(p.includes(e)||!A.contributorMode)continue;(Array.isArray(g?.contributors)?g.contributors.filter(f=>typeof f=="string"):[]).some(f=>f.includes(e))||n.push(I.path)}let o=s.length+n.length;if(o===0){new Ae.Notice("Nothing to claim \u2014 those notes are already authored by you.");return}if(A.scope==="folder"){let I=[`Stamp yourself as author on ${s.length} unauthored note(s)`];if(n.length&&I.push(`and as a contributor on ${n.length} already-authored note(s)`),!await new Promise(p=>{new Dt(this.host.app,"Claim authorship",`${I.join(" ")}? -Existing authors are never overwritten. This can be undone.`,"Claim",p).open()}))return}let a=this.host.noteFolder,r=t.link,c=new Set,l=async()=>{await this.pacedFrontmatter(s,(I,g)=>{typeof I.author=="string"&&I.author.trim()||(I.author=r),Array.isArray(I.contributors)&&I.contributors.some(p=>typeof p=="string"&&p.includes(e))&&(I.contributors=I.contributors.filter(p=>!(typeof p=="string"&&p.includes(e))),c.add(g))}),await this.pacedFrontmatter(n,I=>{let g=Array.isArray(I.contributors)?I.contributors.filter(p=>typeof p=="string"):[];g.some(p=>p.includes(e))||g.push(r),I.contributors=g})};this.ensureAuthorFile(t),await l(),this.host.plugin.getUndoStack(a).push({label:`Claim authorship (${o} note${o===1?"":"s"})`,undo:async()=>{await this.pacedFrontmatter(s,(I,g)=>{if(typeof I.author=="string"&&I.author.includes(e)&&delete I.author,c.has(g)){let p=Array.isArray(I.contributors)?I.contributors.filter(u=>typeof u=="string"):[];p.some(u=>u.includes(e))||p.push(r),I.contributors=p}}),await this.pacedFrontmatter(n,I=>{Array.isArray(I.contributors)&&(I.contributors=I.contributors.filter(g=>!(typeof g=="string"&&g.includes(e))))}),this.host.debouncedRender()},redo:async()=>{c.clear(),await l(),this.host.debouncedRender()}});let d=[];s.length&&d.push(`authored ${s.length}`),n.length&&d.push(`contributing to ${n.length}`),new Ae.Notice(`Claimed authorship: ${d.join(", ")}. Undo available.`),this.host.debouncedRender()}async ensureAuthorFile(A){try{A.id&&this.host.plugin.authorRegistry.record({id:A.id,name:A.name});let t=`${this.host.noteFolder}/_authors`;if(await this.host.ensureFolder(t),await this.host.app.vault.adapter.exists(A.path))return;let e=A.id===(this.host.plugin.settings.authorId??"").trim(),i=this.host.plugin.buildAuthorStub({id:A.id,name:A.name,role:e?this.host.plugin.settings.authorRole:void 0,department:e?this.host.plugin.settings.authorDepartment:void 0},new Date().toISOString());await this.host.app.vault.create(A.path,i)}catch(t){console.warn("[Stashpad] ensureAuthorFile failed",t)}}collectAuthorIds(A){let t=new Set,e=i=>{if(typeof i!="string")return null;let s=i.match(/-([a-z0-9]{4,12})(?:\.md)?(?:\||\]\])/i);return s?s[1]:null};for(let i of A){if(!i.file)continue;let s=this.host.app.metadataCache.getFileCache(i.file)?.frontmatter;if(!s)continue;let n=e(s.author);if(n&&t.add(n),Array.isArray(s.contributors))for(let o of s.contributors){let a=e(o);a&&t.add(a)}}return Array.from(t)}pruneContribMaps(){let A=Date.now(),t=xt.EXTERNAL_WRITE_GRACE_MS*20,e=xt.EXTERNAL_QUIESCENCE_MS*12;for(let[i,s]of this.recentSelfWrites)A-s>t&&this.recentSelfWrites.delete(i);for(let[i,s]of this.lastExternalModify)A-s>e&&this.lastExternalModify.delete(i);if(this.knownBodies.size>64)for(let i of this.knownBodies.keys())this.host.tree.idForPath(i)||this.knownBodies.delete(i)}noteModify(A){let t=Date.now(),e=this.recentSelfWrites.get(A.path);e!==void 0&&t-e<xt.EXTERNAL_WRITE_GRACE_MS||this.lastExternalModify.set(A.path,t),this.scheduleContribution(A)}scheduleContribution(A){let t=this.contribTimers.get(A.path);t&&clearTimeout(t);let e=this.isFileActivelyEdited(A),i=xt.CONTRIB_DEBOUNCE_MS+(e?xt.CONTRIB_ACTIVE_EDITOR_BONUS_MS:0),s=setTimeout(()=>{if(this.contribTimers.delete(A.path),this.isFileActivelyEdited(A)){this.scheduleContribution(A);return}let n=this.lastExternalModify.get(A.path);if(n!==void 0&&Date.now()-n<xt.EXTERNAL_QUIESCENCE_MS){this.scheduleContribution(A);return}this.maybeRecordContribution(A)},i);this.contribTimers.set(A.path,s)}isFileActivelyEdited(A){try{let t=this.host.app.workspace.activeLeaf;if(!t)return!1;let e=t.view;if(!e||e.getViewType?.()!=="markdown"||e.file?.path!==A.path)return!1;let i=e.containerEl??null;return!!i&&i.contains(document.activeElement)}catch{return!1}}async maybeRecordContribution(A){let t="";try{t=await this.host.app.vault.cachedRead(A)}catch{return}let e=this.host.stripFrontmatter(t),i=this.knownBodies.get(A.path);if(this.knownBodies.set(A.path,e),i===void 0||i===e||this.host.plugin.rebootstrapInProgress)return;let s=this.currentAuthorLink();if(!s)return;this.ensureAuthorFile(s);let n=new Date().toISOString();this.recentSelfWrites.set(A.path,Date.now());try{await this.host.app.fileManager.processFrontMatter(A,o=>{o.modified=n;let a=typeof o.author=="string"?o.author:"",r=Array.isArray(o.contributors)?o.contributors.filter(I=>typeof I=="string"):[],c=`-${s.id}`,l=a.includes(c),d=r.some(I=>I.includes(c));!l&&!d&&r.push(s.link),o.contributors=r})}catch(o){console.warn("[Stashpad] maybeRecordContribution failed",o)}}};xt.CONTRIB_DEBOUNCE_MS=4e3,xt.CONTRIB_ACTIVE_EDITOR_BONUS_MS=2e3,xt.EXTERNAL_WRITE_GRACE_MS=1500,xt.EXTERNAL_QUIESCENCE_MS=5e3;var bi=xt;var Ni=class{constructor(A){this.host=A;this.dragSourceIds=null;this.dragPlaceholder=null;this.dragRowHeight=0}attachRowDnD(A,t,e){A.addEventListener("dragstart",i=>{let s=this.host.selection.has(t.id)&&this.host.selection.size>1?[...this.host.selection]:[t.id];if(this.dragSourceIds=s,this.dragRowHeight=A.offsetHeight,A.addClass("is-dragging"),this.host.listEl&&(this.dragPlaceholder=this.host.listEl.createDiv({cls:"stashpad-drop-placeholder"}),this.dragPlaceholder.style.height="0px",this.dragPlaceholder.addEventListener("dragover",n=>{this.dragSourceIds&&(n.preventDefault(),n.dataTransfer&&(n.dataTransfer.dropEffect="move"))}),this.dragPlaceholder.addEventListener("drop",n=>{if(!this.dragSourceIds||!this.dragPlaceholder)return;n.preventDefault(),n.stopPropagation();let o=this.dragSourceIds.slice();this.dragSourceIds=null;let a=this.dragPlaceholder.nextElementSibling,r=this.dragPlaceholder.previousElementSibling;this.removeDragPlaceholder();let c,l="before";a&&a.classList.contains("stashpad-note")?(c=a.dataset.id,l="before"):r&&r.classList.contains("stashpad-note")&&(c=r.dataset.id,l="after"),c&&this.host.reorderToTarget(o,c,l)}),this.dragPlaceholder.remove()),i.dataTransfer?.setData("text/plain",s.join(",")),i.dataTransfer){i.dataTransfer.effectAllowed="move";try{i.dataTransfer.setDragImage(A,12,12)}catch{}}}),A.addEventListener("dragend",()=>{A.removeClass("is-dragging"),this.clearDropIndicators(),this.removeDragPlaceholder(),this.dragSourceIds=null}),A.addEventListener("dragover",i=>{if(!this.dragSourceIds)return;i.preventDefault(),i.dataTransfer&&(i.dataTransfer.dropEffect="move");let s=this.dropZone(i,A);this.clearDropIndicators(),s==="drop-into"?(this.removeDragPlaceholder(),A.addClass("drop-into")):(A.removeClass("drop-into"),this.placePlaceholder(A,s==="drop-above"?"before":"after"))}),A.addEventListener("dragleave",i=>{let s=A.getBoundingClientRect();(i.clientX<s.left||i.clientX>s.right||i.clientY<s.top||i.clientY>s.bottom)&&A.removeClass("drop-into")}),A.addEventListener("drop",i=>{if(!this.dragSourceIds)return;i.preventDefault(),i.stopPropagation();let s=this.dragSourceIds.slice();this.dragSourceIds=null;let n=this.dropZone(i,A);this.clearDropIndicators(),this.removeDragPlaceholder(),A.removeClass("is-dragging"),n==="drop-into"?this.host.reorderToTarget(s,t.id,"into"):this.host.reorderToTarget(s,t.id,n==="drop-above"?"before":"after")})}attachListDnD(A){A.addEventListener("dragover",t=>{if(!this.dragSourceIds)return;let e=t.target;if(e&&e.closest&&e.closest(".stashpad-note"))return;t.preventDefault(),t.dataTransfer&&(t.dataTransfer.dropEffect="move");let i=Array.from(A.querySelectorAll(".stashpad-note"));if(i.length!==0){for(let s of i){let n=s.getBoundingClientRect();if(t.clientY<n.top+n.height/2){this.placePlaceholder(s,"before");return}}this.placePlaceholder(i[i.length-1],"after")}}),A.addEventListener("drop",t=>{if(!this.dragSourceIds)return;t.preventDefault();let e=this.dragSourceIds.slice();if(this.dragSourceIds=null,!this.dragPlaceholder)return;let i=this.dragPlaceholder.nextElementSibling,s=this.dragPlaceholder.previousElementSibling;if(this.removeDragPlaceholder(),i&&i.classList.contains("stashpad-note")){let n=i.dataset.id;n&&this.host.reorderToTarget(e,n,"before")}else if(s&&s.classList.contains("stashpad-note")){let n=s.dataset.id;n&&this.host.reorderToTarget(e,n,"after")}})}placePlaceholder(A,t){if(!this.dragPlaceholder||!this.host.listEl)return;let e=t==="before"?A:A.nextSibling;if(t==="before"&&this.dragPlaceholder.nextSibling===A||t==="after"&&this.dragPlaceholder.previousSibling===A)return;let i=!!this.dragPlaceholder.parentElement;this.host.listEl.insertBefore(this.dragPlaceholder,e),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 A=this.dragPlaceholder;A.style.height="0px",A.style.opacity="0",setTimeout(()=>{A.parentElement&&A.remove()},150)}dropZone(A,t){let e=t.getBoundingClientRect(),i=A.clientY-e.top;return i<e.height*.3?"drop-above":i>e.height*.7?"drop-below":"drop-into"}clearDropIndicators(){if(this.host.listEl)for(let A of Array.from(this.host.listEl.querySelectorAll(".drop-into")))A.removeClass("drop-into")}};var nn=require("obsidian");var xi=class{constructor(A,t,e){this.host=A;this.component=t;this.bodyObserver=null;this.lazyBodies=new WeakMap;this.renderCache=e??new Map}async getOrComputeRender(A){let t=this.renderCache.get(A.path);if(t&&t.mtime===A.stat.mtime)return vt.record("render.row.cacheHit",0),t;let e=await vt.timeAsync("render.row.read",()=>this.host.app.vault.cachedRead(A)),i=this.host.stripFrontmatter(e),{text:s,attachments:n}=this.splitAttachments(i),o=createDiv({cls:"stashpad-note-text"});await vt.timeAsync("render.row.markdown",()=>nn.MarkdownRenderer.render(this.host.app,s,o,A.path,this.component));let a=o.innerHTML,r={mtime:A.stat.mtime,text:s,attachments:n,html:a};return this.renderCache.set(A.path,r),r}arm(){this.bodyObserver?.disconnect(),this.lazyBodies=new WeakMap,this.bodyObserver=new IntersectionObserver(A=>{for(let t of A){if(!t.isIntersecting)continue;let e=t.target,i=this.lazyBodies.get(e);this.bodyObserver?.unobserve(e),this.lazyBodies.delete(e),i&&i()}},{root:this.host.contentEl,rootMargin:"1400px 0px"})}dispose(){this.bodyObserver?.disconnect(),this.bodyObserver=null}isArmed(){return!!this.bodyObserver}hasFreshRenderCache(A){let t=this.renderCache.get(A.path);return!!t&&t.mtime===A.stat.mtime}defer(A,t){this.lazyBodies.set(A,t),this.bodyObserver?.observe(A)}splitAttachments(A){let t=[];return{text:A.replace(/!\[\[([^\]\|]+)(?:\|[^\]]+)?\]\]/g,(i,s)=>(t.push(s),"")).replace(/\n{3,}/g,` +`)}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 i=e.createDiv({cls:"stashpad-suggest-body"}),s=this.notes.find(h=>t.crossFolder?h.cross?.id===t.id.replace(/^cross:/,""):h.node?.id===t.id),n=Cn(this.inputEl?.value??"").text,o=this.firstLineOfBody(s?.body??"")||t.label.trim(),r=i.createDiv({cls:"stashpad-suggest-title"});this.highlightInto(r,o,n);let a=t.crossFolder??this.opts.localFolder??null;if(t.bodyPreview&&t.matchLine!=null&&t.matchLine>=0){let h=i.createDiv({cls:"stashpad-suggest-preview stashpad-suggest-snippet"});this.highlightInto(h,t.bodyPreview,n)}let c="";if(t.crossFolder?c=s?.cross?.parentBlurb??"":c=this.parentBlurbFor(t.node),c){let h=i.createDiv({cls:"stashpad-suggest-preview"});h.appendText("Parent: "),this.highlightInto(h,c,n)}let l=t.crossFolder?this.buildCrossBreadcrumb(t):this.buildLocalBreadcrumb(t.node),p=t.crossFolder??this.opts.localFolder??null;if(p||l){let h=i.createDiv({cls:"stashpad-suggest-breadcrumb"}),u=[p?p.split("/").pop()||p:"",l].filter(f=>f&&f.length>0).join(" \u203A ");u&&h.setText(u)}let g=s?this.createdMsFor(s):null;if(g!=null||a){let h=e.createDiv({cls:"stashpad-suggest-rail"});if(g!=null){let I=h.createDiv({cls:"stashpad-suggest-time"});I.setText(this.formatRelativeTime(g)),I.title=(0,ht.moment)(g).format("YYYY-MM-DD HH:mm")}a&&h.createDiv({cls:"stashpad-suggest-folder-badge",text:a.split("/").pop()||a})}}formatRelativeTime(t){let e=(0,ht.moment)(t),i=(0,ht.moment)().startOf("day").diff((0,ht.moment)(t).startOf("day"),"days");return i===0?e.format("h:mm a"):i===1?"yesterday":i>1&&i<7?`${i}d ago`:i>=7&&i<30?`${Math.floor(i/7)}w ago`:i>=30&&i<365?e.format("MMM D"):e.format("MMM D, YYYY")}highlightInto(t,e,i){if(!e)return;let s=i.filter(c=>c&&c.length>0);if(!s.length){t.appendText(e);return}let n=e.toLowerCase(),o=[];for(let c of s){let l=0;for(;(l=n.indexOf(c,l))!==-1;)o.push([l,l+c.length]),l+=c.length}if(!o.length){t.appendText(e);return}o.sort((c,l)=>c[0]-l[0]);let r=[];for(let c of o){let l=r[r.length-1];l&&c[0]<=l[1]?l[1]=Math.max(l[1],c[1]):r.push([c[0],c[1]])}let a=0;for(let[c,l]of r)c>a&&t.appendText(e.slice(a,c)),t.createSpan({cls:"stashpad-suggest-match",text:e.slice(c,l)}),a=l;a<e.length&&t.appendText(e.slice(a))}buildLocalBreadcrumb(t){if(!t||!t.parent||t.parent===G)return"";let e=[],i=new Set([t.id]),s=this.tree.get(t.parent);for(;s&&s.id!==G&&!i.has(s.id);)i.add(s.id),e.unshift(this.titleFn(s)),s=s.parent&&s.parent!==G?this.tree.get(s.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 c=this.crossFolderIndex.get(a.cross.folder);c||(c=new Map,this.crossFolderIndex.set(a.cross.folder,c)),c.set(a.cross.id,a.cross)}}let e=this.crossFolderIndex.get(t.crossFolder);if(!e)return"";let i=t.id.replace(/^cross:/,""),s=e.get(i);if(!s)return"";let n=[],o=new Set([s.id]),r=s.parentId?e.get(s.parentId):null;for(;r&&!o.has(r.id);)o.add(r.id),n.unshift(r.title),r=r.parentId?e.get(r.parentId):null;return n.join(" \u203A ")}firstLineOfBody(t){if(!t)return"";let e=t.split(/\r?\n/);for(let i of e){let s=i.trim();if(s)return s}return""}parentBlurbFor(t){if(!t||!t.parent||t.parent===G)return"";let e=this.tree.get(t.parent);if(!e||!e.file)return"";let i=this.notes.find(s=>s.node?.id===e.id);return i?this.firstLineOfBody(i.body):""}onOpen(){if(super.onOpen(),this.opts.showFilterChips&&!ht.Platform.isMobile){let t=this.inputEl,e=this.resultContainerEl;if(!t||!e)return;this.mountFilterChipRow(t,e);return}if(ht.Platform.isMobile){let t=this.inputEl;t&&t.focus()}}mountFilterChipRow(t,e){t.addEventListener("keydown",c=>{if(c.key==="["){c.preventDefault();let l=t.selectionStart??t.value.length,p=t.selectionEnd??l,g=t.value.slice(0,l),h=t.value.slice(l,p),I=t.value.slice(p);t.value=`${g}[${h}]${I}`;let u=l+1+h.length;t.setSelectionRange(u,u),t.dispatchEvent(new Event("input",{bubbles:!0}));return}if(c.key==="]"){let l=t.selectionStart??-1;l>=0&&t.value[l]==="]"&&(c.preventDefault(),t.setSelectionRange(l+1,l+1));return}if(c.key==="Backspace"&&!c.metaKey&&!c.ctrlKey&&!c.altKey&&t.selectionStart===t.selectionEnd){let l=t.selectionStart??-1;if(l>0&&t.value[l-1]==="["&&t.value[l]==="]"){c.preventDefault();let p=t.value.slice(0,l-1),g=t.value.slice(l+1);t.value=`${p}${g}`,t.setSelectionRange(l-1,l-1),t.dispatchEvent(new Event("input",{bubbles:!0}))}}});let i=document.createElement("div");i.className="stashpad-search-filter-row";let s=document.createElement("span");s.className="stashpad-search-filter-label",s.textContent="Filters:",i.appendChild(s);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",c=>{c.preventDefault()}),n.addEventListener("click",c=>{c.preventDefault(),this.appendFilterToInput(t,"in","")}),n.addEventListener("keydown",c=>{(c.key==="Enter"||c.key===" ")&&(c.preventDefault(),c.stopPropagation(),n.click())}),i.appendChild(n);let o=document.createElement("button");o.className="stashpad-search-filter-chip stashpad-search-filter-when",o.type="button",o.textContent="when:[date / day / timeframe]",o.title="Open the time-filter builder (Before / On / After / Between).",o.addEventListener("mousedown",c=>{c.preventDefault()}),o.addEventListener("click",c=>{c.preventDefault(),this.toggleWhenBuilder(t,i)}),o.addEventListener("keydown",c=>{(c.key==="Enter"||c.key===" ")&&(c.preventDefault(),c.stopPropagation(),o.click())}),i.appendChild(o),e.parentElement?.insertBefore(i,e);let r=new ht.Scope(this.scope),a=c=>{let l=document.activeElement;return l?.classList?.contains("stashpad-search-filter-chip")?(c.preventDefault(),l.click(),!1):c.key==="Enter"&&!c.isComposing?(c.preventDefault(),this.selectActiveSuggestion?.(c),!1):!0};r.register([],"Enter",a),r.register([]," ",a),r.register(["Mod"],"f",c=>{c.preventDefault();let l=this.inputEl;return l&&(l.focus(),l.select()),!1}),r.register([],"Tab",c=>{let l=this.modalEl,p=this.inputEl;if(!l)return!0;let g=Array.from(l.querySelectorAll('input, button, select, textarea, a[href], [tabindex]:not([tabindex="-1"])')).filter(u=>!u.hasAttribute("disabled")&&u.tabIndex!==-1&&u.offsetParent!==null);if(g.length===0)return!0;let h=document.activeElement,I=h?g.indexOf(h):-1;if(c.shiftKey){if(I<=0)return c.preventDefault(),g[g.length-1].focus(),!1}else if(I===g.length-1)return c.preventDefault(),(p??g[0]).focus(),!1;return!0}),this.app.keymap?.pushScope(r),this.pendingCleanups.push(()=>{try{this.app.keymap?.popScope(r)}catch{}})}appendFilterToInput(t,e,i){let s=t.value,o=`${s.length>0&&!/\s$/.test(s)?" ":""}${e}: [`,r="]",a=i;t.value=`${s}${o}${a}${r}`;let c=s.length+o.length+a.length;if(t.setSelectionRange(c,c+0),!a){let l=s.length+o.length;t.setSelectionRange(l,l)}t.focus(),t.dispatchEvent(new Event("input",{bubbles:!0}))}toggleWhenBuilder(t,e){let i=this.modalEl;if(this.whenBuilderEl){this.whenBuilderEl.remove(),this.whenBuilderEl=null,i?.removeClass("is-when-builder-open");return}i?.addClass("is-when-builder-open");let s=document.createElement("div");s.className="stashpad-when-builder";let n=document.createElement("div");n.className="stashpad-when-tabs";let o=[{id:"before",label:"Before"},{id:"on",label:"On"},{id:"after",label:"After"},{id:"between",label:"Between"}],r={};for(let u of o){let f=document.createElement("button");f.type="button",f.className="stashpad-when-tab",f.textContent=u.label,this.whenMode===u.id&&f.addClass("is-active"),f.addEventListener("mousedown",C=>C.preventDefault()),f.addEventListener("click",C=>{if(C.preventDefault(),this.whenMode===u.id)return;let m=this.whenMode;m!=="between"&&u.id==="between"?(this.whenBetweenEndText="",this.whenBetweenEndDate="",this.whenBetweenEndTime=""):m==="between"&&u.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=u.id;for(let E in r)r[E].toggleClass("is-active",E===u.id);I()}),r[u.id]=f,n.appendChild(f)}s.appendChild(n);let a=document.createElement("div");a.className="stashpad-when-body",s.appendChild(a);let c=(u,f,C="single")=>{let m=(0,ht.moment)().format("YYYY-MM-DD"),E=!f||f===m;if(C==="betweenStart")return"00:00";if(C==="betweenEnd")return"23:59";switch(u){case"after":return"00:00";case"on":return E?(0,ht.moment)().format("HH:mm"):"23:59";case"before":return E?(0,ht.moment)().format("HH:mm"):"23:59";default:return"23:59"}},l=(u,f)=>{u.addEventListener("keydown",C=>{C.key==="Enter"?(C.preventDefault(),C.stopPropagation(),f()):C.key==="Escape"&&(C.preventDefault(),C.stopPropagation(),this.closeWhenBuilder())})},p=(u,f)=>{let C=u.selectionStart??u.value.length,m=u.selectionEnd??u.value.length,y=`${C>0&&!/\s$/.test(u.value.slice(0,C))?" ":""}${f}`,w=u.value.slice(0,C)+y+u.value.slice(m);u.value=w;let v=C+y.length;u.setSelectionRange(v,v),u.focus(),u.dispatchEvent(new Event("input",{bubbles:!0}))},g=(u,f)=>{let m=u.slice(0,f).match(/(\d{4}-\d{2}-\d{2})(?!.*\d{4}-\d{2}-\d{2})/);return m?m[1]:null},h=(u,f,C,m)=>{let E=a.createDiv({cls:"stashpad-when-input-wrap has-icons"}),y=E.createDiv({cls:"stashpad-when-icon-slot"}),w=y.createEl("button",{cls:"stashpad-when-icon stashpad-when-icon-cal"});w.type="button",w.title="Pick date",(0,ht.setIcon)(w,"calendar-days");let v=y.createEl("input",{cls:"stashpad-when-native",attr:{type:"date"}});v.tabIndex=-1;let D=E.createDiv({cls:"stashpad-when-icon-slot"}),L=D.createEl("button",{cls:"stashpad-when-icon stashpad-when-icon-clock"});L.type="button",L.title="Pick time",(0,ht.setIcon)(L,"clock");let S=E.createDiv({cls:"stashpad-when-icon-slot"}),b=S.createEl("button",{cls:"stashpad-when-icon stashpad-when-icon-day"});b.type="button",b.title="Pick day",(0,ht.setIcon)(b,"calendar");let Q=E.createDiv({cls:"stashpad-when-icon-slot"}),H=Q.createEl("button",{cls:"stashpad-when-icon stashpad-when-icon-tf"});H.type="button",H.title="Pick timeframe",(0,ht.setIcon)(H,"history");let $=E.createEl("input",{cls:"stashpad-when-input",attr:{type:"text",placeholder:u}});$.value=f(),$.addEventListener("input",()=>C($.value));let M=E.createEl("button",{cls:"stashpad-when-clear"});M.type="button",M.textContent="\xD7",M.title="Clear";for(let N of[w,L,b,H,M])N.addEventListener("mousedown",j=>j.preventDefault());let T=null,J=(N,j)=>{T&&T();let K=N.createDiv({cls:"stashpad-when-popover"}),z=new ht.Scope(this.scope),ot=null,dt=nt=>{ot=nt},st=!1,at=nt=>{!K.contains(nt.target)&&nt.target!==N&&!N.contains(nt.target)&&At()},At=()=>{if(!st){st=!0,K.remove(),document.removeEventListener("mousedown",at,!0);try{this.app.keymap?.popScope(z)}catch{}T===At&&(T=null)}};T=At,z.register([],"Escape",nt=>(nt.preventDefault(),At(),!1)),z.register([],"Enter",nt=>(nt.preventDefault(),ot&&ot(),!1));try{j(K,At,dt)}catch(nt){console.error("[stashpad] popover fill threw:",nt),K.remove(),T=null;return}this.app.keymap?.pushScope(z),this.pendingCleanups.push(At),setTimeout(()=>document.addEventListener("mousedown",at,!0),0)};H.addEventListener("click",N=>{N.preventDefault(),J(Q,(j,K,z)=>{let ot=this.whenMode==="on",dt=(O,P)=>{if(!ot)return`${O}${P}`;let k={d:"days",w:"weeks",m:"months",y:"years"}[P];return(0,ht.moment)().subtract(O,k).format("YYYY-MM-DD")},st=j.createDiv({cls:"stashpad-when-pop-row"}),at=[{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 O of at){let P=st.createEl("button",{cls:"stashpad-when-pop-chip",text:O.label});P.type="button",P.addEventListener("mousedown",k=>k.preventDefault()),P.addEventListener("click",k=>{k.preventDefault(),p($,dt(O.n,O.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 nt=At.createEl("input",{cls:"stashpad-when-pop-number",attr:{type:"number",min:"1",max:"999",value:"7"}}),mt=At.createEl("select",{cls:"stashpad-when-pop-unit"});for(let O of[{v:"d",label:"days"},{v:"w",label:"weeks"},{v:"m",label:"months"},{v:"y",label:"years"}]){let P=mt.createEl("option",{text:O.label});P.value=O.v}let Ct=At.createEl("button",{cls:"stashpad-when-pop-chip stashpad-when-pop-go",text:"Insert"});Ct.type="button";let B=()=>{let O=parseInt(nt.value,10);!Number.isFinite(O)||O<1||(p($,dt(O,mt.value)),K())};Ct.addEventListener("mousedown",O=>O.preventDefault()),Ct.addEventListener("click",O=>{O.preventDefault(),B()}),z(B),nt.focus(),nt.select()})});let Z=(N,j,K,z,ot)=>{J(j,(dt,st,at)=>{li(dt,{seedH:K,seedM:z,seedPeriod:ot,close:st,setOnEnter:at,onFinalize:At=>p(N,_s(At))})})};b.addEventListener("click",N=>{N.preventDefault(),J(S,(j,K,z)=>{let ot=j.createDiv({cls:"stashpad-when-pop-row"});for(let nt of["Today","Yesterday"]){let mt=ot.createEl("button",{cls:"stashpad-when-pop-chip",text:nt});mt.type="button",mt.addEventListener("mousedown",Ct=>Ct.preventDefault()),mt.addEventListener("click",Ct=>{Ct.preventDefault(),p($,nt),K()})}let dt=j.createDiv({cls:"stashpad-when-pop-row stashpad-when-pop-days"}),st=["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],At=((0,ht.moment)().day()+6)%7;for(let nt=0;nt<st.length;nt++){let mt=st[nt],Ct=dt.createEl("button",{cls:"stashpad-when-pop-chip",text:mt.slice(0,3)});Ct.type="button",Ct.title=mt,nt===At&&Ct.addClass("is-today"),Ct.addEventListener("mousedown",B=>B.preventDefault()),Ct.addEventListener("click",B=>{if(B.preventDefault(),m==="betweenEnd"){let O=nt,P=(0,ht.moment)().startOf("day"),k=(P.day()+6)%7,F=(O-k+7)%7;F===0&&(F=7);let x=P.clone().add(F,"days").format("YYYY-MM-DD");p($,x)}else p($,mt);K()})}})});let U=(N,j)=>{N.value||(N.value=j);let K=N;if(typeof K.showPicker=="function")try{K.showPicker();return}catch{}N.focus(),N.click()};return w.addEventListener("click",N=>{N.preventDefault(),U(v,(0,ht.moment)().format("YYYY-MM-DD"))}),v.addEventListener("change",()=>{v.value&&p($,v.value)}),L.addEventListener("click",N=>{N.preventDefault();let j=$.selectionStart??$.value.length,K=g($.value,j),z=c(this.whenMode,K,m),[ot,dt]=z.split(":"),st=parseInt(ot,10),at=parseInt(dt,10),At=st%12;At===0&&(At=12);let nt=st>=12?"pm":"am";Z($,D,At,at,nt)}),M.addEventListener("click",N=>{N.preventDefault(),$.value="",C(""),$.focus()}),$},I=()=>{if(a.empty(),this.whenMode==="between"){let u=h("start (date / day / timeframe)",()=>this.whenSingleText,w=>{this.whenSingleText=w},"betweenStart"),f=h("end (date / day / timeframe)",()=>this.whenBetweenEndText,w=>{this.whenBetweenEndText=w},"betweenEnd"),C=a.createDiv({cls:"stashpad-when-actions"}),m=C.createEl("button",{cls:"stashpad-when-insert",text:"Insert"});m.type="button",m.addEventListener("mousedown",w=>w.preventDefault());let E=()=>{let w=u.value.trim(),v=f.value.trim();w&&this.appendFilterToInput(t,"after",w),v&&this.appendFilterToInput(t,"before",v),this.closeWhenBuilder()};m.addEventListener("click",w=>{w.preventDefault(),E()});let y=C.createEl("button",{cls:"stashpad-when-cancel",text:"Cancel"});y.type="button",y.addEventListener("mousedown",w=>w.preventDefault()),y.addEventListener("click",w=>{w.preventDefault(),this.closeWhenBuilder()}),l(u,E),l(f,E),u.focus(),u.setSelectionRange(u.value.length,u.value.length)}else{let u=h("date / day / timeframe",()=>this.whenSingleText,y=>{this.whenSingleText=y},"single"),f=a.createDiv({cls:"stashpad-when-actions"}),C=f.createEl("button",{cls:"stashpad-when-insert",text:"Insert"});C.type="button",C.addEventListener("mousedown",y=>y.preventDefault());let m=()=>{let y=u.value.trim();y&&this.appendFilterToInput(t,this.whenMode,y),this.closeWhenBuilder()};C.addEventListener("click",y=>{y.preventDefault(),m()});let E=f.createEl("button",{cls:"stashpad-when-cancel",text:"Cancel"});E.type="button",E.addEventListener("mousedown",y=>y.preventDefault()),E.addEventListener("click",y=>{y.preventDefault(),this.closeWhenBuilder()}),l(u,m),u.focus(),u.setSelectionRange(u.value.length,u.value.length)}};I(),e.parentElement?.insertBefore(s,e.nextSibling),this.whenBuilderEl=s}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 i=this.inputEl?.value??"",s=!1,n=g=>{s=!0;let h=g.split("/").pop()??g;this.opts.onPick({id:`folder:${g}`,label:`Open folder \u201C${h}\u201D in a new tab`,node:null,kind:"folder-open",folder:g})},o=new Qs(this.app,e,n),r=o.onClose.bind(o),a=this.tree,c=this.titleFn,l=this.opts,p=this.app;o.onClose=()=>{if(r(),!s){let g=new d(p,a,c,l);g.open(),setTimeout(()=>{let h=g.inputEl;h&&(i&&(h.value=i,h.dispatchEvent(new Event("input",{bubbles:!0}))),h.focus(),h.setSelectionRange(h.value.length,h.value.length))},0)}},o.open();return}this.opts.onPick(t)}},Qs=class extends ht.FuzzySuggestModal{constructor(t,e,i){super(t);this.folders=e;this.onChosen=i;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)}};var Bn=require("obsidian");wt();var Gi=class extends Bn.SuggestModal{constructor(A){super(A),this.setPlaceholder("Run a Stashpad command\u2026");let t=this.app.commands?.commands??{};this.commands=Object.keys(t).filter(e=>e.startsWith("stashpad:")).filter(e=>e!=="stashpad:stashpad-command-palette").map(e=>({id:e,name:xo(t[e]?.name??e)})).sort((e,i)=>e.name.localeCompare(i.name))}getSuggestions(A){return this.commands.filter(t=>Ai(A,t.name))}renderSuggestion(A,t){t.createDiv({text:A.name,cls:"stashpad-cmd-palette-name"})}onChooseSuggestion(A){this.app.commands?.executeCommandById?.(A.id)}};function xo(d){return d.replace(/^(?:\s*Stashpad:\s*)+/i,"").trim()||d}Mt();var Es=require("obsidian");function Mo(d,A){return!A||d.metaKey||d.ctrlKey||d.altKey?!1:d.key.toLowerCase()===A.toLowerCase()}function Fe(d,A){return A?A.includes("+")?Ho(d,A):Mo(d,A):!1}function rt(d,A){if(!A)return!1;let{primary:t,secondary:e,preferRight:i,useBoth:s}=A;return t&&e?s?Fe(d,t)||Fe(d,e):i?Fe(d,e):Fe(d,t):Fe(d,t)||Fe(d,e)}function je(d){if(!d)return"";let A=Es.Platform.isMacOS??navigator.platform.toLowerCase().includes("mac");return d.split("+").map(t=>{let e=t.trim();return e?e.toLowerCase()==="mod"?A?"Cmd":"Ctrl":e.toLowerCase()==="alt"?A?"Opt":"Alt":e.length===1?e.toUpperCase():e:""}).filter(Boolean).join("+")}function Ho(d,A){if(!A)return!1;let t=A.split("+").map(p=>p.trim()).filter(Boolean);if(t.length<2)return!1;let e=t[t.length-1].toLowerCase(),i=new Set(t.slice(0,-1).map(p=>p.toLowerCase())),s=i.has("mod"),n=i.has("ctrl")||i.has("control"),o=i.has("cmd")||i.has("meta")||i.has("command"),r=i.has("alt")||i.has("option"),a=i.has("shift"),l=Es.Platform.isMacOS??navigator.platform.toLowerCase().includes("mac")?d.metaKey:d.ctrlKey;return s&&!l||n&&!d.ctrlKey||o&&!d.metaKey||r!==d.altKey||a!==d.shiftKey||!s&&(!n&&d.ctrlKey||!o&&d.metaKey)?!1:d.key.toLowerCase()===e}var de=require("obsidian");Mt();var Ht=class Ht{constructor(A){this.host=A;this.knownBodies=new Map;this.contribTimers=new Map;this.recentSelfWrites=new Map;this.lastExternalModify=new Map}dispose(){for(let A of this.contribTimers.values())clearTimeout(A);this.contribTimers.clear(),this.knownBodies.clear(),this.recentSelfWrites.clear(),this.lastExternalModify.clear()}currentAuthorLink(){let A=(this.host.plugin.settings.authorName??"").trim(),t=(this.host.plugin.settings.authorId??"").trim();if(!A||!t)return null;let e=A.replace(/[^\w\- ]+/g,"").trim().replace(/\s+/g,"-")||"author",i=`${this.host.noteFolder}/_authors/${e}-${t}.md`,s=A.replace(/[\[\]|]/g,"").trim()||e;return{link:`[[${i}|${s}]]`,path:i,name:A,id:t}}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 A=this.host.noteFolder.replace(/\/+$/,"");return this.host.app.vault.getMarkdownFiles().filter(t=>{let e=t.parent?.path?.replace(/\/+$/,"")??"";if(e!==A&&!e.startsWith(A+"/")||t.path.includes("/_authors/"))return!1;let i=this.host.app.metadataCache.getFileCache(t)?.frontmatter;return typeof i?.id=="string"&&!!i.id})}async pacedFrontmatter(A,t){for(let s=0;s<A.length;s++){let n=this.host.app.vault.getAbstractFileByPath(A[s]);if(n instanceof de.TFile){this.recentSelfWrites.set(n.path,Date.now());try{await this.host.app.fileManager.processFrontMatter(n,o=>t(o,A[s]))}catch(o){console.warn("[Stashpad] claim: frontmatter write failed",A[s],o)}}(s+1)%25===0&&await new Promise(o=>setTimeout(o,30))}}async claimAuthorship(A){let t=this.currentAuthorLink();if(!t){new de.Notice("Set your author name in Stashpad settings first.");return}let e=`-${t.id}`,i=A.scope==="selection"?this.host.getActionTargets().map(g=>g.file).filter(g=>!!g):this.fileBackedNotesInFolder();if(i.length===0){new de.Notice(A.scope==="selection"?"No notes selected.":"No notes in this folder.");return}let s=[],n=[];for(let g of i){let h=this.host.app.metadataCache.getFileCache(g)?.frontmatter,I=typeof h?.author=="string"?h.author:"";if(!I.trim()){s.push(g.path);continue}if(I.includes(e)||!A.contributorMode)continue;(Array.isArray(h?.contributors)?h.contributors.filter(f=>typeof f=="string"):[]).some(f=>f.includes(e))||n.push(g.path)}let o=s.length+n.length;if(o===0){new de.Notice("Nothing to claim \u2014 those notes are already authored by you.");return}if(A.scope==="folder"){let g=[`Stamp yourself as author on ${s.length} unauthored note(s)`];if(n.length&&g.push(`and as a contributor on ${n.length} already-authored note(s)`),!await new Promise(I=>{new vt(this.host.app,"Claim authorship",`${g.join(" ")}? +Existing authors are never overwritten. This can be undone.`,"Claim",I).open()}))return}let r=this.host.noteFolder,a=t.link,c=new Set,l=async()=>{await this.pacedFrontmatter(s,(g,h)=>{typeof g.author=="string"&&g.author.trim()||(g.author=a),Array.isArray(g.contributors)&&g.contributors.some(I=>typeof I=="string"&&I.includes(e))&&(g.contributors=g.contributors.filter(I=>!(typeof I=="string"&&I.includes(e))),c.add(h))}),await this.pacedFrontmatter(n,g=>{let h=Array.isArray(g.contributors)?g.contributors.filter(I=>typeof I=="string"):[];h.some(I=>I.includes(e))||h.push(a),g.contributors=h})};this.ensureAuthorFile(t),await l(),this.host.plugin.getUndoStack(r).push({label:`Claim authorship (${o} note${o===1?"":"s"})`,undo:async()=>{await this.pacedFrontmatter(s,(g,h)=>{if(typeof g.author=="string"&&g.author.includes(e)&&delete g.author,c.has(h)){let I=Array.isArray(g.contributors)?g.contributors.filter(u=>typeof u=="string"):[];I.some(u=>u.includes(e))||I.push(a),g.contributors=I}}),await this.pacedFrontmatter(n,g=>{Array.isArray(g.contributors)&&(g.contributors=g.contributors.filter(h=>!(typeof h=="string"&&h.includes(e))))}),this.host.debouncedRender()},redo:async()=>{c.clear(),await l(),this.host.debouncedRender()}});let p=[];s.length&&p.push(`authored ${s.length}`),n.length&&p.push(`contributing to ${n.length}`),new de.Notice(`Claimed authorship: ${p.join(", ")}. Undo available.`),this.host.debouncedRender()}async ensureAuthorFile(A){try{A.id&&this.host.plugin.authorRegistry.record({id:A.id,name:A.name});let t=`${this.host.noteFolder}/_authors`;if(await this.host.ensureFolder(t),await this.host.app.vault.adapter.exists(A.path))return;let e=A.id===(this.host.plugin.settings.authorId??"").trim(),i=this.host.plugin.buildAuthorStub({id:A.id,name:A.name,role:e?this.host.plugin.settings.authorRole:void 0,department:e?this.host.plugin.settings.authorDepartment:void 0},new Date().toISOString());await this.host.app.vault.create(A.path,i)}catch(t){console.warn("[Stashpad] ensureAuthorFile failed",t)}}collectAuthorIds(A){let t=new Set,e=i=>{if(typeof i!="string")return null;let s=i.match(/-([a-z0-9]{4,12})(?:\.md)?(?:\||\]\])/i);return s?s[1]:null};for(let i of A){if(!i.file)continue;let s=this.host.app.metadataCache.getFileCache(i.file)?.frontmatter;if(!s)continue;let n=e(s.author);if(n&&t.add(n),Array.isArray(s.contributors))for(let o of s.contributors){let r=e(o);r&&t.add(r)}}return Array.from(t)}pruneContribMaps(){let A=Date.now(),t=Ht.EXTERNAL_WRITE_GRACE_MS*20,e=Ht.EXTERNAL_QUIESCENCE_MS*12;for(let[i,s]of this.recentSelfWrites)A-s>t&&this.recentSelfWrites.delete(i);for(let[i,s]of this.lastExternalModify)A-s>e&&this.lastExternalModify.delete(i);if(this.knownBodies.size>64)for(let i of this.knownBodies.keys())this.host.tree.idForPath(i)||this.knownBodies.delete(i)}noteModify(A){let t=Date.now(),e=this.recentSelfWrites.get(A.path);e!==void 0&&t-e<Ht.EXTERNAL_WRITE_GRACE_MS||this.lastExternalModify.set(A.path,t),this.scheduleContribution(A)}scheduleContribution(A){let t=this.contribTimers.get(A.path);t&&clearTimeout(t);let e=this.isFileActivelyEdited(A),i=Ht.CONTRIB_DEBOUNCE_MS+(e?Ht.CONTRIB_ACTIVE_EDITOR_BONUS_MS:0),s=setTimeout(()=>{if(this.contribTimers.delete(A.path),this.isFileActivelyEdited(A)){this.scheduleContribution(A);return}let n=this.lastExternalModify.get(A.path);if(n!==void 0&&Date.now()-n<Ht.EXTERNAL_QUIESCENCE_MS){this.scheduleContribution(A);return}this.maybeRecordContribution(A)},i);this.contribTimers.set(A.path,s)}isFileActivelyEdited(A){try{let t=this.host.app.workspace.activeLeaf;if(!t)return!1;let e=t.view;if(!e||e.getViewType?.()!=="markdown"||e.file?.path!==A.path)return!1;let i=e.containerEl??null;return!!i&&i.contains(document.activeElement)}catch{return!1}}async maybeRecordContribution(A){let t="";try{t=await this.host.app.vault.cachedRead(A)}catch{return}let e=this.host.stripFrontmatter(t),i=this.knownBodies.get(A.path);if(this.knownBodies.set(A.path,e),i===void 0||i===e||this.host.plugin.rebootstrapInProgress)return;let s=this.currentAuthorLink();if(!s)return;this.ensureAuthorFile(s);let n=new Date().toISOString();this.recentSelfWrites.set(A.path,Date.now());try{await this.host.app.fileManager.processFrontMatter(A,o=>{o.modified=n;let r=typeof o.author=="string"?o.author:"",a=Array.isArray(o.contributors)?o.contributors.filter(g=>typeof g=="string"):[],c=`-${s.id}`,l=r.includes(c),p=a.some(g=>g.includes(c));!l&&!p&&a.push(s.link),o.contributors=a})}catch(o){console.warn("[Stashpad] maybeRecordContribution failed",o)}}};Ht.CONTRIB_DEBOUNCE_MS=4e3,Ht.CONTRIB_ACTIVE_EDITOR_BONUS_MS=2e3,Ht.EXTERNAL_WRITE_GRACE_MS=1500,Ht.EXTERNAL_QUIESCENCE_MS=5e3;var Ri=Ht;var Pi=class{constructor(A){this.host=A;this.dragSourceIds=null;this.dragPlaceholder=null;this.dragRowHeight=0}attachRowDnD(A,t,e){A.addEventListener("dragstart",i=>{let s=this.host.selection.has(t.id)&&this.host.selection.size>1?[...this.host.selection]:[t.id];if(this.dragSourceIds=s,this.dragRowHeight=A.offsetHeight,A.addClass("is-dragging"),this.host.listEl&&(this.dragPlaceholder=this.host.listEl.createDiv({cls:"stashpad-drop-placeholder"}),this.dragPlaceholder.style.height="0px",this.dragPlaceholder.addEventListener("dragover",n=>{this.dragSourceIds&&(n.preventDefault(),n.dataTransfer&&(n.dataTransfer.dropEffect="move"))}),this.dragPlaceholder.addEventListener("drop",n=>{if(!this.dragSourceIds||!this.dragPlaceholder)return;n.preventDefault(),n.stopPropagation();let o=this.dragSourceIds.slice();this.dragSourceIds=null;let r=this.dragPlaceholder.nextElementSibling,a=this.dragPlaceholder.previousElementSibling;this.removeDragPlaceholder();let c,l="before";r&&r.classList.contains("stashpad-note")?(c=r.dataset.id,l="before"):a&&a.classList.contains("stashpad-note")&&(c=a.dataset.id,l="after"),c&&this.host.reorderToTarget(o,c,l)}),this.dragPlaceholder.remove()),i.dataTransfer?.setData("text/plain",s.join(",")),i.dataTransfer){i.dataTransfer.effectAllowed="move";try{i.dataTransfer.setDragImage(A,12,12)}catch{}}}),A.addEventListener("dragend",()=>{A.removeClass("is-dragging"),this.clearDropIndicators(),this.removeDragPlaceholder(),this.dragSourceIds=null}),A.addEventListener("dragover",i=>{if(!this.dragSourceIds)return;i.preventDefault(),i.dataTransfer&&(i.dataTransfer.dropEffect="move");let s=this.dropZone(i,A);this.clearDropIndicators(),s==="drop-into"?(this.removeDragPlaceholder(),A.addClass("drop-into")):(A.removeClass("drop-into"),this.placePlaceholder(A,s==="drop-above"?"before":"after"))}),A.addEventListener("dragleave",i=>{let s=A.getBoundingClientRect();(i.clientX<s.left||i.clientX>s.right||i.clientY<s.top||i.clientY>s.bottom)&&A.removeClass("drop-into")}),A.addEventListener("drop",i=>{if(!this.dragSourceIds)return;i.preventDefault(),i.stopPropagation();let s=this.dragSourceIds.slice();this.dragSourceIds=null;let n=this.dropZone(i,A);this.clearDropIndicators(),this.removeDragPlaceholder(),A.removeClass("is-dragging"),n==="drop-into"?this.host.reorderToTarget(s,t.id,"into"):this.host.reorderToTarget(s,t.id,n==="drop-above"?"before":"after")})}attachListDnD(A){A.addEventListener("dragover",t=>{if(!this.dragSourceIds)return;let e=t.target;if(e&&e.closest&&e.closest(".stashpad-note"))return;t.preventDefault(),t.dataTransfer&&(t.dataTransfer.dropEffect="move");let i=Array.from(A.querySelectorAll(".stashpad-note"));if(i.length!==0){for(let s of i){let n=s.getBoundingClientRect();if(t.clientY<n.top+n.height/2){this.placePlaceholder(s,"before");return}}this.placePlaceholder(i[i.length-1],"after")}}),A.addEventListener("drop",t=>{if(!this.dragSourceIds)return;t.preventDefault();let e=this.dragSourceIds.slice();if(this.dragSourceIds=null,!this.dragPlaceholder)return;let i=this.dragPlaceholder.nextElementSibling,s=this.dragPlaceholder.previousElementSibling;if(this.removeDragPlaceholder(),i&&i.classList.contains("stashpad-note")){let n=i.dataset.id;n&&this.host.reorderToTarget(e,n,"before")}else if(s&&s.classList.contains("stashpad-note")){let n=s.dataset.id;n&&this.host.reorderToTarget(e,n,"after")}})}placePlaceholder(A,t){if(!this.dragPlaceholder||!this.host.listEl)return;let e=t==="before"?A:A.nextSibling;if(t==="before"&&this.dragPlaceholder.nextSibling===A||t==="after"&&this.dragPlaceholder.previousSibling===A)return;let i=!!this.dragPlaceholder.parentElement;this.host.listEl.insertBefore(this.dragPlaceholder,e),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 A=this.dragPlaceholder;A.style.height="0px",A.style.opacity="0",setTimeout(()=>{A.parentElement&&A.remove()},150)}dropZone(A,t){let e=t.getBoundingClientRect(),i=A.clientY-e.top;return i<e.height*.3?"drop-above":i>e.height*.7?"drop-below":"drop-into"}clearDropIndicators(){if(this.host.listEl)for(let A of Array.from(this.host.listEl.querySelectorAll(".drop-into")))A.removeClass("drop-into")}};var mn=require("obsidian");var Li=class{constructor(A,t,e){this.host=A;this.component=t;this.bodyObserver=null;this.lazyBodies=new WeakMap;this.renderCache=e??new Map}async getOrComputeRender(A){let t=this.renderCache.get(A.path);if(t&&t.mtime===A.stat.mtime)return St.record("render.row.cacheHit",0),t;let e=await St.timeAsync("render.row.read",()=>this.host.app.vault.cachedRead(A)),i=this.host.stripFrontmatter(e),{text:s,attachments:n}=this.splitAttachments(i),o=createDiv({cls:"stashpad-note-text"});await St.timeAsync("render.row.markdown",()=>mn.MarkdownRenderer.render(this.host.app,s,o,A.path,this.component));let r=o.innerHTML,a={mtime:A.stat.mtime,text:s,attachments:n,html:r};return this.renderCache.set(A.path,a),a}arm(){this.bodyObserver?.disconnect(),this.lazyBodies=new WeakMap,this.bodyObserver=new IntersectionObserver(A=>{for(let t of A){if(!t.isIntersecting)continue;let e=t.target,i=this.lazyBodies.get(e);this.bodyObserver?.unobserve(e),this.lazyBodies.delete(e),i&&i()}},{root:this.host.contentEl,rootMargin:"1400px 0px"})}dispose(){this.bodyObserver?.disconnect(),this.bodyObserver=null}isArmed(){return!!this.bodyObserver}hasFreshRenderCache(A){let t=this.renderCache.get(A.path);return!!t&&t.mtime===A.stat.mtime}defer(A,t){this.lazyBodies.set(A,t),this.bodyObserver?.observe(A)}splitAttachments(A){let t=[];return{text:A.replace(/!\[\[([^\]\|]+)(?:\|[^\]]+)?\]\]/g,(i,s)=>(t.push(s),"")).replace(/\n{3,}/g,` -`).trim(),attachments:t}}};function an(h,A,t){return h.tree.getChildren(A).slice().sort((i,s)=>po(h,i,s,t)).map(i=>i.id)}function po(h,A,t,e){switch(e){case"created-asc":return(A.created||"").localeCompare(t.created||"");case"created-desc":return(t.created||"").localeCompare(A.created||"");case"modified-asc":case"modified-desc":{let i=on(h,A)||A.created||"",s=on(h,t)||t.created||"";return e==="modified-asc"?i.localeCompare(s):s.localeCompare(i)}case"title-az":case"title-za":{let i=h.titleForNode(A),s=h.titleForNode(t),n={numeric:!0,sensitivity:"base"};return e==="title-az"?i.localeCompare(s,void 0,n):s.localeCompare(i,void 0,n)}default:return 0}}function on(h,A){if(!A.file)return"";let t=h.app.metadataCache.getFileCache(A.file)?.frontmatter;return(typeof t?.modified=="string"?t.modified:"")||""}var Ee=require("obsidian");var rn=require("obsidian");function Zt(h,A,t){h.empty();try{(0,rn.setIcon)(h,A)}catch{}let e=h.querySelector("svg");e&&e.querySelector("path, line, circle, rect, polyline, polygon, ellipse")||(h.empty(),h.createSpan({cls:"stashpad-icon-fallback",text:t}))}function An(h){if(h instanceof Element&&h.closest(".modal, .modal-container, .suggestion-container, .menu, .prompt"))return!0;let A=new Set([document]);h instanceof Element&&h.ownerDocument&&A.add(h.ownerDocument);for(let t of A)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}function cn(h){let A=[],t=/^([ \t]*)(`{3,})[ \t]*([^\n`]*)\n([\s\S]*?)\n\1\2[ \t]*$/gm,e;for(;(e=t.exec(h))!=null;)A.push({lang:e[3].trim(),code:e[4]});return A}function Xe(h){return h.split("/").map(A=>A.split(" ").map(t=>t&&/^[a-z]/.test(t)?t[0].toUpperCase()+t.slice(1):t).join(" ")).join("/")}function ln(h,A,t){let e=new Set(A),i=h.filter(n=>!e.has(n)),s=h.findIndex(n=>e.has(n));if(s<0)return h.slice();switch(t){case"top":return[...A,...i];case"bottom":return[...i,...A];case"up":{let n=Math.max(0,s-1),o=i.slice();return o.splice(n,0,...A),o}case"down":{let n=(()=>{let c=-1;return h.forEach((l,d)=>{e.has(l)&&(c=d)}),c})(),o=0;for(let c=0;c<Math.min(h.length,n+2);c++)e.has(h[c])||o++;let a=Math.min(i.length,o),r=i.slice();return r.splice(a,0,...A),r}}}function Is(h,A){if(h.length!==A.length)return!1;for(let t=0;t<h.length;t++)if(h[t]!==A[t])return!1;return!0}async function dn(h){let A=h.getActionTargets();if(!A.length)return;let t=Bt().prefixTimestampsOnCopy,e=[];for(let i of A){if(!i.file)continue;let s=await h.app.vault.cachedRead(i.file),n=h.stripFrontmatter(s).trim();e.push(t?`${h.formatTimeInline(i.created)} ${n}`:n)}await navigator.clipboard.writeText(e.join(` +`).trim(),attachments:t}}};function En(d,A,t){return d.tree.getChildren(A).slice().sort((i,s)=>To(d,i,s,t)).map(i=>i.id)}function To(d,A,t,e){switch(e){case"created-asc":return(A.created||"").localeCompare(t.created||"");case"created-desc":return(t.created||"").localeCompare(A.created||"");case"modified-asc":case"modified-desc":{let i=Qn(d,A)||A.created||"",s=Qn(d,t)||t.created||"";return e==="modified-asc"?i.localeCompare(s):s.localeCompare(i)}case"title-az":case"title-za":{let i=d.titleForNode(A),s=d.titleForNode(t),n={numeric:!0,sensitivity:"base"};return e==="title-az"?i.localeCompare(s,void 0,n):s.localeCompare(i,void 0,n)}default:return 0}}function Qn(d,A){if(!A.file)return"";let t=d.app.metadataCache.getFileCache(A.file)?.frontmatter;return(typeof t?.modified=="string"?t.modified:"")||""}var ve=require("obsidian");var yn=require("obsidian");function jt(d,A,t){d.empty();try{(0,yn.setIcon)(d,A)}catch{}let e=d.querySelector("svg");e&&e.querySelector("path, line, circle, rect, polyline, polygon, ellipse")||(d.empty(),d.createSpan({cls:"stashpad-icon-fallback",text:t}))}function wn(d){if(d instanceof Element&&d.closest(".modal, .modal-container, .suggestion-container, .menu, .prompt"))return!0;let A=new Set([document]);d instanceof Element&&d.ownerDocument&&A.add(d.ownerDocument);for(let t of A)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}function Fn(d){let A=[],t=/^([ \t]*)(`{3,})[ \t]*([^\n`]*)\n([\s\S]*?)\n\1\2[ \t]*$/gm,e;for(;(e=t.exec(d))!=null;)A.push({lang:e[3].trim(),code:e[4]});return A}function ti(d){return d.split("/").map(A=>A.split(" ").map(t=>t&&/^[a-z]/.test(t)?t[0].toUpperCase()+t.slice(1):t).join(" ")).join("/")}function vn(d,A,t){let e=new Set(A),i=d.filter(n=>!e.has(n)),s=d.findIndex(n=>e.has(n));if(s<0)return d.slice();switch(t){case"top":return[...A,...i];case"bottom":return[...i,...A];case"up":{let n=Math.max(0,s-1),o=i.slice();return o.splice(n,0,...A),o}case"down":{let n=(()=>{let c=-1;return d.forEach((l,p)=>{e.has(l)&&(c=p)}),c})(),o=0;for(let c=0;c<Math.min(d.length,n+2);c++)e.has(d[c])||o++;let r=Math.min(i.length,o),a=i.slice();return a.splice(r,0,...A),a}}}function ys(d,A){if(d.length!==A.length)return!1;for(let t=0;t<d.length;t++)if(d[t]!==A[t])return!1;return!0}async function kn(d){let A=d.getActionTargets();if(!A.length)return;let t=ft().prefixTimestampsOnCopy,e=[];for(let i of A){if(!i.file)continue;let s=await d.app.vault.cachedRead(i.file),n=d.stripFrontmatter(s).trim();e.push(t?`${d.formatTimeInline(i.created)} ${n}`:n)}await navigator.clipboard.writeText(e.join(` -`)),h.plugin.notifications.show({message:`Copied ${h.titleList(A)} to clipboard`,kind:"success",category:"system",affectedIds:A.map(i=>i.id),folder:h.noteFolder})}async function hn(h){let A=h.getActionTargets();if(!A.length||!A[0].file){new Ee.Notice("Nothing to copy from.");return}let t=A[0],e=await h.app.vault.cachedRead(t.file),i=h.stripFrontmatter(e),s=cn(i);if(s.length===0){h.plugin.notifications.show({message:`No codeblock found in "${h.titleForNode(t)}".`,kind:"info",category:"system",affectedIds:[t.id],folder:h.noteFolder});return}if(s.length===1){await navigator.clipboard.writeText(s[0].code),h.plugin.notifications.show({message:`Copied codeblock${s[0].lang?` (${s[0].lang})`:""} from "${h.titleForNode(t)}".`,kind:"success",category:"system",affectedIds:[t.id],folder:h.noteFolder});return}let n=s.map((a,r)=>({kind:"one",idx:r,label:`${r+1}. ${a.lang||"(no language)"} \u2014 ${a.code.split(` -`)[0].slice(0,60)}${a.code.includes(` -`)?"\u2026":""}`}));n.push({kind:"all",idx:-1,label:`Copy all ${s.length} blocks (joined with blank lines)`});let o=new class extends Ee.SuggestModal{getSuggestions(a){let r=a.trim().toLowerCase();if(!r)return n;let c=r.split(/\s+/).filter(Boolean);return n.filter(l=>{let d=l.label.toLowerCase();return c.every(I=>d.includes(I))})}renderSuggestion(a,r){r.createDiv({cls:"stashpad-suggest-title",text:a.label})}async onChooseSuggestion(a){let r=a.kind==="all"?s.map(c=>c.code).join(` +`)),d.plugin.notifications.show({message:`Copied ${d.titleList(A)} to clipboard`,kind:"success",category:"system",affectedIds:A.map(i=>i.id),folder:d.noteFolder})}async function Sn(d){let A=d.getActionTargets();if(!A.length||!A[0].file){new ve.Notice("Nothing to copy from.");return}let t=A[0],e=await d.app.vault.cachedRead(t.file),i=d.stripFrontmatter(e),s=Fn(i);if(s.length===0){d.plugin.notifications.show({message:`No codeblock found in "${d.titleForNode(t)}".`,kind:"info",category:"system",affectedIds:[t.id],folder:d.noteFolder});return}if(s.length===1){await navigator.clipboard.writeText(s[0].code),d.plugin.notifications.show({message:`Copied codeblock${s[0].lang?` (${s[0].lang})`:""} from "${d.titleForNode(t)}".`,kind:"success",category:"system",affectedIds:[t.id],folder:d.noteFolder});return}let n=s.map((r,a)=>({kind:"one",idx:a,label:`${a+1}. ${r.lang||"(no language)"} \u2014 ${r.code.split(` +`)[0].slice(0,60)}${r.code.includes(` +`)?"\u2026":""}`}));n.push({kind:"all",idx:-1,label:`Copy all ${s.length} blocks (joined with blank lines)`});let o=new class extends ve.SuggestModal{getSuggestions(r){let a=r.trim().toLowerCase();if(!a)return n;let c=a.split(/\s+/).filter(Boolean);return n.filter(l=>{let p=l.label.toLowerCase();return c.every(g=>p.includes(g))})}renderSuggestion(r,a){a.createDiv({cls:"stashpad-suggest-title",text:r.label})}async onChooseSuggestion(r){let a=r.kind==="all"?s.map(c=>c.code).join(` -`):s[a.idx].code;await navigator.clipboard.writeText(r),h.plugin.notifications.show({message:a.kind==="all"?`Copied all ${s.length} codeblocks from "${h.titleForNode(t)}".`:`Copied codeblock${s[a.idx].lang?` (${s[a.idx].lang})`:""} from "${h.titleForNode(t)}".`,kind:"success",category:"system",affectedIds:[t.id],folder:h.noteFolder})}}(h.app);o.setPlaceholder(`${s.length} codeblocks in "${h.titleForNode(t)}" \u2014 pick one to copy.`),o.open()}async function gn(h){let A=h.getActionTargets();if(A.length===0){let s=h.tree.get(h.focusId);s?.file&&(A=[s])}if(A.length===0){new Ee.Notice("Nothing to copy.");return}let t=Bt().prefixTimestampsOnCopy,e=[],i=async(s,n)=>{if(s.file){let o=await h.app.vault.cachedRead(s.file),a=h.stripFrontmatter(o).trim().split(/\r?\n/).join(" "),r=t?`${h.formatTimeInline(s.created)} `:"";e.push(`${" ".repeat(n)}- ${r}${a}`)}for(let o of h.tree.getChildren(s.id))await i(o,n+1)};for(let s of A)await i(s,0);await navigator.clipboard.writeText(e.join(` -`)),h.plugin.notifications.show({message:`Copied tree of ${h.titleList(A)} (${e.length} entries)`,kind:"success",category:"system",affectedIds:A.map(s=>s.id),folder:h.noteFolder})}async function In(h){let A=h.getActionTargets();if(A.length===0){let i=h.tree.get(h.focusId);i?.file&&(A=[i])}if(A.length===0){new Ee.Notice("Nothing to copy.");return}let t=[],e=(i,s)=>{if(!i.file)return;let n=" ".repeat(s);t.push(`${n}- ![[${i.file.basename}]]`);for(let o of h.tree.getChildren(i.id))e(o,s+1)};for(let i of A)e(i,0);await navigator.clipboard.writeText(t.join(` -`)),h.plugin.notifications.show({message:`Copied outline of ${h.titleList(A)} (${t.length} entr${t.length===1?"y":"ies"})`,kind:"success",category:"system",affectedIds:A.map(i=>i.id),folder:h.noteFolder})}var jt=require("obsidian");yt();var fs=jn(un()),Mi=require("obsidian");Tt();yt();var _t="stash",Cn=1;function fn(h){let t=(h.split(/[\\/]/).pop()??"").trim();return!t||t==="."||t===".."||t.includes("/")||t.includes("\\")||t.includes("..")?"":t}var us=/!\[\[([^\]\|]+)(?:\|[^\]]+)?\]\]/g;async function Qn(h,A){let t=new fs.default,e=fo([...A.rootNotes,...A.allDescendants]),i=new Map,s=[];for(let o of e){let a=await h.vault.read(o.file),r=a,c=Bo(a);for(let l of c){let d=h.metadataCache.getFirstLinkpathDest(l,o.file.path);if(!d){s.push(`Missing attachment "${l}" in ${o.file.path}`);continue}let I=d.name;i.has(I)||i.set(I,await h.vault.readBinary(d)),r=Co(r,l,I)}r=mo(r,h,o.file.path),t.file(`notes/${o.file.name}`,r)}for(let[o,a]of i)t.file(`attachments/${o}`,a);let n={stashSchema:Cn,exportedAt:new Date().toISOString(),sourceFolder:A.sourceFolder,noteCount:e.length,rootIds:A.rootNotes.map(o=>o.id)};return t.file("manifest.json",JSON.stringify(n,null,2)),s.length&&t.file("warnings.txt",s.join(` -`)),t.generateAsync({type:"uint8array",compression:"DEFLATE",compressionOptions:{level:6}})}async function ye(h,A,t,e){let i=await fs.default.loadAsync(A),s=i.file("manifest.json");if(!s)throw new Error("Not a valid .stash package: missing manifest.json");let n=JSON.parse(await s.async("string"));if(typeof n.stashSchema!="number"||n.stashSchema>Cn)throw new Error(`Unsupported .stash schema: v${n.stashSchema}`);await Bn(h,t);let o=Object.values(i.files).filter(f=>!f.dir&&f.name.startsWith("notes/")&&f.name.endsWith(".md")),a=[];for(let f of o){let B=await f.async("string"),{fm:Q,body:E}=we(B),y=fn(f.name.slice(6))||`${Q.id||"imported-"+mt(4)}.md`;a.push({originalName:y,fm:Q,body:E})}let r=new Map,c=0;for(let f of a){let B=f.fm.id;B&&(e.has(B)||r.has(B)?(r.set(B,`${B}-${mt(4)}-Imported`),c++):r.set(B,B))}let l=new Date().toISOString(),d=[],I=`${t}/_attachments`,g=0,p=Object.values(i.files).filter(f=>!f.dir&&f.name.startsWith("attachments/"));p.length>0&&await Bn(h,I);for(let f of p){let B=fn(f.name.slice(12));if(!B)continue;let Q=`${I}/${B}`;if(await h.vault.adapter.exists(Q))continue;let E=await f.async("arraybuffer");await h.vault.createBinary(Q,E),g++}let u=0;for(let f of a){let B=f.fm.id;if(!B){d.push(`Skipped ${f.originalName} \u2014 no id in frontmatter`);continue}let Q=r.get(B),E=f.fm.parent??null,y=E;E&&E!==G&&r.has(E)?y=r.get(E):E&&E!==G&&!r.has(E)&&(y=G);let v=Qo(f.body,I),k={...f.fm,id:Q,parent:y,import_date:l};Array.isArray(k.attachments)&&(k.attachments=k.attachments.map(D=>ie(`${I}/${mn(he(D))}`)));let b=$t(k,v),R=Q===B?f.originalName:yo(f.originalName,B,Q),w=`${t}/${R}`;await h.vault.adapter.exists(w)&&(R=`${R.replace(/\.md$/,"")}-${mt(4)}.md`,w=`${t}/${R}`),await h.vault.create(w,b),u++}return{notesWritten:u,attachmentsWritten:g,collisionsRenamed:c,warnings:d}}function fo(h){let A=new Set,t=[];for(let e of h)A.has(e.id)||(A.add(e.id),t.push(e));return t}function Bo(h){let A=new Set,t;for(us.lastIndex=0;(t=us.exec(h))!==null;)A.add(t[1]);return[...A]}function Co(h,A,t){return h.replace(new RegExp(`!\\[\\[${Eo(A)}(\\|[^\\]]+)?\\]\\]`,"g"),(e,i)=>`![[${t}${i??""}]]`)}function Qo(h,A){return h.replace(us,(t,e,i)=>e.includes("/")?t:t.replace(e,`${A}/${e}`))}function mo(h,A,t){let e=we(h);if(!e.fm.attachments||!Array.isArray(e.fm.attachments))return h;let i=e.fm.attachments.map(n=>{let o=A.metadataCache.getFirstLinkpathDest(n,t);return o?o.name:mn(n)}),s={...e.fm,attachments:i};return $t(s,e.body)}function Eo(h){return h.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function mn(h){let A=h.lastIndexOf("/");return A<0?h:h.slice(A+1)}function yo(h,A,t){return h.includes(A)?h.replace(A,t):h.replace(/\.md$/,`-${t}.md`)}function we(h){if(!h.startsWith("---"))return{fm:{},body:h};let A=h.indexOf(` ----`,3);if(A<0)return{fm:{},body:h};let t=h.slice(3,A).replace(/^\n/,""),e=h.slice(A+4),i={};try{i=(0,Mi.parseYaml)(t)??{}}catch{i={}}let s=e.startsWith(` -`)?e.slice(1):e;return{fm:i,body:s}}function $t(h,A){return`--- -${(0,Mi.stringifyYaml)(h).trimEnd()} +`):s[r.idx].code;await navigator.clipboard.writeText(a),d.plugin.notifications.show({message:r.kind==="all"?`Copied all ${s.length} codeblocks from "${d.titleForNode(t)}".`:`Copied codeblock${s[r.idx].lang?` (${s[r.idx].lang})`:""} from "${d.titleForNode(t)}".`,kind:"success",category:"system",affectedIds:[t.id],folder:d.noteFolder})}}(d.app);o.setPlaceholder(`${s.length} codeblocks in "${d.titleForNode(t)}" \u2014 pick one to copy.`),o.open()}async function Dn(d){let A=d.getActionTargets();if(A.length===0){let s=d.tree.get(d.focusId);s?.file&&(A=[s])}if(A.length===0){new ve.Notice("Nothing to copy.");return}let t=ft().prefixTimestampsOnCopy,e=[],i=async(s,n)=>{if(s.file){let o=await d.app.vault.cachedRead(s.file),r=d.stripFrontmatter(o).trim().split(/\r?\n/).join(" "),a=t?`${d.formatTimeInline(s.created)} `:"";e.push(`${" ".repeat(n)}- ${a}${r}`)}for(let o of d.tree.getChildren(s.id))await i(o,n+1)};for(let s of A)await i(s,0);await navigator.clipboard.writeText(e.join(` +`)),d.plugin.notifications.show({message:`Copied tree of ${d.titleList(A)} (${e.length} entries)`,kind:"success",category:"system",affectedIds:A.map(s=>s.id),folder:d.noteFolder})}async function bn(d){let A=d.getActionTargets();if(A.length===0){let i=d.tree.get(d.focusId);i?.file&&(A=[i])}if(A.length===0){new ve.Notice("Nothing to copy.");return}let t=[],e=(i,s)=>{if(!i.file)return;let n=" ".repeat(s);t.push(`${n}- ![[${i.file.basename}]]`);for(let o of d.tree.getChildren(i.id))e(o,s+1)};for(let i of A)e(i,0);await navigator.clipboard.writeText(t.join(` +`)),d.plugin.notifications.show({message:`Copied outline of ${d.titleList(A)} (${t.length} entr${t.length===1?"y":"ies"})`,kind:"success",category:"system",affectedIds:A.map(i=>i.id),folder:d.noteFolder})}var ie=require("obsidian");wt();var vs=fo(xn()),Ji=require("obsidian");Rt();wt();var te="stash",Tn=1;function Mn(d){let t=(d.split(/[\\/]/).pop()??"").trim();return!t||t==="."||t===".."||t.includes("/")||t.includes("\\")||t.includes("..")?"":t}var Fs=/!\[\[([^\]\|]+)(?:\|[^\]]+)?\]\]/g;async function Un(d,A){let t=new vs.default,e=Go([...A.rootNotes,...A.allDescendants]),i=new Map,s=[];for(let o of e){let r=await d.vault.read(o.file),a=r,c=Ro(r);for(let l of c){let p=d.metadataCache.getFirstLinkpathDest(l,o.file.path);if(!p){s.push(`Missing attachment "${l}" in ${o.file.path}`);continue}let g=p.name;i.has(g)||i.set(g,await d.vault.readBinary(p)),a=Po(a,l,g)}a=Jo(a,d,o.file.path),t.file(`notes/${o.file.name}`,a)}for(let[o,r]of i)t.file(`attachments/${o}`,r);let n={stashSchema:Tn,exportedAt:new Date().toISOString(),sourceFolder:A.sourceFolder,noteCount:e.length,rootIds:A.rootNotes.map(o=>o.id)};return t.file("manifest.json",JSON.stringify(n,null,2)),s.length&&t.file("warnings.txt",s.join(` +`)),t.generateAsync({type:"uint8array",compression:"DEFLATE",compressionOptions:{level:6}})}async function ke(d,A,t,e){let i=await vs.default.loadAsync(A),s=i.file("manifest.json");if(!s)throw new Error("Not a valid .stash package: missing manifest.json");let n=JSON.parse(await s.async("string"));if(typeof n.stashSchema!="number"||n.stashSchema>Tn)throw new Error(`Unsupported .stash schema: v${n.stashSchema}`);await Hn(d,t);let o=Object.values(i.files).filter(f=>!f.dir&&f.name.startsWith("notes/")&&f.name.endsWith(".md")),r=[];for(let f of o){let C=await f.async("string"),{fm:m,body:E}=Se(C),y=Mn(f.name.slice(6))||`${m.id||"imported-"+Et(4)}.md`;r.push({originalName:y,fm:m,body:E})}let a=new Map,c=0;for(let f of r){let C=f.fm.id;C&&(e.has(C)||a.has(C)?(a.set(C,`${C}-${Et(4)}-Imported`),c++):a.set(C,C))}let l=new Date().toISOString(),p=[],g=`${t}/_attachments`,h=0,I=Object.values(i.files).filter(f=>!f.dir&&f.name.startsWith("attachments/"));I.length>0&&await Hn(d,g);for(let f of I){let C=Mn(f.name.slice(12));if(!C)continue;let m=`${g}/${C}`;if(await d.vault.adapter.exists(m))continue;let E=await f.async("arraybuffer");await d.vault.createBinary(m,E),h++}let u=0;for(let f of r){let C=f.fm.id;if(!C){p.push(`Skipped ${f.originalName} \u2014 no id in frontmatter`);continue}let m=a.get(C),E=f.fm.parent??null,y=E;E&&E!==G&&a.has(E)?y=a.get(E):E&&E!==G&&!a.has(E)&&(y=G);let w=Lo(f.body,g),v={...f.fm,id:m,parent:y,import_date:l};Array.isArray(v.attachments)&&(v.attachments=v.attachments.map(b=>Gt(`${g}/${Gn(oe(b))}`)));let D=ee(v,w),L=m===C?f.originalName:Oo(f.originalName,C,m),S=`${t}/${L}`;await d.vault.adapter.exists(S)&&(L=`${L.replace(/\.md$/,"")}-${Et(4)}.md`,S=`${t}/${L}`),await d.vault.create(S,D),u++}return{notesWritten:u,attachmentsWritten:h,collisionsRenamed:c,warnings:p}}function Go(d){let A=new Set,t=[];for(let e of d)A.has(e.id)||(A.add(e.id),t.push(e));return t}function Ro(d){let A=new Set,t;for(Fs.lastIndex=0;(t=Fs.exec(d))!==null;)A.add(t[1]);return[...A]}function Po(d,A,t){return d.replace(new RegExp(`!\\[\\[${qo(A)}(\\|[^\\]]+)?\\]\\]`,"g"),(e,i)=>`![[${t}${i??""}]]`)}function Lo(d,A){return d.replace(Fs,(t,e,i)=>e.includes("/")?t:t.replace(e,`${A}/${e}`))}function Jo(d,A,t){let e=Se(d);if(!e.fm.attachments||!Array.isArray(e.fm.attachments))return d;let i=e.fm.attachments.map(n=>{let o=A.metadataCache.getFirstLinkpathDest(n,t);return o?o.name:Gn(n)}),s={...e.fm,attachments:i};return ee(s,e.body)}function qo(d){return d.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Gn(d){let A=d.lastIndexOf("/");return A<0?d:d.slice(A+1)}function Oo(d,A,t){return d.includes(A)?d.replace(A,t):d.replace(/\.md$/,`-${t}.md`)}function Se(d){if(!d.startsWith("---"))return{fm:{},body:d};let A=d.indexOf(` +---`,3);if(A<0)return{fm:{},body:d};let t=d.slice(3,A).replace(/^\n/,""),e=d.slice(A+4),i={};try{i=(0,Ji.parseYaml)(t)??{}}catch{i={}}let s=e.startsWith(` +`)?e.slice(1):e;return{fm:i,body:s}}function ee(d,A){return`--- +${(0,Ji.stringifyYaml)(d).trimEnd()} --- -${A}`}async function Bn(h,A){if(!(!A||await h.vault.adapter.exists(A)))try{await h.vault.createFolder(A)}catch(e){let i=e?.message??"";if(!/already exists/i.test(i))throw e}}function ce(h,A,t,e){function i(s){return s instanceof t?s:new t(function(n){n(s)})}return new(t||(t=Promise))(function(s,n){function o(c){try{r(e.next(c))}catch(l){n(l)}}function a(c){try{r(e.throw(c))}catch(l){n(l)}}function r(c){c.done?s(c.value):i(c.value).then(o,a)}r((e=e.apply(h,A||[])).next())})}var ft=class{constructor(){this.mutex=Promise.resolve()}lock(){let A=()=>{};return this.mutex=this.mutex.then(()=>new Promise(A)),new Promise(t=>{A=t})}dispatch(A){return ce(this,void 0,void 0,function*(){let t=yield this.lock();try{return yield Promise.resolve(A())}finally{t()}})}},Bs;function wo(){return typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:global}var Es=wo(),Cs=(Bs=Es.Buffer)!==null&&Bs!==void 0?Bs:null,Fo=Es.TextEncoder?new Es.TextEncoder:null;function kn(h,A){return(h&15)+(h>>6|h>>3&8)<<4|(A&15)+(A>>6|A>>3&8)}function Sn(h,A){let t=A.length>>1;for(let e=0;e<t;e++){let i=e<<1;h[e]=kn(A.charCodeAt(i),A.charCodeAt(i+1))}}function vo(h,A){if(h.length!==A.length*2)return!1;for(let t=0;t<A.length;t++){let e=t<<1;if(A[t]!==kn(h.charCodeAt(e),h.charCodeAt(e+1)))return!1}return!0}var En=87,yn=48;function ys(h,A,t){let e=0;for(let i=0;i<t;i++){let s=A[i]>>>4;h[e++]=s>9?s+En:s+yn,s=A[i]&15,h[e++]=s>9?s+En:s+yn}return String.fromCharCode.apply(null,h)}var Kt=Cs!==null?h=>{if(typeof h=="string"){let A=Cs.from(h,"utf8");return new Uint8Array(A.buffer,A.byteOffset,A.length)}if(Cs.isBuffer(h))return new Uint8Array(h.buffer,h.byteOffset,h.length);if(ArrayBuffer.isView(h))return new Uint8Array(h.buffer,h.byteOffset,h.byteLength);throw new Error("Invalid data type!")}:h=>{if(typeof h=="string")return Fo.encode(h);if(ArrayBuffer.isView(h))return new Uint8Array(h.buffer,h.byteOffset,h.byteLength);throw new Error("Invalid data type!")},Ht="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",_e=new Uint8Array(256);for(let h=0;h<Ht.length;h++)_e[Ht.charCodeAt(h)]=h;function wn(h,A=!0){let t=h.length,e=t%3,i=[],s=t-e;for(let n=0;n<s;n+=3){let o=(h[n]<<16&16711680)+(h[n+1]<<8&65280)+(h[n+2]&255),a=Ht.charAt(o>>18&63)+Ht.charAt(o>>12&63)+Ht.charAt(o>>6&63)+Ht.charAt(o&63);i.push(a)}if(e===1){let n=h[t-1],o=Ht.charAt(n>>2),a=Ht.charAt(n<<4&63);i.push(`${o}${a}`),A&&i.push("==")}else if(e===2){let n=(h[t-2]<<8)+h[t-1],o=Ht.charAt(n>>10),a=Ht.charAt(n>>4&63),r=Ht.charAt(n<<2&63);i.push(`${o}${a}${r}`),A&&i.push("=")}return i.join("")}function ko(h){let A=Math.floor(h.length*.75),t=h.length;return h[t-1]==="="&&(A-=1,h[t-2]==="="&&(A-=1)),A}function So(h){let A=ko(h),t=h.length,e=new Uint8Array(A),i=0;for(let s=0;s<t;s+=4){let n=_e[h.charCodeAt(s)],o=_e[h.charCodeAt(s+1)],a=_e[h.charCodeAt(s+2)],r=_e[h.charCodeAt(s+3)];e[i]=n<<2|o>>4,i+=1,e[i]=(o&15)<<4|a>>2,i+=1,e[i]=(a&3)<<6|r&63,i+=1}return e}var Hi=16*1024,Ze=4,Do=new ft,Qs=new Map;function Dn(h,A){return ce(this,void 0,void 0,function*(){let t=null,e=null,i=!1;if(typeof WebAssembly>"u")throw new Error("WebAssembly is not supported in this environment!");let s=(v,k=0)=>{e.set(v,k)},n=()=>e,o=()=>t.exports,a=v=>{t.exports.Hash_SetMemorySize(v);let k=t.exports.Hash_GetBuffer(),b=t.exports.memory.buffer;e=new Uint8Array(b,k,v)},r=()=>new DataView(t.exports.memory.buffer).getUint32(t.exports.STATE_SIZE,!0),c=Do.dispatch(()=>ce(this,void 0,void 0,function*(){if(!Qs.has(h.name)){let k=So(h.data),b=WebAssembly.compile(k);Qs.set(h.name,b)}let v=yield Qs.get(h.name);t=yield WebAssembly.instantiate(v,{})})),l=()=>ce(this,void 0,void 0,function*(){t||(yield c);let v=t.exports.Hash_GetBuffer(),k=t.exports.memory.buffer;e=new Uint8Array(k,v,Hi)}),d=(v=null)=>{i=!0,t.exports.Hash_Init(v)},I=v=>{let k=0;for(;k<v.length;){let b=v.subarray(k,k+Hi);k+=b.length,e.set(b),t.exports.Hash_Update(b.length)}},g=v=>{if(!i)throw new Error("update() called before init()");let k=Kt(v);I(k)},p=new Uint8Array(A*2),u=(v,k=null)=>{if(!i)throw new Error("digest() called before init()");return i=!1,t.exports.Hash_Final(k),v==="binary"?e.slice(0,A):ys(p,e,A)},f=()=>{if(!i)throw new Error("save() can only be called after init() and before digest()");let v=t.exports.Hash_GetState(),k=r(),b=t.exports.memory.buffer,R=new Uint8Array(b,v,k),w=new Uint8Array(Ze+k);return Sn(w,h.hash),w.set(R,Ze),w},B=v=>{if(!(v instanceof Uint8Array))throw new Error("load() expects an Uint8Array generated by save()");let k=t.exports.Hash_GetState(),b=r(),R=Ze+b,w=t.exports.memory.buffer;if(v.length!==R)throw new Error(`Bad state length (expected ${R} bytes, got ${v.length})`);if(!vo(h.hash,v.subarray(0,Ze)))throw new Error("This state was written by an incompatible hash implementation");let D=v.subarray(Ze);new Uint8Array(w,k,b).set(D),i=!0},Q=v=>typeof v=="string"?v.length<Hi/4:v.byteLength<Hi,E=Q;switch(h.name){case"argon2":case"scrypt":E=()=>!0;break;case"blake2b":case"blake2s":E=(v,k)=>k<=512&&Q(v);break;case"blake3":E=(v,k)=>k===0&&Q(v);break;case"xxhash64":case"xxhash3":case"xxhash128":case"crc64":E=()=>!1;break}let y=(v,k=null,b=null)=>{if(!E(v,k))return d(k),g(v),u("hex",b);let R=Kt(v);return e.set(R),t.exports.Hash_Calculate(R.length,k,b),ys(p,e,A)};return yield l(),{getMemory:n,writeMemory:s,getExports:o,setMemorySize:a,init:d,update:g,digest:u,save:f,load:B,calculate:y,hashLength:A}})}var Pr=new ft;var bo="argon2",No="AGFzbQEAAAABKQVgAX8Bf2AAAX9gEH9/f39/f39/f39/f39/f38AYAR/f39/AGACf38AAwYFAAECAwQFBgEBAoCAAgYIAX8BQZCoBAsHQQQGbWVtb3J5AgASSGFzaF9TZXRNZW1vcnlTaXplAAAOSGFzaF9HZXRCdWZmZXIAAQ5IYXNoX0NhbGN1bGF0ZQAECvEyBVgBAn9BACEBAkAgAEEAKAKICCICRg0AAkAgACACayIAQRB2IABBgIB8cSAASWoiAEAAQX9HDQBB/wHADwtBACEBQQBBACkDiAggAEEQdK18NwOICAsgAcALcAECfwJAQQAoAoAIIgANAEEAPwBBEHQiADYCgAhBACgCiAgiAUGAgCBGDQACQEGAgCAgAWsiAEEQdiAAQYCAfHEgAElqIgBAAEF/Rw0AQQAPC0EAQQApA4gIIABBEHStfDcDiAhBACgCgAghAAsgAAvcDgECfiAAIAQpAwAiECAAKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACAMIBAgDCkDAIVCIIkiEDcDACAIIBAgCCkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgBCAQIAQpAwCFQiiJIhA3AwAgACAQIAApAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIAwgECAMKQMAhUIwiSIQNwMAIAggECAIKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAEIBAgBCkDAIVCAYk3AwAgASAFKQMAIhAgASkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgDSAQIA0pAwCFQiCJIhA3AwAgCSAQIAkpAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIAUgECAFKQMAhUIoiSIQNwMAIAEgECABKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACANIBAgDSkDAIVCMIkiEDcDACAJIBAgCSkDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgBSAQIAUpAwCFQgGJNwMAIAIgBikDACIQIAIpAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIA4gECAOKQMAhUIgiSIQNwMAIAogECAKKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACAGIBAgBikDAIVCKIkiEDcDACACIBAgAikDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgDiAQIA4pAwCFQjCJIhA3AwAgCiAQIAopAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIAYgECAGKQMAhUIBiTcDACADIAcpAwAiECADKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACAPIBAgDykDAIVCIIkiEDcDACALIBAgCykDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgByAQIAcpAwCFQiiJIhA3AwAgAyAQIAMpAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIA8gECAPKQMAhUIwiSIQNwMAIAsgECALKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAHIBAgBykDAIVCAYk3AwAgACAFKQMAIhAgACkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgDyAQIA8pAwCFQiCJIhA3AwAgCiAQIAopAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIAUgECAFKQMAhUIoiSIQNwMAIAAgECAAKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAPIBAgDykDAIVCMIkiEDcDACAKIBAgCikDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgBSAQIAUpAwCFQgGJNwMAIAEgBikDACIQIAEpAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIAwgECAMKQMAhUIgiSIQNwMAIAsgECALKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACAGIBAgBikDAIVCKIkiEDcDACABIBAgASkDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgDCAQIAwpAwCFQjCJIhA3AwAgCyAQIAspAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIAYgECAGKQMAhUIBiTcDACACIAcpAwAiECACKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACANIBAgDSkDAIVCIIkiEDcDACAIIBAgCCkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgByAQIAcpAwCFQiiJIhA3AwAgAiAQIAIpAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIA0gECANKQMAhUIwiSIQNwMAIAggECAIKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAHIBAgBykDAIVCAYk3AwAgAyAEKQMAIhAgAykDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgDiAQIA4pAwCFQiCJIhA3AwAgCSAQIAkpAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIAQgECAEKQMAhUIoiSIQNwMAIAMgECADKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAOIBAgDikDAIVCMIkiEDcDACAJIBAgCSkDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgBCAQIAQpAwCFQgGJNwMAC98aAQN/QQAhBEEAIAIpAwAgASkDAIU3A5AIQQAgAikDCCABKQMIhTcDmAhBACACKQMQIAEpAxCFNwOgCEEAIAIpAxggASkDGIU3A6gIQQAgAikDICABKQMghTcDsAhBACACKQMoIAEpAyiFNwO4CEEAIAIpAzAgASkDMIU3A8AIQQAgAikDOCABKQM4hTcDyAhBACACKQNAIAEpA0CFNwPQCEEAIAIpA0ggASkDSIU3A9gIQQAgAikDUCABKQNQhTcD4AhBACACKQNYIAEpA1iFNwPoCEEAIAIpA2AgASkDYIU3A/AIQQAgAikDaCABKQNohTcD+AhBACACKQNwIAEpA3CFNwOACUEAIAIpA3ggASkDeIU3A4gJQQAgAikDgAEgASkDgAGFNwOQCUEAIAIpA4gBIAEpA4gBhTcDmAlBACACKQOQASABKQOQAYU3A6AJQQAgAikDmAEgASkDmAGFNwOoCUEAIAIpA6ABIAEpA6ABhTcDsAlBACACKQOoASABKQOoAYU3A7gJQQAgAikDsAEgASkDsAGFNwPACUEAIAIpA7gBIAEpA7gBhTcDyAlBACACKQPAASABKQPAAYU3A9AJQQAgAikDyAEgASkDyAGFNwPYCUEAIAIpA9ABIAEpA9ABhTcD4AlBACACKQPYASABKQPYAYU3A+gJQQAgAikD4AEgASkD4AGFNwPwCUEAIAIpA+gBIAEpA+gBhTcD+AlBACACKQPwASABKQPwAYU3A4AKQQAgAikD+AEgASkD+AGFNwOICkEAIAIpA4ACIAEpA4AChTcDkApBACACKQOIAiABKQOIAoU3A5gKQQAgAikDkAIgASkDkAKFNwOgCkEAIAIpA5gCIAEpA5gChTcDqApBACACKQOgAiABKQOgAoU3A7AKQQAgAikDqAIgASkDqAKFNwO4CkEAIAIpA7ACIAEpA7AChTcDwApBACACKQO4AiABKQO4AoU3A8gKQQAgAikDwAIgASkDwAKFNwPQCkEAIAIpA8gCIAEpA8gChTcD2ApBACACKQPQAiABKQPQAoU3A+AKQQAgAikD2AIgASkD2AKFNwPoCkEAIAIpA+ACIAEpA+AChTcD8ApBACACKQPoAiABKQPoAoU3A/gKQQAgAikD8AIgASkD8AKFNwOAC0EAIAIpA/gCIAEpA/gChTcDiAtBACACKQOAAyABKQOAA4U3A5ALQQAgAikDiAMgASkDiAOFNwOYC0EAIAIpA5ADIAEpA5ADhTcDoAtBACACKQOYAyABKQOYA4U3A6gLQQAgAikDoAMgASkDoAOFNwOwC0EAIAIpA6gDIAEpA6gDhTcDuAtBACACKQOwAyABKQOwA4U3A8ALQQAgAikDuAMgASkDuAOFNwPIC0EAIAIpA8ADIAEpA8ADhTcD0AtBACACKQPIAyABKQPIA4U3A9gLQQAgAikD0AMgASkD0AOFNwPgC0EAIAIpA9gDIAEpA9gDhTcD6AtBACACKQPgAyABKQPgA4U3A/ALQQAgAikD6AMgASkD6AOFNwP4C0EAIAIpA/ADIAEpA/ADhTcDgAxBACACKQP4AyABKQP4A4U3A4gMQQAgAikDgAQgASkDgASFNwOQDEEAIAIpA4gEIAEpA4gEhTcDmAxBACACKQOQBCABKQOQBIU3A6AMQQAgAikDmAQgASkDmASFNwOoDEEAIAIpA6AEIAEpA6AEhTcDsAxBACACKQOoBCABKQOoBIU3A7gMQQAgAikDsAQgASkDsASFNwPADEEAIAIpA7gEIAEpA7gEhTcDyAxBACACKQPABCABKQPABIU3A9AMQQAgAikDyAQgASkDyASFNwPYDEEAIAIpA9AEIAEpA9AEhTcD4AxBACACKQPYBCABKQPYBIU3A+gMQQAgAikD4AQgASkD4ASFNwPwDEEAIAIpA+gEIAEpA+gEhTcD+AxBACACKQPwBCABKQPwBIU3A4ANQQAgAikD+AQgASkD+ASFNwOIDUEAIAIpA4AFIAEpA4AFhTcDkA1BACACKQOIBSABKQOIBYU3A5gNQQAgAikDkAUgASkDkAWFNwOgDUEAIAIpA5gFIAEpA5gFhTcDqA1BACACKQOgBSABKQOgBYU3A7ANQQAgAikDqAUgASkDqAWFNwO4DUEAIAIpA7AFIAEpA7AFhTcDwA1BACACKQO4BSABKQO4BYU3A8gNQQAgAikDwAUgASkDwAWFNwPQDUEAIAIpA8gFIAEpA8gFhTcD2A1BACACKQPQBSABKQPQBYU3A+ANQQAgAikD2AUgASkD2AWFNwPoDUEAIAIpA+AFIAEpA+AFhTcD8A1BACACKQPoBSABKQPoBYU3A/gNQQAgAikD8AUgASkD8AWFNwOADkEAIAIpA/gFIAEpA/gFhTcDiA5BACACKQOABiABKQOABoU3A5AOQQAgAikDiAYgASkDiAaFNwOYDkEAIAIpA5AGIAEpA5AGhTcDoA5BACACKQOYBiABKQOYBoU3A6gOQQAgAikDoAYgASkDoAaFNwOwDkEAIAIpA6gGIAEpA6gGhTcDuA5BACACKQOwBiABKQOwBoU3A8AOQQAgAikDuAYgASkDuAaFNwPIDkEAIAIpA8AGIAEpA8AGhTcD0A5BACACKQPIBiABKQPIBoU3A9gOQQAgAikD0AYgASkD0AaFNwPgDkEAIAIpA9gGIAEpA9gGhTcD6A5BACACKQPgBiABKQPgBoU3A/AOQQAgAikD6AYgASkD6AaFNwP4DkEAIAIpA/AGIAEpA/AGhTcDgA9BACACKQP4BiABKQP4BoU3A4gPQQAgAikDgAcgASkDgAeFNwOQD0EAIAIpA4gHIAEpA4gHhTcDmA9BACACKQOQByABKQOQB4U3A6APQQAgAikDmAcgASkDmAeFNwOoD0EAIAIpA6AHIAEpA6AHhTcDsA9BACACKQOoByABKQOoB4U3A7gPQQAgAikDsAcgASkDsAeFNwPAD0EAIAIpA7gHIAEpA7gHhTcDyA9BACACKQPAByABKQPAB4U3A9APQQAgAikDyAcgASkDyAeFNwPYD0EAIAIpA9AHIAEpA9AHhTcD4A9BACACKQPYByABKQPYB4U3A+gPQQAgAikD4AcgASkD4AeFNwPwD0EAIAIpA+gHIAEpA+gHhTcD+A9BACACKQPwByABKQPwB4U3A4AQQQAgAikD+AcgASkD+AeFNwOIEEGQCEGYCEGgCEGoCEGwCEG4CEHACEHICEHQCEHYCEHgCEHoCEHwCEH4CEGACUGICRACQZAJQZgJQaAJQagJQbAJQbgJQcAJQcgJQdAJQdgJQeAJQegJQfAJQfgJQYAKQYgKEAJBkApBmApBoApBqApBsApBuApBwApByApB0ApB2ApB4ApB6ApB8ApB+ApBgAtBiAsQAkGQC0GYC0GgC0GoC0GwC0G4C0HAC0HIC0HQC0HYC0HgC0HoC0HwC0H4C0GADEGIDBACQZAMQZgMQaAMQagMQbAMQbgMQcAMQcgMQdAMQdgMQeAMQegMQfAMQfgMQYANQYgNEAJBkA1BmA1BoA1BqA1BsA1BuA1BwA1ByA1B0A1B2A1B4A1B6A1B8A1B+A1BgA5BiA4QAkGQDkGYDkGgDkGoDkGwDkG4DkHADkHIDkHQDkHYDkHgDkHoDkHwDkH4DkGAD0GIDxACQZAPQZgPQaAPQagPQbAPQbgPQcAPQcgPQdAPQdgPQeAPQegPQfAPQfgPQYAQQYgQEAJBkAhBmAhBkAlBmAlBkApBmApBkAtBmAtBkAxBmAxBkA1BmA1BkA5BmA5BkA9BmA8QAkGgCEGoCEGgCUGoCUGgCkGoCkGgC0GoC0GgDEGoDEGgDUGoDUGgDkGoDkGgD0GoDxACQbAIQbgIQbAJQbgJQbAKQbgKQbALQbgLQbAMQbgMQbANQbgNQbAOQbgOQbAPQbgPEAJBwAhByAhBwAlByAlBwApByApBwAtByAtBwAxByAxBwA1ByA1BwA5ByA5BwA9ByA8QAkHQCEHYCEHQCUHYCUHQCkHYCkHQC0HYC0HQDEHYDEHQDUHYDUHQDkHYDkHQD0HYDxACQeAIQegIQeAJQegJQeAKQegKQeALQegLQeAMQegMQeANQegNQeAOQegOQeAPQegPEAJB8AhB+AhB8AlB+AlB8ApB+ApB8AtB+AtB8AxB+AxB8A1B+A1B8A5B+A5B8A9B+A8QAkGACUGICUGACkGICkGAC0GIC0GADEGIDEGADUGIDUGADkGIDkGAD0GID0GAEEGIEBACAkACQCADRQ0AA0AgACAEaiIDIAIgBGoiBSkDACABIARqIgYpAwCFIARBkAhqKQMAhSADKQMAhTcDACADQQhqIgMgBUEIaikDACAGQQhqKQMAhSAEQZgIaikDAIUgAykDAIU3AwAgBEEQaiIEQYAIRw0ADAILC0EAIQQDQCAAIARqIgMgAiAEaiIFKQMAIAEgBGoiBikDAIUgBEGQCGopAwCFNwMAIANBCGogBUEIaikDACAGQQhqKQMAhSAEQZgIaikDAIU3AwAgBEEQaiIEQYAIRw0ACwsL5QcMBX8BfgR/An4BfwF+AX8Bfgd/AX4DfwF+AkBBACgCgAgiAiABQQp0aiIDKAIIIAFHDQAgAygCDCEEIAMoAgAhBUEAIAMoAhQiBq03A7gQQQAgBK0iBzcDsBBBACAFIAEgBUECdG4iCGwiCUECdK03A6gQAkACQAJAAkAgBEUNAEF/IQogBUUNASAIQQNsIQsgCEECdCIErSEMIAWtIQ0gBkF/akECSSEOQgAhDwNAQQAgDzcDkBAgD6chEEIAIRFBACEBA0BBACARNwOgECAPIBGEUCIDIA5xIRIgBkEBRiAPUCITIAZBAkYgEUICVHFxciEUQX8gAUEBakEDcSAIbEF/aiATGyEVIAEgEHIhFiABIAhsIRcgA0EBdCEYQgAhGQNAQQBCADcDwBBBACAZNwOYECAYIQECQCASRQ0AQQBCATcDwBBBkBhBkBBBkCBBABADQZAYQZAYQZAgQQAQA0ECIQELAkAgASAITw0AIAQgGaciGmwgF2ogAWohAwNAIANBACAEIAEbQQAgEVAiGxtqQX9qIRwCQAJAIBQNAEEAKAKACCICIBxBCnQiHGohCgwBCwJAIAFB/wBxIgINAEEAQQApA8AQQgF8NwPAEEGQGEGQEEGQIEEAEANBkBhBkBhBkCBBABADCyAcQQp0IRwgAkEDdEGQGGohCkEAKAKACCECCyACIANBCnRqIAIgHGogAiAKKQMAIh1CIIinIAVwIBogFhsiHCAEbCABIAFBACAZIBytUSIcGyIKIBsbIBdqIAogC2ogExsgAUUgHHJrIhsgFWqtIB1C/////w+DIh0gHX5CIIggG61+QiCIfSAMgqdqQQp0akEBEAMgA0EBaiEDIAggAUEBaiIBRw0ACwsgGUIBfCIZIA1SDQALIBFCAXwiEachASARQgRSDQALIA9CAXwiDyAHUg0AC0EAKAKACCECCyAJQQx0QYB4aiEXIAVBf2oiCkUNAgwBC0EAQgM3A6AQQQAgBEF/aq03A5AQQYB4IRcLIAIgF2ohGyAIQQx0IQhBACEcA0AgCCAcQQFqIhxsQYB4aiEEQQAhAQNAIBsgAWoiAyADKQMAIAIgBCABamopAwCFNwMAIANBCGoiAyADKQMAIAIgBCABQQhyamopAwCFNwMAIAFBCGohAyABQRBqIQEgA0H4B0kNAAsgHCAKRw0ACwsgAiAXaiEbQXghAQNAIAIgAWoiA0EIaiAbIAFqIgRBCGopAwA3AwAgA0EQaiAEQRBqKQMANwMAIANBGGogBEEYaikDADcDACADQSBqIARBIGopAwA3AwAgAUEgaiIBQfgHSQ0ACwsL",xo="e4cdc523",Mo={name:bo,data:No,hash:xo},Ho="blake2b",Uo="AGFzbQEAAAABEQRgAAF/YAJ/fwBgAX8AYAAAAwoJAAECAwECAgABBQQBAQICBg4CfwFBsIsFC38AQYAICwdwCAZtZW1vcnkCAA5IYXNoX0dldEJ1ZmZlcgAACkhhc2hfRmluYWwAAwlIYXNoX0luaXQABQtIYXNoX1VwZGF0ZQAGDUhhc2hfR2V0U3RhdGUABw5IYXNoX0NhbGN1bGF0ZQAIClNUQVRFX1NJWkUDAQrTOAkFAEGACQvrAgIFfwF+AkAgAUEBSA0AAkACQAJAIAFBgAFBACgC4IoBIgJrIgNKDQAgASEEDAELQQBBADYC4IoBAkAgAkH/AEoNACACQeCJAWohBSAAIQRBACEGA0AgBSAELQAAOgAAIARBAWohBCAFQQFqIQUgAyAGQQFqIgZB/wFxSg0ACwtBAEEAKQPAiQEiB0KAAXw3A8CJAUEAQQApA8iJASAHQv9+Vq18NwPIiQFB4IkBEAIgACADaiEAAkAgASADayIEQYEBSA0AIAIgAWohBQNAQQBBACkDwIkBIgdCgAF8NwPAiQFBAEEAKQPIiQEgB0L/flatfDcDyIkBIAAQAiAAQYABaiEAIAVBgH9qIgVBgAJLDQALIAVBgH9qIQQMAQsgBEEATA0BC0EAIQUDQCAFQQAoAuCKAWpB4IkBaiAAIAVqLQAAOgAAIAQgBUEBaiIFQf8BcUoNAAsLQQBBACgC4IoBIARqNgLgigELC78uASR+QQBBACkD0IkBQQApA7CJASIBQQApA5CJAXwgACkDICICfCIDhULr+obav7X2wR+FQiCJIgRCq/DT9K/uvLc8fCIFIAGFQiiJIgYgA3wgACkDKCIBfCIHIASFQjCJIgggBXwiCSAGhUIBiSIKQQApA8iJAUEAKQOoiQEiBEEAKQOIiQF8IAApAxAiA3wiBYVCn9j52cKR2oKbf4VCIIkiC0K7zqqm2NDrs7t/fCIMIASFQiiJIg0gBXwgACkDGCIEfCIOfCAAKQNQIgV8Ig9BACkDwIkBQQApA6CJASIQQQApA4CJASIRfCAAKQMAIgZ8IhKFQtGFmu/6z5SH0QCFQiCJIhNCiJLznf/M+YTqAHwiFCAQhUIoiSIVIBJ8IAApAwgiEHwiFiAThUIwiSIXhUIgiSIYQQApA9iJAUEAKQO4iQEiE0EAKQOYiQF8IAApAzAiEnwiGYVC+cL4m5Gjs/DbAIVCIIkiGkLx7fT4paf9p6V/fCIbIBOFQiiJIhwgGXwgACkDOCITfCIZIBqFQjCJIhogG3wiG3wiHSAKhUIoiSIeIA98IAApA1giCnwiDyAYhUIwiSIYIB18Ih0gDiALhUIwiSIOIAx8Ih8gDYVCAYkiDCAWfCAAKQNAIgt8Ig0gGoVCIIkiFiAJfCIaIAyFQiiJIiAgDXwgACkDSCIJfCIhIBaFQjCJIhYgGyAchUIBiSIMIAd8IAApA2AiB3wiDSAOhUIgiSIOIBcgFHwiFHwiFyAMhUIoiSIbIA18IAApA2giDHwiHCAOhUIwiSIOIBd8IhcgG4VCAYkiGyAZIBQgFYVCAYkiFHwgACkDcCINfCIVIAiFQiCJIhkgH3wiHyAUhUIoiSIUIBV8IAApA3giCHwiFXwgDHwiIoVCIIkiI3wiJCAbhUIoiSIbICJ8IBJ8IiIgFyAYIBUgGYVCMIkiFSAffCIZIBSFQgGJIhQgIXwgDXwiH4VCIIkiGHwiFyAUhUIoiSIUIB98IAV8Ih8gGIVCMIkiGCAXfCIXIBSFQgGJIhR8IAF8IiEgFiAafCIWIBUgHSAehUIBiSIaIBx8IAl8IhyFQiCJIhV8Ih0gGoVCKIkiGiAcfCAIfCIcIBWFQjCJIhWFQiCJIh4gGSAOIBYgIIVCAYkiFiAPfCACfCIPhUIgiSIOfCIZIBaFQiiJIhYgD3wgC3wiDyAOhUIwiSIOIBl8Ihl8IiAgFIVCKIkiFCAhfCAEfCIhIB6FQjCJIh4gIHwiICAiICOFQjCJIiIgJHwiIyAbhUIBiSIbIBx8IAp8IhwgDoVCIIkiDiAXfCIXIBuFQiiJIhsgHHwgE3wiHCAOhUIwiSIOIBkgFoVCAYkiFiAffCAQfCIZICKFQiCJIh8gFSAdfCIVfCIdIBaFQiiJIhYgGXwgB3wiGSAfhUIwiSIfIB18Ih0gFoVCAYkiFiAVIBqFQgGJIhUgD3wgBnwiDyAYhUIgiSIYICN8IhogFYVCKIkiFSAPfCADfCIPfCAHfCIihUIgiSIjfCIkIBaFQiiJIhYgInwgBnwiIiAjhUIwiSIjICR8IiQgFoVCAYkiFiAOIBd8Ig4gDyAYhUIwiSIPICAgFIVCAYkiFCAZfCAKfCIXhUIgiSIYfCIZIBSFQiiJIhQgF3wgC3wiF3wgBXwiICAPIBp8Ig8gHyAOIBuFQgGJIg4gIXwgCHwiGoVCIIkiG3wiHyAOhUIoiSIOIBp8IAx8IhogG4VCMIkiG4VCIIkiISAdIB4gDyAVhUIBiSIPIBx8IAF8IhWFQiCJIhx8Ih0gD4VCKIkiDyAVfCADfCIVIByFQjCJIhwgHXwiHXwiHiAWhUIoiSIWICB8IA18IiAgIYVCMIkiISAefCIeIBogFyAYhUIwiSIXIBl8IhggFIVCAYkiFHwgCXwiGSAchUIgiSIaICR8IhwgFIVCKIkiFCAZfCACfCIZIBqFQjCJIhogHSAPhUIBiSIPICJ8IAR8Ih0gF4VCIIkiFyAbIB98Iht8Ih8gD4VCKIkiDyAdfCASfCIdIBeFQjCJIhcgH3wiHyAPhUIBiSIPIBsgDoVCAYkiDiAVfCATfCIVICOFQiCJIhsgGHwiGCAOhUIoiSIOIBV8IBB8IhV8IAx8IiKFQiCJIiN8IiQgD4VCKIkiDyAifCAHfCIiICOFQjCJIiMgJHwiJCAPhUIBiSIPIBogHHwiGiAVIBuFQjCJIhUgHiAWhUIBiSIWIB18IAR8IhuFQiCJIhx8Ih0gFoVCKIkiFiAbfCAQfCIbfCABfCIeIBUgGHwiFSAXIBogFIVCAYkiFCAgfCATfCIYhUIgiSIXfCIaIBSFQiiJIhQgGHwgCXwiGCAXhUIwiSIXhUIgiSIgIB8gISAVIA6FQgGJIg4gGXwgCnwiFYVCIIkiGXwiHyAOhUIoiSIOIBV8IA18IhUgGYVCMIkiGSAffCIffCIhIA+FQiiJIg8gHnwgBXwiHiAghUIwiSIgICF8IiEgGyAchUIwiSIbIB18IhwgFoVCAYkiFiAYfCADfCIYIBmFQiCJIhkgJHwiHSAWhUIoiSIWIBh8IBJ8IhggGYVCMIkiGSAfIA6FQgGJIg4gInwgAnwiHyAbhUIgiSIbIBcgGnwiF3wiGiAOhUIoiSIOIB98IAZ8Ih8gG4VCMIkiGyAafCIaIA6FQgGJIg4gFSAXIBSFQgGJIhR8IAh8IhUgI4VCIIkiFyAcfCIcIBSFQiiJIhQgFXwgC3wiFXwgBXwiIoVCIIkiI3wiJCAOhUIoiSIOICJ8IAh8IiIgGiAgIBUgF4VCMIkiFSAcfCIXIBSFQgGJIhQgGHwgCXwiGIVCIIkiHHwiGiAUhUIoiSIUIBh8IAZ8IhggHIVCMIkiHCAafCIaIBSFQgGJIhR8IAR8IiAgGSAdfCIZIBUgISAPhUIBiSIPIB98IAN8Ih2FQiCJIhV8Ih8gD4VCKIkiDyAdfCACfCIdIBWFQjCJIhWFQiCJIiEgFyAbIBkgFoVCAYkiFiAefCABfCIZhUIgiSIbfCIXIBaFQiiJIhYgGXwgE3wiGSAbhUIwiSIbIBd8Ihd8Ih4gFIVCKIkiFCAgfCAMfCIgICGFQjCJIiEgHnwiHiAiICOFQjCJIiIgJHwiIyAOhUIBiSIOIB18IBJ8Ih0gG4VCIIkiGyAafCIaIA6FQiiJIg4gHXwgC3wiHSAbhUIwiSIbIBcgFoVCAYkiFiAYfCANfCIXICKFQiCJIhggFSAffCIVfCIfIBaFQiiJIhYgF3wgEHwiFyAYhUIwiSIYIB98Ih8gFoVCAYkiFiAVIA+FQgGJIg8gGXwgCnwiFSAchUIgiSIZICN8IhwgD4VCKIkiDyAVfCAHfCIVfCASfCIihUIgiSIjfCIkIBaFQiiJIhYgInwgBXwiIiAjhUIwiSIjICR8IiQgFoVCAYkiFiAbIBp8IhogFSAZhUIwiSIVIB4gFIVCAYkiFCAXfCADfCIXhUIgiSIZfCIbIBSFQiiJIhQgF3wgB3wiF3wgAnwiHiAVIBx8IhUgGCAaIA6FQgGJIg4gIHwgC3wiGoVCIIkiGHwiHCAOhUIoiSIOIBp8IAR8IhogGIVCMIkiGIVCIIkiICAfICEgFSAPhUIBiSIPIB18IAZ8IhWFQiCJIh18Ih8gD4VCKIkiDyAVfCAKfCIVIB2FQjCJIh0gH3wiH3wiISAWhUIoiSIWIB58IAx8Ih4gIIVCMIkiICAhfCIhIBogFyAZhUIwiSIXIBt8IhkgFIVCAYkiFHwgEHwiGiAdhUIgiSIbICR8Ih0gFIVCKIkiFCAafCAJfCIaIBuFQjCJIhsgHyAPhUIBiSIPICJ8IBN8Ih8gF4VCIIkiFyAYIBx8Ihh8IhwgD4VCKIkiDyAffCABfCIfIBeFQjCJIhcgHHwiHCAPhUIBiSIPIBggDoVCAYkiDiAVfCAIfCIVICOFQiCJIhggGXwiGSAOhUIoiSIOIBV8IA18IhV8IA18IiKFQiCJIiN8IiQgD4VCKIkiDyAifCAMfCIiICOFQjCJIiMgJHwiJCAPhUIBiSIPIBsgHXwiGyAVIBiFQjCJIhUgISAWhUIBiSIWIB98IBB8IhiFQiCJIh18Ih8gFoVCKIkiFiAYfCAIfCIYfCASfCIhIBUgGXwiFSAXIBsgFIVCAYkiFCAefCAHfCIZhUIgiSIXfCIbIBSFQiiJIhQgGXwgAXwiGSAXhUIwiSIXhUIgiSIeIBwgICAVIA6FQgGJIg4gGnwgAnwiFYVCIIkiGnwiHCAOhUIoiSIOIBV8IAV8IhUgGoVCMIkiGiAcfCIcfCIgIA+FQiiJIg8gIXwgBHwiISAehUIwiSIeICB8IiAgGCAdhUIwiSIYIB98Ih0gFoVCAYkiFiAZfCAGfCIZIBqFQiCJIhogJHwiHyAWhUIoiSIWIBl8IBN8IhkgGoVCMIkiGiAcIA6FQgGJIg4gInwgCXwiHCAYhUIgiSIYIBcgG3wiF3wiGyAOhUIoiSIOIBx8IAN8IhwgGIVCMIkiGCAbfCIbIA6FQgGJIg4gFSAXIBSFQgGJIhR8IAt8IhUgI4VCIIkiFyAdfCIdIBSFQiiJIhQgFXwgCnwiFXwgBHwiIoVCIIkiI3wiJCAOhUIoiSIOICJ8IAl8IiIgGyAeIBUgF4VCMIkiFSAdfCIXIBSFQgGJIhQgGXwgDHwiGYVCIIkiHXwiGyAUhUIoiSIUIBl8IAp8IhkgHYVCMIkiHSAbfCIbIBSFQgGJIhR8IAN8Ih4gGiAffCIaIBUgICAPhUIBiSIPIBx8IAd8IhyFQiCJIhV8Ih8gD4VCKIkiDyAcfCAQfCIcIBWFQjCJIhWFQiCJIiAgFyAYIBogFoVCAYkiFiAhfCATfCIahUIgiSIYfCIXIBaFQiiJIhYgGnwgDXwiGiAYhUIwiSIYIBd8Ihd8IiEgFIVCKIkiFCAefCAFfCIeICCFQjCJIiAgIXwiISAiICOFQjCJIiIgJHwiIyAOhUIBiSIOIBx8IAt8IhwgGIVCIIkiGCAbfCIbIA6FQiiJIg4gHHwgEnwiHCAYhUIwiSIYIBcgFoVCAYkiFiAZfCABfCIXICKFQiCJIhkgFSAffCIVfCIfIBaFQiiJIhYgF3wgBnwiFyAZhUIwiSIZIB98Ih8gFoVCAYkiFiAVIA+FQgGJIg8gGnwgCHwiFSAdhUIgiSIaICN8Ih0gD4VCKIkiDyAVfCACfCIVfCANfCIihUIgiSIjfCIkIBaFQiiJIhYgInwgCXwiIiAjhUIwiSIjICR8IiQgFoVCAYkiFiAYIBt8IhggFSAahUIwiSIVICEgFIVCAYkiFCAXfCASfCIXhUIgiSIafCIbIBSFQiiJIhQgF3wgCHwiF3wgB3wiISAVIB18IhUgGSAYIA6FQgGJIg4gHnwgBnwiGIVCIIkiGXwiHSAOhUIoiSIOIBh8IAt8IhggGYVCMIkiGYVCIIkiHiAfICAgFSAPhUIBiSIPIBx8IAp8IhWFQiCJIhx8Ih8gD4VCKIkiDyAVfCAEfCIVIByFQjCJIhwgH3wiH3wiICAWhUIoiSIWICF8IAN8IiEgHoVCMIkiHiAgfCIgIBggFyAahUIwiSIXIBt8IhogFIVCAYkiFHwgBXwiGCAchUIgiSIbICR8IhwgFIVCKIkiFCAYfCABfCIYIBuFQjCJIhsgHyAPhUIBiSIPICJ8IAx8Ih8gF4VCIIkiFyAZIB18Ihl8Ih0gD4VCKIkiDyAffCATfCIfIBeFQjCJIhcgHXwiHSAPhUIBiSIPIBkgDoVCAYkiDiAVfCAQfCIVICOFQiCJIhkgGnwiGiAOhUIoiSIOIBV8IAJ8IhV8IBN8IiKFQiCJIiN8IiQgD4VCKIkiDyAifCASfCIiICOFQjCJIiMgJHwiJCAPhUIBiSIPIBsgHHwiGyAVIBmFQjCJIhUgICAWhUIBiSIWIB98IAt8IhmFQiCJIhx8Ih8gFoVCKIkiFiAZfCACfCIZfCAJfCIgIBUgGnwiFSAXIBsgFIVCAYkiFCAhfCAFfCIahUIgiSIXfCIbIBSFQiiJIhQgGnwgA3wiGiAXhUIwiSIXhUIgiSIhIB0gHiAVIA6FQgGJIg4gGHwgEHwiFYVCIIkiGHwiHSAOhUIoiSIOIBV8IAF8IhUgGIVCMIkiGCAdfCIdfCIeIA+FQiiJIg8gIHwgDXwiICAhhUIwiSIhIB58Ih4gGSAchUIwiSIZIB98IhwgFoVCAYkiFiAafCAIfCIaIBiFQiCJIhggJHwiHyAWhUIoiSIWIBp8IAp8IhogGIVCMIkiGCAdIA6FQgGJIg4gInwgBHwiHSAZhUIgiSIZIBcgG3wiF3wiGyAOhUIoiSIOIB18IAd8Ih0gGYVCMIkiGSAbfCIbIA6FQgGJIg4gFSAXIBSFQgGJIhR8IAx8IhUgI4VCIIkiFyAcfCIcIBSFQiiJIhQgFXwgBnwiFXwgEnwiIoVCIIkiI3wiJCAOhUIoiSIOICJ8IBN8IiIgGyAhIBUgF4VCMIkiFSAcfCIXIBSFQgGJIhQgGnwgBnwiGoVCIIkiHHwiGyAUhUIoiSIUIBp8IBB8IhogHIVCMIkiHCAbfCIbIBSFQgGJIhR8IA18IiEgGCAffCIYIBUgHiAPhUIBiSIPIB18IAJ8Ih2FQiCJIhV8Ih4gD4VCKIkiDyAdfCABfCIdIBWFQjCJIhWFQiCJIh8gFyAZIBggFoVCAYkiFiAgfCADfCIYhUIgiSIZfCIXIBaFQiiJIhYgGHwgBHwiGCAZhUIwiSIZIBd8Ihd8IiAgFIVCKIkiFCAhfCAIfCIhIB+FQjCJIh8gIHwiICAiICOFQjCJIiIgJHwiIyAOhUIBiSIOIB18IAd8Ih0gGYVCIIkiGSAbfCIbIA6FQiiJIg4gHXwgDHwiHSAZhUIwiSIZIBcgFoVCAYkiFiAafCALfCIXICKFQiCJIhogFSAefCIVfCIeIBaFQiiJIhYgF3wgCXwiFyAahUIwiSIaIB58Ih4gFoVCAYkiFiAVIA+FQgGJIg8gGHwgBXwiFSAchUIgiSIYICN8IhwgD4VCKIkiDyAVfCAKfCIVfCACfCIChUIgiSIifCIjIBaFQiiJIhYgAnwgC3wiAiAihUIwiSILICN8IiIgFoVCAYkiFiAZIBt8IhkgFSAYhUIwiSIVICAgFIVCAYkiFCAXfCANfCINhUIgiSIXfCIYIBSFQiiJIhQgDXwgBXwiBXwgEHwiECAVIBx8Ig0gGiAZIA6FQgGJIg4gIXwgDHwiDIVCIIkiFXwiGSAOhUIoiSIOIAx8IBJ8IhIgFYVCMIkiDIVCIIkiFSAeIB8gDSAPhUIBiSINIB18IAl8IgmFQiCJIg98IhogDYVCKIkiDSAJfCAIfCIJIA+FQjCJIgggGnwiD3wiGiAWhUIoiSIWIBB8IAd8IhAgEYUgDCAZfCIHIA6FQgGJIgwgCXwgCnwiCiALhUIgiSILIAUgF4VCMIkiBSAYfCIJfCIOIAyFQiiJIgwgCnwgE3wiEyALhUIwiSIKIA58IguFNwOAiQFBACADIAYgDyANhUIBiSINIAJ8fCICIAWFQiCJIgUgB3wiBiANhUIoiSIHIAJ8fCICQQApA4iJAYUgBCABIBIgCSAUhUIBiSIDfHwiASAIhUIgiSISICJ8IgkgA4VCKIkiAyABfHwiASAShUIwiSIEIAl8IhKFNwOIiQFBACATQQApA5CJAYUgECAVhUIwiSIQIBp8IhOFNwOQiQFBACABQQApA5iJAYUgAiAFhUIwiSICIAZ8IgGFNwOYiQFBACASIAOFQgGJQQApA6CJAYUgAoU3A6CJAUEAIBMgFoVCAYlBACkDqIkBhSAKhTcDqIkBQQAgASAHhUIBiUEAKQOwiQGFIASFNwOwiQFBACALIAyFQgGJQQApA7iJAYUgEIU3A7iJAQvdAgUBfwF+AX8BfgJ/IwBBwABrIgAkAAJAQQApA9CJAUIAUg0AQQBBACkDwIkBIgFBACgC4IoBIgKsfCIDNwPAiQFBAEEAKQPIiQEgAyABVK18NwPIiQECQEEALQDoigFFDQBBAEJ/NwPYiQELQQBCfzcD0IkBAkAgAkH/AEoNAEEAIQQDQCACIARqQeCJAWpBADoAACAEQQFqIgRBgAFBACgC4IoBIgJrSA0ACwtB4IkBEAIgAEEAKQOAiQE3AwAgAEEAKQOIiQE3AwggAEEAKQOQiQE3AxAgAEEAKQOYiQE3AxggAEEAKQOgiQE3AyAgAEEAKQOoiQE3AyggAEEAKQOwiQE3AzAgAEEAKQO4iQE3AzhBACgC5IoBIgVBAUgNAEEAIQRBACECA0AgBEGACWogACAEai0AADoAACAEQQFqIQQgBSACQQFqIgJB/wFxSg0ACwsgAEHAAGokAAv9AwMBfwF+AX8jAEGAAWsiAiQAQQBBgQI7AfKKAUEAIAE6APGKAUEAIAA6APCKAUGQfiEAA0AgAEGAiwFqQgA3AAAgAEH4igFqQgA3AAAgAEHwigFqQgA3AAAgAEEYaiIADQALQQAhAEEAQQApA/CKASIDQoiS853/zPmE6gCFNwOAiQFBAEEAKQP4igFCu86qptjQ67O7f4U3A4iJAUEAQQApA4CLAUKr8NP0r+68tzyFNwOQiQFBAEEAKQOIiwFC8e30+KWn/aelf4U3A5iJAUEAQQApA5CLAULRhZrv+s+Uh9EAhTcDoIkBQQBBACkDmIsBQp/Y+dnCkdqCm3+FNwOoiQFBAEEAKQOgiwFC6/qG2r+19sEfhTcDsIkBQQBBACkDqIsBQvnC+JuRo7Pw2wCFNwO4iQFBACADp0H/AXE2AuSKAQJAIAFBAUgNACACQgA3A3ggAkIANwNwIAJCADcDaCACQgA3A2AgAkIANwNYIAJCADcDUCACQgA3A0ggAkIANwNAIAJCADcDOCACQgA3AzAgAkIANwMoIAJCADcDICACQgA3AxggAkIANwMQIAJCADcDCCACQgA3AwBBACEEA0AgAiAAaiAAQYAJai0AADoAACAAQQFqIQAgBEEBaiIEQf8BcSABSA0ACyACQYABEAELIAJBgAFqJAALEgAgAEEDdkH/P3EgAEEQdhAECwkAQYAJIAAQAQsGAEGAiQELGwAgAUEDdkH/P3EgAUEQdhAEQYAJIAAQARADCwsLAQBBgAgLBPAAAAA=",To="c6f286e6",Go={name:Ho,data:Uo,hash:To},Lr=new ft;function Fn(h){return!Number.isInteger(h)||h<8||h>512||h%8!==0?new Error("Invalid variant! Valid values: 8, 16, ..., 512"):null}function Ro(h,A){return h|A<<16}function ws(h=512,A=null){if(Fn(h))return Promise.reject(Fn(h));let t=null,e=h;if(A!==null){if(t=Kt(A),t.length>64)return Promise.reject(new Error("Max key length is 64 bytes"));e=Ro(h,t.length)}let i=h/8;return Dn(Go,i).then(s=>{e>512&&s.writeMemory(t),s.init(e);let n={init:e>512?()=>(s.writeMemory(t),s.init(e),n):()=>(s.init(e),n),update:o=>(s.update(o),n),digest:o=>s.digest(o),save:()=>s.save(),load:o=>(s.load(o),n),blockSize:128,digestSize:i};return n})}function Po(h,A,t){let e=[`m=${A.memorySize}`,`t=${A.iterations}`,`p=${A.parallelism}`].join(",");return`$argon2${A.hashType}$v=19$${e}$${wn(h,!1)}$${wn(t,!1)}`}var vn=new DataView(new ArrayBuffer(4));function qt(h){return vn.setInt32(0,h,!0),new Uint8Array(vn.buffer)}function ms(h,A,t){return ce(this,void 0,void 0,function*(){if(t<=64){let a=yield ws(t*8);return a.update(qt(t)),a.update(A),a.digest("binary")}let e=Math.ceil(t/32)-2,i=new Uint8Array(t);h.init(),h.update(qt(t)),h.update(A);let s=h.digest("binary");i.set(s.subarray(0,32),0);for(let a=1;a<e;a++)h.init(),h.update(s),s=h.digest("binary"),i.set(s.subarray(0,32),a*32);let n=t-32*e,o;return n===64?(o=h,o.init()):o=yield ws(n*8),o.update(s),s=o.digest("binary"),i.set(s.subarray(0,n),e*32),i})}function Lo(h){switch(h){case"d":return 0;case"i":return 1;default:return 2}}function Jo(h){return ce(this,void 0,void 0,function*(){var A;let{parallelism:t,iterations:e,hashLength:i}=h,s=Kt(h.password),n=Kt(h.salt),o=19,a=Lo(h.hashType),{memorySize:r}=h,c=Kt((A=h.secret)!==null&&A!==void 0?A:""),[l,d]=yield Promise.all([Dn(Mo,1024),ws(512)]);l.setMemorySize(r*1024+1024);let I=new Uint8Array(24),g=new DataView(I.buffer);g.setInt32(0,t,!0),g.setInt32(4,i,!0),g.setInt32(8,r,!0),g.setInt32(12,e,!0),g.setInt32(16,o,!0),g.setInt32(20,a,!0),l.writeMemory(I,r*1024),d.init(),d.update(I),d.update(qt(s.length)),d.update(s),d.update(qt(n.length)),d.update(n),d.update(qt(c.length)),d.update(c),d.update(qt(0));let u=Math.floor(r/(t*4))*4,f=new Uint8Array(72),B=d.digest("binary");f.set(B);for(let y=0;y<t;y++){f.set(qt(0),64),f.set(qt(y),68);let v=y*u,k=yield ms(d,f,1024);l.writeMemory(k,v*1024),v+=1,f.set(qt(1),64),k=yield ms(d,f,1024),l.writeMemory(k,v*1024)}let Q=new Uint8Array(1024);Sn(Q,l.calculate(new Uint8Array([]),r));let E=yield ms(d,Q,i);if(h.outputType==="hex"){let y=new Uint8Array(i*2);return ys(y,E,i)}return h.outputType==="encoded"?Po(n,h,E):E})}var qo=h=>{var A;if(!h||typeof h!="object")throw new Error("Invalid options parameter. It requires an object.");if(!h.password)throw new Error("Password must be specified");if(h.password=Kt(h.password),h.password.length<1)throw new Error("Password must be specified");if(!h.salt)throw new Error("Salt must be specified");if(h.salt=Kt(h.salt),h.salt.length<8)throw new Error("Salt should be at least 8 bytes long");if(h.secret=Kt((A=h.secret)!==null&&A!==void 0?A:""),!Number.isInteger(h.iterations)||h.iterations<1)throw new Error("Iterations should be a positive number");if(!Number.isInteger(h.parallelism)||h.parallelism<1)throw new Error("Parallelism should be a positive number");if(!Number.isInteger(h.hashLength)||h.hashLength<4)throw new Error("Hash length should be at least 4 bytes.");if(!Number.isInteger(h.memorySize))throw new Error("Memory size should be specified.");if(h.memorySize<8*h.parallelism)throw new Error("Memory size should be at least 8 * parallelism.");if(h.outputType===void 0&&(h.outputType="hex"),!["hex","binary","encoded"].includes(h.outputType))throw new Error(`Insupported output type ${h.outputType}. Valid values: ['hex', 'binary', 'encoded']`)};function bn(h){return ce(this,void 0,void 0,function*(){return qo(h),Jo(Object.assign(Object.assign({},h),{hashType:"id"}))})}var Jr=new ft;var qr=new ft;var Kr=new ft;var Or=new ft;var Yr=new Uint8Array(8);var zr=new ft;var Vr=new ft;var Wr=new ft;var Xr=new ft;var Zr=new ft;var _r=new ft;var $r=new ft;var jr=new ft;var tA=new ft;var eA=new ft;var iA=new ft;var sA=new Uint8Array(8);var nA=new ft;var oA=new Uint8Array(8);var aA=new ft;var rA=new Uint8Array(8);var AA=new ft;var cA=new ft;var lA=new ft;Mt();var Ot=new Uint8Array([83,84,65,83,72,69,78,67]),Hn=2,Un=1,Tn=2,Ko=32,Fs=12,Nn=32,Oo=6e5,Yo=47104,zo=3,Vo=1,bt=h=>h;function Fe(h){if(h.length<Ot.length+1)return!1;for(let A=0;A<Ot.length;A++)if(h[A]!==Ot[A])return!1;return!0}function xn(h,A,t){h[A]=t>>>24&255,h[A+1]=t>>>16&255,h[A+2]=t>>>8&255,h[A+3]=t&255}function Mn(h,A){return h[A]*16777216+(h[A+1]<<16)+(h[A+2]<<8)+h[A+3]}async function vs(h,A,t){if(t.id===Tn)return await bn({password:h,salt:A,parallelism:t.c,iterations:t.b,memorySize:t.a,hashLength:Nn,outputType:"binary"});if(t.id===Un){let e=await crypto.subtle.importKey("raw",bt(new TextEncoder().encode(h)),"PBKDF2",!1,["deriveBits"]),i=await crypto.subtle.deriveBits({name:"PBKDF2",salt:bt(A),iterations:t.a,hash:"SHA-256"},e,Nn*8);return new Uint8Array(i)}throw new Error(`Unsupported KDF id (${t.id}).`)}async function Gn(h){return crypto.subtle.importKey("raw",bt(h),{name:"AES-GCM"},!1,["encrypt","decrypt"])}var Rn={argon2id:{label:"Argon2id",strong:!0},pbkdf2:{label:"PBKDF2 (fallback)",strong:!1}};async function Pn(h,A){let t=crypto.getRandomValues(new Uint8Array(Ko)),e=crypto.getRandomValues(new Uint8Array(Fs)),i,s,n;try{i={id:Tn,a:Yo,b:zo,c:Vo},n=await vs(A,t,i),s="argon2id"}catch(l){console.warn("[Stashpad] Argon2id unavailable \u2014 encrypting with PBKDF2 fallback.",l),i={id:Un,a:Oo,b:0,c:0},n=await vs(A,t,i),s="pbkdf2"}let o=Wo(i,t,e),a=await Gn(n),r=new Uint8Array(await crypto.subtle.encrypt({name:"AES-GCM",iv:bt(e),additionalData:bt(o)},a,bt(h))),c=new Uint8Array(o.length+r.length);return c.set(o,0),c.set(r,o.length),{data:c,kdf:s}}function Wo(h,A,t){let e=new Uint8Array(Ot.length+1+1+4+4+1+1+A.length+t.length),i=0;return e.set(Ot,i),i+=Ot.length,e[i++]=Hn,e[i++]=h.id,xn(e,i,h.a),i+=4,xn(e,i,h.b),i+=4,e[i++]=h.c,e[i++]=A.length,e.set(A,i),i+=A.length,e.set(t,i),i+=t.length,e}async function Xo(h,A){if(!Fe(h))throw new Error("Not an encrypted Stashpad file.");let t=h[Ot.length];if(t===1)return Zo(h,A);if(t!==Hn)throw new Error(`Unsupported encrypted .stash version (${t}).`);let e=Ot.length+1,i={id:h[e++],a:0,b:0,c:0};i.a=Mn(h,e),e+=4,i.b=Mn(h,e),e+=4,i.c=h[e++];let s=h[e++],n=h.slice(e,e+s);e+=s;let o=h.slice(e,e+Fs);e+=Fs;let a=h.slice(0,e),r=h.slice(e),c=await vs(A,n,i),l=await Gn(c),d=await crypto.subtle.decrypt({name:"AES-GCM",iv:bt(o),additionalData:bt(a)},l,bt(r));return new Uint8Array(d)}async function Zo(h,A){let t=Ot.length+1,e=h.slice(t,t+16);t+=16;let i=h.slice(t,t+12);t+=12;let s=h.slice(t),n=await crypto.subtle.importKey("raw",bt(new TextEncoder().encode(A)),"PBKDF2",!1,["deriveKey"]),o=await crypto.subtle.deriveKey({name:"PBKDF2",salt:bt(e),iterations:21e4,hash:"SHA-256"},n,{name:"AES-GCM",length:256},!1,["decrypt"]),a=await crypto.subtle.decrypt({name:"AES-GCM",iv:bt(i)},o,bt(s));return new Uint8Array(a)}async function ve(h,A,t={}){if(!Fe(A))return A;let e;for(;;){let i=await new Promise(s=>{new Ge(h,e,!!t.allowLater,s).open()});if(i.kind==="cancel")return null;if(i.kind==="later")return t.onLater?.(),null;try{return await Xo(A,i.value)}catch{e="Wrong password or corrupted file. Try again."}}}Mt();function _o(h){return h.replace(/[^\w.\-]+/g,"_").replace(/^\.+/,"").slice(0,60)||"stash-export"}async function Ln(h,A){let t=jo(h,A);if(t.length===0){new jt.Notice("Nothing to export.");return}let e=ta(h,t);if(e.length===0){new jt.Notice("No exportable notes (no files attached).");return}let i=(h.noteFolder.split("/").pop()||h.noteFolder).trim(),s=t.length===1?h.titleForNode(t[0]):`${i}-${t.length}notes`;new Te(h.app,s,e.length,(n,o)=>{$o(h,t,e,n,o)}).open()}async function $o(h,A,t,e,i){try{let s=await Qn(h.app,{rootNotes:A.filter(d=>!!d.file).map(d=>({id:d.id,file:d.file})),allDescendants:t.filter(d=>!A.some(I=>I.id===d.id)).filter(d=>!!d.file).map(d=>({id:d.id,file:d.file})),sourceFolder:h.noteFolder}),n="";if(i){let d=await Pn(s,i);s=d.data;let I=Rn[d.kdf];n=I.strong?` (encrypted \xB7 ${I.label})`:` (encrypted \xB7 ${I.label} \u2014 Argon2id unavailable on this device, this export is weaker)`}let o=(0,jt.moment)().format("YYYYMMDD-HHmmss"),a=_o(e),r=(h.plugin.settings.exportFolder||"_exports").trim().replace(/^\/+|\/+$/g,""),c=`${h.noteFolder}/${r}`;await h.ensureFolder(c);let l=`${c}/${a}-${o}.${_t}`;await h.app.vault.createBinary(l,s.buffer.slice(s.byteOffset,s.byteOffset+s.byteLength)),await h.log.append({type:"stash_export",id:A[0].id,payload:{path:l,noteCount:t.length,rootIds:A.map(d=>d.id)}}),h.plugin.notifications.show({message:`Exported ${t.length} note${t.length===1?"":"s"}${n} \u2192 \`${l}\``,kind:i&&n.includes("weaker")?"warning":"success",category:"export",affectedPaths:[l],folder:h.noteFolder,actions:h.actionsForFile(l),duration:0})}catch(s){h.plugin.notifications.show({message:`Stashpad: export failed -Error: ${s.message} -Check disk space + write permissions on the export folder.`,kind:"error",category:"export"}),console.error(s)}}function jo(h,A){if(A?.file)return[A];if(h.selection.size>0)return[...h.selection].map(e=>h.tree.get(e)).filter(e=>!!e?.file);if(h.cursorIdx>=0&&h.currentChildren[h.cursorIdx])return[h.currentChildren[h.cursorIdx]];let t=h.tree.get(h.focusId);return t?.file?[t]:[]}function ta(h,A){let t=new Set,e=[],i=s=>{if(!t.has(s.id)){t.add(s.id),s.file&&e.push(s);for(let n of h.tree.getChildren(s.id))i(n)}};for(let s of A)i(s);return e}async function Jn(h){let A=h.app.vault.getFiles().filter(e=>e.extension===_t);if(A.length===0){new jt.Notice("No .stash files found in this vault.");return}let t=new class extends jt.FuzzySuggestModal{getItems(){return A}getItemText(e){return e.path}onChooseItem(e){ks(h,e)}}(h.app);t.setPlaceholder("Pick a .stash file to import\u2026"),t.open()}async function ks(h,A){try{let t=new Uint8Array(await h.app.vault.readBinary(A)),e=await ve(h.app,t);if(!e)return;let i=await ye(h.app,e,h.noteFolder,ea(h));h.tree.rebuild(h.noteFolder),h.render(),await h.log.append({type:"stash_import",id:G,payload:{from:A.path,into:h.noteFolder,noteCount:i.notesWritten,attachmentsWritten:i.attachmentsWritten,collisionsRenamed:i.collisionsRenamed}});try{await h.app.fileManager.trashFile(A)}catch{}h.plugin.importService.clearPendingEncrypted(A.path);let s=[`Imported ${i.notesWritten} note${i.notesWritten===1?"":"s"}`];i.attachmentsWritten&&s.push(`+ ${i.attachmentsWritten} attachment${i.attachmentsWritten===1?"":"s"}`),i.collisionsRenamed&&s.push(`(${i.collisionsRenamed} id collision${i.collisionsRenamed===1?"":"s"} renamed)`),h.plugin.notifications.show({message:s.join(" "),kind:"success",category:"import",folder:h.noteFolder})}catch(t){h.plugin.notifications.show({message:`Stashpad: import failed +${A}`}async function Hn(d,A){if(!(!A||await d.vault.adapter.exists(A)))try{await d.vault.createFolder(A)}catch(e){let i=e?.message??"";if(!/already exists/i.test(i))throw e}}function he(d,A,t,e){function i(s){return s instanceof t?s:new t(function(n){n(s)})}return new(t||(t=Promise))(function(s,n){function o(c){try{a(e.next(c))}catch(l){n(l)}}function r(c){try{a(e.throw(c))}catch(l){n(l)}}function a(c){c.done?s(c.value):i(c.value).then(o,r)}a((e=e.apply(d,A||[])).next())})}var Bt=class{constructor(){this.mutex=Promise.resolve()}lock(){let A=()=>{};return this.mutex=this.mutex.then(()=>new Promise(A)),new Promise(t=>{A=t})}dispatch(A){return he(this,void 0,void 0,function*(){let t=yield this.lock();try{return yield Promise.resolve(A())}finally{t()}})}},ks;function Ko(){return typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:global}var Ns=Ko(),Ss=(ks=Ns.Buffer)!==null&&ks!==void 0?ks:null,Yo=Ns.TextEncoder?new Ns.TextEncoder:null;function On(d,A){return(d&15)+(d>>6|d>>3&8)<<4|(A&15)+(A>>6|A>>3&8)}function Kn(d,A){let t=A.length>>1;for(let e=0;e<t;e++){let i=e<<1;d[e]=On(A.charCodeAt(i),A.charCodeAt(i+1))}}function zo(d,A){if(d.length!==A.length*2)return!1;for(let t=0;t<A.length;t++){let e=t<<1;if(A[t]!==On(d.charCodeAt(e),d.charCodeAt(e+1)))return!1}return!0}var Rn=87,Pn=48;function xs(d,A,t){let e=0;for(let i=0;i<t;i++){let s=A[i]>>>4;d[e++]=s>9?s+Rn:s+Pn,s=A[i]&15,d[e++]=s>9?s+Rn:s+Pn}return String.fromCharCode.apply(null,d)}var Yt=Ss!==null?d=>{if(typeof d=="string"){let A=Ss.from(d,"utf8");return new Uint8Array(A.buffer,A.byteOffset,A.length)}if(Ss.isBuffer(d))return new Uint8Array(d.buffer,d.byteOffset,d.length);if(ArrayBuffer.isView(d))return new Uint8Array(d.buffer,d.byteOffset,d.byteLength);throw new Error("Invalid data type!")}:d=>{if(typeof d=="string")return Yo.encode(d);if(ArrayBuffer.isView(d))return new Uint8Array(d.buffer,d.byteOffset,d.byteLength);throw new Error("Invalid data type!")},Tt="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",ii=new Uint8Array(256);for(let d=0;d<Tt.length;d++)ii[Tt.charCodeAt(d)]=d;function Ln(d,A=!0){let t=d.length,e=t%3,i=[],s=t-e;for(let n=0;n<s;n+=3){let o=(d[n]<<16&16711680)+(d[n+1]<<8&65280)+(d[n+2]&255),r=Tt.charAt(o>>18&63)+Tt.charAt(o>>12&63)+Tt.charAt(o>>6&63)+Tt.charAt(o&63);i.push(r)}if(e===1){let n=d[t-1],o=Tt.charAt(n>>2),r=Tt.charAt(n<<4&63);i.push(`${o}${r}`),A&&i.push("==")}else if(e===2){let n=(d[t-2]<<8)+d[t-1],o=Tt.charAt(n>>10),r=Tt.charAt(n>>4&63),a=Tt.charAt(n<<2&63);i.push(`${o}${r}${a}`),A&&i.push("=")}return i.join("")}function Vo(d){let A=Math.floor(d.length*.75),t=d.length;return d[t-1]==="="&&(A-=1,d[t-2]==="="&&(A-=1)),A}function Wo(d){let A=Vo(d),t=d.length,e=new Uint8Array(A),i=0;for(let s=0;s<t;s+=4){let n=ii[d.charCodeAt(s)],o=ii[d.charCodeAt(s+1)],r=ii[d.charCodeAt(s+2)],a=ii[d.charCodeAt(s+3)];e[i]=n<<2|o>>4,i+=1,e[i]=(o&15)<<4|r>>2,i+=1,e[i]=(r&3)<<6|a&63,i+=1}return e}var qi=16*1024,ei=4,Xo=new Bt,Ds=new Map;function Yn(d,A){return he(this,void 0,void 0,function*(){let t=null,e=null,i=!1;if(typeof WebAssembly>"u")throw new Error("WebAssembly is not supported in this environment!");let s=(w,v=0)=>{e.set(w,v)},n=()=>e,o=()=>t.exports,r=w=>{t.exports.Hash_SetMemorySize(w);let v=t.exports.Hash_GetBuffer(),D=t.exports.memory.buffer;e=new Uint8Array(D,v,w)},a=()=>new DataView(t.exports.memory.buffer).getUint32(t.exports.STATE_SIZE,!0),c=Xo.dispatch(()=>he(this,void 0,void 0,function*(){if(!Ds.has(d.name)){let v=Wo(d.data),D=WebAssembly.compile(v);Ds.set(d.name,D)}let w=yield Ds.get(d.name);t=yield WebAssembly.instantiate(w,{})})),l=()=>he(this,void 0,void 0,function*(){t||(yield c);let w=t.exports.Hash_GetBuffer(),v=t.exports.memory.buffer;e=new Uint8Array(v,w,qi)}),p=(w=null)=>{i=!0,t.exports.Hash_Init(w)},g=w=>{let v=0;for(;v<w.length;){let D=w.subarray(v,v+qi);v+=D.length,e.set(D),t.exports.Hash_Update(D.length)}},h=w=>{if(!i)throw new Error("update() called before init()");let v=Yt(w);g(v)},I=new Uint8Array(A*2),u=(w,v=null)=>{if(!i)throw new Error("digest() called before init()");return i=!1,t.exports.Hash_Final(v),w==="binary"?e.slice(0,A):xs(I,e,A)},f=()=>{if(!i)throw new Error("save() can only be called after init() and before digest()");let w=t.exports.Hash_GetState(),v=a(),D=t.exports.memory.buffer,L=new Uint8Array(D,w,v),S=new Uint8Array(ei+v);return Kn(S,d.hash),S.set(L,ei),S},C=w=>{if(!(w instanceof Uint8Array))throw new Error("load() expects an Uint8Array generated by save()");let v=t.exports.Hash_GetState(),D=a(),L=ei+D,S=t.exports.memory.buffer;if(w.length!==L)throw new Error(`Bad state length (expected ${L} bytes, got ${w.length})`);if(!zo(d.hash,w.subarray(0,ei)))throw new Error("This state was written by an incompatible hash implementation");let b=w.subarray(ei);new Uint8Array(S,v,D).set(b),i=!0},m=w=>typeof w=="string"?w.length<qi/4:w.byteLength<qi,E=m;switch(d.name){case"argon2":case"scrypt":E=()=>!0;break;case"blake2b":case"blake2s":E=(w,v)=>v<=512&&m(w);break;case"blake3":E=(w,v)=>v===0&&m(w);break;case"xxhash64":case"xxhash3":case"xxhash128":case"crc64":E=()=>!1;break}let y=(w,v=null,D=null)=>{if(!E(w,v))return p(v),h(w),u("hex",D);let L=Yt(w);return e.set(L),t.exports.Hash_Calculate(L.length,v,D),xs(I,e,A)};return yield l(),{getMemory:n,writeMemory:s,getExports:o,setMemorySize:r,init:p,update:h,digest:u,save:f,load:C,calculate:y,hashLength:A}})}var cA=new Bt;var Zo="argon2",$o="AGFzbQEAAAABKQVgAX8Bf2AAAX9gEH9/f39/f39/f39/f39/f38AYAR/f39/AGACf38AAwYFAAECAwQFBgEBAoCAAgYIAX8BQZCoBAsHQQQGbWVtb3J5AgASSGFzaF9TZXRNZW1vcnlTaXplAAAOSGFzaF9HZXRCdWZmZXIAAQ5IYXNoX0NhbGN1bGF0ZQAECvEyBVgBAn9BACEBAkAgAEEAKAKICCICRg0AAkAgACACayIAQRB2IABBgIB8cSAASWoiAEAAQX9HDQBB/wHADwtBACEBQQBBACkDiAggAEEQdK18NwOICAsgAcALcAECfwJAQQAoAoAIIgANAEEAPwBBEHQiADYCgAhBACgCiAgiAUGAgCBGDQACQEGAgCAgAWsiAEEQdiAAQYCAfHEgAElqIgBAAEF/Rw0AQQAPC0EAQQApA4gIIABBEHStfDcDiAhBACgCgAghAAsgAAvcDgECfiAAIAQpAwAiECAAKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACAMIBAgDCkDAIVCIIkiEDcDACAIIBAgCCkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgBCAQIAQpAwCFQiiJIhA3AwAgACAQIAApAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIAwgECAMKQMAhUIwiSIQNwMAIAggECAIKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAEIBAgBCkDAIVCAYk3AwAgASAFKQMAIhAgASkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgDSAQIA0pAwCFQiCJIhA3AwAgCSAQIAkpAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIAUgECAFKQMAhUIoiSIQNwMAIAEgECABKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACANIBAgDSkDAIVCMIkiEDcDACAJIBAgCSkDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgBSAQIAUpAwCFQgGJNwMAIAIgBikDACIQIAIpAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIA4gECAOKQMAhUIgiSIQNwMAIAogECAKKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACAGIBAgBikDAIVCKIkiEDcDACACIBAgAikDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgDiAQIA4pAwCFQjCJIhA3AwAgCiAQIAopAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIAYgECAGKQMAhUIBiTcDACADIAcpAwAiECADKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACAPIBAgDykDAIVCIIkiEDcDACALIBAgCykDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgByAQIAcpAwCFQiiJIhA3AwAgAyAQIAMpAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIA8gECAPKQMAhUIwiSIQNwMAIAsgECALKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAHIBAgBykDAIVCAYk3AwAgACAFKQMAIhAgACkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgDyAQIA8pAwCFQiCJIhA3AwAgCiAQIAopAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIAUgECAFKQMAhUIoiSIQNwMAIAAgECAAKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAPIBAgDykDAIVCMIkiEDcDACAKIBAgCikDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgBSAQIAUpAwCFQgGJNwMAIAEgBikDACIQIAEpAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIAwgECAMKQMAhUIgiSIQNwMAIAsgECALKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACAGIBAgBikDAIVCKIkiEDcDACABIBAgASkDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgDCAQIAwpAwCFQjCJIhA3AwAgCyAQIAspAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIAYgECAGKQMAhUIBiTcDACACIAcpAwAiECACKQMAIhF8IBFCAYZC/v///x+DIBBC/////w+DfnwiEDcDACANIBAgDSkDAIVCIIkiEDcDACAIIBAgCCkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgByAQIAcpAwCFQiiJIhA3AwAgAiAQIAIpAwAiEXwgEEL/////D4MgEUIBhkL+////H4N+fCIQNwMAIA0gECANKQMAhUIwiSIQNwMAIAggECAIKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAHIBAgBykDAIVCAYk3AwAgAyAEKQMAIhAgAykDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgDiAQIA4pAwCFQiCJIhA3AwAgCSAQIAkpAwAiEXwgEUIBhkL+////H4MgEEL/////D4N+fCIQNwMAIAQgECAEKQMAhUIoiSIQNwMAIAMgECADKQMAIhF8IBBC/////w+DIBFCAYZC/v///x+DfnwiEDcDACAOIBAgDikDAIVCMIkiEDcDACAJIBAgCSkDACIRfCAQQv////8PgyARQgGGQv7///8fg358IhA3AwAgBCAQIAQpAwCFQgGJNwMAC98aAQN/QQAhBEEAIAIpAwAgASkDAIU3A5AIQQAgAikDCCABKQMIhTcDmAhBACACKQMQIAEpAxCFNwOgCEEAIAIpAxggASkDGIU3A6gIQQAgAikDICABKQMghTcDsAhBACACKQMoIAEpAyiFNwO4CEEAIAIpAzAgASkDMIU3A8AIQQAgAikDOCABKQM4hTcDyAhBACACKQNAIAEpA0CFNwPQCEEAIAIpA0ggASkDSIU3A9gIQQAgAikDUCABKQNQhTcD4AhBACACKQNYIAEpA1iFNwPoCEEAIAIpA2AgASkDYIU3A/AIQQAgAikDaCABKQNohTcD+AhBACACKQNwIAEpA3CFNwOACUEAIAIpA3ggASkDeIU3A4gJQQAgAikDgAEgASkDgAGFNwOQCUEAIAIpA4gBIAEpA4gBhTcDmAlBACACKQOQASABKQOQAYU3A6AJQQAgAikDmAEgASkDmAGFNwOoCUEAIAIpA6ABIAEpA6ABhTcDsAlBACACKQOoASABKQOoAYU3A7gJQQAgAikDsAEgASkDsAGFNwPACUEAIAIpA7gBIAEpA7gBhTcDyAlBACACKQPAASABKQPAAYU3A9AJQQAgAikDyAEgASkDyAGFNwPYCUEAIAIpA9ABIAEpA9ABhTcD4AlBACACKQPYASABKQPYAYU3A+gJQQAgAikD4AEgASkD4AGFNwPwCUEAIAIpA+gBIAEpA+gBhTcD+AlBACACKQPwASABKQPwAYU3A4AKQQAgAikD+AEgASkD+AGFNwOICkEAIAIpA4ACIAEpA4AChTcDkApBACACKQOIAiABKQOIAoU3A5gKQQAgAikDkAIgASkDkAKFNwOgCkEAIAIpA5gCIAEpA5gChTcDqApBACACKQOgAiABKQOgAoU3A7AKQQAgAikDqAIgASkDqAKFNwO4CkEAIAIpA7ACIAEpA7AChTcDwApBACACKQO4AiABKQO4AoU3A8gKQQAgAikDwAIgASkDwAKFNwPQCkEAIAIpA8gCIAEpA8gChTcD2ApBACACKQPQAiABKQPQAoU3A+AKQQAgAikD2AIgASkD2AKFNwPoCkEAIAIpA+ACIAEpA+AChTcD8ApBACACKQPoAiABKQPoAoU3A/gKQQAgAikD8AIgASkD8AKFNwOAC0EAIAIpA/gCIAEpA/gChTcDiAtBACACKQOAAyABKQOAA4U3A5ALQQAgAikDiAMgASkDiAOFNwOYC0EAIAIpA5ADIAEpA5ADhTcDoAtBACACKQOYAyABKQOYA4U3A6gLQQAgAikDoAMgASkDoAOFNwOwC0EAIAIpA6gDIAEpA6gDhTcDuAtBACACKQOwAyABKQOwA4U3A8ALQQAgAikDuAMgASkDuAOFNwPIC0EAIAIpA8ADIAEpA8ADhTcD0AtBACACKQPIAyABKQPIA4U3A9gLQQAgAikD0AMgASkD0AOFNwPgC0EAIAIpA9gDIAEpA9gDhTcD6AtBACACKQPgAyABKQPgA4U3A/ALQQAgAikD6AMgASkD6AOFNwP4C0EAIAIpA/ADIAEpA/ADhTcDgAxBACACKQP4AyABKQP4A4U3A4gMQQAgAikDgAQgASkDgASFNwOQDEEAIAIpA4gEIAEpA4gEhTcDmAxBACACKQOQBCABKQOQBIU3A6AMQQAgAikDmAQgASkDmASFNwOoDEEAIAIpA6AEIAEpA6AEhTcDsAxBACACKQOoBCABKQOoBIU3A7gMQQAgAikDsAQgASkDsASFNwPADEEAIAIpA7gEIAEpA7gEhTcDyAxBACACKQPABCABKQPABIU3A9AMQQAgAikDyAQgASkDyASFNwPYDEEAIAIpA9AEIAEpA9AEhTcD4AxBACACKQPYBCABKQPYBIU3A+gMQQAgAikD4AQgASkD4ASFNwPwDEEAIAIpA+gEIAEpA+gEhTcD+AxBACACKQPwBCABKQPwBIU3A4ANQQAgAikD+AQgASkD+ASFNwOIDUEAIAIpA4AFIAEpA4AFhTcDkA1BACACKQOIBSABKQOIBYU3A5gNQQAgAikDkAUgASkDkAWFNwOgDUEAIAIpA5gFIAEpA5gFhTcDqA1BACACKQOgBSABKQOgBYU3A7ANQQAgAikDqAUgASkDqAWFNwO4DUEAIAIpA7AFIAEpA7AFhTcDwA1BACACKQO4BSABKQO4BYU3A8gNQQAgAikDwAUgASkDwAWFNwPQDUEAIAIpA8gFIAEpA8gFhTcD2A1BACACKQPQBSABKQPQBYU3A+ANQQAgAikD2AUgASkD2AWFNwPoDUEAIAIpA+AFIAEpA+AFhTcD8A1BACACKQPoBSABKQPoBYU3A/gNQQAgAikD8AUgASkD8AWFNwOADkEAIAIpA/gFIAEpA/gFhTcDiA5BACACKQOABiABKQOABoU3A5AOQQAgAikDiAYgASkDiAaFNwOYDkEAIAIpA5AGIAEpA5AGhTcDoA5BACACKQOYBiABKQOYBoU3A6gOQQAgAikDoAYgASkDoAaFNwOwDkEAIAIpA6gGIAEpA6gGhTcDuA5BACACKQOwBiABKQOwBoU3A8AOQQAgAikDuAYgASkDuAaFNwPIDkEAIAIpA8AGIAEpA8AGhTcD0A5BACACKQPIBiABKQPIBoU3A9gOQQAgAikD0AYgASkD0AaFNwPgDkEAIAIpA9gGIAEpA9gGhTcD6A5BACACKQPgBiABKQPgBoU3A/AOQQAgAikD6AYgASkD6AaFNwP4DkEAIAIpA/AGIAEpA/AGhTcDgA9BACACKQP4BiABKQP4BoU3A4gPQQAgAikDgAcgASkDgAeFNwOQD0EAIAIpA4gHIAEpA4gHhTcDmA9BACACKQOQByABKQOQB4U3A6APQQAgAikDmAcgASkDmAeFNwOoD0EAIAIpA6AHIAEpA6AHhTcDsA9BACACKQOoByABKQOoB4U3A7gPQQAgAikDsAcgASkDsAeFNwPAD0EAIAIpA7gHIAEpA7gHhTcDyA9BACACKQPAByABKQPAB4U3A9APQQAgAikDyAcgASkDyAeFNwPYD0EAIAIpA9AHIAEpA9AHhTcD4A9BACACKQPYByABKQPYB4U3A+gPQQAgAikD4AcgASkD4AeFNwPwD0EAIAIpA+gHIAEpA+gHhTcD+A9BACACKQPwByABKQPwB4U3A4AQQQAgAikD+AcgASkD+AeFNwOIEEGQCEGYCEGgCEGoCEGwCEG4CEHACEHICEHQCEHYCEHgCEHoCEHwCEH4CEGACUGICRACQZAJQZgJQaAJQagJQbAJQbgJQcAJQcgJQdAJQdgJQeAJQegJQfAJQfgJQYAKQYgKEAJBkApBmApBoApBqApBsApBuApBwApByApB0ApB2ApB4ApB6ApB8ApB+ApBgAtBiAsQAkGQC0GYC0GgC0GoC0GwC0G4C0HAC0HIC0HQC0HYC0HgC0HoC0HwC0H4C0GADEGIDBACQZAMQZgMQaAMQagMQbAMQbgMQcAMQcgMQdAMQdgMQeAMQegMQfAMQfgMQYANQYgNEAJBkA1BmA1BoA1BqA1BsA1BuA1BwA1ByA1B0A1B2A1B4A1B6A1B8A1B+A1BgA5BiA4QAkGQDkGYDkGgDkGoDkGwDkG4DkHADkHIDkHQDkHYDkHgDkHoDkHwDkH4DkGAD0GIDxACQZAPQZgPQaAPQagPQbAPQbgPQcAPQcgPQdAPQdgPQeAPQegPQfAPQfgPQYAQQYgQEAJBkAhBmAhBkAlBmAlBkApBmApBkAtBmAtBkAxBmAxBkA1BmA1BkA5BmA5BkA9BmA8QAkGgCEGoCEGgCUGoCUGgCkGoCkGgC0GoC0GgDEGoDEGgDUGoDUGgDkGoDkGgD0GoDxACQbAIQbgIQbAJQbgJQbAKQbgKQbALQbgLQbAMQbgMQbANQbgNQbAOQbgOQbAPQbgPEAJBwAhByAhBwAlByAlBwApByApBwAtByAtBwAxByAxBwA1ByA1BwA5ByA5BwA9ByA8QAkHQCEHYCEHQCUHYCUHQCkHYCkHQC0HYC0HQDEHYDEHQDUHYDUHQDkHYDkHQD0HYDxACQeAIQegIQeAJQegJQeAKQegKQeALQegLQeAMQegMQeANQegNQeAOQegOQeAPQegPEAJB8AhB+AhB8AlB+AlB8ApB+ApB8AtB+AtB8AxB+AxB8A1B+A1B8A5B+A5B8A9B+A8QAkGACUGICUGACkGICkGAC0GIC0GADEGIDEGADUGIDUGADkGIDkGAD0GID0GAEEGIEBACAkACQCADRQ0AA0AgACAEaiIDIAIgBGoiBSkDACABIARqIgYpAwCFIARBkAhqKQMAhSADKQMAhTcDACADQQhqIgMgBUEIaikDACAGQQhqKQMAhSAEQZgIaikDAIUgAykDAIU3AwAgBEEQaiIEQYAIRw0ADAILC0EAIQQDQCAAIARqIgMgAiAEaiIFKQMAIAEgBGoiBikDAIUgBEGQCGopAwCFNwMAIANBCGogBUEIaikDACAGQQhqKQMAhSAEQZgIaikDAIU3AwAgBEEQaiIEQYAIRw0ACwsL5QcMBX8BfgR/An4BfwF+AX8Bfgd/AX4DfwF+AkBBACgCgAgiAiABQQp0aiIDKAIIIAFHDQAgAygCDCEEIAMoAgAhBUEAIAMoAhQiBq03A7gQQQAgBK0iBzcDsBBBACAFIAEgBUECdG4iCGwiCUECdK03A6gQAkACQAJAAkAgBEUNAEF/IQogBUUNASAIQQNsIQsgCEECdCIErSEMIAWtIQ0gBkF/akECSSEOQgAhDwNAQQAgDzcDkBAgD6chEEIAIRFBACEBA0BBACARNwOgECAPIBGEUCIDIA5xIRIgBkEBRiAPUCITIAZBAkYgEUICVHFxciEUQX8gAUEBakEDcSAIbEF/aiATGyEVIAEgEHIhFiABIAhsIRcgA0EBdCEYQgAhGQNAQQBCADcDwBBBACAZNwOYECAYIQECQCASRQ0AQQBCATcDwBBBkBhBkBBBkCBBABADQZAYQZAYQZAgQQAQA0ECIQELAkAgASAITw0AIAQgGaciGmwgF2ogAWohAwNAIANBACAEIAEbQQAgEVAiGxtqQX9qIRwCQAJAIBQNAEEAKAKACCICIBxBCnQiHGohCgwBCwJAIAFB/wBxIgINAEEAQQApA8AQQgF8NwPAEEGQGEGQEEGQIEEAEANBkBhBkBhBkCBBABADCyAcQQp0IRwgAkEDdEGQGGohCkEAKAKACCECCyACIANBCnRqIAIgHGogAiAKKQMAIh1CIIinIAVwIBogFhsiHCAEbCABIAFBACAZIBytUSIcGyIKIBsbIBdqIAogC2ogExsgAUUgHHJrIhsgFWqtIB1C/////w+DIh0gHX5CIIggG61+QiCIfSAMgqdqQQp0akEBEAMgA0EBaiEDIAggAUEBaiIBRw0ACwsgGUIBfCIZIA1SDQALIBFCAXwiEachASARQgRSDQALIA9CAXwiDyAHUg0AC0EAKAKACCECCyAJQQx0QYB4aiEXIAVBf2oiCkUNAgwBC0EAQgM3A6AQQQAgBEF/aq03A5AQQYB4IRcLIAIgF2ohGyAIQQx0IQhBACEcA0AgCCAcQQFqIhxsQYB4aiEEQQAhAQNAIBsgAWoiAyADKQMAIAIgBCABamopAwCFNwMAIANBCGoiAyADKQMAIAIgBCABQQhyamopAwCFNwMAIAFBCGohAyABQRBqIQEgA0H4B0kNAAsgHCAKRw0ACwsgAiAXaiEbQXghAQNAIAIgAWoiA0EIaiAbIAFqIgRBCGopAwA3AwAgA0EQaiAEQRBqKQMANwMAIANBGGogBEEYaikDADcDACADQSBqIARBIGopAwA3AwAgAUEgaiIBQfgHSQ0ACwsL",_o="e4cdc523",jo={name:Zo,data:$o,hash:_o},ta="blake2b",ea="AGFzbQEAAAABEQRgAAF/YAJ/fwBgAX8AYAAAAwoJAAECAwECAgABBQQBAQICBg4CfwFBsIsFC38AQYAICwdwCAZtZW1vcnkCAA5IYXNoX0dldEJ1ZmZlcgAACkhhc2hfRmluYWwAAwlIYXNoX0luaXQABQtIYXNoX1VwZGF0ZQAGDUhhc2hfR2V0U3RhdGUABw5IYXNoX0NhbGN1bGF0ZQAIClNUQVRFX1NJWkUDAQrTOAkFAEGACQvrAgIFfwF+AkAgAUEBSA0AAkACQAJAIAFBgAFBACgC4IoBIgJrIgNKDQAgASEEDAELQQBBADYC4IoBAkAgAkH/AEoNACACQeCJAWohBSAAIQRBACEGA0AgBSAELQAAOgAAIARBAWohBCAFQQFqIQUgAyAGQQFqIgZB/wFxSg0ACwtBAEEAKQPAiQEiB0KAAXw3A8CJAUEAQQApA8iJASAHQv9+Vq18NwPIiQFB4IkBEAIgACADaiEAAkAgASADayIEQYEBSA0AIAIgAWohBQNAQQBBACkDwIkBIgdCgAF8NwPAiQFBAEEAKQPIiQEgB0L/flatfDcDyIkBIAAQAiAAQYABaiEAIAVBgH9qIgVBgAJLDQALIAVBgH9qIQQMAQsgBEEATA0BC0EAIQUDQCAFQQAoAuCKAWpB4IkBaiAAIAVqLQAAOgAAIAQgBUEBaiIFQf8BcUoNAAsLQQBBACgC4IoBIARqNgLgigELC78uASR+QQBBACkD0IkBQQApA7CJASIBQQApA5CJAXwgACkDICICfCIDhULr+obav7X2wR+FQiCJIgRCq/DT9K/uvLc8fCIFIAGFQiiJIgYgA3wgACkDKCIBfCIHIASFQjCJIgggBXwiCSAGhUIBiSIKQQApA8iJAUEAKQOoiQEiBEEAKQOIiQF8IAApAxAiA3wiBYVCn9j52cKR2oKbf4VCIIkiC0K7zqqm2NDrs7t/fCIMIASFQiiJIg0gBXwgACkDGCIEfCIOfCAAKQNQIgV8Ig9BACkDwIkBQQApA6CJASIQQQApA4CJASIRfCAAKQMAIgZ8IhKFQtGFmu/6z5SH0QCFQiCJIhNCiJLznf/M+YTqAHwiFCAQhUIoiSIVIBJ8IAApAwgiEHwiFiAThUIwiSIXhUIgiSIYQQApA9iJAUEAKQO4iQEiE0EAKQOYiQF8IAApAzAiEnwiGYVC+cL4m5Gjs/DbAIVCIIkiGkLx7fT4paf9p6V/fCIbIBOFQiiJIhwgGXwgACkDOCITfCIZIBqFQjCJIhogG3wiG3wiHSAKhUIoiSIeIA98IAApA1giCnwiDyAYhUIwiSIYIB18Ih0gDiALhUIwiSIOIAx8Ih8gDYVCAYkiDCAWfCAAKQNAIgt8Ig0gGoVCIIkiFiAJfCIaIAyFQiiJIiAgDXwgACkDSCIJfCIhIBaFQjCJIhYgGyAchUIBiSIMIAd8IAApA2AiB3wiDSAOhUIgiSIOIBcgFHwiFHwiFyAMhUIoiSIbIA18IAApA2giDHwiHCAOhUIwiSIOIBd8IhcgG4VCAYkiGyAZIBQgFYVCAYkiFHwgACkDcCINfCIVIAiFQiCJIhkgH3wiHyAUhUIoiSIUIBV8IAApA3giCHwiFXwgDHwiIoVCIIkiI3wiJCAbhUIoiSIbICJ8IBJ8IiIgFyAYIBUgGYVCMIkiFSAffCIZIBSFQgGJIhQgIXwgDXwiH4VCIIkiGHwiFyAUhUIoiSIUIB98IAV8Ih8gGIVCMIkiGCAXfCIXIBSFQgGJIhR8IAF8IiEgFiAafCIWIBUgHSAehUIBiSIaIBx8IAl8IhyFQiCJIhV8Ih0gGoVCKIkiGiAcfCAIfCIcIBWFQjCJIhWFQiCJIh4gGSAOIBYgIIVCAYkiFiAPfCACfCIPhUIgiSIOfCIZIBaFQiiJIhYgD3wgC3wiDyAOhUIwiSIOIBl8Ihl8IiAgFIVCKIkiFCAhfCAEfCIhIB6FQjCJIh4gIHwiICAiICOFQjCJIiIgJHwiIyAbhUIBiSIbIBx8IAp8IhwgDoVCIIkiDiAXfCIXIBuFQiiJIhsgHHwgE3wiHCAOhUIwiSIOIBkgFoVCAYkiFiAffCAQfCIZICKFQiCJIh8gFSAdfCIVfCIdIBaFQiiJIhYgGXwgB3wiGSAfhUIwiSIfIB18Ih0gFoVCAYkiFiAVIBqFQgGJIhUgD3wgBnwiDyAYhUIgiSIYICN8IhogFYVCKIkiFSAPfCADfCIPfCAHfCIihUIgiSIjfCIkIBaFQiiJIhYgInwgBnwiIiAjhUIwiSIjICR8IiQgFoVCAYkiFiAOIBd8Ig4gDyAYhUIwiSIPICAgFIVCAYkiFCAZfCAKfCIXhUIgiSIYfCIZIBSFQiiJIhQgF3wgC3wiF3wgBXwiICAPIBp8Ig8gHyAOIBuFQgGJIg4gIXwgCHwiGoVCIIkiG3wiHyAOhUIoiSIOIBp8IAx8IhogG4VCMIkiG4VCIIkiISAdIB4gDyAVhUIBiSIPIBx8IAF8IhWFQiCJIhx8Ih0gD4VCKIkiDyAVfCADfCIVIByFQjCJIhwgHXwiHXwiHiAWhUIoiSIWICB8IA18IiAgIYVCMIkiISAefCIeIBogFyAYhUIwiSIXIBl8IhggFIVCAYkiFHwgCXwiGSAchUIgiSIaICR8IhwgFIVCKIkiFCAZfCACfCIZIBqFQjCJIhogHSAPhUIBiSIPICJ8IAR8Ih0gF4VCIIkiFyAbIB98Iht8Ih8gD4VCKIkiDyAdfCASfCIdIBeFQjCJIhcgH3wiHyAPhUIBiSIPIBsgDoVCAYkiDiAVfCATfCIVICOFQiCJIhsgGHwiGCAOhUIoiSIOIBV8IBB8IhV8IAx8IiKFQiCJIiN8IiQgD4VCKIkiDyAifCAHfCIiICOFQjCJIiMgJHwiJCAPhUIBiSIPIBogHHwiGiAVIBuFQjCJIhUgHiAWhUIBiSIWIB18IAR8IhuFQiCJIhx8Ih0gFoVCKIkiFiAbfCAQfCIbfCABfCIeIBUgGHwiFSAXIBogFIVCAYkiFCAgfCATfCIYhUIgiSIXfCIaIBSFQiiJIhQgGHwgCXwiGCAXhUIwiSIXhUIgiSIgIB8gISAVIA6FQgGJIg4gGXwgCnwiFYVCIIkiGXwiHyAOhUIoiSIOIBV8IA18IhUgGYVCMIkiGSAffCIffCIhIA+FQiiJIg8gHnwgBXwiHiAghUIwiSIgICF8IiEgGyAchUIwiSIbIB18IhwgFoVCAYkiFiAYfCADfCIYIBmFQiCJIhkgJHwiHSAWhUIoiSIWIBh8IBJ8IhggGYVCMIkiGSAfIA6FQgGJIg4gInwgAnwiHyAbhUIgiSIbIBcgGnwiF3wiGiAOhUIoiSIOIB98IAZ8Ih8gG4VCMIkiGyAafCIaIA6FQgGJIg4gFSAXIBSFQgGJIhR8IAh8IhUgI4VCIIkiFyAcfCIcIBSFQiiJIhQgFXwgC3wiFXwgBXwiIoVCIIkiI3wiJCAOhUIoiSIOICJ8IAh8IiIgGiAgIBUgF4VCMIkiFSAcfCIXIBSFQgGJIhQgGHwgCXwiGIVCIIkiHHwiGiAUhUIoiSIUIBh8IAZ8IhggHIVCMIkiHCAafCIaIBSFQgGJIhR8IAR8IiAgGSAdfCIZIBUgISAPhUIBiSIPIB98IAN8Ih2FQiCJIhV8Ih8gD4VCKIkiDyAdfCACfCIdIBWFQjCJIhWFQiCJIiEgFyAbIBkgFoVCAYkiFiAefCABfCIZhUIgiSIbfCIXIBaFQiiJIhYgGXwgE3wiGSAbhUIwiSIbIBd8Ihd8Ih4gFIVCKIkiFCAgfCAMfCIgICGFQjCJIiEgHnwiHiAiICOFQjCJIiIgJHwiIyAOhUIBiSIOIB18IBJ8Ih0gG4VCIIkiGyAafCIaIA6FQiiJIg4gHXwgC3wiHSAbhUIwiSIbIBcgFoVCAYkiFiAYfCANfCIXICKFQiCJIhggFSAffCIVfCIfIBaFQiiJIhYgF3wgEHwiFyAYhUIwiSIYIB98Ih8gFoVCAYkiFiAVIA+FQgGJIg8gGXwgCnwiFSAchUIgiSIZICN8IhwgD4VCKIkiDyAVfCAHfCIVfCASfCIihUIgiSIjfCIkIBaFQiiJIhYgInwgBXwiIiAjhUIwiSIjICR8IiQgFoVCAYkiFiAbIBp8IhogFSAZhUIwiSIVIB4gFIVCAYkiFCAXfCADfCIXhUIgiSIZfCIbIBSFQiiJIhQgF3wgB3wiF3wgAnwiHiAVIBx8IhUgGCAaIA6FQgGJIg4gIHwgC3wiGoVCIIkiGHwiHCAOhUIoiSIOIBp8IAR8IhogGIVCMIkiGIVCIIkiICAfICEgFSAPhUIBiSIPIB18IAZ8IhWFQiCJIh18Ih8gD4VCKIkiDyAVfCAKfCIVIB2FQjCJIh0gH3wiH3wiISAWhUIoiSIWIB58IAx8Ih4gIIVCMIkiICAhfCIhIBogFyAZhUIwiSIXIBt8IhkgFIVCAYkiFHwgEHwiGiAdhUIgiSIbICR8Ih0gFIVCKIkiFCAafCAJfCIaIBuFQjCJIhsgHyAPhUIBiSIPICJ8IBN8Ih8gF4VCIIkiFyAYIBx8Ihh8IhwgD4VCKIkiDyAffCABfCIfIBeFQjCJIhcgHHwiHCAPhUIBiSIPIBggDoVCAYkiDiAVfCAIfCIVICOFQiCJIhggGXwiGSAOhUIoiSIOIBV8IA18IhV8IA18IiKFQiCJIiN8IiQgD4VCKIkiDyAifCAMfCIiICOFQjCJIiMgJHwiJCAPhUIBiSIPIBsgHXwiGyAVIBiFQjCJIhUgISAWhUIBiSIWIB98IBB8IhiFQiCJIh18Ih8gFoVCKIkiFiAYfCAIfCIYfCASfCIhIBUgGXwiFSAXIBsgFIVCAYkiFCAefCAHfCIZhUIgiSIXfCIbIBSFQiiJIhQgGXwgAXwiGSAXhUIwiSIXhUIgiSIeIBwgICAVIA6FQgGJIg4gGnwgAnwiFYVCIIkiGnwiHCAOhUIoiSIOIBV8IAV8IhUgGoVCMIkiGiAcfCIcfCIgIA+FQiiJIg8gIXwgBHwiISAehUIwiSIeICB8IiAgGCAdhUIwiSIYIB98Ih0gFoVCAYkiFiAZfCAGfCIZIBqFQiCJIhogJHwiHyAWhUIoiSIWIBl8IBN8IhkgGoVCMIkiGiAcIA6FQgGJIg4gInwgCXwiHCAYhUIgiSIYIBcgG3wiF3wiGyAOhUIoiSIOIBx8IAN8IhwgGIVCMIkiGCAbfCIbIA6FQgGJIg4gFSAXIBSFQgGJIhR8IAt8IhUgI4VCIIkiFyAdfCIdIBSFQiiJIhQgFXwgCnwiFXwgBHwiIoVCIIkiI3wiJCAOhUIoiSIOICJ8IAl8IiIgGyAeIBUgF4VCMIkiFSAdfCIXIBSFQgGJIhQgGXwgDHwiGYVCIIkiHXwiGyAUhUIoiSIUIBl8IAp8IhkgHYVCMIkiHSAbfCIbIBSFQgGJIhR8IAN8Ih4gGiAffCIaIBUgICAPhUIBiSIPIBx8IAd8IhyFQiCJIhV8Ih8gD4VCKIkiDyAcfCAQfCIcIBWFQjCJIhWFQiCJIiAgFyAYIBogFoVCAYkiFiAhfCATfCIahUIgiSIYfCIXIBaFQiiJIhYgGnwgDXwiGiAYhUIwiSIYIBd8Ihd8IiEgFIVCKIkiFCAefCAFfCIeICCFQjCJIiAgIXwiISAiICOFQjCJIiIgJHwiIyAOhUIBiSIOIBx8IAt8IhwgGIVCIIkiGCAbfCIbIA6FQiiJIg4gHHwgEnwiHCAYhUIwiSIYIBcgFoVCAYkiFiAZfCABfCIXICKFQiCJIhkgFSAffCIVfCIfIBaFQiiJIhYgF3wgBnwiFyAZhUIwiSIZIB98Ih8gFoVCAYkiFiAVIA+FQgGJIg8gGnwgCHwiFSAdhUIgiSIaICN8Ih0gD4VCKIkiDyAVfCACfCIVfCANfCIihUIgiSIjfCIkIBaFQiiJIhYgInwgCXwiIiAjhUIwiSIjICR8IiQgFoVCAYkiFiAYIBt8IhggFSAahUIwiSIVICEgFIVCAYkiFCAXfCASfCIXhUIgiSIafCIbIBSFQiiJIhQgF3wgCHwiF3wgB3wiISAVIB18IhUgGSAYIA6FQgGJIg4gHnwgBnwiGIVCIIkiGXwiHSAOhUIoiSIOIBh8IAt8IhggGYVCMIkiGYVCIIkiHiAfICAgFSAPhUIBiSIPIBx8IAp8IhWFQiCJIhx8Ih8gD4VCKIkiDyAVfCAEfCIVIByFQjCJIhwgH3wiH3wiICAWhUIoiSIWICF8IAN8IiEgHoVCMIkiHiAgfCIgIBggFyAahUIwiSIXIBt8IhogFIVCAYkiFHwgBXwiGCAchUIgiSIbICR8IhwgFIVCKIkiFCAYfCABfCIYIBuFQjCJIhsgHyAPhUIBiSIPICJ8IAx8Ih8gF4VCIIkiFyAZIB18Ihl8Ih0gD4VCKIkiDyAffCATfCIfIBeFQjCJIhcgHXwiHSAPhUIBiSIPIBkgDoVCAYkiDiAVfCAQfCIVICOFQiCJIhkgGnwiGiAOhUIoiSIOIBV8IAJ8IhV8IBN8IiKFQiCJIiN8IiQgD4VCKIkiDyAifCASfCIiICOFQjCJIiMgJHwiJCAPhUIBiSIPIBsgHHwiGyAVIBmFQjCJIhUgICAWhUIBiSIWIB98IAt8IhmFQiCJIhx8Ih8gFoVCKIkiFiAZfCACfCIZfCAJfCIgIBUgGnwiFSAXIBsgFIVCAYkiFCAhfCAFfCIahUIgiSIXfCIbIBSFQiiJIhQgGnwgA3wiGiAXhUIwiSIXhUIgiSIhIB0gHiAVIA6FQgGJIg4gGHwgEHwiFYVCIIkiGHwiHSAOhUIoiSIOIBV8IAF8IhUgGIVCMIkiGCAdfCIdfCIeIA+FQiiJIg8gIHwgDXwiICAhhUIwiSIhIB58Ih4gGSAchUIwiSIZIB98IhwgFoVCAYkiFiAafCAIfCIaIBiFQiCJIhggJHwiHyAWhUIoiSIWIBp8IAp8IhogGIVCMIkiGCAdIA6FQgGJIg4gInwgBHwiHSAZhUIgiSIZIBcgG3wiF3wiGyAOhUIoiSIOIB18IAd8Ih0gGYVCMIkiGSAbfCIbIA6FQgGJIg4gFSAXIBSFQgGJIhR8IAx8IhUgI4VCIIkiFyAcfCIcIBSFQiiJIhQgFXwgBnwiFXwgEnwiIoVCIIkiI3wiJCAOhUIoiSIOICJ8IBN8IiIgGyAhIBUgF4VCMIkiFSAcfCIXIBSFQgGJIhQgGnwgBnwiGoVCIIkiHHwiGyAUhUIoiSIUIBp8IBB8IhogHIVCMIkiHCAbfCIbIBSFQgGJIhR8IA18IiEgGCAffCIYIBUgHiAPhUIBiSIPIB18IAJ8Ih2FQiCJIhV8Ih4gD4VCKIkiDyAdfCABfCIdIBWFQjCJIhWFQiCJIh8gFyAZIBggFoVCAYkiFiAgfCADfCIYhUIgiSIZfCIXIBaFQiiJIhYgGHwgBHwiGCAZhUIwiSIZIBd8Ihd8IiAgFIVCKIkiFCAhfCAIfCIhIB+FQjCJIh8gIHwiICAiICOFQjCJIiIgJHwiIyAOhUIBiSIOIB18IAd8Ih0gGYVCIIkiGSAbfCIbIA6FQiiJIg4gHXwgDHwiHSAZhUIwiSIZIBcgFoVCAYkiFiAafCALfCIXICKFQiCJIhogFSAefCIVfCIeIBaFQiiJIhYgF3wgCXwiFyAahUIwiSIaIB58Ih4gFoVCAYkiFiAVIA+FQgGJIg8gGHwgBXwiFSAchUIgiSIYICN8IhwgD4VCKIkiDyAVfCAKfCIVfCACfCIChUIgiSIifCIjIBaFQiiJIhYgAnwgC3wiAiAihUIwiSILICN8IiIgFoVCAYkiFiAZIBt8IhkgFSAYhUIwiSIVICAgFIVCAYkiFCAXfCANfCINhUIgiSIXfCIYIBSFQiiJIhQgDXwgBXwiBXwgEHwiECAVIBx8Ig0gGiAZIA6FQgGJIg4gIXwgDHwiDIVCIIkiFXwiGSAOhUIoiSIOIAx8IBJ8IhIgFYVCMIkiDIVCIIkiFSAeIB8gDSAPhUIBiSINIB18IAl8IgmFQiCJIg98IhogDYVCKIkiDSAJfCAIfCIJIA+FQjCJIgggGnwiD3wiGiAWhUIoiSIWIBB8IAd8IhAgEYUgDCAZfCIHIA6FQgGJIgwgCXwgCnwiCiALhUIgiSILIAUgF4VCMIkiBSAYfCIJfCIOIAyFQiiJIgwgCnwgE3wiEyALhUIwiSIKIA58IguFNwOAiQFBACADIAYgDyANhUIBiSINIAJ8fCICIAWFQiCJIgUgB3wiBiANhUIoiSIHIAJ8fCICQQApA4iJAYUgBCABIBIgCSAUhUIBiSIDfHwiASAIhUIgiSISICJ8IgkgA4VCKIkiAyABfHwiASAShUIwiSIEIAl8IhKFNwOIiQFBACATQQApA5CJAYUgECAVhUIwiSIQIBp8IhOFNwOQiQFBACABQQApA5iJAYUgAiAFhUIwiSICIAZ8IgGFNwOYiQFBACASIAOFQgGJQQApA6CJAYUgAoU3A6CJAUEAIBMgFoVCAYlBACkDqIkBhSAKhTcDqIkBQQAgASAHhUIBiUEAKQOwiQGFIASFNwOwiQFBACALIAyFQgGJQQApA7iJAYUgEIU3A7iJAQvdAgUBfwF+AX8BfgJ/IwBBwABrIgAkAAJAQQApA9CJAUIAUg0AQQBBACkDwIkBIgFBACgC4IoBIgKsfCIDNwPAiQFBAEEAKQPIiQEgAyABVK18NwPIiQECQEEALQDoigFFDQBBAEJ/NwPYiQELQQBCfzcD0IkBAkAgAkH/AEoNAEEAIQQDQCACIARqQeCJAWpBADoAACAEQQFqIgRBgAFBACgC4IoBIgJrSA0ACwtB4IkBEAIgAEEAKQOAiQE3AwAgAEEAKQOIiQE3AwggAEEAKQOQiQE3AxAgAEEAKQOYiQE3AxggAEEAKQOgiQE3AyAgAEEAKQOoiQE3AyggAEEAKQOwiQE3AzAgAEEAKQO4iQE3AzhBACgC5IoBIgVBAUgNAEEAIQRBACECA0AgBEGACWogACAEai0AADoAACAEQQFqIQQgBSACQQFqIgJB/wFxSg0ACwsgAEHAAGokAAv9AwMBfwF+AX8jAEGAAWsiAiQAQQBBgQI7AfKKAUEAIAE6APGKAUEAIAA6APCKAUGQfiEAA0AgAEGAiwFqQgA3AAAgAEH4igFqQgA3AAAgAEHwigFqQgA3AAAgAEEYaiIADQALQQAhAEEAQQApA/CKASIDQoiS853/zPmE6gCFNwOAiQFBAEEAKQP4igFCu86qptjQ67O7f4U3A4iJAUEAQQApA4CLAUKr8NP0r+68tzyFNwOQiQFBAEEAKQOIiwFC8e30+KWn/aelf4U3A5iJAUEAQQApA5CLAULRhZrv+s+Uh9EAhTcDoIkBQQBBACkDmIsBQp/Y+dnCkdqCm3+FNwOoiQFBAEEAKQOgiwFC6/qG2r+19sEfhTcDsIkBQQBBACkDqIsBQvnC+JuRo7Pw2wCFNwO4iQFBACADp0H/AXE2AuSKAQJAIAFBAUgNACACQgA3A3ggAkIANwNwIAJCADcDaCACQgA3A2AgAkIANwNYIAJCADcDUCACQgA3A0ggAkIANwNAIAJCADcDOCACQgA3AzAgAkIANwMoIAJCADcDICACQgA3AxggAkIANwMQIAJCADcDCCACQgA3AwBBACEEA0AgAiAAaiAAQYAJai0AADoAACAAQQFqIQAgBEEBaiIEQf8BcSABSA0ACyACQYABEAELIAJBgAFqJAALEgAgAEEDdkH/P3EgAEEQdhAECwkAQYAJIAAQAQsGAEGAiQELGwAgAUEDdkH/P3EgAUEQdhAEQYAJIAAQARADCwsLAQBBgAgLBPAAAAA=",ia="c6f286e6",sa={name:ta,data:ea,hash:ia},lA=new Bt;function Jn(d){return!Number.isInteger(d)||d<8||d>512||d%8!==0?new Error("Invalid variant! Valid values: 8, 16, ..., 512"):null}function na(d,A){return d|A<<16}function Ms(d=512,A=null){if(Jn(d))return Promise.reject(Jn(d));let t=null,e=d;if(A!==null){if(t=Yt(A),t.length>64)return Promise.reject(new Error("Max key length is 64 bytes"));e=na(d,t.length)}let i=d/8;return Yn(sa,i).then(s=>{e>512&&s.writeMemory(t),s.init(e);let n={init:e>512?()=>(s.writeMemory(t),s.init(e),n):()=>(s.init(e),n),update:o=>(s.update(o),n),digest:o=>s.digest(o),save:()=>s.save(),load:o=>(s.load(o),n),blockSize:128,digestSize:i};return n})}function oa(d,A,t){let e=[`m=${A.memorySize}`,`t=${A.iterations}`,`p=${A.parallelism}`].join(",");return`$argon2${A.hashType}$v=19$${e}$${Ln(d,!1)}$${Ln(t,!1)}`}var qn=new DataView(new ArrayBuffer(4));function Kt(d){return qn.setInt32(0,d,!0),new Uint8Array(qn.buffer)}function bs(d,A,t){return he(this,void 0,void 0,function*(){if(t<=64){let r=yield Ms(t*8);return r.update(Kt(t)),r.update(A),r.digest("binary")}let e=Math.ceil(t/32)-2,i=new Uint8Array(t);d.init(),d.update(Kt(t)),d.update(A);let s=d.digest("binary");i.set(s.subarray(0,32),0);for(let r=1;r<e;r++)d.init(),d.update(s),s=d.digest("binary"),i.set(s.subarray(0,32),r*32);let n=t-32*e,o;return n===64?(o=d,o.init()):o=yield Ms(n*8),o.update(s),s=o.digest("binary"),i.set(s.subarray(0,n),e*32),i})}function aa(d){switch(d){case"d":return 0;case"i":return 1;default:return 2}}function ra(d){return he(this,void 0,void 0,function*(){var A;let{parallelism:t,iterations:e,hashLength:i}=d,s=Yt(d.password),n=Yt(d.salt),o=19,r=aa(d.hashType),{memorySize:a}=d,c=Yt((A=d.secret)!==null&&A!==void 0?A:""),[l,p]=yield Promise.all([Yn(jo,1024),Ms(512)]);l.setMemorySize(a*1024+1024);let g=new Uint8Array(24),h=new DataView(g.buffer);h.setInt32(0,t,!0),h.setInt32(4,i,!0),h.setInt32(8,a,!0),h.setInt32(12,e,!0),h.setInt32(16,o,!0),h.setInt32(20,r,!0),l.writeMemory(g,a*1024),p.init(),p.update(g),p.update(Kt(s.length)),p.update(s),p.update(Kt(n.length)),p.update(n),p.update(Kt(c.length)),p.update(c),p.update(Kt(0));let u=Math.floor(a/(t*4))*4,f=new Uint8Array(72),C=p.digest("binary");f.set(C);for(let y=0;y<t;y++){f.set(Kt(0),64),f.set(Kt(y),68);let w=y*u,v=yield bs(p,f,1024);l.writeMemory(v,w*1024),w+=1,f.set(Kt(1),64),v=yield bs(p,f,1024),l.writeMemory(v,w*1024)}let m=new Uint8Array(1024);Kn(m,l.calculate(new Uint8Array([]),a));let E=yield bs(p,m,i);if(d.outputType==="hex"){let y=new Uint8Array(i*2);return xs(y,E,i)}return d.outputType==="encoded"?oa(n,d,E):E})}var Aa=d=>{var A;if(!d||typeof d!="object")throw new Error("Invalid options parameter. It requires an object.");if(!d.password)throw new Error("Password must be specified");if(d.password=Yt(d.password),d.password.length<1)throw new Error("Password must be specified");if(!d.salt)throw new Error("Salt must be specified");if(d.salt=Yt(d.salt),d.salt.length<8)throw new Error("Salt should be at least 8 bytes long");if(d.secret=Yt((A=d.secret)!==null&&A!==void 0?A:""),!Number.isInteger(d.iterations)||d.iterations<1)throw new Error("Iterations should be a positive number");if(!Number.isInteger(d.parallelism)||d.parallelism<1)throw new Error("Parallelism should be a positive number");if(!Number.isInteger(d.hashLength)||d.hashLength<4)throw new Error("Hash length should be at least 4 bytes.");if(!Number.isInteger(d.memorySize))throw new Error("Memory size should be specified.");if(d.memorySize<8*d.parallelism)throw new Error("Memory size should be at least 8 * parallelism.");if(d.outputType===void 0&&(d.outputType="hex"),!["hex","binary","encoded"].includes(d.outputType))throw new Error(`Insupported output type ${d.outputType}. Valid values: ['hex', 'binary', 'encoded']`)};function Hs(d){return he(this,void 0,void 0,function*(){return Aa(d),ra(Object.assign(Object.assign({},d),{hashType:"id"}))})}var dA=new Bt;var hA=new Bt;var gA=new Bt;var pA=new Bt;var IA=new Uint8Array(8);var uA=new Bt;var fA=new Bt;var CA=new Bt;var BA=new Bt;var mA=new Bt;var QA=new Bt;var EA=new Bt;var yA=new Bt;var wA=new Bt;var FA=new Bt;var vA=new Bt;var kA=new Uint8Array(8);var SA=new Bt;var DA=new Uint8Array(8);var bA=new Bt;var NA=new Uint8Array(8);var xA=new Bt;var MA=new Bt;var HA=new Bt;Mt();var zt=new Uint8Array([83,84,65,83,72,69,78,67]),Zn=2,$n=1,_n=2,ca=32,Ts=12,zn=32,la=6e5,da=47104,ha=3,ga=1,Nt=d=>d;function De(d){if(d.length<zt.length+1)return!1;for(let A=0;A<zt.length;A++)if(d[A]!==zt[A])return!1;return!0}function Vn(d,A,t){d[A]=t>>>24&255,d[A+1]=t>>>16&255,d[A+2]=t>>>8&255,d[A+3]=t&255}function Wn(d,A){return d[A]*16777216+(d[A+1]<<16)+(d[A+2]<<8)+d[A+3]}async function Us(d,A,t){if(t.id===_n)return await Hs({password:d,salt:A,parallelism:t.c,iterations:t.b,memorySize:t.a,hashLength:zn,outputType:"binary"});if(t.id===$n){let e=await crypto.subtle.importKey("raw",Nt(new TextEncoder().encode(d)),"PBKDF2",!1,["deriveBits"]),i=await crypto.subtle.deriveBits({name:"PBKDF2",salt:Nt(A),iterations:t.a,hash:"SHA-256"},e,zn*8);return new Uint8Array(i)}throw new Error(`Unsupported KDF id (${t.id}).`)}async function jn(d){return crypto.subtle.importKey("raw",Nt(d),{name:"AES-GCM"},!1,["encrypt","decrypt"])}var to={argon2id:{label:"Argon2id",strong:!0},pbkdf2:{label:"PBKDF2 (fallback)",strong:!1}};async function eo(d,A){let t=crypto.getRandomValues(new Uint8Array(ca)),e=crypto.getRandomValues(new Uint8Array(Ts)),i,s,n;try{i={id:_n,a:da,b:ha,c:ga},n=await Us(A,t,i),s="argon2id"}catch(l){console.warn("[Stashpad] Argon2id unavailable \u2014 encrypting with PBKDF2 fallback.",l),i={id:$n,a:la,b:0,c:0},n=await Us(A,t,i),s="pbkdf2"}let o=pa(i,t,e),r=await jn(n),a=new Uint8Array(await crypto.subtle.encrypt({name:"AES-GCM",iv:Nt(e),additionalData:Nt(o)},r,Nt(d))),c=new Uint8Array(o.length+a.length);return c.set(o,0),c.set(a,o.length),{data:c,kdf:s}}var si=null;async function io(){if(si!==null)return si;try{await Hs({password:"x",salt:new Uint8Array(16),parallelism:1,iterations:1,memorySize:8,hashLength:16,outputType:"binary"}),si=!0}catch{si=!1}return si}function pa(d,A,t){let e=new Uint8Array(zt.length+1+1+4+4+1+1+A.length+t.length),i=0;return e.set(zt,i),i+=zt.length,e[i++]=Zn,e[i++]=d.id,Vn(e,i,d.a),i+=4,Vn(e,i,d.b),i+=4,e[i++]=d.c,e[i++]=A.length,e.set(A,i),i+=A.length,e.set(t,i),i+=t.length,e}async function Xn(d,A){if(!De(d))throw new Error("Not an encrypted Stashpad file.");let t=d[zt.length];if(t===1)return Ia(d,A);if(t!==Zn)throw new Error(`Unsupported encrypted .stash version (${t}).`);let e=zt.length+1,i={id:d[e++],a:0,b:0,c:0};i.a=Wn(d,e),e+=4,i.b=Wn(d,e),e+=4,i.c=d[e++];let s=d[e++],n=d.slice(e,e+s);e+=s;let o=d.slice(e,e+Ts);e+=Ts;let r=d.slice(0,e),a=d.slice(e),c=await Us(A,n,i),l=await jn(c),p=await crypto.subtle.decrypt({name:"AES-GCM",iv:Nt(o),additionalData:Nt(r)},l,Nt(a));return new Uint8Array(p)}async function Ia(d,A){let t=zt.length+1,e=d.slice(t,t+16);t+=16;let i=d.slice(t,t+12);t+=12;let s=d.slice(t),n=await crypto.subtle.importKey("raw",Nt(new TextEncoder().encode(A)),"PBKDF2",!1,["deriveKey"]),o=await crypto.subtle.deriveKey({name:"PBKDF2",salt:Nt(e),iterations:21e4,hash:"SHA-256"},n,{name:"AES-GCM",length:256},!1,["decrypt"]),r=await crypto.subtle.decrypt({name:"AES-GCM",iv:Nt(i)},o,Nt(s));return new Uint8Array(r)}async function be(d,A,t={}){if(!De(A))return A;if(t.secretId){let i=d.secretStorage,s=null;try{s=i?.getSecret(t.secretId)??null}catch{s=null}if(s)try{return await Xn(A,s)}catch{}}let e;for(;;){let i=await new Promise(s=>{new Je(d,e,!!t.allowLater,s).open()});if(i.kind==="cancel")return null;if(i.kind==="later")return t.onLater?.(),null;try{return await Xn(A,i.value)}catch{e="Wrong password or corrupted file. Try again."}}}di();Mt();function ua(d){return d.replace(/[^\w.\-]+/g,"_").replace(/^\.+/,"").slice(0,60)||"stash-export"}async function so(d,A){let t=Ca(d,A);if(t.length===0){new ie.Notice("Nothing to export.");return}let e=Ba(d,t);if(e.length===0){new ie.Notice("No exportable notes (no files attached).");return}let i=(d.noteFolder.split("/").pop()||d.noteFolder).trim(),s=t.length===1?d.titleForNode(t[0]):`${i}-${t.length}notes`;new Le(d.app,s,e.length,(n,o,r)=>{fa(d,t,e,n,o,r)},io).open()}async function fa(d,A,t,e,i,s=!1){try{let n=await Un(d.app,{rootNotes:A.filter(h=>!!h.file).map(h=>({id:h.id,file:h.file})),allDescendants:t.filter(h=>!A.some(I=>I.id===h.id)).filter(h=>!!h.file).map(h=>({id:h.id,file:h.file})),sourceFolder:d.noteFolder}),o="";if(i){let h=await eo(n,i);n=h.data;let I=to[h.kdf];o=I.strong?` (encrypted \xB7 ${I.label})`:` (encrypted \xB7 ${I.label} \u2014 Argon2id unavailable on this device, this export is weaker)`}let r=(0,ie.moment)().format("YYYYMMDD-HHmmss"),a=ua(e),c=(d.plugin.settings.exportFolder||"_exports").trim().replace(/^\/+|\/+$/g,""),l=`${d.noteFolder}/${c}`;await d.ensureFolder(l);let p=`${a}-${r}`,g=`${l}/${p}.${te}`;if(await d.app.vault.createBinary(g,n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength)),s&&i){let h=d.app.secretStorage;try{h?.setSecret(Ge(p),i)}catch(I){console.warn("[Stashpad] couldn't save export passphrase to secret storage",I)}}await d.log.append({type:"stash_export",id:A[0].id,payload:{path:g,noteCount:t.length,rootIds:A.map(h=>h.id)}}),d.plugin.notifications.show({message:`Exported ${t.length} note${t.length===1?"":"s"}${o} \u2192 \`${g}\``,kind:i&&o.includes("weaker")?"warning":"success",category:"export",affectedPaths:[g],folder:d.noteFolder,actions:d.actionsForFile(g),duration:0})}catch(n){d.plugin.notifications.show({message:`Stashpad: export failed +Error: ${n.message} +Check disk space + write permissions on the export folder.`,kind:"error",category:"export"}),console.error(n)}}function Ca(d,A){if(A?.file)return[A];if(d.selection.size>0)return[...d.selection].map(e=>d.tree.get(e)).filter(e=>!!e?.file);if(d.cursorIdx>=0&&d.currentChildren[d.cursorIdx])return[d.currentChildren[d.cursorIdx]];let t=d.tree.get(d.focusId);return t?.file?[t]:[]}function Ba(d,A){let t=new Set,e=[],i=s=>{if(!t.has(s.id)){t.add(s.id),s.file&&e.push(s);for(let n of d.tree.getChildren(s.id))i(n)}};for(let s of A)i(s);return e}async function no(d){let A=d.app.vault.getFiles().filter(e=>e.extension===te);if(A.length===0){new ie.Notice("No .stash files found in this vault.");return}let t=new class extends ie.FuzzySuggestModal{getItems(){return A}getItemText(e){return e.path}onChooseItem(e){Gs(d,e)}}(d.app);t.setPlaceholder("Pick a .stash file to import\u2026"),t.open()}async function Gs(d,A){try{let t=new Uint8Array(await d.app.vault.readBinary(A)),e=await be(d.app,t,{secretId:Ge(A.basename)});if(!e)return;let i=await ke(d.app,e,d.noteFolder,ma(d));d.tree.rebuild(d.noteFolder),d.render(),await d.log.append({type:"stash_import",id:G,payload:{from:A.path,into:d.noteFolder,noteCount:i.notesWritten,attachmentsWritten:i.attachmentsWritten,collisionsRenamed:i.collisionsRenamed}});try{await d.app.fileManager.trashFile(A)}catch{}d.plugin.importService.clearPendingEncrypted(A.path);let s=[`Imported ${i.notesWritten} note${i.notesWritten===1?"":"s"}`];i.attachmentsWritten&&s.push(`+ ${i.attachmentsWritten} attachment${i.attachmentsWritten===1?"":"s"}`),i.collisionsRenamed&&s.push(`(${i.collisionsRenamed} id collision${i.collisionsRenamed===1?"":"s"} renamed)`),d.plugin.notifications.show({message:s.join(" "),kind:"success",category:"import",folder:d.noteFolder})}catch(t){d.plugin.notifications.show({message:`Stashpad: import failed File: \`${A.name}\` Error: ${t.message} -Inspect with the buttons below \u2014 rename to .zip to crack it open in an archive tool.`,kind:"error",category:"import",affectedPaths:[A.path],actions:h.actionsForFile(A.path)}),console.error(t)}}function ea(h){let A=new Set,t=e=>{if(A.add(e),!!h.tree.get(e))for(let s of h.tree.getChildren(e))t(s.id)};return t(G),A}var sa=new Set(["png","jpg","jpeg","gif","webp","svg","bmp","avif"]),Ui={nested:"Nested",flat:"Flat",everything:"Everything"},Ti=[{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"}],Gi=class extends L.ItemView{constructor(t,e){super(t);this.focusId=G;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._renderT0=null;this.tinyOpacityPopover=null;this.lastListWidth=0;this.onDocKeyDown=t=>{if(!this.viewRoot.isConnected||this.app.workspace.activeLeaf!==this.leaf||An(t.target))return;let e=Bt().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 i=t.target,s=!!i&&(i.tagName==="INPUT"||i.tagName==="TEXTAREA");if(t.key===" "&&!t.metaKey&&!t.ctrlKey&&!t.altKey&&!t.shiftKey&&!s){let r=this.composerInputEl;if(r){t.preventDefault(),t.stopPropagation(),r.focus();let c=r.value.length;r.setSelectionRange(c,c);return}}let n=!!i&&(i.tagName==="INPUT"||i.tagName==="TEXTAREA"||i.tagName==="BUTTON"||i.tagName==="SELECT");if(t.key==="Escape"&&i instanceof HTMLElement&&(i.tagName==="BUTTON"||i.tagName==="SELECT")&&this.viewRoot.contains(i)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.viewRoot.focus();return}if(this.inListPicker&&t.key==="Escape"){t.preventDefault(),t.stopPropagation(),this.inListPicker=null;let r=this.listEl,c=!!r&&r.scrollTop+r.clientHeight>=r.scrollHeight-2,l=r?.scrollTop??0;if(this.render(),r){let d=c?r.scrollHeight:l;r.scrollTop=d,requestAnimationFrame(()=>{r.scrollTop=c?r.scrollHeight:l}),setTimeout(()=>{r.scrollTop=c?r.scrollHeight:l},60),this.revealCursorRow()}return}if(this.inListPicker&&!n){if(t.key==="ArrowDown"){t.preventDefault(),this.inListPicker.activeIdx=this.nextPickableIdx(this.inListPicker.activeIdx,1),this.repaintSelectionClasses(),this.revealRowAt(this.inListPicker.activeIdx);return}if(t.key==="ArrowUp"){t.preventDefault(),this.inListPicker.activeIdx=this.nextPickableIdx(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 r=this.composerInputEl;if(r){r.focus();let c=r.value.length;r.setSelectionRange(c,c)}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 r=this.currentChildren[this.cursorIdx];r&&(t.preventDefault(),this.navigateTo(r.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 r=this.firstSelectedId??(this.selection.size>0?this.selection.values().next().value:null);if(this.selection.clear(),this.firstSelectedId=null,r){let c=this.currentChildren.findIndex(l=>l.id===r);this.selection.add(r),this.lastSelected=r,c>=0&&(this.cursorIdx=c)}this.repaintSelectionClasses(),this.revealCursorRow();return}let o=Bt().bindings;if(this.selection.size>0||this.cursorIdx>=0&&this.currentChildren[this.cursorIdx]){if(ot(t,o.move)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdMovePicker();return}if(ot(t,o.pickMove)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdInListPicker();return}if(ot(t,o.merge)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdMerge();return}if(ot(t,o.copy)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdCopy();return}if(ot(t,o.copyTree)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdCopyTree();return}if(ot(t,o.copyOutline)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdCopyOutline();return}if(ot(t,o.copyCodeBlock)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdCopyCodeBlock();return}if(ot(t,o.openEditor)){if(t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),t.shiftKey){let r=this.tree.get(this.focusId);r?.file&&this.cmdOpenInEditor(r)}else this.cmdOpenInEditor();return}if(ot(t,o.openTab)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdOpenInNewStashpadTab();return}if(ot(t,o.split)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdSplit();return}if(ot(t,o.clone)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdClone();return}if(ot(t,o.insertTemplate)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdInsertTemplate();return}if(ot(t,o.toggleExpand)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdToggleExpand();return}if(ot(t,o.togglePin)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdTogglePin();return}if(ot(t,o.toggleTask)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdToggleTask();return}if(ot(t,o.setDue)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdSetDue();return}}if(this.currentChildren.length>0){if(ot(t,o.jumpToTop)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.jumpToTop();return}if(ot(t,o.jumpToBottom)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.jumpToBottom();return}}let a=this.tree.get(this.focusId);if(a?.file){if(ot(t,o.openEditor)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdOpenInEditor(a);return}if(ot(t,o.openTab)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdOpenInNewStashpadTab(a);return}}};this.openSearchInstance=null;this.fmSyncUnsubscribe=null;this.completedState=new Map;this.pendingFocusIds=null;this.onFileModify=t=>{!(t instanceof L.TFile)||t.extension!=="md"||t.path.startsWith(this.noteFolder+"/")&&(this.scheduleSlugRename(t),this.scheduleAttachmentSync(t),this.authorship.noteModify(t),this.debouncedRender())};this.onFileCreate=t=>{!(t instanceof L.TFile)||t.extension!=="md"||t.path.startsWith(this.noteFolder+"/")&&this.debouncedRender()};this.plugin=e,this.tree=new Ei(this.app),this.log=e.newLog(),this.integrity=new Si(this.tree,this.log),this.order=new yi(this.app),this.sortStore=new wi(this.app),this.fmSync=new vi(this.app,()=>this.tree),this.tree.setOrderProvider(i=>{let s=this.noteFolder,n=this.sortStore.getMode(s,i);return n==="manual"?this.order.getOrder(s,i):an(this,i,n)}),this.debouncedRender=(0,L.debounce)(()=>this.render(),80),this.authorship=new bi(this),this.dnd=new Ni(this),this.bodyRenderer=new xi(this,this,this.plugin.renderCacheStore)}getViewType(){return ut}getDisplayText(){let t=(this.noteFolder||"").trim(),e=t.split("/").pop()||t||"Stashpad";if(this.focusId&&this.focusId!==G){let i=this.tree.get(this.focusId);if(i){let s=this.titleForNode(i).trim(),n=s.length>40?s.slice(0,40)+"\u2026":s;if(n)return`${e} \u2014 ${n}`}}return e}refreshHeaderTitle(){let t=this.getDisplayText();try{this.leaf.updateHeader?.()}catch{}let i=(this.headerEl??this.containerEl?.querySelector?.(".view-header"))?.querySelector?.(".view-header-title")??this.titleEl;i&&i.textContent!==t&&i.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",()=>ui(this)),this.viewRoot.addEventListener("click",()=>ui(this)),this.viewRoot.addEventListener("mouseup",a=>{a.button===3?(a.preventDefault(),this.navigateBack()):a.button===4&&(a.preventDefault(),this.navigateForward())}),this.viewRoot.addEventListener("auxclick",a=>{a.button===3?(a.preventDefault(),this.navigateBack()):a.button===4&&(a.preventDefault(),this.navigateForward())}),ui(this),this.registerInterval(window.setInterval(()=>this.authorship.pruneContribMaps(),6e4));let e=null,i=()=>{e||(e=new L.Scope(this.app.scope),e.register([],"Escape",()=>{if(this.selection.size>1){let a=this.firstSelectedId??this.selection.values().next().value??null;if(this.selection.clear(),this.firstSelectedId=null,a){let r=this.currentChildren.findIndex(c=>c.id===a);this.selection.add(a),this.lastSelected=a,r>=0&&(this.cursorIdx=r)}this.render(),this.revealCursorRow()}return!1}),this.app.keymap?.pushScope(e))},s=()=>{if(e){try{this.app.keymap?.popScope(e)}catch{}e=null}};this.viewRoot.addEventListener("focusin",i),this.viewRoot.addEventListener("focusout",a=>{let r=a.relatedTarget;r&&this.viewRoot&&this.viewRoot.contains(r)||s()}),this.register(()=>s()),this.detachTreeHook=this.tree.hookMetadataCache(()=>this.debouncedRender()),this.registerEvent(this.app.metadataCache.on("resolved",()=>this.scheduleTreeReconcile())),this.registerEvent(this.app.metadataCache.on("changed",a=>{if(a.extension!=="md")return;let r=this.app.metadataCache.getFileCache(a)?.frontmatter;this.completedState.set(a.path,!!r?.completed)})),this.registerEvent(this.app.vault.on("rename",(a,r)=>{this.completedState.has(r)&&(this.completedState.set(a.path,this.completedState.get(r)),this.completedState.delete(r))})),this.registerEvent(this.app.vault.on("delete",a=>{this.completedState.delete(a.path)})),this.detachSettings=_s(()=>{this.loadConfig();let a=this.plugin.settings.drafts?.[this.noteFolder]??"",r=this.composerInputEl?.value??"";a===""&&this.composerDraft!==""&&r===""?(this.composerDraft="",this.composerInputEl&&(this.composerInputEl.value="")):a===""&&r!==""&&(this.composerDraft=r),!!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(a){let r=a?.message??"";/already exists/i.test(r)||console.warn("[Stashpad] bootstrapFolder failed:",a)}this.tree.rebuild(this.noteFolder),this.installFmSyncActivityNotice(),this.backfillFrontmatterSync(),this.plugin.maybeSweepFolder(this.noteFolder),this.defaultCursorToLast(),this.refreshHeaderTitle(),await this.loadDraftsForFolder();try{let a=this.plugin.loadLastCursor(this.noteFolder);for(let[r,c]of a)this.lastCursorByFocus.set(r,c)}catch{}let n=this.lastCursorByFocus.get(this.focusId),o;n&&this.tree.get(n)?(o={kind:"scroll-to-id",id:n,align:"start"},this.pendingFocusIds=[n]):(this.scrollToBottomOnNextRender=!0,o={kind:"pin-bottom",until:"next-user-input"}),this.render(o),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",a=>{a===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+"/",i=0;for(let s of this.app.vault.getMarkdownFiles()){let n=s.parent?.path?.replace(/\/+$/,"")??"";if(!(n===t||t!==""&&n.startsWith(e)))continue;let o=this.app.metadataCache.getFileCache(s)?.frontmatter?.id;typeof o=="string"&&o&&i++}i!==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(!Bt().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(){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.bodyRenderer.dispose(),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();this.authorship.dispose();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 i=t??null;if(i){"folderOverride"in i&&(this.folderOverride=i.folderOverride??null),i.timeFilter&&(this.timeFilter=i.timeFilter),i.focusId&&(this.focusId=i.focusId),"tagFilter"in i&&(this.tagFilter=i.tagFilter??null),"colorFilter"in i&&(this.colorFilter=i.colorFilter??null),"timeFilterCalendar"in i&&(this.timeFilterCalendar=!!i.timeFilterCalendar),"tinyMode"in i&&(this.tinyMode=!!i.tinyMode),"tinyAlwaysOnTop"in i&&(this.tinyAlwaysOnTop=!!i.tinyAlwaysOnTop),typeof i.tinyOpacity=="number"&&Number.isFinite(i.tinyOpacity)&&(this.tinyOpacity=Math.min(1,Math.max(.3,i.tinyOpacity))),"compactMode"in i&&(this.compactMode=!!i.compactMode);let o=a=>a&&typeof a.folder=="string"&&typeof a.focusId=="string";Array.isArray(i.navBackStack)&&(this.navBackStack=i.navBackStack.filter(o)),Array.isArray(i.navForwardSnapshots)&&(this.navForwardSnapshots=i.navForwardSnapshots.filter(o))}let s=(this.plugin?.settings?.folder??"Stashpad").trim().replace(/^\/+|\/+$/g,""),n=this.folderOverride?.trim().replace(/^\/+|\/+$/g,"")||null;if(this.noteFolder=n||s||"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 r=this.plugin.loadLastCursor(this.noteFolder);for(let[c,l]of r)this.lastCursorByFocus.set(c,l)}catch{}let o=this.lastCursorByFocus.get(this.focusId),a;o&&this.tree.get(o)?(this.pendingFocusIds=[o],a={kind:"scroll-to-id",id:o,align:"start"}):a={kind:"pin-bottom",until:"next-user-input"},this.render(a)}}focus(){this.viewRoot?.focus({preventScroll:!0})}loadConfig(){let t=(this.plugin?.settings?.folder??"Stashpad").trim().replace(/^\/+|\/+$/g,""),i=this.folderOverride?.trim().replace(/^\/+|\/+$/g,"")||null||t||"Stashpad";i!==this.noteFolder?(this.noteFolder=i,this.tree.rebuild(this.noteFolder)):this.noteFolder=i}captureNavSnapshot(){return{folder:this.noteFolder,focusId:this.focusId}}recordNavState(t={}){let e=this.captureNavSnapshot(),i=this.navBackStack[this.navBackStack.length-1];i&&i.folder===e.folder&&i.focusId===e.focusId||(this.navBackStack.push(e),t.keepForward||(this.navForwardSnapshots=[]))}async setFolderOverride(t,e={}){let i=t?.trim().replace(/^\/+|\/+$/g,"")||null;if(i&&this.isReservedFolder(i)){new L.Notice(`"${i}" is a reserved Stashpad subfolder (imports/exports/attachments). Pick a different folder.`);return}if((i||null)!==(this.folderOverride||null)){e.skipHistory||this.recordNavState(),this.folderOverride=i,this.focusId=G,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(s){let n=s?.message??"";/already exists/i.test(n)||console.warn("[Stashpad] bootstrapFolder failed:",s)}this.tree.rebuild(this.noteFolder),this.backfillFrontmatterSync(),this.plugin.maybeSweepFolder(this.noteFolder),this.defaultCursorToLast(),await this.loadDraftsForFolder();try{let s=this.app.workspace;typeof s.saveLayout=="function"?await s.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 L.TFolder){if(e.path==="/"||e.path===""||e.path.startsWith(".")||this.isReservedFolder(e.path))continue;t.push(e.path)}return t.sort((e,i)=>e.localeCompare(i))}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(s=>(s??"").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 L.Notice("Nothing to undo.");return}let e=t.peekUndoLabel(),i=this.plugin.notifications.recent()[0]?.category??"system";t.undo().then(()=>this.plugin.notifications.show({message:`Undid: ${e}`,kind:"info",category:i,folder:this.noteFolder})).catch(s=>this.plugin.notifications.show({message:`Undo failed: ${s.message}`,kind:"error",category:"system",folder:this.noteFolder}))}cmdRedo(){let t=this.plugin.getUndoStack(this.noteFolder);if(!t.canRedo()){new L.Notice("Nothing to redo.");return}let e=t.peekRedoLabel(),i=this.plugin.notifications.recent()[0]?.category??"system";t.redo().then(()=>this.plugin.notifications.show({message:`Redid: ${e}`,kind:"info",category:i,folder:this.noteFolder})).catch(s=>this.plugin.notifications.show({message:`Redo failed: ${s.message}`,kind:"error",category:"system",folder:this.noteFolder}))}async snapshotNotes(t,e){let i=[],s=new Set;for(let r of t)!r.file||s.has(r.file.path)||(s.add(r.file.path),i.push(r.file));let n=await Promise.all(i.map(r=>this.app.vault.read(r))),o=i.map((r,c)=>({path:r.path,content:n[c]})),a=[];if(e){let r=new Set,c=[];for(let d of n)for(let I of this.extractAttachments(this.stripFrontmatter(d))){let g=this.app.metadataCache.getFirstLinkpathDest(I,"");g&&!r.has(g.path)&&(r.add(g.path),c.push(g))}let l=await Promise.all(c.map(d=>this.app.vault.readBinary(d)));for(let d=0;d<c.length;d++)a.push({path:c[d].path,data:l[d]})}return{notes:o,attachments:a}}async restoreSnapshots(t,e){for(let s of t.attachments)try{await this.app.vault.adapter.exists(s.path)||await this.app.vault.createBinary(s.path,s.data)}catch{}for(let s of t.notes)try{await this.app.vault.adapter.exists(s.path)||await this.app.vault.create(s.path,s.content)}catch{}let i=()=>{e&&e.some(n=>this.tree.get(n))&&(this.pendingFocusIds=e.slice())};i(),this.tree.rebuild(this.noteFolder),this.render({kind:"follow-cursor"}),setTimeout(()=>{i(),this.tree.rebuild(this.noteFolder),this.render({kind:"follow-cursor"})},100),setTimeout(()=>{i(),this.tree.rebuild(this.noteFolder),this.render({kind:"follow-cursor"})},400),setTimeout(()=>{for(let s of t.notes){let n=this.tree.idForPath(s.path);n&&this.fmSync.schedule(n)}},500)}async trashNotesAndAttachments(t){let e=new Set;for(let i of t.notes){let s=this.tree.idForPath(i.path);if(!s)continue;let n=this.tree.get(s);n?.parent&&e.add(n.parent)}for(let i of t.notes){let s=this.app.vault.getAbstractFileByPath(i.path);if(s)try{await this.app.fileManager.trashFile(s)}catch{}}for(let i of t.attachments){let s=this.app.vault.getAbstractFileByPath(i.path);if(s)try{await this.app.fileManager.trashFile(s)}catch{}}this.tree.rebuild(this.noteFolder),this.render();for(let i of e)this.fmSync.scheduleParentOfDeleted(i)}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 s={...this.plugin.settings.drafts??{}};t.length===0?delete s[e]:s[e]=t,this.plugin.settings.drafts=s,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,L.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()}currentAttachmentsOnly(){return!!this.plugin.settings.attachmentsOnlyNotes?.[this.noteFolder]}async setAttachmentsOnly(t){let e={...this.plugin.settings.attachmentsOnlyNotes??{}};t?e[this.noteFolder]=!0:delete e[this.noteFolder],this.plugin.settings.attachmentsOnlyNotes=e,await this.plugin.saveSettings()}nodeHasAttachment(t){if(!t.file)return!1;let e=this.app.metadataCache.getFileCache(t.file)?.frontmatter?.attachments;return Array.isArray(e)&&e.length>0}hasAttachmentInSubtree(t){if(this.nodeHasAttachment(t))return!0;for(let e of this.tree.getChildren(t.id))if(this.hasAttachmentInSubtree(e))return!0;return!1}hasIncompleteDescendant(t){for(let e of t.children){let i=this.tree.get(e);if(i&&(!this.isCompleted(i)||this.hasIncompleteDescendant(i)))return!0}return!1}collectEmbeddedAttachmentPaths(){let t=new Set,e=this.noteFolder,i=this.app.vault.getAbstractFileByPath(e);if(!(i instanceof L.TFolder))return t;let s=[i];for(;s.length;){let n=s.pop();for(let o of n.children){if(o instanceof L.TFolder){s.push(o);continue}if(!(o instanceof L.TFile)||o.extension!=="md")continue;let a=this.app.metadataCache.getFileCache(o)?.frontmatter;if(!(!a||!Array.isArray(a.attachments)))for(let r of a.attachments){if(typeof r!="string")continue;let c=he(r),l=this.app.metadataCache.getFirstLinkpathDest(c,o.path);l?t.add(l.path):t.add(c)}}}return t}collectFileItems(t){let e=this.noteFolder,i=this.app.vault.getAbstractFileByPath(e);if(!(i instanceof L.TFolder))return[];let s=this.currentIncludeAttachments(),n=s?new Set:this.collectEmbeddedAttachmentPaths(),o=new Set(["_authors","_imports","_exports","_processed","_attachments","_archive",".archive"]),a=[],r=[i];for(;r.length;){let c=r.pop();for(let l of c.children){if(l instanceof L.TFolder){let d=l.name;if(c===i&&o.has(d)||c===i&&d==="_attachments"&&!s)continue;r.push(l);continue}l instanceof L.TFile&&l.extension!=="md"&&(l.name===".stashpad-order.json"||l.name===".stashpad-sort.json"||!s&&n.has(l.path)||a.push(l))}}return a}populateListBody(t,e){this.lastListWidth=t.clientWidth||this.lastListWidth,this.bodyRenderer.arm(),e.file&&L.Platform.isMobile&&(this.renderFocusedHeaderMini(t,e),this.renderFocusedHeader(t,e));let s=this.currentViewMode()==="everything"?this.collectFileItems(e.id):[];if(this.currentChildren.length===0&&s.length===0)t.createDiv({cls:"stashpad-empty",text:"No notes here yet. Type below to add one."});else if(s.length===0)for(let n=0;n<this.currentChildren.length;n++)this.renderNote(t,this.currentChildren[n],n);else{let o=[...this.currentChildren.map((a,r)=>({kind:"note",ts:Number.isFinite(Date.parse(a.created))?Date.parse(a.created):0,idx:r})),...s.map(a=>({kind:"file",ts:a.stat.ctime,file:a}))];o.sort((a,r)=>a.ts-r.ts);for(let a of o)a.kind==="note"?this.renderNote(t,this.currentChildren[a.idx],a.idx):this.renderFileRow(t,a.file)}e.file&&L.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,i=this.listEl.scrollTop;this.listEl.empty(),this.populateListBody(this.listEl,t),e?this.listEl.scrollTop=this.listEl.scrollHeight:this.listEl.scrollTop=i}renderFileRow(t,e){let i=t.createDiv({cls:"stashpad-file-row"});i.dataset.path=e.path,i.createDiv({cls:"stashpad-file-meta"}).createSpan({cls:"stashpad-file-time",text:this.formatTime(new Date(e.stat.ctime).toISOString())});let n=i.createDiv({cls:"stashpad-file-body"});n.createSpan({cls:"stashpad-file-name",text:e.name}),n.createSpan({cls:"stashpad-file-ext",text:e.extension.toUpperCase()}),i.title=`${e.path} \u2014 click to open`,i.onclick=o=>{o.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(),i=this.currentHideChildless(),s=this.tree.getChildren(t),n=i?s.filter(r=>r.children.length>0):s;if(e==="nested")return n;let o=[],a=r=>{o.push(r);for(let c of this.tree.getChildren(r.id))a(c)};for(let r of n)a(r);return o}filterChildren(t){let e=this.timeFilterCutoff(),i=this.tagFilter?.toLowerCase(),s=this.colorFilter?.toLowerCase()??null,n=this.currentHideCompleted(),o=this.currentAttachmentsOnly();return!e&&!i&&!s&&!n&&!o?t:t.filter(a=>{if(e&&a.created){let r=Date.parse(a.created);if(!Number.isNaN(r)&&r<e)return!1}return!(i&&(!a.file||!this.nodeHasTag(a,i))||s&&(this.colorForNode(a)?.toLowerCase()??null)!==s||n&&this.isCompleted(a)&&!this.hasIncompleteDescendant(a)||o&&!this.hasAttachmentInSubtree(a))})}nodeHasTag(t,e){if(!t.file)return!1;let i=this.app.metadataCache.getFileCache(t.file);if(!i)return!1;if(i.tags){for(let n of i.tags)if((n.tag||"").replace(/^#/,"").toLowerCase()===e)return!0}let s=i.frontmatter?.tags;if(s){let n=Array.isArray(s)?s:[s];for(let o of n)if(typeof o=="string"&&o.replace(/^#/,"").toLowerCase()===e)return!0}return!1}collectFolderTags(){let t=new Map,e=this.tree.getChildren(this.focusId);for(let s of e){if(!s.file)continue;let n=this.app.metadataCache.getFileCache(s.file);if(n?.tags)for(let a of n.tags){let r=(a.tag||"").replace(/^#/,"");r&&t.set(r,(t.get(r)??0)+1)}let o=n?.frontmatter?.tags;if(o){let a=Array.isArray(o)?o:[o];for(let r of a){if(typeof r!="string")continue;let c=r.replace(/^#/,"");c&&t.set(c,(t.get(c)??0)+1)}}}let i=[...t.entries()].map(([s,n])=>({raw:s,count:n,label:this.formatTagLabel(s)}));return i.sort((s,n)=>n.count-s.count||s.label.localeCompare(n.label)),i}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 s of e){let n=this.colorForNode(s);if(!n)continue;let o=n.toLowerCase();t.set(o,(t.get(o)??0)+1)}let i=[...t.entries()].map(([s,n])=>({hex:s,count:n}));return i.sort((s,n)=>n.count-s.count||s.hex.localeCompare(n.hex)),i}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 i=this.currentChildren[this.cursorIdx]?.id??this.lastSelected;if(!i)return;this.lastCursorByFocus.set(this.focusId,i);let s=()=>{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,s();return}this.stampLastCursorTimer!=null&&window.clearTimeout(this.stampLastCursorTimer),this.stampLastCursorTimer=window.setTimeout(()=>{this.stampLastCursorTimer=null,s()},400)}captureScrollAnchor(){let t=this.listEl;if(!t)return null;let e=t.getBoundingClientRect().top,i=Array.from(t.querySelectorAll(".stashpad-note"));if(i.length===0)return null;let s=null;for(let n of i){let o=n.dataset.id;if(!o)continue;let a=n.getBoundingClientRect().top-e;if(a>=0){s={id:o,offsetFromListTop:a};break}s={id:o,offsetFromListTop:a}}return s}restoreScrollAnchor(t,e){let i=this.listEl;if(i){if(t){let s=i.querySelector(`[data-id="${t.id}"]`);if(s){let n=i.getBoundingClientRect().top,o=s.getBoundingClientRect().top-n;i.scrollTop+=o-t.offsetFromListTop;return}}e>0&&(i.scrollTop=e)}}render(t){vt.enabled&&(this._renderT0=performance.now()),this.pendingRenderPolicy=t??{kind:"preserve"},this.loadConfig();let e=this.viewRoot,i=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 a=!!this.listEl&&(this.stickToListBottom||this.listEl.scrollTop+this.listEl.clientHeight>=this.listEl.scrollHeight-2);e.empty(),e.toggleClass("is-mobile",L.Platform.isMobile),e.toggleClass("is-tiny",this.tinyMode),e.toggleClass("is-compact",this.compactMode);let r=this.containerEl.closest(".workspace-leaf");r&&(r.classList.toggle("stashpad-is-tiny",this.tinyMode),r.classList.toggle("stashpad-is-compact",this.compactMode));let c=this.containerEl.closest(".workspace-tabs");c&&c.classList.toggle("stashpad-has-tiny",this.tinyMode),this.tinyMode?this.renderTinyHeader(e):(this.compactMode||this.renderTimeFilterBar(e),this.renderBreadcrumb(e));let l=this.tree.get(this.focusId)??this.tree.getRoot();l.file&&!L.Platform.isMobile&&!this.tinyMode&&!this.compactMode&&this.renderFocusedHeader(e,l),this.currentChildren=this.filterChildren(this.collectViewItems(l.id));let d=!1;if(this.autoSelectNewest&&this.currentChildren.length>0){let p=this.currentChildren[this.currentChildren.length-1];this.cursorIdx=this.currentChildren.length-1,this.selection.clear(),this.selection.add(p.id),this.lastSelected=p.id,this.autoSelectNewest=!1,d=!0}else if(this.pendingFocusIds){let p=this.pendingFocusIds;this.pendingFocusIds=null,this.selection.clear();let u=-1;for(let f of p){let B=this.currentChildren.findIndex(Q=>Q.id===f);B>=0&&(this.selection.add(f),u<0&&(u=B))}this.cursorIdx=u,u>=0&&(this.lastSelected=p.find(f=>this.currentChildren.some(B=>B.id===f))??null)}else this.cursorIdx>=this.currentChildren.length&&(this.cursorIdx=this.currentChildren.length-1);let I=e.createDiv({cls:"stashpad-list"});if(this.listEl=I,this.dnd.attachListDnD(I),this.populateListBody(I,l),this.renderComposer(e),L.Platform.isMobile&&this.renderMobileNav(e),this._renderT0!=null&&(vt.record("render.total",performance.now()-this._renderT0),this._renderT0=null),this.plugin.notifyStashpadContentChanged(),d&&this.plugin.notifyStashpadSelectionChanged(),this.focusComposerOnNextRender){this.focusComposerOnNextRender=!1;let p=this.pendingComposerCaret;this.pendingComposerCaret=null;let u=this.composerInputEl;if(u&&u.isConnected){if(u.focus({preventScroll:!0}),p!=null){let f=Math.min(p,u.value.length);try{u.setSelectionRange(f,f)}catch{}}}else requestAnimationFrame(()=>{let f=this.composerInputEl;if(f&&(f.focus({preventScroll:!0}),p!=null)){let B=Math.min(p,f.value.length);try{f.setSelectionRange(B,B)}catch{}}})}let g=this.pendingRenderPolicy;if(this.pendingRenderPolicy=null,g&&this.listEl){let p=this.scrollToBottomOnNextRender;switch(this.scrollToBottomOnNextRender=!1,g.kind){case"preserve":p?this.scrollListToBottom():a?this.scrollListToBottom():this.restoreScrollAnchor(n,i);break;case"pin-bottom":this.scrollListToBottom();break;case"restore":{let u=g.scrollTop,f=this.listEl,B=()=>{this.suppressScrollSave=!0;let Q=Math.max(0,f.scrollHeight-f.clientHeight);f.scrollTop=Math.min(u,Q),Promise.resolve().then(()=>{this.suppressScrollSave=!1})};B(),requestAnimationFrame(B),setTimeout(B,60),setTimeout(B,200),setTimeout(B,600);break}case"follow-cursor":i>0&&(this.listEl.scrollTop=i),this.revealCursorRow();break;case"scroll-to-id":{let u=g.id,f=g.align,B=this.listEl,Q=()=>{this.suppressScrollSave=!0;let E=B.querySelector(`[data-id="${u}"]`);E&&E.scrollIntoView({block:f,behavior:"auto"}),Promise.resolve().then(()=>{this.suppressScrollSave=!1})};Q(),requestAnimationFrame(Q),setTimeout(Q,60),setTimeout(Q,200),setTimeout(Q,600),setTimeout(()=>{this.suppressScrollSave=!1},700);break}}}else this.scrollToBottomOnNextRender?(this.scrollToBottomOnNextRender=!1,this.scrollListToBottom()):this.listEl&&a?this.scrollListToBottom():this.listEl&&i>0&&(this.listEl.scrollTop=i);if(this.stampSelectedCursor(),this.listEl){this.listResizeObserver?.disconnect();let p=this.listEl,u=p.scrollTop,f=new ResizeObserver(()=>{if(Date.now()<this.keyboardTransitionUntil)return;if(this.stickToListBottom){p.scrollTop=p.scrollHeight,u=p.scrollTop;return}let Q=Math.max(0,p.scrollHeight-p.clientHeight);p.scrollTop<u&&u<=Q?p.scrollTop=u:u=p.scrollTop});f.observe(p),this.listResizeObserver=f,p.addEventListener("wheel",Q=>{Q.deltaY<0&&(this.stickToListBottom=!1)},{passive:!0});let B=0;p.addEventListener("touchstart",Q=>{B=Q.touches[0]?.clientY??0},{passive:!0}),p.addEventListener("touchmove",Q=>{let E=Q.touches[0]?.clientY??B;E>B&&(this.stickToListBottom=!1),B=E},{passive:!0}),p.addEventListener("mousedown",()=>{this.stickToListBottom=!1}),p.addEventListener("keydown",()=>{this.stickToListBottom=!1})}}renderTimeFilterBar(t){let e=t.createDiv({cls:"stashpad-time-filter-bar"}),i=e.createEl("button",{cls:"stashpad-folder-btn"}),s=!!this.folderOverride,n=this.noteFolder.split("/").pop()||this.noteFolder||"Stashpad";(0,L.setIcon)(i.createSpan({cls:"stashpad-btn-icon"}),"folder"),i.createSpan({text:n,cls:"stashpad-btn-text"}),i.title=s?`Folder (override): ${this.noteFolder} +Inspect with the buttons below \u2014 rename to .zip to crack it open in an archive tool.`,kind:"error",category:"import",affectedPaths:[A.path],actions:d.actionsForFile(A.path)}),console.error(t)}}function ma(d){let A=new Set,t=e=>{if(A.add(e),!!d.tree.get(e))for(let s of d.tree.getChildren(e))t(s.id)};return t(G),A}var Ea=new Set(["png","jpg","jpeg","gif","webp","svg","bmp","avif"]),Oi={nested:"Nested",flat:"Flat",everything:"Everything"},Ki=[{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"}],Yi=class extends q.ItemView{constructor(t,e){super(t);this.focusId=G;this.timeFilter="all";this.timeFilterCalendar=!1;this.tagFilter=null;this.colorFilter=null;this.importedOnly=!1;this.authorFilter=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.pickerEscapeAt=0;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.lastSelectionByFocus=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.stampSelectionTimer=null;this._renderT0=null;this.tinyOpacityPopover=null;this.lastListWidth=0;this.onDocKeyDown=t=>{if(!this.viewRoot.isConnected||this.app.workspace.activeLeaf!==this.leaf||wn(t.target))return;let e=ft().bindings;if(rt(t,e.toggleSplit)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.toggleSplit();return}if(rt(t,e.pickDestination)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.openDestinationPicker();return}if(rt(t,e.search)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.openSearchModal();return}if(rt(t,e.commandPalette)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.openStashpadCommandPalette();return}if(rt(t,e.searchInParent)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.openSearchInParentModal();return}if(rt(t,e.exportStash)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdExportStash();return}if(rt(t,e.importStash)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdImportStash();return}if(rt(t,e.pickFolder)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdOpenFolderPicker();return}if(rt(t,e.cloneStashpadTab)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdCloneStashpadTab();return}let i=t.target,s=!!i&&(i.tagName==="INPUT"||i.tagName==="TEXTAREA");if(t.key===" "&&!t.metaKey&&!t.ctrlKey&&!t.altKey&&!t.shiftKey&&!s){let a=this.composerInputEl;if(a){t.preventDefault(),t.stopPropagation(),a.focus();let c=a.value.length;a.setSelectionRange(c,c);return}}let n=!!i&&(i.tagName==="INPUT"||i.tagName==="TEXTAREA"||i.tagName==="BUTTON"||i.tagName==="SELECT");if(t.key==="Escape"&&i instanceof HTMLElement&&(i.tagName==="BUTTON"||i.tagName==="SELECT")&&this.viewRoot.contains(i)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.viewRoot.focus();return}if(this.inListPicker&&t.key==="Escape"){t.preventDefault(),t.stopPropagation(),this.inListPicker=null,this.pickerEscapeAt=Date.now();let a=this.listEl,c=!!a&&a.scrollTop+a.clientHeight>=a.scrollHeight-2,l=a?.scrollTop??0;if(this.render(),a){let p=c?a.scrollHeight:l;a.scrollTop=p,requestAnimationFrame(()=>{a.scrollTop=c?a.scrollHeight:l}),setTimeout(()=>{a.scrollTop=c?a.scrollHeight:l},60),this.revealCursorRow()}return}if(this.inListPicker&&!n){if(t.key==="ArrowDown"){t.preventDefault(),this.inListPicker.activeIdx=this.nextPickableIdx(this.inListPicker.activeIdx,1),this.repaintSelectionClasses(),this.revealRowAt(this.inListPicker.activeIdx);return}if(t.key==="ArrowUp"){t.preventDefault(),this.inListPicker.activeIdx=this.nextPickableIdx(this.inListPicker.activeIdx,-1),this.repaintSelectionClasses(),this.revealRowAt(this.inListPicker.activeIdx);return}if(t.key==="Enter"){t.preventDefault(),this.commitInListPicker();return}if(rt(t,ft().bindings.move)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.inListPicker=null,this.repaintSelectionClasses(),this.cmdMovePicker();return}return}if(n)return;if(rt(t,e.delete)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdDelete();return}if(rt(t,e.toggleComplete)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdToggleComplete();return}if(rt(t,e.moveToTop)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdMoveToTop();return}if(rt(t,e.moveToBottom)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdMoveToBottom();return}if(rt(t,e.moveUp)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdMoveUp();return}if(rt(t,e.moveDown)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdMoveDown();return}if(rt(t,e.outdent)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdOutdent();return}if(rt(t,e.setColor)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdSetColor();return}if(rt(t,e.selectAll)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdSelectAll();return}if(rt(t,e.swapWithParent)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdSwapWithParent();return}if(rt(t,e.undo)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdUndo();return}if(rt(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 c=a.value.length;a.setSelectionRange(c,c)}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"){if(t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),Date.now()-this.pickerEscapeAt<350)return;let a=this.firstSelectedId??(this.selection.size>0?this.selection.values().next().value:null);if(this.selection.clear(),this.firstSelectedId=null,a){let c=this.currentChildren.findIndex(l=>l.id===a);this.selection.add(a),this.lastSelected=a,c>=0&&(this.cursorIdx=c)}this.repaintSelectionClasses(),this.revealCursorRow();return}let o=ft().bindings;if(this.selection.size>0||this.cursorIdx>=0&&this.currentChildren[this.cursorIdx]){if(rt(t,o.move)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdMovePicker();return}if(rt(t,o.pickMove)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdInListPicker();return}if(rt(t,o.merge)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdMerge();return}if(rt(t,o.copy)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdCopy();return}if(rt(t,o.copyTree)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdCopyTree();return}if(rt(t,o.copyOutline)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdCopyOutline();return}if(rt(t,o.copyCodeBlock)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdCopyCodeBlock();return}if(rt(t,o.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(rt(t,o.openTab)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdOpenInNewStashpadTab();return}if(rt(t,o.split)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdSplit();return}if(rt(t,o.clone)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdClone();return}if(rt(t,o.insertTemplate)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdInsertTemplate();return}if(rt(t,o.toggleExpand)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdToggleExpand();return}if(rt(t,o.togglePin)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdTogglePin();return}if(rt(t,o.toggleTask)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdToggleTask();return}if(rt(t,o.setDue)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdSetDue();return}}if(this.currentChildren.length>0){if(rt(t,o.jumpToTop)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.jumpToTop();return}if(rt(t,o.jumpToBottom)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.jumpToBottom();return}}let r=this.tree.get(this.focusId);if(r?.file){if(rt(t,o.openEditor)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdOpenInEditor(r);return}if(rt(t,o.openTab)){t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.cmdOpenInNewStashpadTab(r);return}}};this.openSearchInstance=null;this.fmSyncUnsubscribe=null;this.completedState=new Map;this.taskTaggedState=new Map;this.pendingFocusIds=null;this.onFileModify=t=>{!(t instanceof q.TFile)||t.extension!=="md"||t.path.startsWith(this.noteFolder+"/")&&(this.scheduleSlugRename(t),this.scheduleAttachmentSync(t),this.authorship.noteModify(t),this.debouncedRender())};this.onFileCreate=t=>{!(t instanceof q.TFile)||t.extension!=="md"||t.path.startsWith(this.noteFolder+"/")&&this.debouncedRender()};this.plugin=e,this.tree=new bi(this.app),this.log=e.newLog(),this.integrity=new Ui(this.tree,this.log),this.order=new Ni(this.app),this.sortStore=new xi(this.app),this.fmSync=new Hi(this.app,()=>this.tree),this.tree.setOrderProvider(i=>{let s=this.noteFolder,n=this.sortStore.getMode(s,i);return n==="manual"?this.order.getOrder(s,i):En(this,i,n)}),this.debouncedRender=(0,q.debounce)(()=>this.render(),80),this.authorship=new Ri(this),this.dnd=new Pi(this),this.bodyRenderer=new Li(this,this,this.plugin.renderCacheStore)}getViewType(){return gt}getDisplayText(){let t=(this.noteFolder||"").trim(),e=t.split("/").pop()||t||"Stashpad";if(this.focusId&&this.focusId!==G){let i=this.tree.get(this.focusId);if(i){let s=this.titleForNode(i).trim(),n=s.length>40?s.slice(0,40)+"\u2026":s;if(n)return`${e} \u2014 ${n}`}}return e}refreshHeaderTitle(){let t=this.getDisplayText();try{this.leaf.updateHeader?.()}catch{}let i=(this.headerEl??this.containerEl?.querySelector?.(".view-header"))?.querySelector?.(".view-header-title")??this.titleEl;i&&i.textContent!==t&&i.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",()=>wi(this)),this.viewRoot.addEventListener("click",()=>wi(this)),this.viewRoot.addEventListener("mouseup",a=>{a.button===3?(a.preventDefault(),this.navigateBack()):a.button===4&&(a.preventDefault(),this.navigateForward())}),this.viewRoot.addEventListener("auxclick",a=>{a.button===3?(a.preventDefault(),this.navigateBack()):a.button===4&&(a.preventDefault(),this.navigateForward())}),wi(this),this.registerInterval(window.setInterval(()=>this.authorship.pruneContribMaps(),6e4));let e=null,i=()=>{e||(e=new q.Scope(this.app.scope),e.register([],"Escape",()=>{if(this.inListPicker)return this.inListPicker=null,this.pickerEscapeAt=Date.now(),this.repaintSelectionClasses(),!1;if(Date.now()-this.pickerEscapeAt<350)return!1;if(this.selection.size>1){let a=this.firstSelectedId??this.selection.values().next().value??null;if(this.selection.clear(),this.firstSelectedId=null,a){let c=this.currentChildren.findIndex(l=>l.id===a);this.selection.add(a),this.lastSelected=a,c>=0&&(this.cursorIdx=c)}this.render(),this.revealCursorRow()}return!1}),this.app.keymap?.pushScope(e))},s=()=>{if(e){try{this.app.keymap?.popScope(e)}catch{}e=null}};this.viewRoot.addEventListener("focusin",i),this.viewRoot.addEventListener("focusout",a=>{let c=a.relatedTarget;c&&this.viewRoot&&this.viewRoot.contains(c)||s()}),this.register(()=>s()),this.detachTreeHook=this.tree.hookMetadataCache(()=>this.debouncedRender()),this.registerEvent(this.app.metadataCache.on("resolved",()=>this.scheduleTreeReconcile())),this.registerEvent(this.app.metadataCache.on("changed",a=>{if(a.extension!=="md")return;let c=this.app.metadataCache.getFileCache(a)?.frontmatter;this.completedState.set(a.path,!!c?.completed),this.taskTaggedState.set(a.path,this.taggedFromFm(c))})),this.registerEvent(this.app.vault.on("rename",(a,c)=>{for(let l of[this.completedState,this.taskTaggedState])l.has(c)&&(l.set(a.path,l.get(c)),l.delete(c))})),this.registerEvent(this.app.vault.on("delete",a=>{this.completedState.delete(a.path),this.taskTaggedState.delete(a.path)})),this.detachSettings=pn(()=>{this.loadConfig();let a=this.plugin.settings.drafts?.[this.noteFolder]??"",c=this.composerInputEl?.value??"";a===""&&this.composerDraft!==""&&c===""?(this.composerDraft="",this.composerInputEl&&(this.composerInputEl.value="")):a===""&&c!==""&&(this.composerDraft=c),!!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(a){let c=a?.message??"";/already exists/i.test(c)||console.warn("[Stashpad] bootstrapFolder failed:",a)}this.tree.rebuild(this.noteFolder),this.installFmSyncActivityNotice(),this.backfillFrontmatterSync(),this.plugin.maybeSweepFolder(this.noteFolder),this.defaultCursorToLast(),this.refreshHeaderTitle(),await this.loadDraftsForFolder();try{let a=this.plugin.loadLastCursor(this.noteFolder);for(let[c,l]of a)this.lastCursorByFocus.set(c,l);this.lastSelectionByFocus=this.plugin.loadLastSelection(this.noteFolder)}catch{}let n=this.lastCursorByFocus.get(this.focusId),o;n&&this.tree.get(n)?(o={kind:"scroll-to-id",id:n,align:"start"},this.pendingFocusIds=[n]):(this.scrollToBottomOnNextRender=!0,o={kind:"pin-bottom",until:"next-user-input"});let r=this.foldRestoredSelection(n);r&&(this.pendingFocusIds=r),this.render(o),this.scheduleSelectionRestore(),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",a=>{a===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+"/",i=0;for(let s of this.app.vault.getMarkdownFiles()){let n=s.parent?.path?.replace(/\/+$/,"")??"";if(!(n===t||t!==""&&n.startsWith(e)))continue;let o=this.app.metadataCache.getFileCache(s)?.frontmatter?.id;typeof o=="string"&&o&&i++}i!==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(!ft().autofocusComposerAfterSend)return;let t=()=>{if(!this.viewRoot?.isConnected||Date.now()<this.suppressComposerFocusUntil||Date.now()<this.plugin.suppressComposerAutofocusUntil)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(){dn(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.bodyRenderer.dispose(),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();this.authorship.dispose();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 i=t??null;if(i){"folderOverride"in i&&(this.folderOverride=i.folderOverride??null),i.timeFilter&&(this.timeFilter=i.timeFilter),i.focusId&&(this.focusId=i.focusId),"tagFilter"in i&&(this.tagFilter=i.tagFilter??null),"colorFilter"in i&&(this.colorFilter=i.colorFilter??null),"timeFilterCalendar"in i&&(this.timeFilterCalendar=!!i.timeFilterCalendar),"tinyMode"in i&&(this.tinyMode=!!i.tinyMode),"tinyAlwaysOnTop"in i&&(this.tinyAlwaysOnTop=!!i.tinyAlwaysOnTop),typeof i.tinyOpacity=="number"&&Number.isFinite(i.tinyOpacity)&&(this.tinyOpacity=Math.min(1,Math.max(.3,i.tinyOpacity))),"compactMode"in i&&(this.compactMode=!!i.compactMode);let o=r=>r&&typeof r.folder=="string"&&typeof r.focusId=="string";Array.isArray(i.navBackStack)&&(this.navBackStack=i.navBackStack.filter(o)),Array.isArray(i.navForwardSnapshots)&&(this.navForwardSnapshots=i.navForwardSnapshots.filter(o))}let s=(this.plugin?.settings?.folder??"Stashpad").trim().replace(/^\/+|\/+$/g,""),n=this.folderOverride?.trim().replace(/^\/+|\/+$/g,"")||null;if(this.noteFolder=n||s||"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(),this.lastSelectionByFocus.clear();try{let c=this.plugin.loadLastCursor(this.noteFolder);for(let[l,p]of c)this.lastCursorByFocus.set(l,p);this.lastSelectionByFocus=this.plugin.loadLastSelection(this.noteFolder)}catch{}let o=this.lastCursorByFocus.get(this.focusId),r;o&&this.tree.get(o)?(this.pendingFocusIds=[o],r={kind:"scroll-to-id",id:o,align:"start"}):r={kind:"pin-bottom",until:"next-user-input"};let a=this.foldRestoredSelection(o);a&&(this.pendingFocusIds=a),this.render(r),this.scheduleSelectionRestore()}}focus(){this.viewRoot?.focus({preventScroll:!0})}foldRestoredSelection(t){let e=this.lastSelectionByFocus.get(this.focusId)??null;if(!e||!e.length)return null;let i=e.filter(s=>!!this.tree.get(s));return i.length?t&&i.includes(t)?[t,...i.filter(s=>s!==t)]:i:null}stampSelection(t=!1){let e=[...this.selection],i=()=>{try{this.plugin.saveLastSelection(this.noteFolder,this.focusId,e)}catch{}};if(this.stampSelectionTimer!=null&&(window.clearTimeout(this.stampSelectionTimer),this.stampSelectionTimer=null),t){i();return}this.stampSelectionTimer=window.setTimeout(()=>{this.stampSelectionTimer=null,i()},400)}scheduleSelectionRestore(){let t=this.lastSelectionByFocus.get(this.focusId);if(!t||!t.length)return;let e=()=>{let i=t.filter(r=>this.currentChildren.some(a=>a.id===r));if(!i.length)return;let s=[...this.selection],n=new Set(i);if(s.length<i.length&&s.every(r=>n.has(r))){this.selection.clear();for(let r of i)this.selection.add(r);this.firstSelectedId=i[0],this.lastSelected=i[i.length-1],this.repaintSelectionClasses()}};for(let i of[120,400,900,1600])window.setTimeout(e,i)}loadConfig(){let t=(this.plugin?.settings?.folder??"Stashpad").trim().replace(/^\/+|\/+$/g,""),i=this.folderOverride?.trim().replace(/^\/+|\/+$/g,"")||null||t||"Stashpad";i!==this.noteFolder?(this.noteFolder=i,this.tree.rebuild(this.noteFolder)):this.noteFolder=i}captureNavSnapshot(){return{folder:this.noteFolder,focusId:this.focusId}}recordNavState(t={}){let e=this.captureNavSnapshot(),i=this.navBackStack[this.navBackStack.length-1];i&&i.folder===e.folder&&i.focusId===e.focusId||(this.navBackStack.push(e),t.keepForward||(this.navForwardSnapshots=[]))}async setFolderOverride(t,e={}){let i=t?.trim().replace(/^\/+|\/+$/g,"")||null;if(i&&this.isReservedFolder(i)){new q.Notice(`"${i}" is a reserved Stashpad subfolder (imports/exports/attachments). Pick a different folder.`);return}if((i||null)!==(this.folderOverride||null)){e.skipHistory||this.recordNavState(),this.folderOverride=i,this.focusId=G,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(s){let n=s?.message??"";/already exists/i.test(n)||console.warn("[Stashpad] bootstrapFolder failed:",s)}this.tree.rebuild(this.noteFolder),this.backfillFrontmatterSync(),this.plugin.maybeSweepFolder(this.noteFolder),this.defaultCursorToLast(),await this.loadDraftsForFolder();try{let s=this.app.workspace;typeof s.saveLayout=="function"?await s.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 q.TFolder){if(e.path==="/"||e.path===""||e.path.startsWith(".")||this.isReservedFolder(e.path))continue;t.push(e.path)}return t.sort((e,i)=>e.localeCompare(i))}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(s=>(s??"").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 q.Notice("Nothing to undo.");return}let e=t.peekUndoLabel(),i=this.plugin.notifications.recent()[0]?.category??"system";t.undo().then(()=>this.plugin.notifications.show({message:`Undid: ${e}`,kind:"info",category:i,folder:this.noteFolder})).catch(s=>this.plugin.notifications.show({message:`Undo failed: ${s.message}`,kind:"error",category:"system",folder:this.noteFolder}))}cmdRedo(){let t=this.plugin.getUndoStack(this.noteFolder);if(!t.canRedo()){new q.Notice("Nothing to redo.");return}let e=t.peekRedoLabel(),i=this.plugin.notifications.recent()[0]?.category??"system";t.redo().then(()=>this.plugin.notifications.show({message:`Redid: ${e}`,kind:"info",category:i,folder:this.noteFolder})).catch(s=>this.plugin.notifications.show({message:`Redo failed: ${s.message}`,kind:"error",category:"system",folder:this.noteFolder}))}async snapshotNotes(t,e){let i=[],s=new Set;for(let a of t)!a.file||s.has(a.file.path)||(s.add(a.file.path),i.push(a.file));let n=await Promise.all(i.map(a=>this.app.vault.read(a))),o=i.map((a,c)=>({path:a.path,content:n[c]})),r=[];if(e){let a=new Set,c=[];for(let p of n)for(let g of this.extractAttachments(this.stripFrontmatter(p))){let h=this.app.metadataCache.getFirstLinkpathDest(g,"");h&&!a.has(h.path)&&(a.add(h.path),c.push(h))}let l=await Promise.all(c.map(p=>this.app.vault.readBinary(p)));for(let p=0;p<c.length;p++)r.push({path:c[p].path,data:l[p]})}return{notes:o,attachments:r}}async restoreSnapshots(t,e){for(let s of t.attachments)try{await this.app.vault.adapter.exists(s.path)||await this.app.vault.createBinary(s.path,s.data)}catch{}for(let s of t.notes)try{await this.app.vault.adapter.exists(s.path)||await this.app.vault.create(s.path,s.content)}catch{}let i=()=>{e&&e.some(n=>this.tree.get(n))&&(this.pendingFocusIds=e.slice())};i(),this.tree.rebuild(this.noteFolder),this.render({kind:"follow-cursor"}),setTimeout(()=>{i(),this.tree.rebuild(this.noteFolder),this.render({kind:"follow-cursor"})},100),setTimeout(()=>{i(),this.tree.rebuild(this.noteFolder),this.render({kind:"follow-cursor"})},400),setTimeout(()=>{for(let s of t.notes){let n=this.tree.idForPath(s.path);n&&this.fmSync.schedule(n)}},500)}async trashNotesAndAttachments(t){let e=new Set;for(let i of t.notes){let s=this.tree.idForPath(i.path);if(!s)continue;let n=this.tree.get(s);n?.parent&&e.add(n.parent)}for(let i of t.notes){let s=this.app.vault.getAbstractFileByPath(i.path);if(s)try{await this.app.fileManager.trashFile(s)}catch{}}for(let i of t.attachments){let s=this.app.vault.getAbstractFileByPath(i.path);if(s)try{await this.app.fileManager.trashFile(s)}catch{}}this.tree.rebuild(this.noteFolder),this.render();for(let i of e)this.fmSync.scheduleParentOfDeleted(i)}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 s={...this.plugin.settings.drafts??{}};t.length===0?delete s[e]:s[e]=t,this.plugin.settings.drafts=s,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,q.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()}currentAttachmentsOnly(){return!!this.plugin.settings.attachmentsOnlyNotes?.[this.noteFolder]}async setAttachmentsOnly(t){let e={...this.plugin.settings.attachmentsOnlyNotes??{}};t?e[this.noteFolder]=!0:delete e[this.noteFolder],this.plugin.settings.attachmentsOnlyNotes=e,await this.plugin.saveSettings()}nodeHasAttachment(t){if(!t.file)return!1;let e=this.app.metadataCache.getFileCache(t.file)?.frontmatter?.attachments;return Array.isArray(e)&&e.length>0}hasAttachmentInSubtree(t){if(this.nodeHasAttachment(t))return!0;for(let e of this.tree.getChildren(t.id))if(this.hasAttachmentInSubtree(e))return!0;return!1}hasIncompleteDescendant(t){for(let e of t.children){let i=this.tree.get(e);if(i&&(!this.isCompleted(i)||this.hasIncompleteDescendant(i)))return!0}return!1}collectEmbeddedAttachmentPaths(){let t=new Set,e=this.noteFolder,i=this.app.vault.getAbstractFileByPath(e);if(!(i instanceof q.TFolder))return t;let s=[i];for(;s.length;){let n=s.pop();for(let o of n.children){if(o instanceof q.TFolder){s.push(o);continue}if(!(o instanceof q.TFile)||o.extension!=="md")continue;let r=this.app.metadataCache.getFileCache(o)?.frontmatter;if(!(!r||!Array.isArray(r.attachments)))for(let a of r.attachments){if(typeof a!="string")continue;let c=oe(a),l=this.app.metadataCache.getFirstLinkpathDest(c,o.path);l?t.add(l.path):t.add(c)}}}return t}collectFileItems(t){let e=this.noteFolder,i=this.app.vault.getAbstractFileByPath(e);if(!(i instanceof q.TFolder))return[];let s=this.currentIncludeAttachments(),n=s?new Set:this.collectEmbeddedAttachmentPaths(),o=new Set(["_authors","_imports","_exports","_processed","_attachments","_archive",".archive"]),r=[],a=[i];for(;a.length;){let c=a.pop();for(let l of c.children){if(l instanceof q.TFolder){let p=l.name;if(c===i&&o.has(p)||c===i&&p==="_attachments"&&!s)continue;a.push(l);continue}l instanceof q.TFile&&l.extension!=="md"&&(l.name===".stashpad-order.json"||l.name===".stashpad-sort.json"||!s&&n.has(l.path)||r.push(l))}}return r}populateListBody(t,e){this.lastListWidth=t.clientWidth||this.lastListWidth,this.bodyRenderer.arm(),e.file&&q.Platform.isMobile&&(this.renderFocusedHeaderMini(t,e),this.renderFocusedHeader(t,e));let s=this.currentViewMode()==="everything"?this.collectFileItems(e.id):[];if(this.currentChildren.length===0&&s.length===0)t.createDiv({cls:"stashpad-empty",text:"No notes here yet. Type below to add one."});else if(s.length===0)for(let n=0;n<this.currentChildren.length;n++)this.renderNote(t,this.currentChildren[n],n);else{let o=[...this.currentChildren.map((r,a)=>({kind:"note",ts:Number.isFinite(Date.parse(r.created))?Date.parse(r.created):0,idx:a})),...s.map(r=>({kind:"file",ts:r.stat.ctime,file:r}))];o.sort((r,a)=>r.ts-a.ts);for(let r of o)r.kind==="note"?this.renderNote(t,this.currentChildren[r.idx],r.idx):this.renderFileRow(t,r.file)}e.file&&q.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,i=this.listEl.scrollTop;this.listEl.empty(),this.populateListBody(this.listEl,t),e?this.listEl.scrollTop=this.listEl.scrollHeight:this.listEl.scrollTop=i}renderFileRow(t,e){let i=t.createDiv({cls:"stashpad-file-row"});i.dataset.path=e.path,i.createDiv({cls:"stashpad-file-meta"}).createSpan({cls:"stashpad-file-time",text:this.formatTime(new Date(e.stat.ctime).toISOString())});let n=i.createDiv({cls:"stashpad-file-body"});n.createSpan({cls:"stashpad-file-name",text:e.name}),n.createSpan({cls:"stashpad-file-ext",text:e.extension.toUpperCase()}),i.title=`${e.path} \u2014 click to open`,i.onclick=o=>{o.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(),i=this.currentHideChildless(),s=this.tree.getChildren(t),n=i?s.filter(a=>a.children.length>0):s;if(e==="nested")return n;let o=[],r=a=>{o.push(a);for(let c of this.tree.getChildren(a.id))r(c)};for(let a of n)r(a);return o}filterChildren(t){let e=this.timeFilterCutoff(),i=this.tagFilter?.toLowerCase(),s=this.colorFilter?.toLowerCase()??null,n=this.currentHideCompleted(),o=this.currentAttachmentsOnly(),r=this.importedOnly,a=this.authorFilter;return!e&&!i&&!s&&!n&&!o&&!r&&!a?t:t.filter(c=>{if(r&&(!c.file||this.app.metadataCache.getFileCache(c.file)?.frontmatter?.imported!==!0))return!1;if(a){if(!c.file)return!1;let l=Xt(this.app.metadataCache.getFileCache(c.file)?.frontmatter?.author);if(!l||l.id!==a)return!1}if(e&&c.created){let l=Date.parse(c.created);if(!Number.isNaN(l)&&l<e)return!1}return!(i&&(!c.file||!this.nodeHasTag(c,i))||s&&(this.colorForNode(c)?.toLowerCase()??null)!==s||n&&this.isCompleted(c)&&!this.hasIncompleteDescendant(c)||o&&!this.hasAttachmentInSubtree(c))})}nodeHasTag(t,e){if(!t.file)return!1;let i=this.app.metadataCache.getFileCache(t.file);if(!i)return!1;if(i.tags){for(let n of i.tags)if((n.tag||"").replace(/^#/,"").toLowerCase()===e)return!0}let s=i.frontmatter?.tags;if(s){let n=Array.isArray(s)?s:[s];for(let o of n)if(typeof o=="string"&&o.replace(/^#/,"").toLowerCase()===e)return!0}return!1}collectFolderTags(){let t=new Map,e=this.tree.getChildren(this.focusId);for(let s of e){if(!s.file)continue;let n=this.app.metadataCache.getFileCache(s.file);if(n?.tags)for(let r of n.tags){let a=(r.tag||"").replace(/^#/,"");a&&t.set(a,(t.get(a)??0)+1)}let o=n?.frontmatter?.tags;if(o){let r=Array.isArray(o)?o:[o];for(let a of r){if(typeof a!="string")continue;let c=a.replace(/^#/,"");c&&t.set(c,(t.get(c)??0)+1)}}}let i=[...t.entries()].map(([s,n])=>({raw:s,count:n,label:this.formatTagLabel(s)}));return i.sort((s,n)=>n.count-s.count||s.label.localeCompare(n.label)),i}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 s of e){let n=this.colorForNode(s);if(!n)continue;let o=n.toLowerCase();t.set(o,(t.get(o)??0)+1)}let i=[...t.entries()].map(([s,n])=>({hex:s,count:n}));return i.sort((s,n)=>n.count-s.count||s.hex.localeCompare(n.hex)),i}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){this.stampSelection(t);let i=this.currentChildren[this.cursorIdx]?.id??this.lastSelected;if(!i)return;this.lastCursorByFocus.set(this.focusId,i);let s=()=>{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,s();return}this.stampLastCursorTimer!=null&&window.clearTimeout(this.stampLastCursorTimer),this.stampLastCursorTimer=window.setTimeout(()=>{this.stampLastCursorTimer=null,s()},400)}captureScrollAnchor(){let t=this.listEl;if(!t)return null;let e=t.getBoundingClientRect().top,i=Array.from(t.querySelectorAll(".stashpad-note"));if(i.length===0)return null;let s=null;for(let n of i){let o=n.dataset.id;if(!o)continue;let r=n.getBoundingClientRect().top-e;if(r>=0){s={id:o,offsetFromListTop:r};break}s={id:o,offsetFromListTop:r}}return s}restoreScrollAnchor(t,e){let i=this.listEl;if(i){if(t){let s=i.querySelector(`[data-id="${t.id}"]`);if(s){let n=i.getBoundingClientRect().top,o=s.getBoundingClientRect().top-n;i.scrollTop+=o-t.offsetFromListTop;return}}e>0&&(i.scrollTop=e)}}render(t){St.enabled&&(this._renderT0=performance.now()),this.pendingRenderPolicy=t??{kind:"preserve"},this.loadConfig();let e=this.viewRoot,i=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 r=!!this.listEl&&(this.stickToListBottom||this.listEl.scrollTop+this.listEl.clientHeight>=this.listEl.scrollHeight-2);e.empty(),e.toggleClass("is-mobile",q.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 c=this.containerEl.closest(".workspace-tabs");c&&c.classList.toggle("stashpad-has-tiny",this.tinyMode),this.tinyMode?this.renderTinyHeader(e):(this.compactMode||this.renderTimeFilterBar(e),this.renderBreadcrumb(e));let l=this.tree.get(this.focusId)??this.tree.getRoot();l.file&&!q.Platform.isMobile&&!this.tinyMode&&!this.compactMode&&this.renderFocusedHeader(e,l),this.currentChildren=this.filterChildren(this.collectViewItems(l.id));let p=!1;if(this.autoSelectNewest&&this.currentChildren.length>0){let I=this.currentChildren[this.currentChildren.length-1];this.cursorIdx=this.currentChildren.length-1,this.selection.clear(),this.selection.add(I.id),this.lastSelected=I.id,this.autoSelectNewest=!1,p=!0}else if(this.pendingFocusIds){let I=this.pendingFocusIds;this.pendingFocusIds=null,this.selection.clear();let u=-1;for(let f of I){let C=this.currentChildren.findIndex(m=>m.id===f);C>=0&&(this.selection.add(f),u<0&&(u=C))}this.cursorIdx=u,u>=0&&(this.lastSelected=I.find(f=>this.currentChildren.some(C=>C.id===f))??null)}else this.cursorIdx>=this.currentChildren.length&&(this.cursorIdx=this.currentChildren.length-1);let g=e.createDiv({cls:"stashpad-list"});if(this.listEl=g,this.dnd.attachListDnD(g),this.populateListBody(g,l),this.renderComposer(e),q.Platform.isMobile&&this.renderMobileNav(e),this._renderT0!=null&&(St.record("render.total",performance.now()-this._renderT0),this._renderT0=null),this.plugin.notifyStashpadContentChanged(),p&&this.plugin.notifyStashpadSelectionChanged(),this.focusComposerOnNextRender){this.focusComposerOnNextRender=!1;let I=this.pendingComposerCaret;this.pendingComposerCaret=null;let u=this.composerInputEl;if(u&&u.isConnected){if(u.focus({preventScroll:!0}),I!=null){let f=Math.min(I,u.value.length);try{u.setSelectionRange(f,f)}catch{}}}else requestAnimationFrame(()=>{let f=this.composerInputEl;if(f&&(f.focus({preventScroll:!0}),I!=null)){let C=Math.min(I,f.value.length);try{f.setSelectionRange(C,C)}catch{}}})}let h=this.pendingRenderPolicy;if(this.pendingRenderPolicy=null,h&&this.listEl){let I=this.scrollToBottomOnNextRender;switch(this.scrollToBottomOnNextRender=!1,h.kind){case"preserve":I?this.scrollListToBottom():r?this.scrollListToBottom():this.restoreScrollAnchor(n,i);break;case"pin-bottom":this.scrollListToBottom();break;case"restore":{let u=h.scrollTop,f=this.listEl,C=()=>{this.suppressScrollSave=!0;let m=Math.max(0,f.scrollHeight-f.clientHeight);f.scrollTop=Math.min(u,m),Promise.resolve().then(()=>{this.suppressScrollSave=!1})};C(),requestAnimationFrame(C),setTimeout(C,60),setTimeout(C,200),setTimeout(C,600);break}case"follow-cursor":i>0&&(this.listEl.scrollTop=i),this.revealCursorRow();break;case"scroll-to-id":{let u=h.id,f=h.align,C=this.listEl,m=()=>{this.suppressScrollSave=!0;let E=C.querySelector(`[data-id="${u}"]`);E&&E.scrollIntoView({block:f,behavior:"auto"}),Promise.resolve().then(()=>{this.suppressScrollSave=!1})};m(),requestAnimationFrame(m),setTimeout(m,60),setTimeout(m,200),setTimeout(m,600),setTimeout(()=>{this.suppressScrollSave=!1},700);break}}}else this.scrollToBottomOnNextRender?(this.scrollToBottomOnNextRender=!1,this.scrollListToBottom()):this.listEl&&r?this.scrollListToBottom():this.listEl&&i>0&&(this.listEl.scrollTop=i);if(this.stampSelectedCursor(),this.listEl){this.listResizeObserver?.disconnect();let I=this.listEl,u=I.scrollTop,f=new ResizeObserver(()=>{if(Date.now()<this.keyboardTransitionUntil)return;if(this.stickToListBottom){I.scrollTop=I.scrollHeight,u=I.scrollTop;return}let m=Math.max(0,I.scrollHeight-I.clientHeight);I.scrollTop<u&&u<=m?I.scrollTop=u:u=I.scrollTop});f.observe(I),this.listResizeObserver=f,I.addEventListener("wheel",m=>{m.deltaY<0&&(this.stickToListBottom=!1)},{passive:!0});let C=0;I.addEventListener("touchstart",m=>{C=m.touches[0]?.clientY??0},{passive:!0}),I.addEventListener("touchmove",m=>{let E=m.touches[0]?.clientY??C;E>C&&(this.stickToListBottom=!1),C=E},{passive:!0}),I.addEventListener("mousedown",()=>{this.stickToListBottom=!1}),I.addEventListener("keydown",()=>{this.stickToListBottom=!1})}}renderTimeFilterBar(t){let e=t.createDiv({cls:"stashpad-time-filter-bar"}),i=e.createEl("button",{cls:"stashpad-folder-btn"}),s=!!this.folderOverride,n=this.noteFolder.split("/").pop()||this.noteFolder||"Stashpad";(0,q.setIcon)(i.createSpan({cls:"stashpad-btn-icon"}),"folder"),i.createSpan({text:n,cls:"stashpad-btn-text"}),i.title=s?`Folder (override): ${this.noteFolder} Click to change or revert to default.`:`Folder: ${this.noteFolder} -Click to override for this tab.`,s&&i.addClass("is-override"),i.onclick=g=>{g.preventDefault(),this.openFolderPicker()};let o=e.createEl("button",{cls:"stashpad-search-btn"});Zt(o,"search","\u{1F50D}"),o.title="Search notes (Mod+F)",o.onclick=g=>{g.preventDefault(),this.openSearchModal()},L.Platform.isMobile?this.renderMobileFiltersButton(e):(this.renderTagFilterDropdown(e),this.renderColorFilterDropdown(e),this.renderSortDropdown(e),this.renderViewDropdown(e));let a=e.createDiv({cls:"stashpad-time-filter-btns"}),r=a.createEl("button",{cls:"stashpad-time-filter-btn stashpad-time-filter-cal"});(0,L.setIcon)(r,this.timeFilterCalendar?"calendar":"history"),r.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&&r.addClass("is-active"),r.onclick=g=>{g.preventDefault(),this.timeFilterCalendar=!this.timeFilterCalendar,this.persistFocus(),this.render()};for(let g of Ti){let p=this.timeFilterCalendar?g.calShort:g.rollShort,u=this.timeFilterCalendar?g.calLong:g.rollLong,f=a.createEl("button",{cls:"stashpad-time-filter-btn",text:p});f.title=u,this.timeFilter===g.key&&f.addClass("is-active"),f.onclick=B=>{B.preventDefault(),this.setTimeFilter(g.key)}}let c=e.createEl("select",{cls:"stashpad-time-filter-select"});for(let g of Ti){let p=this.timeFilterCalendar?g.calLong:g.rollLong,u=c.createEl("option",{text:p});u.value=g.key,this.timeFilter===g.key&&(u.selected=!0)}c.onchange=()=>this.setTimeFilter(c.value);let l=e.createDiv({cls:"stashpad-view-mode-btns"});if(!L.Platform.isMobile){let g=l.createEl("button",{cls:"stashpad-view-mode-btn"});(0,L.setIcon)(g,"minimize-2"),g.title="Tiny mode \u2014 open this tab in a small always-on-top-capable popout window.",g.onclick=p=>{p.preventDefault(),this.plugin.openTinyWindow()}}let d=l.createEl("button",{cls:"stashpad-view-mode-btn"});if((0,L.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=g=>{g.preventDefault(),this.toggleCompactMode()},L.Platform.isMobile)return;let I=l.createEl("button",{cls:"stashpad-view-mode-btn"});(0,L.setIcon)(I,"external-link"),I.title=Bt().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.)",I.onclick=g=>{g.preventDefault();let p=Bt().popoutDuplicates;try{let u=this.app.workspace;if(p){let f=this.leaf.getViewState(),B=u.openPopoutLeaf?.();B?B.setViewState({...f,active:!0}):new L.Notice("Stashpad: this Obsidian build doesn't expose openPopoutLeaf.")}else u.moveLeafToPopout?.(this.leaf)}catch(u){new L.Notice(`Stashpad: open-in-new-window failed (${u.message})`)}}}toggleCompactMode(){this.compactMode=!this.compactMode,this.render();try{this.app.workspace.requestSaveLayout?.()}catch{}}renderActionsCluster(t){let e=t.createDiv({cls:"stashpad-mobile-actions"}),i=e.createEl("button",{cls:"stashpad-mobile-action-btn"});Zt(i,"arrow-left","\u2039");let s=this.navBackStack.length>0||this.focusId!==G;i.title=this.navBackStack.length>0?"Back":this.focusId!==G?"Back (up to parent)":"No back history",s||i.addClass("is-disabled"),i.onclick=l=>{l.preventDefault(),this.navigateBack()};let n=e.createEl("button",{cls:"stashpad-mobile-action-btn"});Zt(n,"arrow-right","\u203A");let o=this.navForwardSnapshots.length>0;n.title=o?"Forward":"No forward history",o||n.addClass("is-disabled"),n.onclick=l=>{l.preventDefault(),this.navigateForward()};let a=e.createEl("button",{cls:"stashpad-mobile-action-btn"}),r=this.mobileSelectMode;Zt(a,r?"check-square":"square",r?"\u2611":"\u2610"),a.title=r?`${this.selection.size} selected \u2014 tap to exit (keeps the first selection)`:"Enter select mode (tap notes to add)",r&&a.addClass("is-active"),a.onclick=l=>{if(l.preventDefault(),this.mobileSelectMode){let d=this.firstSelectedId??this.selection.values().next().value;if(this.selection.clear(),d){let I=this.currentChildren.findIndex(g=>g.id===d);this.selection.add(d),this.lastSelected=d,I>=0&&(this.cursorIdx=I)}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 L.Notice("Select mode: tap notes to add, press \u26A1 for actions")}};let c=e.createEl("button",{cls:"stashpad-mobile-action-btn"});Zt(c,"zap","\u26A1"),c.title="Actions (move, delete, undo, \u2026)",c.onclick=l=>{l.preventDefault(),this.openMobileActionsMenu(c)}}openMobileActionsMenu(t){let e=new L.Menu,i=this.selection.size>0||this.cursorIdx>=0&&!!this.currentChildren[this.cursorIdx],s=this.selection.size<=1;e.addItem(o=>o.setTitle("Undo").setIcon("undo").onClick(()=>this.cmdUndo())),e.addItem(o=>o.setTitle("Redo").setIcon("redo").onClick(()=>this.cmdRedo())),e.addSeparator(),e.addItem(o=>o.setTitle("Notification history\u2026").setIcon("bell").onClick(()=>{this.app.commands?.executeCommandById?.("stashpad:stashpad-open-notification-history")})),e.addSeparator(),e.addItem(o=>o.setTitle("Open in new Stashpad tab").setIcon("list-tree").setDisabled(!i).onClick(()=>this.cmdOpenInNewStashpadTab())),e.addItem(o=>o.setTitle("Open in editor").setIcon("pencil").setDisabled(!i).onClick(()=>this.cmdOpenInEditor())),e.addSeparator(),e.addItem(o=>o.setTitle("Move\u2026").setIcon("arrow-right-circle").setDisabled(!i).onClick(()=>this.cmdMovePicker())),e.addItem(o=>o.setTitle("Nest under\u2026 (in-list)").setIcon("indent").setDisabled(!i).onClick(()=>this.cmdInListPicker())),e.addItem(o=>o.setTitle("Outdent").setIcon("outdent").setDisabled(!i).onClick(()=>void this.cmdOutdent())),e.addItem(o=>o.setTitle("Set color\u2026").setIcon("palette").setDisabled(!i).onClick(()=>this.cmdSetColor())),e.addItem(o=>o.setTitle("Toggle complete").setIcon("check-circle").setDisabled(!i).onClick(()=>void this.cmdToggleComplete())),e.addItem(o=>o.setTitle("Toggle task (todo)").setIcon("check-square").setDisabled(!i).onClick(()=>void this.cmdToggleTask())),e.addItem(o=>o.setTitle("Set due date\u2026").setIcon("calendar-clock").setDisabled(!i).onClick(()=>this.cmdSetDue())),e.addItem(o=>o.setTitle("Assign to\u2026").setIcon("user-plus").setDisabled(!i).onClick(()=>this.cmdAssign())),e.addSeparator(),e.addItem(o=>o.setTitle("Copy").setIcon("copy").setDisabled(!i).onClick(()=>void this.cmdCopy())),e.addItem(o=>o.setTitle("Copy tree").setIcon("copy-plus").setDisabled(!i).onClick(()=>void this.cmdCopyTree())),e.addItem(o=>o.setTitle("Clone (duplicate / copy)").setIcon("files").setDisabled(!i).onClick(()=>void this.cmdClone())),e.addItem(o=>o.setTitle("Insert template\u2026").setIcon("file-plus-2").onClick(()=>this.cmdInsertTemplate())),e.addItem(o=>o.setTitle("Merge").setIcon("merge").setDisabled(this.selection.size<2).onClick(()=>void this.cmdMerge())),e.addItem(o=>o.setTitle("Split note\u2026").setIcon("scissors").setDisabled(!i||!s).onClick(()=>void this.cmdSplit())),e.addSeparator(),e.addItem(o=>o.setTitle("Delete").setIcon("trash-2").setDisabled(!i).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"}),i=e.createEl("option",{text:"All tags"});i.value="",this.tagFilter||(i.selected=!0);let s=this.collectFolderTags();if(s.length===0)e.disabled=!0,i.text="No tags";else for(let n of s){let o=e.createEl("option",{text:`${n.label} (${n.count})`});o.value=n.raw,this.tagFilter&&this.tagFilter.toLowerCase()===n.raw.toLowerCase()&&(o.selected=!0)}e.onchange=()=>this.setTagFilter(e.value||null)}renderColorFilterDropdown(t){let e=this.collectFolderColors(),i=t.createDiv({cls:"stashpad-color-filter-btn"});i.setAttribute("role","button"),i.setAttribute("tabindex","0"),(()=>{i.empty();let o=i.createSpan({cls:"stashpad-color-filter-swatch"}),a=i.createSpan({cls:"stashpad-color-filter-label"});if(this.colorFilter){let r=this.colorFilter.toLowerCase();o.style.background=r;let c=this.plugin.getColorAlias(this.noteFolder,r);a.setText(c??r)}else e.length===0?(o.addClass("is-empty"),a.setText("No colors"),i.addClass("is-disabled")):(o.addClass("is-empty"),a.setText("All colors"))})();let n=o=>{o.preventDefault(),!(e.length===0&&!this.colorFilter)&&this.openColorFilterMenu(i,e)};i.onclick=n,i.onkeydown=o=>{(o.key==="Enter"||o.key===" ")&&n(o)}}openColorFilterMenu(t,e){let i=t.ownerDocument??document;i.querySelectorAll(".stashpad-color-filter-popover").forEach(c=>c.remove());let s=i.body.createDiv({cls:"stashpad-color-filter-popover"}),n=t.getBoundingClientRect();s.style.left=`${Math.max(8,n.left)}px`,s.style.top=`${n.bottom+4}px`,s.style.minWidth=`${n.width}px`,s.style.maxWidth="min(280px, calc(100vw - 16px))",s.style.width="max-content";let o=new L.Scope(this.app.scope),a=()=>{s.remove(),i.removeEventListener("mousedown",r,!0);try{this.app.keymap?.popScope(o)}catch{}},r=c=>{!s.contains(c.target)&&c.target!==t&&!t.contains(c.target)&&a()};o.register([],"Escape",c=>(c.preventDefault(),a(),!1)),this.app.keymap?.pushScope(o),this.populateColorMenuBody(s,e,a),setTimeout(()=>{i.addEventListener("mousedown",r,!0)},0)}renderSortDropdown(t){let e=this.noteFolder,i=this.focusId,s=this.sortStore.getMode(e,i),n=this.currentViewMode(),o=n!=="nested",a=t.createDiv({cls:"stashpad-sort-btn"});a.setAttribute("role","button"),a.setAttribute("tabindex",o?"-1":"0"),o&&a.addClass("is-disabled");let r=a.createSpan({cls:"stashpad-sort-icon"});(0,L.setIcon)(r,"arrow-up-down");let c=a.createSpan({cls:"stashpad-sort-label"});o?(c.setText("Sort: \u2014"),a.title=`Sort is per-parent and applies only to Nested view. The current view (${Ui[n]}) shows a synthesized flat list sorted by created time \u2014 switch back to Nested to change sort.`):(c.setText(We[s]),s!=="manual"&&a.addClass("is-active"),a.title=s==="manual"?"Sort children of this view. Click to change. Drag-reorder always reverts the affected parent to Manual.":`Currently: ${We[s]}. Drag-reorder will revert this parent to Manual.`);let l=d=>{o||(d.preventDefault(),this.openSortMenu(a))};a.onclick=l,a.onkeydown=d=>{o||(d.key==="Enter"||d.key===" ")&&l(d)}}openSortMenu(t){let e=t.ownerDocument??document;e.querySelectorAll(".stashpad-sort-popover").forEach(r=>r.remove());let i=e.body.createDiv({cls:"stashpad-sort-popover"}),s=t.getBoundingClientRect();i.style.left=`${Math.max(8,s.left)}px`,i.style.top=`${s.bottom+4}px`,i.style.minWidth=`${s.width}px`,i.style.maxWidth="min(280px, calc(100vw - 16px))",i.style.width="max-content";let n=()=>{i.remove(),e.removeEventListener("mousedown",o,!0);try{this.app.keymap?.popScope(a)}catch{}},o=r=>{!i.contains(r.target)&&r.target!==t&&!t.contains(r.target)&&n()};this.populateSortMenuBody(i,n);let a=new L.Scope(this.app.scope);a.register([],"Escape",r=>(r.preventDefault(),n(),!1)),this.app.keymap?.pushScope(a),setTimeout(()=>{e.addEventListener("mousedown",o,!0)},0)}renderMobileFiltersButton(t){let e=t.createDiv({cls:"stashpad-mobile-filters-btn"});e.setAttribute("role","button"),e.setAttribute("tabindex","0");let i=e.createSpan({cls:"stashpad-mobile-filters-icon"});(0,L.setIcon)(i,"sliders-horizontal"),e.title="Filters / view options";let s=!!this.tagFilter,n=!!this.colorFilter,o=this.timeFilter!=="all",a=this.sortStore.getMode(this.noteFolder,this.focusId)!=="manual",r=this.currentViewMode()!=="nested"||this.currentHideChildless()||this.currentHideCompleted()||this.currentAttachmentsOnly()||this.currentIncludeAttachments();(s||n||o||a||r)&&e.addClass("is-active");let c=l=>{l.preventDefault(),this.openMobileFiltersMenu(e)};e.onclick=c,e.onkeydown=l=>{(l.key==="Enter"||l.key===" ")&&c(l)}}openMobileFiltersMenu(t){let e=t.ownerDocument??document;e.querySelectorAll(".stashpad-mobile-filters-popover").forEach(I=>I.remove());let i=e.body.createDiv({cls:"stashpad-mobile-filters-popover"}),s=t.getBoundingClientRect(),n=e.defaultView??window;i.style.right=`${Math.max(8,n.innerWidth-s.right)}px`,i.style.left="auto",i.style.top=`${s.bottom+4}px`,i.style.maxWidth="min(360px, calc(100vw - 16px))",i.style.width="max-content",i.style.minWidth="260px";let o=()=>{i.remove(),e.removeEventListener("mousedown",a,!0);try{this.app.keymap?.popScope(d)}catch{}},a=I=>{!i.contains(I.target)&&I.target!==t&&!t.contains(I.target)&&o()},r=[{key:"tag",title:"Tag filter",summary:()=>this.tagFilter?`#${this.tagFilter}`:"All tags",populate:I=>this.populateTagMenuBody(I,o)},{key:"color",title:"Color filter",summary:()=>this.colorFilter?this.plugin.getColorAlias(this.noteFolder,this.colorFilter)??this.colorFilter:"All colors",populate:I=>this.populateColorMenuBody(I,this.collectFolderColors(),o)},{key:"time",title:"Time filter",summary:()=>{let I=Ti.find(g=>g.key===this.timeFilter);return I?this.timeFilterCalendar?I.calShort:I.rollShort:"All"},populate:I=>this.populateTimeMenuBody(I,o)},{key:"sort",title:"Sort",summary:()=>this.currentViewMode()!=="nested"?"\u2014 (Nested only)":We[this.sortStore.getMode(this.noteFolder,this.focusId)],populate:I=>{if(this.currentViewMode()!=="nested"){I.createDiv({cls:"stashpad-mobile-filters-note",text:"Sort applies only in Nested view."});return}this.populateSortMenuBody(I,o)}},{key:"view",title:"View",summary:()=>Ui[this.currentViewMode()],populate:I=>this.populateViewMenuBody(I,o)}],c="",l=()=>{i.empty();for(let I of r){let g=i.createDiv({cls:"stashpad-mobile-filters-section"}),p=g.createDiv({cls:"stashpad-mobile-filters-header"}),u=p.createSpan({cls:"stashpad-mobile-filters-chev"});if((0,L.setIcon)(u,c===I.key?"chevron-down":"chevron-right"),p.createSpan({cls:"stashpad-mobile-filters-title",text:I.title}),p.createSpan({cls:"stashpad-mobile-filters-summary",text:I.summary()}),p.onclick=f=>{f.preventDefault(),f.stopPropagation(),c=c===I.key?"":I.key,l()},c===I.key){let f=g.createDiv({cls:"stashpad-mobile-filters-body"});I.populate(f)}}};l();let d=new L.Scope(this.app.scope);d.register([],"Escape",I=>(I.preventDefault(),o(),!1)),this.app.keymap?.pushScope(d),setTimeout(()=>{e.addEventListener("mousedown",a,!0)},0)}renderViewDropdown(t){let e=this.currentViewMode(),i=t.createDiv({cls:"stashpad-view-btn"});i.setAttribute("role","button"),i.setAttribute("tabindex","0");let s=i.createSpan({cls:"stashpad-view-icon"});(0,L.setIcon)(s,e==="flat"?"list":e==="everything"?"layout-grid":"list-tree"),i.createSpan({cls:"stashpad-view-label"}).setText(Ui[e]),e!=="nested"&&i.addClass("is-active"),i.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 o=a=>{a.preventDefault(),this.openViewMenu(i)};i.onclick=o,i.onkeydown=a=>{(a.key==="Enter"||a.key===" ")&&o(a)}}openViewMenu(t){let e=t.ownerDocument??document;e.querySelectorAll(".stashpad-view-popover").forEach(r=>r.remove());let i=e.body.createDiv({cls:"stashpad-view-popover"});L.Platform.isMobile&&i.addClass("is-mobile");let s=t.getBoundingClientRect();i.style.left=`${Math.max(8,s.left)}px`,i.style.top=`${s.bottom+4}px`,i.style.minWidth=`${s.width}px`,i.style.maxWidth="min(320px, calc(100vw - 16px))",i.style.width="max-content";let n=()=>{i.remove(),e.removeEventListener("mousedown",o,!0);try{this.app.keymap?.popScope(a)}catch{}},o=r=>{!i.contains(r.target)&&r.target!==t&&!t.contains(r.target)&&n()};this.populateViewMenuBody(i,n);let a=new L.Scope(this.app.scope);a.register([],"Escape",r=>(r.preventDefault(),n(),!1)),this.app.keymap?.pushScope(a),setTimeout(()=>{e.addEventListener("mousedown",o,!0)},0)}populateViewMenuBody(t,e){let i=this.currentViewMode(),s=(g,p)=>{let u=t.createDiv({cls:"stashpad-view-popover-row"});g===i&&u.addClass("is-active"),u.createDiv({cls:"stashpad-view-popover-main"}).createSpan({cls:"stashpad-view-popover-label",text:Ui[g]}),u.createDiv({cls:"stashpad-view-popover-desc",text:p}),u.onclick=async B=>{B.preventDefault(),B.stopPropagation(),e(),g!==i&&(await this.setViewMode(g),this.render())}};s("nested","Tree of immediate children (default)."),s("flat","All descendants of the current focus, flat by sort."),s("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"}),o=n.createEl("input",{type:"checkbox"});o.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:i==="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 g=>{g.target!==o&&(g.preventDefault(),o.checked=!o.checked),await this.setHideChildless(o.checked),this.refreshList()};let a=t.createDiv({cls:"stashpad-view-popover-row stashpad-view-popover-toggle"}),r=a.createEl("input",{type:"checkbox"});r.checked=this.currentHideCompleted(),a.createDiv({cls:"stashpad-view-popover-main"}).createSpan({cls:"stashpad-view-popover-label",text:"Hide completed notes"}),a.createDiv({cls:"stashpad-view-popover-desc",text:"Hide notes marked complete. A completed parent stays visible while any descendant is still incomplete."}),a.onclick=async g=>{g.target!==r&&(g.preventDefault(),r.checked=!r.checked),await this.setHideCompleted(r.checked),this.refreshList()};let c=t.createDiv({cls:"stashpad-view-popover-row stashpad-view-popover-toggle"}),l=c.createEl("input",{type:"checkbox"});l.checked=this.currentAttachmentsOnly(),c.createDiv({cls:"stashpad-view-popover-main"}).createSpan({cls:"stashpad-view-popover-label",text:"Hide notes without attachments"}),c.createDiv({cls:"stashpad-view-popover-desc",text:"Show only notes that have an attachment. A parent stays visible while any descendant has one."}),c.onclick=async g=>{g.target!==l&&(g.preventDefault(),l.checked=!l.checked),await this.setAttachmentsOnly(l.checked),this.refreshList()},t.createDiv({cls:"stashpad-view-popover-divider"});let d=t.createDiv({cls:"stashpad-view-popover-row stashpad-view-popover-toggle"});i!=="everything"&&d.addClass("is-disabled");let I=d.createEl("input",{type:"checkbox"});I.checked=this.currentIncludeAttachments(),I.disabled=i!=="everything",d.createDiv({cls:"stashpad-view-popover-main"}).createSpan({cls:"stashpad-view-popover-label",text:"Include attachments"}),d.createDiv({cls:"stashpad-view-popover-desc",text:i==="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."}),d.onclick=async g=>{i==="everything"&&(g.target!==I&&(g.preventDefault(),I.checked=!I.checked),await this.setIncludeAttachments(I.checked),this.refreshList())}}setTagFilter(t){(this.tagFilter??null)!==(t??null)&&(this.tagFilter=t,this.reconcileSelectionAfterFilter(),this.persistFocus(),this.render())}populateSortMenuBody(t,e){let i=this.noteFolder,s=this.focusId,n=this.sortStore.getMode(i,s);for(let o of ls){let a=t.createDiv({cls:"stashpad-sort-popover-row"});o===n&&a.addClass("is-active"),a.createSpan({cls:"stashpad-sort-popover-label",text:We[o]}),a.onclick=async r=>{r.preventDefault(),r.stopPropagation(),e(),o!==n&&(this.sortStore.setMode(i,s,o),await this.sortStore.save(i),this.tree.rebuild(i),this.render())}}}populateTimeMenuBody(t,e){let i=t.createDiv({cls:"stashpad-view-popover-row stashpad-view-popover-toggle"}),s=i.createEl("input",{type:"checkbox"});s.checked=this.timeFilterCalendar,i.createDiv({cls:"stashpad-view-popover-main"}).createSpan({cls:"stashpad-view-popover-label",text:"Calendar mode"}),i.createDiv({cls:"stashpad-view-popover-desc",text:"Use calendar boundaries (start of today/week/month/year). Off = rolling windows back from now."}),i.onclick=n=>{n.target!==s&&(n.preventDefault(),s.checked=!s.checked),this.timeFilterCalendar=s.checked,this.persistFocus(),this.refreshList()};for(let n of Ti){let o=t.createDiv({cls:"stashpad-sort-popover-row"});this.timeFilter===n.key&&o.addClass("is-active");let a=this.timeFilterCalendar?n.calLong:n.rollLong;o.createSpan({cls:"stashpad-sort-popover-label",text:a}),o.onclick=r=>{r.preventDefault(),r.stopPropagation(),e(),this.timeFilter!==n.key&&this.setTimeFilter(n.key)}}}populateColorMenuBody(t,e,i){let s=(n,o,a)=>{let r=t.createDiv({cls:"stashpad-color-filter-popover-row"}),c=r.createSpan({cls:"stashpad-color-filter-swatch"});o?c.style.background=o:c.addClass("is-empty");let l=r.createSpan({cls:"stashpad-color-filter-popover-label"});l.setText(n),o&&(l.style.color=o),r.onclick=d=>{d.preventDefault(),d.stopPropagation(),a(),i()}};s("All colors",null,()=>this.setColorFilter(null));for(let n of e){let o=this.plugin.getColorAlias(this.noteFolder,n.hex),a=o?`${o} (${n.count})`:`${n.hex} (${n.count})`;s(a,n.hex,()=>this.setColorFilter(n.hex))}}populateTagMenuBody(t,e){let i=this.collectFolderTags(),s=(n,o)=>{let a=t.createDiv({cls:"stashpad-color-filter-popover-row"});a.createSpan({cls:"stashpad-color-filter-swatch is-empty"}),a.createSpan({cls:"stashpad-color-filter-popover-label"}).setText(n),(this.tagFilter??"")===(o??"")&&a.addClass("is-active"),a.onclick=l=>{l.preventDefault(),l.stopPropagation(),this.setTagFilter(o),e()}};s(i.length===0?"No tags":"All tags",null);for(let n of i)s(`${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(i=>i.id));for(let i of[...this.selection])e.has(i)||this.selection.delete(i);if(this.firstSelectedId&&!e.has(this.firstSelectedId)&&(this.firstSelectedId=null),this.lastSelected&&!e.has(this.lastSelected)&&(this.lastSelected=null),this.selection.size>0){let i=t.findIndex(s=>this.selection.has(s.id));this.cursorIdx=i>=0?i: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"}),i=e.createEl("button",{cls:"stashpad-tiny-nav-btn"});Zt(i,"arrow-left","\u2039"),i.title="Back (up to parent)",this.navBackStack.length>0||this.focusId!==G||i.addClass("is-disabled"),i.title=this.navBackStack.length>0?"Back":this.focusId!==G?"Back (up to parent)":"No back history",i.onclick=()=>this.navigateBack();let n=e.createEl("button",{cls:"stashpad-tiny-nav-btn"});Zt(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 o=this.tree.get(this.focusId)??this.tree.getRoot(),a=(this.noteFolder.split("/").pop()||this.noteFolder).trim(),r=this.focusId===G?a:`${a} / ${this.titleForNode(o).trim()}`,c=e.createEl("button",{cls:"stashpad-tiny-title stashpad-folder-btn"}),l=c.createSpan({cls:"stashpad-tiny-title-icon stashpad-btn-icon"});(0,L.setIcon)(l,"folder"),c.createSpan({cls:"stashpad-tiny-title-text stashpad-btn-text",text:r}),c.title=`${this.noteFolder}${this.focusId!==G?` / ${this.titleForNode(o).trim()}`:""} -Click to switch / create folder.`,c.onclick=u=>{u.preventDefault(),this.plugin.openFolderPicker()};let d=e.createDiv({cls:"stashpad-tiny-sticky"}),I=d.createEl("input",{type:"checkbox"});if(I.checked=this.tinyAlwaysOnTop,d.createSpan({text:"Sticky"}),I.onchange=()=>{this.tinyAlwaysOnTop=I.checked,this.applyTinyAlwaysOnTop()},!L.Platform.isMobile){let u=e.createEl("button",{cls:"stashpad-tiny-nav-btn stashpad-tiny-opacity-btn"});(0,L.setIcon)(u,"contrast"),u.title="Window transparency",this.tinyOpacity<1&&u.addClass("is-active"),u.onclick=f=>{f.stopPropagation(),this.toggleTinyOpacityPopover(u)}}let g=e.createEl("button",{cls:"stashpad-tiny-expand stashpad-tiny-exit-compact"});(0,L.setIcon)(g,this.compactMode?"panel-top":"rows-2"),g.title=this.compactMode?"Compact mode is ON \u2014 click to turn off.":"Compact mode \u2014 click to turn on (strips row metadata).",this.compactMode&&g.addClass("is-active"),g.onclick=()=>{this.toggleCompactMode()};let p=e.createEl("button",{cls:"stashpad-tiny-expand"});(0,L.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 i=e.createEl("input",{type:"range"});i.min="30",i.max="100",i.step="1",i.value=String(Math.round(this.tinyOpacity*100));let s=e.createSpan({cls:"stashpad-tiny-opacity-pct",text:`${i.value}%`});i.addEventListener("input",()=>{let l=Math.min(100,Math.max(30,parseInt(i.value,10)||100));this.tinyOpacity=l/100,s.setText(`${l}%`),this.applyTinyOpacity(),t.toggleClass("is-active",this.tinyOpacity<1)}),i.addEventListener("change",()=>{this.app.workspace.requestSaveLayout()}),this.viewRoot.appendChild(e);let n=t.getBoundingClientRect(),o=this.viewRoot.getBoundingClientRect();e.style.top=`${n.bottom-o.top+4}px`,e.style.left=`${Math.max(4,Math.min(n.left-o.left,o.width-180))}px`;let a=l=>{e.contains(l.target)||l.target===t||t.contains(l.target)||c()},r=l=>{l.key==="Escape"&&c()},c=()=>{e.remove(),this.tinyOpacityPopover=null,document.removeEventListener("mousedown",a,!0),document.removeEventListener("keydown",r,!0)};setTimeout(()=>{document.addEventListener("mousedown",a,!0),document.addEventListener("keydown",r,!0)},0),this.tinyOpacityPopover=e,i.focus()}getOwnElectronWindow(){try{let t=this.containerEl?.ownerDocument?.defaultView??window,s=((t?.require?.("electron")??window.require?.("electron"))?.remote??t?.electron?.remote??t?.["@electron/remote"])?.getCurrentWindow?.()??t?.electronWindow??null;if(!s)try{let n=window.require?.("electron"),o=n?.remote??n?.["@electron/remote"],r=(o?.BrowserWindow??n?.BrowserWindow)?.getAllWindows?.()??[];r.length===1?s=r[0]:r.length>1&&(s=o?.getFocusedWindow?.()??null??r[r.length-1])}catch(n){console.debug("[Stashpad] BrowserWindow.getAllWindows fallback failed",n)}return s||console.debug("[Stashpad] couldn't resolve own electron window"),s??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(i){console.debug("[Stashpad] setOpacity failed",i)}}applyTinyWindow(){let t=this.getOwnElectronWindow();if(t)try{if(this.tinyMode){t.setMinimumSize?.(220,260);let s=100,n=100;try{let o=t.getBounds?.();o&&typeof o.x=="number"&&(s=o.x,n=o.y)}catch{}try{t.setBounds?.({x:s,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),L.Platform.isMacOS??!1){let i=this.containerEl?.ownerDocument?.defaultView?.require?.("electron")??window.require?.("electron"),n=(i?.remote?.screen??i?.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 i=e.createSpan({cls:"stashpad-crumb stashpad-crumb-home"});if(L.Platform.isMobile?((0,L.setIcon)(i,"home"),i.title="Home"):i.setText("Home"),i.onclick=()=>this.navigateTo(G),this.focusId===G){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 d=e.createEl("button",{cls:"stashpad-compact-exit-btn"});(0,L.setIcon)(d,"panel-top"),d.title="Exit compact mode",d.onclick=I=>{I.preventDefault(),this.toggleCompactMode()}}return}let s=28,n=100,o=this.tree.pathTo(this.focusId),a=o.map(l=>{let d=this.titleForNode(l),I=d.length>s?d.slice(0,s-1)+"\u2026":d;return{id:l.id,label:I}}),r=l=>l.reduce((d,I)=>d+I.label.length+3,0);if(r(a)>n&&a.length>2){let l=!1;for(;r(a)>n&&a.length>2;)a.splice(1,1),l||(a.splice(1,0,{id:"__ellipsis__",label:"\u2026",isEllipsis:!0}),l=!0)}for(let l of a)if(e.createSpan({cls:"stashpad-crumb-sep",text:" / "}),l.isEllipsis)e.createSpan({cls:"stashpad-crumb stashpad-crumb-ellipsis",text:l.label}).title=o.map(d=>this.titleForNode(d)).join(" / ");else{let d=l.id,I=e.createSpan({cls:"stashpad-crumb",text:l.label});I.title=l.label,I.onclick=()=>this.navigateTo(d),I.oncontextmenu=g=>{g.preventDefault(),this.openCrumbMenu(g,d)},L.Platform.isMobile&&this.attachLongPress(I,()=>this.openCrumbMenu(null,d))}if(e.querySelector(".stashpad-crumb-home")?.addEventListener("contextmenu",l=>{l.preventDefault(),this.openCrumbMenu(l,G)}),L.Platform.isMobile){let l=e.querySelector(".stashpad-crumb-home");l&&this.attachLongPress(l,()=>this.openCrumbMenu(null,G))}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 l=e.createEl("button",{cls:"stashpad-compact-exit-btn"});(0,L.setIcon)(l,"panel-top"),l.title="Exit compact mode",l.onclick=d=>{d.preventDefault(),this.toggleCompactMode()}}}attachLongPress(t,e){let i=null,s=0,n=0,o=()=>{i!=null&&(window.clearTimeout(i),i=null)};t.addEventListener("touchstart",a=>{let r=a.touches[0];s=r?.clientX??0,n=r?.clientY??0,o(),i=window.setTimeout(()=>{i=null,e()},500)},{passive:!0}),t.addEventListener("touchmove",a=>{let r=a.touches[0];r&&(Math.abs(r.clientX-s)>10||Math.abs(r.clientY-n)>10)&&o()},{passive:!0}),t.addEventListener("touchend",o),t.addEventListener("touchcancel",o)}openCrumbMenu(t,e){let i=this.tree.get(e);if(!i)return;let s=new L.Menu;if(s.addItem(n=>n.setTitle("Navigate here").setIcon("arrow-right-circle").onClick(()=>this.navigateTo(e))),s.addItem(n=>n.setTitle("Open in new Stashpad tab").setIcon("list-tree").onClick(()=>this.cmdOpenInNewStashpadTab(i))),i.file&&s.addItem(n=>n.setTitle("Open in editor (new tab)").setIcon("pencil").onClick(()=>this.cmdOpenInEditor(i))),t&&(t.clientX>0||t.clientY>0))s.showAtMouseEvent(t);else{let o=(t?.target??null)?.getBoundingClientRect();s.showAtPosition({x:o?.left??8,y:(o?.bottom??60)+4})}}renderFocusedHeaderMini(t,e){if(!e.file)return;let i=e.file,s=t.createDiv({cls:"stashpad-focused-mini"});s.dataset.id=e.id,s.createDiv({cls:"stashpad-focused-mini-text"}).setText(this.titleForNode(e).trim());let o=s.createEl("button",{cls:"stashpad-pencil stashpad-focused-mini-pencil"});(0,L.setIcon)(o,"pencil"),o.title="Edit in new tab",o.onclick=a=>{a.stopPropagation(),this.openFileAtEnd(i)}}installFocusedMiniObserver(t){let e=t.querySelector(".stashpad-focused"),i=t.querySelector(".stashpad-focused-mini");!e||!i||(this.focusedMiniObserver&&this.focusedMiniObserver.disconnect(),this.focusedMiniObserver=new IntersectionObserver(s=>{for(let n of s)i.toggleClass("is-visible",!n.isIntersecting)},{root:t,threshold:.05}),this.focusedMiniObserver.observe(e))}renderFocusedHeader(t,e){if(!e.file)return;let i=e.file,s=t.createDiv({cls:"stashpad-focused"}),o=s.createDiv({cls:"stashpad-focused-meta"}).createDiv({cls:"stashpad-focused-meta-top"});o.createSpan({cls:"stashpad-focused-time stashpad-note-time",text:this.formatTime(e.created)}),o.createDiv({cls:"stashpad-focused-grip-spacer"});let a=s.createDiv({cls:"stashpad-focused-body"});a.addEventListener("click",d=>this.handleRenderedClick(d,e));let r=s.createDiv({cls:"stashpad-focused-actions"}),c=r.createEl("button",{cls:"stashpad-pencil stashpad-focused-pencil"});(0,L.setIcon)(c,"pencil"),c.title="Edit in new tab",c.onclick=()=>void this.openFileAtEnd(i);let l=r.createEl("button",{cls:"stashpad-pencil stashpad-focused-dup"});(0,L.setIcon)(l,"copy"),l.title="Open this Stashpad in a new tab (clone)",l.onclick=()=>this.cmdOpenInNewStashpadTab(e),this.renderNoteBody(a,e,{clamp:L.Platform.isMobile,toggleHost:r,toggleAnchor:c})}renderRowBreadcrumb(t,e){let i=this.tree.pathTo(e.id),s=i.findIndex(a=>a.id===this.focusId),n=i.slice(s+1,i.length-1);if(n.length===0)return;let o=t.createDiv({cls:"stashpad-row-breadcrumb"});n.forEach((a,r)=>{let c=o.createSpan({cls:"stashpad-row-breadcrumb-seg",text:this.titleForNode(a)});c.title=`Focus into "${this.titleForNode(a)}"`,c.onclick=l=>{l.stopPropagation(),this.navigateTo(a.id)},r<n.length-1&&o.createSpan({cls:"stashpad-row-breadcrumb-sep",text:" / "})})}actionsForFile(t){return Ii(this.app,t,L.Platform.isMobile)}bulkActionMessage(t){let e=t.nodes.map(a=>`"${this.titleForNode(a).trim()||"(untitled)"}"`),i=t.suffix?` ${t.suffix}`:"",s=t.destination?` ${t.destination}`:"";if(e.length===0)return`${t.verb}${i}${s}`;if(e.length===1)return`${t.verb} ${e[0]}${i}${s}`;let n=t.bulletMax??10,o=e.length<=n?e.map(a=>`\u2022 ${a}`).join(` -`):e.slice(0,n).map(a=>`\u2022 ${a}`).join(` +Click to override for this tab.`,s&&i.addClass("is-override"),i.onclick=h=>{h.preventDefault(),this.openFolderPicker()};let o=e.createEl("button",{cls:"stashpad-search-btn"});jt(o,"search","\u{1F50D}"),o.title="Search notes (Mod+F)",o.onclick=h=>{h.preventDefault(),this.openSearchModal()},q.Platform.isMobile?this.renderMobileFiltersButton(e):(this.renderTagFilterDropdown(e),this.renderColorFilterDropdown(e),this.renderSortDropdown(e),this.renderViewDropdown(e));let r=e.createDiv({cls:"stashpad-time-filter-btns"}),a=r.createEl("button",{cls:"stashpad-time-filter-btn stashpad-time-filter-cal"});(0,q.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 Ki){let I=this.timeFilterCalendar?h.calShort:h.rollShort,u=this.timeFilterCalendar?h.calLong:h.rollLong,f=r.createEl("button",{cls:"stashpad-time-filter-btn",text:I});f.title=u,this.timeFilter===h.key&&f.addClass("is-active"),f.onclick=C=>{C.preventDefault(),this.setTimeFilter(h.key)}}let c=e.createEl("select",{cls:"stashpad-time-filter-select"});for(let h of Ki){let I=this.timeFilterCalendar?h.calLong:h.rollLong,u=c.createEl("option",{text:I});u.value=h.key,this.timeFilter===h.key&&(u.selected=!0)}c.onchange=()=>this.setTimeFilter(c.value);let l=e.createDiv({cls:"stashpad-view-mode-btns"});if(!q.Platform.isMobile){let h=l.createEl("button",{cls:"stashpad-view-mode-btn"});(0,q.setIcon)(h,"minimize-2"),h.title="Tiny mode \u2014 open this tab in a small always-on-top-capable popout window.",h.onclick=I=>{I.preventDefault(),this.plugin.openTinyWindow()}}let p=l.createEl("button",{cls:"stashpad-view-mode-btn"});if((0,q.setIcon)(p,this.compactMode?"panel-top":"rows-2"),p.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&&p.addClass("is-active"),p.onclick=h=>{h.preventDefault(),this.toggleCompactMode()},q.Platform.isMobile)return;let g=l.createEl("button",{cls:"stashpad-view-mode-btn"});(0,q.setIcon)(g,"external-link"),g.title=ft().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.)",g.onclick=h=>{h.preventDefault();let I=ft().popoutDuplicates;try{let u=this.app.workspace;if(I){let f=this.leaf.getViewState(),C=u.openPopoutLeaf?.();C?C.setViewState({...f,active:!0}):new q.Notice("Stashpad: this Obsidian build doesn't expose openPopoutLeaf.")}else u.moveLeafToPopout?.(this.leaf)}catch(u){new q.Notice(`Stashpad: open-in-new-window failed (${u.message})`)}}}toggleCompactMode(){this.compactMode=!this.compactMode,this.render();try{this.app.workspace.requestSaveLayout?.()}catch{}}renderActionsCluster(t){let e=t.createDiv({cls:"stashpad-mobile-actions"}),i=e.createEl("button",{cls:"stashpad-mobile-action-btn"});jt(i,"arrow-left","\u2039");let s=this.navBackStack.length>0||this.focusId!==G;i.title=this.navBackStack.length>0?"Back":this.focusId!==G?"Back (up to parent)":"No back history",s||i.addClass("is-disabled"),i.onclick=l=>{l.preventDefault(),this.navigateBack()};let n=e.createEl("button",{cls:"stashpad-mobile-action-btn"});jt(n,"arrow-right","\u203A");let o=this.navForwardSnapshots.length>0;n.title=o?"Forward":"No forward history",o||n.addClass("is-disabled"),n.onclick=l=>{l.preventDefault(),this.navigateForward()};let r=e.createEl("button",{cls:"stashpad-mobile-action-btn"}),a=this.mobileSelectMode;jt(r,a?"check-square":"square",a?"\u2611":"\u2610"),r.title=a?`${this.selection.size} selected \u2014 tap to exit (keeps the first selection)`:"Enter select mode (tap notes to add)",a&&r.addClass("is-active"),r.onclick=l=>{if(l.preventDefault(),this.mobileSelectMode){let p=this.firstSelectedId??this.selection.values().next().value;if(this.selection.clear(),p){let g=this.currentChildren.findIndex(h=>h.id===p);this.selection.add(p),this.lastSelected=p,g>=0&&(this.cursorIdx=g)}this.firstSelectedId=null,this.mobileSelectMode=!1,this.render()}else{let p=this.currentChildren[Math.max(0,this.cursorIdx)];this.mobileSelectMode=!0,this.selection.clear(),p&&(this.selection.add(p.id),this.lastSelected=p.id,this.firstSelectedId=p.id),this.render(),new q.Notice("Select mode: tap notes to add, press \u26A1 for actions")}};let c=e.createEl("button",{cls:"stashpad-mobile-action-btn"});jt(c,"zap","\u26A1"),c.title="Actions (move, delete, undo, \u2026)",c.onclick=l=>{l.preventDefault(),this.openMobileActionsMenu(c)}}openMobileActionsMenu(t){let e=new q.Menu,i=this.selection.size>0||this.cursorIdx>=0&&!!this.currentChildren[this.cursorIdx],s=this.selection.size<=1;e.addItem(o=>o.setTitle("Undo").setIcon("undo").onClick(()=>this.cmdUndo())),e.addItem(o=>o.setTitle("Redo").setIcon("redo").onClick(()=>this.cmdRedo())),e.addSeparator(),e.addItem(o=>o.setTitle("Notification history\u2026").setIcon("bell").onClick(()=>{this.app.commands?.executeCommandById?.("stashpad:stashpad-open-notification-history")})),e.addSeparator(),e.addItem(o=>o.setTitle("Open in new Stashpad tab").setIcon("list-tree").setDisabled(!i).onClick(()=>this.cmdOpenInNewStashpadTab())),e.addItem(o=>o.setTitle("Open in editor").setIcon("pencil").setDisabled(!i).onClick(()=>this.cmdOpenInEditor())),e.addSeparator(),e.addItem(o=>o.setTitle("Move\u2026").setIcon("arrow-right-circle").setDisabled(!i).onClick(()=>this.cmdMovePicker())),e.addItem(o=>o.setTitle("Nest under\u2026 (in-list)").setIcon("indent").setDisabled(!i).onClick(()=>this.cmdInListPicker())),e.addItem(o=>o.setTitle("Outdent").setIcon("outdent").setDisabled(!i).onClick(()=>void this.cmdOutdent())),e.addItem(o=>o.setTitle("Set color\u2026").setIcon("palette").setDisabled(!i).onClick(()=>this.cmdSetColor())),e.addItem(o=>o.setTitle("Toggle complete").setIcon("check-circle").setDisabled(!i).onClick(()=>void this.cmdToggleComplete())),e.addItem(o=>o.setTitle("Toggle task (todo)").setIcon("check-square").setDisabled(!i).onClick(()=>void this.cmdToggleTask())),e.addItem(o=>o.setTitle("Set due date\u2026").setIcon("calendar-clock").setDisabled(!i).onClick(()=>this.cmdSetDue())),e.addItem(o=>o.setTitle("Assign to\u2026").setIcon("user-plus").setDisabled(!i).onClick(()=>this.cmdAssign())),e.addSeparator(),e.addItem(o=>o.setTitle("Copy").setIcon("copy").setDisabled(!i).onClick(()=>void this.cmdCopy())),e.addItem(o=>o.setTitle("Copy tree").setIcon("copy-plus").setDisabled(!i).onClick(()=>void this.cmdCopyTree())),e.addItem(o=>o.setTitle("Clone (duplicate / copy)").setIcon("files").setDisabled(!i).onClick(()=>void this.cmdClone())),e.addItem(o=>o.setTitle("Insert template\u2026").setIcon("file-plus-2").onClick(()=>this.cmdInsertTemplate())),e.addItem(o=>o.setTitle("Merge").setIcon("merge").setDisabled(this.selection.size<2).onClick(()=>void this.cmdMerge())),e.addItem(o=>o.setTitle("Split note\u2026").setIcon("scissors").setDisabled(!i||!s).onClick(()=>void this.cmdSplit())),e.addSeparator(),e.addItem(o=>o.setTitle("Delete").setIcon("trash-2").setDisabled(!i).onClick(()=>void this.cmdDelete())),e.addSeparator(),e.addItem(o=>o.setTitle("More commands\u2026").setIcon("terminal").onClick(()=>this.openCommandPalette()));let n=t.getBoundingClientRect();e.showAtPosition({x:n.left,y:n.bottom+4})}openCommandPalette(){this.app.commands?.executeCommandById?.("command-palette:open")}openStashpadCommandPalette(){new Gi(this.app).open()}renderTagFilterDropdown(t){let e=t.createEl("select",{cls:"stashpad-tag-filter-select"}),i=e.createEl("option",{text:"All tags"});i.value="",this.tagFilter||(i.selected=!0);let s=this.collectFolderTags();if(s.length===0)e.disabled=!0,i.text="No tags";else for(let n of s){let o=e.createEl("option",{text:`${n.label} (${n.count})`});o.value=n.raw,this.tagFilter&&this.tagFilter.toLowerCase()===n.raw.toLowerCase()&&(o.selected=!0)}e.onchange=()=>this.setTagFilter(e.value||null)}renderColorFilterDropdown(t){let e=this.collectFolderColors(),i=t.createDiv({cls:"stashpad-color-filter-btn"});i.setAttribute("role","button"),i.setAttribute("tabindex","0"),(()=>{i.empty();let o=i.createSpan({cls:"stashpad-color-filter-swatch"}),r=i.createSpan({cls:"stashpad-color-filter-label"});if(this.colorFilter){let a=this.colorFilter.toLowerCase();o.style.background=a;let c=this.plugin.getColorAlias(this.noteFolder,a);r.setText(c??a)}else e.length===0?(o.addClass("is-empty"),r.setText("No colors"),i.addClass("is-disabled")):(o.addClass("is-empty"),r.setText("All colors"))})();let n=o=>{o.preventDefault(),!(e.length===0&&!this.colorFilter)&&this.openColorFilterMenu(i,e)};i.onclick=n,i.onkeydown=o=>{(o.key==="Enter"||o.key===" ")&&n(o)}}openColorFilterMenu(t,e){let i=t.ownerDocument??document;i.querySelectorAll(".stashpad-color-filter-popover").forEach(c=>c.remove());let s=i.body.createDiv({cls:"stashpad-color-filter-popover"}),n=t.getBoundingClientRect();s.style.left=`${Math.max(8,n.left)}px`,s.style.top=`${n.bottom+4}px`,s.style.minWidth=`${n.width}px`,s.style.maxWidth="min(280px, calc(100vw - 16px))",s.style.width="max-content";let o=new q.Scope(this.app.scope),r=()=>{s.remove(),i.removeEventListener("mousedown",a,!0);try{this.app.keymap?.popScope(o)}catch{}},a=c=>{!s.contains(c.target)&&c.target!==t&&!t.contains(c.target)&&r()};o.register([],"Escape",c=>(c.preventDefault(),r(),!1)),this.app.keymap?.pushScope(o),this.populateColorMenuBody(s,e,r),setTimeout(()=>{i.addEventListener("mousedown",a,!0)},0)}renderSortDropdown(t){let e=this.noteFolder,i=this.focusId,s=this.sortStore.getMode(e,i),n=this.currentViewMode(),o=n!=="nested",r=t.createDiv({cls:"stashpad-sort-btn"});r.setAttribute("role","button"),r.setAttribute("tabindex",o?"-1":"0"),o&&r.addClass("is-disabled");let a=r.createSpan({cls:"stashpad-sort-icon"});(0,q.setIcon)(a,"arrow-up-down");let c=r.createSpan({cls:"stashpad-sort-label"});o?(c.setText("Sort: \u2014"),r.title=`Sort is per-parent and applies only to Nested view. The current view (${Oi[n]}) shows a synthesized flat list sorted by created time \u2014 switch back to Nested to change sort.`):(c.setText(_e[s]),s!=="manual"&&r.addClass("is-active"),r.title=s==="manual"?"Sort children of this view. Click to change. Drag-reorder always reverts the affected parent to Manual.":`Currently: ${_e[s]}. Drag-reorder will revert this parent to Manual.`);let l=p=>{o||(p.preventDefault(),this.openSortMenu(r))};r.onclick=l,r.onkeydown=p=>{o||(p.key==="Enter"||p.key===" ")&&l(p)}}openSortMenu(t){let e=t.ownerDocument??document;e.querySelectorAll(".stashpad-sort-popover").forEach(a=>a.remove());let i=e.body.createDiv({cls:"stashpad-sort-popover"}),s=t.getBoundingClientRect();i.style.left=`${Math.max(8,s.left)}px`,i.style.top=`${s.bottom+4}px`,i.style.minWidth=`${s.width}px`,i.style.maxWidth="min(280px, calc(100vw - 16px))",i.style.width="max-content";let n=()=>{i.remove(),e.removeEventListener("mousedown",o,!0);try{this.app.keymap?.popScope(r)}catch{}},o=a=>{!i.contains(a.target)&&a.target!==t&&!t.contains(a.target)&&n()};this.populateSortMenuBody(i,n);let r=new q.Scope(this.app.scope);r.register([],"Escape",a=>(a.preventDefault(),n(),!1)),this.app.keymap?.pushScope(r),setTimeout(()=>{e.addEventListener("mousedown",o,!0)},0)}renderMobileFiltersButton(t){let e=t.createDiv({cls:"stashpad-mobile-filters-btn"});e.setAttribute("role","button"),e.setAttribute("tabindex","0");let i=e.createSpan({cls:"stashpad-mobile-filters-icon"});(0,q.setIcon)(i,"sliders-horizontal"),e.title="Filters / view options";let s=!!this.tagFilter,n=!!this.colorFilter,o=this.timeFilter!=="all",r=this.sortStore.getMode(this.noteFolder,this.focusId)!=="manual",a=this.currentViewMode()!=="nested"||this.currentHideChildless()||this.currentHideCompleted()||this.currentAttachmentsOnly()||this.currentIncludeAttachments();(s||n||o||r||a)&&e.addClass("is-active");let c=l=>{l.preventDefault(),this.openMobileFiltersMenu(e)};e.onclick=c,e.onkeydown=l=>{(l.key==="Enter"||l.key===" ")&&c(l)}}openMobileFiltersMenu(t){let e=t.ownerDocument??document;e.querySelectorAll(".stashpad-mobile-filters-popover").forEach(g=>g.remove());let i=e.body.createDiv({cls:"stashpad-mobile-filters-popover"}),s=t.getBoundingClientRect(),n=e.defaultView??window;i.style.right=`${Math.max(8,n.innerWidth-s.right)}px`,i.style.left="auto",i.style.top=`${s.bottom+4}px`,i.style.maxWidth="min(360px, calc(100vw - 16px))",i.style.width="max-content",i.style.minWidth="260px";let o=()=>{i.remove(),e.removeEventListener("mousedown",r,!0);try{this.app.keymap?.popScope(p)}catch{}},r=g=>{!i.contains(g.target)&&g.target!==t&&!t.contains(g.target)&&o()},a=[{key:"tag",title:"Tag filter",summary:()=>this.tagFilter?`#${this.tagFilter}`:"All tags",populate:g=>this.populateTagMenuBody(g,o)},{key:"color",title:"Color filter",summary:()=>this.colorFilter?this.plugin.getColorAlias(this.noteFolder,this.colorFilter)??this.colorFilter:"All colors",populate:g=>this.populateColorMenuBody(g,this.collectFolderColors(),o)},{key:"time",title:"Time filter",summary:()=>{let g=Ki.find(h=>h.key===this.timeFilter);return g?this.timeFilterCalendar?g.calShort:g.rollShort:"All"},populate:g=>this.populateTimeMenuBody(g,o)},{key:"sort",title:"Sort",summary:()=>this.currentViewMode()!=="nested"?"\u2014 (Nested only)":_e[this.sortStore.getMode(this.noteFolder,this.focusId)],populate:g=>{if(this.currentViewMode()!=="nested"){g.createDiv({cls:"stashpad-mobile-filters-note",text:"Sort applies only in Nested view."});return}this.populateSortMenuBody(g,o)}},{key:"view",title:"View",summary:()=>Oi[this.currentViewMode()],populate:g=>this.populateViewMenuBody(g,o)}],c="",l=()=>{i.empty();for(let g of a){let h=i.createDiv({cls:"stashpad-mobile-filters-section"}),I=h.createDiv({cls:"stashpad-mobile-filters-header"}),u=I.createSpan({cls:"stashpad-mobile-filters-chev"});if((0,q.setIcon)(u,c===g.key?"chevron-down":"chevron-right"),I.createSpan({cls:"stashpad-mobile-filters-title",text:g.title}),I.createSpan({cls:"stashpad-mobile-filters-summary",text:g.summary()}),I.onclick=f=>{f.preventDefault(),f.stopPropagation(),c=c===g.key?"":g.key,l()},c===g.key){let f=h.createDiv({cls:"stashpad-mobile-filters-body"});g.populate(f)}}};l();let p=new q.Scope(this.app.scope);p.register([],"Escape",g=>(g.preventDefault(),o(),!1)),this.app.keymap?.pushScope(p),setTimeout(()=>{e.addEventListener("mousedown",r,!0)},0)}renderViewDropdown(t){let e=this.currentViewMode(),i=t.createDiv({cls:"stashpad-view-btn"});i.setAttribute("role","button"),i.setAttribute("tabindex","0");let s=i.createSpan({cls:"stashpad-view-icon"});(0,q.setIcon)(s,e==="flat"?"list":e==="everything"?"layout-grid":"list-tree"),i.createSpan({cls:"stashpad-view-label"}).setText(Oi[e]),e!=="nested"&&i.addClass("is-active"),i.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 o=r=>{r.preventDefault(),this.openViewMenu(i)};i.onclick=o,i.onkeydown=r=>{(r.key==="Enter"||r.key===" ")&&o(r)}}openViewMenu(t){let e=t.ownerDocument??document;e.querySelectorAll(".stashpad-view-popover").forEach(a=>a.remove());let i=e.body.createDiv({cls:"stashpad-view-popover"});q.Platform.isMobile&&i.addClass("is-mobile");let s=t.getBoundingClientRect();i.style.left=`${Math.max(8,s.left)}px`,i.style.top=`${s.bottom+4}px`,i.style.minWidth=`${s.width}px`,i.style.maxWidth="min(320px, calc(100vw - 16px))",i.style.width="max-content";let n=()=>{i.remove(),e.removeEventListener("mousedown",o,!0);try{this.app.keymap?.popScope(r)}catch{}},o=a=>{!i.contains(a.target)&&a.target!==t&&!t.contains(a.target)&&n()};this.populateViewMenuBody(i,n);let r=new q.Scope(this.app.scope);r.register([],"Escape",a=>(a.preventDefault(),n(),!1)),this.app.keymap?.pushScope(r),setTimeout(()=>{e.addEventListener("mousedown",o,!0)},0)}populateViewMenuBody(t,e){let i=this.currentViewMode(),s=(w,v)=>{let D=t.createDiv({cls:"stashpad-view-popover-row"});w===i&&D.addClass("is-active"),D.createDiv({cls:"stashpad-view-popover-main"}).createSpan({cls:"stashpad-view-popover-label",text:Oi[w]}),D.createDiv({cls:"stashpad-view-popover-desc",text:v}),D.onclick=async S=>{S.preventDefault(),S.stopPropagation(),e(),w!==i&&(await this.setViewMode(w),this.render())}};s("nested","Tree of immediate children (default)."),s("flat","All descendants of the current focus, flat by sort."),s("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"}),o=n.createEl("input",{type:"checkbox"});o.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:i==="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 w=>{w.target!==o&&(w.preventDefault(),o.checked=!o.checked),await this.setHideChildless(o.checked),this.refreshList()};let r=t.createDiv({cls:"stashpad-view-popover-row stashpad-view-popover-toggle"}),a=r.createEl("input",{type:"checkbox"});a.checked=this.currentHideCompleted(),r.createDiv({cls:"stashpad-view-popover-main"}).createSpan({cls:"stashpad-view-popover-label",text:"Hide completed notes"}),r.createDiv({cls:"stashpad-view-popover-desc",text:"Hide notes marked complete. A completed parent stays visible while any descendant is still incomplete."}),r.onclick=async w=>{w.target!==a&&(w.preventDefault(),a.checked=!a.checked),await this.setHideCompleted(a.checked),this.refreshList()};let c=t.createDiv({cls:"stashpad-view-popover-row stashpad-view-popover-toggle"}),l=c.createEl("input",{type:"checkbox"});l.checked=this.currentAttachmentsOnly(),c.createDiv({cls:"stashpad-view-popover-main"}).createSpan({cls:"stashpad-view-popover-label",text:"Hide notes without attachments"}),c.createDiv({cls:"stashpad-view-popover-desc",text:"Show only notes that have an attachment. A parent stays visible while any descendant has one."}),c.onclick=async w=>{w.target!==l&&(w.preventDefault(),l.checked=!l.checked),await this.setAttachmentsOnly(l.checked),this.refreshList()},t.createDiv({cls:"stashpad-view-popover-divider"});let p=t.createDiv({cls:"stashpad-view-popover-row stashpad-view-popover-toggle"});i!=="everything"&&p.addClass("is-disabled");let g=p.createEl("input",{type:"checkbox"});g.checked=this.currentIncludeAttachments(),g.disabled=i!=="everything",p.createDiv({cls:"stashpad-view-popover-main"}).createSpan({cls:"stashpad-view-popover-label",text:"Include attachments"}),p.createDiv({cls:"stashpad-view-popover-desc",text:i==="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."}),p.onclick=async w=>{i==="everything"&&(w.target!==g&&(w.preventDefault(),g.checked=!g.checked),await this.setIncludeAttachments(g.checked),this.refreshList())},t.createDiv({cls:"stashpad-view-popover-divider"});let h=t.createDiv({cls:"stashpad-view-popover-row stashpad-view-popover-toggle"}),I=h.createEl("input",{type:"checkbox"});I.checked=this.importedOnly,h.createDiv({cls:"stashpad-view-popover-main"}).createSpan({cls:"stashpad-view-popover-label",text:"Imported notes only"}),h.createDiv({cls:"stashpad-view-popover-desc",text:"Show only notes that came in via import."}),h.onclick=w=>{w.target!==I&&(w.preventDefault(),I.checked=!I.checked),this.importedOnly=I.checked,this.reconcileSelectionAfterFilter(),this.refreshList()};let u=new Map,f=this.noteFolder.replace(/\/+$/,"");for(let w of this.app.vault.getMarkdownFiles()){if((w.parent?.path?.replace(/\/+$/,"")??"")!==f)continue;let v=Xt(this.app.metadataCache.getFileCache(w)?.frontmatter?.author);v&&u.set(v.id,v.name)}let C=t.createDiv({cls:"stashpad-view-popover-row stashpad-view-popover-toggle"}),m=C.createDiv({cls:"stashpad-view-popover-main"});m.createSpan({cls:"stashpad-view-popover-label",text:"By author"});let E=m.createEl("select",{cls:"stashpad-view-author-select"}),y=E.createEl("option",{text:"All authors",value:""});this.authorFilter||(y.selected=!0);for(let[w,v]of[...u.entries()].sort((D,L)=>D[1].localeCompare(L[1]))){let D=E.createEl("option",{text:v,value:w});this.authorFilter===w&&(D.selected=!0)}E.onclick=w=>w.stopPropagation(),E.onchange=()=>{this.authorFilter=E.value||null,this.reconcileSelectionAfterFilter(),this.refreshList()},C.createDiv({cls:"stashpad-view-popover-desc",text:u.size?"Show only notes by the chosen author.":"No authored notes in this folder yet."})}setTagFilter(t){(this.tagFilter??null)!==(t??null)&&(this.tagFilter=t,this.reconcileSelectionAfterFilter(),this.persistFocus(),this.render())}populateSortMenuBody(t,e){let i=this.noteFolder,s=this.focusId,n=this.sortStore.getMode(i,s);for(let o of Bs){let r=t.createDiv({cls:"stashpad-sort-popover-row"});o===n&&r.addClass("is-active"),r.createSpan({cls:"stashpad-sort-popover-label",text:_e[o]}),r.onclick=async a=>{a.preventDefault(),a.stopPropagation(),e(),o!==n&&(this.sortStore.setMode(i,s,o),await this.sortStore.save(i),this.tree.rebuild(i),this.render())}}}populateTimeMenuBody(t,e){let i=t.createDiv({cls:"stashpad-view-popover-row stashpad-view-popover-toggle"}),s=i.createEl("input",{type:"checkbox"});s.checked=this.timeFilterCalendar,i.createDiv({cls:"stashpad-view-popover-main"}).createSpan({cls:"stashpad-view-popover-label",text:"Calendar mode"}),i.createDiv({cls:"stashpad-view-popover-desc",text:"Use calendar boundaries (start of today/week/month/year). Off = rolling windows back from now."}),i.onclick=n=>{n.target!==s&&(n.preventDefault(),s.checked=!s.checked),this.timeFilterCalendar=s.checked,this.persistFocus(),this.refreshList()};for(let n of Ki){let o=t.createDiv({cls:"stashpad-sort-popover-row"});this.timeFilter===n.key&&o.addClass("is-active");let r=this.timeFilterCalendar?n.calLong:n.rollLong;o.createSpan({cls:"stashpad-sort-popover-label",text:r}),o.onclick=a=>{a.preventDefault(),a.stopPropagation(),e(),this.timeFilter!==n.key&&this.setTimeFilter(n.key)}}}populateColorMenuBody(t,e,i){let s=(n,o,r)=>{let a=t.createDiv({cls:"stashpad-color-filter-popover-row"}),c=a.createSpan({cls:"stashpad-color-filter-swatch"});o?c.style.background=o:c.addClass("is-empty");let l=a.createSpan({cls:"stashpad-color-filter-popover-label"});l.setText(n),o&&(l.style.color=o),a.onclick=p=>{p.preventDefault(),p.stopPropagation(),r(),i()}};s("All colors",null,()=>this.setColorFilter(null));for(let n of e){let o=this.plugin.getColorAlias(this.noteFolder,n.hex),r=o?`${o} (${n.count})`:`${n.hex} (${n.count})`;s(r,n.hex,()=>this.setColorFilter(n.hex))}}populateTagMenuBody(t,e){let i=this.collectFolderTags(),s=(n,o)=>{let r=t.createDiv({cls:"stashpad-color-filter-popover-row"});r.createSpan({cls:"stashpad-color-filter-swatch is-empty"}),r.createSpan({cls:"stashpad-color-filter-popover-label"}).setText(n),(this.tagFilter??"")===(o??"")&&r.addClass("is-active"),r.onclick=l=>{l.preventDefault(),l.stopPropagation(),this.setTagFilter(o),e()}};s(i.length===0?"No tags":"All tags",null);for(let n of i)s(`${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(i=>i.id));for(let i of[...this.selection])e.has(i)||this.selection.delete(i);if(this.firstSelectedId&&!e.has(this.firstSelectedId)&&(this.firstSelectedId=null),this.lastSelected&&!e.has(this.lastSelected)&&(this.lastSelected=null),this.selection.size>0){let i=t.findIndex(s=>this.selection.has(s.id));this.cursorIdx=i>=0?i: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"}),i=e.createEl("button",{cls:"stashpad-tiny-nav-btn"});jt(i,"arrow-left","\u2039"),i.title="Back (up to parent)",this.navBackStack.length>0||this.focusId!==G||i.addClass("is-disabled"),i.title=this.navBackStack.length>0?"Back":this.focusId!==G?"Back (up to parent)":"No back history",i.onclick=()=>this.navigateBack();let n=e.createEl("button",{cls:"stashpad-tiny-nav-btn"});jt(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 o=this.tree.get(this.focusId)??this.tree.getRoot(),r=(this.noteFolder.split("/").pop()||this.noteFolder).trim(),a=this.focusId===G?r:`${r} / ${this.titleForNode(o).trim()}`,c=e.createEl("button",{cls:"stashpad-tiny-title stashpad-folder-btn"}),l=c.createSpan({cls:"stashpad-tiny-title-icon stashpad-btn-icon"});(0,q.setIcon)(l,"folder"),c.createSpan({cls:"stashpad-tiny-title-text stashpad-btn-text",text:a}),c.title=`${this.noteFolder}${this.focusId!==G?` / ${this.titleForNode(o).trim()}`:""} +Click to switch / create folder.`,c.onclick=u=>{u.preventDefault(),this.plugin.openFolderPicker()};let p=e.createDiv({cls:"stashpad-tiny-sticky"}),g=p.createEl("input",{type:"checkbox"});if(g.checked=this.tinyAlwaysOnTop,p.createSpan({text:"Sticky"}),g.onchange=()=>{this.tinyAlwaysOnTop=g.checked,this.applyTinyAlwaysOnTop()},!q.Platform.isMobile){let u=e.createEl("button",{cls:"stashpad-tiny-nav-btn stashpad-tiny-opacity-btn"});(0,q.setIcon)(u,"contrast"),u.title="Window transparency",this.tinyOpacity<1&&u.addClass("is-active"),u.onclick=f=>{f.stopPropagation(),this.toggleTinyOpacityPopover(u)}}let h=e.createEl("button",{cls:"stashpad-tiny-expand stashpad-tiny-exit-compact"});(0,q.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 I=e.createEl("button",{cls:"stashpad-tiny-expand"});(0,q.setIcon)(I,"maximize-2"),I.title="Exit tiny mode",I.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 i=e.createEl("input",{type:"range"});i.min="30",i.max="100",i.step="1",i.value=String(Math.round(this.tinyOpacity*100));let s=e.createSpan({cls:"stashpad-tiny-opacity-pct",text:`${i.value}%`});i.addEventListener("input",()=>{let l=Math.min(100,Math.max(30,parseInt(i.value,10)||100));this.tinyOpacity=l/100,s.setText(`${l}%`),this.applyTinyOpacity(),t.toggleClass("is-active",this.tinyOpacity<1)}),i.addEventListener("change",()=>{this.app.workspace.requestSaveLayout()}),this.viewRoot.appendChild(e);let n=t.getBoundingClientRect(),o=this.viewRoot.getBoundingClientRect();e.style.top=`${n.bottom-o.top+4}px`,e.style.left=`${Math.max(4,Math.min(n.left-o.left,o.width-180))}px`;let r=l=>{e.contains(l.target)||l.target===t||t.contains(l.target)||c()},a=l=>{l.key==="Escape"&&c()},c=()=>{e.remove(),this.tinyOpacityPopover=null,document.removeEventListener("mousedown",r,!0),document.removeEventListener("keydown",a,!0)};setTimeout(()=>{document.addEventListener("mousedown",r,!0),document.addEventListener("keydown",a,!0)},0),this.tinyOpacityPopover=e,i.focus()}getOwnElectronWindow(){try{let t=this.containerEl?.ownerDocument?.defaultView??window,s=((t?.require?.("electron")??window.require?.("electron"))?.remote??t?.electron?.remote??t?.["@electron/remote"])?.getCurrentWindow?.()??t?.electronWindow??null;if(!s)try{let n=window.require?.("electron"),o=n?.remote??n?.["@electron/remote"],a=(o?.BrowserWindow??n?.BrowserWindow)?.getAllWindows?.()??[];a.length===1?s=a[0]:a.length>1&&(s=o?.getFocusedWindow?.()??null??a[a.length-1])}catch(n){console.debug("[Stashpad] BrowserWindow.getAllWindows fallback failed",n)}return s||console.debug("[Stashpad] couldn't resolve own electron window"),s??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(i){console.debug("[Stashpad] setOpacity failed",i)}}applyTinyWindow(){let t=this.getOwnElectronWindow();if(t)try{if(this.tinyMode){t.setMinimumSize?.(220,260);let s=100,n=100;try{let o=t.getBounds?.();o&&typeof o.x=="number"&&(s=o.x,n=o.y)}catch{}try{t.setBounds?.({x:s,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),q.Platform.isMacOS??!1){let i=this.containerEl?.ownerDocument?.defaultView?.require?.("electron")??window.require?.("electron"),n=(i?.remote?.screen??i?.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 i=e.createSpan({cls:"stashpad-crumb stashpad-crumb-home"});if(q.Platform.isMobile?((0,q.setIcon)(i,"home"),i.title="Home"):i.setText("Home"),i.onclick=()=>this.navigateTo(G),this.focusId===G){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 p=e.createEl("button",{cls:"stashpad-compact-exit-btn"});(0,q.setIcon)(p,"panel-top"),p.title="Exit compact mode",p.onclick=g=>{g.preventDefault(),this.toggleCompactMode()}}return}let s=28,n=100,o=this.tree.pathTo(this.focusId),r=o.map(l=>{let p=this.titleForNode(l),g=p.length>s?p.slice(0,s-1)+"\u2026":p;return{id:l.id,label:g}}),a=l=>l.reduce((p,g)=>p+g.label.length+3,0);if(a(r)>n&&r.length>2){let l=!1;for(;a(r)>n&&r.length>2;)r.splice(1,1),l||(r.splice(1,0,{id:"__ellipsis__",label:"\u2026",isEllipsis:!0}),l=!0)}for(let l of r)if(e.createSpan({cls:"stashpad-crumb-sep",text:" / "}),l.isEllipsis)e.createSpan({cls:"stashpad-crumb stashpad-crumb-ellipsis",text:l.label}).title=o.map(p=>this.titleForNode(p)).join(" / ");else{let p=l.id,g=e.createSpan({cls:"stashpad-crumb",text:l.label});g.title=l.label,g.onclick=()=>this.navigateTo(p),g.oncontextmenu=h=>{h.preventDefault(),this.openCrumbMenu(h,p)},q.Platform.isMobile&&this.attachLongPress(g,()=>this.openCrumbMenu(null,p))}if(e.querySelector(".stashpad-crumb-home")?.addEventListener("contextmenu",l=>{l.preventDefault(),this.openCrumbMenu(l,G)}),q.Platform.isMobile){let l=e.querySelector(".stashpad-crumb-home");l&&this.attachLongPress(l,()=>this.openCrumbMenu(null,G))}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 l=e.createEl("button",{cls:"stashpad-compact-exit-btn"});(0,q.setIcon)(l,"panel-top"),l.title="Exit compact mode",l.onclick=p=>{p.preventDefault(),this.toggleCompactMode()}}}attachLongPress(t,e){let i=null,s=0,n=0,o=()=>{i!=null&&(window.clearTimeout(i),i=null)};t.addEventListener("touchstart",r=>{let a=r.touches[0];s=a?.clientX??0,n=a?.clientY??0,o(),i=window.setTimeout(()=>{i=null,e()},500)},{passive:!0}),t.addEventListener("touchmove",r=>{let a=r.touches[0];a&&(Math.abs(a.clientX-s)>10||Math.abs(a.clientY-n)>10)&&o()},{passive:!0}),t.addEventListener("touchend",o),t.addEventListener("touchcancel",o)}openCrumbMenu(t,e){let i=this.tree.get(e);if(!i)return;let s=new q.Menu;if(s.addItem(n=>n.setTitle("Navigate here").setIcon("arrow-right-circle").onClick(()=>this.navigateTo(e))),s.addItem(n=>n.setTitle("Open in new Stashpad tab").setIcon("list-tree").onClick(()=>this.cmdOpenInNewStashpadTab(i))),i.file&&s.addItem(n=>n.setTitle("Open in editor (new tab)").setIcon("pencil").onClick(()=>this.cmdOpenInEditor(i))),t&&(t.clientX>0||t.clientY>0))s.showAtMouseEvent(t);else{let o=(t?.target??null)?.getBoundingClientRect();s.showAtPosition({x:o?.left??8,y:(o?.bottom??60)+4})}}renderFocusedHeaderMini(t,e){if(!e.file)return;let i=e.file,s=t.createDiv({cls:"stashpad-focused-mini"});s.dataset.id=e.id,s.createDiv({cls:"stashpad-focused-mini-text"}).setText(this.titleForNode(e).trim());let o=s.createEl("button",{cls:"stashpad-pencil stashpad-focused-mini-pencil"});(0,q.setIcon)(o,"pencil"),o.title="Edit in new tab",o.onclick=r=>{r.stopPropagation(),this.openFileAtEnd(i)}}installFocusedMiniObserver(t){let e=t.querySelector(".stashpad-focused"),i=t.querySelector(".stashpad-focused-mini");!e||!i||(this.focusedMiniObserver&&this.focusedMiniObserver.disconnect(),this.focusedMiniObserver=new IntersectionObserver(s=>{for(let n of s)i.toggleClass("is-visible",!n.isIntersecting)},{root:t,threshold:.05}),this.focusedMiniObserver.observe(e))}renderFocusedHeader(t,e){if(!e.file)return;let i=e.file,s=t.createDiv({cls:"stashpad-focused"}),o=s.createDiv({cls:"stashpad-focused-meta"}).createDiv({cls:"stashpad-focused-meta-top"});o.createSpan({cls:"stashpad-focused-time stashpad-note-time",text:this.formatTime(e.created)}),o.createDiv({cls:"stashpad-focused-grip-spacer"});let r=s.createDiv({cls:"stashpad-focused-body"});r.addEventListener("click",p=>this.handleRenderedClick(p,e));let a=s.createDiv({cls:"stashpad-focused-actions"}),c=a.createEl("button",{cls:"stashpad-pencil stashpad-focused-pencil"});(0,q.setIcon)(c,"pencil"),c.title="Edit in new tab",c.onclick=()=>void this.openFileAtEnd(i);let l=a.createEl("button",{cls:"stashpad-pencil stashpad-focused-dup"});(0,q.setIcon)(l,"copy"),l.title="Open this Stashpad in a new tab (clone)",l.onclick=()=>this.cmdOpenInNewStashpadTab(e),this.renderNoteBody(r,e,{clamp:q.Platform.isMobile,toggleHost:a,toggleAnchor:c})}renderRowBreadcrumb(t,e){let i=this.tree.pathTo(e.id),s=i.findIndex(r=>r.id===this.focusId),n=i.slice(s+1,i.length-1);if(n.length===0)return;let o=t.createDiv({cls:"stashpad-row-breadcrumb"});n.forEach((r,a)=>{let c=o.createSpan({cls:"stashpad-row-breadcrumb-seg",text:this.titleForNode(r)});c.title=`Focus into "${this.titleForNode(r)}"`,c.onclick=l=>{l.stopPropagation(),this.navigateTo(r.id)},a<n.length-1&&o.createSpan({cls:"stashpad-row-breadcrumb-sep",text:" / "})})}actionsForFile(t){return Ei(this.app,t,q.Platform.isMobile)}bulkActionMessage(t){let e=t.nodes.map(r=>`"${this.titleForNode(r).trim()||"(untitled)"}"`),i=t.suffix?` ${t.suffix}`:"",s=t.destination?` ${t.destination}`:"";if(e.length===0)return`${t.verb}${i}${s}`;if(e.length===1)return`${t.verb} ${e[0]}${i}${s}`;let n=t.bulletMax??10,o=e.length<=n?e.map(r=>`\u2022 ${r}`).join(` +`):e.slice(0,n).map(r=>`\u2022 ${r}`).join(` `)+` \u2026+ ${e.length-n} more`;return`${t.verb} ${e.length} notes${i}${s}: -${o}`}titleList(t,e=3){if(!t.length)return"";let i=t.map(n=>this.titleForNode(n).trim()||"(untitled)");return i.length<=e?i.map(n=>`"${n}"`).join(", "):`${i.slice(0,e).map(n=>`"${n}"`).join(", ")}, +${i.length-e} more`}titleForNode(t){if(!t.file)return"Untitled";let i=this.app.metadataCache.getFileCache(t.file)?.headings?.[0]?.heading;return i||t.file.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ")||"Untitled"}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,i){if(!e.file)return;let s=e.file,n=this.tree.getChildren(e.id).length,o=this.selection.has(e.id),a=i===this.cursorIdx,r=this.inListPicker?.activeIdx===i,c=t.createDiv({cls:"stashpad-note"});o&&c.addClass("is-selected"),a&&c.addClass("is-cursor"),a&&this.plugin.settings.autoExpandCursorRow&&c.addClass("is-cursor-expanded"),r&&c.addClass("is-pick-target"),this.isCompleted(e)&&c.addClass("is-completed"),c.dataset.idx=String(i),c.dataset.id=e.id;let l=this.currentViewMode()==="nested";if(c.draggable=l,l&&this.dnd.attachRowDnD(c,e,i),c.addEventListener("click",y=>this.handleRowClick(y,i,e)),c.addEventListener("dblclick",y=>{!this.plugin.settings.doubleClickToFocus||y.target?.closest?.(".internal-link, .tag, a, .stashpad-note-task-checkbox")||(y.preventDefault(),window.getSelection()?.removeAllRanges(),this.navigateTo(e.id))}),this.isTask(e)){c.addClass("is-task");let y=c.createSpan({cls:"stashpad-note-task-checkbox"}),v=this.isCompleted(e);(0,L.setIcon)(y,v?"check-square":"square"),y.title=v?"Mark not done":"Mark done",y.addEventListener("mousedown",k=>k.stopPropagation()),y.addEventListener("dblclick",k=>{k.preventDefault(),k.stopPropagation()}),y.onclick=k=>{k.preventDefault(),k.stopPropagation(),this.toggleCompletedForNode(e)}}let d=c.createDiv({cls:"stashpad-note-meta"}),I=d.createDiv({cls:"stashpad-note-meta-top"});I.createSpan({cls:"stashpad-note-time",text:this.formatTime(e.created)});let g=this.colorForNode(e),p=I.createDiv({cls:"stashpad-note-grip"});if(g&&p.addClass("has-color"),(0,L.setIcon)(p,"grip-vertical"),p.title=g?"Drag to reorder \xB7 right-click to change color":"Drag to reorder",p.draggable=l,l||(p.title=g?"Right-click to change color \xB7 drag disabled in this view mode":"Drag disabled in this view mode"),g&&p.style.setProperty("--stashpad-note-color",g),n>0){let y=d.createSpan({cls:"stashpad-note-enter"});g&&(y.style.color=g),(0,L.setIcon)(y.createSpan({cls:"stashpad-btn-icon"}),"corner-down-right"),y.createSpan({text:` ${n}`}),y.onclick=v=>{v.stopPropagation(),this.navigateTo(e.id)}}if(g)c.addClass("has-color"),c.style.setProperty("--stashpad-note-color",g);else{let y=this.inheritedColorForNode(e);y&&y.depth>0&&(c.addClass("has-inherited-color"),c.style.setProperty("--stashpad-inherited-color",y.hex),c.style.setProperty("--stashpad-inherited-depth",String(y.depth)))}let u=c.createDiv({cls:"stashpad-note-body"});this.currentViewMode()!=="nested"&&this.renderRowBreadcrumb(u,e);let f=u.createDiv({cls:"stashpad-note-body-content"}),B=c.createDiv({cls:"stashpad-note-actions"}),Q=B.createEl("button",{cls:"stashpad-pencil"});(0,L.setIcon)(Q,"pencil"),Q.title="Edit in new tab",Q.onclick=y=>{y.stopPropagation(),this.openFileAtEnd(s)};let E=B.createEl("button",{cls:"stashpad-pencil stashpad-enter-btn"});(0,L.setIcon)(E,"arrow-right"),E.title="Open in Stashpad view",E.onclick=y=>{y.stopPropagation(),this.navigateTo(e.id)},this.renderNoteBody(f,e,{clamp:!0,toggleHost:B,toggleAnchor:Q}),c.oncontextmenu=y=>{y.preventDefault(),this.openNoteMenu(y,e)}}renderNoteBody(t,e,i={clamp:!0}){if(!e.file)return;if(this.bodyRenderer.hasFreshRenderCache(e.file)||!this.bodyRenderer.isArmed()){this.renderNoteBodyNow(t,e,i);return}t.empty();let s=t.createDiv({cls:"stashpad-note-text is-plain is-lazy-placeholder"});s.textContent=this.titleForNode(e),this.bodyRenderer.defer(t,()=>this.renderNoteBodyNow(t,e,i))}renderNoteBodyNow(t,e,i={clamp:!0}){if(!e.file)return;let s=e.file,n=(t.__stashpadRenderToken??0)+1;t.__stashpadRenderToken=n,this.bodyRenderer.getOrComputeRender(s).then(o=>{if(t.__stashpadRenderToken!==n)return;let{text:a,attachments:r,html:c}=o;t.empty();let l=t.createDiv({cls:"stashpad-note-text"}),d=this.expandedNotes.has(e.id);if(i.clamp&&!d&&l.addClass("is-clamped"),this.compactMode||this.tinyMode?(l.addClass("is-plain"),l.textContent=a):l.innerHTML=c,r.length>0&&this.renderAttachmentRail(t,r),this.renderAuthorshipFooter(t,e),!i.clamp)return;let I=this.lastListWidth;if(o.ovW===I&&o.ovV!==void 0&&!d){o.ovV?this.attachExpandToggle(i,t,e,d):l.removeClass("is-clamped");return}requestAnimationFrame(()=>{if(t.closest?.(".stashpad-note.is-cursor-expanded"))return;let g=l.scrollHeight>l.clientHeight+4;if(o.ovW=I,o.ovV=g,!g&&!d){l.removeClass("is-clamped");return}this.attachExpandToggle(i,t,e,d)})})}attachExpandToggle(t,e,i,s){let n=!!t.toggleHost,o=t.toggleHost??e;o.querySelector(".stashpad-expand-toggle")?.remove();let a=o.createEl("button",{cls:"stashpad-expand-toggle"});a.title=s?"Show less":"Show more",n||L.Platform.isMobile?((0,L.setIcon)(a,s?"chevron-up":"chevron-down"),a.addClass("is-icon"),n&&a.addClass("is-inline")):a.setText(s?"Show less":"Show more"),t.toggleAnchor&&t.toggleAnchor.parentElement===o&&o.insertBefore(a,t.toggleAnchor),a.onclick=r=>{r.stopPropagation(),this.expandedNotes.has(i.id)?this.expandedNotes.delete(i.id):this.expandedNotes.add(i.id),e.empty(),this.renderNoteBody(e,i,t)}}renderAttachmentRail(t,e){let i=t.createDiv({cls:"stashpad-rail"});for(let s of e){let n=this.app.metadataCache.getFirstLinkpathDest(s,""),o=(s.split(".").pop()??"").toLowerCase(),a=i.createDiv({cls:"stashpad-att"});if(a.title=s,n&&sa.has(o)){let r=a.createEl("img",{cls:"stashpad-att-img"});r.src=this.app.vault.getResourcePath(n),r.alt=s}else{a.createDiv({cls:"stashpad-att-ext",text:o.toUpperCase()||"?"});let r=(s.split("/").pop()??s).replace(/\.[^.]+$/,"");a.createDiv({cls:"stashpad-att-name",text:r})}a.onclick=r=>{r.stopPropagation(),n&&this.app.workspace.getLeaf("tab").openFile(n)}}}renderComposer(t){let e=Bt(),i=this.modeEnterSubmits,s=this.modeSplit??e.splitOnLines,n=null,o=t.createDiv({cls:"stashpad-composer"}),a=o.createDiv({cls:"stashpad-composer-input-wrap"}),r=a.createEl("textarea",{cls:"stashpad-composer-input",attr:{rows:"2",placeholder:this.composerPlaceholder(i,s)}});r.value=this.composerDraft;let c=null,l=()=>{c&&(c.remove(),c=null)};n!==null&&n.length>0&&(c=a.createEl("button",{cls:"stashpad-composer-clear"}),(0,L.setIcon)(c,"x"),c.title="Clear restored draft",c.onmousedown=J=>J.preventDefault(),c.onclick=J=>{J.preventDefault(),r.value="",this.composerDraft="",this.saveDraft(""),l(),r.focus()},requestAnimationFrame(()=>{r.focus(),r.setSelectionRange(0,r.value.length)})),this.debouncedSaveDraft||(this.debouncedSaveDraft=(0,L.debounce)(J=>{this.saveDraft(J)},250)),r.addEventListener("input",()=>{this.composerDraft=r.value,this.debouncedSaveDraft(r.value),l()}),r.addEventListener("blur",()=>{this.saveDraft(r.value)});let d=null,I=()=>{d||(d=new L.Scope(this.app.scope),d.register([],"Escape",()=>(r.blur(),this.viewRoot?.focus({preventScroll:!0}),!1)),d.register(["Mod"],"z",()=>!0),d.register(["Mod","Shift"],"z",()=>!0),this.app.keymap?.pushScope(d))},g=()=>{if(d){try{this.app.keymap?.popScope(d)}catch{}d=null}};if(r.addEventListener("focus",I),r.addEventListener("blur",g),document.activeElement===r&&I(),L.Platform.isMobile){let J=()=>{this.keyboardTransitionUntil=Date.now()+600};r.addEventListener("focus",()=>{document.body.classList.add("stashpad-keyboard-open"),J()}),r.addEventListener("blur",()=>{document.body.classList.remove("stashpad-keyboard-open"),J()})}this.composerInputEl=r,this.composerAutocomplete&&this.composerAutocomplete.detach(),this.composerAutocomplete=new Ce(this.app,r),this.composerAutocomplete.attach();let p=async J=>{let q="";for(let j of J){let H=await this.importAttachment(j);if(!H)continue;let N=r.value+q,$=N&&!N.endsWith(` +${o}`}titleList(t,e=3){if(!t.length)return"";let i=t.map(n=>this.titleForNode(n).trim()||"(untitled)");return i.length<=e?i.map(n=>`"${n}"`).join(", "):`${i.slice(0,e).map(n=>`"${n}"`).join(", ")}, +${i.length-e} more`}titleForNode(t){if(!t.file)return"Untitled";let i=this.app.metadataCache.getFileCache(t.file)?.headings?.[0]?.heading;return i||t.file.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ")||"Untitled"}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,i){if(!e.file)return;let s=e.file,n=this.tree.getChildren(e.id).length,o=this.selection.has(e.id),r=i===this.cursorIdx,a=this.inListPicker?.activeIdx===i,c=t.createDiv({cls:"stashpad-note"});o&&c.addClass("is-selected"),r&&c.addClass("is-cursor"),r&&this.plugin.settings.autoExpandCursorRow&&c.addClass("is-cursor-expanded"),a&&c.addClass("is-pick-target"),this.isCompleted(e)&&c.addClass("is-completed"),c.dataset.idx=String(i),c.dataset.id=e.id;let l=this.currentViewMode()==="nested";c.draggable=l,l&&this.dnd.attachRowDnD(c,e,i),c.addEventListener("click",y=>this.handleRowClick(y,i,e)),c.addEventListener("dblclick",y=>{!this.plugin.settings.doubleClickToFocus||y.target?.closest?.(".internal-link, .tag, a, .stashpad-note-task-checkbox")||(y.preventDefault(),window.getSelection()?.removeAllRanges(),this.navigateTo(e.id))}),this.isTask(e)&&(c.addClass("is-task"),q.Platform.isMobile||this.addTaskCheckbox(c,e));let p=c.createDiv({cls:"stashpad-note-meta"}),g=p.createDiv({cls:"stashpad-note-meta-top"});g.createSpan({cls:"stashpad-note-time",text:this.formatTime(e.created)});let h=this.colorForNode(e),I=g.createDiv({cls:"stashpad-note-grip"});h&&I.addClass("has-color"),(0,q.setIcon)(I,"grip-vertical"),I.title=h?"Drag to reorder \xB7 right-click to change color":"Drag to reorder",I.draggable=l,l||(I.title=h?"Right-click to change color \xB7 drag disabled in this view mode":"Drag disabled in this view mode"),h&&I.style.setProperty("--stashpad-note-color",h);let u=this.isTask(e)&&q.Platform.isMobile;if(n>0||u){let y=p.createDiv({cls:"stashpad-note-meta-bottom"});if(u&&this.addTaskCheckbox(y,e),n>0){let w=y.createSpan({cls:"stashpad-note-enter"});h&&(w.style.color=h),(0,q.setIcon)(w.createSpan({cls:"stashpad-btn-icon"}),"corner-down-right"),w.createSpan({text:` ${n}`}),w.onclick=v=>{v.stopPropagation(),this.navigateTo(e.id)}}}if(h)c.addClass("has-color"),c.style.setProperty("--stashpad-note-color",h);else{let y=this.inheritedColorForNode(e);y&&y.depth>0&&(c.addClass("has-inherited-color"),c.style.setProperty("--stashpad-inherited-color",y.hex),c.style.setProperty("--stashpad-inherited-depth",String(y.depth)))}let f=c.createDiv({cls:"stashpad-note-body"});this.currentViewMode()!=="nested"&&this.renderRowBreadcrumb(f,e);let C=f.createDiv({cls:"stashpad-note-body-content"}),m=c.createDiv({cls:"stashpad-note-actions"}),E;if(q.Platform.isMobile){let y=m.createEl("button",{cls:"stashpad-pencil stashpad-note-more"});(0,q.setIcon)(y,"ellipsis-vertical"),y.title="Actions",y.onclick=w=>{w.stopPropagation(),this.openNoteMenu(w,e)},E=y}else{let y=m.createEl("button",{cls:"stashpad-pencil"});(0,q.setIcon)(y,"pencil"),y.title="Edit in new tab",y.onclick=v=>{v.stopPropagation(),this.openFileAtEnd(s)};let w=m.createEl("button",{cls:"stashpad-pencil stashpad-enter-btn"});(0,q.setIcon)(w,"arrow-right"),w.title="Open in Stashpad view",w.onclick=v=>{v.stopPropagation(),this.navigateTo(e.id)},E=y}this.renderNoteBody(C,e,{clamp:!0,toggleHost:m,toggleAnchor:E}),c.oncontextmenu=y=>{y.preventDefault(),this.openNoteMenu(y,e)}}addTaskCheckbox(t,e){let i=t.createSpan({cls:"stashpad-note-task-checkbox"}),s=this.isCompleted(e);(0,q.setIcon)(i,s?"check-square":"square"),i.title=s?"Mark not done":"Mark done",i.addEventListener("mousedown",n=>n.stopPropagation()),i.addEventListener("dblclick",n=>{n.preventDefault(),n.stopPropagation()}),i.onclick=n=>{n.preventDefault(),n.stopPropagation(),this.toggleCompletedForNode(e)}}renderNoteBody(t,e,i={clamp:!0}){if(!e.file)return;if(this.bodyRenderer.hasFreshRenderCache(e.file)||!this.bodyRenderer.isArmed()){this.renderNoteBodyNow(t,e,i);return}t.empty();let s=t.createDiv({cls:"stashpad-note-text is-plain is-lazy-placeholder"});s.textContent=this.titleForNode(e),this.bodyRenderer.defer(t,()=>this.renderNoteBodyNow(t,e,i))}renderNoteBodyNow(t,e,i={clamp:!0}){if(!e.file)return;let s=e.file,n=(t.__stashpadRenderToken??0)+1;t.__stashpadRenderToken=n,this.bodyRenderer.getOrComputeRender(s).then(o=>{if(t.__stashpadRenderToken!==n)return;let{text:r,attachments:a,html:c}=o;t.empty();let l=t.createDiv({cls:"stashpad-note-text"}),p=this.expandedNotes.has(e.id);if(i.clamp&&!p&&l.addClass("is-clamped"),this.compactMode||this.tinyMode?(l.addClass("is-plain"),l.textContent=r):l.innerHTML=c,a.length>0&&this.renderAttachmentRail(t,a),this.renderAuthorshipFooter(t,e),!i.clamp)return;let g=this.lastListWidth;if(o.ovW===g&&o.ovV!==void 0&&!p){o.ovV?this.attachExpandToggle(i,t,e,p):l.removeClass("is-clamped");return}requestAnimationFrame(()=>{if(t.closest?.(".stashpad-note.is-cursor-expanded"))return;let h=l.scrollHeight>l.clientHeight+4;if(o.ovW=g,o.ovV=h,!h&&!p){l.removeClass("is-clamped");return}this.attachExpandToggle(i,t,e,p)})})}attachExpandToggle(t,e,i,s){let n=!!t.toggleHost,o=t.toggleHost??e;o.querySelector(".stashpad-expand-toggle")?.remove();let r=o.createEl("button",{cls:"stashpad-expand-toggle"});r.title=s?"Show less":"Show more",n||q.Platform.isMobile?((0,q.setIcon)(r,s?"chevron-up":"chevron-down"),r.addClass("is-icon"),n&&r.addClass("is-inline")):r.setText(s?"Show less":"Show more"),t.toggleAnchor&&t.toggleAnchor.parentElement===o&&o.insertBefore(r,t.toggleAnchor),r.onclick=a=>{a.stopPropagation(),this.expandedNotes.has(i.id)?this.expandedNotes.delete(i.id):this.expandedNotes.add(i.id),e.empty(),this.renderNoteBody(e,i,t)}}renderAttachmentRail(t,e){let i=t.createDiv({cls:"stashpad-rail"});for(let s of e){let n=this.app.metadataCache.getFirstLinkpathDest(s,""),o=(s.split(".").pop()??"").toLowerCase(),r=i.createDiv({cls:"stashpad-att"});if(r.title=s,n&&Ea.has(o)){let a=r.createEl("img",{cls:"stashpad-att-img"});a.src=this.app.vault.getResourcePath(n),a.alt=s}else{r.createDiv({cls:"stashpad-att-ext",text:o.toUpperCase()||"?"});let a=(s.split("/").pop()??s).replace(/\.[^.]+$/,"");r.createDiv({cls:"stashpad-att-name",text:a})}r.onclick=a=>{a.stopPropagation(),n&&this.app.workspace.getLeaf("tab").openFile(n)}}}renderComposer(t){let e=ft(),i=this.modeEnterSubmits,s=this.modeSplit??e.splitOnLines,n=null,o=t.createDiv({cls:"stashpad-composer"}),r=o.createDiv({cls:"stashpad-composer-input-wrap"}),a=r.createEl("textarea",{cls:"stashpad-composer-input",attr:{rows:"2",placeholder:this.composerPlaceholder(i,s)}});a.value=this.composerDraft;let c=null,l=()=>{c&&(c.remove(),c=null)};n!==null&&n.length>0&&(c=r.createEl("button",{cls:"stashpad-composer-clear"}),(0,q.setIcon)(c,"x"),c.title="Clear restored draft",c.onmousedown=T=>T.preventDefault(),c.onclick=T=>{T.preventDefault(),a.value="",this.composerDraft="",this.saveDraft(""),l(),a.focus()},requestAnimationFrame(()=>{a.focus(),a.setSelectionRange(0,a.value.length)})),this.debouncedSaveDraft||(this.debouncedSaveDraft=(0,q.debounce)(T=>{this.saveDraft(T)},250)),a.addEventListener("input",()=>{this.composerDraft=a.value,this.debouncedSaveDraft(a.value),l()}),a.addEventListener("blur",()=>{this.saveDraft(a.value)});let p=null,g=()=>{p||(p=new q.Scope(this.app.scope),p.register([],"Escape",()=>(a.blur(),this.viewRoot?.focus({preventScroll:!0}),!1)),p.register(["Mod"],"z",()=>!0),p.register(["Mod","Shift"],"z",()=>!0),this.app.keymap?.pushScope(p))},h=()=>{if(p){try{this.app.keymap?.popScope(p)}catch{}p=null}};if(a.addEventListener("focus",g),a.addEventListener("blur",h),document.activeElement===a&&g(),q.Platform.isMobile){let T=()=>{this.keyboardTransitionUntil=Date.now()+600};a.addEventListener("focus",()=>{document.body.classList.add("stashpad-keyboard-open"),T()}),a.addEventListener("blur",()=>{document.body.classList.remove("stashpad-keyboard-open"),T(),q.Platform.isMobile&&this.cursorIdx>=0&&setTimeout(()=>this.revealCursorRow(),350)})}this.composerInputEl=a,this.composerAutocomplete&&this.composerAutocomplete.detach(),this.composerAutocomplete=new Ee(this.app,a),this.composerAutocomplete.attach();let I=async T=>{let J="";for(let Z of T){let U=await this.importAttachment(Z);if(!U)continue;let N=a.value+J,j=N&&!N.endsWith(` `)?` -`:"";q+=`${$}${H} -`}q&&(r.value=r.value+q,this.composerDraft=r.value,this.saveDraft(r.value),r.focus(),r.setSelectionRange(r.value.length,r.value.length))};r.addEventListener("dragover",J=>{if(!(!J.dataTransfer||!Array.from(J.dataTransfer.types).includes("Files"))){J.preventDefault(),J.stopPropagation();try{J.dataTransfer.dropEffect="copy"}catch{}}}),r.addEventListener("drop",J=>{let q=Array.from(J.dataTransfer?.files??[]);q.length!==0&&(J.preventDefault(),J.stopPropagation(),p(q))}),r.addEventListener("paste",J=>{let q=[],j=J.clipboardData;if(j){for(let H of Array.from(j.files??[]))q.push(H);if(q.length===0){for(let H of Array.from(j.items??[]))if(H.kind==="file"){let N=H.getAsFile();N&&q.push(N)}}q.length!==0&&(J.preventDefault(),J.stopPropagation(),p(q))}});let u=o.createEl("input",{cls:"stashpad-composer-file-input",type:"file",attr:{multiple:"true"}});u.style.display="none";let f=o.createDiv({cls:"stashpad-composer-btn-rail"}),B=f.createDiv({cls:"stashpad-composer-btn-group"}),Q=B.createEl("button",{cls:"stashpad-composer-btn"});(0,L.setIcon)(Q,"list-end"),Q.title=s?"Split on newlines: ON (Mod+/)":"Split on newlines (Mod+/)",s&&Q.addClass("is-active"),Q.onmousedown=J=>J.preventDefault(),Q.onclick=J=>{J.preventDefault(),this.toggleSplit()};let E=B.createEl("button",{cls:"stashpad-composer-btn"});(0,L.setIcon)(E,"map-pin"),this.nextDestination&&E.createSpan({text:` ${this.destinationLabel()}`,cls:"stashpad-btn-text"}),E.title="Set destination (Mod+D)",this.nextDestination&&E.addClass("is-active"),E.onmousedown=J=>J.preventDefault(),E.onclick=J=>{J.preventDefault();let q=document.activeElement===r;if(this.openDestinationPicker(),q){let j=()=>{r.focus()};setTimeout(j,50),setTimeout(j,250)}};let y=B.createEl("button",{cls:"stashpad-composer-btn"});(0,L.setIcon)(y,i?"corner-down-left":"arrow-big-down-dash"),y.title=i?"Enter sends (click to switch to Shift+Enter)":"Shift+Enter sends (click to switch to Enter)",y.onmousedown=J=>J.preventDefault(),y.onclick=J=>{J.preventDefault(),this.modeEnterSubmits=!i,this.render(),this.composerInputEl?.focus()};let v=J=>{let q=r.value&&!r.value.endsWith(` +`:"";J+=`${j}${U} +`}J&&(a.value=a.value+J,this.composerDraft=a.value,this.saveDraft(a.value),a.focus(),a.setSelectionRange(a.value.length,a.value.length))};a.addEventListener("dragover",T=>{if(!(!T.dataTransfer||!Array.from(T.dataTransfer.types).includes("Files"))){T.preventDefault(),T.stopPropagation();try{T.dataTransfer.dropEffect="copy"}catch{}}}),a.addEventListener("drop",T=>{let J=Array.from(T.dataTransfer?.files??[]);J.length!==0&&(T.preventDefault(),T.stopPropagation(),I(J))}),a.addEventListener("paste",T=>{let J=[],Z=T.clipboardData;if(Z){for(let U of Array.from(Z.files??[]))J.push(U);if(J.length===0){for(let U of Array.from(Z.items??[]))if(U.kind==="file"){let N=U.getAsFile();N&&J.push(N)}}J.length!==0&&(T.preventDefault(),T.stopPropagation(),I(J))}});let u=o.createEl("input",{cls:"stashpad-composer-file-input",type:"file",attr:{multiple:"true"}});u.style.display="none";let f=o.createDiv({cls:"stashpad-composer-btn-rail"}),C=f.createDiv({cls:"stashpad-composer-btn-group"}),m=C.createEl("button",{cls:"stashpad-composer-btn"});(0,q.setIcon)(m,"list-end"),m.title=s?"Split on newlines: ON (Mod+/)":"Split on newlines (Mod+/)",s&&m.addClass("is-active"),m.onmousedown=T=>T.preventDefault(),m.onclick=T=>{T.preventDefault(),this.toggleSplit()};let E=C.createEl("button",{cls:"stashpad-composer-btn"});(0,q.setIcon)(E,"map-pin"),this.nextDestination&&E.createSpan({text:` ${this.destinationLabel()}`,cls:"stashpad-btn-text"}),E.title="Set destination (Mod+D)",this.nextDestination&&E.addClass("is-active"),E.onmousedown=T=>T.preventDefault(),E.onclick=T=>{T.preventDefault();let J=document.activeElement===a;this.openDestinationPicker(J)};let y=C.createEl("button",{cls:"stashpad-composer-btn"});(0,q.setIcon)(y,i?"corner-down-left":"arrow-big-down-dash"),y.title=i?"Enter sends (click to switch to Shift+Enter)":"Shift+Enter sends (click to switch to Enter)",y.onmousedown=T=>T.preventDefault(),y.onclick=T=>{T.preventDefault(),this.modeEnterSubmits=!i,this.render(),this.composerInputEl?.focus()};let w=T=>{let J=a.value&&!a.value.endsWith(` `)?` -`:"";r.value+=`${q}${J} -`,this.composerDraft=r.value},k=B.createEl("button",{cls:"stashpad-composer-btn"});(0,L.setIcon)(k,"paperclip"),k.title="Attach files",k.onmousedown=J=>J.preventDefault(),k.onclick=J=>{J.preventDefault();let q=document.activeElement===r;if(u.click(),q){let j=()=>{r.focus()};setTimeout(j,100),setTimeout(j,500)}},u.addEventListener("change",async()=>{let J=Array.from(u.files??[]);u.value="";for(let q of J){let j=await this.importAttachment(q);j&&v(j)}r.focus()});let b=f.createEl("button",{cls:"stashpad-composer-btn stashpad-composer-rail-toggle"});(0,L.setIcon)(b,"chevron-left"),b.title="Show more composer options",f.insertBefore(b,B);let R=J=>{f.toggleClass("is-expanded",J),b.title=J?"Hide options":"Show more composer options",(0,L.setIcon)(b,J?"chevron-right":"chevron-left")};b.onmousedown=J=>J.preventDefault(),b.onclick=J=>{J.preventDefault(),R(!f.hasClass("is-expanded"))},R(!1);let w=()=>o.clientWidth<700,D=()=>{let J=w();o.toggleClass("is-narrow",J),R(!J)};D(),requestAnimationFrame(D);let m=new ResizeObserver(D);m.observe(o),this.composerNarrowObserver?.disconnect(),this.composerNarrowObserver=m;let M=f.createEl("button",{cls:"stashpad-composer-btn stashpad-composer-send"});M.title="Send (Enter)",(0,L.setIcon)(M,"arrow-up");let _=async()=>{let J=r.value.trim();if(!J)return;r.value="",this.composerDraft="";try{await this.saveDraft("")}catch{}try{await this.recordLastSubmitted(J)}catch{}let q=this.modeSplit??Bt().splitOnLines,j=this.nextDestination,H=this.nextDestinationFolder,N=!!H&&H!==this.noteFolder;this.nextDestination=null,this.nextDestinationFolder=null,this.nextDestinationLabel=null,this.autoSelectNewest=!N,this.scrollToBottomOnNextRender=!N;let $=N?{targetFolder:H}:void 0;if(q)for(let V of J.split(/\r?\n/)){let z=V.trim();z&&await this.createNoteUnder(z,j,$)}else await this.createNoteUnder(J,j,$);Bt().autofocusComposerAfterSend&&(this.focusComposerOnNextRender=!0,N&&this.composerInputEl?.focus())};M.onclick=()=>void _(),r.addEventListener("keydown",J=>{let q=this.modeEnterSubmits;if(J.key==="Escape"){J.preventDefault(),J.stopPropagation(),r.blur(),this.viewRoot.focus({preventScroll:!0});return}if(J.key==="ArrowUp"&&r.selectionStart===0&&r.selectionEnd===0){if(J.preventDefault(),r.blur(),this.viewRoot.focus({preventScroll:!0}),this.currentChildren.length>0){let j=this.lastCursorByFocus.get(this.focusId)??this.lastSelected,H=j?this.currentChildren.findIndex(N=>N.id===j):-1;this.cursorIdx=H>=0?H:this.currentChildren.length-1,this.selectCursor(!1)}return}J.key==="Enter"&&!J.isComposing&&(q?!J.shiftKey:J.shiftKey)&&(J.preventDefault(),J.stopPropagation(),J.stopImmediatePropagation(),_())}),t.createDiv({cls:"stashpad-composer-help"}).setText(this.composerHelperText(i,s))}composerPlaceholder(t,e){return L.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 i=t?"Enter":"Shift+Enter",s=t?"Shift+Enter":"Enter",n=Bt().bindings,o=d=>{let I=n[d];return I.primary&&I.secondary?I.preferRight?I.secondary:I.primary:I.primary||I.secondary},a=Di(o("toggleSplit")),r=Di(o("pickDestination")),c=Di(o("search")),l=this.nextDestination?` \u2022 destination: ${this.destinationLabel()}`:"";return`${i} sends \xB7 ${s} newline \xB7 ${a} split: ${e?"ON":"off"} \xB7 ${r} destination \xB7 ${c} search${l}`}destinationLabel(){if(!this.nextDestination)return"current";if(this.nextDestinationFolder)return this.nextDestinationLabel??this.nextDestinationFolder;if(this.nextDestination===G)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(G),e.createEl("button",{text:"Back"}).onclick=()=>this.navigateUp(),e.createEl("button",{text:"Bookmarks"}).onclick=()=>this.openBookmarks()}handleRenderedClick(t,e){let i=t.target,s=i?.closest?.(".tag");if(s){t.preventDefault(),t.stopPropagation();let a=(s.getAttribute("href")||s.textContent||"").replace(/^#/,"").trim();if(a){let r=this.app.internalPlugins?.plugins?.["global-search"],c=r?.instance?.openGlobalSearch?.bind(r.instance);c&&c(`tag:#${a}`)}return}let n=i?.closest?.(".internal-link");if(n){t.preventDefault(),t.stopPropagation();let o=n.getAttribute("data-href")||n.getAttribute("href");if(o){let a=e.file?.path||"";this.app.workspace.openLinkText(o,a,!0)}}}handleRowClick(t,e,i){let s=t.target,n=s?.closest?.(".tag");if(n){t.preventDefault(),t.stopPropagation();let c=(n.getAttribute("href")||n.textContent||"").replace(/^#/,"").trim();if(c){let l=this.app.internalPlugins?.plugins?.["global-search"],d=l?.instance?.openGlobalSearch?.bind(l.instance);d&&d(`tag:#${c}`)}return}let o=s?.closest?.(".internal-link");if(o){t.preventDefault(),t.stopPropagation();let r=o.getAttribute("data-href")||o.getAttribute("href");if(r){let c=i.file?.path||"";this.app.workspace.openLinkText(r,c,!0)}return}if(s?.tagName==="A"&&s.href)return;if(t.stopPropagation(),this.inListPicker){this.inListPicker.activeIdx=e,this.commitInListPicker();return}let a=this.selection.size===0;if(t.shiftKey&&this.lastSelected){this.cursorIdx=e;let r=this.currentChildren.findIndex(c=>c.id===this.lastSelected);if(a&&(this.firstSelectedId=this.lastSelected),r!==-1){let[c,l]=r<e?[r,e]:[e,r];for(let d=c;d<=l;d++)this.selection.add(this.currentChildren[d].id)}else this.selection.add(i.id)}else if(t.metaKey||t.ctrlKey)if(this.selection.has(i.id))if(this.selection.delete(i.id),this.firstSelectedId===i.id&&(this.firstSelectedId=null),this.lastSelected===i.id&&(this.lastSelected=this.selection.size>0?[...this.selection][this.selection.size-1]:null),this.selection.size===0)this.cursorIdx=-1;else{let r=this.lastSelected??[...this.selection][this.selection.size-1],c=r?this.currentChildren.findIndex(l=>l.id===r):-1;c>=0&&(this.cursorIdx=c)}else this.cursorIdx=e,a&&(this.firstSelectedId=i.id),this.selection.add(i.id);else this.mobileSelectMode?(this.cursorIdx=e,this.selection.has(i.id)?(this.selection.delete(i.id),this.firstSelectedId===i.id&&(this.firstSelectedId=null)):this.selection.add(i.id)):(this.cursorIdx=e,this.selection.clear(),this.selection.add(i.id),this.firstSelectedId=i.id,this.lastSelected=i.id);this.selection.size===0&&(this.firstSelectedId=null),this.selection.has(i.id)&&(this.lastSelected=i.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 i=this.listEl,s=i.getBoundingClientRect(),n=e.getBoundingClientRect(),o=4;n.top<s.top+o?i.scrollTop+=n.top-s.top-o:n.bottom>s.bottom-o&&(i.scrollTop+=n.bottom-s.bottom+o)};t(),requestAnimationFrame(t),setTimeout(t,60),setTimeout(t,200)}jumpToTop(){this.currentChildren.length!==0&&(this.cursorIdx=0,this.selectCursor(!1))}jumpToBottom(){this.currentChildren.length!==0&&(this.cursorIdx=this.currentChildren.length-1,this.selectCursor(!1))}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 i=this.firstSelectedId??e.id,s=this.currentChildren.findIndex(n=>n.id===i);if(s===-1)this.selection.add(e.id),this.firstSelectedId=e.id;else{let[n,o]=s<this.cursorIdx?[s,this.cursorIdx]:[this.cursorIdx,s];this.selection.clear();for(let a=n;a<=o;a++)this.selection.add(this.currentChildren[a].id);this.firstSelectedId=i}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(s=>{let n=Number(s.dataset.idx),o=s.dataset.id??"",a=n===this.cursorIdx;s.classList.toggle("is-cursor",a),s.classList.toggle("is-selected",this.selection.has(o)),s.classList.toggle("is-cursor-expanded",t&&a),s.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 i=e.getBoundingClientRect(),s=this.listEl.getBoundingClientRect();(i.top<s.top||i.bottom>s.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??Bt().splitOnLines;this.modeSplit=!t,this.render(),this.composerInputEl?.focus()}openDestinationPicker(){new Jt(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 i=t.crossFolder.split("/").pop()||t.crossFolder,s=e===G?"Home":(t.crossFile?.basename??"note").replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ");this.nextDestinationLabel=`${i} \u25B8 ${s}`,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),i=new Map;for(let n of this.app.vault.getMarkdownFiles()){let o=n.parent?.path?.replace(/\/+$/,"")??"";if(!e.includes(o))continue;this.app.metadataCache.getFileCache(n)?.frontmatter?.id===G&&i.set(o,n)}return[...e.map(n=>({file:i.get(n),folder:n,id:G,title:`Home \u2014 ${n.split("/").pop()||n}`,body:""})),...t]}openSearchInParentModal(){let t=this.focusId,e=s=>{if(s===t)return!0;let n=new Set,o=this.tree.get(s);for(;o&&o.id!==G&&!n.has(o.id);){if(n.add(o.id),o.parent===t||o.id===t)return!0;if(!o.parent)return!1;o=this.tree.get(o.parent)}return t===G},i=new Proxy(this.tree,{get:(s,n)=>n==="getRoot"?()=>s.get(t)??s.getRoot():n==="getChildren"?o=>s.getChildren(o):s[n]});new Jt(this.app,i,s=>this.titleForNode(s),{mode:"search",placeholder:`Search in "${this.titleForNode(this.tree.get(t)??this.tree.getRoot()).trim()}"\u2026`,allowCreate:!1,onPick:s=>{s.node&&e(s.node.id)?this.navigateTo(s.node.id):s.node&&this.navigateTo(s.node.id)}}).open()}openSearchModal(){if(this.openSearchInstance){let i=this.openSearchInstance.inputEl;i&&(i.focus(),i.select());return}let t=new Jt(this.app,this.tree,i=>this.titleForNode(i),{mode:"search",placeholder:"Search Stashpad notes\u2026",allowCreate:!0,onCreate:async i=>{let s=i.trim();s&&new Jt(this.app,this.tree,n=>this.titleForNode(n),{mode:"pick",placeholder:`Create "${s}" under which note?`,allowCreate:!1,crossFolderNotes:()=>this.collectCrossFolderDestinations(),folderResults:()=>this.plugin.discoverStashpadFolders().filter(n=>n!==this.noteFolder),localFolder:this.noteFolder,onPick:async n=>{let o=n.crossFolder?n.id.replace(/^cross:/,""):n.node?.id,a=n.crossFolder??this.noteFolder;if(!o)return;let r=(this.plugin.settings.folder||"Stashpad").trim().replace(/^\/+|\/+$/g,"")||"Stashpad",c=this.app.workspace,l=c.getLeaf("tab");await l.setViewState({type:ut,active:!0,state:{focusId:o,folderOverride:a===r?null:a}}),c.revealLeaf(l);let d=l.view;if(d&&typeof d.createNoteUnder=="function"){let I=await d.createNoteUnder(s,o);I&&typeof d.navigateTo=="function"&&d.navigateTo(I)}}}).open()},onPick:i=>{if(i.kind==="folder-open"&&i.folder){this.openFolderInNewTab(i.folder);return}if(i.crossFolder&&i.crossFile){let s=i.id.replace(/^cross:/,"");this.switchToFolderAndFocus(i.crossFolder,s);return}i.node&&this.navigateTo(i.node.id)},crossFolderNotes:()=>this.collectCrossFolderDestinations(),folderResults:()=>this.plugin.discoverStashpadFolders().filter(i=>i!==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 i=new Set(e),s=new Map;for(let n of this.app.vault.getMarkdownFiles()){let o=n.parent?.path?.replace(/\/+$/,"")??"";if(!i.has(o))continue;let a=s.get(o);a||(a=[],s.set(o,a)),a.push(n)}for(let n of e){let o=s.get(n)??[],a=new Map;for(let r of o){let c=this.app.metadataCache.getFileCache(r)?.frontmatter;typeof c?.id=="string"&&a.set(c.id,r)}for(let r of o){let c=this.app.metadataCache.getFileCache(r)?.frontmatter,l=typeof c?.id=="string"?c.id:"";if(!l||l===G)continue;let d=r.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," "),I,g=c?.parent??null;if(g&&g!==G){let p=a.get(g);p&&(I=p.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," "))}t.push({file:r,folder:n,id:l,title:d,body:"",parentBlurb:I,parentId:g??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=[],i=[];for(let s of t){let n=s.parent?this.tree.get(s.parent):null;if(!n||n.id===G){i.push(s.id);continue}let o=n.parent??G;await this.changeParent(s,o),e.push(s)}if(e.length===0){new L.Notice(i.length?"Already at the top level.":"Nothing to outdent.");return}if(this.render(),i.length){let s=e.map(n=>this.tree.get(n)).filter(n=>!!n);this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Outdented",nodes:s,suffix:i.length?`(${i.length} already at root)`:void 0}),kind:"success",category:"move",affectedIds:e,folder:this.noteFolder})}if(this.plugin.settings.autoNavOnMoveOut&&e.length>0){let s=e[0].parent;s!=null&&e.every(o=>o.parent===s)&&s!==this.focusId&&this.navigateTo(s)}}cmdSetColor(){let t=this.getActionTargets();if(!t.length)return;let e=new Set(t.map(n=>this.colorForNode(n)??"")),i=e.size===1&&Array.from(e)[0]||null,s=this.plugin.settings.customPalette??[];new ae(this.app,i,s,async(n,o)=>{let a=[];for(let d of t)if(d.file){a.push({id:d.id,path:d.file.path,was:this.colorForNode(d)??null});try{await this.app.fileManager.processFrontMatter(d.file,I=>{n?I.color=n:delete I.color})}catch(I){new L.Notice(`Couldn't set color for ${d.id}: ${I.message}`)}}if(o.addToPalette&&typeof n=="string"){let d=[...this.plugin.settings.customPalette??[]],I=n.toLowerCase();d.some(g=>g.toLowerCase()===I)||(d.push(n),this.plugin.settings.customPalette=d,await this.plugin.persistSettingsQuiet(),await this.log.append({type:"palette_color_add",id:G,payload:{color:n}}))}this.render();let r=this.noteFolder,c=n,l=async d=>{for(let I of d){let g=this.app.vault.getAbstractFileByPath(I.path);if(g)try{await this.app.fileManager.processFrontMatter(g,p=>{I.col?p.color=I.col:delete p.color})}catch{}}this.tree.rebuild(r),this.render()};this.plugin.getUndoStack(r).push({label:a.length===1?"Color change":`Color change (${a.length})`,undo:()=>l(a.map(d=>({path:d.path,col:d.was}))),redo:()=>l(a.map(d=>({path:d.path,col:c})))})},async n=>{let o=(this.plugin.settings.customPalette??[]).filter(a=>a.toLowerCase()!==n.toLowerCase());return this.plugin.settings.customPalette=o,await this.plugin.persistSettingsQuiet(),await this.log.append({type:"palette_color_remove",id:G,payload:{color:n}}),o}).open()}cmdMovePicker(){let t=this.getActionTargets();t.length&&new Jt(this.app,this.tree,e=>this.titleForNode(e),{mode:"pick",placeholder:"Move to which note?",allowCreate:!0,onPick:async e=>{if(e.crossFolder){let s=e.id.replace(/^cross:/,"");await this.moveAcrossFolders(t,e.crossFolder,s),this.selection.clear(),this.render();return}let i=e.id;for(let s of t)await this.changeParent(s,i);this.selection.clear(),this.render(),this.plugin.settings.autoNavOnMoveOut&&i!==this.focusId&&this.navigateTo(i)},onCreate:async e=>{let i=await this.createNoteUnder(e,this.focusId);if(i){for(let s of t)await this.changeParent(s,i);this.selection.clear(),this.render(),this.plugin.settings.autoNavOnMoveOut&&this.navigateTo(i)}},crossFolderNotes:()=>this.collectCrossFolderDestinations(),showFilterChips:!0}).open()}async moveAcrossFolders(t,e,i){if(!t.length)return;let s=(e||"").replace(/\/+$/,"");if(!s){new L.Notice("Target folder is empty");return}let n=[],o=new Set;for(let d of this.app.vault.getMarkdownFiles())(d.parent?.path?.replace(/\/+$/,"")??"")===s&&o.add(d.path);let a=(d,I)=>{if(!d.file)return;let g=d.file,p=`${s}/${g.name}`;if(o.has(p)){let u=g.basename.match(/^(.*)(-[a-z0-9]{4,12})$/),f=u?u[1]:g.basename,B=u?u[2]:"";for(let Q=1;Q<1e3;Q++){let E=`${f}-${Q}${B}.md`,y=`${s}/${E}`;if(!o.has(y)){p=y;break}}}o.add(p),n.push({id:d.id,file:g,oldPath:g.path,newPath:p,oldParent:d.parent,isRoot:I});for(let u of this.tree.getChildren(d.id))a(u,!1)};for(let d of t)a(d,!0);if(!n.length)return;await this.ensureFolder(s);for(let d of n)try{await this.app.fileManager.renameFile(d.file,d.newPath),d.isRoot&&await this.app.fileManager.processFrontMatter(d.file,I=>{I.parent=i}),await this.log.append({type:"parent_change",id:d.id,payload:{from:d.oldParent,to:d.isRoot?i:d.oldParent,crossFolder:{from:this.noteFolder,to:s}}})}catch(I){new L.Notice(`Move failed for ${d.id}: ${I.message}`)}this.tree.rebuild(this.noteFolder);let r=t.map(d=>this.tree.get(d.id)).filter(d=>!!d),c=r.length>0?this.titleList(r):`${t.length} note${t.length===1?"":"s"}`,l=i===G?"Open home":"Open parent";this.plugin.notifications.show({message:`Moved ${c} \u2192 \`${s}\``,kind:"success",category:"move",affectedIds:t.map(d=>d.id),folder:this.noteFolder,actions:[{label:l,onClick:()=>{this.switchToFolderAndFocus(s,i)}}]}),this.plugin.getUndoStack(this.noteFolder).push({label:`Cross-Stashpad move (${n.length})`,undo:async()=>{for(let d of n){let I=this.app.vault.getAbstractFileByPath(d.newPath);if(I)try{await this.app.fileManager.renameFile(I,d.oldPath),d.isRoot&&await this.app.fileManager.processFrontMatter(I,g=>{g.parent=d.oldParent})}catch{}}this.tree.rebuild(this.noteFolder),this.render()},redo:async()=>{for(let d of n){let I=this.app.vault.getAbstractFileByPath(d.oldPath);if(I)try{await this.app.fileManager.renameFile(I,d.newPath),d.isRoot&&await this.app.fileManager.processFrontMatter(I,g=>{g.parent=i})}catch{}}this.tree.rebuild(this.noteFolder),this.render()}})}nextPickableIdx(t,e){for(let i=t+e;i>=0&&i<this.currentChildren.length;i+=e){let s=this.currentChildren[i];if(s&&!this.selection.has(s.id))return i}return t}cmdInListPicker(){if(this.currentChildren.length===0)return;let t=this.cursorIdx>0?this.cursorIdx-1:0;if(this.currentChildren[t]&&this.selection.has(this.currentChildren[t].id)){let i=this.nextPickableIdx(t,-1);t=i!==t?i:this.nextPickableIdx(t,1)}this.inListPicker={activeIdx:t},new L.Notice("Arrows to pick parent, Enter confirms, Esc cancels.");let e=this.listEl?.scrollTop??0;if(this.render(),this.listEl){let i=this.listEl;i.scrollTop=e,requestAnimationFrame(()=>{i.scrollTop=e}),setTimeout(()=>{i.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 i=this.selectionGuardKey,s=()=>{if(this.selectionGuardKey!==i||this.selection.has(t.id))return;let n=this.currentChildren.findIndex(o=>o.id===t.id);n<0||(this.selection.add(t.id),this.cursorIdx=n,this.render({kind:"follow-cursor"}))};setTimeout(s,120),setTimeout(s,400)}async cmdMerge(){let t=this.getActionTargets();if(t.length<2){new L.Notice("Select 2+ notes to merge.");return}t.sort((u,f)=>(u.created||"").localeCompare(f.created||""));let e=t[0];if(!e.file)return;let i=e.file.path,s=await this.app.vault.read(e.file),n=await this.snapshotNotes(t.slice(1),!1),o=[],a=[];for(let u of t){if(!u.file)continue;let f=await this.app.vault.cachedRead(u.file);a.push(this.stripFrontmatter(f).trim())}let r=a.map(u=>u.trim()).filter(Boolean).join(` +`:"";a.value+=`${J}${T} +`,this.composerDraft=a.value},v=C.createEl("button",{cls:"stashpad-composer-btn"});(0,q.setIcon)(v,"paperclip"),v.title="Attach files",v.onmousedown=T=>T.preventDefault(),v.onclick=T=>{T.preventDefault();let J=document.activeElement===a;if(u.click(),J){let Z=()=>{a.focus()};setTimeout(Z,100),setTimeout(Z,500)}},u.addEventListener("change",async()=>{let T=Array.from(u.files??[]);u.value="";for(let J of T){let Z=await this.importAttachment(J);Z&&w(Z)}a.focus()});let D=f.createEl("button",{cls:"stashpad-composer-btn stashpad-composer-rail-toggle"});(0,q.setIcon)(D,"chevron-left"),D.title="Show more composer options",f.insertBefore(D,C);let L=T=>{f.toggleClass("is-expanded",T),D.title=T?"Hide options":"Show more composer options",(0,q.setIcon)(D,T?"chevron-right":"chevron-left")};D.onmousedown=T=>T.preventDefault(),D.onclick=T=>{T.preventDefault(),L(!f.hasClass("is-expanded"))},L(!1);let S=()=>o.clientWidth<700,b=()=>{let T=S();o.toggleClass("is-narrow",T),L(!T)};b(),requestAnimationFrame(b);let Q=new ResizeObserver(b);Q.observe(o),this.composerNarrowObserver?.disconnect(),this.composerNarrowObserver=Q;let H=f.createEl("button",{cls:"stashpad-composer-btn stashpad-composer-send"});H.title="Send (Enter)",(0,q.setIcon)(H,"arrow-up");let $=async()=>{let T=a.value.trim();if(!T)return;a.value="",this.composerDraft="";try{await this.saveDraft("")}catch{}try{await this.recordLastSubmitted(T)}catch{}let J=this.modeSplit??ft().splitOnLines,Z=this.nextDestination,U=this.nextDestinationFolder,N=!!U&&U!==this.noteFolder;this.nextDestination=null,this.nextDestinationFolder=null,this.nextDestinationLabel=null,this.autoSelectNewest=!N,this.scrollToBottomOnNextRender=!N;let j=N?{targetFolder:U}:void 0;if(J)for(let K of T.split(/\r?\n/)){let z=K.trim();z&&await this.createNoteUnder(z,Z,j)}else await this.createNoteUnder(T,Z,j);ft().autofocusComposerAfterSend&&(this.focusComposerOnNextRender=!0,N&&this.composerInputEl?.focus())};H.onclick=()=>void $(),a.addEventListener("keydown",T=>{let J=this.modeEnterSubmits;if(T.key==="Escape"){T.preventDefault(),T.stopPropagation(),a.blur(),this.viewRoot.focus({preventScroll:!0});return}if(T.key==="ArrowUp"&&a.selectionStart===0&&a.selectionEnd===0){if(T.preventDefault(),a.blur(),this.viewRoot.focus({preventScroll:!0}),this.currentChildren.length>0){let Z=this.lastCursorByFocus.get(this.focusId)??this.lastSelected,U=Z?this.currentChildren.findIndex(N=>N.id===Z):-1;this.cursorIdx=U>=0?U:this.currentChildren.length-1,this.selectCursor(!1)}return}T.key==="Enter"&&!T.isComposing&&(J?!T.shiftKey:T.shiftKey)&&(T.preventDefault(),T.stopPropagation(),T.stopImmediatePropagation(),$())}),t.createDiv({cls:"stashpad-composer-help"}).setText(this.composerHelperText(i,s))}composerPlaceholder(t,e){return q.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 i=t?"Enter":"Shift+Enter",s=t?"Shift+Enter":"Enter",n=ft().bindings,o=p=>{let g=n[p];return g.primary&&g.secondary?g.preferRight?g.secondary:g.primary:g.primary||g.secondary},r=je(o("toggleSplit")),a=je(o("pickDestination")),c=je(o("search")),l=this.nextDestination?` \u2022 destination: ${this.destinationLabel()}`:"";return`${i} sends \xB7 ${s} newline \xB7 ${r} split: ${e?"ON":"off"} \xB7 ${a} destination \xB7 ${c} search${l}`}destinationLabel(){if(!this.nextDestination)return"current";if(this.nextDestinationFolder)return this.nextDestinationLabel??this.nextDestinationFolder;if(this.nextDestination===G)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(G),e.createEl("button",{text:"Back"}).onclick=()=>this.navigateUp(),e.createEl("button",{text:"Bookmarks"}).onclick=()=>this.openBookmarks()}handleRenderedClick(t,e){let i=t.target,s=i?.closest?.(".tag");if(s){t.preventDefault(),t.stopPropagation();let r=(s.getAttribute("href")||s.textContent||"").replace(/^#/,"").trim();if(r){let a=this.app.internalPlugins?.plugins?.["global-search"],c=a?.instance?.openGlobalSearch?.bind(a.instance);c&&c(`tag:#${r}`)}return}let n=i?.closest?.(".internal-link");if(n){t.preventDefault(),t.stopPropagation();let o=n.getAttribute("data-href")||n.getAttribute("href");if(o){let r=e.file?.path||"";this.app.workspace.openLinkText(o,r,!0)}}}handleRowClick(t,e,i){let s=t.target,n=s?.closest?.(".tag");if(n){t.preventDefault(),t.stopPropagation();let c=(n.getAttribute("href")||n.textContent||"").replace(/^#/,"").trim();if(c){let l=this.app.internalPlugins?.plugins?.["global-search"],p=l?.instance?.openGlobalSearch?.bind(l.instance);p&&p(`tag:#${c}`)}return}let o=s?.closest?.(".internal-link");if(o){t.preventDefault(),t.stopPropagation();let a=o.getAttribute("data-href")||o.getAttribute("href");if(a){let c=i.file?.path||"";this.app.workspace.openLinkText(a,c,!0)}return}if(s?.tagName==="A"&&s.href)return;if(t.stopPropagation(),this.inListPicker){this.inListPicker.activeIdx=e,this.commitInListPicker();return}let r=this.selection.size===0;if(t.shiftKey&&this.lastSelected){this.cursorIdx=e;let a=this.currentChildren.findIndex(c=>c.id===this.lastSelected);if(r&&(this.firstSelectedId=this.lastSelected),a!==-1){let[c,l]=a<e?[a,e]:[e,a];for(let p=c;p<=l;p++)this.selection.add(this.currentChildren[p].id)}else this.selection.add(i.id)}else if(t.metaKey||t.ctrlKey)if(this.selection.has(i.id))if(this.selection.delete(i.id),this.firstSelectedId===i.id&&(this.firstSelectedId=null),this.lastSelected===i.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],c=a?this.currentChildren.findIndex(l=>l.id===a):-1;c>=0&&(this.cursorIdx=c)}else this.cursorIdx=e,r&&(this.firstSelectedId=i.id),this.selection.add(i.id);else this.mobileSelectMode?(this.cursorIdx=e,this.selection.has(i.id)?(this.selection.delete(i.id),this.firstSelectedId===i.id&&(this.firstSelectedId=null)):this.selection.add(i.id)):(this.cursorIdx=e,this.selection.clear(),this.selection.add(i.id),this.firstSelectedId=i.id,this.lastSelected=i.id);this.selection.size===0&&(this.firstSelectedId=null),this.selection.has(i.id)&&(this.lastSelected=i.id),this.viewRoot.focus({preventScroll:!0}),this.repaintSelectionClasses(),this.revealCursorRow(),this.stampSelectedCursor(),this.plugin.notifyStashpadSelectionChanged()}revealCursorRow(){let t=()=>{if(this.cursorIdx<0)return;let e=this.listEl?.querySelector(`[data-idx="${this.cursorIdx}"]`);if(!e||!this.listEl)return;let i=this.listEl,s=i.getBoundingClientRect(),n=e.getBoundingClientRect(),o=4,r=s.top+o,a=s.bottom-o;if(q.Platform.isMobile&&document.body.classList.contains("stashpad-keyboard-open")){let c=this.viewRoot?.querySelector(".stashpad-composer");c&&(a=Math.min(a,c.getBoundingClientRect().top-o))}n.top<r?i.scrollTop+=n.top-r:n.bottom>a&&(i.scrollTop+=n.bottom-a)};t(),requestAnimationFrame(t),setTimeout(t,60),setTimeout(t,200)}jumpToTop(){this.currentChildren.length!==0&&(this.cursorIdx=0,this.selectCursor(!1))}jumpToBottom(){this.currentChildren.length!==0&&(this.cursorIdx=this.currentChildren.length-1,this.selectCursor(!1))}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 i=this.firstSelectedId??e.id,s=this.currentChildren.findIndex(n=>n.id===i);if(s===-1)this.selection.add(e.id),this.firstSelectedId=e.id;else{let[n,o]=s<this.cursorIdx?[s,this.cursorIdx]:[this.cursorIdx,s];this.selection.clear();for(let r=n;r<=o;r++)this.selection.add(this.currentChildren[r].id);this.firstSelectedId=i}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(s=>{let n=Number(s.dataset.idx),o=s.dataset.id??"",r=n===this.cursorIdx;s.classList.toggle("is-cursor",r),s.classList.toggle("is-selected",this.selection.has(o)),s.classList.toggle("is-cursor-expanded",t&&r),s.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 i=e.getBoundingClientRect(),s=this.listEl.getBoundingClientRect();(i.top<s.top||i.bottom>s.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??ft().splitOnLines;this.modeSplit=!t,this.render(),this.composerInputEl?.focus()}openDestinationPicker(t=!1){let e=!1;new Ot(this.app,this.tree,i=>this.titleForNode(i),{mode:"pick",placeholder:"Send next note(s) under which note?",allowCreate:!0,onPick:async i=>{if(e=!0,i.crossFolder){let s=i.id.replace(/^cross:/,"");this.nextDestination=s,this.nextDestinationFolder=i.crossFolder;let n=i.crossFolder.split("/").pop()||i.crossFolder,o=s===G?"Home":(i.crossFile?.basename??"note").replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ");this.nextDestinationLabel=`${n} \u25B8 ${o}`,this.render(),this.composerInputEl?.focus();return}this.nextDestination=i.id,this.nextDestinationFolder=null,this.nextDestinationLabel=null,this.render(),this.composerInputEl?.focus()},onCreate:async i=>{e=!0;let s=await this.createNoteUnder(i,this.focusId);s&&(this.nextDestination=s,this.nextDestinationFolder=null,this.nextDestinationLabel=null,this.render(),this.composerInputEl?.focus())},crossFolderNotes:()=>this.collectCrossFolderDestinations(),onClose:()=>{t&&!e&&this.composerInputEl?.focus()}}).open()}collectCrossFolderDestinations(){let t=this.collectCrossFolderNotes(),e=this.plugin.searchableFolders(this.noteFolder).filter(n=>n!==this.noteFolder),i=new Map;for(let n of this.app.vault.getMarkdownFiles()){let o=n.parent?.path?.replace(/\/+$/,"")??"";if(!e.includes(o))continue;this.app.metadataCache.getFileCache(n)?.frontmatter?.id===G&&i.set(o,n)}return[...e.map(n=>({file:i.get(n),folder:n,id:G,title:`Home \u2014 ${n.split("/").pop()||n}`,body:""})),...t]}openSearchInParentModal(){let t=this.focusId,e=s=>{if(s===t)return!0;let n=new Set,o=this.tree.get(s);for(;o&&o.id!==G&&!n.has(o.id);){if(n.add(o.id),o.parent===t||o.id===t)return!0;if(!o.parent)return!1;o=this.tree.get(o.parent)}return t===G},i=new Proxy(this.tree,{get:(s,n)=>n==="getRoot"?()=>s.get(t)??s.getRoot():n==="getChildren"?o=>s.getChildren(o):s[n]});new Ot(this.app,i,s=>this.titleForNode(s),{mode:"search",placeholder:`Search in "${this.titleForNode(this.tree.get(t)??this.tree.getRoot()).trim()}"\u2026`,allowCreate:!1,onPick:s=>{s.node&&e(s.node.id)?this.navigateTo(s.node.id):s.node&&this.navigateTo(s.node.id)}}).open()}openSearchModal(){if(this.openSearchInstance){let i=this.openSearchInstance.inputEl;i&&(i.focus(),i.select());return}let t=new Ot(this.app,this.tree,i=>this.titleForNode(i),{mode:"search",placeholder:"Search Stashpad notes\u2026",allowCreate:!0,onCreate:async i=>{let s=i.trim();s&&new Ot(this.app,this.tree,n=>this.titleForNode(n),{mode:"pick",placeholder:`Create "${s}" under which note?`,allowCreate:!1,crossFolderNotes:()=>this.collectCrossFolderDestinations(),folderResults:()=>this.plugin.discoverStashpadFolders().filter(n=>n!==this.noteFolder),localFolder:this.noteFolder,onPick:async n=>{let o=n.crossFolder?n.id.replace(/^cross:/,""):n.node?.id,r=n.crossFolder??this.noteFolder;if(!o)return;let a=(this.plugin.settings.folder||"Stashpad").trim().replace(/^\/+|\/+$/g,"")||"Stashpad",c=this.app.workspace,l=c.getLeaf("tab");await l.setViewState({type:gt,active:!0,state:{focusId:o,folderOverride:r===a?null:r}}),c.revealLeaf(l);let p=l.view;if(p&&typeof p.createNoteUnder=="function"){let g=await p.createNoteUnder(s,o);g&&typeof p.navigateTo=="function"&&p.navigateTo(g)}}}).open()},onPick:i=>{if(i.kind==="folder-open"&&i.folder){this.openFolderInNewTab(i.folder);return}if(i.crossFolder&&i.crossFile){let s=i.id.replace(/^cross:/,"");this.switchToFolderAndFocus(i.crossFolder,s);return}i.node&&this.navigateTo(i.node.id)},crossFolderNotes:()=>this.collectCrossFolderDestinations(),folderResults:()=>this.plugin.discoverStashpadFolders().filter(i=>i!==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 i=new Set(e),s=new Map;for(let n of this.app.vault.getMarkdownFiles()){let o=n.parent?.path?.replace(/\/+$/,"")??"";if(!i.has(o))continue;let r=s.get(o);r||(r=[],s.set(o,r)),r.push(n)}for(let n of e){let o=s.get(n)??[],r=new Map;for(let a of o){let c=this.app.metadataCache.getFileCache(a)?.frontmatter;typeof c?.id=="string"&&r.set(c.id,a)}for(let a of o){let c=this.app.metadataCache.getFileCache(a)?.frontmatter,l=typeof c?.id=="string"?c.id:"";if(!l||l===G)continue;let p=a.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," "),g,h=c?.parent??null;if(h&&h!==G){let I=r.get(h);I&&(g=I.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," "))}t.push({file:a,folder:n,id:l,title:p,body:"",parentBlurb:g,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=[],i=[];for(let s of t){let n=s.parent?this.tree.get(s.parent):null;if(!n||n.id===G){i.push(s.id);continue}let o=n.parent??G;await this.changeParent(s,o),e.push(s)}if(e.length===0){new q.Notice(i.length?"Already at the top level.":"Nothing to outdent.");return}if(this.render(),i.length){let s=e.map(n=>this.tree.get(n)).filter(n=>!!n);this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Outdented",nodes:s,suffix:i.length?`(${i.length} already at root)`:void 0}),kind:"success",category:"move",affectedIds:e,folder:this.noteFolder})}if(this.plugin.settings.autoNavOnMoveOut&&e.length>0){let s=e[0].parent;s!=null&&e.every(o=>o.parent===s)&&s!==this.focusId&&this.navigateTo(s)}}cmdSetColor(){let t=this.getActionTargets();if(!t.length)return;let e=new Set(t.map(n=>this.colorForNode(n)??"")),i=e.size===1&&Array.from(e)[0]||null,s=this.plugin.settings.customPalette??[];new ce(this.app,i,s,async(n,o)=>{let r=[];for(let p of t)if(p.file){r.push({id:p.id,path:p.file.path,was:this.colorForNode(p)??null});try{await this.app.fileManager.processFrontMatter(p.file,g=>{n?g.color=n:delete g.color})}catch(g){new q.Notice(`Couldn't set color for ${p.id}: ${g.message}`)}}if(o.addToPalette&&typeof n=="string"){let p=[...this.plugin.settings.customPalette??[]],g=n.toLowerCase();p.some(h=>h.toLowerCase()===g)||(p.push(n),this.plugin.settings.customPalette=p,await this.plugin.persistSettingsQuiet(),await this.log.append({type:"palette_color_add",id:G,payload:{color:n}}))}this.render();let a=this.noteFolder,c=n,l=async p=>{for(let g of p){let h=this.app.vault.getAbstractFileByPath(g.path);if(h)try{await this.app.fileManager.processFrontMatter(h,I=>{g.col?I.color=g.col:delete I.color})}catch{}}this.tree.rebuild(a),this.render()};this.plugin.getUndoStack(a).push({label:r.length===1?"Color change":`Color change (${r.length})`,undo:()=>l(r.map(p=>({path:p.path,col:p.was}))),redo:()=>l(r.map(p=>({path:p.path,col:c})))})},async n=>{let o=(this.plugin.settings.customPalette??[]).filter(r=>r.toLowerCase()!==n.toLowerCase());return this.plugin.settings.customPalette=o,await this.plugin.persistSettingsQuiet(),await this.log.append({type:"palette_color_remove",id:G,payload:{color:n}}),o}).open()}cmdMovePicker(){let t=this.getActionTargets();t.length&&new Ot(this.app,this.tree,e=>this.titleForNode(e),{mode:"pick",placeholder:"Move to which note?",allowCreate:!0,onPick:async e=>{if(e.crossFolder){let o=e.id.replace(/^cross:/,"");await this.moveAcrossFolders(t,e.crossFolder,o),this.selection.clear(),this.render();return}let i=e.id,s=new Map(t.map(o=>[o.id,this.tree.getChildren(o.id).length])),n=[];for(let o of t)await this.changeParent(o,i,{silentSuccess:!0})&&n.push(o);this.notifyBatchMove(n,i,s),this.selection.clear(),this.render(),this.plugin.settings.autoNavOnMoveOut&&i!==this.focusId&&this.navigateTo(i)},onCreate:async e=>{let i=await this.createNoteUnder(e,this.focusId);if(!i)return;let s=new Map(t.map(o=>[o.id,this.tree.getChildren(o.id).length])),n=[];for(let o of t)await this.changeParent(o,i,{silentSuccess:!0})&&n.push(o);this.notifyBatchMove(n,i,s),this.selection.clear(),this.render(),this.plugin.settings.autoNavOnMoveOut&&this.navigateTo(i)},crossFolderNotes:()=>this.collectCrossFolderDestinations(),showFilterChips:!0}).open()}async moveAcrossFolders(t,e,i){if(!t.length)return;let s=(e||"").replace(/\/+$/,"");if(!s){new q.Notice("Target folder is empty");return}let n=[],o=new Set;for(let g of this.app.vault.getMarkdownFiles())(g.parent?.path?.replace(/\/+$/,"")??"")===s&&o.add(g.path);let r=(g,h)=>{if(!g.file)return;let I=g.file,u=`${s}/${I.name}`;if(o.has(u)){let f=I.basename.match(/^(.*)(-[a-z0-9]{4,12})$/),C=f?f[1]:I.basename,m=f?f[2]:"";for(let E=1;E<1e3;E++){let y=`${C}-${E}${m}.md`,w=`${s}/${y}`;if(!o.has(w)){u=w;break}}}o.add(u),n.push({id:g.id,file:I,oldPath:I.path,newPath:u,oldParent:g.parent,isRoot:h});for(let f of this.tree.getChildren(g.id))r(f,!1)};for(let g of t)r(g,!0);if(!n.length)return;await this.ensureFolder(s);for(let g of n)try{await this.app.fileManager.renameFile(g.file,g.newPath),g.isRoot&&await this.app.fileManager.processFrontMatter(g.file,h=>{h.parent=i}),await this.log.append({type:"parent_change",id:g.id,payload:{from:g.oldParent,to:g.isRoot?i:g.oldParent,crossFolder:{from:this.noteFolder,to:s}}})}catch(h){new q.Notice(`Move failed for ${g.id}: ${h.message}`)}if(ft().writeRecoveryLinks){let g=this.noteFolder;window.setTimeout(()=>{we(this.app,g),we(this.app,s)},350)}let a=this.titleList(t);this.tree.rebuild(this.noteFolder);let c=i===G?"Open home":"Open parent",l=Math.max(0,n.length-t.length),p=t.length===1?`Moved ${a}${l>0?` and its ${l} nested note${l===1?"":"s"}`:""} \u2192 \`${s}\``:`Moved ${a}${l>0?` (${l} nested)`:""} \u2192 \`${s}\``;this.plugin.notifications.show({message:p,kind:"success",category:"move",duration:0,affectedIds:t.map(g=>g.id),folder:this.noteFolder,actions:[{label:c,onClick:()=>{this.switchToFolderAndFocus(s,i)}}]}),this.plugin.getUndoStack(this.noteFolder).push({label:`Cross-Stashpad move (${n.length})`,undo:async()=>{for(let g of n){let h=this.app.vault.getAbstractFileByPath(g.newPath);if(h)try{await this.app.fileManager.renameFile(h,g.oldPath),g.isRoot&&await this.app.fileManager.processFrontMatter(h,I=>{I.parent=g.oldParent})}catch{}}this.tree.rebuild(this.noteFolder),this.render()},redo:async()=>{for(let g of n){let h=this.app.vault.getAbstractFileByPath(g.oldPath);if(h)try{await this.app.fileManager.renameFile(h,g.newPath),g.isRoot&&await this.app.fileManager.processFrontMatter(h,I=>{I.parent=i})}catch{}}this.tree.rebuild(this.noteFolder),this.render()}})}nextPickableIdx(t,e){for(let i=t+e;i>=0&&i<this.currentChildren.length;i+=e){let s=this.currentChildren[i];if(s&&!this.selection.has(s.id))return i}return t}cmdInListPicker(){if(this.currentChildren.length===0)return;let t=this.cursorIdx>0?this.cursorIdx-1:0;if(this.currentChildren[t]&&this.selection.has(this.currentChildren[t].id)){let n=this.nextPickableIdx(t,-1);t=n!==t?n:this.nextPickableIdx(t,1)}this.inListPicker={activeIdx:t};let e=ft().bindings.move,i=je(e.primary||e.secondary||"M");new q.Notice(`Arrows to pick parent, Enter confirms, ${i} for the full picker, Esc cancels.`);let s=this.listEl?.scrollTop??0;if(this.render(),this.listEl){let n=this.listEl;n.scrollTop=s,requestAnimationFrame(()=>{n.scrollTop=s}),setTimeout(()=>{n.scrollTop=s},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(r=>r.id!==t.id),i=new Map(e.map(r=>[r.id,this.tree.getChildren(r.id).length])),s=[];for(let r of e)await this.changeParent(r,t.id,{silentSuccess:!0})&&s.push(r);if(this.notifyBatchMove(s,t.id,i),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 n=this.selectionGuardKey,o=()=>{if(this.selectionGuardKey!==n||this.selection.has(t.id))return;let r=this.currentChildren.findIndex(a=>a.id===t.id);r<0||(this.selection.add(t.id),this.cursorIdx=r,this.render({kind:"follow-cursor"}))};setTimeout(o,120),setTimeout(o,400)}async cmdMerge(){let t=this.getActionTargets();if(t.length<2){new q.Notice("Select 2+ notes to merge.");return}t.sort((u,f)=>(u.created||"").localeCompare(f.created||""));let e=t[0];if(!e.file)return;let i=e.file.path,s=await this.app.vault.read(e.file),n=await this.snapshotNotes(t.slice(1),!1),o=[],r=[];for(let u of t){if(!u.file)continue;let f=await this.app.vault.cachedRead(u.file);r.push(this.stripFrontmatter(f).trim())}let a=r.map(u=>u.trim()).filter(Boolean).join(` `),c=await this.app.vault.read(e.file),l=c.startsWith("---")?c.indexOf(` ----`,3)+4:0,I=`${c.slice(0,l)} -${r} -`;await this.app.vault.modify(e.file,I);for(let u=1;u<t.length;u++){let f=t[u];if(f.file){for(let B of this.tree.getChildren(f.id))B.file&&o.push({childId:B.id,childPath:B.file.path,oldParent:B.parent}),await this.changeParent(B,e.id,{record:!1});await this.app.fileManager.trashFile(f.file),await this.log.append({type:"delete",id:f.id,payload:{mergedInto:e.id}})}}this.selection.clear(),this.cursorIdx=-1,this.pendingFocusIds=[e.id];let g=this.titleForNode(e);this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Merged",nodes:t,destination:`\u2192 kept "${g}"`}),kind:"success",category:"merge",affectedIds:t.map(u=>u.id),folder:this.noteFolder}),this.tree.rebuild(this.noteFolder),this.render({kind:"follow-cursor"});{let u=e.id,f=this.selectionGuardKey,B=()=>{if(this.selectionGuardKey!==f||this.selection.has(u))return;let Q=this.currentChildren.findIndex(E=>E.id===u);Q<0||(this.selection.add(u),this.cursorIdx=Q,this.render({kind:"follow-cursor"}))};setTimeout(B,120),setTimeout(B,400)}let p=this.noteFolder;this.plugin.getUndoStack(p).push({label:`Merge ${t.length} notes`,undo:async()=>{await this.restoreSnapshots(n,t.map(f=>f.id));let u=this.app.vault.getAbstractFileByPath(i);u&&await this.app.vault.modify(u,s);for(let f of o){let B=this.app.vault.getAbstractFileByPath(f.childPath);B&&await this.app.fileManager.processFrontMatter(B,Q=>{Q.parent=f.oldParent})}this.pendingFocusIds=t.map(f=>f.id),this.tree.rebuild(p),this.render({kind:"follow-cursor"})},redo:async()=>{await this.trashNotesAndAttachments(n);let u=this.app.vault.getAbstractFileByPath(i);u&&await this.app.vault.modify(u,I);for(let f of o){let B=this.app.vault.getAbstractFileByPath(f.childPath);B&&await this.app.fileManager.processFrontMatter(B,Q=>{Q.parent=e.id})}this.tree.rebuild(p),this.render()}})}cmdCopy(){return dn(this)}cmdCopyCodeBlock(){return hn(this)}cmdCopyTree(){return gn(this)}cmdCopyOutline(){return In(this)}cmdToggleExpand(){let t=this.getActionTargets();if(!t.length)return;let e=t.some(i=>!this.expandedNotes.has(i.id));for(let i of t)e?this.expandedNotes.add(i.id):this.expandedNotes.delete(i.id);this.render()}async cloneSubtree(t,e,i){if(!t.file)return null;if(t.id===e||this.isDescendant(e,t.id))return new L.Notice(`Can't insert "${this.titleForNode(t)}" into itself or a descendant \u2014 that would loop forever.`),null;let s=this.tree.getChildren(t.id).slice(),n=t.file,o=await this.app.vault.read(n),a=this.stripFrontmatter(o),r=this.app.metadataCache.getFileCache(n)?.frontmatter??{},c=mt(),l=kt(a,this.activeStopwords()),d=St(l,c),I=`${this.noteFolder}/${d}`,g=new Date().toISOString(),p=this.extractAttachments(a),u=["---",`id: ${c}`,`parent: ${e}`,`created: ${g}`];if(p.length>0){u.push("attachments:");for(let B of p)u.push(` - "${B.replace(/"/g,'\\"')}"`)}else u.push("attachments: []");u.push("---",a),await this.ensureFolder(this.noteFolder),await this.app.vault.create(I,u.join(` -`)),i.push(I);let f=this.app.vault.getAbstractFileByPath(I);if(f){try{await this.app.fileManager.processFrontMatter(f,B=>{for(let[Q,E]of Object.entries(r))zt.includes(Q)||(B[Q]=E)})}catch(B){console.warn("[Stashpad] cloneSubtree: processFrontMatter failed",B)}try{this.tree.insertSynthetic({id:c,parent:e,children:[],file:f,created:g})}catch{}this.fmSync.scheduleParentChange(c,null,e)}for(let B of s)await this.cloneSubtree(B,c,i);return c}async cmdClone(){let t=this.getActionTargets();if(!t.length){new L.Notice("Nothing to clone.");return}let e=this.noteFolder,i=[],s=[];for(let r of t){if(!r.file)continue;let c=r.parent??this.focusId,l=await this.cloneSubtree(r,c,i);l&&s.push(l)}if(!s.length)return;this.tree.rebuild(e),this.pendingFocusIds=s.slice(),this.render();let n=i.map(r=>this.app.vault.getAbstractFileByPath(r)).filter(r=>!!r&&r.extension==="md").map(r=>({id:pe(r.basename)??r.basename,parent:null,children:[],file:r,created:new Date().toISOString()})),o=await this.snapshotNotes(n,!1);this.plugin.getUndoStack(e).push({label:`Clone ${s.length} note${s.length===1?"":"s"}`,undo:async()=>{for(let r of[...i].reverse()){let c=this.app.vault.getAbstractFileByPath(r);if(c)try{await this.app.fileManager.trashFile(c)}catch{}}this.tree.rebuild(e),this.render()},redo:async()=>{await this.restoreSnapshots(o,s)}});let a=s.map(r=>this.tree.get(r)).filter(r=>!!r);this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Cloned",nodes:a,suffix:`(${i.length} file${i.length===1?"":"s"} total)`}),kind:"success",category:"clone",affectedIds:s,folder:this.noteFolder})}cmdInsertTemplate(){new Jt(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 L.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 i=this.noteFolder,s=[],n=await this.cloneSubtree(e,this.focusId,s);if(!n)return;this.tree.rebuild(i),this.pendingFocusIds=[n],this.render();let o=s.map(r=>this.app.vault.getAbstractFileByPath(r)).filter(r=>!!r&&r.extension==="md").map(r=>({id:pe(r.basename)??r.basename,parent:null,children:[],file:r,created:new Date().toISOString()})),a=await this.snapshotNotes(o,!1);this.plugin.getUndoStack(i).push({label:"Insert template",undo:async()=>{for(let r of[...s].reverse()){let c=this.app.vault.getAbstractFileByPath(r);if(c)try{await this.app.fileManager.trashFile(c)}catch{}}this.tree.rebuild(i),this.render()},redo:async()=>{await this.restoreSnapshots(a,[n])}}),this.plugin.notifications.show({message:`Inserted template (${s.length} file${s.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(a=>a.raw.toLowerCase()===n)||(this.tagFilter=null)}if(this.colorFilter){let n=this.colorFilter.toLowerCase();this.collectFolderColors().some(a=>a.hex===n)||(this.colorFilter=null)}let i=this.lastCursorByFocus.get(t),s;i&&this.tree.get(i)?(this.pendingFocusIds=[i],s={kind:"scroll-to-id",id:i,align:"start"}):s={kind:"preserve"},this.render(s),this.refreshHeaderTitle(),this.viewRoot.focus({preventScroll:!0}),this.plugin.notifyStashpadSelectionChanged()}navigateBack(){let t=this.navBackStack.pop();if(!t){this.focusId!==G&&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),i;e&&this.tree.get(e)?(this.pendingFocusIds=[e],i={kind:"scroll-to-id",id:e,align:"start"}):i={kind:"preserve"},this.render(i),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(G)}let e=this.focusId;if(this.recordNavState(),this.listEl){let o=this.currentChildren[this.cursorIdx]?.id??this.lastSelected;o&&this.plugin.saveLastCursor(this.noteFolder,e,o)}this.focusId=t.parent,this.persistFocus(),this.syncComposerDraftForFocus();let i=this.filterChildren(this.tree.getChildren(this.focusId)),s=i.findIndex(n=>n.id===e);this.selection.clear(),s>=0?(this.cursorIdx=s,this.selection.add(e),this.lastSelected=e):(this.cursorIdx=i.length-1,i.length>0&&(this.selection.add(i[i.length-1].id),this.lastSelected=i[i.length-1].id)),s>=0?this.render({kind:"scroll-to-id",id:e,align:"start"}):this.render({kind:"follow-cursor"}),this.refreshHeaderTitle(),s<0&&this.revealCursorRow()}openBookmarks(){let t=this.app.internalPlugins?.plugins?.bookmarks?.instance?.items??[],e=this.allowedByBases(),i=new L.Menu,s=0;for(let n of t){if(n.type!=="file"||e&&!e.has(n.path))continue;let o=this.tree.idForPath(n.path);o&&(i.addItem(a=>a.setTitle(n.title||n.path).onClick(()=>this.navigateTo(o))),s++)}s||i.addItem(n=>n.setTitle("(no bookmarks in scope)").setDisabled(!0)),i.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=[G],e=this.tree.getRoot(),i=s=>{for(let n of this.tree.getChildren(s))t.push(n.id),i(n.id)};for(let s of e.children)i(s);for(let s of t)this.fmSync.wouldWrite(s)&&this.fmSync.schedule(s)}installFmSyncActivityNotice(){this.fmSyncUnsubscribe||(this.fmSyncUnsubscribe=this.fmSync.onError((t,e)=>{this.plugin.notifications.show({message:`Stashpad: couldn't update recovery metadata +---`,3)+4:0,g=`${c.slice(0,l)} +${a} +`;await this.app.vault.modify(e.file,g);for(let u=1;u<t.length;u++){let f=t[u];if(f.file){for(let C of this.tree.getChildren(f.id))C.file&&o.push({childId:C.id,childPath:C.file.path,oldParent:C.parent}),await this.changeParent(C,e.id,{record:!1});await this.app.fileManager.trashFile(f.file),await this.log.append({type:"delete",id:f.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(u=>u.id),folder:this.noteFolder}),this.tree.rebuild(this.noteFolder),this.render({kind:"follow-cursor"});{let u=e.id,f=this.selectionGuardKey,C=()=>{if(this.selectionGuardKey!==f||this.selection.has(u))return;let m=this.currentChildren.findIndex(E=>E.id===u);m<0||(this.selection.add(u),this.cursorIdx=m,this.render({kind:"follow-cursor"}))};setTimeout(C,120),setTimeout(C,400)}let I=this.noteFolder;this.plugin.getUndoStack(I).push({label:`Merge ${t.length} notes`,undo:async()=>{await this.restoreSnapshots(n,t.map(f=>f.id));let u=this.app.vault.getAbstractFileByPath(i);u&&await this.app.vault.modify(u,s);for(let f of o){let C=this.app.vault.getAbstractFileByPath(f.childPath);C&&await this.app.fileManager.processFrontMatter(C,m=>{m.parent=f.oldParent})}this.pendingFocusIds=t.map(f=>f.id),this.tree.rebuild(I),this.render({kind:"follow-cursor"})},redo:async()=>{await this.trashNotesAndAttachments(n);let u=this.app.vault.getAbstractFileByPath(i);u&&await this.app.vault.modify(u,g);for(let f of o){let C=this.app.vault.getAbstractFileByPath(f.childPath);C&&await this.app.fileManager.processFrontMatter(C,m=>{m.parent=e.id})}this.tree.rebuild(I),this.render()}})}cmdCopy(){return kn(this)}cmdCopyCodeBlock(){return Sn(this)}cmdCopyTree(){return Dn(this)}cmdCopyOutline(){return bn(this)}cmdToggleExpand(){let t=this.getActionTargets();if(!t.length)return;let e=t.some(i=>!this.expandedNotes.has(i.id));for(let i of t)e?this.expandedNotes.add(i.id):this.expandedNotes.delete(i.id);this.render()}async cloneSubtree(t,e,i){if(!t.file)return null;if(t.id===e||this.isDescendant(e,t.id))return new q.Notice(`Can't insert "${this.titleForNode(t)}" into itself or a descendant \u2014 that would loop forever.`),null;let s=this.tree.getChildren(t.id).slice(),n=t.file,o=await this.app.vault.read(n),r=this.stripFrontmatter(o),a=this.app.metadataCache.getFileCache(n)?.frontmatter??{},c=Et(),l=Dt(r,this.activeStopwords()),p=bt(l,c),g=`${this.noteFolder}/${p}`,h=new Date().toISOString(),I=this.extractAttachments(r),u=["---",`id: ${c}`,`parent: ${e}`,`created: ${h}`];if(I.length>0){u.push("attachments:");for(let C of I)u.push(` - "${C.replace(/"/g,'\\"')}"`)}else u.push("attachments: []");u.push("---",r),await this.ensureFolder(this.noteFolder),await this.app.vault.create(g,u.join(` +`)),i.push(g);let f=this.app.vault.getAbstractFileByPath(g);if(f){try{await this.app.fileManager.processFrontMatter(f,C=>{for(let[m,E]of Object.entries(a))Wt.includes(m)||(C[m]=E)})}catch(C){console.warn("[Stashpad] cloneSubtree: processFrontMatter failed",C)}try{this.tree.insertSynthetic({id:c,parent:e,children:[],file:f,created:h})}catch{}this.fmSync.scheduleParentChange(c,null,e)}for(let C of s)await this.cloneSubtree(C,c,i);return c}async cmdClone(){let t=this.getActionTargets();if(!t.length){new q.Notice("Nothing to clone.");return}let e=this.noteFolder,i=[],s=[];for(let a of t){if(!a.file)continue;let c=a.parent??this.focusId,l=await this.cloneSubtree(a,c,i);l&&s.push(l)}if(!s.length)return;this.tree.rebuild(e),this.pendingFocusIds=s.slice(),this.render();let n=i.map(a=>this.app.vault.getAbstractFileByPath(a)).filter(a=>!!a&&a.extension==="md").map(a=>({id:Ce(a.basename)??a.basename,parent:null,children:[],file:a,created:new Date().toISOString()})),o=await this.snapshotNotes(n,!1);this.plugin.getUndoStack(e).push({label:`Clone ${s.length} note${s.length===1?"":"s"}`,undo:async()=>{for(let a of[...i].reverse()){let c=this.app.vault.getAbstractFileByPath(a);if(c)try{await this.app.fileManager.trashFile(c)}catch{}}this.tree.rebuild(e),this.render()},redo:async()=>{await this.restoreSnapshots(o,s)}});let r=s.map(a=>this.tree.get(a)).filter(a=>!!a);this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Cloned",nodes:r,suffix:`(${i.length} file${i.length===1?"":"s"} total)`}),kind:"success",category:"clone",affectedIds:s,folder:this.noteFolder})}cmdInsertTemplate(){new Ot(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 q.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 i=this.noteFolder,s=[],n=await this.cloneSubtree(e,this.focusId,s);if(!n)return;this.tree.rebuild(i),this.pendingFocusIds=[n],this.render();let o=s.map(a=>this.app.vault.getAbstractFileByPath(a)).filter(a=>!!a&&a.extension==="md").map(a=>({id:Ce(a.basename)??a.basename,parent:null,children:[],file:a,created:new Date().toISOString()})),r=await this.snapshotNotes(o,!1);this.plugin.getUndoStack(i).push({label:"Insert template",undo:async()=>{for(let a of[...s].reverse()){let c=this.app.vault.getAbstractFileByPath(a);if(c)try{await this.app.fileManager.trashFile(c)}catch{}}this.tree.rebuild(i),this.render()},redo:async()=>{await this.restoreSnapshots(r,[n])}}),this.plugin.notifications.show({message:`Inserted template (${s.length} file${s.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(r=>r.raw.toLowerCase()===n)||(this.tagFilter=null)}if(this.colorFilter){let n=this.colorFilter.toLowerCase();this.collectFolderColors().some(r=>r.hex===n)||(this.colorFilter=null)}let i=this.lastCursorByFocus.get(t),s;i&&this.tree.get(i)?(this.pendingFocusIds=[i],s={kind:"scroll-to-id",id:i,align:"start"}):s={kind:"preserve"},this.render(s),this.refreshHeaderTitle(),this.viewRoot.focus({preventScroll:!0}),this.plugin.notifyStashpadSelectionChanged()}navigateBack(){let t=this.navBackStack.pop();if(!t){this.focusId!==G&&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),i;e&&this.tree.get(e)?(this.pendingFocusIds=[e],i={kind:"scroll-to-id",id:e,align:"start"}):i={kind:"preserve"},this.render(i),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(G)}let e=this.focusId;if(this.recordNavState(),this.listEl){let o=this.currentChildren[this.cursorIdx]?.id??this.lastSelected;o&&this.plugin.saveLastCursor(this.noteFolder,e,o)}this.focusId=t.parent,this.persistFocus(),this.syncComposerDraftForFocus();let i=this.filterChildren(this.tree.getChildren(this.focusId)),s=i.findIndex(n=>n.id===e);this.selection.clear(),s>=0?(this.cursorIdx=s,this.selection.add(e),this.lastSelected=e):(this.cursorIdx=i.length-1,i.length>0&&(this.selection.add(i[i.length-1].id),this.lastSelected=i[i.length-1].id)),s>=0?this.render({kind:"scroll-to-id",id:e,align:"start"}):this.render({kind:"follow-cursor"}),this.refreshHeaderTitle(),s<0&&this.revealCursorRow()}openBookmarks(){let t=this.app.internalPlugins?.plugins?.bookmarks?.instance?.items??[],e=this.allowedByBases(),i=new q.Menu,s=0;for(let n of t){if(n.type!=="file"||e&&!e.has(n.path))continue;let o=this.tree.idForPath(n.path);o&&(i.addItem(r=>r.setTitle(n.title||n.path).onClick(()=>this.navigateTo(o))),s++)}s||i.addItem(n=>n.setTitle("(no bookmarks in scope)").setDisabled(!0)),i.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=[G],e=this.tree.getRoot(),i=s=>{for(let n of this.tree.getChildren(s))t.push(n.id),i(n.id)};for(let s of e.children)i(s);for(let s of t)this.fmSync.wouldWrite(s)&&this.fmSync.schedule(s)}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)}`,i=this.app.vault.getMarkdownFiles().filter(o=>o.path.startsWith(t+"/"));for(let o of i){if(this.app.metadataCache.getFileCache(o)?.frontmatter?.id!==G)continue;if(o.path===e||this.app.vault.getAbstractFileByPath(e))return o;try{await this.app.fileManager.renameFile(o,e);let c=this.app.vault.getAbstractFileByPath(e);if(c instanceof L.TFile)return c}catch(c){console.warn("[Stashpad] home note rename failed; keeping legacy path",c)}return o}let s=new Date().toISOString(),n=["---",`id: ${G}`,"parent: null",`created: ${s}`,"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(i=>i.path.startsWith(t+"/"));for(let i of e){let s=this.app.metadataCache.getFileCache(i)?.frontmatter,n=s?.id;if(!n||n===G)continue;let o=s?.parent;(o==null||o===""||o==="null")&&(await this.app.fileManager.processFrontMatter(i,a=>{a.parent=G}),await this.log.append({type:"parent_change",id:n,payload:{from:null,to:G,reason:"migration"}}))}}async openInNewStashpadTab(t){let e=this.app.workspace,i=this.leaf,s=e.getLeaf("tab");await s.setViewState({type:ut,active:!0,state:{focusId:t,timeFilter:this.timeFilter,folderOverride:this.folderOverride}}),e.setActiveLeaf(s,{focus:!0}),e.revealLeaf(s);let n=e.on("active-leaf-change",()=>{if((()=>{let r=!1;return e.iterateAllLeaves(c=>{c===s&&(r=!0)}),r})())return;e.offref(n),(()=>{let r=!1;return e.iterateAllLeaves(c=>{c===i&&(r=!0)}),r})()&&(e.setActiveLeaf(i,{focus:!0}),e.revealLeaf(i))})}async openFolderInNewTab(t){let e=(t||"").trim().replace(/^\/+|\/+$/g,"");if(!e)return;let i=(this.plugin.settings.folder||"Stashpad").trim().replace(/^\/+|\/+$/g,"")||"Stashpad",s=this.app.workspace,n=this.leaf,o=s.getLeaf("tab");await o.setViewState({type:ut,active:!0,state:{focusId:G,folderOverride:e===i?null:e}}),s.setActiveLeaf(o,{focus:!0}),s.revealLeaf(o);let a=s.on("active-leaf-change",()=>{if((()=>{let l=!1;return s.iterateAllLeaves(d=>{d===o&&(l=!0)}),l})())return;s.offref(a),(()=>{let l=!1;return s.iterateAllLeaves(d=>{d===n&&(l=!0)}),l})()&&(s.setActiveLeaf(n,{focus:!0}),s.revealLeaf(n))})}cmdOpenInEditor(t){if(t){this.openFileAtEnd(t.file);return}let e=this.getActionTargets();if(e.length)for(let i of e)i.file&&this.openFileAtEnd(i.file)}cmdOpenParentInEditor(){let t=this.tree.get(this.focusId);if(!t?.file){new L.Notice("No focused parent to open.");return}this.openFileAtEnd(t.file)}async openFileAtEnd(t){let e=this.app.workspace,i=this.leaf,s=e.getLeaf("tab");await s.openFile(t,{active:!0}),e.setActiveLeaf(s,{focus:!0}),e.revealLeaf(s);let n=e.on("active-leaf-change",()=>{if((()=>{let l=!1;return e.iterateAllLeaves(d=>{d===s&&(l=!0)}),l})())return;e.offref(n),(()=>{let l=!1;return e.iterateAllLeaves(d=>{d===i&&(l=!0)}),l})()&&(e.setActiveLeaf(i,{focus:!0}),e.revealLeaf(i))}),a=s.view?.editor;a&&requestAnimationFrame(()=>{try{let r=a.lastLine(),c=a.getLine(r)?.length??0;a.setCursor({line:r,ch:c}),a.scrollIntoView({from:{line:r,ch:c},to:{line:r,ch:c}},!0),a.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 L.Notice("Nothing to pin.");return}let e=t.some(n=>!this.plugin.isPinned({folder:this.noteFolder,id:n.id})),i=0,s=0;for(let n of t){let o={folder:this.noteFolder,id:n.id};e?this.plugin.isPinned(o)||(await this.plugin.pinNote(o),i++):this.plugin.isPinned(o)&&(await this.plugin.unpinNote(o),s++)}i>0?new L.Notice(`Pinned ${i} note${i===1?"":"s"} to sidebar.`):s>0&&new L.Notice(`Unpinned ${s} note${s===1?"":"s"} from sidebar.`)}async cmdToggleComplete(){let t=this.getActionTargets();if(t.length===0){let a=this.tree.get(this.focusId);a?.file&&(t=[a])}if(t.length===0){new L.Notice("Nothing to toggle.");return}let i=t.some(a=>!this.isCompleted(a)),s=[],n=[];for(let a of t){if(!a.file)continue;let r=this.isCompleted(a);s.push({id:a.id,path:a.file.path,was:r}),r!==i&&(await this.app.fileManager.processFrontMatter(a.file,c=>{i?c.completed=!0:delete c.completed}),this.completedState.set(a.file.path,i),n.push(a.id))}if(this.render(),n.length>0){await this.log.append({type:i?"complete":"uncomplete",id:n[0],payload:{ids:n,count:n.length}});let a=n.map(r=>this.tree.get(r)).filter(r=>!!r);this.plugin.notifications.show({message:this.bulkActionMessage({verb:i?"Marked complete":"Unmarked",nodes:a}),kind:"success",category:i?"complete":"uncomplete",affectedIds:n,folder:this.noteFolder})}let o=this.noteFolder;this.plugin.getUndoStack(o).push({label:`${i?"Mark complete":"Unmark complete"} (${t.length})`,undo:async()=>{let a=[];for(let r of s){let c=this.app.vault.getAbstractFileByPath(r.path);c&&(await this.app.fileManager.processFrontMatter(c,l=>{r.was?l.completed=!0:delete l.completed}),n.includes(r.id)&&a.push(r.id))}a.length>0&&await this.log.append({type:i?"uncomplete":"complete",id:a[0],payload:{ids:a,count:a.length,undo:!0}}),this.tree.rebuild(o),this.render()},redo:async()=>{for(let a of s){let r=this.app.vault.getAbstractFileByPath(a.path);r&&await this.app.fileManager.processFrontMatter(r,c=>{i?c.completed=!0:delete c.completed})}n.length>0&&await this.log.append({type:i?"complete":"uncomplete",id:n[0],payload:{ids:n,count:n.length,redo:!0}}),this.tree.rebuild(o),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 a=this.tree.get(this.focusId);a?.file&&(t=[a])}if(t.length===0){new L.Notice("Nothing to schedule.");return}let e=t[0],i=e.file?this.app.metadataCache.getFileCache(e.file)?.frontmatter:null,s=i&&(typeof i.due=="string"||typeof i.due=="number")?String(i.due):null,n=this.plugin.authorRegistry.all().map(a=>({id:a.id,name:a.name})),o=Me(i??{});new Pe(this.app,s,a=>{this.applyDue(t,a.iso,a.assignees)},{knownAuthors:n,currentAssignees:o}).open()}async applyDue(t,e,i=[]){let s=[],n=[],o=this.authorship.currentAuthorLink();for(let c of i)await this.plugin.ensureAuthorStubFor(this.noteFolder,c.id,c.name);let a=i.map(c=>this.plugin.authorRefFor(this.noteFolder,c.id,c.name));for(let c of t){if(!c.file)continue;let l=this.app.metadataCache.getFileCache(c.file)?.frontmatter;s.push({id:c.id,path:c.file.path,due:l?.due,task:l?.task,assignedTo:l?.assignedTo,assignedBy:l?.assignedBy}),await this.app.fileManager.processFrontMatter(c.file,d=>{e===null?delete d.due:(d.due=e,d.task=!0),a.length>0?(d.assignedTo=a,o&&(d.assignedBy=o.link),d.task=!0):(delete d.assignedTo,delete d.assignedBy)}),n.push(c.id)}if(this.render(),n.length>0){let c=n.map(l=>this.tree.get(l)).filter(l=>!!l);this.plugin.notifications.show({message:this.bulkActionMessage({verb:e===null?"Cleared due date":`Due ${se(Date.parse(e),this.plugin.settings)}`,nodes:c}),kind:"success",category:"edit",affectedIds:n,folder:this.noteFolder})}let r=this.noteFolder;this.plugin.getUndoStack(r).push({label:e===null?`Clear due date (${t.length})`:`Set due date (${t.length})`,undo:async()=>{for(let c of s){let l=this.app.vault.getAbstractFileByPath(c.path);l&&await this.app.fileManager.processFrontMatter(l,d=>{c.due===void 0?delete d.due:d.due=c.due,c.task===void 0?delete d.task:d.task=c.task,c.assignedTo===void 0?delete d.assignedTo:d.assignedTo=c.assignedTo,c.assignedBy===void 0?delete d.assignedBy:d.assignedBy=c.assignedBy})}this.tree.rebuild(r),this.render()}})}cmdAssign(){let t=this.getActionTargets();if(t.length===0){let o=this.tree.get(this.focusId);o?.file&&(t=[o])}if(t.length===0){new L.Notice("Nothing to assign.");return}let e=t[0],i=e.file?this.app.metadataCache.getFileCache(e.file)?.frontmatter:null,s=this.plugin.authorRegistry.all().map(o=>({id:o.id,name:o.name})),n=Me(i??{});new Re(this.app,{knownAuthors:s,currentAssignees:n},o=>{this.applyAssignees(t,o)}).open()}async applyAssignees(t,e){let i=this.authorship.currentAuthorLink();for(let r of e)await this.plugin.ensureAuthorStubFor(this.noteFolder,r.id,r.name);let s=e.map(r=>this.plugin.authorRefFor(this.noteFolder,r.id,r.name)),n=[],o=[];for(let r of t){if(!r.file)continue;let c=this.app.metadataCache.getFileCache(r.file)?.frontmatter;n.push({path:r.file.path,assignedTo:c?.assignedTo,assignedBy:c?.assignedBy,task:c?.task}),await this.app.fileManager.processFrontMatter(r.file,l=>{s.length>0?(l.assignedTo=s,i&&(l.assignedBy=i.link),l.task=!0):(delete l.assignedTo,delete l.assignedBy)}),o.push(r.id)}if(this.render(),o.length>0){let r=o.map(l=>this.tree.get(l)).filter(l=>!!l),c=e.map(l=>l.name).join(", ");this.plugin.notifications.show({message:this.bulkActionMessage({verb:s.length>0?`Assigned to ${c}`:"Cleared assignment",nodes:r}),kind:"success",category:"edit",affectedIds:o,folder:this.noteFolder})}let a=this.noteFolder;this.plugin.getUndoStack(a).push({label:s.length>0?`Assign (${t.length})`:`Clear assignment (${t.length})`,undo:async()=>{for(let r of n){let c=this.app.vault.getAbstractFileByPath(r.path);c&&await this.app.fileManager.processFrontMatter(c,l=>{r.assignedTo===void 0?delete l.assignedTo:l.assignedTo=r.assignedTo,r.assignedBy===void 0?delete l.assignedBy:l.assignedBy=r.assignedBy,r.task===void 0?delete l.task:l.task=r.task})}this.tree.rebuild(a),this.render()}})}isTask(t){if(!t.file)return!1;let e=this.app.metadataCache.getFileCache(t.file)?.frontmatter;return e?ee(e,"task")||e.task===!0||e.completed!==void 0:!1}async cmdToggleTask(){let t=this.getActionTargets();if(t.length===0){let a=this.tree.get(this.focusId);a?.file&&(t=[a])}if(t.length===0){new L.Notice("Nothing to toggle.");return}let e=t.some(a=>!this.isTaskTagged(a)),i=[],s=[];for(let a of t){if(!a.file)continue;let r=this.isTaskTagged(a),c=this.app.metadataCache.getFileCache(a.file)?.frontmatter;if(i.push({id:a.id,path:a.file.path,tags:c?.tags,completed:c?.completed,task:c?.task}),r===e)continue;let l=!1;await this.app.fileManager.processFrontMatter(a.file,d=>{e?(Xi(d,"task"),d.completed===void 0&&(d.completed=!1),l=d.completed===!0,delete d.task):(Zi(d,"task"),delete d.completed,delete d.task,l=!1)}),this.completedState.set(a.file.path,l),s.push(a.id)}if(this.render(),s.length>0){let a=e?"marked as task":"unmarked as task",r;if(s.length===1){let c=this.tree.get(s[0]);r=`"${c&&this.titleForNode(c).trim()||"(untitled)"}" ${a}`}else r=`${s.length} notes ${a}`;this.plugin.notifications.show({message:r,kind:"success",category:"edit",affectedIds:s,folder:this.noteFolder})}let n=this.noteFolder,o=async()=>{for(let a of i){let r=this.app.vault.getAbstractFileByPath(a.path);r&&await this.app.fileManager.processFrontMatter(r,c=>{a.tags===void 0?delete c.tags:c.tags=a.tags,a.completed===void 0?delete c.completed:c.completed=a.completed,a.task===void 0?delete c.task:c.task=a.task})}this.tree.rebuild(n),this.render()};this.plugin.getUndoStack(n).push({label:`${e?"Mark task":"Unmark task"} (${t.length})`,undo:o,redo:async()=>{for(let a of i){let r=this.app.vault.getAbstractFileByPath(a.path);r&&await this.app.fileManager.processFrontMatter(r,c=>{e?(Xi(c,"task"),c.completed===void 0&&(c.completed=!1),delete c.task):(Zi(c,"task"),delete c.completed,delete c.task)})}this.tree.rebuild(n),this.render()}})}async toggleCompletedForNode(t){if(!t.file)return;let e=t.file.path,i=this.isCompleted(t);await this.app.fileManager.processFrontMatter(t.file,n=>{n.completed=!i}),this.completedState.set(e,!i),await this.log.append({type:i?"uncomplete":"complete",id:t.id}),this.render();let s=this.noteFolder;this.plugin.getUndoStack(s).push({label:i?"Mark incomplete":"Mark complete",undo:async()=>{let n=this.app.vault.getAbstractFileByPath(e);n&&(await this.app.fileManager.processFrontMatter(n,o=>{o.completed=i}),this.tree.rebuild(s),this.render())}})}isTaskTagged(t){if(!t.file)return!1;let e=this.app.metadataCache.getFileCache(t.file)?.frontmatter;return e?ee(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 i=e.trim();return/^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(i)?i:null}inheritedColorForNode(t){let e=t,i=0,s=new Set;for(;e&&e.id!==G&&!s.has(e.id);){s.add(e.id);let n=this.colorForNode(e);if(n)return{hex:n,depth:i};e=e.parent?this.tree.get(e.parent):void 0,i+=1}return null}isDescendant(t,e){let i=this.tree.get(t),s=new Set;for(;i&&i.parent&&!s.has(i.id);){if(i.parent===e)return!0;s.add(i.id),i=this.tree.get(i.parent)}return!1}async moveAcrossThenReorder(t,e,i,s){let n=[],o=new Set;for(let b of t){let R=this.tree.get(b);R?.file&&(n.push({id:b,path:R.file.path,oldParent:R.parent}),o.add(R.parent??G))}o.add(e);let a=this.authorship.collectAuthorIds(t.map(b=>this.tree.get(b)).filter(b=>!!b)),r=this.noteFolder,c={};for(let b of o)c[b]=this.order.getOrder(r,b).slice();for(let b of n){let R=this.app.vault.getAbstractFileByPath(b.path);R&&(await this.app.fileManager.processFrontMatter(R,w=>{w.parent=e}),this.fmSync.scheduleParentChange(b.id,b.oldParent,e),await this.log.append({type:"parent_change",id:b.id,payload:{from:b.oldParent,to:e,reason:"drag"}}),this.order.removeChild(r,b.id))}this.tree.rebuild(r);let l=this.tree.getChildren(e).map(b=>b.id),d=new Set(t),I=l.filter(b=>!d.has(b)),g=I.indexOf(i);g<0&&(g=I.length),s==="after"&&(g+=1);let p=[...I.slice(0,g),...t.filter(b=>!!this.tree.get(b)),...I.slice(g)];this.order.setOrder(r,e,p),await this.order.save(r),await this.forceManualMode(e),await this.log.append({type:"reorder",id:e,payload:{dir:"drag-cross",parent:e,ids:t,count:t.length}});let u=this.focusId===e,f=u?t[0]:e,B=u?t.slice():[e];u?this.pendingFocusIds=B:(this.selection.clear(),this.cursorIdx=-1,this.pendingFocusIds=B),this.tree.rebuild(r),this.render({kind:"follow-cursor"});let Q=this.selectionGuardKey,E=()=>{if(this.selectionGuardKey!==Q||this.selection.has(f))return;let b=this.currentChildren.findIndex(R=>R.id===f);b<0||(this.selection.add(f),this.cursorIdx=b,this.render({kind:"follow-cursor"}))};setTimeout(E,120),setTimeout(E,400);let y=t.map(b=>this.tree.get(b)).filter(b=>!!b),v=this.tree.get(e),k=v?this.titleForNode(v):"(root)";this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Reparented",nodes:y,destination:`\u2192 "${k}"`}),kind:"success",category:"move",affectedIds:t,affectedAuthorIds:a,folder:r,actions:e===G?[]:[{label:"Jump to parent",onClick:()=>this.navigateTo(e)}]}),this.plugin.getUndoStack(r).push({label:`Move + reorder (${t.length})`,undo:async()=>{for(let b of n){let R=this.app.vault.getAbstractFileByPath(b.path);R&&(await this.app.fileManager.processFrontMatter(R,w=>{b.oldParent===null||b.oldParent===void 0?w.parent=G:w.parent=b.oldParent}),await this.log.append({type:"parent_change",id:b.id,payload:{from:e,to:b.oldParent,reason:"drag-undo"}}))}for(let[b,R]of Object.entries(c))if(R.length===0){let w=this.order.cache.get(r)??{};delete w[b],this.order.cache.set(r,w)}else this.order.setOrder(r,b,R);await this.order.save(r),this.pendingFocusIds=t.slice(),this.selection.clear(),this.cursorIdx=-1,this.tree.rebuild(r),this.render()},redo:async()=>{for(let b of n){let R=this.app.vault.getAbstractFileByPath(b.path);R&&(await this.app.fileManager.processFrontMatter(R,w=>{w.parent=e}),this.order.removeChild(r,b.id))}this.order.setOrder(r,e,p),await this.order.save(r),this.pendingFocusIds=t.slice(),this.focusId!==e&&(this.selection.clear(),this.cursorIdx=-1),this.tree.rebuild(r),this.render()}})}async reorderToTarget(t,e,i){let s=this.tree.get(e);if(!s)return;let n=t.map(Q=>this.tree.get(Q)).filter(Q=>!!Q&&!!Q.file);if(n.length===0)return;if(n.some(Q=>Q.id===e)){this.plugin.notifications.show({message:"Can't move a note into itself.",kind:"warning",category:"move",folder:this.noteFolder});return}if(i==="into"){for(let Q of n)if(this.isDescendant(e,Q.id)){this.plugin.notifications.show({message:`Can't nest "${this.titleForNode(Q)}" under one of its own descendants \u2014 that would create a cycle.`,kind:"warning",category:"move",folder:this.noteFolder});return}}let o=i==="into"?e:s.parent??G;if(n.some(Q=>(Q.parent??G)!==o)){let Q=Bt(),E=async()=>{i==="into"?await this.moveAcrossThenReorder(n.map(y=>y.id),o,"","after"):await this.moveAcrossThenReorder(n.map(y=>y.id),o,e,i)};if(Q.confirmCrossParentDrag){let y=this.titleForNode(s),v=n.length,k=i==="into"?"Nest":"Move",b=i==="into"?"as children of":"under";new Dt(this.app,i==="into"?"Nest under target?":"Move under different parent?",`${k} ${v} note${v===1?"":"s"} ${b} "${y}"? Their parent will change.`,k,R=>{R&&E()}).open()}else await E();return}let r=o,c=n.map(Q=>Q.id),l=this.tree.getChildren(r).map(Q=>Q.id),d=new Set(c),I=l.filter(Q=>!d.has(Q)),g=I.indexOf(e);if(g<0)return;i==="after"&&(g+=1);let p=[...I.slice(0,g),...c,...I.slice(g)];if(Is(p,l))return;let u=this.noteFolder,f=this.order.getOrder(u,r).slice();this.order.setOrder(u,r,p),await this.order.save(u),await this.forceManualMode(r),await this.log.append({type:"reorder",id:r,payload:{dir:"drag",parent:r,ids:c,count:c.length}}),this.pendingFocusIds=c.slice(),this.tree.rebuild(u),this.render();let B=c.map(Q=>this.tree.get(Q)).filter(Q=>!!Q);this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Reordered",nodes:B}),kind:"success",category:"reorder",affectedIds:c,folder:u}),this.plugin.getUndoStack(u).push({label:`Reorder (drag, ${c.length})`,undo:async()=>{if(f.length===0){let Q=this.order.cache.get(u)??{};delete Q[r],this.order.cache.set(u,Q)}else this.order.setOrder(u,r,f);await this.order.save(u),await this.log.append({type:"reorder",id:r,payload:{dir:"undo",parent:r,ids:c,count:c.length}}),this.pendingFocusIds=c.slice(),this.tree.rebuild(u),this.render()},redo:async()=>{this.order.setOrder(u,r,p),await this.order.save(u),await this.log.append({type:"reorder",id:r,payload:{dir:"redo:drag",parent:r,ids:c,count:c.length}}),this.pendingFocusIds=c.slice(),this.tree.rebuild(u),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(g=>this.tree.get(g)).filter(g=>!!g&&!!g.file);if(d.length===0)return;if(new Set(d.map(g=>g.parent)).size>1){new L.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 L.Notice("Nothing to reorder.");return}let i=e[0].parent??G,s=this.tree.getChildren(i).map(d=>d.id);if(s.length===0)return;let n=new Set(e.map(d=>d.id)),o=s.filter(d=>n.has(d));if(o.length===0)return;let a=ln(s,o,t);if(Is(a,s))return;let r=this.noteFolder,c=this.order.getOrder(r,i).slice();this.order.setOrder(r,i,a),await this.order.save(r),await this.forceManualMode(i),await this.log.append({type:"reorder",id:i,payload:{dir:t,parent:i,ids:o,count:o.length}}),this.pendingFocusIds=o.slice(),this.tree.rebuild(r),this.render({kind:"follow-cursor"});let l=o.map(d=>this.tree.get(d)).filter(d=>!!d);this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Moved",nodes:l,destination:t}),kind:"success",category:"reorder",affectedIds:o,folder:r}),this.plugin.getUndoStack(r).push({label:`Reorder (${t})`,undo:async()=>{if(c.length===0){let d=this.order.cache.get(r)??{};delete d[i],this.order.cache.set(r,d)}else this.order.setOrder(r,i,c);await this.order.save(r),await this.log.append({type:"reorder",id:i,payload:{dir:"undo",parent:i,ids:o,count:o.length}}),this.pendingFocusIds=o.slice(),this.tree.rebuild(r),this.render()},redo:async()=>{this.order.setOrder(r,i,a),await this.order.save(r),await this.log.append({type:"reorder",id:i,payload:{dir:`redo:${t}`,parent:i,ids:o,count:o.length}}),this.pendingFocusIds=o.slice(),this.tree.rebuild(r),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 L.Notice("Nothing selected to delete.");return}if(t.length===1){await this.deleteNote(t[0]);return}let e=[],i=new Set,s=p=>{if(!i.has(p.id)){i.add(p.id);for(let u of this.tree.getChildren(p.id))s(u);e.push(p)}};for(let p of t)s(p);let n=e.filter(p=>!!p.file),o=await Promise.all(n.map(p=>this.app.vault.read(p.file))),a=[];for(let p=0;p<n.length;p++){let u=n[p];a.push(...this.extractAttachments(this.stripFrontmatter(o[p])));let f=this.app.metadataCache.getFileCache(u.file)?.frontmatter;if(Array.isArray(f?.attachments))for(let B of f.attachments)typeof B=="string"&&B.trim()&&a.push(he(B))}let r=[...new Set(a)],c=e.length-t.length,l=async p=>{let u=await this.snapshotNotes(e,p),f=0;if(p)for(let M of r){let _=this.app.metadataCache.getFirstLinkpathDest(M,"");if(_)try{await this.app.fileManager.trashFile(_),await this.log.append({type:"attachment_remove",id:G,payload:{path:_.path}}),this.plugin.notifications.show({message:`Deleted attachment "${_.name}"`,kind:"warning",category:"attachment",affectedPaths:[_.path],folder:this.noteFolder}),f+=1}catch{}}let B=new Set;for(let M of e)M.parent&&B.add(M.parent);let Q=this.authorship.collectAuthorIds(e),E=new Set(t.map(M=>M.id)),y=this.currentChildren.map((M,_)=>E.has(M.id)?_:-1).filter(M=>M>=0),v=y.length>0?y[0]:-1,k=null;if(v>=0){for(let M=v+1;M<this.currentChildren.length;M++)if(!E.has(this.currentChildren[M].id)){k=this.currentChildren[M].id;break}if(!k){for(let M=v-1;M>=0;M--)if(!E.has(this.currentChildren[M].id)){k=this.currentChildren[M].id;break}}}for(let M of e)if(M.file){try{await this.app.fileManager.trashFile(M.file)}catch{}await this.log.append({type:"delete",id:M.id,payload:{path:M.file.path,attachmentsRemoved:p?r:[]}})}this.selection.clear(),this.cursorIdx=-1,k&&(this.pendingFocusIds=[k]),this.tree.rebuild(this.noteFolder);for(let M of B)e.some(_=>_.id===M)||this.fmSync.scheduleParentOfDeleted(M);this.render({kind:"follow-cursor"});let b=f>0?` with ${f} attachment${f===1?"":"s"}`:"",R=this.noteFolder,w=t.map(M=>M.id),D=!1,m=async()=>{D||(D=!0,this.selection.clear(),this.cursorIdx=-1,await this.restoreSnapshots(u,w.slice()))};this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Deleted",nodes:t,suffix:b.trim()||void 0}),kind:"warning",category:"delete",duration:0,affectedIds:t.map(M=>M.id),affectedAuthorIds:Q,folder:this.noteFolder,actions:[{label:"Undo delete",onClick:()=>void m()}]}),this.plugin.getUndoStack(R).push({label:`Delete ${t.length} note${t.length===1?"":"s"}`,undo:async()=>{await m()},redo:async()=>{this.selection.clear(),this.cursorIdx=-1,D=!1,await this.trashNotesAndAttachments(u)}}),this.focusView()},d=Bt(),I=d.confirmBulkDelete,g=r.length>0&&d.confirmAttachmentDelete;if(!I&&!g){await l(!1);return}new Ie(this.app,`${t.length} selected note${t.length===1?"":"s"}`,c,r.length,g,l).open()}async cmdSplit(t){let e=t??this.resolveActionTarget();if(!e?.file){new L.Notice("Pick a note to split.");return}let i=e.file,s=await this.app.vault.read(i),n=this.stripFrontmatter(s).replace(/\s+$/,""),o=n.split(/\r?\n/);if(n.trim().length<2){new L.Notice("Note is too short to split.");return}let a=s,r=i.path,c=async(l,d,I)=>{if(!l.trim()||!d.trim()){new L.Notice("Split would leave one part empty.");return}try{let g=s.startsWith("---")?s.slice(0,s.indexOf(` ----`,3)+4):"",p=g+(g?` +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)}`,i=this.app.vault.getMarkdownFiles().filter(o=>o.path.startsWith(t+"/"));for(let o of i){if(this.app.metadataCache.getFileCache(o)?.frontmatter?.id!==G)continue;if(o.path===e||this.app.vault.getAbstractFileByPath(e))return o;try{await this.app.fileManager.renameFile(o,e);let c=this.app.vault.getAbstractFileByPath(e);if(c instanceof q.TFile)return c}catch(c){console.warn("[Stashpad] home note rename failed; keeping legacy path",c)}return o}let s=new Date().toISOString(),n=["---",`id: ${G}`,"parent: null",`created: ${s}`,"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(i=>i.path.startsWith(t+"/"));for(let i of e){let s=this.app.metadataCache.getFileCache(i)?.frontmatter,n=s?.id;if(!n||n===G)continue;let o=s?.parent;(o==null||o===""||o==="null")&&(await this.app.fileManager.processFrontMatter(i,r=>{r.parent=G}),await this.log.append({type:"parent_change",id:n,payload:{from:null,to:G,reason:"migration"}}))}}async openInNewStashpadTab(t){let e=this.app.workspace,i=this.leaf,s=e.getLeaf("tab");await s.setViewState({type:gt,active:!0,state:{focusId:t,timeFilter:this.timeFilter,folderOverride:this.folderOverride}}),e.setActiveLeaf(s,{focus:!0}),e.revealLeaf(s);let n=e.on("active-leaf-change",()=>{if((()=>{let a=!1;return e.iterateAllLeaves(c=>{c===s&&(a=!0)}),a})())return;e.offref(n),(()=>{let a=!1;return e.iterateAllLeaves(c=>{c===i&&(a=!0)}),a})()&&(e.setActiveLeaf(i,{focus:!0}),e.revealLeaf(i))})}async openFolderInNewTab(t){let e=(t||"").trim().replace(/^\/+|\/+$/g,"");if(!e)return;let i=(this.plugin.settings.folder||"Stashpad").trim().replace(/^\/+|\/+$/g,"")||"Stashpad",s=this.app.workspace,n=this.leaf,o=s.getLeaf("tab");await o.setViewState({type:gt,active:!0,state:{focusId:G,folderOverride:e===i?null:e}}),s.setActiveLeaf(o,{focus:!0}),s.revealLeaf(o);let r=s.on("active-leaf-change",()=>{if((()=>{let l=!1;return s.iterateAllLeaves(p=>{p===o&&(l=!0)}),l})())return;s.offref(r),(()=>{let l=!1;return s.iterateAllLeaves(p=>{p===n&&(l=!0)}),l})()&&(s.setActiveLeaf(n,{focus:!0}),s.revealLeaf(n))})}cmdOpenInEditor(t){if(t){this.openFileAtEnd(t.file);return}let e=this.getActionTargets();if(e.length)for(let i of e)i.file&&this.openFileAtEnd(i.file)}cmdOpenParentInEditor(){let t=this.tree.get(this.focusId);if(!t?.file){new q.Notice("No focused parent to open.");return}this.openFileAtEnd(t.file)}async openFileAtEnd(t){let e=this.app.workspace,i=this.leaf,s=e.getLeaf("tab");await s.openFile(t,{active:!0}),e.setActiveLeaf(s,{focus:!0}),e.revealLeaf(s);let n=e.on("active-leaf-change",()=>{if((()=>{let l=!1;return e.iterateAllLeaves(p=>{p===s&&(l=!0)}),l})())return;e.offref(n),(()=>{let l=!1;return e.iterateAllLeaves(p=>{p===i&&(l=!0)}),l})()&&(e.setActiveLeaf(i,{focus:!0}),e.revealLeaf(i))}),r=s.view?.editor;r&&requestAnimationFrame(()=>{try{let a=r.lastLine(),c=r.getLine(a)?.length??0;r.setCursor({line:a,ch:c}),r.scrollIntoView({from:{line:a,ch:c},to:{line:a,ch:c}},!0),r.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 q.Notice("Nothing to pin.");return}let e=t.some(n=>!this.plugin.isPinned({folder:this.noteFolder,id:n.id})),i=0,s=0;for(let n of t){let o={folder:this.noteFolder,id:n.id};e?this.plugin.isPinned(o)||(await this.plugin.pinNote(o),i++):this.plugin.isPinned(o)&&(await this.plugin.unpinNote(o),s++)}i>0?new q.Notice(`Pinned ${i} note${i===1?"":"s"} to sidebar.`):s>0&&new q.Notice(`Unpinned ${s} note${s===1?"":"s"} from sidebar.`)}async cmdToggleComplete(){let t=this.getActionTargets();if(t.length===0){let r=this.tree.get(this.focusId);r?.file&&(t=[r])}if(t.length===0){new q.Notice("Nothing to toggle.");return}let i=t.some(r=>!this.isCompleted(r)),s=[],n=[];for(let r of t){if(!r.file)continue;let a=this.isCompleted(r);s.push({id:r.id,path:r.file.path,was:a}),a!==i&&(await this.app.fileManager.processFrontMatter(r.file,c=>{i?c.completed=!0:delete c.completed}),this.completedState.set(r.file.path,i),n.push(r.id))}if(this.render(),n.length>0){await this.log.append({type:i?"complete":"uncomplete",id:n[0],payload:{ids:n,count:n.length}});let r=n.map(a=>this.tree.get(a)).filter(a=>!!a);this.plugin.notifications.show({message:this.bulkActionMessage({verb:i?"Marked complete":"Unmarked",nodes:r}),kind:"success",category:i?"complete":"uncomplete",affectedIds:n,folder:this.noteFolder})}let o=this.noteFolder;this.plugin.getUndoStack(o).push({label:`${i?"Mark complete":"Unmark complete"} (${t.length})`,undo:async()=>{let r=[];for(let a of s){let c=this.app.vault.getAbstractFileByPath(a.path);c&&(await this.app.fileManager.processFrontMatter(c,l=>{a.was?l.completed=!0:delete l.completed}),n.includes(a.id)&&r.push(a.id))}r.length>0&&await this.log.append({type:i?"uncomplete":"complete",id:r[0],payload:{ids:r,count:r.length,undo:!0}}),this.tree.rebuild(o),this.render()},redo:async()=>{for(let r of s){let a=this.app.vault.getAbstractFileByPath(r.path);a&&await this.app.fileManager.processFrontMatter(a,c=>{i?c.completed=!0:delete c.completed})}n.length>0&&await this.log.append({type:i?"complete":"uncomplete",id:n[0],payload:{ids:n,count:n.length,redo:!0}}),this.tree.rebuild(o),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}taggedFromFm(t){return t?pe(t,"task")||t.task===!0:!1}cmdSetDue(){let t=this.getActionTargets();if(t.length===0){let r=this.tree.get(this.focusId);r?.file&&(t=[r])}if(t.length===0){new q.Notice("Nothing to schedule.");return}let e=t[0],i=e.file?this.app.metadataCache.getFileCache(e.file)?.frontmatter:null,s=i&&(typeof i.due=="string"||typeof i.due=="number")?String(i.due):null,n=this.plugin.authorRegistry.all().map(r=>({id:r.id,name:r.name})),o=Ue(i??{});new Oe(this.app,s,r=>{this.applyDue(t,r.iso,r.assignees)},{knownAuthors:n,currentAssignees:o}).open()}async applyDue(t,e,i=[]){let s=[],n=[],o=this.authorship.currentAuthorLink();for(let c of i)await this.plugin.ensureAuthorStubFor(this.noteFolder,c.id,c.name);let r=i.map(c=>this.plugin.authorRefFor(this.noteFolder,c.id,c.name));for(let c of t){if(!c.file)continue;let l=this.app.metadataCache.getFileCache(c.file)?.frontmatter,p=this.isTaskTagged(c);s.push({id:c.id,path:c.file.path,due:l?.due,task:l?.task,assignedTo:l?.assignedTo,assignedBy:l?.assignedBy,wasTagged:p}),await this.app.fileManager.processFrontMatter(c.file,h=>{e===null?delete h.due:(h.due=e,h.task=!0),r.length>0?(h.assignedTo=r,o&&(h.assignedBy=o.link),h.task=!0):(delete h.assignedTo,delete h.assignedBy)});let g=e!==null||r.length>0;this.taskTaggedState.set(c.file.path,g||p),n.push(c.id)}if(this.render(),n.length>0){let c=n.map(l=>this.tree.get(l)).filter(l=>!!l);this.plugin.notifications.show({message:this.bulkActionMessage({verb:e===null?"Cleared due date":`Due ${ae(Date.parse(e),this.plugin.settings)}`,nodes:c}),kind:"success",category:"edit",affectedIds:n,folder:this.noteFolder})}let a=this.noteFolder;this.plugin.getUndoStack(a).push({label:e===null?`Clear due date (${t.length})`:`Set due date (${t.length})`,undo:async()=>{for(let c of s){let l=this.app.vault.getAbstractFileByPath(c.path);l&&(await this.app.fileManager.processFrontMatter(l,p=>{c.due===void 0?delete p.due:p.due=c.due,c.task===void 0?delete p.task:p.task=c.task,c.assignedTo===void 0?delete p.assignedTo:p.assignedTo=c.assignedTo,c.assignedBy===void 0?delete p.assignedBy:p.assignedBy=c.assignedBy}),this.taskTaggedState.set(c.path,c.wasTagged))}this.tree.rebuild(a),this.render()}})}cmdAssign(){let t=this.getActionTargets();if(t.length===0){let o=this.tree.get(this.focusId);o?.file&&(t=[o])}if(t.length===0){new q.Notice("Nothing to assign.");return}let e=t[0],i=e.file?this.app.metadataCache.getFileCache(e.file)?.frontmatter:null,s=this.plugin.authorRegistry.all().map(o=>({id:o.id,name:o.name})),n=Ue(i??{});new qe(this.app,{knownAuthors:s,currentAssignees:n},o=>{this.applyAssignees(t,o)}).open()}async applyAssignees(t,e){let i=this.authorship.currentAuthorLink();for(let a of e)await this.plugin.ensureAuthorStubFor(this.noteFolder,a.id,a.name);let s=e.map(a=>this.plugin.authorRefFor(this.noteFolder,a.id,a.name)),n=[],o=[];for(let a of t){if(!a.file)continue;let c=this.app.metadataCache.getFileCache(a.file)?.frontmatter,l=this.isTaskTagged(a);n.push({path:a.file.path,assignedTo:c?.assignedTo,assignedBy:c?.assignedBy,task:c?.task,wasTagged:l}),await this.app.fileManager.processFrontMatter(a.file,p=>{s.length>0?(p.assignedTo=s,i&&(p.assignedBy=i.link),p.task=!0):(delete p.assignedTo,delete p.assignedBy)}),this.taskTaggedState.set(a.file.path,s.length>0||l),o.push(a.id)}if(this.render(),o.length>0){let a=o.map(l=>this.tree.get(l)).filter(l=>!!l),c=e.map(l=>l.name).join(", ");this.plugin.notifications.show({message:this.bulkActionMessage({verb:s.length>0?`Assigned to ${c}`:"Cleared assignment",nodes:a}),kind:"success",category:"edit",affectedIds:o,folder:this.noteFolder})}let r=this.noteFolder;this.plugin.getUndoStack(r).push({label:s.length>0?`Assign (${t.length})`:`Clear assignment (${t.length})`,undo:async()=>{for(let a of n){let c=this.app.vault.getAbstractFileByPath(a.path);c&&(await this.app.fileManager.processFrontMatter(c,l=>{a.assignedTo===void 0?delete l.assignedTo:l.assignedTo=a.assignedTo,a.assignedBy===void 0?delete l.assignedBy:l.assignedBy=a.assignedBy,a.task===void 0?delete l.task:l.task=a.task}),this.taskTaggedState.set(a.path,a.wasTagged))}this.tree.rebuild(r),this.render()}})}isTask(t){return t.file?this.isTaskTagged(t)?!0:this.app.metadataCache.getFileCache(t.file)?.frontmatter?.completed!==void 0:!1}async cmdToggleTask(){let t=this.getActionTargets();if(t.length===0){let r=this.tree.get(this.focusId);r?.file&&(t=[r])}if(t.length===0){new q.Notice("Nothing to toggle.");return}let e=t.some(r=>!this.isTaskTagged(r)),i=[],s=[];for(let r of t){if(!r.file)continue;let a=this.isTaskTagged(r),c=this.app.metadataCache.getFileCache(r.file)?.frontmatter;if(i.push({id:r.id,path:r.file.path,tags:c?.tags,completed:c?.completed,task:c?.task,wasTagged:a}),a===e)continue;let l=!1;await this.app.fileManager.processFrontMatter(r.file,p=>{e?(ns(p,"task"),p.completed===void 0&&(p.completed=!1),l=p.completed===!0,delete p.task):(os(p,"task"),delete p.completed,delete p.task,l=!1)}),this.completedState.set(r.file.path,l),this.taskTaggedState.set(r.file.path,e),s.push(r.id)}if(this.render(),s.length>0){let r=e?"marked as task":"unmarked as task",a;if(s.length===1){let c=this.tree.get(s[0]);a=`"${c&&this.titleForNode(c).trim()||"(untitled)"}" ${r}`}else a=`${s.length} notes ${r}`;this.plugin.notifications.show({message:a,kind:"success",category:"edit",affectedIds:s,folder:this.noteFolder})}let n=this.noteFolder,o=async()=>{for(let r of i){let a=this.app.vault.getAbstractFileByPath(r.path);a&&(await this.app.fileManager.processFrontMatter(a,c=>{r.tags===void 0?delete c.tags:c.tags=r.tags,r.completed===void 0?delete c.completed:c.completed=r.completed,r.task===void 0?delete c.task:c.task=r.task}),this.completedState.set(r.path,!!r.completed),this.taskTaggedState.set(r.path,r.wasTagged))}this.tree.rebuild(n),this.render()};this.plugin.getUndoStack(n).push({label:`${e?"Mark task":"Unmark task"} (${t.length})`,undo:o,redo:async()=>{for(let r of i){let a=this.app.vault.getAbstractFileByPath(r.path);if(!a)continue;let c=!1;await this.app.fileManager.processFrontMatter(a,l=>{e?(ns(l,"task"),l.completed===void 0&&(l.completed=!1),c=l.completed===!0,delete l.task):(os(l,"task"),delete l.completed,delete l.task,c=!1)}),this.completedState.set(r.path,c),this.taskTaggedState.set(r.path,e)}this.tree.rebuild(n),this.render()}})}async toggleCompletedForNode(t){if(!t.file)return;let e=t.file.path,i=this.isCompleted(t);await this.app.fileManager.processFrontMatter(t.file,n=>{n.completed=!i}),this.completedState.set(e,!i),await this.log.append({type:i?"uncomplete":"complete",id:t.id}),this.render();let s=this.noteFolder;this.plugin.getUndoStack(s).push({label:i?"Mark incomplete":"Mark complete",undo:async()=>{let n=this.app.vault.getAbstractFileByPath(e);n&&(await this.app.fileManager.processFrontMatter(n,o=>{o.completed=i}),this.tree.rebuild(s),this.render())}})}isTaskTagged(t){if(!t.file)return!1;let e=this.taskTaggedState.get(t.file.path);if(e!==void 0)return e;let i=this.app.metadataCache.getFileCache(t.file)?.frontmatter;return this.taggedFromFm(i)}colorForNode(t){if(!t.file)return null;let e=this.app.metadataCache.getFileCache(t.file)?.frontmatter?.color;if(typeof e!="string")return null;let i=e.trim();return/^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(i)?i:null}inheritedColorForNode(t){let e=t,i=0,s=new Set;for(;e&&e.id!==G&&!s.has(e.id);){s.add(e.id);let n=this.colorForNode(e);if(n)return{hex:n,depth:i};e=e.parent?this.tree.get(e.parent):void 0,i+=1}return null}isDescendant(t,e){let i=this.tree.get(t),s=new Set;for(;i&&i.parent&&!s.has(i.id);){if(i.parent===e)return!0;s.add(i.id),i=this.tree.get(i.parent)}return!1}async moveAcrossThenReorder(t,e,i,s){let n=[],o=new Set;for(let D of t){let L=this.tree.get(D);L?.file&&(n.push({id:D,path:L.file.path,oldParent:L.parent}),o.add(L.parent??G))}o.add(e);let r=this.authorship.collectAuthorIds(t.map(D=>this.tree.get(D)).filter(D=>!!D)),a=this.noteFolder,c={};for(let D of o)c[D]=this.order.getOrder(a,D).slice();for(let D of n){let L=this.app.vault.getAbstractFileByPath(D.path);L&&(await this.app.fileManager.processFrontMatter(L,S=>{S.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 l=this.tree.getChildren(e).map(D=>D.id),p=new Set(t),g=l.filter(D=>!p.has(D)),h=g.indexOf(i);h<0&&(h=g.length),s==="after"&&(h+=1);let I=[...g.slice(0,h),...t.filter(D=>!!this.tree.get(D)),...g.slice(h)];this.order.setOrder(a,e,I),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 u=this.focusId===e,f=u?t[0]:e,C=u?t.slice():[e];u?this.pendingFocusIds=C:(this.selection.clear(),this.cursorIdx=-1,this.pendingFocusIds=C),this.tree.rebuild(a),this.render({kind:"follow-cursor"});let m=this.selectionGuardKey,E=()=>{if(this.selectionGuardKey!==m||this.selection.has(f))return;let D=this.currentChildren.findIndex(L=>L.id===f);D<0||(this.selection.add(f),this.cursorIdx=D,this.render({kind:"follow-cursor"}))};setTimeout(E,120),setTimeout(E,400);let y=t.map(D=>this.tree.get(D)).filter(D=>!!D),w=this.tree.get(e),v=w?this.titleForNode(w):"(root)";this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Reparented",nodes:y,destination:`\u2192 "${v}"`}),kind:"success",category:"move",affectedIds:t,affectedAuthorIds:r,folder:a,actions:e===G?[]:[{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 L=this.app.vault.getAbstractFileByPath(D.path);L&&(await this.app.fileManager.processFrontMatter(L,S=>{D.oldParent===null||D.oldParent===void 0?S.parent=G:S.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,L]of Object.entries(c))if(L.length===0){let S=this.order.cache.get(a)??{};delete S[D],this.order.cache.set(a,S)}else this.order.setOrder(a,D,L);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 L=this.app.vault.getAbstractFileByPath(D.path);L&&(await this.app.fileManager.processFrontMatter(L,S=>{S.parent=e}),this.order.removeChild(a,D.id))}this.order.setOrder(a,e,I),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,i){let s=this.tree.get(e);if(!s)return;let n=t.map(m=>this.tree.get(m)).filter(m=>!!m&&!!m.file);if(n.length===0)return;if(n.some(m=>m.id===e)){this.plugin.notifications.show({message:"Can't move a note into itself.",kind:"warning",category:"move",folder:this.noteFolder});return}if(i==="into"){for(let m of n)if(this.isDescendant(e,m.id)){this.plugin.notifications.show({message:`Can't nest "${this.titleForNode(m)}" under one of its own descendants \u2014 that would create a cycle.`,kind:"warning",category:"move",folder:this.noteFolder});return}}let o=i==="into"?e:s.parent??G;if(n.some(m=>(m.parent??G)!==o)){let m=ft(),E=async()=>{i==="into"?await this.moveAcrossThenReorder(n.map(y=>y.id),o,"","after"):await this.moveAcrossThenReorder(n.map(y=>y.id),o,e,i)};if(m.confirmCrossParentDrag){let y=this.titleForNode(s),w=n.length,v=i==="into"?"Nest":"Move",D=i==="into"?"as children of":"under";new vt(this.app,i==="into"?"Nest under target?":"Move under different parent?",`${v} ${w} note${w===1?"":"s"} ${D} "${y}"? Their parent will change.`,v,L=>{L&&E()}).open()}else await E();return}let a=o,c=n.map(m=>m.id),l=this.tree.getChildren(a).map(m=>m.id),p=new Set(c),g=l.filter(m=>!p.has(m)),h=g.indexOf(e);if(h<0)return;i==="after"&&(h+=1);let I=[...g.slice(0,h),...c,...g.slice(h)];if(ys(I,l))return;let u=this.noteFolder,f=this.order.getOrder(u,a).slice();this.order.setOrder(u,a,I),await this.order.save(u),await this.forceManualMode(a),await this.log.append({type:"reorder",id:a,payload:{dir:"drag",parent:a,ids:c,count:c.length}}),this.pendingFocusIds=c.slice(),this.tree.rebuild(u),this.render();let C=c.map(m=>this.tree.get(m)).filter(m=>!!m);this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Reordered",nodes:C}),kind:"success",category:"reorder",affectedIds:c,folder:u}),this.plugin.getUndoStack(u).push({label:`Reorder (drag, ${c.length})`,undo:async()=>{if(f.length===0){let m=this.order.cache.get(u)??{};delete m[a],this.order.cache.set(u,m)}else this.order.setOrder(u,a,f);await this.order.save(u),await this.log.append({type:"reorder",id:a,payload:{dir:"undo",parent:a,ids:c,count:c.length}}),this.pendingFocusIds=c.slice(),this.tree.rebuild(u),this.render()},redo:async()=>{this.order.setOrder(u,a,I),await this.order.save(u),await this.log.append({type:"reorder",id:a,payload:{dir:"redo:drag",parent:a,ids:c,count:c.length}}),this.pendingFocusIds=c.slice(),this.tree.rebuild(u),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 p=[...this.selection].map(h=>this.tree.get(h)).filter(h=>!!h&&!!h.file);if(p.length===0)return;if(new Set(p.map(h=>h.parent)).size>1){new q.Notice("Reorder requires a single-parent selection.");return}e=p}else this.cursorIdx>=0&&this.currentChildren[this.cursorIdx]&&(e=[this.currentChildren[this.cursorIdx]]);if(e.length===0){new q.Notice("Nothing to reorder.");return}let i=e[0].parent??G,s=this.tree.getChildren(i).map(p=>p.id);if(s.length===0)return;let n=new Set(e.map(p=>p.id)),o=s.filter(p=>n.has(p));if(o.length===0)return;let r=vn(s,o,t);if(ys(r,s))return;let a=this.noteFolder,c=this.order.getOrder(a,i).slice();this.order.setOrder(a,i,r),await this.order.save(a),await this.forceManualMode(i),await this.log.append({type:"reorder",id:i,payload:{dir:t,parent:i,ids:o,count:o.length}}),this.pendingFocusIds=o.slice(),this.tree.rebuild(a),this.render({kind:"follow-cursor"});let l=o.map(p=>this.tree.get(p)).filter(p=>!!p);this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Moved",nodes:l,destination:t}),kind:"success",category:"reorder",affectedIds:o,folder:a}),this.plugin.getUndoStack(a).push({label:`Reorder (${t})`,undo:async()=>{if(c.length===0){let p=this.order.cache.get(a)??{};delete p[i],this.order.cache.set(a,p)}else this.order.setOrder(a,i,c);await this.order.save(a),await this.log.append({type:"reorder",id:i,payload:{dir:"undo",parent:i,ids:o,count:o.length}}),this.pendingFocusIds=o.slice(),this.tree.rebuild(a),this.render()},redo:async()=>{this.order.setOrder(a,i,r),await this.order.save(a),await this.log.append({type:"reorder",id:i,payload:{dir:`redo:${t}`,parent:i,ids:o,count:o.length}}),this.pendingFocusIds=o.slice(),this.tree.rebuild(a),this.render()}})}async cmdDelete(){let t=this.getActionTargets();if(t.length===0){let I=this.tree.get(this.focusId);I?.file&&(t=[I])}if(t.length===0){new q.Notice("Nothing selected to delete.");return}if(t.length===1){await this.deleteNote(t[0]);return}let e=[],i=new Set,s=I=>{if(!i.has(I.id)){i.add(I.id);for(let u of this.tree.getChildren(I.id))s(u);e.push(I)}};for(let I of t)s(I);let n=e.filter(I=>!!I.file),o=await Promise.all(n.map(I=>this.app.vault.read(I.file))),r=[];for(let I=0;I<n.length;I++){let u=n[I];r.push(...this.extractAttachments(this.stripFrontmatter(o[I])));let f=this.app.metadataCache.getFileCache(u.file)?.frontmatter;if(Array.isArray(f?.attachments))for(let C of f.attachments)typeof C=="string"&&C.trim()&&r.push(oe(C))}let a=[...new Set(r)],c=e.length-t.length,l=async I=>{let u=await this.snapshotNotes(e,I),f=0;if(I)for(let H of a){let $=this.app.metadataCache.getFirstLinkpathDest(H,"");if($)try{await this.app.fileManager.trashFile($),await this.log.append({type:"attachment_remove",id:G,payload:{path:$.path}}),this.plugin.notifications.show({message:`Deleted attachment "${$.name}"`,kind:"warning",category:"attachment",affectedPaths:[$.path],folder:this.noteFolder}),f+=1}catch{}}let C=new Set;for(let H of e)H.parent&&C.add(H.parent);let m=this.authorship.collectAuthorIds(e),E=new Set(t.map(H=>H.id)),y=this.currentChildren.map((H,$)=>E.has(H.id)?$:-1).filter(H=>H>=0),w=y.length>0?y[0]:-1,v=null;if(w>=0){for(let H=w+1;H<this.currentChildren.length;H++)if(!E.has(this.currentChildren[H].id)){v=this.currentChildren[H].id;break}if(!v){for(let H=w-1;H>=0;H--)if(!E.has(this.currentChildren[H].id)){v=this.currentChildren[H].id;break}}}for(let H of e)if(H.file){try{await this.app.fileManager.trashFile(H.file)}catch{}await this.log.append({type:"delete",id:H.id,payload:{path:H.file.path,attachmentsRemoved:I?a:[]}})}this.selection.clear(),this.cursorIdx=-1,v&&(this.pendingFocusIds=[v]),this.tree.rebuild(this.noteFolder);for(let H of C)e.some($=>$.id===H)||this.fmSync.scheduleParentOfDeleted(H);this.render({kind:"follow-cursor"});let D=f>0?` with ${f} attachment${f===1?"":"s"}`:"",L=this.noteFolder,S=t.map(H=>H.id),b=!1,Q=async()=>{b||(b=!0,this.selection.clear(),this.cursorIdx=-1,await this.restoreSnapshots(u,S.slice()))};this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Deleted",nodes:t,suffix:D.trim()||void 0}),kind:"warning",category:"delete",duration:0,affectedIds:t.map(H=>H.id),affectedAuthorIds:m,folder:this.noteFolder,actions:[{label:"Undo delete",onClick:()=>void Q()}]}),this.plugin.getUndoStack(L).push({label:`Delete ${t.length} note${t.length===1?"":"s"}`,undo:async()=>{await Q()},redo:async()=>{this.selection.clear(),this.cursorIdx=-1,b=!1,await this.trashNotesAndAttachments(u)}}),this.focusView()},p=ft(),g=p.confirmBulkDelete,h=a.length>0&&p.confirmAttachmentDelete;if(!g&&!h){await l(!1);return}new fe(this.app,`${t.length} selected note${t.length===1?"":"s"}`,c,a.length,h,l).open()}async cmdSplit(t){let e=t??this.resolveActionTarget();if(!e?.file){new q.Notice("Pick a note to split.");return}let i=e.file,s=await this.app.vault.read(i),n=this.stripFrontmatter(s).replace(/\s+$/,""),o=n.split(/\r?\n/);if(n.trim().length<2){new q.Notice("Note is too short to split.");return}let r=s,a=i.path,c=async(l,p,g)=>{if(!l.trim()||!p.trim()){new q.Notice("Split would leave one part empty.");return}try{let h=s.startsWith("---")?s.slice(0,s.indexOf(` +---`,3)+4):"",I=h+(h?` `:"")+l+` -`;await this.app.vault.modify(i,p);let u=e.parent??G,f=Date.parse(e.created||""),B=Number.isFinite(f)?new Date(f+1).toISOString():new Date().toISOString(),Q=await this.createNoteUnder(d,u,{record:!1,createdOverride:B});await this.log.append({type:"rename",id:e.id,payload:{action:"split",into:Q,...I}}),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 E=Q?this.tree.get(Q):void 0,y=E?.file?.path,v=y?await this.app.vault.read(E.file):null,k=this.noteFolder;this.plugin.getUndoStack(k).push({label:"Split note",undo:async()=>{if(y){let R=this.app.vault.getAbstractFileByPath(y);if(R)try{await this.app.fileManager.trashFile(R)}catch{}}let b=this.app.vault.getAbstractFileByPath(r);b&&await this.app.vault.modify(b,a),this.tree.rebuild(k),this.render()},redo:async()=>{let b=this.app.vault.getAbstractFileByPath(r);b&&await this.app.vault.modify(b,p),y&&v&&!await this.app.vault.adapter.exists(y)&&await this.app.vault.create(y,v),this.tree.rebuild(k),this.render()}})}catch(g){new L.Notice(`Stashpad: split failed (${g.message})`),console.error(g)}};new Ue(this.app,n,async l=>{let d=o.slice(0,l).join(` -`).replace(/\s+$/,""),I=o.slice(l).join(` -`).replace(/^\s+|\s+$/g,"");await c(d,I,{mode:"line",splitAtLine:l})},async l=>{let d=n.slice(0,l).replace(/\s+$/,""),I=n.slice(l).replace(/^\s+|\s+$/g,"");await c(d,I,{mode:"cursor",splitAtChar:l})}).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}cmdExportStash(t){return Ln(this,t)}cmdImportStash(){return Jn(this)}processStashFile(t){return ks(this,t)}async createNoteUnder(t,e,i={record:!0}){let s=(i.targetFolder??this.noteFolder).replace(/\/+$/,""),n=s!==this.noteFolder;await this.ensureFolder(s);let o=mt(),a=null;{let f=(this.plugin.settings.noteTemplates??{})[s];if(f){let B=this.app.vault.getAbstractFileByPath(f);if(B&&B.extension==="md")try{let Q=await this.app.vault.cachedRead(B),E=this.stripFrontmatter(Q);a=this.app.metadataCache.getFileCache(B)?.frontmatter??{},E.includes("{{body}}")?t=E.replace(/\{\{body\}\}/g,t):t.trim()?E.trim()&&(t=`${t} +`;await this.app.vault.modify(i,I);let u=e.parent??G,f=Date.parse(e.created||""),C=Number.isFinite(f)?new Date(f+1).toISOString():new Date().toISOString(),m=await this.createNoteUnder(p,u,{record:!1,createdOverride:C});await this.log.append({type:"rename",id:e.id,payload:{action:"split",into:m,...g}}),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 E=m?this.tree.get(m):void 0,y=E?.file?.path,w=y?await this.app.vault.read(E.file):null,v=this.noteFolder;this.plugin.getUndoStack(v).push({label:"Split note",undo:async()=>{if(y){let L=this.app.vault.getAbstractFileByPath(y);if(L)try{await this.app.fileManager.trashFile(L)}catch{}}let D=this.app.vault.getAbstractFileByPath(a);D&&await this.app.vault.modify(D,r),this.tree.rebuild(v),this.render()},redo:async()=>{let D=this.app.vault.getAbstractFileByPath(a);D&&await this.app.vault.modify(D,I),y&&w&&!await this.app.vault.adapter.exists(y)&&await this.app.vault.create(y,w),this.tree.rebuild(v),this.render()}})}catch(h){new q.Notice(`Stashpad: split failed (${h.message})`),console.error(h)}};new Pe(this.app,n,async l=>{let p=o.slice(0,l).join(` +`).replace(/\s+$/,""),g=o.slice(l).join(` +`).replace(/^\s+|\s+$/g,"");await c(p,g,{mode:"line",splitAtLine:l})},async l=>{let p=n.slice(0,l).replace(/\s+$/,""),g=n.slice(l).replace(/^\s+|\s+$/g,"");await c(p,g,{mode:"cursor",splitAtChar:l})}).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}cmdExportStash(t){return so(this,t)}cmdImportStash(){return no(this)}processStashFile(t){return Gs(this,t)}async createNoteUnder(t,e,i={record:!0}){let s=(i.targetFolder??this.noteFolder).replace(/\/+$/,""),n=s!==this.noteFolder;await this.ensureFolder(s);let o=Et(),r=null;{let f=(this.plugin.settings.noteTemplates??{})[s];if(f){let C=this.app.vault.getAbstractFileByPath(f);if(C&&C.extension==="md")try{let m=await this.app.vault.cachedRead(C),E=this.stripFrontmatter(m);r=this.app.metadataCache.getFileCache(C)?.frontmatter??{},E.includes("{{body}}")?t=E.replace(/\{\{body\}\}/g,t):t.trim()?E.trim()&&(t=`${t} -${E}`):t=E}catch(Q){console.warn("[Stashpad] template read failed",Q)}}}let r=kt(t,this.activeStopwords()),c=St(r,o),l=`${s}/${c}`,d=e??this.focusId,I=i.createdOverride??new Date().toISOString(),g=this.extractAttachments(t),p=this.authorship.currentAuthorLink();p&&this.authorship.ensureAuthorFile(p);let u=["---",`id: ${o}`,`parent: ${d}`,`created: ${I}`,`modified: ${I}`];if(p&&u.push(`author: "${p.link.replace(/"/g,'\\"')}"`),g.length>0){u.push("attachments:");for(let f of g)u.push(` - "${f.replace(/"/g,'\\"')}"`)}else u.push("attachments: []");u.push("---",t);try{let f=u.join(` -`);this.plugin.importService.suppress(l,6e4),await vt.timeAsync("write.createNote.file",()=>this.app.vault.create(l,f));try{let B=this.app.vault.getAbstractFileByPath(l);if(B&&B.extension==="md"){if(!n)this.tree.insertSynthetic({id:o,parent:d,children:[],file:B,created:I}),this.render(),this.fmSync.scheduleParentChange(o,null,d);else{this.render();let Q=s.split("/").pop()||s,E=(t.split(` -`).find(y=>y.trim())??"note").trim().slice(0,60);this.plugin.notifications.show({message:`"${E}" landed in \`${Q}\``,kind:"success",category:"create",duration:0,folder:s,affectedIds:[o],actions:[{label:"Jump to note",onClick:()=>{this.switchToFolderAndFocus(s,o)}}]})}if(a)try{await this.app.fileManager.processFrontMatter(B,Q=>{for(let[E,y]of Object.entries(a))zt.includes(E)||Q[E]===void 0&&(Q[E]=y)})}catch(Q){console.warn("[Stashpad] template fm overlay failed",Q)}}}catch{}if(await this.log.append({type:"create",id:o,payload:{path:l,parent:d}}),i.record!==!1){let B=t;this.plugin.getUndoStack(s).push({label:n?"Send note":"Create note",undo:async()=>{let Q=this.app.vault.getAbstractFileByPath(l);if(Q)try{await this.app.fileManager.trashFile(Q)}catch{}if(this.composerDraft=B,this.saveDraft(B),this.recordLastSubmitted(""),this.composerInputEl){this.composerInputEl.value=B;let E=B.length;this.composerInputEl.setSelectionRange(E,E),this.composerInputEl.focus()}n||this.tree.rebuild(this.noteFolder),this.render()},redo:async()=>{await this.app.vault.adapter.exists(l)||await this.app.vault.create(l,f),this.composerDraft="",this.saveDraft(""),this.recordLastSubmitted(B),this.composerInputEl&&(this.composerInputEl.value=""),n||this.tree.rebuild(this.noteFolder),this.render()}})}return o}catch(f){return new L.Notice(`Stashpad: failed to create note (${f.message})`),null}}extractAttachments(t){let e=[],i=/!\[\[([^\]\|]+)(?:\|[^\]]+)?\]\]/g,s;for(;(s=i.exec(t))!==null;)e.push(s[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 L.TFolder))throw new Error(`${t} exists and is not a folder`);return}try{await this.app.vault.createFolder(t)}catch(e){let i=e?.message??"";if(!/already exists/i.test(i))throw e}}async importAttachment(t){try{let e=await t.arrayBuffer(),i=`${this.noteFolder}/_attachments`;await this.ensureFolder(i);let s=t.name.replace(/[^\w.\-]+/g,"_"),n=Date.now().toString(36),o=`${i}/${n}-${s}`;return await this.app.vault.createBinary(o,e),await this.log.append({type:"attachment_add",id:G,payload:{path:o,name:t.name,size:t.size}}),this.plugin.notifications.show({message:`Attached ${t.name}`,kind:"success",category:"attachment",affectedPaths:[o],folder:this.noteFolder}),`![[${o}]]`}catch(e){return new L.Notice(`Stashpad: attachment failed (${e.message})`),null}}claimSelectedAsAuthor(){this.authorship.claimSelectedAsAuthor()}claimFolderAsAuthor(){this.authorship.claimFolderAsAuthor()}claimSelectedWithContributor(){this.authorship.claimSelectedWithContributor()}claimFolderWithContributor(){this.authorship.claimFolderWithContributor()}renderAuthorshipFooter(t,e){if(!e.file)return;let i=this.plugin.settings;if(!i.showAuthor&&!i.showContributors&&!i.showLastEdit)return;let s=this.app.metadataCache.getFileCache(e.file)?.frontmatter??{},n=typeof s.author=="string"?s.author:"",o=Array.isArray(s.contributors)?s.contributors.filter(p=>typeof p=="string"&&p.trim()!==""):[],a=typeof s.modified=="string"?s.modified:typeof s.created=="string"?s.created:"",r=i.showAuthor&&!!n,c=i.showContributors&&o.length>0,l=i.showLastEdit&&!!a;if(!r&&!c&&!l)return;let d=t.createDiv({cls:"stashpad-note-authorship"}),I=(p,u)=>{let f=u.replace(/^\[\[/,"").replace(/\]\]$/,""),B=f.indexOf("|"),Q=B>=0?f.slice(0,B):f,E=B>=0?f.slice(B+1):f.split("/").pop()??f,y=p.createEl("a",{cls:"internal-link",text:E});y.setAttribute("data-href",Q),y.setAttribute("href",Q)},g=[];r&&g.push(p=>{p.createSpan({cls:"stashpad-authorship-label",text:"by "}),I(p,n)}),c&&g.push(p=>{p.createSpan({cls:"stashpad-authorship-label",text:"with "}),o.forEach((u,f)=>{f>0&&p.createSpan({text:", "}),I(p,u)})}),l&&g.push(p=>{p.createSpan({cls:"stashpad-authorship-label",text:"edited "}),p.createSpan({text:this.formatTimeInline(a)})}),g.forEach((p,u)=>{u>0&&d.createSpan({cls:"stashpad-authorship-sep",text:"\xB7"});let f=d.createSpan({cls:"stashpad-authorship-piece"});p(f)}),d.addEventListener("click",p=>this.handleRenderedClick(p,e))}activeStopwords(){return this.plugin.settings.slugStopWords??Gt}scheduleSlugRename(t){let e=this.slugDebouncers.get(t.path);e&&e.cancel(),e=(0,L.debounce)(()=>void this.maybeRenameForSlug(t),3e4),this.slugDebouncers.set(t.path,e),e()}async maybeRenameForSlug(t){let e=pe(t.basename);if(!e||e===G)return;let i=await this.app.vault.cachedRead(t),s=this.stripFrontmatter(i),n=kt(s,this.activeStopwords()),o=St(n,e);if(t.name===o)return;let a=t.parent?`${t.parent.path}/${o}`:o;if(this.app.vault.getAbstractFileByPath(a))return;let r=t.path;try{await this.app.fileManager.renameFile(t,a),await this.log.append({type:"rename",id:e,payload:{from:r,to:a}})}catch{}}scheduleAttachmentSync(t){let e=this.attachmentDebouncers.get(t.path);e&&e.cancel(),e=(0,L.debounce)(()=>void this.syncAttachmentsFrontmatter(t),1500),this.attachmentDebouncers.set(t.path,e),e()}async syncAttachmentsFrontmatter(t){let e=await this.app.vault.cachedRead(t),i=this.stripFrontmatter(e),s=this.extractAttachments(i),n=this.app.metadataCache.getFileCache(t)?.frontmatter,o=Array.isArray(n?.attachments)?n.attachments:[];o.length===s.length&&o.every((r,c)=>r===s[c])||await this.app.fileManager.processFrontMatter(t,r=>{r.attachments=s})}stripFrontmatter(t){let e=t.replace(/^/,""),i=e.match(/^\s*---\s*\r?\n[\s\S]*?\r?\n---\s*(?:\r?\n|$)/);return i?e.slice(i[0].length):e}formatTime(t){if(!t)return"";let e=(0,L.moment)(t);if(!e.isValid())return"";if(Bt().useTemplatesFormat){let s=Ci(this.app);if(s)return`${e.format(s.dateFormat)} +${E}`):t=E}catch(m){console.warn("[Stashpad] template read failed",m)}}}let a=Dt(t,this.activeStopwords()),c=bt(a,o),l=`${s}/${c}`,p=e??this.focusId,g=i.createdOverride??new Date().toISOString(),h=this.extractAttachments(t),I=this.authorship.currentAuthorLink();I&&this.authorship.ensureAuthorFile(I);let u=["---",`id: ${o}`,`parent: ${p}`,`created: ${g}`,`modified: ${g}`];if(I&&u.push(`author: "${I.link.replace(/"/g,'\\"')}"`),h.length>0){u.push("attachments:");for(let f of h)u.push(` - "${f.replace(/"/g,'\\"')}"`)}else u.push("attachments: []");u.push("---",t);try{let f=u.join(` +`);this.plugin.importService.suppress(l,6e4),await St.timeAsync("write.createNote.file",()=>this.app.vault.create(l,f));try{let C=this.app.vault.getAbstractFileByPath(l);if(C&&C.extension==="md"){if(!n)this.tree.insertSynthetic({id:o,parent:p,children:[],file:C,created:g}),this.render(),this.fmSync.scheduleParentChange(o,null,p);else{this.render();let m=s.split("/").pop()||s,E=(t.split(` +`).find(y=>y.trim())??"note").trim().slice(0,60);this.plugin.notifications.show({message:`"${E}" landed in \`${m}\``,kind:"success",category:"create",duration:0,folder:s,affectedIds:[o],actions:[{label:"Jump to note",onClick:()=>{this.switchToFolderAndFocus(s,o)}}]})}if(r)try{await this.app.fileManager.processFrontMatter(C,m=>{for(let[E,y]of Object.entries(r))Wt.includes(E)||m[E]===void 0&&(m[E]=y)})}catch(m){console.warn("[Stashpad] template fm overlay failed",m)}}}catch{}if(await this.log.append({type:"create",id:o,payload:{path:l,parent:p}}),i.record!==!1){let C=t;this.plugin.getUndoStack(s).push({label:n?"Send note":"Create note",undo:async()=>{let m=this.app.vault.getAbstractFileByPath(l);if(m)try{await this.app.fileManager.trashFile(m)}catch{}if(this.composerDraft=C,this.saveDraft(C),this.recordLastSubmitted(""),this.composerInputEl){this.composerInputEl.value=C;let E=C.length;this.composerInputEl.setSelectionRange(E,E),this.composerInputEl.focus()}n||this.tree.rebuild(this.noteFolder),this.render()},redo:async()=>{await this.app.vault.adapter.exists(l)||await this.app.vault.create(l,f),this.composerDraft="",this.saveDraft(""),this.recordLastSubmitted(C),this.composerInputEl&&(this.composerInputEl.value=""),n||this.tree.rebuild(this.noteFolder),this.render()}})}return o}catch(f){return new q.Notice(`Stashpad: failed to create note (${f.message})`),null}}extractAttachments(t){let e=[],i=/!\[\[([^\]\|]+)(?:\|[^\]]+)?\]\]/g,s;for(;(s=i.exec(t))!==null;)e.push(s[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 q.TFolder))throw new Error(`${t} exists and is not a folder`);return}try{await this.app.vault.createFolder(t)}catch(e){let i=e?.message??"";if(!/already exists/i.test(i))throw e}}async importAttachment(t){try{let e=await t.arrayBuffer(),i=`${this.noteFolder}/_attachments`;await this.ensureFolder(i);let s=t.name.replace(/[^\w.\-]+/g,"_"),n=Date.now().toString(36),o=`${i}/${n}-${s}`;return await this.app.vault.createBinary(o,e),await this.log.append({type:"attachment_add",id:G,payload:{path:o,name:t.name,size:t.size}}),this.plugin.notifications.show({message:`Attached ${t.name}`,kind:"success",category:"attachment",affectedPaths:[o],folder:this.noteFolder}),`![[${o}]]`}catch(e){return new q.Notice(`Stashpad: attachment failed (${e.message})`),null}}claimSelectedAsAuthor(){this.authorship.claimSelectedAsAuthor()}claimFolderAsAuthor(){this.authorship.claimFolderAsAuthor()}claimSelectedWithContributor(){this.authorship.claimSelectedWithContributor()}claimFolderWithContributor(){this.authorship.claimFolderWithContributor()}renderAuthorshipFooter(t,e){if(!e.file)return;let i=this.plugin.settings;if(!i.showAuthor&&!i.showContributors&&!i.showLastEdit)return;let s=this.app.metadataCache.getFileCache(e.file)?.frontmatter??{},n=typeof s.author=="string"?s.author:"",o=Array.isArray(s.contributors)?s.contributors.filter(I=>typeof I=="string"&&I.trim()!==""):[],r=typeof s.modified=="string"?s.modified:typeof s.created=="string"?s.created:"",a=i.showAuthor&&!!n,c=i.showContributors&&o.length>0,l=i.showLastEdit&&!!r;if(!a&&!c&&!l)return;let p=t.createDiv({cls:"stashpad-note-authorship"}),g=(I,u)=>{let f=u.replace(/^\[\[/,"").replace(/\]\]$/,""),C=f.indexOf("|"),m=C>=0?f.slice(0,C):f,E=C>=0?f.slice(C+1):f.split("/").pop()??f,y=I.createEl("a",{cls:"internal-link",text:E});y.setAttribute("data-href",m),y.setAttribute("href",m)},h=[];a&&h.push(I=>{I.createSpan({cls:"stashpad-authorship-label",text:"by "}),g(I,n)}),c&&h.push(I=>{I.createSpan({cls:"stashpad-authorship-label",text:"with "}),o.forEach((u,f)=>{f>0&&I.createSpan({text:", "}),g(I,u)})}),l&&h.push(I=>{I.createSpan({cls:"stashpad-authorship-label",text:"edited "}),I.createSpan({text:this.formatTimeInline(r)})}),h.forEach((I,u)=>{u>0&&p.createSpan({cls:"stashpad-authorship-sep",text:"\xB7"});let f=p.createSpan({cls:"stashpad-authorship-piece"});I(f)}),p.addEventListener("click",I=>this.handleRenderedClick(I,e))}activeStopwords(){return this.plugin.settings.slugStopWords??Pt}scheduleSlugRename(t){let e=this.slugDebouncers.get(t.path);e&&e.cancel(),e=(0,q.debounce)(()=>void this.maybeRenameForSlug(t),3e4),this.slugDebouncers.set(t.path,e),e()}async maybeRenameForSlug(t){let e=Ce(t.basename);if(!e||e===G)return;let i=await this.app.vault.cachedRead(t),s=this.stripFrontmatter(i),n=Dt(s,this.activeStopwords()),o=bt(n,e);if(t.name===o)return;let r=t.parent?`${t.parent.path}/${o}`:o;if(this.app.vault.getAbstractFileByPath(r))return;let a=t.path;try{await this.app.fileManager.renameFile(t,r),await this.log.append({type:"rename",id:e,payload:{from:a,to:r}})}catch{}}scheduleAttachmentSync(t){let e=this.attachmentDebouncers.get(t.path);e&&e.cancel(),e=(0,q.debounce)(()=>void this.syncAttachmentsFrontmatter(t),1500),this.attachmentDebouncers.set(t.path,e),e()}async syncAttachmentsFrontmatter(t){let e=await this.app.vault.cachedRead(t),i=this.stripFrontmatter(e),s=this.extractAttachments(i),n=this.app.metadataCache.getFileCache(t)?.frontmatter,r=(Array.isArray(n?.attachments)?n.attachments:[]).filter(l=>typeof l=="string").map(l=>oe(l));if(r.length===s.length&&r.every((l,p)=>l===s[p]))return;let c=s.map(l=>Gt(l));await this.app.fileManager.processFrontMatter(t,l=>{l.attachments=c})}stripFrontmatter(t){let e=t.replace(/^/,""),i=e.match(/^\s*---\s*\r?\n[\s\S]*?\r?\n---\s*(?:\r?\n|$)/);return i?e.slice(i[0].length):e}formatTime(t){if(!t)return"";let e=(0,q.moment)(t);if(!e.isValid())return"";if(ft().useTemplatesFormat){let s=ki(this.app);if(s)return`${e.format(s.dateFormat)} ${e.format(s.timeFormat)}`}return`${e.format("YYYY.MM.DD")} -${e.format("HH:mm A")}`}formatTimeInline(t){if(!t)return"";let e=(0,L.moment)(t);if(!e.isValid())return"";if(Bt().useTemplatesFormat){let s=Ci(this.app);if(s){let n=/:ss/.test(s.timeFormat)?s.timeFormat:s.timeFormat.replace(/(:mm)/,"$1:ss");return`${e.format(s.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,L.Platform.isMobile){let a=0,r=()=>{!this.stickToListBottom||a>=8||(a++,Date.now()>=this.keyboardTransitionUntil&&(t.scrollTop=t.scrollHeight),window.setTimeout(r,120))};window.setTimeout(r,60);return}this.stickyRowObserver?.disconnect();let e=()=>{if(!this.stickToListBottom){this.stickyRowObserver?.disconnect(),this.stickyRowObserver=null;return}t.scrollTop=t.scrollHeight},i=new ResizeObserver(e);for(let a of Array.from(t.children))a instanceof HTMLElement&&i.observe(a);this.stickyRowObserver=i;let s=performance.now(),n=t.scrollHeight,o=()=>{if(!this.stickToListBottom)return;let a=t.scrollHeight;a!==n&&(t.scrollTop=a,n=a),performance.now()-s<3e4?requestAnimationFrame(o):(this.stickToListBottom=!1,this.stickyRowObserver?.disconnect(),this.stickyRowObserver=null)};requestAnimationFrame(o)}openNoteMenu(t,e){if(!e.file)return;let i=e.file,s=new L.Menu;s.addItem(r=>r.setTitle("Open in new Stashpad tab").setIcon("layout-grid").onClick(()=>{this.openInNewStashpadTab(e.id)})),s.addItem(r=>r.setTitle("Open in editor").setIcon("file-text").onClick(()=>{this.openFileAtEnd(i)})),s.addItem(r=>r.setTitle("Focus in Stashpad").setIcon("arrow-right").onClick(()=>this.navigateTo(e.id))),s.addSeparator(),s.addItem(r=>r.setTitle("Split note\u2026").setIcon("split").onClick(()=>void this.cmdSplit(e))),s.addItem(r=>r.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()})),s.addItem(r=>r.setTitle("Insert template\u2026").setIcon("file-plus-2").onClick(()=>this.cmdInsertTemplate())),s.addItem(r=>r.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()})),s.addSeparator(),s.addItem(r=>r.setTitle("Move to\u2026").setIcon("move").onClick(()=>this.cmdMovePicker())),s.addItem(r=>r.setTitle("Move to Home").setIcon("home").onClick(async()=>{await this.changeParent(e,G),this.plugin.settings.autoNavOnMoveOut&&this.focusId!==G&&this.navigateTo(G)}));let n={folder:this.noteFolder,id:e.id},o=this.plugin.isPinned(n);s.addItem(r=>r.setTitle(o?"Unpin from sidebar":"Pin to sidebar").setIcon(o?"pin-off":"pin").onClick(async()=>{o?await this.plugin.unpinNote(n):await this.plugin.pinNote(n)})),s.addItem(r=>r.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 a=this.isCompleted(e);s.addItem(r=>r.setTitle(a?"Mark incomplete":"Mark complete").setIcon(a?"circle":"check-circle").onClick(()=>{this.selection.has(e.id)||(this.selection.clear(),this.selection.add(e.id),this.lastSelected=e.id),this.cmdToggleComplete()})),s.addSeparator(),s.addItem(r=>r.setTitle("Delete").setIcon("trash").onClick(async()=>{await this.deleteNote(e)})),s.showAtMouseEvent(t)}async deleteNote(t){if(!t.file)return;let e=[],i=p=>{for(let u of this.tree.getChildren(p.id))i(u),e.push(u)};i(t);let s=[...e,t],n=s.filter(p=>!!p.file),o=await Promise.all(n.map(p=>this.app.vault.cachedRead(p.file))),a=[];for(let p=0;p<n.length;p++){let u=n[p];a.push(...this.extractAttachments(this.stripFrontmatter(o[p])));let f=this.app.metadataCache.getFileCache(u.file)?.frontmatter;if(Array.isArray(f?.attachments))for(let B of f.attachments)typeof B=="string"&&B.trim()&&a.push(he(B))}let r=[...new Set(a)],c=this.authorship.collectAuthorIds(s),l=async p=>{let u=await this.snapshotNotes(s,p),f=0;if(p)for(let D of r){let m=this.app.metadataCache.getFirstLinkpathDest(D,"");if(m)try{await this.app.fileManager.trashFile(m),await this.log.append({type:"attachment_remove",id:G,payload:{path:m.path}}),this.plugin.notifications.show({message:`Deleted attachment "${m.name}"`,kind:"warning",category:"attachment",affectedPaths:[m.path],folder:this.noteFolder}),f+=1}catch{}}let B=new Set;for(let D of s)D.parent&&B.add(D.parent);let Q=this.currentChildren.findIndex(D=>D.id===t.id),E=null;if(Q>=0){for(let D=Q+1;D<this.currentChildren.length;D++)if(this.currentChildren[D].id!==t.id){E=this.currentChildren[D].id;break}if(!E){for(let D=Q-1;D>=0;D--)if(this.currentChildren[D].id!==t.id){E=this.currentChildren[D].id;break}}}for(let D of s)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?r:[]}})}this.selection.clear(),this.cursorIdx=-1,E&&(this.pendingFocusIds=[E]),this.tree.rebuild(this.noteFolder),this.render({kind:"follow-cursor"});for(let D of B)s.some(m=>m.id===D)||this.fmSync.scheduleParentOfDeleted(D);let y=this.noteFolder,v=`Delete "${this.titleForNode(t)}"`,k=t.id,b=f>0?` with ${f} attachment${f===1?"":"s"}`:"",R=!1,w=async()=>{R||(R=!0,this.selection.clear(),this.cursorIdx=-1,await this.restoreSnapshots(u,[k]))};this.plugin.notifications.show({message:`Deleted "${this.titleForNode(t)}"${b}`,kind:"warning",category:"delete",duration:0,affectedIds:[t.id],affectedAuthorIds:c,folder:this.noteFolder,actions:[{label:"Undo delete",onClick:()=>void w()}]}),this.plugin.getUndoStack(y).push({label:v,undo:async()=>{await w()},redo:async()=>{this.selection.clear(),this.cursorIdx=-1,R=!1,await this.trashNotesAndAttachments(u)}})},d=Bt(),I=e.length>0&&d.confirmBulkDelete,g=r.length>0&&d.confirmAttachmentDelete;if(!I&&!g){await l(!1),this.focusView();return}new Ie(this.app,this.titleForNode(t),e.length,r.length,g,async p=>{await l(p),this.focusView()}).open()}async cmdSwapWithParent(){let t=this.cursorIdx>=0?this.currentChildren[this.cursorIdx]:null;if(!t?.file){new L.Notice("Pick a note first (move the cursor onto it).");return}if(!t.parent||t.parent===G){new L.Notice("Already at Home \u2014 no parent to swap with.");return}let e=this.tree.get(t.parent);if(!e?.file){new L.Notice("Couldn't find the parent note.");return}let i=e.parent??G,s=this.titleForNode(t),n=this.titleForNode(e),o=this.tree.getChildren(e.id).filter(r=>r.id!==t.id).length,a=[`"${n}" becomes a child of "${s}".`];o>0&&a.push(`${o} sibling${o===1?"":"s"} move with it.`),new Dt(this.app,"Swap notes?",a.join(` -`),"Swap",async r=>{r&&await this.swapParentChild(e,t,i)}).open()}offerSwapForDescendantMove(t,e){let i=this.tree.get(e);if(!i?.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(i.parent!==t.id){this.plugin.notifications.show({message:`Can't nest "${this.titleForNode(t)}" under "${this.titleForNode(i)}" \u2014 it's a deeper descendant. Only direct parent \u2194 child swaps are supported (try moving "${this.titleForNode(i)}" up first, then swap).`,kind:"warning",category:"move",affectedIds:[t.id,i.id],folder:this.noteFolder});return}let s=this.titleForNode(t),n=this.titleForNode(i),o=this.tree.getChildren(t.id).filter(r=>r.id!==i.id).length,a=[`"${s}" becomes a child of "${n}".`];o>0&&a.push(`${o} sibling${o===1?"":"s"} move with it.`),new Dt(this.app,"Confirm Note Swap",a.join(` -`),"Swap",async r=>{if(!r)return;let c=t.parent??G;await this.swapParentChild(t,i,c)}).open()}async swapParentChild(t,e,i){if(!t.file||!e.file)return;if(e.parent!==t.id){new L.Notice("Swap aborted: parent/child relationship changed.");return}let s=this.noteFolder,n=t.parent,o=this.tree.getChildren(t.id).filter(g=>g.id!==e.id).filter(g=>!!g.file),a=o.map(g=>({id:g.id,path:g.file.path,was:g.parent})),r=this.order.getOrder(s,i).slice(),c=this.order.getOrder(s,e.id).slice(),l=this.order.getOrder(s,t.id).slice();await this.app.fileManager.processFrontMatter(e.file,g=>{g.parent=i}),this.fmSync.scheduleParentChange(e.id,t.id,i),await this.app.fileManager.processFrontMatter(t.file,g=>{g.parent=e.id}),this.fmSync.scheduleParentChange(t.id,n,e.id);for(let g of o)await this.app.fileManager.processFrontMatter(g.file,p=>{p.parent=e.id}),this.fmSync.scheduleParentChange(g.id,t.id,e.id);if(r.length>0){let g=r.includes(t.id)?r.map(p=>p===t.id?e.id:p):[...r.filter(p=>p!==e.id),e.id];this.order.setOrder(s,i,g)}let d=o.map(g=>g.id),I=[t.id,...c.filter(g=>g!==t.id&&!d.includes(g)),...d];this.order.setOrder(s,e.id,I),this.order.setOrder(s,t.id,[]),await this.order.save(s),await this.log.append({type:"parent_change",id:e.id,payload:{from:t.id,to:i,reason:"swap"}}),await this.log.append({type:"parent_change",id:t.id,payload:{from:n,to:e.id,reason:"swap"}});for(let g of a)await this.log.append({type:"parent_change",id:g.id,payload:{from:g.was,to:e.id,reason:"swap"}});this.tree.rebuild(s),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:s}),this.plugin.getUndoStack(s).push({label:`Swap "${this.titleForNode(e)}" \u2194 parent`,undo:async()=>{let g=this.tree.get(t.id),p=this.tree.get(e.id);g?.file&&await this.app.fileManager.processFrontMatter(g.file,u=>{n==null||n===G?(delete u.parent,u.parent=G):u.parent=n}),p?.file&&await this.app.fileManager.processFrontMatter(p.file,u=>{u.parent=t.id});for(let u of a){let f=this.app.vault.getAbstractFileByPath(u.path);f&&await this.app.fileManager.processFrontMatter(f,B=>{u.was==null?B.parent=G:B.parent=u.was})}this.order.setOrder(s,i,r),this.order.setOrder(s,e.id,c),this.order.setOrder(s,t.id,l),await this.order.save(s),this.tree.rebuild(s),this.pendingFocusIds=[t.id],this.render({kind:"follow-cursor"})},redo:async()=>{await this.swapParentChild(t,e,i)}})}async changeParent(t,e,i={record:!0}){if(!t.file)return;let s=t.file,n=t.parent,o=r=>r??G;if(o(n)===o(e)){if(!i.quiet){let r=this.titleForNode(t),c=e===G?"Home":`"${this.titleForNode(this.tree.get(e)??t)}"`;this.plugin.notifications.show({message:`"${r}" is already under ${c}.`,kind:"info",category:"move",affectedIds:[t.id],folder:this.noteFolder})}return}if(e===t.id){i.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!==G&&this.isDescendant(e,t.id)){i.quiet||this.offerSwapForDescendantMove(t,e);return}let a=this.authorship.collectAuthorIds([t]);if(await this.app.fileManager.processFrontMatter(s,r=>{r.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),!i.quiet){let r=this.tree.get(e),c=r?this.titleForNode(r):"(root)";this.plugin.notifications.show({message:`Reparented "${this.titleForNode(t)}" \u2192 "${c}"`,kind:"success",category:"move",affectedIds:[t.id],affectedAuthorIds:a,folder:this.noteFolder,actions:e===G?[]:[{label:"Jump to parent",onClick:()=>this.navigateTo(e)}]})}if(i.record!==!1){let r=this.noteFolder,c=s.path,l=t.id;this.plugin.getUndoStack(r).push({label:"Move note",undo:async()=>{let d=this.app.vault.getAbstractFileByPath(c);if(d){await this.app.fileManager.processFrontMatter(d,I=>{I.parent=n}),this.pendingFocusIds=[l],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(r),this.render({kind:"follow-cursor"});{let I=this.selectionGuardKey,g=()=>{if(this.selectionGuardKey!==I||this.selection.has(l))return;let p=this.currentChildren.findIndex(u=>u.id===l);p<0||(this.selection.add(l),this.cursorIdx=p,this.render({kind:"follow-cursor"}))};setTimeout(g,120),setTimeout(g,400)}}},redo:async()=>{let d=this.app.vault.getAbstractFileByPath(c);if(d){await this.app.fileManager.processFrontMatter(d,I=>{I.parent=e}),this.pendingFocusIds=[l],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(r),this.render({kind:"follow-cursor"});{let I=this.selectionGuardKey,g=()=>{if(this.selectionGuardKey!==I||this.selection.has(l))return;let p=this.currentChildren.findIndex(u=>u.id===l);p<0||(this.selection.add(l),this.cursorIdx=p,this.render({kind:"follow-cursor"}))};setTimeout(g,120),setTimeout(g,400)}}}})}}};ue();var Ri=class{constructor(A,t,e){this.app=A;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 A=this.app.vault.adapter,t=this.baseDir.split("/").filter(Boolean),e="";for(let i of t)e=e?`${e}/${i}`:i,await A.exists(e)||await A.mkdir(e);this.dirOk=!0}append(A){let t=A.author??this.getAuthor()??"",e={ts:new Date().toISOString(),...A};t?e.author=t:delete e.author;let i=JSON.stringify(e)+` -`;return this.writeChain=this.writeChain.then(async()=>{try{await this.ensureDir();let s=this.app.vault.adapter;if(typeof s.append=="function")await s.append(this.logPath,i);else{let n=await s.exists(this.logPath)?await s.read(this.logPath):"";await s.write(this.logPath,n+i)}}catch(s){console.warn("Stashpad: log append failed",s)}}),Promise.resolve()}async readState(){let A=this.app.vault.adapter;if(!await A.exists(this.statePath))return{};try{return JSON.parse(await A.read(this.statePath))}catch{return{}}}async writeState(A){await this.ensureDir(),await this.app.vault.adapter.write(this.statePath,JSON.stringify(A,null,2))}};yt();var Pi=class{constructor(){this.undoStack=[];this.redoStack=[];this.cap=30}push(A){for(this.undoStack.push(A),this.redoStack.length=0;this.undoStack.length>this.cap;)this.undoStack.shift()}async undo(){let A=this.undoStack.pop();if(!A)return null;try{await A.undo()}catch(t){throw console.error("Stashpad: undo failed",t),t}return this.redoStack.push(A),A}async redo(){let A=this.redoStack.pop();if(!A)return null;try{await A.redo()}catch(t){throw console.error("Stashpad: redo failed",t),t}return this.undoStack.push(A),A}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 Li=class{constructor(A,t){this.app=A;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 A=this.app.vault.adapter;if(await A.exists(this.path)){let t=JSON.parse(await A.read(this.path));t&&typeof t=="object"&&t.authors&&(this.data={version:typeof t.version=="number"?t.version:1,authors:t.authors})}}catch(A){console.warn("[Stashpad] author registry load failed; starting empty",A),this.data={version:1,authors:{}}}}}all(){return Object.values(this.data.authors).sort((A,t)=>(t.lastSeen??"").localeCompare(A.lastSeen??""))}get(A){return this.data.authors[A]??null}record(A){let t=(A.id??"").trim();if(!t)return!1;let e=A.at??new Date().toISOString(),i=(A.name??"").trim(),s=this.data.authors[t],n=!1;if(!s)this.data.authors[t]={id:t,name:i,role:A.role?.trim()||void 0,department:A.department?.trim()||void 0,firstSeen:e,lastSeen:e,renames:[]},n=!0;else{if(i&&i!==s.name&&(s.renames.push({from:s.name,to:i,at:e}),s.name=i,n=!0),A.role!==void 0){let o=A.role.trim()||void 0;o!==s.role&&(s.role=o,n=!0)}if(A.department!==void 0){let o=A.department.trim()||void 0;o!==s.department&&(s.department=o,n=!0)}s.lastSeen=e}return n&&this.save(),n}replaceAll(A,t){let e=t??new Date().toISOString(),i={};for(let s of A){let n=(s.id??"").trim();if(!n)continue;let o=this.data.authors[n],a=(s.name??"").trim()||o?.name||"",r=o?.renames?[...o.renames]:[];o&&a&&a!==o.name&&r.push({from:o.name,to:a,at:e}),i[n]={id:n,name:a,role:s.role?.trim()||o?.role||void 0,department:s.department?.trim()||o?.department||void 0,firstSeen:o?.firstSeen??e,lastSeen:e,renames:r}}this.data={version:1,authors:i},this.save()}async ensureDir(){if(this.dirOk)return;let A=this.app.vault.adapter,e=this.path.slice(0,this.path.lastIndexOf("/")).split("/").filter(Boolean),i="";for(let s of e)i=i?`${i}/${s}`:s,await A.exists(i)||await A.mkdir(i);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(A){console.warn("[Stashpad] author registry save failed",A)}}),this.writeChain}};var ht=require("obsidian");yt();Tt();ue();Mt();var Ji=new Set(["_attachments","_authors","_exports","_imports","_processed","_archive",".archive"]),qn="_archive",Kn=new Set([_t,"edtz"]),ke=class ke{constructor(A){this.plugin=A;this.pending=new Map;this.pendingFolders=new Map;this.suppressed=new Set;this.armed=!1;this.drainTimer=null;this.draining=!1;this.pendingEncryptedStashes=new Set;this.encryptedNotifySnoozeUntil=0}setArmed(A){this.armed=A}isArmed(){return this.armed}get app(){return this.plugin.app}enqueue(A){this.armed&&this.plugin.settings.autoImport&&this.isEligiblePath(A)&&(this.pending.set(A.path,Date.now()),this.arm())}enqueueFolder(A){if(!this.armed||!this.plugin.settings.autoImport||this.suppressed.has(A.path))return;let t=A.parent?.path?.replace(/\/+$/,"")??"";this.plugin.discoverStashpadFolders().includes(t)&&(Ji.has(A.name)||(this.pendingFolders.set(A.path,Date.now()),this.arm()))}arm(){this.drainTimer!=null&&window.clearTimeout(this.drainTimer),this.drainTimer=window.setTimeout(()=>void this.drain(),ke.DEBOUNCE_MS)}suppress(A,t=4e3){this.suppressed.add(A),window.setTimeout(()=>this.suppressed.delete(A),t)}async createNote(A,t){this.suppress(A,6e4),await this.app.vault.create(A,t)}isEligiblePath(A){if(this.suppressed.has(A.path)||Kn.has(A.extension))return!1;let t=A.parent?.path?.replace(/\/+$/,"")??"",e=t.split("/").pop()??"";return Ji.has(e)?!1:this.plugin.discoverStashpadFolders().includes(t)}async isStillImportable(A){if(!this.isEligiblePath(A))return!1;if(A.extension==="md")try{let{fm:t}=we(await this.app.vault.read(A));if(t&&typeof t.id=="string"&&t.id)return!1}catch{}return!0}async drain(){if(this.drainTimer=null,!this.draining){this.draining=!0;try{let A=[...this.pending.keys()];this.pending.clear();let t=A.map(d=>this.app.vault.getAbstractFileByPath(d)).filter(d=>d instanceof ht.TFile),e=[];for(let d of t)await this.isStillImportable(d)&&e.push(d);let i=[...this.pendingFolders.keys()];this.pendingFolders.clear();let s=i.map(d=>this.app.vault.getAbstractFileByPath(d)).filter(d=>d instanceof ht.TFolder).map(d=>({folder:d,files:this.filesUnder(d.path)})).filter(d=>d.files.length>0),n=s.reduce((d,I)=>d+I.files.length,0),o=e.length+n;if(o===0)return;await this.plugin.importLog.load();let a=e,r=[],c=e.filter(d=>this.plugin.importLog.findDuplicate(d.name,d.stat?.size??null));if(c.length>0){let d=c.slice(0,5).map(p=>`\u2022 ${p.name}`).join(` -`),I=c.length>5?` -\u2026and ${c.length-5} more`:"",g=await this.dupChoice(`${c.length} of these look like files you've imported before: -${d}${I} +${e.format("HH:mm A")}`}formatTimeInline(t){if(!t)return"";let e=(0,q.moment)(t);if(!e.isValid())return"";if(ft().useTemplatesFormat){let s=ki(this.app);if(s){let n=/:ss/.test(s.timeFormat)?s.timeFormat:s.timeFormat.replace(/(:mm)/,"$1:ss");return`${e.format(s.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,q.Platform.isMobile){let r=0,a=()=>{!this.stickToListBottom||r>=8||(r++,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},i=new ResizeObserver(e);for(let r of Array.from(t.children))r instanceof HTMLElement&&i.observe(r);this.stickyRowObserver=i;let s=performance.now(),n=t.scrollHeight,o=()=>{if(!this.stickToListBottom)return;let r=t.scrollHeight;r!==n&&(t.scrollTop=r,n=r),performance.now()-s<3e4?requestAnimationFrame(o):(this.stickToListBottom=!1,this.stickyRowObserver?.disconnect(),this.stickyRowObserver=null)};requestAnimationFrame(o)}openNoteMenu(t,e){if(!e.file)return;let i=e.file,s=new q.Menu;s.addItem(a=>a.setTitle("Open in new Stashpad tab").setIcon("layout-grid").onClick(()=>{this.openInNewStashpadTab(e.id)})),s.addItem(a=>a.setTitle("Open in editor").setIcon("file-text").onClick(()=>{this.openFileAtEnd(i)})),s.addItem(a=>a.setTitle("Focus in Stashpad").setIcon("arrow-right").onClick(()=>this.navigateTo(e.id))),s.addSeparator(),s.addItem(a=>a.setTitle("Split note\u2026").setIcon("split").onClick(()=>void this.cmdSplit(e))),s.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()})),s.addItem(a=>a.setTitle("Insert template\u2026").setIcon("file-plus-2").onClick(()=>this.cmdInsertTemplate())),s.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()})),s.addSeparator(),s.addItem(a=>a.setTitle("Move to\u2026").setIcon("move").onClick(()=>this.cmdMovePicker())),s.addItem(a=>a.setTitle("Move to Home").setIcon("home").onClick(async()=>{await this.changeParent(e,G),this.plugin.settings.autoNavOnMoveOut&&this.focusId!==G&&this.navigateTo(G)}));let n={folder:this.noteFolder,id:e.id},o=this.plugin.isPinned(n);s.addItem(a=>a.setTitle(o?"Unpin from sidebar":"Pin to sidebar").setIcon(o?"pin-off":"pin").onClick(async()=>{o?await this.plugin.unpinNote(n):await this.plugin.pinNote(n)})),s.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 r=this.isCompleted(e);s.addItem(a=>a.setTitle(r?"Mark incomplete":"Mark complete").setIcon(r?"circle":"check-circle").onClick(()=>{this.selection.has(e.id)||(this.selection.clear(),this.selection.add(e.id),this.lastSelected=e.id),this.cmdToggleComplete()})),s.addSeparator(),s.addItem(a=>a.setTitle("Delete").setIcon("trash").onClick(async()=>{await this.deleteNote(e)})),s.addSeparator(),s.addItem(a=>a.setTitle("More commands\u2026").setIcon("terminal").onClick(()=>this.openCommandPalette())),s.showAtMouseEvent(t)}async deleteNote(t){if(!t.file)return;let e=[],i=I=>{for(let u of this.tree.getChildren(I.id))i(u),e.push(u)};i(t);let s=[...e,t],n=s.filter(I=>!!I.file),o=await Promise.all(n.map(I=>this.app.vault.cachedRead(I.file))),r=[];for(let I=0;I<n.length;I++){let u=n[I];r.push(...this.extractAttachments(this.stripFrontmatter(o[I])));let f=this.app.metadataCache.getFileCache(u.file)?.frontmatter;if(Array.isArray(f?.attachments))for(let C of f.attachments)typeof C=="string"&&C.trim()&&r.push(oe(C))}let a=[...new Set(r)],c=this.authorship.collectAuthorIds(s),l=async I=>{let u=await this.snapshotNotes(s,I),f=0;if(I)for(let b of a){let Q=this.app.metadataCache.getFirstLinkpathDest(b,"");if(Q)try{await this.app.fileManager.trashFile(Q),await this.log.append({type:"attachment_remove",id:G,payload:{path:Q.path}}),this.plugin.notifications.show({message:`Deleted attachment "${Q.name}"`,kind:"warning",category:"attachment",affectedPaths:[Q.path],folder:this.noteFolder}),f+=1}catch{}}let C=new Set;for(let b of s)b.parent&&C.add(b.parent);let m=this.currentChildren.findIndex(b=>b.id===t.id),E=null;if(m>=0){for(let b=m+1;b<this.currentChildren.length;b++)if(this.currentChildren[b].id!==t.id){E=this.currentChildren[b].id;break}if(!E){for(let b=m-1;b>=0;b--)if(this.currentChildren[b].id!==t.id){E=this.currentChildren[b].id;break}}}for(let b of s)if(b.file){try{await this.app.fileManager.trashFile(b.file)}catch{}await this.log.append({type:"delete",id:b.id,payload:{path:b.file.path,attachmentsRemoved:I?a:[]}})}this.selection.clear(),this.cursorIdx=-1,E&&(this.pendingFocusIds=[E]),this.tree.rebuild(this.noteFolder),this.render({kind:"follow-cursor"});for(let b of C)s.some(Q=>Q.id===b)||this.fmSync.scheduleParentOfDeleted(b);let y=this.noteFolder,w=`Delete "${this.titleForNode(t)}"`,v=t.id,D=f>0?` with ${f} attachment${f===1?"":"s"}`:"",L=!1,S=async()=>{L||(L=!0,this.selection.clear(),this.cursorIdx=-1,await this.restoreSnapshots(u,[v]))};this.plugin.notifications.show({message:`Deleted "${this.titleForNode(t)}"${D}`,kind:"warning",category:"delete",duration:0,affectedIds:[t.id],affectedAuthorIds:c,folder:this.noteFolder,actions:[{label:"Undo delete",onClick:()=>void S()}]}),this.plugin.getUndoStack(y).push({label:w,undo:async()=>{await S()},redo:async()=>{this.selection.clear(),this.cursorIdx=-1,L=!1,await this.trashNotesAndAttachments(u)}})},p=ft(),g=e.length>0&&p.confirmBulkDelete,h=a.length>0&&p.confirmAttachmentDelete;if(!g&&!h){await l(!1),this.focusView();return}new fe(this.app,this.titleForNode(t),e.length,a.length,h,async I=>{await l(I),this.focusView()}).open()}async cmdSwapWithParent(){let t=this.cursorIdx>=0?this.currentChildren[this.cursorIdx]:null;if(!t?.file){new q.Notice("Pick a note first (move the cursor onto it).");return}if(!t.parent||t.parent===G){new q.Notice("Already at Home \u2014 no parent to swap with.");return}let e=this.tree.get(t.parent);if(!e?.file){new q.Notice("Couldn't find the parent note.");return}let i=e.parent??G,s=this.titleForNode(t),n=this.titleForNode(e),o=this.tree.getChildren(e.id).filter(a=>a.id!==t.id).length,r=[`"${n}" becomes a child of "${s}".`];o>0&&r.push(`${o} sibling${o===1?"":"s"} move with it.`),new vt(this.app,"Swap notes?",r.join(` +`),"Swap",async a=>{a&&await this.swapParentChild(e,t,i)}).open()}offerSwapForDescendantMove(t,e){let i=this.tree.get(e);if(!i?.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(i.parent!==t.id){this.plugin.notifications.show({message:`Can't nest "${this.titleForNode(t)}" under "${this.titleForNode(i)}" \u2014 it's a deeper descendant. Only direct parent \u2194 child swaps are supported (try moving "${this.titleForNode(i)}" up first, then swap).`,kind:"warning",category:"move",affectedIds:[t.id,i.id],folder:this.noteFolder});return}let s=this.titleForNode(t),n=this.titleForNode(i),o=this.tree.getChildren(t.id).filter(a=>a.id!==i.id).length,r=[`"${s}" becomes a child of "${n}".`];o>0&&r.push(`${o} sibling${o===1?"":"s"} move with it.`),new vt(this.app,"Confirm Note Swap",r.join(` +`),"Swap",async a=>{if(!a)return;let c=t.parent??G;await this.swapParentChild(t,i,c)}).open()}async swapParentChild(t,e,i){if(!t.file||!e.file)return;if(e.parent!==t.id){new q.Notice("Swap aborted: parent/child relationship changed.");return}let s=this.noteFolder,n=t.parent,o=this.tree.getChildren(t.id).filter(h=>h.id!==e.id).filter(h=>!!h.file),r=o.map(h=>({id:h.id,path:h.file.path,was:h.parent})),a=this.order.getOrder(s,i).slice(),c=this.order.getOrder(s,e.id).slice(),l=this.order.getOrder(s,t.id).slice();await this.app.fileManager.processFrontMatter(e.file,h=>{h.parent=i}),this.fmSync.scheduleParentChange(e.id,t.id,i),await this.app.fileManager.processFrontMatter(t.file,h=>{h.parent=e.id}),this.fmSync.scheduleParentChange(t.id,n,e.id);for(let h of o)await this.app.fileManager.processFrontMatter(h.file,I=>{I.parent=e.id}),this.fmSync.scheduleParentChange(h.id,t.id,e.id);if(a.length>0){let h=a.includes(t.id)?a.map(I=>I===t.id?e.id:I):[...a.filter(I=>I!==e.id),e.id];this.order.setOrder(s,i,h)}let p=o.map(h=>h.id),g=[t.id,...c.filter(h=>h!==t.id&&!p.includes(h)),...p];this.order.setOrder(s,e.id,g),this.order.setOrder(s,t.id,[]),await this.order.save(s),await this.log.append({type:"parent_change",id:e.id,payload:{from:t.id,to:i,reason:"swap"}}),await this.log.append({type:"parent_change",id:t.id,payload:{from:n,to:e.id,reason:"swap"}});for(let h of r)await this.log.append({type:"parent_change",id:h.id,payload:{from:h.was,to:e.id,reason:"swap"}});this.tree.rebuild(s),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,...p],folder:s}),this.plugin.getUndoStack(s).push({label:`Swap "${this.titleForNode(e)}" \u2194 parent`,undo:async()=>{let h=this.tree.get(t.id),I=this.tree.get(e.id);h?.file&&await this.app.fileManager.processFrontMatter(h.file,u=>{n==null||n===G?(delete u.parent,u.parent=G):u.parent=n}),I?.file&&await this.app.fileManager.processFrontMatter(I.file,u=>{u.parent=t.id});for(let u of r){let f=this.app.vault.getAbstractFileByPath(u.path);f&&await this.app.fileManager.processFrontMatter(f,C=>{u.was==null?C.parent=G:C.parent=u.was})}this.order.setOrder(s,i,a),this.order.setOrder(s,e.id,c),this.order.setOrder(s,t.id,l),await this.order.save(s),this.tree.rebuild(s),this.pendingFocusIds=[t.id],this.render({kind:"follow-cursor"})},redo:async()=>{await this.swapParentChild(t,e,i)}})}async changeParent(t,e,i={record:!0}){if(!t.file)return!1;let s=t.file,n=t.parent,o=a=>a??G;if(o(n)===o(e)){if(!i.quiet){let a=this.titleForNode(t),c=e===G?"Home":`"${this.titleForNode(this.tree.get(e)??t)}"`;this.plugin.notifications.show({message:`"${a}" is already under ${c}.`,kind:"info",category:"move",affectedIds:[t.id],folder:this.noteFolder})}return!1}if(e===t.id)return i.quiet||this.plugin.notifications.show({message:`Can't move "${this.titleForNode(t)}" into itself.`,kind:"warning",category:"move",affectedIds:[t.id],folder:this.noteFolder}),!1;if(e!==G&&this.isDescendant(e,t.id))return i.quiet||this.offerSwapForDescendantMove(t,e),!1;let r=this.authorship.collectAuthorIds([t]);if(await this.app.fileManager.processFrontMatter(s,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),!i.quiet&&!i.silentSuccess){let a=this.tree.get(e),c=a?this.titleForNode(a):"(root)";this.plugin.notifications.show({message:`Reparented "${this.titleForNode(t)}" \u2192 "${c}"`,kind:"success",category:"move",affectedIds:[t.id],affectedAuthorIds:r,folder:this.noteFolder,actions:e===G?[]:[{label:"Jump to parent",onClick:()=>this.navigateTo(e)}]})}if(i.record!==!1){let a=this.noteFolder,c=s.path,l=t.id;this.plugin.getUndoStack(a).push({label:"Move note",undo:async()=>{let p=this.app.vault.getAbstractFileByPath(c);if(p){await this.app.fileManager.processFrontMatter(p,g=>{g.parent=n}),this.pendingFocusIds=[l],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 g=this.selectionGuardKey,h=()=>{if(this.selectionGuardKey!==g||this.selection.has(l))return;let I=this.currentChildren.findIndex(u=>u.id===l);I<0||(this.selection.add(l),this.cursorIdx=I,this.render({kind:"follow-cursor"}))};setTimeout(h,120),setTimeout(h,400)}}},redo:async()=>{let p=this.app.vault.getAbstractFileByPath(c);if(p){await this.app.fileManager.processFrontMatter(p,g=>{g.parent=e}),this.pendingFocusIds=[l],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 g=this.selectionGuardKey,h=()=>{if(this.selectionGuardKey!==g||this.selection.has(l))return;let I=this.currentChildren.findIndex(u=>u.id===l);I<0||(this.selection.add(l),this.cursorIdx=I,this.render({kind:"follow-cursor"}))};setTimeout(h,120),setTimeout(h,400)}}}})}return!0}notifyBatchMove(t,e,i){if(!t.length)return;let s=this.tree.get(e),n=e===G?"Home":`"${s?this.titleForNode(s):"the destination"}"`,o=a=>i.get(a.id)??0,r;if(t.length===1){let a=this.titleForNode(t[0]),c=o(t[0]);r=c>0?`Moved "${a}" and its ${c} ${c===1?"child":"children"} \u2192 ${n}`:`Moved "${a}" \u2192 ${n}`}else{let a=t.reduce((c,l)=>c+o(l),0);r=a>0?`Moved ${t.length} notes (${a} nested) \u2192 ${n}`:`Moved ${t.length} notes \u2192 ${n}`}this.plugin.notifications.show({message:r,kind:"success",category:"move",duration:e===G?void 0:0,affectedIds:t.map(a=>a.id),affectedAuthorIds:this.authorship.collectAuthorIds(t),folder:this.noteFolder,actions:e===G?[]:[{label:"Jump to destination",onClick:()=>this.navigateTo(e)}]})}};var It=require("obsidian");wt();Mt();var zi=class extends It.ItemView{constructor(t,e){super(t);this.plugin=e;this.renderTimer=null}getViewType(){return ge}getDisplayText(){return"Stashpad folders"}getIcon(){return"folders"}async onOpen(){this.render(),this.registerEvent(this.app.workspace.on("active-leaf-change",()=>this.scheduleRender())),this.registerEvent(this.app.workspace.on("layout-change",()=>this.scheduleRender())),this.registerEvent(this.app.vault.on("create",()=>this.scheduleRender())),this.registerEvent(this.app.vault.on("delete",()=>this.scheduleRender())),this.registerEvent(this.app.vault.on("rename",()=>this.scheduleRender())),this.registerEvent(this.app.metadataCache.on("changed",()=>this.scheduleRender()))}scheduleRender(){this.renderTimer==null&&(this.renderTimer=window.setTimeout(()=>{this.renderTimer=null,this.containerEl.isConnected&&this.render()},100))}render(){let t=this.contentEl;t.empty(),t.addClass("stashpad-folderpanel-root");let e=this.clampFrac(this.plugin.settings.folderPanelPinnedFraction??.5),i=t.createDiv({cls:"stashpad-folderpanel-section stashpad-folderpanel-pinned"});i.style.flex=`0 0 ${(e*100).toFixed(2)}%`,i.createDiv({cls:"stashpad-folderpanel-heading"}).setText("Pinned"),this.renderPinned(i.createDiv({cls:"stashpad-folderpanel-list"}));let s=t.createDiv({cls:"stashpad-folderpanel-divider"});s.createDiv({cls:"stashpad-folderpanel-divider-grip"}),this.attachDividerDrag(t,i,s);let n=t.createDiv({cls:"stashpad-folderpanel-section stashpad-folderpanel-folders"});n.style.flex="1 1 0",n.createDiv({cls:"stashpad-folderpanel-heading"}).setText("Folders"),this.renderFolders(n.createDiv({cls:"stashpad-folderpanel-list"}))}clampFrac(t){return Number.isFinite(t)?Math.max(.15,Math.min(.85,t)):.5}attachDividerDrag(t,e,i){let s=null,n=r=>{let a=t.getBoundingClientRect();if(a.height<=0)return;let c=this.clampFrac((r.clientY-a.top)/a.height);s=c,e.style.flex=`0 0 ${(c*100).toFixed(2)}%`},o=r=>{document.removeEventListener("pointermove",n),document.removeEventListener("pointerup",o),document.body.removeClass("stashpad-folderpanel-resizing");try{i.releasePointerCapture(r.pointerId)}catch{}s!=null&&(this.plugin.settings.folderPanelPinnedFraction=s,this.plugin.saveSettings())};i.addEventListener("pointerdown",r=>{r.preventDefault(),document.body.addClass("stashpad-folderpanel-resizing");try{i.setPointerCapture(r.pointerId)}catch{}document.addEventListener("pointermove",n),document.addEventListener("pointerup",o)})}renderPinned(t){let e=this.plugin.listPinnedNotes();if(e.length===0){t.createDiv({cls:"stashpad-folderpanel-empty",text:"No pinned notes yet \u2014 pin a note from its right-click menu."});return}for(let i of e){let s=i.file,n=t.createEl("button",{cls:"stashpad-folderpanel-row stashpad-folderpanel-pin-row"});(0,It.setIcon)(n.createSpan({cls:"stashpad-folderpanel-row-icon"}),"pin"),n.createSpan({cls:"stashpad-folderpanel-row-label",text:this.titleFromFile(s)});let o=i.folder.split("/").pop()||i.folder;n.createSpan({cls:"stashpad-folderpanel-row-sub",text:o}),n.onclick=()=>{this.onNavigateAway(),this.plugin.revealNoteInStashpad(s)}}}onNavigateAway(){It.Platform.isMobile&&(this.plugin.suppressComposerAutofocusUntil=Date.now()+1500,this.app.workspace.leftSplit?.collapse?.())}titleFromFile(t){return t.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ").trim()||t.basename}openFolders(){let t=new Set;for(let e of this.app.workspace.getLeavesOfType(gt)){let i=(e.view?.noteFolder??"").replace(/\/+$/,"");i&&t.add(i)}return t}renderFolders(t){let e=this.plugin.discoverStashpadFolders();if(e.length===0){t.createDiv({cls:"stashpad-folderpanel-empty",text:"No Stashpad folders yet."});return}let i=this.openFolders();for(let s of e){let n=i.has(s.replace(/\/+$/,"")),o=t.createDiv({cls:"stashpad-folderpanel-row stashpad-folderpanel-folder-row"});n&&o.addClass("is-open");let r=o.createSpan({cls:"stashpad-folderpanel-dot"});r.setAttr("aria-label",n?"Open in a tab":"Not open"),n&&r.setAttr("title","Open in a tab");let a=s.split("/").pop()||s;o.createSpan({cls:"stashpad-folderpanel-row-label",text:a});let c=o.createDiv({cls:"stashpad-folderpanel-actions"}),l=c.createEl("button",{cls:"stashpad-folderpanel-iconbtn"});(0,It.setIcon)(l,"folder-search"),l.setAttr("aria-label","Reveal in file explorer"),l.onclick=g=>{g.stopPropagation(),this.revealFolder(s)};let p=c.createEl("button",{cls:"stashpad-folderpanel-iconbtn"});(0,It.setIcon)(p,"plus-square"),p.setAttr("aria-label","Open in new tab"),p.onclick=g=>{g.stopPropagation(),this.onNavigateAway(),this.plugin.activateViewForFolder(s)},o.onclick=()=>{this.onNavigateAway(),this.jumpToFolder(s)},o.oncontextmenu=g=>{g.preventDefault(),this.openFolderMenu(g,s)}}}jumpToFolder(t){let e=t.replace(/\/+$/,""),i=this.app.workspace.getLeavesOfType(gt).find(s=>(s.view?.noteFolder??"").replace(/\/+$/,"")===e);if(i){this.app.workspace.revealLeaf(i);return}this.plugin.activateViewForFolder(t)}revealFolder(t){let e=this.app.vault.getAbstractFileByPath(t.replace(/\/+$/,""));if(!(e instanceof It.TFolder)){new It.Notice("Couldn't find that folder.");return}let i=this.app.workspace.getLeavesOfType("file-explorer")[0];if(!i){new It.Notice("File explorer isn't available.");return}this.app.workspace.revealLeaf(i),i.view?.revealInFolder?.(e)}openFolderMenu(t,e){let i=new It.Menu;i.addItem(s=>s.setTitle("Open in new tab").setIcon("plus-square").onClick(()=>void this.plugin.activateViewForFolder(e))),i.addItem(s=>s.setTitle("Reveal in file explorer").setIcon("folder-search").onClick(()=>this.revealFolder(e))),i.addSeparator(),i.addItem(s=>s.setTitle("Rename\u2026").setIcon("pencil").onClick(()=>this.renameFolder(e))),i.addSeparator(),i.addItem(s=>{s.setTitle("Delete folder\u2026").setIcon("trash").onClick(()=>this.deleteFolder(e)),s.setWarning?.(!0)}),i.showAtMouseEvent(t)}renameFolder(t){let e=t.replace(/\/+$/,""),i=this.app.vault.getAbstractFileByPath(e);if(!(i instanceof It.TFolder)){new It.Notice("Couldn't find that folder.");return}let s=i.name;new Rs(this.app,s,async n=>{let o=n.trim().replace(/[\\/:]+/g,"").trim();if(!o||o===s)return;let a=`${i.parent?.path&&i.parent.path!=="/"?`${i.parent.path}/`:""}${o}`;if(this.app.vault.getAbstractFileByPath(a)){new It.Notice(`"${o}" already exists.`);return}try{await this.app.fileManager.renameFile(i,a),(this.plugin.settings.folder||"").replace(/\/+$/,"")===e&&(this.plugin.settings.folder=a,await this.plugin.saveSettings()),new It.Notice(`Renamed to "${o}".`)}catch(c){console.warn("[Stashpad] folder rename failed",c),new It.Notice("Rename failed (see console).")}}).open()}deleteFolder(t){let e=t.replace(/\/+$/,""),i=this.app.vault.getAbstractFileByPath(e);if(!(i instanceof It.TFolder)){new It.Notice("Couldn't find that folder.");return}let s=this.app.vault.getMarkdownFiles().filter(o=>(o.parent?.path?.replace(/\/+$/,"")??"")===e||o.path.startsWith(e+"/")).length,n=i.name;new vt(this.app,`Delete "${n}"?`,`This moves the entire folder \u2014 about ${s} note${s===1?"":"s"} plus its attachments and exports \u2014 to the trash. +You can restore it from your system/Obsidian trash.`,"Delete folder",async o=>{if(o)try{await this.app.fileManager.trashFile(i),new It.Notice(`Deleted "${n}".`)}catch(r){console.warn("[Stashpad] folder delete failed",r),new It.Notice("Delete failed (see console).")}}).open()}},Rs=class extends It.Modal{constructor(t,e,i){super(t);this.current=e;this.onSubmit=i;this.delivered=!1}onOpen(){this.modalEl.addClass("stashpad-compact-modal"),this.contentEl.empty(),this.titleEl.setText("Rename folder");let t=this.contentEl.createEl("input",{type:"text"});t.addClass("stashpad-folderpanel-rename-input"),t.value=this.current;let e=this.contentEl.createDiv({cls:"stashpad-folderpanel-rename-footer"});e.createEl("button",{text:"Cancel"}).onclick=()=>this.close();let i=e.createEl("button",{cls:"mod-cta",text:"Rename"}),s=()=>{this.delivered=!0;let n=t.value;this.close(),this.onSubmit(n)};i.onclick=s,this.scope.register([],"Enter",n=>{n.preventDefault(),t.value.trim()&&s()}),requestAnimationFrame(()=>{t.focus(),t.select()})}onClose(){this.contentEl.empty()}};async function Ps(d){let A=d.workspace.getLeavesOfType(ge);if(A.length>0){d.workspace.revealLeaf(A[0]);return}let t=d.workspace.getLeftLeaf(!1);if(!t){new It.Notice("Stashpad: couldn't open the folder panel.");return}await t.setViewState({type:ge,active:!0}),d.workspace.revealLeaf(t)}Be();var Vi=class{constructor(A,t,e){this.app=A;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 A=this.app.vault.adapter,t=this.baseDir.split("/").filter(Boolean),e="";for(let i of t)e=e?`${e}/${i}`:i,await A.exists(e)||await A.mkdir(e);this.dirOk=!0}append(A){let t=A.author??this.getAuthor()??"",e={ts:new Date().toISOString(),...A};t?e.author=t:delete e.author;let i=JSON.stringify(e)+` +`;return this.writeChain=this.writeChain.then(async()=>{try{await this.ensureDir();let s=this.app.vault.adapter;if(typeof s.append=="function")await s.append(this.logPath,i);else{let n=await s.exists(this.logPath)?await s.read(this.logPath):"";await s.write(this.logPath,n+i)}}catch(s){console.warn("Stashpad: log append failed",s)}}),Promise.resolve()}async readState(){let A=this.app.vault.adapter;if(!await A.exists(this.statePath))return{};try{return JSON.parse(await A.read(this.statePath))}catch{return{}}}async writeState(A){await this.ensureDir(),await this.app.vault.adapter.write(this.statePath,JSON.stringify(A,null,2))}};wt();var Wi=class{constructor(){this.undoStack=[];this.redoStack=[];this.cap=30}push(A){for(this.undoStack.push(A),this.redoStack.length=0;this.undoStack.length>this.cap;)this.undoStack.shift()}async undo(){let A=this.undoStack.pop();if(!A)return null;try{await A.undo()}catch(t){throw console.error("Stashpad: undo failed",t),t}return this.redoStack.push(A),A}async redo(){let A=this.redoStack.pop();if(!A)return null;try{await A.redo()}catch(t){throw console.error("Stashpad: redo failed",t),t}return this.undoStack.push(A),A}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 Xi=class{constructor(A,t){this.app=A;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 A=this.app.vault.adapter;if(await A.exists(this.path)){let t=JSON.parse(await A.read(this.path));t&&typeof t=="object"&&t.authors&&(this.data={version:typeof t.version=="number"?t.version:1,authors:t.authors})}}catch(A){console.warn("[Stashpad] author registry load failed; starting empty",A),this.data={version:1,authors:{}}}}}all(){return Object.values(this.data.authors).sort((A,t)=>(t.lastSeen??"").localeCompare(A.lastSeen??""))}get(A){return this.data.authors[A]??null}record(A){let t=(A.id??"").trim();if(!t)return!1;let e=A.at??new Date().toISOString(),i=(A.name??"").trim(),s=this.data.authors[t],n=!1;if(!s)this.data.authors[t]={id:t,name:i,role:A.role?.trim()||void 0,department:A.department?.trim()||void 0,firstSeen:e,lastSeen:e,renames:[]},n=!0;else{if(i&&i!==s.name&&(s.renames.push({from:s.name,to:i,at:e}),s.name=i,n=!0),A.role!==void 0){let o=A.role.trim()||void 0;o!==s.role&&(s.role=o,n=!0)}if(A.department!==void 0){let o=A.department.trim()||void 0;o!==s.department&&(s.department=o,n=!0)}s.lastSeen=e}return n&&this.save(),n}replaceAll(A,t){let e=t??new Date().toISOString(),i={};for(let s of A){let n=(s.id??"").trim();if(!n)continue;let o=this.data.authors[n],r=(s.name??"").trim()||o?.name||"",a=o?.renames?[...o.renames]:[];o&&r&&r!==o.name&&a.push({from:o.name,to:r,at:e}),i[n]={id:n,name:r,role:s.role?.trim()||o?.role||void 0,department:s.department?.trim()||o?.department||void 0,firstSeen:o?.firstSeen??e,lastSeen:e,renames:a}}this.data={version:1,authors:i},this.save()}async ensureDir(){if(this.dirOk)return;let A=this.app.vault.adapter,e=this.path.slice(0,this.path.lastIndexOf("/")).split("/").filter(Boolean),i="";for(let s of e)i=i?`${i}/${s}`:s,await A.exists(i)||await A.mkdir(i);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(A){console.warn("[Stashpad] author registry save failed",A)}}),this.writeChain}};var pt=require("obsidian");wt();Rt();Be();di();Mt();var Zi=new Set(["_attachments","_authors","_exports","_imports","_processed","_archive",".archive"]),oo="_archive",ao=new Set([te,"edtz"]),Ne=class Ne{constructor(A){this.plugin=A;this.pending=new Map;this.pendingFolders=new Map;this.suppressed=new Set;this.armed=!1;this.drainTimer=null;this.draining=!1;this.pendingEncryptedStashes=new Set;this.encryptedNotifySnoozeUntil=0}setArmed(A){this.armed=A}isArmed(){return this.armed}get app(){return this.plugin.app}enqueue(A){this.armed&&this.plugin.settings.autoImport&&this.isEligiblePath(A)&&(this.pending.set(A.path,Date.now()),this.arm())}enqueueFolder(A){if(!this.armed||!this.plugin.settings.autoImport||this.suppressed.has(A.path))return;let t=A.parent?.path?.replace(/\/+$/,"")??"";this.plugin.discoverStashpadFolders().includes(t)&&(Zi.has(A.name)||(this.pendingFolders.set(A.path,Date.now()),this.arm()))}arm(){this.drainTimer!=null&&window.clearTimeout(this.drainTimer),this.drainTimer=window.setTimeout(()=>void this.drain(),Ne.DEBOUNCE_MS)}suppress(A,t=4e3){this.suppressed.add(A),window.setTimeout(()=>this.suppressed.delete(A),t)}async createNote(A,t){this.suppress(A,6e4),await this.app.vault.create(A,t)}isEligiblePath(A){if(this.suppressed.has(A.path)||ao.has(A.extension))return!1;let t=A.parent?.path?.replace(/\/+$/,"")??"",e=t.split("/").pop()??"";return Zi.has(e)?!1:this.plugin.discoverStashpadFolders().includes(t)}async isStillImportable(A){if(!this.isEligiblePath(A))return!1;if(A.extension==="md")try{let{fm:t}=Se(await this.app.vault.read(A));if(t&&typeof t.id=="string"&&t.id)return!1}catch{}return!0}async drain(){if(this.drainTimer=null,!this.draining){this.draining=!0;try{let A=[...this.pending.keys()];this.pending.clear();let t=A.map(p=>this.app.vault.getAbstractFileByPath(p)).filter(p=>p instanceof pt.TFile),e=[];for(let p of t)await this.isStillImportable(p)&&e.push(p);let i=[...this.pendingFolders.keys()];this.pendingFolders.clear();let s=i.map(p=>this.app.vault.getAbstractFileByPath(p)).filter(p=>p instanceof pt.TFolder).map(p=>({folder:p,files:this.filesUnder(p.path)})).filter(p=>p.files.length>0),n=s.reduce((p,g)=>p+g.files.length,0),o=e.length+n;if(o===0)return;await this.plugin.importLog.load();let r=e,a=[],c=e.filter(p=>this.plugin.importLog.findDuplicate(p.name,p.stat?.size??null));if(c.length>0){let p=c.slice(0,5).map(I=>`\u2022 ${I.name}`).join(` +`),g=c.length>5?` +\u2026and ${c.length-5} more`:"",h=await this.dupChoice(`${c.length} of these look like files you've imported before: +${p}${g} -Replace the existing notes, skip the duplicates, or import them anyway as new notes?`);if(g==="skip"){let p=new Set(c.map(u=>u.path));if(a=e.filter(u=>!p.has(u.path)),a.length===0&&s.length===0){new ht.Notice(`Skipped ${c.length} duplicate file(s) \u2014 nothing new to import.`);return}}else if(g==="replace")for(let p of c){let u=this.plugin.importLog.findDuplicate(p.name,p.stat?.size??null);for(let f of u?.notePaths??[]){let B=this.app.vault.getAbstractFileByPath(f);if(B instanceof ht.TFile)try{r.push({path:f,content:await this.app.vault.read(B)}),await this.app.fileManager.trashFile(B)}catch(Q){console.warn("[Stashpad] replace: couldn't remove prior note",f,Q)}}}}if(o=a.length+n,o>=ke.BATCH_CONFIRM_AT){let d=s.length?` (incl. ${s.length} folder${s.length===1?"":"s"})`:"";if(!await this.confirm("Import many files?",`You're about to auto-import ${o} files into Stashpad${d}. Proceed? -Markdown becomes notes (originals archived); other files move to _attachments with a linking note. Dropped folders move to _archive.`,"Import all")){new ht.Notice(`Import cancelled \u2014 ${o} file(s) left as-is.`);return}}let l=[];for(let d of a)try{let I=d.stat?.size??null,g=d.extension==="md"?await this.importMarkdown(d):await this.importOtherFile(d);g&&(l.push(g),this.plugin.importLog.append({ts:new Date().toISOString(),folder:g.folder,kind:g.kind,originalName:d.name,size:I,sourcePath:d.path,notePaths:g.kind==="folder"?g.notePaths:[g.notePath]}))}catch(I){console.warn("[Stashpad] import failed",d.path,I)}for(let{folder:d}of s)try{let I=await this.importFolder(d);I&&I.kind==="folder"&&(l.push(I),this.plugin.importLog.append({ts:new Date().toISOString(),folder:I.folder,kind:"folder",originalName:I.originalName,size:null,sourcePath:d.path,notePaths:I.notePaths}))}catch(I){console.warn("[Stashpad] folder import failed",d.path,I)}(l.length>0||r.length>0)&&this.announce(l,r)}finally{this.draining=!1}}}async importMarkdown(A){let t=A.parent.path.replace(/\/+$/,""),e=await this.app.vault.read(A),{fm:i,body:s}=we(e),n=`${t}/${qn}`;await this.ensureFolder(n);let o=await this.uniquePath(n,A.name);if(await this.app.fileManager.renameFile(A,o),!(this.app.vault.getAbstractFileByPath(o)instanceof ht.TFile))throw new Error(`archive move failed for ${A.path} \u2014 import aborted to avoid data loss`);let a={};for(let[d,I]of Object.entries(i))zt.includes(d)||(a[d]=I);a.id=mt(),a.parent=G;let r=this.preservedTimes(i,A);a.created=r.created,r.modified&&(a.modified=r.modified),a.attachments=Array.isArray(i.attachments)?i.attachments:[];let c=kt(s)||A.basename,l=await this.uniquePath(t,St(c,a.id));return await this.createNote(l,$t(a,s)),{kind:"md",folder:t,archivePath:o,notePath:l,originalName:A.name}}async importOtherFile(A){let t=A.parent.path.replace(/\/+$/,""),e=`${t}/_attachments`;await this.ensureFolder(e);let i=await this.uniquePath(e,A.name);await this.app.fileManager.renameFile(A,i);let s=A.basename,n=mt(),o={id:n,parent:G,created:new Date().toISOString(),attachments:[ie(i)]},a=`${s} +Replace the existing notes, skip the duplicates, or import them anyway as new notes?`);if(h==="skip"){let I=new Set(c.map(u=>u.path));if(r=e.filter(u=>!I.has(u.path)),r.length===0&&s.length===0){new pt.Notice(`Skipped ${c.length} duplicate file(s) \u2014 nothing new to import.`);return}}else if(h==="replace")for(let I of c){let u=this.plugin.importLog.findDuplicate(I.name,I.stat?.size??null);for(let f of u?.notePaths??[]){let C=this.app.vault.getAbstractFileByPath(f);if(C instanceof pt.TFile)try{a.push({path:f,content:await this.app.vault.read(C)}),await this.app.fileManager.trashFile(C)}catch(m){console.warn("[Stashpad] replace: couldn't remove prior note",f,m)}}}}if(o=r.length+n,o>=Ne.BATCH_CONFIRM_AT){let p=s.length?` (incl. ${s.length} folder${s.length===1?"":"s"})`:"";if(!await this.confirm("Import many files?",`You're about to auto-import ${o} files into Stashpad${p}. Proceed? +Markdown becomes notes (originals archived); other files move to _attachments with a linking note. Dropped folders move to _archive.`,"Import all")){new pt.Notice(`Import cancelled \u2014 ${o} file(s) left as-is.`);return}}let l=[];for(let p of r)try{let g=p.stat?.size??null,h=p.extension==="md"?await this.importMarkdown(p):await this.importOtherFile(p);h&&(l.push(h),this.plugin.importLog.append({ts:new Date().toISOString(),folder:h.folder,kind:h.kind,originalName:p.name,size:g,sourcePath:p.path,notePaths:h.kind==="folder"?h.notePaths:[h.notePath]}))}catch(g){console.warn("[Stashpad] import failed",p.path,g)}for(let{folder:p}of s)try{let g=await this.importFolder(p);g&&g.kind==="folder"&&(l.push(g),this.plugin.importLog.append({ts:new Date().toISOString(),folder:g.folder,kind:"folder",originalName:g.originalName,size:null,sourcePath:p.path,notePaths:g.notePaths}))}catch(g){console.warn("[Stashpad] folder import failed",p.path,g)}(l.length>0||a.length>0)&&this.announce(l,a)}finally{this.draining=!1}}}async importMarkdown(A){let t=A.parent.path.replace(/\/+$/,""),e=await this.app.vault.read(A),{fm:i,body:s}=Se(e),n=`${t}/${oo}`;await this.ensureFolder(n);let o=await this.uniquePath(n,A.name);if(await this.app.fileManager.renameFile(A,o),!(this.app.vault.getAbstractFileByPath(o)instanceof pt.TFile))throw new Error(`archive move failed for ${A.path} \u2014 import aborted to avoid data loss`);let r={};for(let[p,g]of Object.entries(i))Wt.includes(p)||(r[p]=g);r.id=Et(),r.parent=G;let a=this.preservedTimes(i,A);r.created=a.created,a.modified&&(r.modified=a.modified),r.attachments=Array.isArray(i.attachments)?i.attachments:[],i.author!==void 0&&(r.author=i.author),i.contributors!==void 0&&(r.contributors=i.contributors),r.imported=!0;let c=Dt(s)||A.basename,l=await this.uniquePath(t,bt(c,r.id));return await this.createNote(l,ee(r,s)),{kind:"md",folder:t,archivePath:o,notePath:l,originalName:A.name}}async importOtherFile(A){let t=A.parent.path.replace(/\/+$/,""),e=`${t}/_attachments`;await this.ensureFolder(e);let i=await this.uniquePath(e,A.name);await this.app.fileManager.renameFile(A,i);let s=A.basename,n=Et(),o={id:n,parent:G,created:new Date().toISOString(),attachments:[Gt(i)],imported:!0},r=`${s} ![[${i}]] -`,r=kt(s)||s,c=await this.uniquePath(t,St(r,n));return await this.createNote(c,$t(o,a)),{kind:"file",folder:t,attachmentPath:i,notePath:c,originalName:A.name}}preservedTimes(A,t){let e=n=>typeof n=="string"&&n.trim().length>0&&!Number.isNaN(Date.parse(n)),i=e(A.created)?A.created:t.stat?.ctime?new Date(t.stat.ctime).toISOString():new Date().toISOString(),s=e(A.modified)?A.modified:t.stat?.mtime?new Date(t.stat.mtime).toISOString():null;return{created:i,modified:s}}filesUnder(A){let t=A.replace(/\/+$/,"")+"/";return this.app.vault.getFiles().filter(e=>e.path.startsWith(t))}async importFolder(A){let t=A.parent.path.replace(/\/+$/,""),e=A.name,i=`${t}/${qn}`;await this.ensureFolder(i);let s=await this.uniquePath(i,e);await this.app.fileManager.renameFile(A,s);let n=this.app.vault.getAbstractFileByPath(s),o=new Set;for(let l of this.app.vault.getMarkdownFiles()){if((l.parent?.path?.replace(/\/+$/,"")??"")!==t)continue;let d=this.app.metadataCache.getFileCache(l)?.frontmatter?.id;typeof d=="string"&&d&&o.add(d)}let a=[],r=[],c=await this.createFolderNote(t,e,G,r,o);return n instanceof ht.TFolder&&await this.buildNotesFromArchive(n,t,c,r,o,a),a.length&&new ht.Notice(`Stashpad: ${a.length} attachment name collision(s) renamed on import \u2014 check ![[links]] in the imported notes.`),{kind:"folder",folder:t,archivePath:s,notePaths:r,attachmentPaths:[],originalName:e}}async createFolderNote(A,t,e,i,s){let n=mt();s.add(n);let o={id:n,parent:e,created:new Date().toISOString(),attachments:[]},a=kt(t)||t,r=await this.uniquePath(A,St(a,n));return await this.createNote(r,$t(o,`${t} -`)),i.push(r),n}async mergeReservedFolder(A,t,e){await this.ensureFolder(t);for(let i of[...A.children])if(i instanceof ht.TFolder)await this.mergeReservedFolder(i,`${t}/${i.name}`,e);else if(i instanceof ht.TFile){let s=`${t}/${i.name}`;await this.app.vault.adapter.exists(s)&&(s=await this.uniquePath(t,i.name),e.push(`${i.name} \u2192 ${s.split("/").pop()}`)),await this.app.fileManager.renameFile(i,s)}}async buildNotesFromArchive(A,t,e,i,s,n){for(let o of[...A.children])if(o instanceof ht.TFolder)if(Ji.has(o.name))await this.mergeReservedFolder(o,`${t}/${o.name}`,n);else{let a=await this.createFolderNote(t,o.name,e,i,s);await this.buildNotesFromArchive(o,t,a,i,s,n)}else if(o instanceof ht.TFile)if(o.extension==="md"){let a=await this.app.vault.read(o),{fm:r,body:c}=we(a),l={};for(let[f,B]of Object.entries(r))zt.includes(f)||(l[f]=B);let d=typeof r.id=="string"&&r.id?r.id:null,I=d&&!s.has(d)?d:mt();s.add(I),l.id=I,l.parent=e;let g=this.preservedTimes(r,o);l.created=g.created,g.modified&&(l.modified=g.modified),l.attachments=Array.isArray(r.attachments)?r.attachments:[];let p=kt(c)||o.basename,u=await this.uniquePath(t,St(p,l.id));await this.createNote(u,$t(l,c)),i.push(u)}else{if(Kn.has(o.extension))continue;{let a=mt(),r={id:a,parent:e,created:new Date().toISOString(),attachments:[ie(o.path)]},c=`${o.basename} +`,a=Dt(s)||s,c=await this.uniquePath(t,bt(a,n));return await this.createNote(c,ee(o,r)),{kind:"file",folder:t,attachmentPath:i,notePath:c,originalName:A.name}}preservedTimes(A,t){let e=n=>typeof n=="string"&&n.trim().length>0&&!Number.isNaN(Date.parse(n)),i=e(A.created)?A.created:t.stat?.ctime?new Date(t.stat.ctime).toISOString():new Date().toISOString(),s=e(A.modified)?A.modified:t.stat?.mtime?new Date(t.stat.mtime).toISOString():null;return{created:i,modified:s}}filesUnder(A){let t=A.replace(/\/+$/,"")+"/";return this.app.vault.getFiles().filter(e=>e.path.startsWith(t))}async importFolder(A){let t=A.parent.path.replace(/\/+$/,""),e=A.name,i=`${t}/${oo}`;await this.ensureFolder(i);let s=await this.uniquePath(i,e);await this.app.fileManager.renameFile(A,s);let n=this.app.vault.getAbstractFileByPath(s),o=new Set;for(let l of this.app.vault.getMarkdownFiles()){if((l.parent?.path?.replace(/\/+$/,"")??"")!==t)continue;let p=this.app.metadataCache.getFileCache(l)?.frontmatter?.id;typeof p=="string"&&p&&o.add(p)}let r=[],a=[],c=await this.createFolderNote(t,e,G,a,o);return n instanceof pt.TFolder&&await this.buildNotesFromArchive(n,t,c,a,o,r),r.length&&new pt.Notice(`Stashpad: ${r.length} attachment name collision(s) renamed on import \u2014 check ![[links]] in the imported notes.`),{kind:"folder",folder:t,archivePath:s,notePaths:a,attachmentPaths:[],originalName:e}}async createFolderNote(A,t,e,i,s){let n=Et();s.add(n);let o={id:n,parent:e,created:new Date().toISOString(),attachments:[]},r=Dt(t)||t,a=await this.uniquePath(A,bt(r,n));return await this.createNote(a,ee(o,`${t} +`)),i.push(a),n}async mergeReservedFolder(A,t,e){await this.ensureFolder(t);for(let i of[...A.children])if(i instanceof pt.TFolder)await this.mergeReservedFolder(i,`${t}/${i.name}`,e);else if(i instanceof pt.TFile){let s=`${t}/${i.name}`;await this.app.vault.adapter.exists(s)&&(s=await this.uniquePath(t,i.name),e.push(`${i.name} \u2192 ${s.split("/").pop()}`)),await this.app.fileManager.renameFile(i,s)}}async buildNotesFromArchive(A,t,e,i,s,n){for(let o of[...A.children])if(o instanceof pt.TFolder)if(Zi.has(o.name))await this.mergeReservedFolder(o,`${t}/${o.name}`,n);else{let r=await this.createFolderNote(t,o.name,e,i,s);await this.buildNotesFromArchive(o,t,r,i,s,n)}else if(o instanceof pt.TFile)if(o.extension==="md"){let r=await this.app.vault.read(o),{fm:a,body:c}=Se(r),l={};for(let[f,C]of Object.entries(a))Wt.includes(f)||(l[f]=C);let p=typeof a.id=="string"&&a.id?a.id:null,g=p&&!s.has(p)?p:Et();s.add(g),l.id=g,l.parent=e;let h=this.preservedTimes(a,o);l.created=h.created,h.modified&&(l.modified=h.modified),l.attachments=Array.isArray(a.attachments)?a.attachments:[];let I=Dt(c)||o.basename,u=await this.uniquePath(t,bt(I,l.id));await this.createNote(u,ee(l,c)),i.push(u)}else{if(ao.has(o.extension))continue;{let r=Et(),a={id:r,parent:e,created:new Date().toISOString(),attachments:[Gt(o.path)]},c=`${o.basename} ![[${o.path}]] -`,l=kt(o.basename)||o.basename,d=await this.uniquePath(t,St(l,a));await this.createNote(d,$t(r,c)),i.push(d)}}}recordNotePaths(A){return A.kind==="folder"?A.notePaths:[A.notePath]}announce(A,t=[]){let e=A[0]?.folder??"",i=A.length,s=t.length?`, replaced ${t.length}`:"",n=!1,o=async()=>{n||(n=!0,await this.undo(A,t))};this.plugin.notifications.show({message:`Imported ${i} file${i===1?"":"s"}${s} into \`${e.split("/").pop()}\`.`,kind:"success",category:"import",duration:0,folder:e,affectedPaths:A.flatMap(a=>this.recordNotePaths(a)),actions:[{label:"Undo import",onClick:()=>void o()}]}),e&&this.plugin.getUndoStack(e).push({label:`Import ${i} file${i===1?"":"s"}`,undo:async()=>{await o()},redo:async()=>{}})}async undo(A,t=[]){for(let e of A)try{if(e.kind==="md"){let i=this.app.vault.getAbstractFileByPath(e.notePath);i instanceof ht.TFile&&await this.app.fileManager.trashFile(i);let s=this.app.vault.getAbstractFileByPath(e.archivePath);if(s instanceof ht.TFile){let n=await this.uniquePath(e.folder,e.originalName);this.suppress(n),await this.app.fileManager.renameFile(s,n)}}else if(e.kind==="file"){let i=this.app.vault.getAbstractFileByPath(e.notePath);i instanceof ht.TFile&&await this.app.fileManager.trashFile(i);let s=this.app.vault.getAbstractFileByPath(e.attachmentPath);if(s instanceof ht.TFile){let n=await this.uniquePath(e.folder,e.originalName);this.suppress(n),await this.app.fileManager.renameFile(s,n)}}else{for(let s of e.notePaths){let n=this.app.vault.getAbstractFileByPath(s);n instanceof ht.TFile&&await this.app.fileManager.trashFile(n)}for(let s of e.attachmentPaths){let n=this.app.vault.getAbstractFileByPath(s);n instanceof ht.TFile&&await this.app.fileManager.trashFile(n)}let i=this.app.vault.getAbstractFileByPath(e.archivePath);if(i instanceof ht.TFolder){let s=await this.uniquePath(e.folder,e.originalName);this.suppress(s),await this.app.fileManager.renameFile(i,s)}}}catch(i){console.warn("[Stashpad] import undo failed",e,i)}for(let e of t)try{await this.app.vault.adapter.exists(e.path)||await this.app.vault.create(e.path,e.content)}catch(i){console.warn("[Stashpad] import undo: couldn't restore replaced note",e.path,i)}new ht.Notice(`Undid import of ${A.length} file(s).`)}pickFilesInto(A){let t=document.createElement("input");t.type="file",t.multiple=!0,t.style.display="none",t.onchange=async()=>{let e=Array.from(t.files??[]);if(t.remove(),e.length===0)return;let i=[];for(let n of e)try{let o=await n.arrayBuffer(),a=await this.uniquePath(A,n.name);this.suppress(a,6e4),await this.app.vault.createBinary(a,o);let r=this.app.vault.getAbstractFileByPath(a);r instanceof ht.TFile&&i.push(r)}catch(o){console.warn("[Stashpad] file-picker write failed",n.name,o)}if(i.length===0)return;await this.plugin.importLog.load();let s=[];for(let n of i)try{let o=n.stat?.size??null,a=n.extension==="md"?await this.importMarkdown(n):await this.importOtherFile(n);a&&(s.push(a),this.plugin.importLog.append({ts:new Date().toISOString(),folder:a.folder,kind:a.kind,originalName:n.name,size:o,sourcePath:n.path,notePaths:a.kind==="folder"?a.notePaths:[a.notePath]}))}catch(o){console.warn("[Stashpad] file-picker import failed",n.path,o)}s.length>0&&this.announce(s,[])},document.body.appendChild(t),t.click()}async importLooseFilesIn(A){let t=A.replace(/\/+$/,""),e=this.app.vault.getFiles().filter(n=>(n.parent?.path?.replace(/\/+$/,"")??"")===t),i=[];for(let n of e)await this.isStillImportable(n)&&i.push(n);if(i.length===0)return 0;await this.plugin.importLog.load();let s=0;for(let n of i)try{let o=n.stat?.size??null,a=n.extension==="md"?await this.importMarkdown(n):await this.importOtherFile(n);a&&(s++,this.plugin.importLog.append({ts:new Date().toISOString(),folder:a.folder,kind:a.kind,originalName:n.name,size:o,sourcePath:n.path,notePaths:a.kind==="folder"?a.notePaths:[a.notePath]}))}catch(o){console.warn("[Stashpad] loose-file import failed",n.path,o)}return s}async importLooseFoldersIn(A){let t=A.replace(/\/+$/,""),e=this.app.vault.getAbstractFileByPath(t);if(!(e instanceof ht.TFolder))return 0;let i=e.children.filter(n=>n instanceof ht.TFolder&&!Ji.has(n.name));if(i.length===0)return 0;await this.plugin.importLog.load();let s=0;for(let n of i){let o=n.path;try{let a=await this.importFolder(n);a&&a.kind==="folder"&&(s++,this.plugin.importLog.append({ts:new Date().toISOString(),folder:a.folder,kind:a.kind,originalName:n.name,size:null,sourcePath:o,notePaths:a.notePaths}))}catch(a){console.warn("[Stashpad] loose-folder import failed",o,a)}}return s}pendingEncryptedPaths(){for(let A of[...this.pendingEncryptedStashes])this.app.vault.getAbstractFileByPath(A)instanceof ht.TFile||this.pendingEncryptedStashes.delete(A);return[...this.pendingEncryptedStashes]}clearPendingEncrypted(A){this.pendingEncryptedStashes.delete(A)}shouldNotifyEncrypted(){return Date.now()>=this.encryptedNotifySnoozeUntil}snoozeEncryptedNotify(A){this.encryptedNotifySnoozeUntil=A===1/0?Number.MAX_SAFE_INTEGER:Date.now()+A}parkEncrypted(A){return this.pendingEncryptedStashes.has(A)?!1:(this.pendingEncryptedStashes.add(A),this.encryptedNotifySnoozeUntil=0,!0)}async importPendingEncrypted(){let A=0,t=!1;for(let e of this.pendingEncryptedPaths()){let i=this.app.vault.getAbstractFileByPath(e);if(!(i instanceof ht.TFile))continue;let s=i.parent?.path?.replace(/\/+$/,"")??"";if(await this.importOneStash(i,s,this.liveRootIds(s),!1,{allowLater:!0,onLater:()=>{t=!0,this.snoozeEncryptedNotify(60*60*1e3)}})&&A++,t)break}return{imported:A,rescheduled:t}}liveRootIds(A){let t=new Set;for(let e of this.app.vault.getMarkdownFiles()){if((e.parent?.path?.replace(/\/+$/,"")??"")!==A)continue;let i=this.app.metadataCache.getFileCache(e)?.frontmatter?.id;typeof i=="string"&&i&&t.add(i)}return t}async importOneStash(A,t,e,i,s={}){try{let n=new Uint8Array(await this.app.vault.readBinary(A));if(i&&Fe(n))return this.pendingEncryptedStashes.add(A.path),!1;let o=await ve(this.app,n,s);if(!o)return!1;let a=await ye(this.app,o,t,e);try{await this.app.fileManager.trashFile(A)}catch{}this.pendingEncryptedStashes.delete(A.path);try{await this.plugin.newLog().append({type:"stash_import",id:G,payload:{from:A.path,into:t,noteCount:a.notesWritten,attachmentsWritten:a.attachmentsWritten,collisionsRenamed:a.collisionsRenamed,loose:!0}})}catch{}return!0}catch(n){return console.warn("[Stashpad] loose .stash import failed",A.path,n),!1}}async importLooseStashesIn(A,t={}){let e=A.replace(/\/+$/,""),i=this.app.vault.getFiles().filter(o=>(o.parent?.path?.replace(/\/+$/,"")??"")===e&&o.extension===_t);if(i.length===0)return 0;let s=this.liveRootIds(e),n=0;for(let o of i)await this.importOneStash(o,e,s,!!t.auto)&&n++;return n}async importLooseInto(A,t={}){let e=await this.importLooseFilesIn(A),i=await this.importLooseFoldersIn(A),s=await this.importLooseStashesIn(A,t);return{files:e,folders:i,stashes:s}}defaultDestination(){let t=this.plugin.lastActiveStashpadLeaf?.view?.noteFolder;return t&&this.plugin.discoverStashpadFolders().includes(t)?t:this.plugin.discoverStashpadFolders()[0]??null}confirm(A,t,e){return new Promise(i=>{new Dt(this.app,A,t,e,i).open()})}dupChoice(A){return new Promise(t=>{new Je(this.app,A,t).open()})}async ensureFolder(A){let t=this.app.vault.adapter,e=A.split("/").filter(Boolean),i="";for(let s of e){i=i?`${i}/${s}`:s;try{await t.exists(i)||await t.mkdir(i)}catch(n){if(!/already exists/i.test(n.message))throw n}}}async uniquePath(A,t){let e=this.app.vault.adapter,i=t.lastIndexOf("."),s=i>0?t.slice(0,i):t,n=i>0?t.slice(i):"",o=`${A}/${t}`,a=0;for(;await e.exists(o);)a+=1,o=`${A}/${s}-${a}${n}`;return o}};ke.DEBOUNCE_MS=900,ke.BATCH_CONFIRM_AT=8;var qi=ke;var Ki=class{constructor(A,t){this.app=A;this.entries=[];this.loaded=!1;this.dirOk=!1;this.writeChain=Promise.resolve();this.path=`${t.replace(/\/+$/,"")}/import-log.jsonl`}getPath(){return this.path}async load(){if(!this.loaded){this.loaded=!0;try{let A=this.app.vault.adapter;if(await A.exists(this.path)){let t=await A.read(this.path);for(let e of t.split(/\r?\n/))if(e.trim())try{this.entries.push(JSON.parse(e))}catch{}}}catch(A){console.warn("[Stashpad] import log load failed",A)}}}recent(){return[...this.entries].reverse()}findDuplicate(A,t){for(let e=this.entries.length-1;e>=0;e--){let i=this.entries[e];if(i.originalName===A&&(t==null||i.size==null||i.size===t))return i}return null}append(A){this.entries.push(A),this.writeChain=this.writeChain.then(async()=>{try{await this.ensureDir(),await this.app.vault.adapter.append(this.path,JSON.stringify(A)+` -`)}catch(t){console.warn("[Stashpad] import log append failed",t)}})}async ensureDir(){if(this.dirOk)return;let A=this.app.vault.adapter,e=this.path.slice(0,this.path.lastIndexOf("/")).split("/").filter(Boolean),i="";for(let s of e)i=i?`${i}/${s}`:s,await A.exists(i)||await A.mkdir(i);this.dirOk=!0}};var Yi=class Yi{constructor(A,t){this.app=A;this.map=new Map;this.loaded=!1;this.dirty=!1;this.saveTimer=null;this.dirOk=!1;this.writeChain=Promise.resolve();this.path=`${t.replace(/\/+$/,"")}/render-cache.json`}async load(){if(!this.loaded){this.loaded=!0;try{let A=this.app.vault.adapter;if(await A.exists(this.path)){let t=JSON.parse(await A.read(this.path));if(t?.schema===1&&t.entries){for(let[e,i]of Object.entries(t.entries))this.map.set(e,i);for(let e of[...this.map.keys()])this.app.vault.getAbstractFileByPath(e)||(this.map.delete(e),this.dirty=!0)}}}catch(A){console.warn("[Stashpad] render cache load failed; starting empty",A),this.map.clear()}}}get(A){return this.map.get(A)}has(A){return this.map.has(A)}set(A,t){this.map.set(A,t),this.dirty=!0,this.scheduleSave()}scheduleSave(){this.saveTimer==null&&(this.saveTimer=window.setTimeout(()=>{this.saveTimer=null,this.save()},Yi.SAVE_DEBOUNCE_MS))}save(){return this.saveTimer!=null&&(window.clearTimeout(this.saveTimer),this.saveTimer=null),this.dirty?(this.dirty=!1,this.writeChain=this.writeChain.then(async()=>{try{await this.ensureDir();let A={schema:1,entries:Object.fromEntries(this.map)};await this.app.vault.adapter.write(this.path,JSON.stringify(A))}catch(A){console.warn("[Stashpad] render cache save failed",A)}}),this.writeChain):this.writeChain}async ensureDir(){if(this.dirOk)return;let A=this.app.vault.adapter,e=this.path.slice(0,this.path.lastIndexOf("/")).split("/").filter(Boolean),i="";for(let s of e)i=i?`${i}/${s}`:s,await A.exists(i)||await A.mkdir(i);this.dirOk=!0}};Yi.SAVE_DEBOUNCE_MS=8e3;var Oi=Yi;var zi=class extends et.Plugin{constructor(){super(...arguments);this.settings={...Vt};this.undoStacks=new Map;this.lastActiveStashpadLeaf=null;this.rebootstrapInProgress=!1;this.settingTab=null;this.stashpadSelectionListeners=new Set;this.stashpadContentListeners=new Set;this._notifications=null;this._authorRegistry=null;this._importService=null;this._importLog=null;this._renderCacheStore=null;this.sweptFolders=new Set;this.notifiedBuildVersion=null;this.authorRenameInFlight=new Set;this.autoSweepInProgress=!1;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 gi(this.app)),this._notifications}get authorRegistry(){return this._authorRegistry||(this._authorRegistry=new Li(this.app,this.pluginPrivatePath())),this._authorRegistry}get importService(){return this._importService||(this._importService=new qi(this)),this._importService}get importLog(){return this._importLog||(this._importLog=new Ki(this.app,this.pluginPrivatePath())),this._importLog}get renderCacheStore(){return this._renderCacheStore||(this._renderCacheStore=new Oi(this.app,this.pluginPrivatePath())),this._renderCacheStore}async onunload(){try{await this._renderCacheStore?.save()}catch{}}pluginPrivatePath(t=""){let i=`${this.manifest.dir.replace(/\/+$/,"")}/.stashpad`;return t?`${i}/${t.replace(/^\/+/,"")}`:i}newLog(){return new Ri(this.app,this.pluginPrivatePath(),()=>(this.settings?.authorName??"").trim())}async migrateLegacyPaths(){let t=this.app.vault.adapter,e=this.pluginPrivatePath(),i=async()=>{let a=e.split("/").filter(Boolean),r="";for(let c of a)r=r?`${r}/${c}`:c,await t.exists(r)||await t.mkdir(r)},s=`${this.manifest.dir.replace(/\/+$/,"")}/data.json`,n=this.pluginPrivatePath("data.json");if(await t.exists(s)&&!await t.exists(n))try{await i();let a=await t.read(s);await t.write(n,a),console.debug("[Stashpad] migrated data.json \u2192",n)}catch(a){console.warn("Stashpad: data.json migration failed",a)}let o=".stashpad";if(await t.exists(o))try{await i();let a=await t.list(o);for(let r of a.files){let c=r.replace(/^.*\//,""),l=this.pluginPrivatePath(c);if(!await t.exists(l))try{let d=await t.read(r);await t.write(l,d),console.debug("[Stashpad] migrated",r,"\u2192",l)}catch(d){console.warn(`Stashpad: failed to migrate ${r}`,d)}}}catch(a){console.warn("Stashpad: .stashpad migration scan failed",a)}}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(i){return console.warn("Stashpad: data.json parse failed",i),null}}async saveData(t){let e=this.app.vault.adapter,i=this.pluginPrivatePath();if(!await e.exists(i)){let s=i.split("/").filter(Boolean),n="";for(let o of s)n=n?`${n}/${o}`:o,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 i=this.app.vault.adapter,s=e.split("/").filter(Boolean),n="";for(let c of s)n=n?`${n}/${c}`:c,await i.exists(n)||await i.mkdir(n);let o=`${e}/Home.md`;if(await i.exists(o)){let c=this.app.vault.getAbstractFileByPath(o);c&&await this.app.fileManager.processFrontMatter(c,l=>{(typeof l.id!="string"||!l.id)&&(l.id=G),"parent"in l||(l.parent=null),(typeof l.created!="string"||!l.created)&&(l.created=new Date().toISOString())});return}let a=new Date().toISOString(),r=["---",`id: ${G}`,"parent: null",`created: ${a}`,"---","Home"].join(` -`);await this.app.vault.create(o,r);try{await this.seedLocalAuthorStub(e)}catch{}}collectColorsInFolder(t){let e=new Map,i=t.replace(/\/+$/,"");for(let n of this.app.vault.getMarkdownFiles()){let o=n.parent?.path?.replace(/\/+$/,"")??"";if(o!==i&&!o.startsWith(i+"/"))continue;let a=this.app.metadataCache.getFileCache(n)?.frontmatter,r=typeof a?.color=="string"?a.color.trim():"";if(!r||!/^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(r))continue;let c=r.toLowerCase();e.set(c,(e.get(c)??0)+1)}let s=[...e.entries()].map(([n,o])=>({hex:n,count:o}));return s.sort((n,o)=>o.count-n.count||n.hex.localeCompare(o.hex)),s}async recolorAllInFolder(t,e,i){let s=t.replace(/\/+$/,""),n=e.toLowerCase(),o=0;for(let r of this.app.vault.getMarkdownFiles()){let c=r.parent?.path?.replace(/\/+$/,"")??"";if(c!==s&&!c.startsWith(s+"/"))continue;let l=this.app.metadataCache.getFileCache(r)?.frontmatter;if((typeof l?.color=="string"?l.color.trim().toLowerCase():"")===n)try{await this.app.fileManager.processFrontMatter(r,I=>{i?I.color=i:delete I.color}),o++}catch(I){console.warn(`Stashpad: recolor failed for ${r.path}`,I)}}let a=this.settings.colorAliases?.[s];if(a){let r=a[n];r&&(delete a[n],i&&(a[i.toLowerCase()]=r),Object.keys(a).length===0&&delete this.settings.colorAliases[s],await this.saveSettings())}return o}getColorAlias(t,e){let i=t.replace(/\/+$/,""),s=this.settings.colorAliases?.[i];if(!s)return;let n=s[e.toLowerCase()];return n&&n.trim()?n:void 0}async setColorAlias(t,e,i){let s=t.replace(/\/+$/,""),n=e.toLowerCase();this.settings.colorAliases||(this.settings.colorAliases={}),this.settings.colorAliases[s]||(this.settings.colorAliases[s]={});let o=this.settings.colorAliases[s],a=i.trim();a?o[n]=a:delete o[n],Object.keys(o).length===0&&delete this.settings.colorAliases[s],await this.saveSettings()}async waitForStashpadFolder(t,e=2e3){let i=t.trim().replace(/^\/+|\/+$/g,"");if(!i)return;let s=Date.now();for(;Date.now()-s<e;){if(this.discoverStashpadFolders().includes(i))return;await new Promise(n=>setTimeout(n,80))}}discoverStashpadFolders(){let t=new Set;for(let e of this.app.vault.getMarkdownFiles()){let i=this.app.metadataCache.getFileCache(e)?.frontmatter;if(typeof i?.id!="string"||!i.id.trim()||!i||!("parent"in i))continue;let s=e.parent?.path?.replace(/\/+$/,"")??"";s&&t.add(s)}return[...t].sort()}searchableFolders(t){let e=new Set(this.settings.searchIncludedFolders),i=new Set(this.settings.searchExcludedFolders),n=this.discoverStashpadFolders().filter(r=>e.size>0?e.has(r):!i.has(r)),o=(t||"").trim().replace(/\/+$/,""),a=n.filter(r=>r!==o);return o&&a.unshift(o),a}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 i=this.newLog(),s={},n=this.app.vault.getMarkdownFiles().filter(c=>c.path===t||c.path.startsWith(t+"/"));for(let c of n){let l=this.app.metadataCache.getFileCache(c)?.frontmatter,d=typeof l?.id=="string"?l.id.trim():"";if(!d)continue;let I=l&&"parent"in l?l.parent??null:null;s[d]={parent:I,path:c.path}}let o=await i.readState(),a=c=>c===t||c.startsWith(t+"/");if(!e.silent){for(let[c,l]of Object.entries(s)){let d=o[c];d?d.parent!==l.parent?await i.append({type:"parent_change",id:c,payload:{from:d.parent,to:l.parent}}):d.path!==l.path&&await i.append({type:"rename",id:c,payload:{from:d.path,to:l.path}}):await i.append({type:"create",id:c,payload:{path:l.path,parent:l.parent}})}for(let[c,l]of Object.entries(o))!s[c]&&a(l.path)&&await i.append({type:"missing",id:c,payload:{lastPath:l.path}})}let r={};for(let[c,l]of Object.entries(o))a(l.path)||(r[c]=l);for(let[c,l]of Object.entries(s))r[c]=l;await i.writeState(r)}catch(i){console.warn("Stashpad: integrity sweep failed",i)}}getUndoStack(t){let e=this.undoStacks.get(t);return e||(e=new Pi,this.undoStacks.set(t,e)),e}async onload(){await this.migrateLegacyPaths(),await this.loadSettings(),vt.enabled=!!this.settings.enablePerfProfiling,this.settingTab=new Bi(this.app,this),this.addSettingTab(this.settingTab),await this.renderCacheStore.load(),await this.authorRegistry.load();{let g=(this.settings.authorId??"").trim();g&&this.authorRegistry.record({id:g,name:this.settings.authorName,role:this.settings.authorRole,department:this.settings.authorDepartment})}this.app.workspace.onLayoutReady(()=>{window.setTimeout(()=>{this.seedLocalAuthorStubsEverywhere()},4e3),window.setTimeout(()=>this.syncObsidianExcludedArchives(),4500),window.setTimeout(()=>this.importService.setArmed(!0),2500),window.setTimeout(()=>void this.runAutoImportSweep(),5e3),this.registerInterval(window.setInterval(()=>void this.runAutoImportSweep(),5*60*1e3))}),this.registerView(ut,g=>new Gi(g,this)),this.registerView(te,g=>new Qi(g,this)),this.registerView(Yt,g=>new ri(g,this)),this.registerEvent(this.app.workspace.on("active-leaf-change",g=>{g&&g.view.getViewType()===ut&&(this.lastActiveStashpadLeaf=g,this.settings.autoOpenDetailPanel&&this.app.workspace.getLeavesOfType(te).length===0&&setTimeout(()=>{mi(this.app)},0),this.notifyStashpadSelectionChanged())}));let t=()=>{let g=Lt(),p=!!g&&this.app.workspace.activeLeaf&&this.app.workspace.activeLeaf.view===g,u=!!p&&this.settings.hideMobileToolbarInStashpad;document.body.classList.toggle("stashpad-hide-mobile-toolbar",u),document.body.classList.toggle("stashpad-active",!!p)};this.register(Xs(t)),this.registerEvent(this.app.workspace.on("active-leaf-change",t));let e=g=>{try{let p=Array.from(document.querySelectorAll("style")).filter(u=>(u.textContent??"").includes(".stashpad-"));for(let u of p){let f=u.id||"",B=f?`style[data-stashpad-source="${f}"]`:null;if(B&&g.head.querySelector(B))continue;let Q=g.createElement("style");f?Q.setAttribute("data-stashpad-source",f):Q.setAttribute("data-stashpad-source","anon"),Q.textContent=u.textContent??"",g.head.appendChild(Q)}}catch(p){console.warn("[Stashpad] inject popout styles failed",p)}};this.registerEvent(this.app.workspace.on("window-open",g=>{let p=g?.doc??g?.win?.document??null;p&&e(p)})),setTimeout(()=>{try{let g=this.app.workspace;typeof g.iterateAllLeaves=="function"&&g.iterateAllLeaves(p=>{let u=p?.view?.containerEl?.ownerDocument;u&&u!==document&&e(u)})}catch{}},200),t(),this.register(()=>document.body.classList.remove("stashpad-hide-mobile-toolbar","stashpad-active"));let i=window.visualViewport,s=()=>{let g=document.querySelector(".mobile-toolbar, .mobile-toolbar-container"),p=g&&g.isConnected?g.offsetHeight:0;document.body.style.setProperty("--stashpad-toolbar-h",`${p}px`);let u=0;i&&(u=Math.max(0,window.innerHeight-i.height-i.offsetTop)),document.body.style.setProperty("--stashpad-vv-bottom-gap",`${u}px`),document.body.classList.toggle("stashpad-keyboard-open",u>100)};s(),i&&(i.addEventListener("resize",s),i.addEventListener("scroll",s),this.register(()=>{i.removeEventListener("resize",s),i.removeEventListener("scroll",s)})),window.addEventListener("resize",s),this.register(()=>window.removeEventListener("resize",s)),requestAnimationFrame(s),setTimeout(s,250),setTimeout(s,1e3),this.addRibbonIcon("list-tree","Open Stashpad",()=>{if(this.discoverStashpadFolders().length===0){this.activateView({reveal:!0});return}this.openFolderPicker()}).addEventListener("contextmenu",g=>{g.preventDefault(),this.openFolderPicker()}),this.addRibbonIcon("panel-left","Open Stashpad panels (sidebar)",()=>{Ai(this.app)}),this.addRibbonIcon("panel-right","Open Stashpad detail panel (right sidebar)",()=>{mi(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 o=g=>{let p=Lt();p&&typeof p[g]=="function"&&p[g]()};this.addCommand({id:"stashpad-toggle-split",name:"Toggle split-on-newlines",callback:()=>o("toggleSplit")}),this.addCommand({id:"stashpad-claim-selected-author",name:"Claim authorship of selected notes",callback:()=>o("claimSelectedAsAuthor")}),this.addCommand({id:"stashpad-claim-folder-author",name:"Claim authorship of all unauthored notes in this folder",callback:()=>o("claimFolderAsAuthor")}),this.addCommand({id:"stashpad-claim-selected-contributor",name:"Claim selected notes (author if unowned, else add me as contributor)",callback:()=>o("claimSelectedWithContributor")}),this.addCommand({id:"stashpad-claim-folder-contributor",name:"Claim all notes in this folder (author if unowned, else add me as contributor)",callback:()=>o("claimFolderWithContributor")}),this.addCommand({id:"stashpad-pick-destination",name:"Pick destination for next note",callback:()=>o("openDestinationPicker")}),this.addCommand({id:"stashpad-search",name:"Search Stashpad notes",callback:()=>o("openSearchModal")}),this.addCommand({id:"stashpad-search-in-parent",name:"Search in current parent",callback:()=>o("openSearchInParentModal")}),this.addCommand({id:"stashpad-move-picker",name:"Move selection (picker)",callback:()=>o("cmdMovePicker")}),this.addCommand({id:"stashpad-merge",name:"Merge selection",callback:()=>o("cmdMerge")}),this.addCommand({id:"stashpad-copy",name:"Copy selection",callback:()=>o("cmdCopy")}),this.addCommand({id:"stashpad-copy-tree",name:"Copy focused subtree",callback:()=>o("cmdCopyTree")}),this.addCommand({id:"stashpad-copy-outline",name:"Copy as outline (nested embeds)",callback:()=>o("cmdCopyOutline")}),this.addCommand({id:"stashpad-split",name:"Split note\u2026",callback:()=>o("cmdSplit")}),this.addCommand({id:"stashpad-edit-note",name:"Edit note in new tab (selection)",callback:()=>o("cmdOpenInEditor")}),this.addCommand({id:"stashpad-edit-parent",name:"Edit parent note in new tab",callback:()=>o("cmdOpenParentInEditor")}),this.addCommand({id:"stashpad-delete",name:"Delete selection",callback:()=>o("cmdDelete")}),this.addCommand({id:"stashpad-move-up",name:"Move note up",callback:()=>o("cmdMoveUp")}),this.addCommand({id:"stashpad-move-down",name:"Move note down",callback:()=>o("cmdMoveDown")}),this.addCommand({id:"stashpad-move-to-top",name:"Move note to top",callback:()=>o("cmdMoveToTop")}),this.addCommand({id:"stashpad-move-to-bottom",name:"Move note to bottom",callback:()=>o("cmdMoveToBottom")}),this.addCommand({id:"stashpad-outdent",name:"Outdent (move to grandparent)",callback:()=>o("cmdOutdent")}),this.addCommand({id:"stashpad-set-color",name:"Set note color\u2026",callback:()=>o("cmdSetColor")}),this.addCommand({id:"stashpad-clone",name:"Clone selection (duplicate / copy notes)",callback:()=>o("cmdClone")}),this.addCommand({id:"stashpad-insert-template",name:"Insert template (clone an existing note)",callback:()=>o("cmdInsertTemplate")}),this.addCommand({id:"stashpad-toggle-expand",name:"Show more / show less (expand toggle)",callback:()=>o("cmdToggleExpand")}),this.addCommand({id:"stashpad-pick-move",name:"Move (in-list, arrow + Enter)",callback:()=>o("cmdInListPicker")}),this.addCommand({id:"stashpad-open-in-new-tab",name:"Open in new Stashpad tab",callback:()=>o("cmdOpenInNewStashpadTab")}),this.addCommand({id:"stashpad-toggle-complete",name:"Toggle complete (strikethrough)",callback:()=>o("cmdToggleComplete")}),this.addCommand({id:"stashpad-toggle-task",name:"Toggle task (todo)",callback:()=>o("cmdToggleTask")}),this.addCommand({id:"stashpad-set-due",name:"Set due date\u2026",callback:()=>o("cmdSetDue")}),this.addCommand({id:"stashpad-dump-perf",name:"Dump performance profile (copy to clipboard)",callback:async()=>{if(!this.settings.enablePerfProfiling){new et.Notice("Enable \u201CPerformance profiling\u201D in Stashpad settings first, then use the app and run this again.");return}let g=vt.report();console.log(g);try{await navigator.clipboard.writeText(g)}catch{}new et.Notice("Performance profile copied to clipboard (also in the console).")}}),this.addCommand({id:"stashpad-reset-perf",name:"Reset performance profile",callback:()=>{vt.reset(),new et.Notice("Performance profile reset.")}}),this.addCommand({id:"stashpad-jump-to-top",name:"Jump to top of list",callback:()=>o("jumpToTop")}),this.addCommand({id:"stashpad-jump-to-bottom",name:"Jump to bottom of list",callback:()=>o("jumpToBottom")}),this.addCommand({id:"stashpad-assign",name:"Assign task to\u2026",callback:()=>o("cmdAssign")}),this.addCommand({id:"stashpad-open-import-log",name:"Open import log",callback:async()=>{await this.importLog.load();let{ImportLogModal:g}=await Promise.resolve().then(()=>(Mt(),qe));new g(this.app,this.importLog.recent()).open()}}),this.addCommand({id:"stashpad-import-files",name:"Import file(s) into Stashpad\u2026",callback:()=>this.openImportPicker()}),this.addCommand({id:"stashpad-import-loose-files",name:"Import loose files & folders in this folder (scan for moved-in / unprocessed items)",checkCallback:g=>{let p=this.importService.defaultDestination();return g?!!p:(p&&this.runImportLooseFiles(p),!0)}}),this.addCommand({id:"stashpad-select-all",name:"Select all visible notes",callback:()=>o("cmdSelectAll")}),this.addCommand({id:"stashpad-copy-codeblock",name:"Copy code from codeblock",callback:()=>o("cmdCopyCodeBlock")}),this.addCommand({id:"stashpad-open-panels",name:"Open Stashpad panels (sidebar)",callback:()=>void Ai(this.app)}),this.addCommand({id:"stashpad-open-detail",name:"Open Stashpad detail panel (right sidebar)",callback:()=>void mi(this.app)}),this.addCommand({id:"stashpad-reveal-active-note",name:"Open this note in Stashpad",checkCallback:g=>{let p=this.app.workspace.getActiveFile(),u=!!p&&p.extension==="md"&&this.isStashpadNoteFile(p);return g||u&&p&&this.revealNoteInStashpad(p),u}});let a=Object.keys(Ke);for(let g of a){let p=Ke[g];this.addCommand({id:`stashpad-open-panels-${g}`,name:`Open Stashpad panel: ${p.label}`,callback:async()=>{await Ai(this.app),this.app.workspace.getLeavesOfType(Yt)[0]?.view?.setActivePanel?.(g)}})}this.addCommand({id:"stashpad-swap-with-parent",name:"Swap with parent (ouroboros)",callback:()=>o("cmdSwapWithParent")}),this.addCommand({id:"stashpad-toggle-pin",name:"Pin / unpin selected note (sidebar)",callback:()=>o("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:()=>o("cmdCloneStashpadTab")}),this.addCommand({id:"stashpad-undo",name:"Undo last Stashpad action",callback:()=>o("cmdUndo")}),this.addCommand({id:"stashpad-redo",name:"Redo last undone Stashpad action",callback:()=>o("cmdRedo")}),this.addCommand({id:"stashpad-export-stash",name:"Export selection to .stash",callback:()=>o("cmdExportStash")}),this.addCommand({id:"stashpad-import-stash",name:"Import .stash file\u2026",callback:()=>o("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:g=>{let p=Lt(),u=p&&p.noteFolder;return u?(g||(new et.Notice(`Running integrity check on "${u}"\u2026`),this.runIntegrityCheckOnFolder(u).then(()=>{new et.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 et.Notice("Stashpad: rebuilding author registry\u2026");try{let g=await this.rebuildAuthorRegistry();this.notifications.show({message:`Author registry rebuilt: ${g.total} author(s) \u2014 ${g.fromStubs} from stubs, ${g.fromNotes} from note links.`,kind:"success",category:"system"})}catch(g){new et.Notice(`Author registry rebuild failed: ${g.message}`)}}}),this.addCommand({id:"stashpad-restore-author-stubs",name:"Restore missing author stubs (from registry)",callback:async()=>{new et.Notice("Stashpad: restoring author stubs\u2026");try{let g=await this.restoreMissingAuthorStubs();this.notifications.show({message:g.created>0?`Restored ${g.created} author stub(s) across ${g.folders} folder(s).`:`No missing author stubs \u2014 all present across ${g.folders} folder(s).`,kind:"success",category:"system"})}catch(g){new et.Notice(`Restore author stubs failed: ${g.message}`)}}}),this.addCommand({id:"stashpad-rebootstrap-all",name:"Rebootstrap all Stashpad folders (backfill metadata + rename stale titles)",callback:async()=>{new et.Notice("Stashpad: rebootstrapping\u2026");try{let{touched:g,fmChecked:p,fmWritten:u,slugsRenamed:f,authors:B,imported:Q,attachmentsLinked:E}=await this.rebootstrapAllFolders(),y=[];y.push(`rebootstrapped ${g.length} folder${g.length===1?"":"s"}`),Q>0&&y.push(`imported ${Q} loose file${Q===1?"":"s"}`),E>0&&y.push(`linked attachments on ${E} note${E===1?"":"s"}`),u>0&&y.push(`updated ${u} note${u===1?"":"s"}' metadata`),f>0&&y.push(`renamed ${f} note${f===1?"":"s"}`),B>0&&y.push(`${B} author${B===1?"":"s"} in registry`),y.push(`(checked ${p} total)`),new et.Notice(`Stashpad: ${y.join(" \xB7 ")}`)}catch(g){new et.Notice(`Stashpad: rebootstrap failed (${g.message})`)}}}),this.addCommand({id:"stashpad-adopt-note",name:"Adopt active note into Stashpad (fill missing frontmatter)",checkCallback:g=>{let p=this.app.workspace.getActiveFile();return!p||p.extension!=="md"?!1:(g||this.adoptNote(p),!0)}}),this.addCommand({id:"stashpad-open-notification-history",name:"Open notification history",callback:()=>{Promise.resolve().then(()=>(Mt(),qe)).then(({NotificationHistoryModal:g,LogModal:p})=>{new g(this.app,this.notifications,async()=>{let u=this.app.vault.adapter,f=this.pluginPrivatePath("log.jsonl");if(!await u.exists(f)){new et.Notice("No log yet \u2014 make some changes first.");return}let B=await u.read(f);new p(this.app,B,f).open()},this.settings.authorId||null,u=>this.lookupNoteAuthorIds(u)).open()})}});let r=[{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 g of r){let p=`stashpad-toggle-${String(g.key).replace(/[A-Z]/g,u=>`-${u.toLowerCase()}`)}`;this.addCommand({id:p,name:`Toggle: ${g.label}`,callback:async()=>{let u=!this.settings[g.key];this.settings[g.key]=u,await this.saveSettings(),new et.Notice(`${g.label}: ${u?"ON":"OFF"}`)}})}this.addCommand({id:"stashpad-open-settings",name:"Open Stashpad settings",callback:()=>{let g=this.app.setting;!g?.open||!g?.openTabById||(g.open(),g.openTabById(this.manifest.id))}}),this.addCommand({id:"stashpad-search-settings",name:"Search Stashpad settings\u2026",callback:()=>{let g=this.app.setting;!g?.open||!g?.openTabById||(g.open(),g.openTabById(this.manifest.id),setTimeout(()=>this.settingTab?.focusSearchInput?.(),0))}});for(let g of fi)this.addCommand({id:`stashpad-open-settings-${g.id}`,name:`Open Stashpad settings: ${g.label}`,callback:()=>{let p=this.app.setting;!p?.open||!p?.openTabById||(this.settingTab?.openToTab(g.id),p.open(),p.openTabById(this.manifest.id))}});let c=()=>{let g=this.app.setting;!g?.open||!g?.openTabById||(g.open(),g.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:g}=await Promise.resolve().then(()=>(Ye(),di)),p=await g(this.app,this,this.settings);if(p.error==="no-dest"){new et.Notice("Set a Designated Stashpad folder for Index in settings first.",6e3),c();return}if(p.error==="no-home"){new et.Notice(`"${this.settings.jdIndexStashpadFolder}" has no Stashpad home note. Open the folder in Stashpad first to create one.`,7e3);return}let{buildJdPreviewNotice:u}=await Promise.resolve().then(()=>(Ye(),di));u(this.app,p)}catch(g){console.error("[stashpad] preview failed",g),new et.Notice(`Preview failed: ${g?.message??g}`,8e3)}}}),this.addCommand({id:"stashpad-build-jd-index",name:"Build JD index notes (creates Stashpad-note hierarchy)",callback:async()=>{try{let{buildJdIndexNotes:g,scanForJdNotes:p,JdBuildConfirmModal:u}=await Promise.resolve().then(()=>(Ye(),di));if(!(this.settings.jdIndexStashpadFolder??"").trim().replace(/^\/+|\/+$/g,"")){new et.Notice("Set a Designated Stashpad folder for Index in settings first.",6e3),c();return}let B=p(this.app,this,this.settings);new u(this.app,this,this.settings,B.indexed.length,async()=>{try{let E=await g(this.app,this,this.settings);if(E.error==="no-dest"){new et.Notice("Set a Designated Stashpad folder for Index in settings first.",6e3),c();return}if(E.error==="dest-not-stashpad"){new et.Notice(`"${E.destFolder}" isn't a known Stashpad folder. Pick a real Stashpad folder in settings.`,7e3),c();return}this.settings.jdIndexHasBuilt=!0,await this.saveSettings(),new et.Notice(`Index built: ${E.created} created, ${E.updated} updated, ${E.skipped} skipped \u2192 ${E.destFolder}`,6e3)}catch(E){console.error("[stashpad] build failed",E),new et.Notice(`Build failed: ${E?.message??E}`,8e3)}}).open()}catch(g){console.error("[stashpad] build failed",g),new et.Notice(`Build failed: ${g?.message??g}`,8e3)}}});let l=g=>{if(g.extension!==_t)return;let p=(this.settings.importDropFolder||"").trim().replace(/^\/+|\/+$/g,""),u=(this.settings.exportFolder||"").trim().replace(/^\/+|\/+$/g,""),f=g.parent?.path||"",B=f.split("/").pop()??"";if(p&&B===p){if(u&&f.endsWith(`/${u}`))return;let Q=f.slice(0,f.length-p.length).replace(/\/+$/,"")||this.settings.folder;this.autoImportStash(g,Q);return}this.settings.autoImport&&this.importService.isArmed()&&(de(g.path)||this.discoverStashpadFolders().includes(f)&&this.autoImportStash(g,f))};this.registerEvent(this.app.vault.on("create",g=>{g instanceof et.TFile&&l(g)})),this.registerEvent(this.app.vault.on("rename",g=>{g instanceof et.TFile&&l(g)}));let d=g=>{if(g.extension!=="md")return;let p=g.parent?.path?.replace(/\/+$/,"")??"";this.discoverStashpadFolders().includes(p)&&setTimeout(()=>{this.fixOrphanParentForFile(g)},800)},I=g=>{if(g.extension!=="md")return;let p=(this.settings.importDropFolder||"").trim().replace(/^\/+|\/+$/g,"");if(!p)return;let u=g.parent?.path?.replace(/\/+$/,"")??"";if((u.split("/").pop()??"")!==p)return;let B=u.slice(0,u.length-p.length).replace(/\/+$/,"");!B||!this.discoverStashpadFolders().includes(B)||setTimeout(()=>{this.adoptMarkdownDrop(g,B)},200)};this.registerEvent(this.app.vault.on("create",g=>{g instanceof et.TFile&&(d(g),I(g))})),this.registerEvent(this.app.vault.on("rename",g=>{g instanceof et.TFile&&(d(g),I(g))})),this.registerEvent(this.app.vault.on("create",g=>{g instanceof et.TFile?this.importService.enqueue(g):g instanceof et.TFolder&&this.importService.enqueueFolder(g)})),this.registerEvent(this.app.vault.on("rename",g=>{g instanceof et.TFile?this.importService.enqueue(g):g instanceof et.TFolder&&this.importService.enqueueFolder(g)})),this.registerEvent(this.app.vault.on("rename",(g,p)=>{g instanceof et.TFile&&this.maybeAdoptAuthorRename(g,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`,i=this.app.vault.adapter;if(!await i.exists(e))return;let s=JSON.parse(await i.read(e))?.version,n=this.manifest.version;if(typeof s!="string"||!s||s===n||!this.isSemverGreater(s,n)||this.notifiedBuildVersion===s)return;this.notifiedBuildVersion=s,this.notifications.show({message:`A newer Stashpad build synced in (\`${n}\` \u2192 \`${s}\`). Reload to apply.`,kind:"info",category:"system",duration:0,actions:[{label:"Reload Stashpad",onClick:async()=>{let o=this.app.plugins;try{await o?.disablePlugin?.(this.manifest.id),await o?.enablePlugin?.(this.manifest.id)}catch(a){new et.Notice(`Couldn't reload \u2014 toggle Stashpad off/on in settings. (${a.message})`)}}}]})}catch(t){console.debug("[Stashpad] synced-build check failed",t)}}isSemverGreater(t,e){let i=t.split(".").map(o=>parseInt(o,10)||0),s=e.split(".").map(o=>parseInt(o,10)||0),n=Math.max(i.length,s.length);for(let o=0;o<n;o++){let a=i[o]??0,r=s[o]??0;if(a!==r)return a>r}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 i=this.authorNameToSafe(e);for(let s of this.discoverStashpadFolders()){let n=`${s}/_authors`;if(await this.app.vault.adapter.exists(n))for(let o of this.app.vault.getMarkdownFiles()){if(!o.path.startsWith(n+"/"))continue;let a=this.parseAuthorFilePath(o.path);if(!a||a.id!==t)continue;let r=`${n}/${i}-${t}.md`,c=o;if(o.path!==r)try{this.authorRenameInFlight.add(o.path),this.authorRenameInFlight.add(r),await this.app.fileManager.renameFile(o,r);let l=this.app.vault.getAbstractFileByPath(r);l&&(c=l)}catch(l){console.warn("[Stashpad] author file rename failed",l);continue}try{await this.refreshAuthorStub(c)}catch{}}}}async refreshAuthorStub(t){let e=(this.settings.authorName??"").trim(),i=(this.settings.authorRole??"").trim(),s=(this.settings.authorDepartment??"").trim();if(e)try{let n=await this.app.vault.read(t),o=n.replace(/^# .*$/m,`# ${e}`);o!==n&&await this.app.vault.modify(t,o),await this.app.fileManager.processFrontMatter(t,a=>{a.aliases=[e],delete a.name,i?a.role=i:delete a.role,s?a.department=s:delete a.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 i=this.parseAuthorFilePath(t.path);if(!i)return;let s=(this.settings.authorId??"").trim();if(!s||i.id!==s)return;let n=i.name.trim();!n||n===(this.settings.authorName??"").trim()||(this.settings.authorName=n,await this.saveSettings(),await this.syncAuthorFilesToName())}async adoptMarkdownDrop(t,e){try{let i=this.app.vault.adapter,s=t.name,n=s.lastIndexOf("."),o=n>0?s.slice(0,n):s,a=n>0?s.slice(n):"",r=0;for(;await i.exists(`${e}/${s}`);)r+=1,s=`${o}-${r}${a}`;let c=`${e}/${s}`;await this.app.fileManager.renameFile(t,c);let l=this.app.vault.getAbstractFileByPath(c);l instanceof et.TFile&&setTimeout(()=>{this.fixOrphanParentForFile(l)},500),this.notifications.show({message:`Imported \`${t.name}\` \u2192 \`${e}\``,kind:"success",category:"import",folder:e,affectedPaths:[c]})}catch(i){console.warn("Stashpad: markdown drop adoption failed",i),this.notifications.show({message:`Couldn't import \`${t.name}\`: ${i.message}`,kind:"error",category:"import"})}}async fixOrphanParentForFile(t){try{let e=this.app.metadataCache.getFileCache(t)?.frontmatter,i=typeof e?.id=="string"?e.id.trim():"",s=e?.parent,n=typeof s=="string"?s.trim()!=="":s!=null,o=typeof e?.created=="string"&&e.created.trim()!=="",a=!i,r=!n,c=!o;if(!a&&!r&&!c)return;let{newId:l}=await Promise.resolve().then(()=>(Tt(),ni)),d,I=!1,g=!1;if(await this.app.fileManager.processFrontMatter(t,f=>{if(a&&(typeof f.id=="string"&&f.id.trim()||(d=l(),f.id=d)),r){let B=f.parent;(typeof B=="string"?B.trim()!=="":B!=null)||(f.parent=G,I=!0)}c&&(typeof f.created=="string"&&f.created.trim()||(f.created=new Date(t.stat.ctime).toISOString(),g=!0))}),!d&&!I&&!g)return;let p=this.newLog(),u=d||i;u&&await p.append({type:"parent_change",id:u,payload:{from:null,to:G,reason:"orphan_auto_fix",path:t.path,addedId:!!d,addedParent:I,addedCreated:g}}),new et.Notice(`Adopted ${t.basename} \u2192 Home`)}catch(e){console.warn("Stashpad: orphan auto-fix failed",e)}}async autoImportStash(t,e){try{let i=new Uint8Array(await this.app.vault.readBinary(t));if(Fe(i)){this.importService.parkEncrypted(t.path),this.notifyPendingEncrypted();return}let s=await ve(this.app,i);if(!s)return;let n=Lt(),o=new Set;if(n&&typeof n.collectExistingIds=="function"&&n.noteFolder===e)for(let c of n.collectExistingIds())o.add(c);else for(let c of this.app.vault.getMarkdownFiles()){if(!c.path.startsWith(e+"/"))continue;let l=this.app.metadataCache.getFileCache(c)?.frontmatter?.id;typeof l=="string"&&o.add(l)}let a=await ye(this.app,s,e,o);try{await this.newLog().append({type:"stash_import",id:G,payload:{from:t.path,into:e,noteCount:a.notesWritten,attachmentsWritten:a.attachmentsWritten,collisionsRenamed:a.collisionsRenamed,auto:!0}})}catch{}try{await this.app.fileManager.trashFile(t)}catch{}let r=[`Auto-imported ${a.notesWritten} note${a.notesWritten===1?"":"s"} from ${t.name}`];a.attachmentsWritten&&r.push(`+ ${a.attachmentsWritten} attachment${a.attachmentsWritten===1?"":"s"}`),a.collisionsRenamed&&r.push(`(${a.collisionsRenamed} renamed)`),this.notifications.show({message:r.join(" "),kind:"success",category:"import",folder:e}),n&&typeof n.debouncedRender=="function"&&n.debouncedRender()}catch(i){this.notifications.show({message:`Stashpad: auto-import failed +`,l=Dt(o.basename)||o.basename,p=await this.uniquePath(t,bt(l,r));await this.createNote(p,ee(a,c)),i.push(p)}}}recordNotePaths(A){return A.kind==="folder"?A.notePaths:[A.notePath]}announce(A,t=[]){let e=A[0]?.folder??"",i=A.length,s=t.length?`, replaced ${t.length}`:"",n=!1,o=async()=>{n||(n=!0,await this.undo(A,t))};this.plugin.notifications.show({message:`Imported ${i} file${i===1?"":"s"}${s} into \`${e.split("/").pop()}\`.`,kind:"success",category:"import",duration:0,folder:e,affectedPaths:A.flatMap(r=>this.recordNotePaths(r)),actions:[{label:"Undo import",onClick:()=>void o()}]}),e&&this.plugin.getUndoStack(e).push({label:`Import ${i} file${i===1?"":"s"}`,undo:async()=>{await o()},redo:async()=>{}})}async undo(A,t=[]){for(let e of A)try{if(e.kind==="md"){let i=this.app.vault.getAbstractFileByPath(e.notePath);i instanceof pt.TFile&&await this.app.fileManager.trashFile(i);let s=this.app.vault.getAbstractFileByPath(e.archivePath);if(s instanceof pt.TFile){let n=await this.uniquePath(e.folder,e.originalName);this.suppress(n),await this.app.fileManager.renameFile(s,n)}}else if(e.kind==="file"){let i=this.app.vault.getAbstractFileByPath(e.notePath);i instanceof pt.TFile&&await this.app.fileManager.trashFile(i);let s=this.app.vault.getAbstractFileByPath(e.attachmentPath);if(s instanceof pt.TFile){let n=await this.uniquePath(e.folder,e.originalName);this.suppress(n),await this.app.fileManager.renameFile(s,n)}}else{for(let s of e.notePaths){let n=this.app.vault.getAbstractFileByPath(s);n instanceof pt.TFile&&await this.app.fileManager.trashFile(n)}for(let s of e.attachmentPaths){let n=this.app.vault.getAbstractFileByPath(s);n instanceof pt.TFile&&await this.app.fileManager.trashFile(n)}let i=this.app.vault.getAbstractFileByPath(e.archivePath);if(i instanceof pt.TFolder){let s=await this.uniquePath(e.folder,e.originalName);this.suppress(s),await this.app.fileManager.renameFile(i,s)}}}catch(i){console.warn("[Stashpad] import undo failed",e,i)}for(let e of t)try{await this.app.vault.adapter.exists(e.path)||await this.app.vault.create(e.path,e.content)}catch(i){console.warn("[Stashpad] import undo: couldn't restore replaced note",e.path,i)}new pt.Notice(`Undid import of ${A.length} file(s).`)}pickFilesInto(A){let t=document.createElement("input");t.type="file",t.multiple=!0,t.style.display="none",t.onchange=async()=>{let e=Array.from(t.files??[]);if(t.remove(),e.length===0)return;let i=[];for(let n of e)try{let o=await n.arrayBuffer(),r=await this.uniquePath(A,n.name);this.suppress(r,6e4),await this.app.vault.createBinary(r,o);let a=this.app.vault.getAbstractFileByPath(r);a instanceof pt.TFile&&i.push(a)}catch(o){console.warn("[Stashpad] file-picker write failed",n.name,o)}if(i.length===0)return;await this.plugin.importLog.load();let s=[];for(let n of i)try{let o=n.stat?.size??null,r=n.extension==="md"?await this.importMarkdown(n):await this.importOtherFile(n);r&&(s.push(r),this.plugin.importLog.append({ts:new Date().toISOString(),folder:r.folder,kind:r.kind,originalName:n.name,size:o,sourcePath:n.path,notePaths:r.kind==="folder"?r.notePaths:[r.notePath]}))}catch(o){console.warn("[Stashpad] file-picker import failed",n.path,o)}s.length>0&&this.announce(s,[])},document.body.appendChild(t),t.click()}async importLooseFilesIn(A){let t=A.replace(/\/+$/,""),e=this.app.vault.getFiles().filter(n=>(n.parent?.path?.replace(/\/+$/,"")??"")===t),i=[];for(let n of e)await this.isStillImportable(n)&&i.push(n);if(i.length===0)return 0;await this.plugin.importLog.load();let s=0;for(let n of i)try{let o=n.stat?.size??null,r=n.extension==="md"?await this.importMarkdown(n):await this.importOtherFile(n);r&&(s++,this.plugin.importLog.append({ts:new Date().toISOString(),folder:r.folder,kind:r.kind,originalName:n.name,size:o,sourcePath:n.path,notePaths:r.kind==="folder"?r.notePaths:[r.notePath]}))}catch(o){console.warn("[Stashpad] loose-file import failed",n.path,o)}return s}async importLooseFoldersIn(A){let t=A.replace(/\/+$/,""),e=this.app.vault.getAbstractFileByPath(t);if(!(e instanceof pt.TFolder))return 0;let i=e.children.filter(n=>n instanceof pt.TFolder&&!Zi.has(n.name));if(i.length===0)return 0;await this.plugin.importLog.load();let s=0;for(let n of i){let o=n.path;try{let r=await this.importFolder(n);r&&r.kind==="folder"&&(s++,this.plugin.importLog.append({ts:new Date().toISOString(),folder:r.folder,kind:r.kind,originalName:n.name,size:null,sourcePath:o,notePaths:r.notePaths}))}catch(r){console.warn("[Stashpad] loose-folder import failed",o,r)}}return s}pendingEncryptedPaths(){for(let A of[...this.pendingEncryptedStashes])this.app.vault.getAbstractFileByPath(A)instanceof pt.TFile||this.pendingEncryptedStashes.delete(A);return[...this.pendingEncryptedStashes]}clearPendingEncrypted(A){this.pendingEncryptedStashes.delete(A)}shouldNotifyEncrypted(){return Date.now()>=this.encryptedNotifySnoozeUntil}snoozeEncryptedNotify(A){this.encryptedNotifySnoozeUntil=A===1/0?Number.MAX_SAFE_INTEGER:Date.now()+A}parkEncrypted(A){return this.pendingEncryptedStashes.has(A)?!1:(this.pendingEncryptedStashes.add(A),this.encryptedNotifySnoozeUntil=0,!0)}async importPendingEncrypted(){let A=0,t=!1;for(let e of this.pendingEncryptedPaths()){let i=this.app.vault.getAbstractFileByPath(e);if(!(i instanceof pt.TFile))continue;let s=i.parent?.path?.replace(/\/+$/,"")??"";if(await this.importOneStash(i,s,this.liveRootIds(s),!1,{allowLater:!0,onLater:()=>{t=!0,this.snoozeEncryptedNotify(60*60*1e3)}})&&A++,t)break}return{imported:A,rescheduled:t}}liveRootIds(A){let t=new Set;for(let e of this.app.vault.getMarkdownFiles()){if((e.parent?.path?.replace(/\/+$/,"")??"")!==A)continue;let i=this.app.metadataCache.getFileCache(e)?.frontmatter?.id;typeof i=="string"&&i&&t.add(i)}return t}async importOneStash(A,t,e,i,s={}){try{let n=new Uint8Array(await this.app.vault.readBinary(A));if(i&&De(n))return this.pendingEncryptedStashes.add(A.path),!1;let o=await be(this.app,n,{...s,secretId:Ge(A.basename)});if(!o)return!1;let r=await ke(this.app,o,t,e);try{await this.app.fileManager.trashFile(A)}catch{}this.pendingEncryptedStashes.delete(A.path);try{await this.plugin.newLog().append({type:"stash_import",id:G,payload:{from:A.path,into:t,noteCount:r.notesWritten,attachmentsWritten:r.attachmentsWritten,collisionsRenamed:r.collisionsRenamed,loose:!0}})}catch{}return!0}catch(n){return console.warn("[Stashpad] loose .stash import failed",A.path,n),!1}}async importLooseStashesIn(A,t={}){let e=A.replace(/\/+$/,""),i=this.app.vault.getFiles().filter(o=>(o.parent?.path?.replace(/\/+$/,"")??"")===e&&o.extension===te);if(i.length===0)return 0;let s=this.liveRootIds(e),n=0;for(let o of i)await this.importOneStash(o,e,s,!!t.auto)&&n++;return n}async importLooseInto(A,t={}){let e=await this.importLooseFilesIn(A),i=await this.importLooseFoldersIn(A),s=await this.importLooseStashesIn(A,t);return{files:e,folders:i,stashes:s}}defaultDestination(){let t=this.plugin.lastActiveStashpadLeaf?.view?.noteFolder;return t&&this.plugin.discoverStashpadFolders().includes(t)?t:this.plugin.discoverStashpadFolders()[0]??null}confirm(A,t,e){return new Promise(i=>{new vt(this.app,A,t,e,i).open()})}dupChoice(A){return new Promise(t=>{new Ye(this.app,A,t).open()})}async ensureFolder(A){let t=this.app.vault.adapter,e=A.split("/").filter(Boolean),i="";for(let s of e){i=i?`${i}/${s}`:s;try{await t.exists(i)||await t.mkdir(i)}catch(n){if(!/already exists/i.test(n.message))throw n}}}async uniquePath(A,t){let e=this.app.vault.adapter,i=t.lastIndexOf("."),s=i>0?t.slice(0,i):t,n=i>0?t.slice(i):"",o=`${A}/${t}`,r=0;for(;await e.exists(o);)r+=1,o=`${A}/${s}-${r}${n}`;return o}};Ne.DEBOUNCE_MS=900,Ne.BATCH_CONFIRM_AT=8;var $i=Ne;var _i=class{constructor(A,t){this.app=A;this.entries=[];this.loaded=!1;this.dirOk=!1;this.writeChain=Promise.resolve();this.path=`${t.replace(/\/+$/,"")}/import-log.jsonl`}getPath(){return this.path}async load(){if(!this.loaded){this.loaded=!0;try{let A=this.app.vault.adapter;if(await A.exists(this.path)){let t=await A.read(this.path);for(let e of t.split(/\r?\n/))if(e.trim())try{this.entries.push(JSON.parse(e))}catch{}}}catch(A){console.warn("[Stashpad] import log load failed",A)}}}recent(){return[...this.entries].reverse()}findDuplicate(A,t){for(let e=this.entries.length-1;e>=0;e--){let i=this.entries[e];if(i.originalName===A&&(t==null||i.size==null||i.size===t))return i}return null}append(A){this.entries.push(A),this.writeChain=this.writeChain.then(async()=>{try{await this.ensureDir(),await this.app.vault.adapter.append(this.path,JSON.stringify(A)+` +`)}catch(t){console.warn("[Stashpad] import log append failed",t)}})}async ensureDir(){if(this.dirOk)return;let A=this.app.vault.adapter,e=this.path.slice(0,this.path.lastIndexOf("/")).split("/").filter(Boolean),i="";for(let s of e)i=i?`${i}/${s}`:s,await A.exists(i)||await A.mkdir(i);this.dirOk=!0}};var ts=class ts{constructor(A,t){this.app=A;this.map=new Map;this.loaded=!1;this.dirty=!1;this.saveTimer=null;this.dirOk=!1;this.writeChain=Promise.resolve();this.path=`${t.replace(/\/+$/,"")}/render-cache.json`}async load(){if(!this.loaded){this.loaded=!0;try{let A=this.app.vault.adapter;if(await A.exists(this.path)){let t=JSON.parse(await A.read(this.path));if(t?.schema===1&&t.entries){for(let[e,i]of Object.entries(t.entries))this.map.set(e,i);for(let e of[...this.map.keys()])this.app.vault.getAbstractFileByPath(e)||(this.map.delete(e),this.dirty=!0)}}}catch(A){console.warn("[Stashpad] render cache load failed; starting empty",A),this.map.clear()}}}get(A){return this.map.get(A)}has(A){return this.map.has(A)}set(A,t){this.map.set(A,t),this.dirty=!0,this.scheduleSave()}scheduleSave(){this.saveTimer==null&&(this.saveTimer=window.setTimeout(()=>{this.saveTimer=null,this.save()},ts.SAVE_DEBOUNCE_MS))}save(){return this.saveTimer!=null&&(window.clearTimeout(this.saveTimer),this.saveTimer=null),this.dirty?(this.dirty=!1,this.writeChain=this.writeChain.then(async()=>{try{await this.ensureDir();let A={schema:1,entries:Object.fromEntries(this.map)};await this.app.vault.adapter.write(this.path,JSON.stringify(A))}catch(A){console.warn("[Stashpad] render cache save failed",A)}}),this.writeChain):this.writeChain}async ensureDir(){if(this.dirOk)return;let A=this.app.vault.adapter,e=this.path.slice(0,this.path.lastIndexOf("/")).split("/").filter(Boolean),i="";for(let s of e)i=i?`${i}/${s}`:s,await A.exists(i)||await A.mkdir(i);this.dirOk=!0}};ts.SAVE_DEBOUNCE_MS=8e3;var ji=ts;var Ls="stashpad:unghost-after-reload",es=class extends et.Plugin{constructor(){super(...arguments);this.settings={...Zt};this.undoStacks=new Map;this.lastActiveStashpadLeaf=null;this.rebootstrapInProgress=!1;this.suppressComposerAutofocusUntil=0;this.settingTab=null;this.stashpadSelectionListeners=new Set;this.stashpadContentListeners=new Set;this._notifications=null;this._authorRegistry=null;this._importService=null;this._importLog=null;this._renderCacheStore=null;this.sweptFolders=new Set;this.notifiedBuildVersion=null;this.authorRenameInFlight=new Set;this.reHomePending=new Set;this.autoSweepInProgress=!1;this.notifPersistenceWired=!1;this.notifSaveTimer=null;this.LAST_CURSOR_LS_KEY="stashpad:last-cursor";this.LAST_SELECTION_LS_KEY="stashpad:last-selection";this.writeChain=Promise.resolve()}get notifications(){return this._notifications||(this._notifications=new Qi(this.app)),this._notifications}get authorRegistry(){return this._authorRegistry||(this._authorRegistry=new Xi(this.app,this.pluginPrivatePath())),this._authorRegistry}get importService(){return this._importService||(this._importService=new $i(this)),this._importService}get importLog(){return this._importLog||(this._importLog=new _i(this.app,this.pluginPrivatePath())),this._importLog}get renderCacheStore(){return this._renderCacheStore||(this._renderCacheStore=new ji(this.app,this.pluginPrivatePath())),this._renderCacheStore}async onunload(){try{await this._renderCacheStore?.save()}catch{}}pluginPrivatePath(t=""){let i=`${this.manifest.dir.replace(/\/+$/,"")}/.stashpad`;return t?`${i}/${t.replace(/^\/+/,"")}`:i}newLog(){return new Vi(this.app,this.pluginPrivatePath(),()=>(this.settings?.authorName??"").trim())}async migrateLegacyPaths(){let t=this.app.vault.adapter,e=this.pluginPrivatePath(),i=async()=>{let r=e.split("/").filter(Boolean),a="";for(let c of r)a=a?`${a}/${c}`:c,await t.exists(a)||await t.mkdir(a)},s=`${this.manifest.dir.replace(/\/+$/,"")}/data.json`,n=this.pluginPrivatePath("data.json");if(await t.exists(s)&&!await t.exists(n))try{await i();let r=await t.read(s);await t.write(n,r),console.debug("[Stashpad] migrated data.json \u2192",n)}catch(r){console.warn("Stashpad: data.json migration failed",r)}let o=".stashpad";if(await t.exists(o))try{await i();let r=await t.list(o);for(let a of r.files){let c=a.replace(/^.*\//,""),l=this.pluginPrivatePath(c);if(!await t.exists(l))try{let p=await t.read(a);await t.write(l,p),console.debug("[Stashpad] migrated",a,"\u2192",l)}catch(p){console.warn(`Stashpad: failed to migrate ${a}`,p)}}}catch(r){console.warn("Stashpad: .stashpad migration scan failed",r)}}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(i){return console.warn("Stashpad: data.json parse failed",i),null}}async saveData(t){let e=this.app.vault.adapter,i=this.pluginPrivatePath();if(!await e.exists(i)){let s=i.split("/").filter(Boolean),n="";for(let o of s)n=n?`${n}/${o}`:o,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 i=this.app.vault.adapter,s=e.split("/").filter(Boolean),n="";for(let c of s)n=n?`${n}/${c}`:c,await i.exists(n)||await i.mkdir(n);let o=`${e}/Home.md`;if(await i.exists(o)){let c=this.app.vault.getAbstractFileByPath(o);c&&await this.app.fileManager.processFrontMatter(c,l=>{(typeof l.id!="string"||!l.id)&&(l.id=G),"parent"in l||(l.parent=null),(typeof l.created!="string"||!l.created)&&(l.created=new Date().toISOString())});return}let r=new Date().toISOString(),a=["---",`id: ${G}`,"parent: null",`created: ${r}`,"---","Home"].join(` +`);await this.app.vault.create(o,a);try{await this.seedLocalAuthorStub(e)}catch{}}collectColorsInFolder(t){let e=new Map,i=t.replace(/\/+$/,"");for(let n of this.app.vault.getMarkdownFiles()){let o=n.parent?.path?.replace(/\/+$/,"")??"";if(o!==i&&!o.startsWith(i+"/"))continue;let r=this.app.metadataCache.getFileCache(n)?.frontmatter,a=typeof r?.color=="string"?r.color.trim():"";if(!a||!/^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(a))continue;let c=a.toLowerCase();e.set(c,(e.get(c)??0)+1)}let s=[...e.entries()].map(([n,o])=>({hex:n,count:o}));return s.sort((n,o)=>o.count-n.count||n.hex.localeCompare(o.hex)),s}async recolorAllInFolder(t,e,i){let s=t.replace(/\/+$/,""),n=e.toLowerCase(),o=0;for(let a of this.app.vault.getMarkdownFiles()){let c=a.parent?.path?.replace(/\/+$/,"")??"";if(c!==s&&!c.startsWith(s+"/"))continue;let l=this.app.metadataCache.getFileCache(a)?.frontmatter;if((typeof l?.color=="string"?l.color.trim().toLowerCase():"")===n)try{await this.app.fileManager.processFrontMatter(a,g=>{i?g.color=i:delete g.color}),o++}catch(g){console.warn(`Stashpad: recolor failed for ${a.path}`,g)}}let r=this.settings.colorAliases?.[s];if(r){let a=r[n];a&&(delete r[n],i&&(r[i.toLowerCase()]=a),Object.keys(r).length===0&&delete this.settings.colorAliases[s],await this.saveSettings())}return o}getColorAlias(t,e){let i=t.replace(/\/+$/,""),s=this.settings.colorAliases?.[i];if(!s)return;let n=s[e.toLowerCase()];return n&&n.trim()?n:void 0}async setColorAlias(t,e,i){let s=t.replace(/\/+$/,""),n=e.toLowerCase();this.settings.colorAliases||(this.settings.colorAliases={}),this.settings.colorAliases[s]||(this.settings.colorAliases[s]={});let o=this.settings.colorAliases[s],r=i.trim();r?o[n]=r:delete o[n],Object.keys(o).length===0&&delete this.settings.colorAliases[s],await this.saveSettings()}async waitForStashpadFolder(t,e=2e3){let i=t.trim().replace(/^\/+|\/+$/g,"");if(!i)return;let s=Date.now();for(;Date.now()-s<e;){if(this.discoverStashpadFolders().includes(i))return;await new Promise(n=>setTimeout(n,80))}}discoverStashpadFolders(){let t=new Set;for(let e of this.app.vault.getMarkdownFiles()){let i=this.app.metadataCache.getFileCache(e)?.frontmatter;if(typeof i?.id!="string"||!i.id.trim()||!i||!("parent"in i))continue;let s=e.parent?.path?.replace(/\/+$/,"")??"";s&&t.add(s)}return[...t].sort()}searchableFolders(t){let e=new Set(this.settings.searchIncludedFolders),i=new Set(this.settings.searchExcludedFolders),n=this.discoverStashpadFolders().filter(a=>e.size>0?e.has(a):!i.has(a)),o=(t||"").trim().replace(/\/+$/,""),r=n.filter(a=>a!==o);return o&&r.unshift(o),r}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 i=this.newLog(),s={},n=this.app.vault.getMarkdownFiles().filter(c=>c.path===t||c.path.startsWith(t+"/"));for(let c of n){let l=this.app.metadataCache.getFileCache(c)?.frontmatter,p=typeof l?.id=="string"?l.id.trim():"";if(!p)continue;let g=l&&"parent"in l?l.parent??null:null;s[p]={parent:g,path:c.path}}let o=await i.readState(),r=c=>c===t||c.startsWith(t+"/");if(!e.silent){for(let[c,l]of Object.entries(s)){let p=o[c];p?p.parent!==l.parent?await i.append({type:"parent_change",id:c,payload:{from:p.parent,to:l.parent}}):p.path!==l.path&&await i.append({type:"rename",id:c,payload:{from:p.path,to:l.path}}):await i.append({type:"create",id:c,payload:{path:l.path,parent:l.parent}})}for(let[c,l]of Object.entries(o))!s[c]&&r(l.path)&&await i.append({type:"missing",id:c,payload:{lastPath:l.path}})}let a={};for(let[c,l]of Object.entries(o))r(l.path)||(a[c]=l);for(let[c,l]of Object.entries(s))a[c]=l;await i.writeState(a)}catch(i){console.warn("Stashpad: integrity sweep failed",i)}}getUndoStack(t){let e=this.undoStacks.get(t);return e||(e=new Wi,this.undoStacks.set(t,e)),e}async onload(){await this.migrateLegacyPaths(),await this.loadSettings(),St.enabled=!!this.settings.enablePerfProfiling,this.settingTab=new vi(this.app,this),this.addSettingTab(this.settingTab),await this.renderCacheStore.load(),await this.authorRegistry.load();{let h=(this.settings.authorId??"").trim();h&&this.authorRegistry.record({id:h,name:this.settings.authorName,role:this.settings.authorRole,department:this.settings.authorDepartment})}this.app.workspace.onLayoutReady(()=>{window.setTimeout(()=>{this.seedLocalAuthorStubsEverywhere()},4e3),window.setTimeout(()=>this.syncObsidianExcludedArchives(),4500),window.setTimeout(()=>this.importService.setArmed(!0),2500),window.setTimeout(()=>void this.runAutoImportSweep(),5e3),this.registerInterval(window.setInterval(()=>void this.runAutoImportSweep(),5*60*1e3)),window.setTimeout(()=>void this.migratePinnedNotesToFrontmatter(),3e3),window.setTimeout(()=>void this.unghostStashpadTabsIfFlagged(),1200)}),this.registerView(gt,h=>new Yi(h,this)),this.registerView(ne,h=>new Si(h,this)),this.registerView(Vt,h=>new Ii(h,this)),this.registerView(ge,h=>new zi(h,this)),this.registerEvent(this.app.workspace.on("active-leaf-change",h=>{h&&h.view.getViewType()===gt&&(this.lastActiveStashpadLeaf=h,this.settings.autoOpenDetailPanel&&this.app.workspace.getLeavesOfType(ne).length===0&&setTimeout(()=>{Di(this.app)},0),this.notifyStashpadSelectionChanged())}));let t=()=>{let h=qt(),I=!!h&&this.app.workspace.activeLeaf&&this.app.workspace.activeLeaf.view===h,u=!!I&&this.settings.hideMobileToolbarInStashpad;document.body.classList.toggle("stashpad-hide-mobile-toolbar",u),document.body.classList.toggle("stashpad-active",!!I)};this.register(hn(t)),this.registerEvent(this.app.workspace.on("active-leaf-change",t));let e=h=>{try{let I=Array.from(document.querySelectorAll("style")).filter(u=>(u.textContent??"").includes(".stashpad-"));for(let u of I){let f=u.id||"",C=f?`style[data-stashpad-source="${f}"]`:null;if(C&&h.head.querySelector(C))continue;let m=h.createElement("style");f?m.setAttribute("data-stashpad-source",f):m.setAttribute("data-stashpad-source","anon"),m.textContent=u.textContent??"",h.head.appendChild(m)}}catch(I){console.warn("[Stashpad] inject popout styles failed",I)}};this.registerEvent(this.app.workspace.on("window-open",h=>{let I=h?.doc??h?.win?.document??null;I&&e(I)})),setTimeout(()=>{try{let h=this.app.workspace;typeof h.iterateAllLeaves=="function"&&h.iterateAllLeaves(I=>{let u=I?.view?.containerEl?.ownerDocument;u&&u!==document&&e(u)})}catch{}},200),t(),this.register(()=>document.body.classList.remove("stashpad-hide-mobile-toolbar","stashpad-active"));let i=window.visualViewport,s=()=>{let h=document.querySelector(".mobile-toolbar, .mobile-toolbar-container"),I=h&&h.isConnected?h.offsetHeight:0;document.body.style.setProperty("--stashpad-toolbar-h",`${I}px`);let u=0;i&&(u=Math.max(0,window.innerHeight-i.height-i.offsetTop)),document.body.style.setProperty("--stashpad-vv-bottom-gap",`${u}px`),document.body.classList.toggle("stashpad-keyboard-open",u>100)};s(),i&&(i.addEventListener("resize",s),i.addEventListener("scroll",s),this.register(()=>{i.removeEventListener("resize",s),i.removeEventListener("scroll",s)})),window.addEventListener("resize",s),this.register(()=>window.removeEventListener("resize",s)),requestAnimationFrame(s),setTimeout(s,250),setTimeout(s,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)",()=>{ui(this.app)}),this.addRibbonIcon("folders","Open Stashpad folder panel (sidebar)",()=>{Ps(this.app)}),this.addRibbonIcon("panel-right","Open Stashpad detail panel (right sidebar)",()=>{Di(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 o=h=>{let I=qt();I&&typeof I[h]=="function"&&I[h]()};this.addCommand({id:"stashpad-toggle-split",name:"Toggle split-on-newlines",callback:()=>o("toggleSplit")}),this.addCommand({id:"stashpad-command-palette",name:"Command palette (Stashpad only)",callback:()=>o("openStashpadCommandPalette")}),this.addCommand({id:"stashpad-claim-selected-author",name:"Claim authorship of selected notes",callback:()=>o("claimSelectedAsAuthor")}),this.addCommand({id:"stashpad-claim-folder-author",name:"Claim authorship of all unauthored notes in this folder",callback:()=>o("claimFolderAsAuthor")}),this.addCommand({id:"stashpad-claim-selected-contributor",name:"Claim selected notes (author if unowned, else add me as contributor)",callback:()=>o("claimSelectedWithContributor")}),this.addCommand({id:"stashpad-claim-folder-contributor",name:"Claim all notes in this folder (author if unowned, else add me as contributor)",callback:()=>o("claimFolderWithContributor")}),this.addCommand({id:"stashpad-pick-destination",name:"Pick destination for next note",callback:()=>o("openDestinationPicker")}),this.addCommand({id:"stashpad-search",name:"Search Stashpad notes",callback:()=>o("openSearchModal")}),this.addCommand({id:"stashpad-search-in-parent",name:"Search in current parent",callback:()=>o("openSearchInParentModal")}),this.addCommand({id:"stashpad-move-picker",name:"Move selection (picker)",callback:()=>o("cmdMovePicker")}),this.addCommand({id:"stashpad-merge",name:"Merge selection",callback:()=>o("cmdMerge")}),this.addCommand({id:"stashpad-copy",name:"Copy selection",callback:()=>o("cmdCopy")}),this.addCommand({id:"stashpad-copy-tree",name:"Copy focused subtree",callback:()=>o("cmdCopyTree")}),this.addCommand({id:"stashpad-copy-outline",name:"Copy as outline (nested embeds)",callback:()=>o("cmdCopyOutline")}),this.addCommand({id:"stashpad-split",name:"Split note\u2026",callback:()=>o("cmdSplit")}),this.addCommand({id:"stashpad-edit-note",name:"Edit note in new tab (selection)",callback:()=>o("cmdOpenInEditor")}),this.addCommand({id:"stashpad-edit-parent",name:"Edit parent note in new tab",callback:()=>o("cmdOpenParentInEditor")}),this.addCommand({id:"stashpad-delete",name:"Delete selection",callback:()=>o("cmdDelete")}),this.addCommand({id:"stashpad-move-up",name:"Move note up",callback:()=>o("cmdMoveUp")}),this.addCommand({id:"stashpad-move-down",name:"Move note down",callback:()=>o("cmdMoveDown")}),this.addCommand({id:"stashpad-move-to-top",name:"Move note to top",callback:()=>o("cmdMoveToTop")}),this.addCommand({id:"stashpad-move-to-bottom",name:"Move note to bottom",callback:()=>o("cmdMoveToBottom")}),this.addCommand({id:"stashpad-outdent",name:"Outdent (move to grandparent)",callback:()=>o("cmdOutdent")}),this.addCommand({id:"stashpad-set-color",name:"Set note color\u2026",callback:()=>o("cmdSetColor")}),this.addCommand({id:"stashpad-clone",name:"Clone selection (duplicate / copy notes)",callback:()=>o("cmdClone")}),this.addCommand({id:"stashpad-insert-template",name:"Insert template (clone an existing note)",callback:()=>o("cmdInsertTemplate")}),this.addCommand({id:"stashpad-toggle-expand",name:"Show more / show less (expand toggle)",callback:()=>o("cmdToggleExpand")}),this.addCommand({id:"stashpad-pick-move",name:"Move (in-list, arrow + Enter)",callback:()=>o("cmdInListPicker")}),this.addCommand({id:"stashpad-open-in-new-tab",name:"Open in new Stashpad tab",callback:()=>o("cmdOpenInNewStashpadTab")}),this.addCommand({id:"stashpad-toggle-complete",name:"Toggle complete (strikethrough)",callback:()=>o("cmdToggleComplete")}),this.addCommand({id:"stashpad-toggle-task",name:"Toggle task (todo)",callback:()=>o("cmdToggleTask")}),this.addCommand({id:"stashpad-set-due",name:"Set due date\u2026",callback:()=>o("cmdSetDue")}),this.addCommand({id:"stashpad-dump-perf",name:"Dump performance profile (copy to clipboard)",callback:async()=>{if(!this.settings.enablePerfProfiling){new et.Notice("Enable \u201CPerformance profiling\u201D in Stashpad settings first, then use the app and run this again.");return}let h=St.report();console.log(h);try{await navigator.clipboard.writeText(h)}catch{}new et.Notice("Performance profile copied to clipboard (also in the console).")}}),this.addCommand({id:"stashpad-reset-perf",name:"Reset performance profile",callback:()=>{St.reset(),new et.Notice("Performance profile reset.")}}),this.addCommand({id:"stashpad-jump-to-top",name:"Jump to top of list",callback:()=>o("jumpToTop")}),this.addCommand({id:"stashpad-jump-to-bottom",name:"Jump to bottom of list",callback:()=>o("jumpToBottom")}),this.addCommand({id:"stashpad-assign",name:"Assign task to\u2026",callback:()=>o("cmdAssign")}),this.addCommand({id:"stashpad-open-import-log",name:"Open import log",callback:async()=>{await this.importLog.load();let{ImportLogModal:h}=await Promise.resolve().then(()=>(Mt(),ze));new h(this.app,this.importLog.recent()).open()}}),this.addCommand({id:"stashpad-import-files",name:"Import file(s) into Stashpad\u2026",callback:()=>this.openImportPicker()}),this.addCommand({id:"stashpad-import-loose-files",name:"Import loose files & folders in this folder (scan for moved-in / unprocessed items)",checkCallback:h=>{let I=this.importService.defaultDestination();return h?!!I:(I&&this.runImportLooseFiles(I),!0)}}),this.addCommand({id:"stashpad-rerun-slug-pass",name:"Re-run filename (slug) pass on this folder",checkCallback:h=>{let I=this.importService.defaultDestination();return h?!!I:(I&&this.runFolderSlugPass(I),!0)}}),this.addCommand({id:"stashpad-rerun-frontmatter-backfill",name:"Re-run frontmatter backfill (recovery links) on this folder",checkCallback:h=>{let I=this.importService.defaultDestination();return h?!!I:(I&&this.runFolderFrontmatterBackfill(I),!0)}}),this.addCommand({id:"stashpad-select-all",name:"Select all visible notes",callback:()=>o("cmdSelectAll")}),this.addCommand({id:"stashpad-copy-codeblock",name:"Copy code from codeblock",callback:()=>o("cmdCopyCodeBlock")}),this.addCommand({id:"stashpad-open-panels",name:"Open Stashpad panels (sidebar)",callback:()=>void ui(this.app)}),this.addCommand({id:"stashpad-open-folder-panel",name:"Open folder panel (sidebar)",callback:()=>void Ps(this.app)}),this.addCommand({id:"stashpad-open-detail",name:"Open Stashpad detail panel (right sidebar)",callback:()=>void Di(this.app)}),this.addCommand({id:"stashpad-reveal-active-note",name:"Open this note in Stashpad",checkCallback:h=>{let I=this.app.workspace.getActiveFile(),u=!!I&&I.extension==="md"&&this.isStashpadNoteFile(I);return h||u&&I&&this.revealNoteInStashpad(I),u}});let r=Object.keys(Ve);for(let h of r){let I=Ve[h];this.addCommand({id:`stashpad-open-panels-${h}`,name:`Open Stashpad panel: ${I.label}`,callback:async()=>{await ui(this.app),this.app.workspace.getLeavesOfType(Vt)[0]?.view?.setActivePanel?.(h)}})}this.addCommand({id:"stashpad-swap-with-parent",name:"Swap with parent (ouroboros)",callback:()=>o("cmdSwapWithParent")}),this.addCommand({id:"stashpad-toggle-pin",name:"Pin / unpin selected note (sidebar)",callback:()=>o("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:()=>o("cmdCloneStashpadTab")}),this.addCommand({id:"stashpad-undo",name:"Undo last Stashpad action",callback:()=>o("cmdUndo")}),this.addCommand({id:"stashpad-redo",name:"Redo last undone Stashpad action",callback:()=>o("cmdRedo")}),this.addCommand({id:"stashpad-export-stash",name:"Export selection to .stash",callback:()=>o("cmdExportStash")}),this.addCommand({id:"stashpad-import-stash",name:"Import .stash file\u2026",callback:()=>o("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 I=qt(),u=I&&I.noteFolder;return u?(h||(new et.Notice(`Running integrity check on "${u}"\u2026`),this.runIntegrityCheckOnFolder(u).then(()=>{new et.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 et.Notice("Stashpad: rebuilding author registry\u2026");try{let h=await this.rebuildAuthorRegistry();this.notifications.show({message:`Author registry rebuilt: ${h.total} author(s) \u2014 ${h.fromStubs} from stubs, ${h.fromNotes} from note links.`,kind:"success",category:"system"})}catch(h){new et.Notice(`Author registry rebuild failed: ${h.message}`)}}}),this.addCommand({id:"stashpad-restore-author-stubs",name:"Restore missing author stubs (from registry)",callback:async()=>{new et.Notice("Stashpad: restoring author stubs\u2026");try{let h=await this.restoreMissingAuthorStubs();this.notifications.show({message:h.created>0?`Restored ${h.created} author stub(s) across ${h.folders} folder(s).`:`No missing author stubs \u2014 all present across ${h.folders} folder(s).`,kind:"success",category:"system"})}catch(h){new et.Notice(`Restore author stubs failed: ${h.message}`)}}}),this.addCommand({id:"stashpad-rebootstrap-all",name:"Rebootstrap all Stashpad folders (backfill metadata + rename stale titles)",callback:async()=>{new et.Notice("Stashpad: rebootstrapping\u2026");try{let{touched:h,fmChecked:I,fmWritten:u,slugsRenamed:f,authors:C,imported:m,attachmentsLinked:E}=await this.rebootstrapAllFolders(),y=[];y.push(`rebootstrapped ${h.length} folder${h.length===1?"":"s"}`),m>0&&y.push(`imported ${m} loose file${m===1?"":"s"}`),E>0&&y.push(`linked attachments on ${E} note${E===1?"":"s"}`),u>0&&y.push(`updated ${u} note${u===1?"":"s"}' metadata`),f>0&&y.push(`renamed ${f} note${f===1?"":"s"}`),C>0&&y.push(`${C} author${C===1?"":"s"} in registry`),y.push(`(checked ${I} total)`),new et.Notice(`Stashpad: ${y.join(" \xB7 ")}`)}catch(h){new et.Notice(`Stashpad: rebootstrap failed (${h.message})`)}}}),this.addCommand({id:"stashpad-adopt-note",name:"Adopt active note into Stashpad (fill missing frontmatter)",checkCallback:h=>{let I=this.app.workspace.getActiveFile();return!I||I.extension!=="md"?!1:(h||this.adoptNote(I),!0)}}),this.addCommand({id:"stashpad-open-notification-history",name:"Open notification history",callback:()=>{Promise.resolve().then(()=>(Mt(),ze)).then(({NotificationHistoryModal:h,LogModal:I})=>{new h(this.app,this.notifications,async()=>{let u=this.app.vault.adapter,f=this.pluginPrivatePath("log.jsonl");if(!await u.exists(f)){new et.Notice("No log yet \u2014 make some changes first.");return}let C=await u.read(f);new I(this.app,C,f).open()},this.settings.authorId||null,u=>this.lookupNoteAuthorIds(u)).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 I=`stashpad-toggle-${String(h.key).replace(/[A-Z]/g,u=>`-${u.toLowerCase()}`)}`;this.addCommand({id:I,name:`Toggle: ${h.label}`,callback:async()=>{let u=!this.settings[h.key];this.settings[h.key]=u,await this.saveSettings(),new et.Notice(`${h.label}: ${u?"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 Fi)this.addCommand({id:`stashpad-open-settings-${h.id}`,name:`Open Stashpad settings: ${h.label}`,callback:()=>{let I=this.app.setting;!I?.open||!I?.openTabById||(this.settingTab?.openToTab(h.id),I.open(),I.openTabById(this.manifest.id))}});let c=()=>{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(()=>(Xe(),Bi)),I=await h(this.app,this,this.settings);if(I.error==="no-dest"){new et.Notice("Set a Designated Stashpad folder for Index in settings first.",6e3),c();return}if(I.error==="no-home"){new et.Notice(`"${this.settings.jdIndexStashpadFolder}" has no Stashpad home note. Open the folder in Stashpad first to create one.`,7e3);return}let{buildJdPreviewNotice:u}=await Promise.resolve().then(()=>(Xe(),Bi));u(this.app,I)}catch(h){console.error("[stashpad] preview failed",h),new et.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:I,JdBuildConfirmModal:u}=await Promise.resolve().then(()=>(Xe(),Bi));if(!(this.settings.jdIndexStashpadFolder??"").trim().replace(/^\/+|\/+$/g,"")){new et.Notice("Set a Designated Stashpad folder for Index in settings first.",6e3),c();return}let C=I(this.app,this,this.settings);new u(this.app,this,this.settings,C.indexed.length,async()=>{try{let E=await h(this.app,this,this.settings);if(E.error==="no-dest"){new et.Notice("Set a Designated Stashpad folder for Index in settings first.",6e3),c();return}if(E.error==="dest-not-stashpad"){new et.Notice(`"${E.destFolder}" isn't a known Stashpad folder. Pick a real Stashpad folder in settings.`,7e3),c();return}this.settings.jdIndexHasBuilt=!0,await this.saveSettings(),new et.Notice(`Index built: ${E.created} created, ${E.updated} updated, ${E.skipped} skipped \u2192 ${E.destFolder}`,6e3)}catch(E){console.error("[stashpad] build failed",E),new et.Notice(`Build failed: ${E?.message??E}`,8e3)}}).open()}catch(h){console.error("[stashpad] build failed",h),new et.Notice(`Build failed: ${h?.message??h}`,8e3)}}});let l=h=>{if(h.extension!==te)return;let I=(this.settings.importDropFolder||"").trim().replace(/^\/+|\/+$/g,""),u=(this.settings.exportFolder||"").trim().replace(/^\/+|\/+$/g,""),f=h.parent?.path||"",C=f.split("/").pop()??"";if(I&&C===I){if(u&&f.endsWith(`/${u}`))return;let m=f.slice(0,f.length-I.length).replace(/\/+$/,"")||this.settings.folder;this.autoImportStash(h,m);return}this.settings.autoImport&&this.importService.isArmed()&&(Ie(h.path)||this.discoverStashpadFolders().includes(f)&&this.autoImportStash(h,f))};this.registerEvent(this.app.vault.on("create",h=>{h instanceof et.TFile&&l(h)})),this.registerEvent(this.app.vault.on("rename",h=>{h instanceof et.TFile&&l(h)}));let p=h=>{if(h.extension!=="md")return;let I=h.parent?.path?.replace(/\/+$/,"")??"";this.discoverStashpadFolders().includes(I)&&setTimeout(()=>{this.fixOrphanParentForFile(h)},800)},g=h=>{if(h.extension!=="md")return;let I=(this.settings.importDropFolder||"").trim().replace(/^\/+|\/+$/g,"");if(!I)return;let u=h.parent?.path?.replace(/\/+$/,"")??"";if((u.split("/").pop()??"")!==I)return;let C=u.slice(0,u.length-I.length).replace(/\/+$/,"");!C||!this.discoverStashpadFolders().includes(C)||setTimeout(()=>{this.adoptMarkdownDrop(h,C)},200)};this.registerEvent(this.app.vault.on("create",h=>{h instanceof et.TFile&&(p(h),g(h))})),this.registerEvent(this.app.vault.on("rename",h=>{h instanceof et.TFile&&(p(h),g(h))})),this.registerEvent(this.app.vault.on("rename",(h,I)=>{h instanceof et.TFile&&this.maybeReHomeOnCrossFolderMove(h,I)})),this.registerEvent(this.app.vault.on("create",h=>{h instanceof et.TFile?this.importService.enqueue(h):h instanceof et.TFolder&&this.importService.enqueueFolder(h)})),this.registerEvent(this.app.vault.on("rename",h=>{h instanceof et.TFile?this.importService.enqueue(h):h instanceof et.TFolder&&this.importService.enqueueFolder(h)})),this.registerEvent(this.app.vault.on("rename",(h,I)=>{h instanceof et.TFile&&this.maybeAdoptAuthorRename(h,I)})),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`,i=this.app.vault.adapter;if(!await i.exists(e))return;let s=JSON.parse(await i.read(e))?.version,n=this.manifest.version;if(typeof s!="string"||!s||s===n||!this.isSemverGreater(s,n)||this.notifiedBuildVersion===s)return;this.notifiedBuildVersion=s,this.notifications.show({message:`A newer Stashpad build synced in (\`${n}\` \u2192 \`${s}\`). Reload the app to apply it.`,kind:"info",category:"system",duration:0,actions:[{label:"Reload app",onClick:()=>this.reloadAppForUpdate()}]})}catch(t){console.debug("[Stashpad] synced-build check failed",t)}}reloadAppForUpdate(){try{window.localStorage?.setItem(Ls,"1")}catch{}try{if(this.app.commands?.executeCommandById?.("app:reload"))return}catch(t){console.warn("[Stashpad] app:reload command failed",t)}try{window.location.reload()}catch{new et.Notice("Reload Obsidian (close + reopen) to apply the Stashpad update.")}}async unghostStashpadTabsIfFlagged(){let t=!1;try{t=window.localStorage?.getItem(Ls)==="1"}catch{}if(t){try{window.localStorage?.removeItem(Ls)}catch{}for(let e of this.app.workspace.getLeavesOfType(gt))try{let i=e;i.isDeferred&&typeof i.loadIfDeferred=="function"&&await i.loadIfDeferred()}catch(i){console.warn("[Stashpad] un-ghost leaf failed",i)}}}isSemverGreater(t,e){let i=t.split(".").map(o=>parseInt(o,10)||0),s=e.split(".").map(o=>parseInt(o,10)||0),n=Math.max(i.length,s.length);for(let o=0;o<n;o++){let r=i[o]??0,a=s[o]??0;if(r!==a)return r>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 i=this.authorNameToSafe(e);for(let s of this.discoverStashpadFolders()){let n=`${s}/_authors`;if(await this.app.vault.adapter.exists(n))for(let o of this.app.vault.getMarkdownFiles()){if(!o.path.startsWith(n+"/"))continue;let r=this.parseAuthorFilePath(o.path);if(!r||r.id!==t)continue;let a=`${n}/${i}-${t}.md`,c=o;if(o.path!==a)try{this.authorRenameInFlight.add(o.path),this.authorRenameInFlight.add(a),await this.app.fileManager.renameFile(o,a);let l=this.app.vault.getAbstractFileByPath(a);l&&(c=l)}catch(l){console.warn("[Stashpad] author file rename failed",l);continue}try{await this.refreshAuthorStub(c)}catch{}}}}async refreshAuthorStub(t){let e=(this.settings.authorName??"").trim(),i=(this.settings.authorRole??"").trim(),s=(this.settings.authorDepartment??"").trim();if(e)try{let n=await this.app.vault.read(t),o=n.replace(/^# .*$/m,`# ${e}`);o!==n&&await this.app.vault.modify(t,o),await this.app.fileManager.processFrontMatter(t,r=>{r.aliases=[e],delete r.name,i?r.role=i:delete r.role,s?r.department=s:delete r.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 i=this.parseAuthorFilePath(t.path);if(!i)return;let s=(this.settings.authorId??"").trim();if(!s||i.id!==s)return;let n=i.name.trim();!n||n===(this.settings.authorName??"").trim()||(this.settings.authorName=n,await this.saveSettings(),await this.syncAuthorFilesToName())}async adoptMarkdownDrop(t,e){try{let i=this.app.vault.adapter,s=t.name,n=s.lastIndexOf("."),o=n>0?s.slice(0,n):s,r=n>0?s.slice(n):"",a=0;for(;await i.exists(`${e}/${s}`);)a+=1,s=`${o}-${a}${r}`;let c=`${e}/${s}`;await this.app.fileManager.renameFile(t,c);let l=this.app.vault.getAbstractFileByPath(c);l instanceof et.TFile&&setTimeout(()=>{this.fixOrphanParentForFile(l)},500),this.notifications.show({message:`Imported \`${t.name}\` \u2192 \`${e}\``,kind:"success",category:"import",folder:e,affectedPaths:[c]})}catch(i){console.warn("Stashpad: markdown drop adoption failed",i),this.notifications.show({message:`Couldn't import \`${t.name}\`: ${i.message}`,kind:"error",category:"import"})}}async fixOrphanParentForFile(t){try{let e=this.app.metadataCache.getFileCache(t)?.frontmatter,i=typeof e?.id=="string"?e.id.trim():"",s=e?.parent,n=typeof s=="string"?s.trim()!=="":s!=null,o=typeof e?.created=="string"&&e.created.trim()!=="",r=!i,a=!n,c=!o;if(!r&&!a&&!c)return;let{newId:l}=await Promise.resolve().then(()=>(Rt(),hi)),p,g=!1,h=!1;if(await this.app.fileManager.processFrontMatter(t,f=>{if(r&&(typeof f.id=="string"&&f.id.trim()||(p=l(),f.id=p)),a){let C=f.parent;(typeof C=="string"?C.trim()!=="":C!=null)||(f.parent=G,g=!0)}c&&(typeof f.created=="string"&&f.created.trim()||(f.created=new Date(t.stat.ctime).toISOString(),h=!0))}),!p&&!g&&!h)return;let I=this.newLog(),u=p||i;u&&await I.append({type:"parent_change",id:u,payload:{from:null,to:G,reason:"orphan_auto_fix",path:t.path,addedId:!!p,addedParent:g,addedCreated:h}}),new et.Notice(`Adopted ${t.basename} \u2192 Home`)}catch(e){console.warn("Stashpad: orphan auto-fix failed",e)}}maybeReHomeOnCrossFolderMove(t,e){if(t.extension!=="md")return;let i=t.parent?.path?.replace(/\/+$/,"")??"",s=e.lastIndexOf("/"),n=(s>=0?e.slice(0,s):"").replace(/\/+$/,"");i!==n&&this.discoverStashpadFolders().includes(i)&&(this.reHomePending.has(t.path)||(this.reHomePending.add(t.path),setTimeout(()=>{this.reHomePending.delete(t.path),this.reHomeDanglingParent(t,i)},900)))}async reHomeDanglingParent(t,e){try{let i=this.app.metadataCache.getFileCache(t)?.frontmatter,s=typeof i?.id=="string"?i.id.trim():"",n=typeof i?.parent=="string"?i.parent.trim():"";if(!s||!n||n===G||this.app.vault.getMarkdownFiles().some(r=>(r.parent?.path?.replace(/\/+$/,"")??"")===e&&this.app.metadataCache.getFileCache(r)?.frontmatter?.id===n))return;await this.app.fileManager.processFrontMatter(t,r=>{let a=typeof r.parent=="string"?r.parent.trim():"";a&&a!==G&&(r.parent=G)}),await this.newLog().append({type:"parent_change",id:s,payload:{from:n,to:G,reason:"rehome_cross_folder_move",path:t.path}}),new et.Notice(`Re-homed ${t.basename} \u2192 Home (its parent isn't in this folder)`)}catch(i){console.warn("[Stashpad] re-home on cross-folder move failed",i)}}async autoImportStash(t,e){try{let i=new Uint8Array(await this.app.vault.readBinary(t));if(De(i)){this.importService.parkEncrypted(t.path),this.notifyPendingEncrypted();return}let s=await be(this.app,i);if(!s)return;let n=qt(),o=new Set;if(n&&typeof n.collectExistingIds=="function"&&n.noteFolder===e)for(let c of n.collectExistingIds())o.add(c);else for(let c of this.app.vault.getMarkdownFiles()){if(!c.path.startsWith(e+"/"))continue;let l=this.app.metadataCache.getFileCache(c)?.frontmatter?.id;typeof l=="string"&&o.add(l)}let r=await ke(this.app,s,e,o);try{await this.newLog().append({type:"stash_import",id:G,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 a=[`Auto-imported ${r.notesWritten} note${r.notesWritten===1?"":"s"} from ${t.name}`];r.attachmentsWritten&&a.push(`+ ${r.attachmentsWritten} attachment${r.attachmentsWritten===1?"":"s"}`),r.collisionsRenamed&&a.push(`(${r.collisionsRenamed} renamed)`),this.notifications.show({message:a.join(" "),kind:"success",category:"import",folder:e}),n&&typeof n.debouncedRender=="function"&&n.debouncedRender()}catch(i){this.notifications.show({message:`Stashpad: auto-import failed File: \`${t.name}\` Error: ${i.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:Ii(this.app,t.path,et.Platform.isMobile)}),console.error(i)}}lookupNoteAuthorIds(t){let e=new Set,i=s=>{if(typeof s!="string")return null;let n=s.match(/-([a-z0-9]{4,12})(?:\.md)?(?:\||\]\])/i);return n?n[1]:null};for(let s of this.app.vault.getMarkdownFiles()){let n=this.app.metadataCache.getFileCache(s)?.frontmatter;if(n?.id!==t)continue;let o=i(n?.author);o&&e.add(o);let a=n?.contributors;if(Array.isArray(a))for(let r of a){let c=i(r);c&&e.add(c)}break}return Array.from(e)}lookupNoteAuthorId(t){return this.lookupNoteAuthorIds(t)[0]??null}async rebootstrapAllFolders(){this.rebootstrapInProgress=!0;try{return await this.rebootstrapAllFoldersInner()}finally{window.setTimeout(()=>{this.rebootstrapInProgress=!1},2500)}}async rebootstrapAllFoldersInner(){let t="__root__",e=new Set;for(let g of this.app.vault.getMarkdownFiles()){if(this.app.metadataCache.getFileCache(g)?.frontmatter?.id!==t)continue;let u=g.parent?.path;u&&e.add(u)}let i=(this.settings.importDropFolder||"").trim().replace(/^\/+|\/+$/g,""),s=(this.settings.exportFolder||"").trim().replace(/^\/+|\/+$/g,""),n=[],o=async g=>{if(g&&!await this.app.vault.adapter.exists(g))try{await this.app.vault.createFolder(g)}catch(p){let u=p?.message??"";if(!/already exists/i.test(u))throw p}},a=0,r=0,c=0,l=0;for(let g of e)try{if(i&&await o(`${g}/${i}`),s&&await o(`${g}/${s}`),this.settings.autoImport)try{let u=await this.importService.importLooseInto(g);l+=u.files+u.folders+u.stashes}catch(u){console.warn("Stashpad: loose sweep failed",g,u)}let p=await en(this.app,g);a+=p.checked,r+=p.written,c+=await this.rebootstrapFolderSlugs(g),n.push(g)}catch(p){console.warn(`Stashpad: rebootstrap skipped ${g}`,p)}let d=0;try{d=(await this.rebuildAuthorRegistry()).total}catch(g){console.warn("Stashpad: rebootstrap author-registry rebuild failed",g)}let I=0;try{I=await this.convertAttachmentsToLinks()}catch(g){console.warn("Stashpad: attachment-link conversion failed",g)}return{touched:n,fmChecked:a,fmWritten:r,slugsRenamed:c,authors:d,imported:l,attachmentsLinked:I}}async rebootstrapFolderSlugs(t){let e="__root__",i=t.replace(/\/+$/,""),s=this.settings.slugStopWords??Gt,n=0,o=this.app.vault.getMarkdownFiles().filter(a=>(a.parent?.path?.replace(/\/+$/,"")??"")===i);for(let a of o){let r=pe(a.basename);if(!(!r||r===e||this.app.metadataCache.getFileCache(a)?.frontmatter?.id!==r))try{let l=await this.app.vault.cachedRead(a),d=l.startsWith("---")?l.slice(l.indexOf(` ----`,3)+4).replace(/^\r?\n/,""):l,I=kt(d,s),g=St(I,r);if(a.name===g)continue;let p=a.parent?`${a.parent.path}/${g}`:g;if(this.app.vault.getAbstractFileByPath(p))continue;await this.app.fileManager.renameFile(a,p),n+=1}catch(l){console.warn(`Stashpad: slug rebootstrap skipped ${a.path}`,l)}}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?.()!==ut)return null;let i=e.noteFolder??"";if(!i)return null;let s=e.currentChildren??[],n;if(typeof e.cursorIdx=="number"&&e.cursorIdx>=0&&(n=s[e.cursorIdx]),!n&&e.selection?.size>0){let o=e.firstSelectedId??[...e.selection][0];n=s.find(a=>a.id===o)}return n?.file?{folder:i,id:n.id,file:n.file}:null}async pinNote(t){let e=this.settings.pinnedNotes??[];e.some(i=>i.folder===t.folder&&i.id===t.id)||(this.settings.pinnedNotes=[...e,t],await this.saveSettings(),this.refreshPanelsView())}async unpinNote(t){let e=this.settings.pinnedNotes??[],i=e.filter(s=>!(s.folder===t.folder&&s.id===t.id));i.length!==e.length&&(this.settings.pinnedNotes=i,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(Yt);for(let e of t){let i=e.view;i&&typeof i.render=="function"&&i.render()}}openFolderPicker(){let t=p=>{let f=p.getViewState().state?.folderOverride;return typeof f=="string"&&f.trim()?f.trim().replace(/^\/+|\/+$/g,""):(this.settings.folder||"Stashpad").trim().replace(/^\/+|\/+$/g,"")},e=this.app.workspace.getLeavesOfType(ut),i=this.discoverStashpadFolders(),s=Lt(),n=s?(s.noteFolder??"").trim().replace(/^\/+|\/+$/g,""):"",o=new Set;for(let p of this.app.vault.getAllLoadedFiles())if(p.children){let u=p.path;u&&u!=="/"&&!u.startsWith(".")&&o.add(u)}let a=p=>{let u=p.split("/").filter(Boolean).pop()??"";return u?new Set([this.settings.importDropFolder,this.settings.exportFolder,"_attachments","_processed","_authors","_exports","_imports","_archive",".archive"].map(B=>(B??"").trim().replace(/^\/+|\/+$/g,"")).filter(Boolean)).has(u):!1},r=new Set,c=[],l=[],d=new Set;for(let p of e){let u=t(p);if(d.has(u))continue;d.add(u),r.add(u);let f=u.split("/").pop()||u;c.push({kind:"reveal",folder:u,label:`Reveal "${f}" tab`,leaf:p,icon:"layout-grid"}),l.push({kind:"open-anyway",folder:u,label:`Open "${f}" in another new tab`,icon:"layout-template"})}for(let p of i.filter(u=>!r.has(u))){let u=p.split("/").pop()||p;c.push({kind:"open",folder:p,label:`Open "${u}" in new tab`,icon:"layout-template"})}let I=this,g=new class extends et.SuggestModal{getSuggestions(p){let u=p.trim().toLowerCase(),f=u?u.split(/\s+/).filter(Boolean):[],B=v=>{if(!f.length)return!0;let k=v.toLowerCase();for(let b of f)if(!k.includes(b))return!1;return!0},Q=u?c.filter(v=>{let k="folder"in v?v.folder:"";return B(v.label)||B(k)}):c.slice();if(u&&s&&n)for(let v of i){if(v.toLowerCase()===n.toLowerCase())continue;let k=v.split("/").pop()??v,b=`${v} ${k}`;B(b)&&Q.push({kind:"switch-current",folder:v,label:`Switch this tab to "${k}"`,icon:"folder-input"})}let E=p.trim().replace(/^\/+|\/+$/g,"");if(E&&!a(E)){let v=Array.from(o).find(b=>b.toLowerCase()===E.toLowerCase()),k=i.some(b=>b.toLowerCase()===E.toLowerCase());if(v&&!k)Q.push({kind:"convert",folder:v,label:`Convert \u201C${Xe(v)}\u201D into a Stashpad\u2026`,icon:"folder-cog"});else if(!v){let b=Xe(E);Q.push({kind:"create",folder:E,label:`+ Create new Stashpad \u201C${b}\u201D`,icon:"folder-plus"})}}let y=l.filter(v=>B(v.label)||B(v.folder));return Q.push(...y),Q}renderSuggestion(p,u){u.addClass("stashpad-suggest-item"),u.addClass("stashpad-ribbon-suggest-item"),p.kind==="create"&&u.addClass("stashpad-suggest-create");let f=u.createSpan({cls:"stashpad-ribbon-suggest-icon"});(0,et.setIcon)(f,p.icon);let B=u.createDiv({cls:"stashpad-ribbon-suggest-body"});B.createDiv({cls:"stashpad-suggest-title",text:p.label}),"folder"in p&&p.folder&&p.label!==p.folder&&B.createDiv({cls:"stashpad-suggest-preview",text:p.folder})}async onChooseSuggestion(p){if(p.kind==="reveal"){I.app.workspace.revealLeaf(p.leaf);return}if(p.kind==="open"||p.kind==="open-anyway"){await I.activateViewForFolder(p.folder);return}if(p.kind==="switch-current"){let u=s;u&&typeof u.setFolderOverride=="function"&&(await u.setFolderOverride(p.folder),I.app.workspace.revealLeaf(u.leaf));return}if(p.kind==="create"){try{let u=Xe(p.folder);await I.app.vault.adapter.exists(u)||await I.app.vault.createFolder(u),await I.activateViewForFolder(u)}catch(u){new et.Notice(`Stashpad: couldn't create folder (${u.message})`)}return}if(p.kind==="convert"){let{ConfirmModal:u}=await Promise.resolve().then(()=>(Mt(),qe)),f=p.folder,B=[`\u201C${f}\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 u(I.app,"Convert into a Stashpad?",B.join(` -`),"Convert",async Q=>{if(Q)try{await I.activateViewForFolder(f)}catch(E){new et.Notice(`Stashpad: couldn't convert folder (${E.message})`)}}).open();return}}}(this.app);g.setPlaceholder(s?"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"),g.open()}async openTinyWindow(){let t=Lt(),e=t?.folderOverride??null,i=t?.focusId??"__root__",s=!!t?.compactMode,n=this.app.workspace.openPopoutLeaf?.();if(!n){new et.Notice("Stashpad: couldn't open popout window on this build.");return}await n.setViewState({type:ut,active:!0,state:{folderOverride:e,focusId:i,tinyMode:!0,tinyAlwaysOnTop:!1,compactMode:s}});try{this.app.workspace.revealLeaf(n)}catch{}}async activateView(t={reveal:!0}){let{workspace:e}=this.app;if(t.reveal){let s=e.getLeavesOfType(ut);if(s.length>0){e.revealLeaf(s[0]);return}}let i=e.getLeaf("tab");await i.setViewState({type:ut,active:!0}),e.revealLeaf(i)}async activateViewForFolder(t){let e=(t||"").replace(/^\/+|\/+$/g,"");if(!e)return;let i=this.app.workspace.getLeaf("tab");await i.setViewState({type:ut,active:!0,state:{folderOverride:e}}),this.app.workspace.revealLeaf(i)}isStashpadNoteFile(t){let e=t.parent?.path?.replace(/\/+$/,"")??"";if(!this.discoverStashpadFolders().includes(e))return!1;let i=this.app.metadataCache.getFileCache(t)?.frontmatter?.id;return typeof i=="string"&&i.length>0}async revealNoteInStashpad(t){let e=t.parent?.path?.replace(/\/+$/,"")??"",i=this.app.metadataCache.getFileCache(t)?.frontmatter?.id;if(!e||typeof i!="string"||!i){new et.Notice("That note isn't a Stashpad note.");return}let s=this.app.workspace.getLeavesOfType(ut).find(o=>(o.view?.noteFolder??"")===e);if(s){this.app.workspace.revealLeaf(s);let o=s.view;typeof o?.navigateTo=="function"&&o.navigateTo(i);return}await this.activateViewForFolder(e);let n=this.lastActiveStashpadLeaf?.view;typeof n?.navigateTo=="function"&&n.navigateTo(i)}collectAuthoredFolders(){let t=(this.settings.authorId??"").trim();if(!t)return[];let e=`-${t}`,i=this.discoverStashpadFolders(),s=new Map;for(let n of this.app.vault.getMarkdownFiles()){let o=this.app.metadataCache.getFileCache(n)?.frontmatter;if(!o)continue;let a=typeof o.author=="string"?o.author:"",r=Array.isArray(o.contributors)?o.contributors.filter(p=>typeof p=="string"):[],c=a.includes(e),l=r.some(p=>p.includes(e));if(!c&&!l)continue;let d=n.parent?.path??"",I=i.find(p=>d===p||d.startsWith(p+"/"));if(!I)continue;s.has(I)||s.set(I,{authored:0,contributed:0});let g=s.get(I);c&&g.authored++,l&&g.contributed++}return[...s.entries()].map(([n,o])=>({folder:n,...o})).sort((n,o)=>o.authored+o.contributed-(n.authored+n.contributed))}parseAuthorRef(t){return xe(t)}authorRefFor(t,e,i){let s=i.replace(/[^\w\- ]+/g,"").trim().replace(/\s+/g,"-")||"author",n=`${t.replace(/\/+$/,"")}/_authors/${s}-${e}.md`,o=i.replace(/[\[\]|]/g,"").trim()||s;return`[[${n}|${o}]]`}async ensureAuthorStubFor(t,e,i){if(!e||!i)return;this.authorRegistry.record({id:e,name:i});let s=`${t.replace(/\/+$/,"")}/_authors`;if(this.app.vault.getMarkdownFiles().some(c=>c.path.startsWith(s+"/")&&this.parseAuthorFilePath(c.path)?.id===e))return;let o=this.authorRegistry.get(e),a=this.authorNameToSafe(i),r=`${s}/${a}-${e}.md`;try{if(await this.ensureFolderPath(s),await this.app.vault.adapter.exists(r))return;await this.app.vault.create(r,this.buildAuthorStub({id:e,name:i,role:o?.role,department:o?.department},new Date().toISOString()))}catch(c){console.warn("[Stashpad] ensureAuthorStubFor failed",r,c)}}async rebuildAuthorRegistry(){let t=this.discoverStashpadFolders(),e=new Map,i=0;for(let n of this.app.vault.getMarkdownFiles()){let o=this.app.metadataCache.getFileCache(n)?.frontmatter;if(!o)continue;let a=[];if(typeof o.author=="string"&&a.push(o.author),Array.isArray(o.contributors))for(let r of o.contributors)typeof r=="string"&&a.push(r);for(let r of a){let c=this.parseAuthorRef(r);if(c)if(!e.has(c.id))e.set(c.id,{id:c.id,name:c.name,fromStub:!1}),i++;else{let l=e.get(c.id);!l.name&&c.name&&(l.name=c.name)}}}let s=0;for(let n of t){let o=`${n}/_authors`;for(let a of this.app.vault.getMarkdownFiles()){if(!a.path.startsWith(o+"/"))continue;let r=this.parseAuthorFilePath(a.path);if(!r)continue;let c=this.app.metadataCache.getFileCache(a)?.frontmatter,d=((Array.isArray(c?.aliases)?c.aliases.find(u=>typeof u=="string")??"":typeof c?.aliases=="string"?c.aliases:"")||(typeof c?.name=="string"?c.name:"")||r.name).trim(),I=typeof c?.role=="string"?c.role:void 0,g=typeof c?.department=="string"?c.department:void 0,p=e.get(r.id);p||s++,e.set(r.id,{id:r.id,name:d||p?.name,role:I??p?.role,department:g??p?.department,fromStub:!0})}}return await this.authorRegistry.load(),this.authorRegistry.replaceAll([...e.values()]),await this.authorRegistry.save(),{total:e.size,fromStubs:s,fromNotes:i}}buildAuthorStub(t,e){let i=a=>a.replace(/[\r\n]+/g," ").trim(),s=a=>i(a).replace(/\\/g,"\\\\").replace(/"/g,'\\"'),n=i(t.name),o=["---",`authorId: ${t.id}`,"aliases:",` - "${s(t.name)}"`];return t.role&&o.push(`role: "${s(t.role)}"`),t.department&&o.push(`department: "${s(t.department)}"`),o.push(`created: ${e}`,"---",`# ${n}`),o.join(` -`)}async restoreMissingAuthorStubs(){await this.authorRegistry.load();let t=this.authorRegistry.all().filter(n=>n.id&&n.name),e=this.discoverStashpadFolders(),i=this.app.vault.getMarkdownFiles(),s=0;for(let n of e){let o=`${n}/_authors`,a=new Set;for(let r of i){if(!r.path.startsWith(o+"/"))continue;let c=this.parseAuthorFilePath(r.path)?.id;c&&a.add(c)}for(let r of t){if(a.has(r.id))continue;let c=this.authorNameToSafe(r.name),l=`${o}/${c}-${r.id}.md`;try{if(await this.ensureFolderPath(o),await this.app.vault.adapter.exists(l))continue;await this.app.vault.create(l,this.buildAuthorStub(r,r.firstSeen??new Date().toISOString())),s++}catch(d){console.warn("[Stashpad] restore author stub failed",l,d)}}}return{created:s,folders:e.length}}async convertAttachmentsToLinks(){let t=0,e=i=>/^\[\[.*\]\]$/.test(i.trim());for(let i of this.discoverStashpadFolders()){let s=i.replace(/\/+$/,"");for(let n of this.app.vault.getMarkdownFiles()){let o=n.parent?.path?.replace(/\/+$/,"")??"";if(o!==s&&!o.startsWith(s+"/")||de(n.path))continue;let a=this.app.metadataCache.getFileCache(n)?.frontmatter;if(!(!a||typeof a.id!="string"||!a.id||!Array.isArray(a.attachments)||!a.attachments.some(c=>typeof c=="string"&&c.trim()&&!e(c))))try{await this.app.fileManager.processFrontMatter(n,c=>{Array.isArray(c.attachments)&&(c.attachments=c.attachments.map(l=>typeof l=="string"&&l.trim()?ie(l):l))}),t++}catch(c){console.warn("[Stashpad] attachment-link conversion failed",n.path,c)}}}return t}syncObsidianExcludedArchives(){try{let t=this.app.vault;if(typeof t.getConfig!="function"||typeof t.setConfig!="function")return;let e=Array.isArray(t.getConfig("userIgnoreFilters"))?t.getConfig("userIgnoreFilters"):[],i=new Set(e),s=!1;for(let n of this.discoverStashpadFolders()){let o=`${n.replace(/\/+$/,"")}/_archive/`;i.has(o)||(i.add(o),s=!0)}s&&t.setConfig("userIgnoreFilters",[...i])}catch(t){console.warn("[Stashpad] couldn't update Obsidian excluded files",t)}}openImportPicker(){let t=this.discoverStashpadFolders();if(t.length===0){new et.Notice("No Stashpad folders to import into.");return}if(t.length===1){this.importService.pickFilesInto(t[0]);return}let e=this.importService.defaultDestination()??t[0];new Ss(this.app,e,t,i=>this.importService.pickFilesInto(i)).open()}async runImportLooseFiles(t){let e=t.split("/").pop()||t,i=0,s=0,n=0;try{({files:i,folders:s,stashes:n}=await this.importService.importLooseInto(t))}catch(c){this.notifications.show({message:`Stashpad: import failed in \`${e}\` -Error: ${c.message}`,kind:"error",category:"import",folder:t}),console.error("[Stashpad] runImportLooseFiles failed",t,c);return}let o=i+s+n,a=this.lastActiveStashpadLeaf?.view;o>0&&a?.noteFolder===t&&a?.tree&&(a.tree.rebuild(t),a.render?.());let r;if(o===0)r=`Nothing to import in \`${e}\` \u2014 everything here is already a Stashpad note.`;else{let c=[];i&&c.push(`${i} loose file${i===1?"":"s"}`),s&&c.push(`${s} folder${s===1?"":"s"} (as nested notes)`),n&&c.push(`${n} .stash bundle${n===1?"":"s"}`),r=`Imported ${c.join(" + ")} in \`${e}\`.`}this.notifications.show({message:r,kind:o>0?"success":"info",category:"import",folder:t})}async runAutoImportSweep(){if(!this.settings.autoImport||!this.importService.isArmed()||this.autoSweepInProgress)return;this.autoSweepInProgress=!0;let t=0,e=0,i=0;try{for(let n of this.discoverStashpadFolders())try{let o=await this.importService.importLooseInto(n,{auto:!0});t+=o.files,e+=o.folders,i+=o.stashes}catch(o){console.warn("[Stashpad] auto-import sweep failed",n,o)}}finally{this.autoSweepInProgress=!1}if(t+e+i>0){let n=this.lastActiveStashpadLeaf?.view;n?.tree&&n?.noteFolder&&(n.tree.rebuild(n.noteFolder),n.render?.());let o=[];t&&o.push(`${t} file${t===1?"":"s"}`),e&&o.push(`${e} folder${e===1?"":"s"}`),i&&o.push(`${i} .stash bundle${i===1?"":"s"}`),this.notifications.show({message:`Auto-imported ${o.join(" + ")} (background sweep).`,kind:"success",category:"import"})}this.notifyPendingEncrypted()}notifyPendingEncrypted(){let t=this.importService.pendingEncryptedPaths();if(t.length===0||!this.importService.shouldNotifyEncrypted())return;this.importService.snoozeEncryptedNotify(60*60*1e3);let e=t.length;this.notifications.show({message:`${e} encrypted .stash bundle${e===1?"":"s"} waiting to import. Import ${e===1?"it":"them"} with the password?`,kind:"info",category:"import",duration:0,actions:[{label:"Import now",onClick:()=>void this.importPendingEncryptedNow()},{label:"Remind me later",onClick:()=>this.importService.snoozeEncryptedNotify(60*60*1e3)},{label:"Not now (until next launch)",onClick:()=>this.importService.snoozeEncryptedNotify(1/0)}]})}async importPendingEncryptedNow(){let{imported:t,rescheduled:e}=await this.importService.importPendingEncrypted();if(t>0){let i=this.lastActiveStashpadLeaf?.view;i?.tree&&i?.noteFolder&&(i.tree.rebuild(i.noteFolder),i.render?.()),this.notifications.show({message:`Imported ${t} encrypted .stash bundle${t===1?"":"s"}.`,kind:"success",category:"import"})}}async seedLocalAuthorStub(t){let e=(this.settings.authorId??"").trim(),i=(this.settings.authorName??"").trim();if(!e||!i)return!1;let s=`${t.replace(/\/+$/,"")}/_authors`;if(this.app.vault.getMarkdownFiles().some(r=>r.path.startsWith(s+"/")&&this.parseAuthorFilePath(r.path)?.id===e))return!1;let o=this.authorNameToSafe(i),a=`${s}/${o}-${e}.md`;try{return await this.ensureFolderPath(s),await this.app.vault.adapter.exists(a)?!1:(await this.app.vault.create(a,this.buildAuthorStub({id:e,name:i,role:this.settings.authorRole,department:this.settings.authorDepartment},new Date().toISOString())),this.authorRegistry.record({id:e,name:i,role:this.settings.authorRole,department:this.settings.authorDepartment}),!0)}catch(r){return console.warn("[Stashpad] seedLocalAuthorStub failed",a,r),!1}}async seedLocalAuthorStubsEverywhere(){if(!(this.settings.authorName??"").trim())return 0;let e=0;for(let i of this.discoverStashpadFolders())await this.seedLocalAuthorStub(i)&&e++;return e}async ensureFolderPath(t){let e=this.app.vault.adapter,i=t.split("/").filter(Boolean),s="";for(let n of i){s=s?`${s}/${n}`:n;try{await e.exists(s)||await e.mkdir(s)}catch(o){if(!/already exists/i.test(o.message))throw o}}}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={...Vt,...t,shortcuts:{...Vt.shortcuts,...t?.shortcuts??{}},mod:{...Vt.mod,...t?.mod??{}},bindings:na(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:oa(t?.drafts),lastSubmitted:t?.lastSubmitted&&typeof t.lastSubmitted=="object"?t.lastSubmitted:{},slugStopWords:Array.isArray(t?.slugStopWords)?t.slugStopWords:[...Gt]},As(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 i=await t.read(e),s=JSON.parse(i);Array.isArray(s)&&this.notifications.loadHistory(s)}}catch(i){console.warn("[Stashpad] failed to load notification history",i)}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(),i=e.replace(/\/[^/]+$/,""),s=this.app.vault.adapter;i&&!await s.exists(i)&&await s.mkdir(i),await s.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 i=this.readLastCursorFile()[t]??{};return new Map(Object.entries(i))}saveLastCursor(t,e,i){try{let s=this.readLastCursorFile();s[t]||(s[t]={}),s[t][e]=i,window.localStorage.setItem(this.LAST_CURSOR_LS_KEY,JSON.stringify(s))}catch(s){console.warn("[Stashpad] failed to save last-cursor",s)}}queueWrite(){let t=this.writeChain.then(()=>this.saveData(this.settings));return this.writeChain=t.catch(()=>{}),t}async saveSettings(){await this.queueWrite(),As(this.settings),vt.enabled=!!this.settings.enablePerfProfiling;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 et.Notice("No Stashpad folders found.");return}let e=new Set,i=this.app.vault.getMarkdownFiles();for(let d of i){let I=this.app.metadataCache.getFileCache(d)?.frontmatter,g=typeof I?.id=="string"?I.id.trim():"";g&&e.add(g)}let{newId:s}=await Promise.resolve().then(()=>(Tt(),ni)),n=()=>{for(let d=0;d<100;d++){let I=s();if(!e.has(I))return e.add(I),I}for(let d=8;d<=16;d+=2){let I=s(d);if(!e.has(I))return e.add(I),I}throw new Error("Could not generate a unique id")},o=[];for(let d of i){let I=d.parent?.path?.replace(/\/+$/,"")??"";if(!t.has(I))continue;let g=this.app.metadataCache.getFileCache(d)?.frontmatter,p=typeof g?.id=="string"?g.id.trim():"",u=g?.parent,f=typeof u=="string"?u.trim()!=="":u!=null,B=typeof g?.created=="string"&&g.created.trim()!=="",Q=!p,E=!f,y=!B;!Q&&!E&&!y||o.push({file:d,addId:Q,addParent:E,addCreated:y})}if(o.length===0){new et.Notice("Nothing to fix \u2014 every note in a Stashpad folder already has id + parent + created.");return}let a=0,r=0,c=this.newLog();for(let d of o)try{let I;await this.app.fileManager.processFrontMatter(d.file,u=>{if(d.addId&&(typeof u.id=="string"&&u.id.trim()||(I=n(),u.id=I)),d.addParent){let f=u.parent;(typeof f=="string"?f.trim()!=="":f!=null)||(u.parent=G)}d.addCreated&&(typeof u.created=="string"&&u.created.trim()||(u.created=new Date(d.file.stat.ctime).toISOString()))});let g=this.app.metadataCache.getFileCache(d.file)?.frontmatter,p=I??g?.id??"";p&&await c.append({type:"parent_change",id:p,payload:{from:null,to:G,reason:"orphan_fix",path:d.file.path,addedId:d.addId,addedParent:d.addParent,addedCreated:d.addCreated}}),a++}catch(I){console.warn("Stashpad: orphan fix failed for",d.file.path,I),r++}let l=r?` (${r} failed \u2014 see console)`:"";new et.Notice(`Fixed ${a} note${a===1?"":"s"} in Stashpad folders${l}.`)}async adoptNote(t){let{newId:e}=await Promise.resolve().then(()=>(Tt(),ni)),i=new Set;for(let c of this.app.vault.getMarkdownFiles()){if(c.path===t.path)continue;let l=this.app.metadataCache.getFileCache(c)?.frontmatter,d=typeof l?.id=="string"?l.id.trim():"";d&&i.add(d)}let s=()=>{for(let c=0;c<50;c++){let l=e();if(!i.has(l))return l}for(let c=8;c<=16;c+=2){let l=e(c);if(!i.has(l))return l}throw new Error("Could not generate a unique id")},n=[],o=[];try{await this.app.fileManager.processFrontMatter(t,c=>{let l=typeof c.id=="string"?c.id.trim():"";!l||/\s/.test(l)||i.has(l)?(c.id=s(),n.push("id")):o.push("id"),c.parent!==void 0&&c.parent!==null&&String(c.parent).trim()!==""?o.push("parent"):(c.parent=G,n.push("parent")),typeof c.created=="string"&&c.created.trim()!==""?o.push("created"):(c.created=new Date(t.stat.ctime).toISOString(),n.push("created"))})}catch(c){new et.Notice(`Adopt failed: ${c.message}`);return}let a=!1;try{let c=this.app.metadataCache.getFileCache(t)?.frontmatter,l=typeof c?.id=="string"?c.id.trim():"";if(l&&t.basename&&!t.basename.endsWith(`-${l}`)){let d=`${t.parent?t.parent.path+"/":""}${t.basename}-${l}.md`;await this.app.vault.adapter.exists(d)||(await this.app.fileManager.renameFile(t,d),a=!0)}}catch(c){console.warn("Stashpad: adopt rename failed",c)}if(n.length===0&&!a){new et.Notice(`Already a Stashpad note (${o.join(", ")} present).`);return}let r=[];n.length&&r.push(`added: ${n.join(", ")}`),a&&r.push("renamed with id"),new et.Notice(`Adopted into Stashpad \u2014 ${r.join("; ")}.`);try{let c=this.newLog(),l=this.app.metadataCache.getFileCache(t)?.frontmatter,d=l?.id??"";d&&await c.append({type:"create",id:d,payload:{path:t.path,parent:l?.parent??G,source:"adopt",added:n}})}catch{}}};function na(h,A,t){let e=rs();for(let i of Ve){let s=A&&typeof A[i.id]=="string"?A[i.id]:t&&typeof t[i.id]=="string"?t[i.id]:null;s!=null&&s!==""&&(e[i.id].primary=s)}if(h&&typeof h=="object")for(let i of Ve){let s=h[i.id];!s||typeof s!="object"||(e[i.id]={primary:typeof s.primary=="string"?s.primary:e[i.id].primary,secondary:typeof s.secondary=="string"?s.secondary:"",preferRight:!!s.preferRight,useBoth:!!s.useBoth})}return e}function oa(h){let A={};if(!h||typeof h!="object")return A;for(let[t,e]of Object.entries(h))if(typeof e=="string")A[t]=e;else if(e&&typeof e=="object"){for(let i of Object.values(e))if(typeof i=="string"&&i.length>0){A[t]=i;break}}return A}var Ss=class extends et.SuggestModal{constructor(t,e,i,s){super(t);this.def=e;this.folders=i;this.onPick=s;this.setPlaceholder("Choose a Stashpad folder to import into\u2026")}getSuggestions(t){let e=t.toLowerCase();return[this.def,...this.folders.filter(s=>s!==this.def)].filter(s=>s.toLowerCase().includes(e)).map(s=>({label:s,folder:s,current:s===this.def}))}renderSuggestion(t,e){e.createDiv({text:t.label}),t.current&&(e.createDiv({cls:"stashpad-suggest-note",text:"current"}),e.addClass("is-pinned-import-target"))}onChooseSuggestion(t){this.onPick(t.folder)}}; +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:Ei(this.app,t.path,et.Platform.isMobile)}),console.error(i)}}lookupNoteAuthorIds(t){let e=new Set,i=s=>{if(typeof s!="string")return null;let n=s.match(/-([a-z0-9]{4,12})(?:\.md)?(?:\||\]\])/i);return n?n[1]:null};for(let s of this.app.vault.getMarkdownFiles()){let n=this.app.metadataCache.getFileCache(s)?.frontmatter;if(n?.id!==t)continue;let o=i(n?.author);o&&e.add(o);let r=n?.contributors;if(Array.isArray(r))for(let a of r){let c=i(a);c&&e.add(c)}break}return Array.from(e)}lookupNoteAuthorId(t){return this.lookupNoteAuthorIds(t)[0]??null}async rebootstrapAllFolders(){this.rebootstrapInProgress=!0;try{return await this.rebootstrapAllFoldersInner()}finally{window.setTimeout(()=>{this.rebootstrapInProgress=!1},2500)}}async rebootstrapAllFoldersInner(){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 u=h.parent?.path;u&&e.add(u)}let i=(this.settings.importDropFolder||"").trim().replace(/^\/+|\/+$/g,""),s=(this.settings.exportFolder||"").trim().replace(/^\/+|\/+$/g,""),n=[],o=async h=>{if(h&&!await this.app.vault.adapter.exists(h))try{await this.app.vault.createFolder(h)}catch(I){let u=I?.message??"";if(!/already exists/i.test(u))throw I}},r=0,a=0,c=0,l=0;for(let h of e)try{if(i&&await o(`${h}/${i}`),s&&await o(`${h}/${s}`),this.settings.autoImport)try{let u=await this.importService.importLooseInto(h);l+=u.files+u.folders+u.stashes}catch(u){console.warn("Stashpad: loose sweep failed",h,u)}let I=await we(this.app,h);r+=I.checked,a+=I.written,c+=await this.rebootstrapFolderSlugs(h),n.push(h)}catch(I){console.warn(`Stashpad: rebootstrap skipped ${h}`,I)}let p=0;try{p=(await this.rebuildAuthorRegistry()).total}catch(h){console.warn("Stashpad: rebootstrap author-registry rebuild failed",h)}let g=0;try{g=await this.convertAttachmentsToLinks()}catch(h){console.warn("Stashpad: attachment-link conversion failed",h)}return{touched:n,fmChecked:r,fmWritten:a,slugsRenamed:c,authors:p,imported:l,attachmentsLinked:g}}async rebootstrapFolderSlugs(t){let e="__root__",i=t.replace(/\/+$/,""),s=this.settings.slugStopWords??Pt,n=0,o=this.app.vault.getMarkdownFiles().filter(r=>(r.parent?.path?.replace(/\/+$/,"")??"")===i);for(let r of o){let a=Ce(r.basename);if(!(!a||a===e||this.app.metadataCache.getFileCache(r)?.frontmatter?.id!==a))try{let l=await this.app.vault.cachedRead(r),p=l.startsWith("---")?l.slice(l.indexOf(` +---`,3)+4).replace(/^\r?\n/,""):l,g=Dt(p,s),h=bt(g,a);if(r.name===h)continue;let I=r.parent?`${r.parent.path}/${h}`:h;if(this.app.vault.getAbstractFileByPath(I))continue;await this.app.fileManager.renameFile(r,I),n+=1}catch(l){console.warn(`Stashpad: slug rebootstrap skipped ${r.path}`,l)}}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?.()!==gt)return null;let i=e.noteFolder??"";if(!i)return null;let s=e.currentChildren??[],n;if(typeof e.cursorIdx=="number"&&e.cursorIdx>=0&&(n=s[e.cursorIdx]),!n&&e.selection?.size>0){let o=e.firstSelectedId??[...e.selection][0];n=s.find(r=>r.id===o)}return n?.file?{folder:i,id:n.id,file:n.file}:null}fileForPin(t,e){let i=t.replace(/\/+$/,"");for(let s of this.app.vault.getMarkdownFiles())if((s.parent?.path?.replace(/\/+$/,"")??"")===i&&this.app.metadataCache.getFileCache(s)?.frontmatter?.id===e)return s;return null}async pinNote(t){let e=this.fileForPin(t.folder,t.id);e&&this.app.metadataCache.getFileCache(e)?.frontmatter?.pinned!==!0&&(await this.app.fileManager.processFrontMatter(e,i=>{i.pinned=!0,i.pinnedAt=Date.now()}),this.refreshPanelsView())}async unpinNote(t){let e=this.fileForPin(t.folder,t.id);e&&this.app.metadataCache.getFileCache(e)?.frontmatter?.pinned===!0&&(await this.app.fileManager.processFrontMatter(e,i=>{delete i.pinned,delete i.pinnedAt}),this.refreshPanelsView())}isPinned(t){let e=this.fileForPin(t.folder,t.id);return e?this.app.metadataCache.getFileCache(e)?.frontmatter?.pinned===!0:!1}listPinnedNotes(){let t=new Set(this.discoverStashpadFolders()),e=[];for(let i of this.app.vault.getMarkdownFiles()){let s=i.parent?.path?.replace(/\/+$/,"")??"";if(!t.has(s))continue;let n=this.app.metadataCache.getFileCache(i)?.frontmatter;if(!n||n.pinned!==!0||typeof n.id!="string"||!n.id)continue;let o=typeof n.pinnedAt=="number"?n.pinnedAt:0;e.push({folder:s,id:n.id,pinnedAt:o,file:i})}return e.sort((i,s)=>i.pinnedAt-s.pinnedAt||i.file.path.localeCompare(s.file.path)),e}async migratePinnedNotesToFrontmatter(){let t=this.settings.pinnedNotes??[];if(t.length===0)return;let e=Date.now()-t.length*1e3;for(let i of t){let s=this.fileForPin(i.folder,i.id);if(!s){e+=1e3;continue}try{if(this.app.metadataCache.getFileCache(s)?.frontmatter?.pinned!==!0){let n=e;await this.app.fileManager.processFrontMatter(s,o=>{o.pinned=!0,o.pinnedAt=n})}}catch(n){console.warn("[Stashpad] pin migration failed for",i,n)}e+=1e3}this.settings.pinnedNotes=[],await this.saveSettings(),this.refreshPanelsView()}refreshPanelsView(){let t=this.app.workspace.getLeavesOfType(Vt);for(let e of t){let i=e.view;i&&typeof i.render=="function"&&i.render()}}openFolderPicker(){let t=I=>{let f=I.getViewState().state?.folderOverride;return typeof f=="string"&&f.trim()?f.trim().replace(/^\/+|\/+$/g,""):(this.settings.folder||"Stashpad").trim().replace(/^\/+|\/+$/g,"")},e=this.app.workspace.getLeavesOfType(gt),i=this.discoverStashpadFolders(),s=qt(),n=s?(s.noteFolder??"").trim().replace(/^\/+|\/+$/g,""):"",o=new Set;for(let I of this.app.vault.getAllLoadedFiles())if(I.children){let u=I.path;u&&u!=="/"&&!u.startsWith(".")&&o.add(u)}let r=I=>{let u=I.split("/").filter(Boolean).pop()??"";return u?new Set([this.settings.importDropFolder,this.settings.exportFolder,"_attachments","_processed","_authors","_exports","_imports","_archive",".archive"].map(C=>(C??"").trim().replace(/^\/+|\/+$/g,"")).filter(Boolean)).has(u):!1},a=new Set,c=[],l=[],p=new Set;for(let I of e){let u=t(I);if(p.has(u))continue;p.add(u),a.add(u);let f=u.split("/").pop()||u;c.push({kind:"reveal",folder:u,label:`Reveal "${f}" tab`,leaf:I,icon:"layout-grid"}),l.push({kind:"open-anyway",folder:u,label:`Open "${f}" in another new tab`,icon:"layout-template"})}for(let I of i.filter(u=>!a.has(u))){let u=I.split("/").pop()||I;c.push({kind:"open",folder:I,label:`Open "${u}" in new tab`,icon:"layout-template"})}let g=this,h=new class extends et.SuggestModal{getSuggestions(I){let u=I.trim().toLowerCase(),f=u?u.split(/\s+/).filter(Boolean):[],C=w=>{if(!f.length)return!0;let v=w.toLowerCase();for(let D of f)if(!v.includes(D))return!1;return!0},m=u?c.filter(w=>{let v="folder"in w?w.folder:"";return C(w.label)||C(v)}):c.slice();if(u&&s&&n)for(let w of i){if(w.toLowerCase()===n.toLowerCase())continue;let v=w.split("/").pop()??w,D=`${w} ${v}`;C(D)&&m.push({kind:"switch-current",folder:w,label:`Switch this tab to "${v}"`,icon:"folder-input"})}let E=I.trim().replace(/^\/+|\/+$/g,"");if(E&&!r(E)){let w=Array.from(o).find(D=>D.toLowerCase()===E.toLowerCase()),v=i.some(D=>D.toLowerCase()===E.toLowerCase());if(w&&!v)m.push({kind:"convert",folder:w,label:`Convert \u201C${ti(w)}\u201D into a Stashpad\u2026`,icon:"folder-cog"});else if(!w){let D=ti(E);m.push({kind:"create",folder:E,label:`+ Create new Stashpad \u201C${D}\u201D`,icon:"folder-plus"})}}let y=l.filter(w=>C(w.label)||C(w.folder));return m.push(...y),m}renderSuggestion(I,u){u.addClass("stashpad-suggest-item"),u.addClass("stashpad-ribbon-suggest-item"),I.kind==="create"&&u.addClass("stashpad-suggest-create");let f=u.createSpan({cls:"stashpad-ribbon-suggest-icon"});(0,et.setIcon)(f,I.icon);let C=u.createDiv({cls:"stashpad-ribbon-suggest-body"});C.createDiv({cls:"stashpad-suggest-title",text:I.label}),"folder"in I&&I.folder&&I.label!==I.folder&&C.createDiv({cls:"stashpad-suggest-preview",text:I.folder})}async onChooseSuggestion(I){if(I.kind==="reveal"){g.app.workspace.revealLeaf(I.leaf);return}if(I.kind==="open"||I.kind==="open-anyway"){await g.activateViewForFolder(I.folder);return}if(I.kind==="switch-current"){let u=s;u&&typeof u.setFolderOverride=="function"&&(await u.setFolderOverride(I.folder),g.app.workspace.revealLeaf(u.leaf));return}if(I.kind==="create"){try{let u=ti(I.folder);await g.app.vault.adapter.exists(u)||await g.app.vault.createFolder(u),await g.activateViewForFolder(u)}catch(u){new et.Notice(`Stashpad: couldn't create folder (${u.message})`)}return}if(I.kind==="convert"){let{ConfirmModal:u}=await Promise.resolve().then(()=>(Mt(),ze)),f=I.folder,C=[`\u201C${f}\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 u(g.app,"Convert into a Stashpad?",C.join(` +`),"Convert",async m=>{if(m)try{await g.activateViewForFolder(f)}catch(E){new et.Notice(`Stashpad: couldn't convert folder (${E.message})`)}}).open();return}}}(this.app);h.setPlaceholder(s?"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=qt(),e=t?.folderOverride??null,i=t?.focusId??"__root__",s=!!t?.compactMode,n=this.app.workspace.openPopoutLeaf?.();if(!n){new et.Notice("Stashpad: couldn't open popout window on this build.");return}await n.setViewState({type:gt,active:!0,state:{folderOverride:e,focusId:i,tinyMode:!0,tinyAlwaysOnTop:!1,compactMode:s}});try{this.app.workspace.revealLeaf(n)}catch{}}async activateView(t={reveal:!0}){let{workspace:e}=this.app;if(t.reveal){let s=e.getLeavesOfType(gt);if(s.length>0){e.revealLeaf(s[0]);return}}let i=e.getLeaf("tab");await i.setViewState({type:gt,active:!0}),e.revealLeaf(i)}async activateViewForFolder(t){let e=(t||"").replace(/^\/+|\/+$/g,"");if(!e)return;let i=this.app.workspace.getLeaf("tab");await i.setViewState({type:gt,active:!0,state:{folderOverride:e}}),this.app.workspace.revealLeaf(i)}isStashpadNoteFile(t){let e=t.parent?.path?.replace(/\/+$/,"")??"";if(!this.discoverStashpadFolders().includes(e))return!1;let i=this.app.metadataCache.getFileCache(t)?.frontmatter?.id;return typeof i=="string"&&i.length>0}async revealNoteInStashpad(t){let e=t.parent?.path?.replace(/\/+$/,"")??"",i=this.app.metadataCache.getFileCache(t)?.frontmatter?.id;if(!e||typeof i!="string"||!i){new et.Notice("That note isn't a Stashpad note.");return}let s=this.app.workspace.getLeavesOfType(gt).find(n=>(n.view?.noteFolder??"")===e);if(s){this.app.workspace.revealLeaf(s);let n=s.view;typeof n?.navigateTo=="function"&&n.navigateTo(i);return}await this.activateViewForFolder(e),this.navigateWhenReady(e,i)}navigateWhenReady(t,e,i=15){let s=t.replace(/\/+$/,""),n=this.app.workspace.getLeavesOfType(gt).find(o=>(o.view?.noteFolder??"").replace(/\/+$/,"")===s)?.view??this.lastActiveStashpadLeaf?.view;if(n&&typeof n.navigateTo=="function"&&(!n.tree||typeof n.tree.get!="function"||!!n.tree.get(e))){n.navigateTo(e);return}i>0?window.setTimeout(()=>this.navigateWhenReady(t,e,i-1),90):n&&typeof n.navigateTo=="function"&&n.navigateTo(e)}collectAuthoredFolders(){let t=(this.settings.authorId??"").trim();if(!t)return[];let e=`-${t}`,i=this.discoverStashpadFolders(),s=new Map;for(let n of this.app.vault.getMarkdownFiles()){let o=this.app.metadataCache.getFileCache(n)?.frontmatter;if(!o)continue;let r=typeof o.author=="string"?o.author:"",a=Array.isArray(o.contributors)?o.contributors.filter(I=>typeof I=="string"):[],c=r.includes(e),l=a.some(I=>I.includes(e));if(!c&&!l)continue;let p=n.parent?.path??"",g=i.find(I=>p===I||p.startsWith(I+"/"));if(!g)continue;s.has(g)||s.set(g,{authored:0,contributed:0});let h=s.get(g);c&&h.authored++,l&&h.contributed++}return[...s.entries()].map(([n,o])=>({folder:n,...o})).sort((n,o)=>o.authored+o.contributed-(n.authored+n.contributed))}parseAuthorRef(t){return Xt(t)}authorRefFor(t,e,i){let s=i.replace(/[^\w\- ]+/g,"").trim().replace(/\s+/g,"-")||"author",n=`${t.replace(/\/+$/,"")}/_authors/${s}-${e}.md`,o=i.replace(/[\[\]|]/g,"").trim()||s;return`[[${n}|${o}]]`}async ensureAuthorStubFor(t,e,i){if(!e||!i)return;this.authorRegistry.record({id:e,name:i});let s=`${t.replace(/\/+$/,"")}/_authors`;if(this.app.vault.getMarkdownFiles().some(c=>c.path.startsWith(s+"/")&&this.parseAuthorFilePath(c.path)?.id===e))return;let o=this.authorRegistry.get(e),r=this.authorNameToSafe(i),a=`${s}/${r}-${e}.md`;try{if(await this.ensureFolderPath(s),await this.app.vault.adapter.exists(a))return;await this.app.vault.create(a,this.buildAuthorStub({id:e,name:i,role:o?.role,department:o?.department},new Date().toISOString()))}catch(c){console.warn("[Stashpad] ensureAuthorStubFor failed",a,c)}}async rebuildAuthorRegistry(){let t=this.discoverStashpadFolders(),e=new Map,i=0;for(let n of this.app.vault.getMarkdownFiles()){let o=this.app.metadataCache.getFileCache(n)?.frontmatter;if(!o)continue;let r=[];if(typeof o.author=="string"&&r.push(o.author),Array.isArray(o.contributors))for(let a of o.contributors)typeof a=="string"&&r.push(a);for(let a of r){let c=this.parseAuthorRef(a);if(c)if(!e.has(c.id))e.set(c.id,{id:c.id,name:c.name,fromStub:!1}),i++;else{let l=e.get(c.id);!l.name&&c.name&&(l.name=c.name)}}}let s=0;for(let n of t){let o=`${n}/_authors`;for(let r of this.app.vault.getMarkdownFiles()){if(!r.path.startsWith(o+"/"))continue;let a=this.parseAuthorFilePath(r.path);if(!a)continue;let c=this.app.metadataCache.getFileCache(r)?.frontmatter,p=((Array.isArray(c?.aliases)?c.aliases.find(u=>typeof u=="string")??"":typeof c?.aliases=="string"?c.aliases:"")||(typeof c?.name=="string"?c.name:"")||a.name).trim(),g=typeof c?.role=="string"?c.role:void 0,h=typeof c?.department=="string"?c.department:void 0,I=e.get(a.id);I||s++,e.set(a.id,{id:a.id,name:p||I?.name,role:g??I?.role,department:h??I?.department,fromStub:!0})}}return await this.authorRegistry.load(),this.authorRegistry.replaceAll([...e.values()]),await this.authorRegistry.save(),{total:e.size,fromStubs:s,fromNotes:i}}buildAuthorStub(t,e){let i=r=>r.replace(/[\r\n]+/g," ").trim(),s=r=>i(r).replace(/\\/g,"\\\\").replace(/"/g,'\\"'),n=i(t.name),o=["---",`authorId: ${t.id}`,"aliases:",` - "${s(t.name)}"`];return t.role&&o.push(`role: "${s(t.role)}"`),t.department&&o.push(`department: "${s(t.department)}"`),o.push(`created: ${e}`,"---",`# ${n}`),o.join(` +`)}async restoreMissingAuthorStubs(){await this.authorRegistry.load();let t=this.authorRegistry.all().filter(n=>n.id&&n.name),e=this.discoverStashpadFolders(),i=this.app.vault.getMarkdownFiles(),s=0;for(let n of e){let o=`${n}/_authors`,r=new Set;for(let a of i){if(!a.path.startsWith(o+"/"))continue;let c=this.parseAuthorFilePath(a.path)?.id;c&&r.add(c)}for(let a of t){if(r.has(a.id))continue;let c=this.authorNameToSafe(a.name),l=`${o}/${c}-${a.id}.md`;try{if(await this.ensureFolderPath(o),await this.app.vault.adapter.exists(l))continue;await this.app.vault.create(l,this.buildAuthorStub(a,a.firstSeen??new Date().toISOString())),s++}catch(p){console.warn("[Stashpad] restore author stub failed",l,p)}}}return{created:s,folders:e.length}}async convertAttachmentsToLinks(){let t=0,e=i=>/^\[\[.*\]\]$/.test(i.trim());for(let i of this.discoverStashpadFolders()){let s=i.replace(/\/+$/,"");for(let n of this.app.vault.getMarkdownFiles()){let o=n.parent?.path?.replace(/\/+$/,"")??"";if(o!==s&&!o.startsWith(s+"/")||Ie(n.path))continue;let r=this.app.metadataCache.getFileCache(n)?.frontmatter;if(!r||typeof r.id!="string"||!r.id)continue;let a=r.attachments,c=Array.isArray(a),l=typeof a=="string"&&a.trim().length>0;if(!(!c&&!l||!(l?!e(a):a.some(g=>typeof g=="string"&&g.trim()&&!e(g)))))try{await this.app.fileManager.processFrontMatter(n,g=>{Array.isArray(g.attachments)?g.attachments=g.attachments.map(h=>typeof h=="string"&&h.trim()?Gt(h):h):typeof g.attachments=="string"&&g.attachments.trim()&&(g.attachments=[Gt(g.attachments)])}),t++}catch(g){console.warn("[Stashpad] attachment-link conversion failed",n.path,g)}}}return t}syncObsidianExcludedArchives(){try{let t=this.app.vault;if(typeof t.getConfig!="function"||typeof t.setConfig!="function")return;let e=Array.isArray(t.getConfig("userIgnoreFilters"))?t.getConfig("userIgnoreFilters"):[],i=new Set(e),s=!1;for(let n of this.discoverStashpadFolders()){let o=`${n.replace(/\/+$/,"")}/_archive/`;i.has(o)||(i.add(o),s=!0)}s&&t.setConfig("userIgnoreFilters",[...i])}catch(t){console.warn("[Stashpad] couldn't update Obsidian excluded files",t)}}openImportPicker(){let t=this.discoverStashpadFolders();if(t.length===0){new et.Notice("No Stashpad folders to import into.");return}if(t.length===1){this.importService.pickFilesInto(t[0]);return}let e=this.importService.defaultDestination()??t[0];new Js(this.app,e,t,i=>this.importService.pickFilesInto(i)).open()}async runImportLooseFiles(t){let e=t.split("/").pop()||t,i=0,s=0,n=0;try{({files:i,folders:s,stashes:n}=await this.importService.importLooseInto(t))}catch(c){this.notifications.show({message:`Stashpad: import failed in \`${e}\` +Error: ${c.message}`,kind:"error",category:"import",folder:t}),console.error("[Stashpad] runImportLooseFiles failed",t,c);return}let o=i+s+n,r=this.lastActiveStashpadLeaf?.view;o>0&&r?.noteFolder===t&&r?.tree&&(r.tree.rebuild(t),r.render?.());let a;if(o===0)a=`Nothing to import in \`${e}\` \u2014 everything here is already a Stashpad note.`;else{let c=[];i&&c.push(`${i} loose file${i===1?"":"s"}`),s&&c.push(`${s} folder${s===1?"":"s"} (as nested notes)`),n&&c.push(`${n} .stash bundle${n===1?"":"s"}`),a=`Imported ${c.join(" + ")} in \`${e}\`.`}this.notifications.show({message:a,kind:o>0?"success":"info",category:"import",folder:t})}refreshViewIfShowing(t){let e=this.lastActiveStashpadLeaf?.view;e?.noteFolder===t&&e?.tree&&(e.tree.rebuild(t),e.render?.())}async runFolderSlugPass(t){let e=t.split("/").pop()||t,i=0;try{i=await this.rebootstrapFolderSlugs(t)}catch(s){this.notifications.show({message:`Stashpad: slug pass failed in \`${e}\` +${s.message}`,kind:"error",category:"system",folder:t}),console.error("[Stashpad] runFolderSlugPass failed",t,s);return}this.refreshViewIfShowing(t),this.notifications.show({message:i>0?`Renamed ${i} stale filename${i===1?"":"s"} in \`${e}\`.`:`No stale filenames in \`${e}\` \u2014 all slugs match their notes.`,kind:i>0?"success":"info",category:"system",folder:t})}async runFolderFrontmatterBackfill(t){let e=t.split("/").pop()||t,i=0,s=0;try{let n=await we(this.app,t);i=n.written,s=n.checked}catch(n){this.notifications.show({message:`Stashpad: frontmatter backfill failed in \`${e}\` +${n.message}`,kind:"error",category:"system",folder:t}),console.error("[Stashpad] runFolderFrontmatterBackfill failed",t,n);return}this.notifications.show({message:i>0?`Backfilled recovery links on ${i} note${i===1?"":"s"} in \`${e}\` (${s} checked).`:`Recovery links already up to date in \`${e}\` (${s} checked).`,kind:i>0?"success":"info",category:"system",folder:t})}async runAutoImportSweep(){if(!this.settings.autoImport||!this.importService.isArmed()||this.autoSweepInProgress)return;this.autoSweepInProgress=!0;let t=0,e=0,i=0;try{for(let n of this.discoverStashpadFolders())try{let o=await this.importService.importLooseInto(n,{auto:!0});t+=o.files,e+=o.folders,i+=o.stashes}catch(o){console.warn("[Stashpad] auto-import sweep failed",n,o)}}finally{this.autoSweepInProgress=!1}if(t+e+i>0){let n=this.lastActiveStashpadLeaf?.view;n?.tree&&n?.noteFolder&&(n.tree.rebuild(n.noteFolder),n.render?.());let o=[];t&&o.push(`${t} file${t===1?"":"s"}`),e&&o.push(`${e} folder${e===1?"":"s"}`),i&&o.push(`${i} .stash bundle${i===1?"":"s"}`),this.notifications.show({message:`Auto-imported ${o.join(" + ")} (background sweep).`,kind:"success",category:"import"})}this.notifyPendingEncrypted()}notifyPendingEncrypted(){let t=this.importService.pendingEncryptedPaths();if(t.length===0||!this.importService.shouldNotifyEncrypted())return;this.importService.snoozeEncryptedNotify(60*60*1e3);let e=t.length;this.notifications.show({message:`${e} encrypted .stash bundle${e===1?"":"s"} waiting to import. Import ${e===1?"it":"them"} with the password?`,kind:"info",category:"import",duration:0,actions:[{label:"Import now",onClick:()=>void this.importPendingEncryptedNow()},{label:"Remind me later",onClick:()=>this.importService.snoozeEncryptedNotify(60*60*1e3)},{label:"Not now (until next launch)",onClick:()=>this.importService.snoozeEncryptedNotify(1/0)}]})}async importPendingEncryptedNow(){let{imported:t,rescheduled:e}=await this.importService.importPendingEncrypted();if(t>0){let i=this.lastActiveStashpadLeaf?.view;i?.tree&&i?.noteFolder&&(i.tree.rebuild(i.noteFolder),i.render?.()),this.notifications.show({message:`Imported ${t} encrypted .stash bundle${t===1?"":"s"}.`,kind:"success",category:"import"})}}async seedLocalAuthorStub(t){let e=(this.settings.authorId??"").trim(),i=(this.settings.authorName??"").trim();if(!e||!i)return!1;let s=`${t.replace(/\/+$/,"")}/_authors`;if(this.app.vault.getMarkdownFiles().some(a=>a.path.startsWith(s+"/")&&this.parseAuthorFilePath(a.path)?.id===e))return!1;let o=this.authorNameToSafe(i),r=`${s}/${o}-${e}.md`;try{return await this.ensureFolderPath(s),await this.app.vault.adapter.exists(r)?!1:(await this.app.vault.create(r,this.buildAuthorStub({id:e,name:i,role:this.settings.authorRole,department:this.settings.authorDepartment},new Date().toISOString())),this.authorRegistry.record({id:e,name:i,role:this.settings.authorRole,department:this.settings.authorDepartment}),!0)}catch(a){return console.warn("[Stashpad] seedLocalAuthorStub failed",r,a),!1}}async seedLocalAuthorStubsEverywhere(){if(!(this.settings.authorName??"").trim())return 0;let e=0;for(let i of this.discoverStashpadFolders())await this.seedLocalAuthorStub(i)&&e++;return e}async ensureFolderPath(t){let e=this.app.vault.adapter,i=t.split("/").filter(Boolean),s="";for(let n of i){s=s?`${s}/${n}`:n;try{await e.exists(s)||await e.mkdir(s)}catch(o){if(!/already exists/i.test(o.message))throw o}}}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:ya(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:wa(t?.drafts),lastSubmitted:t?.lastSubmitted&&typeof t.lastSubmitted=="object"?t.lastSubmitted:{},slugStopWords:Array.isArray(t?.slugStopWords)?t.slugStopWords:[...Pt]},fs(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 i=await t.read(e),s=JSON.parse(i);Array.isArray(s)&&this.notifications.loadHistory(s)}}catch(i){console.warn("[Stashpad] failed to load notification history",i)}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(),i=e.replace(/\/[^/]+$/,""),s=this.app.vault.adapter;i&&!await s.exists(i)&&await s.mkdir(i),await s.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 i=this.readLastCursorFile()[t]??{};return new Map(Object.entries(i))}saveLastCursor(t,e,i){try{let s=this.readLastCursorFile();s[t]||(s[t]={}),s[t][e]=i,window.localStorage.setItem(this.LAST_CURSOR_LS_KEY,JSON.stringify(s))}catch(s){console.warn("[Stashpad] failed to save last-cursor",s)}}readLastSelectionFile(){try{let t=window.localStorage.getItem(this.LAST_SELECTION_LS_KEY);if(!t)return{};let e=JSON.parse(t);return e&&typeof e=="object"?e:{}}catch{return{}}}loadLastSelection(t){let i=this.readLastSelectionFile()[t]??{},s=new Map;for(let[n,o]of Object.entries(i))Array.isArray(o)&&s.set(n,o.filter(r=>typeof r=="string"));return s}saveLastSelection(t,e,i){try{let s=this.readLastSelectionFile();s[t]||(s[t]={}),i.length?s[t][e]=i:delete s[t][e],window.localStorage.setItem(this.LAST_SELECTION_LS_KEY,JSON.stringify(s))}catch(s){console.warn("[Stashpad] failed to save last-selection",s)}}queueWrite(){let t=this.writeChain.then(()=>this.saveData(this.settings));return this.writeChain=t.catch(()=>{}),t}async saveSettings(){await this.queueWrite(),fs(this.settings),St.enabled=!!this.settings.enablePerfProfiling;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 et.Notice("No Stashpad folders found.");return}let e=new Set,i=this.app.vault.getMarkdownFiles();for(let p of i){let g=this.app.metadataCache.getFileCache(p)?.frontmatter,h=typeof g?.id=="string"?g.id.trim():"";h&&e.add(h)}let{newId:s}=await Promise.resolve().then(()=>(Rt(),hi)),n=()=>{for(let p=0;p<100;p++){let g=s();if(!e.has(g))return e.add(g),g}for(let p=8;p<=16;p+=2){let g=s(p);if(!e.has(g))return e.add(g),g}throw new Error("Could not generate a unique id")},o=[];for(let p of i){let g=p.parent?.path?.replace(/\/+$/,"")??"";if(!t.has(g))continue;let h=this.app.metadataCache.getFileCache(p)?.frontmatter,I=typeof h?.id=="string"?h.id.trim():"",u=h?.parent,f=typeof u=="string"?u.trim()!=="":u!=null,C=typeof h?.created=="string"&&h.created.trim()!=="",m=!I,E=!f,y=!C;!m&&!E&&!y||o.push({file:p,addId:m,addParent:E,addCreated:y})}if(o.length===0){new et.Notice("Nothing to fix \u2014 every note in a Stashpad folder already has id + parent + created.");return}let r=0,a=0,c=this.newLog();for(let p of o)try{let g;await this.app.fileManager.processFrontMatter(p.file,u=>{if(p.addId&&(typeof u.id=="string"&&u.id.trim()||(g=n(),u.id=g)),p.addParent){let f=u.parent;(typeof f=="string"?f.trim()!=="":f!=null)||(u.parent=G)}p.addCreated&&(typeof u.created=="string"&&u.created.trim()||(u.created=new Date(p.file.stat.ctime).toISOString()))});let h=this.app.metadataCache.getFileCache(p.file)?.frontmatter,I=g??h?.id??"";I&&await c.append({type:"parent_change",id:I,payload:{from:null,to:G,reason:"orphan_fix",path:p.file.path,addedId:p.addId,addedParent:p.addParent,addedCreated:p.addCreated}}),r++}catch(g){console.warn("Stashpad: orphan fix failed for",p.file.path,g),a++}let l=a?` (${a} failed \u2014 see console)`:"";new et.Notice(`Fixed ${r} note${r===1?"":"s"} in Stashpad folders${l}.`)}async adoptNote(t){let{newId:e}=await Promise.resolve().then(()=>(Rt(),hi)),i=new Set;for(let c of this.app.vault.getMarkdownFiles()){if(c.path===t.path)continue;let l=this.app.metadataCache.getFileCache(c)?.frontmatter,p=typeof l?.id=="string"?l.id.trim():"";p&&i.add(p)}let s=()=>{for(let c=0;c<50;c++){let l=e();if(!i.has(l))return l}for(let c=8;c<=16;c+=2){let l=e(c);if(!i.has(l))return l}throw new Error("Could not generate a unique id")},n=[],o=[];try{await this.app.fileManager.processFrontMatter(t,c=>{let l=typeof c.id=="string"?c.id.trim():"";!l||/\s/.test(l)||i.has(l)?(c.id=s(),n.push("id")):o.push("id"),c.parent!==void 0&&c.parent!==null&&String(c.parent).trim()!==""?o.push("parent"):(c.parent=G,n.push("parent")),typeof c.created=="string"&&c.created.trim()!==""?o.push("created"):(c.created=new Date(t.stat.ctime).toISOString(),n.push("created"))})}catch(c){new et.Notice(`Adopt failed: ${c.message}`);return}let r=!1;try{let c=this.app.metadataCache.getFileCache(t)?.frontmatter,l=typeof c?.id=="string"?c.id.trim():"";if(l&&t.basename&&!t.basename.endsWith(`-${l}`)){let p=`${t.parent?t.parent.path+"/":""}${t.basename}-${l}.md`;await this.app.vault.adapter.exists(p)||(await this.app.fileManager.renameFile(t,p),r=!0)}}catch(c){console.warn("Stashpad: adopt rename failed",c)}if(n.length===0&&!r){new et.Notice(`Already a Stashpad note (${o.join(", ")} present).`);return}let a=[];n.length&&a.push(`added: ${n.join(", ")}`),r&&a.push("renamed with id"),new et.Notice(`Adopted into Stashpad \u2014 ${a.join("; ")}.`);try{let c=this.newLog(),l=this.app.metadataCache.getFileCache(t)?.frontmatter,p=l?.id??"";p&&await c.append({type:"create",id:p,payload:{path:t.path,parent:l?.parent??G,source:"adopt",added:n}})}catch{}}};function ya(d,A,t){let e=us();for(let i of $e){let s=A&&typeof A[i.id]=="string"?A[i.id]:t&&typeof t[i.id]=="string"?t[i.id]:null;s!=null&&s!==""&&(e[i.id].primary=s)}if(d&&typeof d=="object")for(let i of $e){let s=d[i.id];!s||typeof s!="object"||(e[i.id]={primary:typeof s.primary=="string"?s.primary:e[i.id].primary,secondary:typeof s.secondary=="string"?s.secondary:"",preferRight:!!s.preferRight,useBoth:!!s.useBoth})}return e}function wa(d){let A={};if(!d||typeof d!="object")return A;for(let[t,e]of Object.entries(d))if(typeof e=="string")A[t]=e;else if(e&&typeof e=="object"){for(let i of Object.values(e))if(typeof i=="string"&&i.length>0){A[t]=i;break}}return A}var Js=class extends et.SuggestModal{constructor(t,e,i,s){super(t);this.def=e;this.folders=i;this.onPick=s;this.setPlaceholder("Choose a Stashpad folder to import into\u2026")}getSuggestions(t){let e=t.toLowerCase();return[this.def,...this.folders.filter(s=>s!==this.def)].filter(s=>s.toLowerCase().includes(e)).map(s=>({label:s,folder:s,current:s===this.def}))}renderSuggestion(t,e){e.createDiv({text:t.label}),t.current&&(e.createDiv({cls:"stashpad-suggest-note",text:"current"}),e.addClass("is-pinned-import-target"))}onChooseSuggestion(t){this.onPick(t.folder)}}; /*! Bundled license information: jszip/dist/jszip.min.js: diff --git a/manifest.json b/manifest.json index 7e839b3..349a81b 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "stashpad", "name": "Stashpad", - "version": "0.84.17", + "version": "0.91.2", "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 43e2aac..7fa9202 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "stashpad-obsidian", - "version": "0.84.17", + "version": "0.91.2", "private": true, "scripts": { "dev": "node esbuild.config.mjs", diff --git a/release-notes/0.91.2.md b/release-notes/0.91.2.md new file mode 100644 index 0000000..aa06b7e --- /dev/null +++ b/release-notes/0.91.2.md @@ -0,0 +1,126 @@ +# 0.91.2 — Folder panel, Stashpad command palette, mobile + import polish + +## Folder panel (0.86) +A new left-sidebar `StashpadFolderPanelView` — a one-tap folder picker that +doubles as a pin shelf. + +- **Split layout:** pinned notes on top, Stashpad folders on the bottom. + Each list is independently scrollable, and the bottom half sits in + thumb-reach territory for mobile swipe-in. +- **Ribbon icon** opens it on mobile (and on desktop if you'd rather click + than chord). +- **Draggable divider** to resize the Pinned / Folders split; the ratio + persists. +- **Compact rows** with a folder badge + title; pins show their parent + blurb. +- **One-click pin open** from the panel. +- **Mobile UX:** tapping a row dismisses the sidebar; opening it doesn't + pop the composer keyboard. + +## Cross-device pin sync (0.86.3) +- Pinned notes used to live in per-device plugin data (`.stashpad/data.json`), + which Obsidian Sync doesn't carry — so pins appeared on desktop but not + mobile. The pin state now lives on the note itself (`pinned: true` + + `pinnedAt` epoch-ms order key in frontmatter), so it travels with the + note. + +## Stashpad command palette (0.90) +- New `StashpadCommandPalette` (default chord **`Mod+K`**) lists only this + plugin's commands — the redundant `Stashpad: ` prefix is stripped and + fuzzy-search is built in. Built from Obsidian's command registry so it + always stays in sync with the actual command list. + +## "More commands…" entry (0.87.0) +- Both the ⚡ (mobile actions) menu and the right-click context menu now + have a **More commands…** entry that opens Obsidian's full command + palette pre-filtered to Stashpad — the escape hatch to all ~90 + commands. + +## Mobile (0.87.1, 0.89.0) +- **One action button per row** (`⋮`) opens the note context menu, which + already carries Focus / Open in editor / everything. Replaces the two + per-row edit + focus buttons that crowded narrow screens. The completed + checkbox tucks into the meta row. +- *(Experimental)* On mobile with the keyboard up, `revealCursorRow` now + clamps the visible bottom to just above the composer, so a tapped note + stays visible instead of disappearing under the keyboard. + +## Search / picker polish (0.85.11–0.85.15) +- At ≥3 characters of query, a matching local home note is **pinned to + the top** of search/destination/move/in-parent picker results so folder + switches don't get buried. +- The local home note is now labeled **`Home — <folder>`** instead of just + `Home`, so it's matchable by folder name and stays consistent with the + cross-folder home entries. +- The "Open folder in a new tab…" shortcut is hidden once you start typing, + and kept on folder-name search at the bottom of the result list. + +## Tasks panel (0.88.1) +- New **Folder** dropdown filter, AND-combined with the existing Status + + Assignment filters. Lists the distinct folders that have tasks; resets + to "all" if the chosen folder drops out. +- **View menu** in any Stashpad gains an **Imported notes only** toggle + and a **By author** filter. + +## Imports retain authorship (0.88.0) +- Imports used to strip `author` / `contributors` (reserved keys), so the + new "by author" filter and "imported only" filter had no data to work + with. `importMarkdown` now retains the source's author and contributors, + and tags the note as imported. + +## Update reload (0.88.2, 0.88.3) +- The "a newer build synced in" notice's Reload button used to do a + plugin disable/enable, which often left the renderer on the old cached + `main.js`. It now runs Obsidian's **Reload app without saving** + (`app:reload`) with a `window.location.reload()` fallback. +- A one-shot localStorage flag bridges the reload, and the next load + un-ghosts every deferred Stashpad tab so they paint with the fresh code + immediately. + +## Export password UX (0.85.4–0.85.8) +- **Live strength meter** in the export modal — pool-size entropy + + repetition penalty + common-password floor. Nudge, never a gate. No new + dependency. +- **Generate strong passphrase** button — XKCD-style 5-word phrase with + separator + digit suffix. +- **Optional keychain remember** (device-local) with an explicit warning + that the remembered passphrase doesn't sync. +- **Word-phrase ceiling** so the meter doesn't mark a strong 5-word phrase + as "weak" because it lacks symbols. +- **Copy / Paste buttons per password field** — Paste when empty, Copy + when filled. +- **Export modal states the actual encryption suite** for this device + (Argon2id vs PBKDF2 fallback). + +## Cross-folder moves (0.86.5, 0.86.7) +- **Re-home stranded notes.** Moving a note's file across folders in + Obsidian's file explorer left its `parent` pointing at a note in the + *old* folder — a dangling parent that orphaned the note. The fix + re-homes any note whose `parent` is missing in the new folder. +- The move modal's cross-folder path now updates the recovery wikilink + fields (`parentLink` + the source / destination parents' `children` + lists) too. The intra-folder reparent already did. + +## Multi-selection survives reload (0.91.0–0.91.2) +- Multi-selection now persists across reload via localStorage (mirrors + last-cursor), so a deferred / lazy-loaded tab restores its selection + on first paint. +- The keymap Scope's Escape handler cancels the in-list picker instead of + immediately collapsing the multi-selection, then collapses on a second + Escape. +- Move toast no longer spams duplicates on cross-folder moves; new "moved + to <folder>" notice fires once per move. + +## Other fixes +- **Task toggle staleness on slow drives** (0.85.1) — new + `taskTaggedState` override mirrors `completedState`, so flipping H after + an FM round-trip no longer reverts the next render. +- **Per-folder rebootstrap-step commands** (0.85.2) — slug pass and + frontmatter backfill can each be run on a single folder. +- **Attachments link/plain format fight** (0.85.9) — `attachments` + frontmatter no longer flip-flops between `[[link]]` form (written by + `convertAttachmentsToLinks`) and plain paths (re-written by the body + sync). Both paths now compare canonical link form. +- **Composer → destination-picker focus** on mobile (0.85.10) — the + destination button no longer schedules blind refocus timers that yanked + the iOS keyboard back onto the composer after a pick. diff --git a/scripts/cdp.mjs b/scripts/cdp.mjs new file mode 100644 index 0000000..e5d91b2 --- /dev/null +++ b/scripts/cdp.mjs @@ -0,0 +1,37 @@ +// Minimal CDP driver for the running Obsidian. Node 18+ globals (fetch/WebSocket). +// Usage: node scripts/cdp.mjs '<js expression returning a JSON-serializable value>' +// The expression runs with `app` in scope (async IIFE; you may await). + +const expr = process.argv[2]; +if (!expr) { console.error("need an expression"); process.exit(1); } + +const targets = await (await fetch("http://localhost:9222/json")).json(); +const page = targets.find((t) => t.type === "page" && /obsidian\.md|app:\/\/obsidian/.test(t.url)) + || targets.find((t) => t.type === "page" && t.url !== "about:blank") + || targets[0]; +if (!page) { console.error("no page target"); process.exit(1); } + +const ws = new WebSocket(page.webSocketDebuggerUrl); +let id = 0; +const pending = new Map(); +const send = (method, params) => new Promise((res, rej) => { + const mid = ++id; + pending.set(mid, { res, rej }); + ws.send(JSON.stringify({ id: mid, method, params })); +}); + +await new Promise((res) => { ws.onopen = res; }); +ws.onmessage = (m) => { + const msg = JSON.parse(m.data); + if (msg.id && pending.has(msg.id)) { + const { res, rej } = pending.get(msg.id); + pending.delete(msg.id); + msg.error ? rej(new Error(JSON.stringify(msg.error))) : res(msg.result); + } +}; + +const wrapped = `(async () => { try { const __r = await (async () => { ${expr} })(); return JSON.stringify(__r); } catch (e) { return JSON.stringify({ __error: String(e && e.stack || e) }); } })()`; +const r = await send("Runtime.evaluate", { expression: wrapped, awaitPromise: true, returnByValue: true }); +console.log(r.result?.value ?? JSON.stringify(r)); +ws.close(); +process.exit(0); diff --git a/scripts/obs b/scripts/obs new file mode 100755 index 0000000..e064f8a --- /dev/null +++ b/scripts/obs @@ -0,0 +1,37 @@ +#!/bin/sh +# Obsidian CLI wrapper for the Stashpad test harness. +# +# The CLI shipped in Obsidian 1.12.4 (GA Feb 2026). It's a remote control for a +# RUNNING desktop instance (not headless) — if Obsidian isn't running, the first +# command launches it. Enable once via Settings → General → Command line +# interface → Register CLI (adds `obsidian` to PATH). This wrapper also works +# BEFORE that registration by falling back to the macOS app-bundle binary. +# +# Usage: +# scripts/obs <command> [k=v ...] # any Obsidian CLI command +# scripts/obs eval code='<js>' # run JS, returns the result (awaits promises) +# scripts/obs eval-file path/to/test.js # run a JS FILE's contents (no shell-escaping pain) +# scripts/obs plugin:reload id=stashpad # reload the dev plugin after a deploy +# scripts/obs dev:screenshot path=/tmp/x.png +# scripts/obs dev:console # captured console messages +# +# `eval` JS runs with `app` in scope. For UI-driving tests, dispatch synthetic +# events inside the code (e.g. el.dispatchEvent(new KeyboardEvent(...))) — same +# as the old cdp.mjs. Keep scripts/cdp.mjs as the fallback when the CLI is +# unavailable (older Obsidian) or when a persistent CDP session is needed. + +BIN="$(command -v obsidian 2>/dev/null)" +[ -n "$BIN" ] || BIN="/Applications/Obsidian.app/Contents/MacOS/obsidian-cli" +if [ ! -x "$BIN" ]; then + echo "Obsidian CLI not found. Need Obsidian 1.12.4+; enable via Settings → General → Register CLI." >&2 + exit 1 +fi + +if [ "$1" = "eval-file" ]; then + [ -n "$2" ] && [ -f "$2" ] || { echo "eval-file: missing/unreadable JS file: $2" >&2; exit 1; } + code="$(cat "$2")" + shift 2 + exec "$BIN" eval code="$code" "$@" +fi + +exec "$BIN" "$@" diff --git a/src/command-palette.ts b/src/command-palette.ts new file mode 100644 index 0000000..df5080c --- /dev/null +++ b/src/command-palette.ts @@ -0,0 +1,62 @@ +import { App, SuggestModal } from "obsidian"; +import { siftMatch } from "./types"; + +/** One entry in the Stashpad-only command palette: an Obsidian command id + * plus its display name (with the redundant "Stashpad: " prefix stripped). */ +interface PaletteCommand { + id: string; + name: string; +} + +/** 0.90.0: a Stashpad-only command palette (default Mod+K). Lists just this + * plugin's commands — built straight from Obsidian's command registry by + * filtering ids that start with `stashpad:` (Obsidian namespaces every plugin + * command as `<pluginId>:<commandId>`), so it auto-covers every command with + * zero id→method bookkeeping. Because every command is already a + * Stashpad one, the "Stashpad: " name prefix Obsidian prepends is dropped. + * + * Search uses Sift (all tokens, any order, case-insensitive substring) — the + * same matcher the note/folder pickers use — so it behaves like the rest of + * Stashpad's search surfaces. No filter chips (those are for note search, + * not commands). On pick we run the command by id via + * `commands.executeCommandById`, which resolves the right target the same way + * the native palette would. */ +export class StashpadCommandPalette extends SuggestModal<PaletteCommand> { + private commands: PaletteCommand[]; + + constructor(app: App) { + super(app); + this.setPlaceholder("Run a Stashpad command…"); + + const registry: Record<string, { name?: string }> = + (this.app as any).commands?.commands ?? {}; + this.commands = Object.keys(registry) + .filter((id) => id.startsWith("stashpad:")) + // Don't list the palette-opener inside its own palette. + .filter((id) => id !== "stashpad:stashpad-command-palette") + .map((id) => ({ id, name: stripStashpadPrefix(registry[id]?.name ?? id) })) + .sort((a, b) => a.name.localeCompare(b.name)); + } + + getSuggestions(query: string): PaletteCommand[] { + return this.commands.filter((c) => siftMatch(query, c.name)); + } + + renderSuggestion(cmd: PaletteCommand, el: HTMLElement): void { + el.createDiv({ text: cmd.name, cls: "stashpad-cmd-palette-name" }); + } + + onChooseSuggestion(cmd: PaletteCommand): void { + (this.app as any).commands?.executeCommandById?.(cmd.id); + } +} + +/** Strip the leading "Stashpad: " that Obsidian prepends to every plugin + * command's display name. The `+` collapses repeats — a couple of commands + * redundantly include "Stashpad:" in their own registered name, so Obsidian's + * auto-prefix doubles it ("Stashpad: Stashpad: …"); one pass would leave one + * behind. Case-insensitive, tolerant of extra spaces. Falls back to the + * original string if no prefix is present. */ +function stripStashpadPrefix(name: string): string { + return name.replace(/^(?:\s*Stashpad:\s*)+/i, "").trim() || name; +} diff --git a/src/commands/io-cmds.ts b/src/commands/io-cmds.ts index 3b3bf42..0d4e911 100644 --- a/src/commands/io-cmds.ts +++ b/src/commands/io-cmds.ts @@ -1,7 +1,8 @@ import { FuzzySuggestModal, Notice, TFile, moment } from "obsidian"; import { ROOT_ID, type StashpadId, type TreeNode } from "../types"; import { buildStashZip, importStashZip, STASH_EXT } from "../stash-package"; -import { encryptStash, resolveStashBytes, STASH_KDF_INFO } from "../stash-crypto"; +import { argon2Available, encryptStash, resolveStashBytes, STASH_KDF_INFO } from "../stash-crypto"; +import { secretIdForStashName } from "../passphrase"; import { ExportStashModal } from "../modals"; import type { StashpadView } from "../view"; @@ -27,14 +28,14 @@ export async function cmdExportStash(view: StashpadView, rootNode?: TreeNode): P ? view.titleForNode(roots[0]) : `${folderTag}-${roots.length}notes`; // 0.84.2: confirm name (+ later: optional encryption) in a modal first. - new ExportStashModal(view.app, defaultBase, all.length, (chosen, password) => { - void runExport(view, roots, all, chosen, password); - }).open(); + new ExportStashModal(view.app, defaultBase, all.length, (chosen, password, remember) => { + void runExport(view, roots, all, chosen, password, remember); + }, argon2Available).open(); } /** Build + write the .stash with the chosen base name, optionally encrypted, * then notify. */ -async function runExport(view: StashpadView, roots: TreeNode[], all: TreeNode[], baseName: string, password: string | null): Promise<void> { +async function runExport(view: StashpadView, roots: TreeNode[], all: TreeNode[], baseName: string, password: string | null, remember = false): Promise<void> { try { let buf = await buildStashZip(view.app, { rootNotes: roots.filter((n) => !!n.file).map((n) => ({ id: n.id, file: n.file! })), @@ -61,8 +62,18 @@ async function runExport(view: StashpadView, roots: TreeNode[], all: TreeNode[], const exportSub = (view.plugin.settings.exportFolder || "_exports").trim().replace(/^\/+|\/+$/g, ""); const exportFolder = `${view.noteFolder}/${exportSub}`; await view.ensureFolder(exportFolder); - const outPath = `${exportFolder}/${safe}-${stamp}.${STASH_EXT}`; + const outBase = `${safe}-${stamp}`; + const outPath = `${exportFolder}/${outBase}.${STASH_EXT}`; await view.app.vault.createBinary(outPath, buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength) as ArrayBuffer); + // 0.85.4: optionally remember the passphrase in this vault's secret storage + // (OS keychain), keyed deterministically by the filename so re-import on + // this device can look it up. Best-effort — a keychain failure must not + // fail the export (the file is already written + encrypted). + if (remember && password) { + const ss = (view.app as { secretStorage?: { setSecret(id: string, v: string): void } }).secretStorage; + try { ss?.setSecret(secretIdForStashName(outBase), password); } + catch (e) { console.warn("[Stashpad] couldn't save export passphrase to secret storage", e); } + } await view.log.append({ type: "stash_export", id: roots[0].id, @@ -135,7 +146,8 @@ export async function processStashFile(view: StashpadView, file: TFile): Promise try { const raw = new Uint8Array(await view.app.vault.readBinary(file)); // 0.84.3: if encrypted, prompt + decrypt before the unchanged import path. - const buf = await resolveStashBytes(view.app, raw); + // 0.85.4: try a passphrase remembered for this filename first (silent). + const buf = await resolveStashBytes(view.app, raw, { secretId: secretIdForStashName(file.basename) }); if (!buf) return; // user cancelled the password prompt — leave the file as-is const summary = await importStashZip(view.app, buf, view.noteFolder, collectExistingIds(view)); view.tree.rebuild(view.noteFolder); diff --git a/src/folder-panel-view.ts b/src/folder-panel-view.ts new file mode 100644 index 0000000..43622b9 --- /dev/null +++ b/src/folder-panel-view.ts @@ -0,0 +1,301 @@ +import { App, ItemView, Menu, Modal, Notice, Platform, TFile, TFolder, WorkspaceLeaf, setIcon } from "obsidian"; +import type StashpadPlugin from "./main"; +import { STASHPAD_FOLDER_PANEL_VIEW_TYPE, STASHPAD_VIEW_TYPE } from "./types"; +import { ConfirmModal } from "./modals"; + +/** 0.86.0: a left-sidebar folder picker, designed for mobile (swipe the left + * panel in, tap a folder to jump). Two stacked scrollable lists: pinned notes + * on top, Stashpad folders on the bottom (within thumb reach). Each folder row + * shows an "open" indicator, a reveal + open-in-new-tab button, and a + * right-click menu (open / reveal / rename / delete). Works on desktop too. */ +export class StashpadFolderPanelView extends ItemView { + constructor(leaf: WorkspaceLeaf, private plugin: StashpadPlugin) { + super(leaf); + } + + getViewType(): string { return STASHPAD_FOLDER_PANEL_VIEW_TYPE; } + getDisplayText(): string { return "Stashpad folders"; } + getIcon(): string { return "folders"; } + + async onOpen(): Promise<void> { + this.render(); + // Keep the "open" indicators + folder/pin lists fresh. + this.registerEvent(this.app.workspace.on("active-leaf-change", () => this.scheduleRender())); + this.registerEvent(this.app.workspace.on("layout-change", () => this.scheduleRender())); + this.registerEvent(this.app.vault.on("create", () => this.scheduleRender())); + this.registerEvent(this.app.vault.on("delete", () => this.scheduleRender())); + this.registerEvent(this.app.vault.on("rename", () => this.scheduleRender())); + this.registerEvent(this.app.metadataCache.on("changed", () => this.scheduleRender())); + } + + private renderTimer: number | null = null; + private scheduleRender(): void { + if (this.renderTimer != null) return; + this.renderTimer = window.setTimeout(() => { + this.renderTimer = null; + if (this.containerEl.isConnected) this.render(); + }, 100); + } + + private render(): void { + const root = this.contentEl; + root.empty(); + root.addClass("stashpad-folderpanel-root"); + + const frac = this.clampFrac(this.plugin.settings.folderPanelPinnedFraction ?? 0.5); + + // --- top: pinned notes (height = saved fraction; resized via the divider) --- + const pinnedSection = root.createDiv({ cls: "stashpad-folderpanel-section stashpad-folderpanel-pinned" }); + pinnedSection.style.flex = `0 0 ${(frac * 100).toFixed(2)}%`; + pinnedSection.createDiv({ cls: "stashpad-folderpanel-heading" }).setText("Pinned"); + this.renderPinned(pinnedSection.createDiv({ cls: "stashpad-folderpanel-list" })); + + // --- draggable divider --- + const divider = root.createDiv({ cls: "stashpad-folderpanel-divider" }); + divider.createDiv({ cls: "stashpad-folderpanel-divider-grip" }); + this.attachDividerDrag(root, pinnedSection, divider); + + // --- bottom: folders (takes the rest; kept low for thumb reach on mobile) --- + const folderSection = root.createDiv({ cls: "stashpad-folderpanel-section stashpad-folderpanel-folders" }); + folderSection.style.flex = "1 1 0"; + folderSection.createDiv({ cls: "stashpad-folderpanel-heading" }).setText("Folders"); + this.renderFolders(folderSection.createDiv({ cls: "stashpad-folderpanel-list" })); + } + + private clampFrac(f: number): number { + if (!Number.isFinite(f)) return 0.5; + return Math.max(0.15, Math.min(0.85, f)); + } + + /** Drag the divider to resize the Pinned/Folders split. Pointer events cover + * both mouse and touch; the fraction is persisted on release. */ + private attachDividerDrag(root: HTMLElement, pinnedSection: HTMLElement, divider: HTMLElement): void { + let pending: number | null = null; + const onMove = (ev: PointerEvent) => { + const rect = root.getBoundingClientRect(); + if (rect.height <= 0) return; + const f = this.clampFrac((ev.clientY - rect.top) / rect.height); + pending = f; + pinnedSection.style.flex = `0 0 ${(f * 100).toFixed(2)}%`; + }; + const onUp = (ev: PointerEvent) => { + document.removeEventListener("pointermove", onMove); + document.removeEventListener("pointerup", onUp); + document.body.removeClass("stashpad-folderpanel-resizing"); + try { divider.releasePointerCapture(ev.pointerId); } catch { /* noop */ } + if (pending != null) { + this.plugin.settings.folderPanelPinnedFraction = pending; + void this.plugin.saveSettings(); + } + }; + divider.addEventListener("pointerdown", (ev: PointerEvent) => { + ev.preventDefault(); + document.body.addClass("stashpad-folderpanel-resizing"); + try { divider.setPointerCapture(ev.pointerId); } catch { /* noop */ } + document.addEventListener("pointermove", onMove); + document.addEventListener("pointerup", onUp); + }); + } + + // ---------- pinned notes (top) ---------- + + private renderPinned(list: HTMLElement): void { + const pins = this.plugin.listPinnedNotes(); + if (pins.length === 0) { + list.createDiv({ cls: "stashpad-folderpanel-empty", text: "No pinned notes yet — pin a note from its right-click menu." }); + return; + } + for (const pin of pins) { + const file = pin.file; + const row = list.createEl("button", { cls: "stashpad-folderpanel-row stashpad-folderpanel-pin-row" }); + setIcon(row.createSpan({ cls: "stashpad-folderpanel-row-icon" }), "pin"); + row.createSpan({ cls: "stashpad-folderpanel-row-label", text: this.titleFromFile(file) }); + const folderName = pin.folder.split("/").pop() || pin.folder; + row.createSpan({ cls: "stashpad-folderpanel-row-sub", text: folderName }); + row.onclick = () => { this.onNavigateAway(); void this.plugin.revealNoteInStashpad(file); }; + } + } + + /** On mobile, jumping out of the panel should reveal the destination — collapse + * the left sidebar — WITHOUT the target view popping its composer keyboard. */ + private onNavigateAway(): void { + if (!Platform.isMobile) return; + this.plugin.suppressComposerAutofocusUntil = Date.now() + 1500; + this.app.workspace.leftSplit?.collapse?.(); + } + + private titleFromFile(file: TFile): string { + return file.basename.replace(/-[a-z0-9]{4,12}$/, "").replace(/-/g, " ").trim() || file.basename; + } + + // ---------- folders (bottom) ---------- + + /** Folder paths (trailing-slash-stripped) that currently have an open + * Stashpad tab. */ + private openFolders(): Set<string> { + const set = new Set<string>(); + for (const leaf of this.app.workspace.getLeavesOfType(STASHPAD_VIEW_TYPE)) { + const f = ((leaf.view as any)?.noteFolder ?? "").replace(/\/+$/, ""); + if (f) set.add(f); + } + return set; + } + + private renderFolders(list: HTMLElement): void { + const folders = this.plugin.discoverStashpadFolders(); + if (folders.length === 0) { + list.createDiv({ cls: "stashpad-folderpanel-empty", text: "No Stashpad folders yet." }); + return; + } + const open = this.openFolders(); + for (const folder of folders) { + const isOpen = open.has(folder.replace(/\/+$/, "")); + const row = list.createDiv({ cls: "stashpad-folderpanel-row stashpad-folderpanel-folder-row" }); + if (isOpen) row.addClass("is-open"); + + const dot = row.createSpan({ cls: "stashpad-folderpanel-dot" }); + dot.setAttr("aria-label", isOpen ? "Open in a tab" : "Not open"); + if (isOpen) dot.setAttr("title", "Open in a tab"); + + const name = folder.split("/").pop() || folder; + row.createSpan({ cls: "stashpad-folderpanel-row-label", text: name }); + + const actions = row.createDiv({ cls: "stashpad-folderpanel-actions" }); + const revealBtn = actions.createEl("button", { cls: "stashpad-folderpanel-iconbtn" }); + setIcon(revealBtn, "folder-search"); + revealBtn.setAttr("aria-label", "Reveal in file explorer"); + revealBtn.onclick = (e) => { e.stopPropagation(); this.revealFolder(folder); }; + + const newTabBtn = actions.createEl("button", { cls: "stashpad-folderpanel-iconbtn" }); + setIcon(newTabBtn, "plus-square"); + newTabBtn.setAttr("aria-label", "Open in new tab"); + newTabBtn.onclick = (e) => { e.stopPropagation(); this.onNavigateAway(); void this.plugin.activateViewForFolder(folder); }; + + // Tapping the row jumps to the folder (reusing an open tab if there is one). + row.onclick = () => { this.onNavigateAway(); this.jumpToFolder(folder); }; + row.oncontextmenu = (e) => { e.preventDefault(); this.openFolderMenu(e, folder); }; + } + } + + /** Reuse an existing Stashpad tab on this folder if present; else open one. */ + private jumpToFolder(folder: string): void { + const cleaned = folder.replace(/\/+$/, ""); + const existing = this.app.workspace.getLeavesOfType(STASHPAD_VIEW_TYPE) + .find((l) => (((l.view as any)?.noteFolder ?? "").replace(/\/+$/, "")) === cleaned); + if (existing) { this.app.workspace.revealLeaf(existing); return; } + void this.plugin.activateViewForFolder(folder); + } + + private revealFolder(folder: string): void { + const tf = this.app.vault.getAbstractFileByPath(folder.replace(/\/+$/, "")); + if (!(tf instanceof TFolder)) { new Notice("Couldn't find that folder."); return; } + const leaf = this.app.workspace.getLeavesOfType("file-explorer")[0]; + if (!leaf) { new Notice("File explorer isn't available."); return; } + this.app.workspace.revealLeaf(leaf); + (leaf.view as any)?.revealInFolder?.(tf); + } + + private openFolderMenu(e: MouseEvent, folder: string): void { + const menu = new Menu(); + // Order: non-destructive navigation first, then rename, then delete (isolated). + menu.addItem((i) => i.setTitle("Open in new tab").setIcon("plus-square") + .onClick(() => void this.plugin.activateViewForFolder(folder))); + menu.addItem((i) => i.setTitle("Reveal in file explorer").setIcon("folder-search") + .onClick(() => this.revealFolder(folder))); + menu.addSeparator(); + menu.addItem((i) => i.setTitle("Rename…").setIcon("pencil") + .onClick(() => this.renameFolder(folder))); + menu.addSeparator(); + menu.addItem((i) => { + i.setTitle("Delete folder…").setIcon("trash").onClick(() => this.deleteFolder(folder)); + (i as any).setWarning?.(true); + }); + menu.showAtMouseEvent(e); + } + + private renameFolder(folder: string): void { + const cleaned = folder.replace(/\/+$/, ""); + const tf = this.app.vault.getAbstractFileByPath(cleaned); + if (!(tf instanceof TFolder)) { new Notice("Couldn't find that folder."); return; } + const current = tf.name; + new RenameFolderModal(this.app, current, async (next) => { + const safe = next.trim().replace(/[\\/:]+/g, "").trim(); + if (!safe || safe === current) return; + const parent = tf.parent?.path && tf.parent.path !== "/" ? `${tf.parent.path}/` : ""; + const target = `${parent}${safe}`; + if (this.app.vault.getAbstractFileByPath(target)) { new Notice(`"${safe}" already exists.`); return; } + try { + await this.app.fileManager.renameFile(tf, target); + // Keep the configured default folder pointing at the renamed path. + if ((this.plugin.settings.folder || "").replace(/\/+$/, "") === cleaned) { + this.plugin.settings.folder = target; + await this.plugin.saveSettings(); + } + new Notice(`Renamed to "${safe}".`); + } catch (err) { + console.warn("[Stashpad] folder rename failed", err); + new Notice("Rename failed (see console)."); + } + }).open(); + } + + private deleteFolder(folder: string): void { + const cleaned = folder.replace(/\/+$/, ""); + const tf = this.app.vault.getAbstractFileByPath(cleaned); + if (!(tf instanceof TFolder)) { new Notice("Couldn't find that folder."); return; } + const noteCount = this.app.vault.getMarkdownFiles() + .filter((f) => (f.parent?.path?.replace(/\/+$/, "") ?? "") === cleaned + || (f.path.startsWith(cleaned + "/"))).length; + const name = tf.name; + new ConfirmModal( + this.app, + `Delete "${name}"?`, + `This moves the entire folder — about ${noteCount} note${noteCount === 1 ? "" : "s"} plus its attachments and exports — to the trash.\nYou can restore it from your system/Obsidian trash.`, + "Delete folder", + async (confirmed) => { + if (!confirmed) return; + try { + await this.app.fileManager.trashFile(tf); + new Notice(`Deleted "${name}".`); + } catch (err) { + console.warn("[Stashpad] folder delete failed", err); + new Notice("Delete failed (see console)."); + } + }, + ).open(); + } +} + +/** Tiny single-input modal for renaming a folder. */ +class RenameFolderModal extends Modal { + private delivered = false; + constructor(app: App, private current: string, private onSubmit: (next: string) => void) { + super(app); + } + onOpen(): void { + this.modalEl.addClass("stashpad-compact-modal"); + this.contentEl.empty(); + this.titleEl.setText("Rename folder"); + const input = this.contentEl.createEl("input", { type: "text" }) as HTMLInputElement; + input.addClass("stashpad-folderpanel-rename-input"); + input.value = this.current; + const footer = this.contentEl.createDiv({ cls: "stashpad-folderpanel-rename-footer" }); + footer.createEl("button", { text: "Cancel" }).onclick = () => this.close(); + const go = footer.createEl("button", { cls: "mod-cta", text: "Rename" }); + const submit = () => { this.delivered = true; const v = input.value; this.close(); this.onSubmit(v); }; + go.onclick = submit; + this.scope.register([], "Enter", (e) => { e.preventDefault(); if (input.value.trim()) submit(); }); + requestAnimationFrame(() => { input.focus(); input.select(); }); + } + onClose(): void { this.contentEl.empty(); } +} + +/** Open the folder panel in the LEFT sidebar (reuse if already open). */ +export async function openFolderPanelView(app: App): Promise<void> { + const existing = app.workspace.getLeavesOfType(STASHPAD_FOLDER_PANEL_VIEW_TYPE); + if (existing.length > 0) { app.workspace.revealLeaf(existing[0]); return; } + const leaf = app.workspace.getLeftLeaf(false); + if (!leaf) { new Notice("Stashpad: couldn't open the folder panel."); return; } + await leaf.setViewState({ type: STASHPAD_FOLDER_PANEL_VIEW_TYPE, active: true }); + app.workspace.revealLeaf(leaf); +} diff --git a/src/import-service.ts b/src/import-service.ts index 01905bc..63d0e75 100644 --- a/src/import-service.ts +++ b/src/import-service.ts @@ -5,6 +5,7 @@ import { newId } from "./id-service"; import { bodyToSlug, buildFilename } from "./slug-service"; import { splitFrontmatter, serializeNote, importStashZip, STASH_EXT } from "./stash-package"; import { resolveStashBytes, isEncryptedStash } from "./stash-crypto"; +import { secretIdForStashName } from "./passphrase"; import { ConfirmModal, ImportDupChoiceModal } from "./modals"; /** Reserved subfolders inside a Stashpad folder — never treated as drop @@ -306,6 +307,12 @@ export class ImportService { cloneFm.created = t.created; if (t.modified) cloneFm.modified = t.modified; cloneFm.attachments = Array.isArray(fm.attachments) ? fm.attachments : []; + // 0.88.0: RETAIN the source's authorship on import. `author`/`contributors` + // are normally reserved/stripped, but an imported note should keep WHO + // wrote it — the importer only becomes a contributor once they edit it. + if (fm.author !== undefined) cloneFm.author = fm.author; + if (fm.contributors !== undefined) cloneFm.contributors = fm.contributors; + cloneFm.imported = true; // mark as imported (the "imported only" view filter) const slug = bodyToSlug(body) || file.basename; const notePath = await this.uniquePath(folder, buildFilename(slug, cloneFm.id)); @@ -331,6 +338,7 @@ export class ImportService { created: new Date().toISOString(), // 0.79.18: attachments stored as internal links (not plain text). attachments: [toAttachmentLink(attachmentPath)], + imported: true, // 0.88.0: mark as imported (the "imported only" view filter) }; // 0.79.18: embed the attachment (! prefix) so it previews inline. const body = `${title}\n\n![[${attachmentPath}]]\n`; @@ -827,7 +835,8 @@ export class ImportService { this.pendingEncryptedStashes.add(file.path); // defer — surfaced by the sweep return false; } - const buf = await resolveStashBytes(this.app, rawBytes, promptOpts); // prompts if encrypted + // 0.85.4: try a passphrase remembered for this filename before prompting. + const buf = await resolveStashBytes(this.app, rawBytes, { ...promptOpts, secretId: secretIdForStashName(file.basename) }); if (!buf) return false; // cancelled / "remind me later" — leave the file const summary = await importStashZip(this.app, buf, root, existingIds); try { await this.app.fileManager.trashFile(file); } catch {} diff --git a/src/main.ts b/src/main.ts index 211a151..ed8e27b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,8 +1,9 @@ import { Notice, Platform, Plugin, SuggestModal, TFile, TFolder, WorkspaceLeaf, setIcon } from "obsidian"; -import { STASHPAD_DETAIL_VIEW_TYPE, STASHPAD_PANELS_VIEW_TYPE, STASHPAD_VIEW_TYPE, parseAuthorRef, toAttachmentLink, isInReservedSubfolder, type PinnedNoteRef, type StashpadId } from "./types"; +import { STASHPAD_DETAIL_VIEW_TYPE, STASHPAD_FOLDER_PANEL_VIEW_TYPE, STASHPAD_PANELS_VIEW_TYPE, STASHPAD_VIEW_TYPE, parseAuthorRef, toAttachmentLink, isInReservedSubfolder, type PinnedNoteRef, type StashpadId } from "./types"; import { StashpadDetailView, openStashpadDetailView } from "./detail-view"; import { StashpadView, properCaseFolderPath } from "./view"; import { StashpadPanelsView, openStashpadPanelsView, PANEL_REGISTRY, type PanelId } from "./panels-view"; +import { StashpadFolderPanelView, openFolderPanelView } from "./folder-panel-view"; import { DEFAULT_SETTINGS, StashpadSettings, StashpadSettingTab, setSettings, SETTINGS_TABS, buildDefaultBindings, COMMAND_META, type CommandBindingMap, type CommandId, @@ -22,6 +23,10 @@ import { ImportLog } from "./import-log"; import { perf } from "./perf"; import { RenderCacheStore } from "./render-cache-store"; +/** 0.89.1: localStorage key — set right before an update-triggered app reload so + * the next load knows to un-ghost the deferred Stashpad tabs. */ +const UNGHOST_FLAG = "stashpad:unghost-after-reload"; + export default class StashpadPlugin extends Plugin { settings: StashpadSettings = { ...DEFAULT_SETTINGS }; private undoStacks = new Map<string, UndoStack>(); @@ -34,6 +39,11 @@ export default class StashpadPlugin extends Plugin { * wikilink rewrites Obsidian does when slug-renames move files — never * bump `modified` (or add the local user as a contributor). */ rebootstrapInProgress = false; + /** 0.86.6: while `Date.now() < this`, a Stashpad view's activation + * auto-focus skips grabbing the composer. Set by the folder panel before it + * reveals/opens a leaf so tapping a pinned note on mobile doesn't pop the + * keyboard. */ + suppressComposerAutofocusUntil = 0; /** 0.73.10: keep a handle on the settings tab so command-palette * entries can pre-select a specific tab when opening Settings. */ settingTab: StashpadSettingTab | null = null; @@ -536,6 +546,12 @@ export default class StashpadPlugin extends Plugin { // is auto-cleared on unload. window.setTimeout(() => void this.runAutoImportSweep(), 5000); this.registerInterval(window.setInterval(() => void this.runAutoImportSweep(), 5 * 60 * 1000)); + // 0.86.3: migrate legacy per-device pinned list → note frontmatter (so + // pins sync). After the metadata cache has settled so fileForPin resolves. + window.setTimeout(() => void this.migratePinnedNotesToFrontmatter(), 3000); + // 0.89.1: if this load follows our update-reload, un-ghost the deferred + // Stashpad tabs so they render with the fresh code (no blank tabs/buttons). + window.setTimeout(() => void this.unghostStashpadTabsIfFlagged(), 1200); }); this.registerView( @@ -552,6 +568,10 @@ export default class StashpadPlugin extends Plugin { STASHPAD_PANELS_VIEW_TYPE, (leaf: WorkspaceLeaf) => new StashpadPanelsView(leaf, this), ); + this.registerView( + STASHPAD_FOLDER_PANEL_VIEW_TYPE, + (leaf: WorkspaceLeaf) => new StashpadFolderPanelView(leaf, this), + ); // 0.68.1: track the most-recently-active Stashpad leaf so the // sidebar panel's Search / Home buttons target the leaf the user // last worked in — not "leaves[0]" (= leftmost tab) which has @@ -720,6 +740,11 @@ export default class StashpadPlugin extends Plugin { this.addRibbonIcon("panel-left", "Open Stashpad panels (sidebar)", () => { void openStashpadPanelsView(this.app); }); + // 0.86.1: folder panel ribbon entry — the main way to open it on mobile + // (commands are buried; the other sidebar panels are reached via ribbon). + this.addRibbonIcon("folders", "Open Stashpad folder panel (sidebar)", () => { + void openFolderPanelView(this.app); + }); // 0.74.1: right-sidebar detail panel ribbon entry. this.addRibbonIcon("panel-right", "Open Stashpad detail panel (right sidebar)", () => { void openStashpadDetailView(this.app); @@ -757,6 +782,11 @@ export default class StashpadPlugin extends Plugin { name: "Toggle split-on-newlines", callback: () => call("toggleSplit"), }); + this.addCommand({ + id: "stashpad-command-palette", + name: "Command palette (Stashpad only)", + callback: () => call("openStashpadCommandPalette"), + }); // 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 @@ -913,6 +943,30 @@ export default class StashpadPlugin extends Plugin { return true; }, }); + // 0.85.2: per-step counterparts to rebootstrap, scoped to the current + // folder — so you can re-run just one repair pass without the heavy + // full-vault sweep. They call the SAME functions rebootstrap uses, so a + // fix in one place applies to both. + this.addCommand({ + id: "stashpad-rerun-slug-pass", + name: "Re-run filename (slug) pass on this folder", + checkCallback: (checking: boolean) => { + const folder = this.importService.defaultDestination(); + if (checking) return !!folder; + if (folder) void this.runFolderSlugPass(folder); + return true; + }, + }); + this.addCommand({ + id: "stashpad-rerun-frontmatter-backfill", + name: "Re-run frontmatter backfill (recovery links) on this folder", + checkCallback: (checking: boolean) => { + const folder = this.importService.defaultDestination(); + if (checking) return !!folder; + if (folder) void this.runFolderFrontmatterBackfill(folder); + return true; + }, + }); this.addCommand({ id: "stashpad-select-all", name: "Select all visible notes", callback: () => call("cmdSelectAll") }); this.addCommand({ id: "stashpad-copy-codeblock", name: "Copy code from codeblock", callback: () => call("cmdCopyCodeBlock") }); // 0.68.0: open the sidebar panels view (Pinned Notes + future panels). @@ -921,6 +975,12 @@ export default class StashpadPlugin extends Plugin { name: "Open Stashpad panels (sidebar)", callback: () => void openStashpadPanelsView(this.app), }); + // 0.86.0: open the left-sidebar folder picker (pinned notes + folders). + this.addCommand({ + id: "stashpad-open-folder-panel", + name: "Open folder panel (sidebar)", + callback: () => void openFolderPanelView(this.app), + }); // 0.74.1: open the right-sidebar detail panel. this.addCommand({ id: "stashpad-open-detail", @@ -1373,6 +1433,15 @@ export default class StashpadPlugin extends Plugin { this.registerEvent(this.app.vault.on("rename", (file) => { if (file instanceof TFile) { onMaybeOrphan(file); onMaybeMarkdownImport(file); } })); + // 0.86.5: when a note's FILE moves to a DIFFERENT folder (e.g. dragged in + // Obsidian's file explorer), its `parent` still points at a note in the OLD + // folder — a dangling parent that orphans it in the new one. The + // missing-parent orphan-fix above doesn't catch this (the parent value is + // present, just invalid here), so re-home such notes to Home. Gated on a + // real cross-folder move, so in-folder reparents/renames are untouched. + this.registerEvent(this.app.vault.on("rename", (file, oldPath) => { + if (file instanceof TFile) this.maybeReHomeOnCrossFolderMove(file, oldPath); + })); // 0.79.1: auto-import — any file appearing directly in a Stashpad // folder root (not a reserved subfolder, not an existing note) gets @@ -1411,8 +1480,10 @@ export default class StashpadPlugin extends Plugin { * 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. */ + * notice with a Reload action. 0.89.1: the action now runs the FULL app + * reload ("Reload app without saving") — plugin disable/enable often left + * the renderer on the cached old main.js, so the update "didn't take". + * Notifies once per detected on-disk version. */ private notifiedBuildVersion: string | null = null; private async checkForSyncedBuild(): Promise<void> { try { @@ -1433,21 +1504,13 @@ export default class StashpadPlugin extends Plugin { if (this.notifiedBuildVersion === onDisk) return; this.notifiedBuildVersion = onDisk; this.notifications.show({ - message: `A newer Stashpad build synced in (\`${loaded}\` → \`${onDisk}\`). Reload to apply.`, + message: `A newer Stashpad build synced in (\`${loaded}\` → \`${onDisk}\`). Reload the app to apply it.`, 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})`); - } - }, + label: "Reload app", + onClick: () => this.reloadAppForUpdate(), }], }); } catch (e) { @@ -1455,6 +1518,46 @@ export default class StashpadPlugin extends Plugin { } } + /** 0.89.1: full app reload ("Reload app without saving") — the reliable way to + * pick up a freshly-synced build. Plugin disable/enable often left the + * renderer on the cached old main.js, so the update wouldn't take. Falls back + * to a raw window reload if the command isn't available. */ + private reloadAppForUpdate(): void { + // 0.89.1: leave a one-shot flag so the NEXT load un-ghosts deferred Stashpad + // tabs. Obsidian defers inactive leaves on launch; after an update reload + // they'd otherwise sit as blank "ghost" tabs (and dead buttons) until tapped. + // (We can't activate them here — app:reload tears down this JS context.) + try { window.localStorage?.setItem(UNGHOST_FLAG, "1"); } catch { /* private mode */ } + try { + if ((this.app as any).commands?.executeCommandById?.("app:reload")) return; + } catch (e) { + console.warn("[Stashpad] app:reload command failed", e); + } + try { + window.location.reload(); + } catch { + new Notice("Reload Obsidian (close + reopen) to apply the Stashpad update."); + } + } + + /** 0.89.1: if the last reload was our update-reload, load every deferred + * Stashpad leaf so the tabs render with the fresh code instead of showing as + * blank ghosts. One-shot (clears the flag); only un-ghosts OUR view type. */ + private async unghostStashpadTabsIfFlagged(): Promise<void> { + let flagged = false; + try { flagged = window.localStorage?.getItem(UNGHOST_FLAG) === "1"; } catch { /* ignore */ } + if (!flagged) return; + try { window.localStorage?.removeItem(UNGHOST_FLAG); } catch { /* ignore */ } + for (const leaf of this.app.workspace.getLeavesOfType(STASHPAD_VIEW_TYPE)) { + try { + const l = leaf as any; + if (l.isDeferred && typeof l.loadIfDeferred === "function") await l.loadIfDeferred(); + } catch (e) { + console.warn("[Stashpad] un-ghost leaf 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 { @@ -1676,6 +1779,57 @@ export default class StashpadPlugin extends Plugin { } } + /** 0.86.5: paths with a pending re-home check (de-dupes burst rename events). */ + private reHomePending = new Set<string>(); + + /** A markdown note's file just moved. If it landed in a DIFFERENT Stashpad + * folder and its `parent` points at a note that isn't in the new folder, + * re-home it to ROOT after a debounce (lets the metadata cache settle and + * lets a Stashpad-initiated move stamp the correct parent first). */ + private maybeReHomeOnCrossFolderMove(file: TFile, oldPath: string): void { + if (file.extension !== "md") return; + const newDir = file.parent?.path?.replace(/\/+$/, "") ?? ""; + const slash = oldPath.lastIndexOf("/"); + const oldDir = (slash >= 0 ? oldPath.slice(0, slash) : "").replace(/\/+$/, ""); + if (newDir === oldDir) return; // not a cross-folder move + if (!this.discoverStashpadFolders().includes(newDir)) return; // not moved into a Stashpad + if (this.reHomePending.has(file.path)) return; + this.reHomePending.add(file.path); + setTimeout(() => { + this.reHomePending.delete(file.path); + void this.reHomeDanglingParent(file, newDir); + }, 900); + } + + /** Set `parent` to ROOT iff the note's current parent is a non-ROOT id with + * no matching note in `dir`. Conservative: a present, resolvable parent (and + * one Stashpad's own move already fixed) is left alone. */ + private async reHomeDanglingParent(file: TFile, dir: string): Promise<void> { + try { + const fm = this.app.metadataCache.getFileCache(file)?.frontmatter as + | { id?: unknown; parent?: unknown } | undefined; + const id = typeof fm?.id === "string" ? fm.id.trim() : ""; + const parent = typeof fm?.parent === "string" ? fm.parent.trim() : ""; + if (!id || !parent || parent === ROOT_ID) return; // no id / no or home parent + const parentInFolder = this.app.vault.getMarkdownFiles().some((f) => + (f.parent?.path?.replace(/\/+$/, "") ?? "") === dir + && this.app.metadataCache.getFileCache(f)?.frontmatter?.id === parent); + if (parentInFolder) return; // parent resolves here — fine + await this.app.fileManager.processFrontMatter(file, (m: any) => { + // re-check against disk truth (cache may have lagged) + const cur = typeof m.parent === "string" ? m.parent.trim() : ""; + if (cur && cur !== ROOT_ID) m.parent = ROOT_ID; + }); + await this.newLog().append({ + type: "parent_change", id, + payload: { from: parent, to: ROOT_ID, reason: "rehome_cross_folder_move", path: file.path }, + }); + new Notice(`Re-homed ${file.basename} → Home (its parent isn't in this folder)`); + } catch (e) { + console.warn("[Stashpad] re-home on cross-folder move failed", e); + } + } + private async autoImportStash(file: TFile, destFolder: string): Promise<void> { try { const raw = new Uint8Array(await this.app.vault.readBinary(file)); @@ -1984,27 +2138,91 @@ export default class StashpadPlugin extends Plugin { return { folder, id: node.id, file: node.file }; } - /** Pin a note to the sidebar panels' Pinned Notes list. Idempotent. */ + /** 0.86.3: pin state lives in the NOTE'S frontmatter (`pinned: true` + + * `pinnedAt` epoch-ms order key) so it syncs with the note across devices, + * rather than in per-device plugin data. */ + fileForPin(folder: string, id: string): TFile | null { + const dir = folder.replace(/\/+$/, ""); + for (const f of this.app.vault.getMarkdownFiles()) { + if ((f.parent?.path?.replace(/\/+$/, "") ?? "") !== dir) continue; + if (this.app.metadataCache.getFileCache(f)?.frontmatter?.id === id) return f; + } + return null; + } + + /** Pin a note. Idempotent — writes `pinned: true` + `pinnedAt` to its FM. */ async pinNote(pin: PinnedNoteRef): Promise<void> { - const list = this.settings.pinnedNotes ?? []; - if (list.some((p) => p.folder === pin.folder && p.id === pin.id)) return; - this.settings.pinnedNotes = [...list, pin]; - await this.saveSettings(); + const file = this.fileForPin(pin.folder, pin.id); + if (!file) return; + if (this.app.metadataCache.getFileCache(file)?.frontmatter?.pinned === true) return; + await this.app.fileManager.processFrontMatter(file, (fm: any) => { + fm.pinned = true; + fm.pinnedAt = Date.now(); + }); this.refreshPanelsView(); } - /** Remove a pin. Idempotent. */ + /** Remove a pin (clears the frontmatter keys). Idempotent. */ async unpinNote(pin: PinnedNoteRef): Promise<void> { - const list = this.settings.pinnedNotes ?? []; - const next = list.filter((p) => !(p.folder === pin.folder && p.id === pin.id)); - if (next.length === list.length) return; - this.settings.pinnedNotes = next; - await this.saveSettings(); + const file = this.fileForPin(pin.folder, pin.id); + if (!file) return; + if (this.app.metadataCache.getFileCache(file)?.frontmatter?.pinned !== true) return; + await this.app.fileManager.processFrontMatter(file, (fm: any) => { + delete fm.pinned; + delete fm.pinnedAt; + }); this.refreshPanelsView(); } isPinned(pin: PinnedNoteRef): boolean { - return (this.settings.pinnedNotes ?? []).some((p) => p.folder === pin.folder && p.id === pin.id); + const file = this.fileForPin(pin.folder, pin.id); + if (!file) return false; + return this.app.metadataCache.getFileCache(file)?.frontmatter?.pinned === true; + } + + /** All pinned notes across discovered Stashpad folders, ordered by `pinnedAt` + * (then path for stability). One metadata-cache scan — backs both the panels + * Pinned section and the folder panel. */ + listPinnedNotes(): Array<{ folder: string; id: string; pinnedAt: number; file: TFile }> { + const folders = new Set(this.discoverStashpadFolders()); + const out: Array<{ folder: string; id: string; pinnedAt: number; file: TFile }> = []; + for (const f of this.app.vault.getMarkdownFiles()) { + const dir = f.parent?.path?.replace(/\/+$/, "") ?? ""; + if (!folders.has(dir)) continue; + const fm = this.app.metadataCache.getFileCache(f)?.frontmatter as any; + if (!fm || fm.pinned !== true || typeof fm.id !== "string" || !fm.id) continue; + const at = typeof fm.pinnedAt === "number" ? fm.pinnedAt : 0; + out.push({ folder: dir, id: fm.id, pinnedAt: at, file: f }); + } + out.sort((a, b) => a.pinnedAt - b.pinnedAt || a.file.path.localeCompare(b.file.path)); + return out; + } + + /** 0.86.3: one-time migration — convert the old per-device + * `settings.pinnedNotes` list into `pinned`/`pinnedAt` frontmatter so pins + * sync. Runs after layout-ready (metadata cache settled); clears the setting + * when done so it never re-runs. */ + private async migratePinnedNotesToFrontmatter(): Promise<void> { + const list = this.settings.pinnedNotes ?? []; + if (list.length === 0) return; + let stamp = Date.now() - list.length * 1000; // preserve order via increasing ts + for (const pin of list) { + const file = this.fileForPin(pin.folder, pin.id); + if (!file) { stamp += 1000; continue; } + try { + if (this.app.metadataCache.getFileCache(file)?.frontmatter?.pinned !== true) { + const at = stamp; + await this.app.fileManager.processFrontMatter(file, (fm: any) => { + fm.pinned = true; + fm.pinnedAt = at; + }); + } + } catch (e) { console.warn("[Stashpad] pin migration failed for", pin, e); } + stamp += 1000; + } + this.settings.pinnedNotes = []; + await this.saveSettings(); + this.refreshPanelsView(); } /** Force any open panels view to re-render — used after pin/unpin. */ @@ -2353,8 +2571,28 @@ export default class StashpadPlugin extends Plugin { return; } await this.activateViewForFolder(folder); - const view = this.lastActiveStashpadLeaf?.view as any; - if (typeof view?.navigateTo === "function") view.navigateTo(id); + // 0.86.4: the freshly-opened view may still be loading its tree — navigate + // once it's actually ready, so a pinned note opens in ONE click instead of + // landing on Home (the first click) and only navigating on the second. + this.navigateWhenReady(folder, id); + } + + /** Poll briefly for the folder's Stashpad view to have `id` in its tree, then + * navigate. One-click open for a not-yet-open folder. */ + private navigateWhenReady(folder: string, id: string, attempts = 15): void { + const clean = folder.replace(/\/+$/, ""); + const view = (this.app.workspace.getLeavesOfType(STASHPAD_VIEW_TYPE) + .find((l) => (((l.view as any)?.noteFolder ?? "").replace(/\/+$/, "")) === clean)?.view + ?? this.lastActiveStashpadLeaf?.view) as any; + if (view && typeof view.navigateTo === "function") { + const treeReady = !view.tree || typeof view.tree.get !== "function" || !!view.tree.get(id); + if (treeReady) { view.navigateTo(id); return; } + } + if (attempts > 0) { + window.setTimeout(() => this.navigateWhenReady(folder, id, attempts - 1), 90); + } else if (view && typeof view.navigateTo === "function") { + view.navigateTo(id); // last resort — navigate anyway + } } /** Walk vault markdown frontmatter for notes whose author or @@ -2575,13 +2813,22 @@ export default class StashpadPlugin extends Plugin { if (isInReservedSubfolder(f.path)) continue; // skip _archive/_attachments/… const fm = this.app.metadataCache.getFileCache(f)?.frontmatter as any; if (!fm || typeof fm.id !== "string" || !fm.id) continue; - if (!Array.isArray(fm.attachments)) continue; - const needs = fm.attachments.some((a: any) => typeof a === "string" && a.trim() && !isLink(a)); + const att: any = fm.attachments; + const isArr = Array.isArray(att); + const isScalar = typeof att === "string" && att.trim().length > 0; + if (!isArr && !isScalar) continue; + // 0.85.9: also handle a SCALAR `attachments:` (hand-edited / odd import) + // — normalize it to a one-item list of the canonical link form. + const needs = isScalar + ? !isLink(att as string) + : (att as any[]).some((a: any) => typeof a === "string" && a.trim() && !isLink(a)); if (!needs) continue; try { await this.app.fileManager.processFrontMatter(f, (m: any) => { if (Array.isArray(m.attachments)) { m.attachments = m.attachments.map((a: any) => (typeof a === "string" && a.trim()) ? toAttachmentLink(a) : a); + } else if (typeof m.attachments === "string" && m.attachments.trim()) { + m.attachments = [toAttachmentLink(m.attachments)]; } }); converted++; @@ -2677,6 +2924,53 @@ export default class StashpadPlugin extends Plugin { }); } + /** Refresh the active view if it's looking at `folder` (so per-step repairs + * show immediately, like the loose-import command does). */ + private refreshViewIfShowing(folder: string): void { + const view = this.lastActiveStashpadLeaf?.view as any; + if (view?.noteFolder === folder && view?.tree) { view.tree.rebuild(folder); view.render?.(); } + } + + /** 0.85.2: re-run just the filename/slug pass on one folder — the same + * `rebootstrapFolderSlugs` rebootstrap uses, without the full-vault sweep. */ + async runFolderSlugPass(folder: string): Promise<void> { + const label = folder.split("/").pop() || folder; + let n = 0; + try { n = await this.rebootstrapFolderSlugs(folder); } + catch (e) { + this.notifications.show({ message: `Stashpad: slug pass failed in \`${label}\`\n${(e as Error).message}`, kind: "error", category: "system", folder }); + console.error("[Stashpad] runFolderSlugPass failed", folder, e); + return; + } + this.refreshViewIfShowing(folder); + this.notifications.show({ + message: n > 0 + ? `Renamed ${n} stale filename${n === 1 ? "" : "s"} in \`${label}\`.` + : `No stale filenames in \`${label}\` — all slugs match their notes.`, + kind: n > 0 ? "success" : "info", category: "system", folder, + }); + } + + /** 0.85.2: re-run just the frontmatter backfill (redundant `parentLink` / + * `children` recovery links) on one folder — the same + * `rebootstrapFolderFrontmatter` rebootstrap uses. */ + async runFolderFrontmatterBackfill(folder: string): Promise<void> { + const label = folder.split("/").pop() || folder; + let written = 0, checked = 0; + try { const s = await rebootstrapFolderFrontmatter(this.app, folder); written = s.written; checked = s.checked; } + catch (e) { + this.notifications.show({ message: `Stashpad: frontmatter backfill failed in \`${label}\`\n${(e as Error).message}`, kind: "error", category: "system", folder }); + console.error("[Stashpad] runFolderFrontmatterBackfill failed", folder, e); + return; + } + this.notifications.show({ + message: written > 0 + ? `Backfilled recovery links on ${written} note${written === 1 ? "" : "s"} in \`${label}\` (${checked} checked).` + : `Recovery links already up to date in \`${label}\` (${checked} checked).`, + kind: written > 0 ? "success" : "info", category: "system", folder, + }); + } + private autoSweepInProgress = false; /** 0.84.11: retroactive auto-import. Periodically (and once at startup) sweep * EVERY Stashpad folder for non-imported loose content — the "watcher @@ -2991,6 +3285,47 @@ export default class StashpadPlugin extends Plugin { } } + // 0.91.0: last MULTI-SELECTION per (folder, focus), persisted to + // localStorage. Mirrors the last-cursor store above. Lives in localStorage + // rather than view state because (a) it must survive even when the tab is + // lazy-loaded/deferred on reload, and (b) selection changes don't trigger a + // workspace-layout save, so getState() would capture stale state. Stamped on + // beforeunload/blur/onClose (eager), read back on view load. + private readonly LAST_SELECTION_LS_KEY = "stashpad:last-selection"; + private readLastSelectionFile(): Record<string, Record<string, string[]>> { + try { + const raw = window.localStorage.getItem(this.LAST_SELECTION_LS_KEY); + if (!raw) return {}; + const parsed = JSON.parse(raw); + return parsed && typeof parsed === "object" ? parsed as Record<string, Record<string, string[]>> : {}; + } catch { + return {}; + } + } + /** Map of <focusId> → <selected note ids> for the given folder. */ + loadLastSelection(folder: string): Map<string, string[]> { + const all = this.readLastSelectionFile(); + const slice = all[folder] ?? {}; + const out = new Map<string, string[]>(); + for (const [focusId, ids] of Object.entries(slice)) { + if (Array.isArray(ids)) out.set(focusId, ids.filter((x): x is string => typeof x === "string")); + } + return out; + } + /** Synchronously persist the selection for one (folder, focus). An empty + * array clears it (so deselect-then-reload doesn't resurrect stale ids). */ + saveLastSelection(folder: string, focusId: string, ids: string[]): void { + try { + const all = this.readLastSelectionFile(); + if (!all[folder]) all[folder] = {}; + if (ids.length) all[folder][focusId] = ids; + else delete all[folder][focusId]; + window.localStorage.setItem(this.LAST_SELECTION_LS_KEY, JSON.stringify(all)); + } catch (e) { + console.warn("[Stashpad] failed to save last-selection", e); + } + } + /** Serializes ALL settings writes so a fast draft-write can't race with * a settings-tab edit and clobber a freshly-changed shortcut. Both * saveSettings() and persistSettingsQuiet() funnel through here. */ diff --git a/src/modals.ts b/src/modals.ts index 0c01c06..c2bc9ba 100644 --- a/src/modals.ts +++ b/src/modals.ts @@ -1,6 +1,7 @@ -import { App, Modal, Platform, moment, Notice, setIcon } from "obsidian"; +import { App, Modal, Platform, moment, Notice, setIcon, type SecretStorage } from "obsidian"; import { buildTimePickerInto } from "./time-picker"; import { siftMatch } from "./types"; +import { generatePassphrase, estimatePasswordStrength } from "./passphrase"; import { newId } from "./id-service"; import type { ImportLogEntry } from "./import-log"; @@ -552,7 +553,11 @@ export class ExportStashModal extends Modal { app: App, private defaultBaseName: string, private noteCount: number, - private onConfirm: (baseName: string, password: string | null) => void, + private onConfirm: (baseName: string, password: string | null, remember: boolean) => void, + /** Probe (cached) for whether Argon2id can run here, so the modal can state + * up front whether this export will use the strong suite or the fallback. + * Optional so callers/tests can omit it (the text just stays generic). */ + private kdfProbe?: () => Promise<boolean>, ) { super(app); } @@ -586,17 +591,103 @@ export class ExportStashModal extends Modal { const pwArea = encWrap.createDiv({ cls: "stashpad-export-pw-area" }); pwArea.style.display = "none"; - const pw1 = pwArea.createEl("input", { type: "password" }) as HTMLInputElement; - pw1.addClass("stashpad-export-name"); pw1.placeholder = "Password"; - const pw2 = pwArea.createEl("input", { type: "password" }) as HTMLInputElement; - pw2.addClass("stashpad-export-name"); pw2.placeholder = "Confirm password"; + // 0.85.7: each field gets an inline button on its right; the passphrase + // stays hidden by default (Show reveals it). 0.85.8: the button is + // **Paste** while the field is empty (one-click drop-in from a password + // manager) and flips to **Copy** once it has a value — clearing the field + // flips it back. Copy works while masked. + const pwSyncers: Array<() => void> = []; + const makePwRow = (placeholder: string): HTMLInputElement => { + const row = pwArea.createDiv({ cls: "stashpad-export-pw-row" }); + const inp = row.createEl("input", { type: "password" }) as HTMLInputElement; + inp.addClass("stashpad-export-name"); inp.placeholder = placeholder; + const btn = row.createEl("button", { cls: "stashpad-export-copy" }); + const syncBtn = () => { + const empty = inp.value.length === 0; + btn.setText(empty ? "Paste" : "Copy"); + btn.toggleClass("is-paste", empty); + btn.setAttr("aria-label", `${empty ? "Paste into" : "Copy"} ${placeholder.toLowerCase()}`); + }; + btn.onclick = async (e) => { + e.preventDefault(); + if (inp.value.length === 0) { + try { + const txt = (await navigator.clipboard?.readText())?.trim(); + if (!txt) { new Notice("Clipboard is empty."); return; } + inp.value = txt; + inp.dispatchEvent(new Event("input")); // → refresh (validation, meter, button sync) + new Notice("Pasted from clipboard."); + } catch { new Notice("Couldn't read the clipboard."); } + } else { + void navigator.clipboard?.writeText(inp.value).then( + () => new Notice("Passphrase copied to clipboard."), + () => new Notice("Couldn't access the clipboard."), + ); + } + }; + syncBtn(); + pwSyncers.push(syncBtn); + return inp; + }; + const pw1 = makePwRow("Password"); + const pw2 = makePwRow("Confirm password"); + + // 0.85.4: live strength meter (a nudge, never a gate) + a generate button. + const meter = pwArea.createDiv({ cls: "stashpad-export-strength" }); + const meterBar = meter.createDiv({ cls: "stashpad-strength-bar" }); + const meterSegs = [0, 1, 2, 3].map(() => meterBar.createDiv({ cls: "stashpad-strength-seg" })); + const meterLabel = meter.createEl("span", { cls: "stashpad-strength-label" }); + + const genRow = pwArea.createDiv({ cls: "stashpad-export-genrow" }); + const genBtn = genRow.createEl("button", { cls: "stashpad-export-gen", text: "Generate strong passphrase" }); + const showBtn = genRow.createEl("button", { cls: "stashpad-export-show", text: "Show" }); + const hint = pwArea.createEl("div", { cls: "stashpad-export-pw-hint" }); - // 0.84.15: name the scheme so it's clear up front; the export toast then - // reports which KDF actually ran (Argon2id, or the weaker PBKDF2 fallback). - pwArea.createEl("div", { - cls: "stashpad-export-pw-suite", - text: "Encryption: Argon2id + AES-256-GCM (strongest). Falls back to PBKDF2 only if Argon2 can't run on this device.", + // 0.84.15: name the scheme so it's clear up front. 0.85.3: probe this device + // and state explicitly which suite WILL be used — the strong default or the + // fallback — rather than describing both abstractly. + const suite = pwArea.createEl("div", { cls: "stashpad-export-pw-suite" }); + suite.setText("Encryption: AES-256-GCM. Checking key-derivation suite for this device…"); + if (this.kdfProbe) { + void this.kdfProbe().then((argonOk) => { + suite.toggleClass("is-weak", !argonOk); + suite.setText( + argonOk + ? "Encryption: Argon2id + AES-256-GCM — the strongest suite (used on this device)." + : "⚠️ Argon2id can't run on this device, so this export will use the weaker PBKDF2 (600k) + AES-256-GCM fallback.", + ); + }).catch(() => { + // Probe failed unexpectedly — keep the neutral text, don't over-claim. + suite.setText("Encryption: AES-256-GCM with a password-derived key."); + }); + } else { + suite.setText("Encryption: Argon2id + AES-256-GCM (falls back to PBKDF2 if Argon2 can't run here)."); + } + + // 0.85.4: optional "remember in this vault" — saves the passphrase to + // Obsidian's secret storage (OS keychain) keyed by the export filename, so + // re-importing on THIS device skips the prompt. Only offered when the API + // exists (≥1.11.4); secrets are device-local, so recipients still need the + // passphrase typed/copied. + const secretStorage = (this.app as App & { secretStorage?: SecretStorage }).secretStorage; + const rememberRow = pwArea.createDiv({ cls: "stashpad-export-remember" }); + const rememberCb = rememberRow.createEl("input", { type: "checkbox" }) as HTMLInputElement; + rememberCb.id = "stashpad-export-remember-cb"; + const rememberLabel = rememberRow.createEl("label", { + text: "Remember in this vault (this device) — skips the prompt when you re-import here.", }); + rememberLabel.htmlFor = rememberCb.id; + // Shown only while "remember" is ticked: make the device-local scope explicit + // so nobody assumes the saved passphrase travels with the file or syncs. + const rememberNote = pwArea.createDiv({ cls: "stashpad-export-remember-note" }); + rememberNote.setText( + "Saved only in this device's keychain — it doesn't sync to your other devices and isn't shared with anyone you send this file to. Keep the passphrase somewhere safe if you'll open this export elsewhere.", + ); + rememberNote.style.display = "none"; + rememberCb.onchange = () => { + rememberNote.style.display = rememberCb.checked ? "" : "none"; + }; + if (!secretStorage) rememberRow.style.display = "none"; // 0.84.13: encrypted exports get an "-encrypted" tag in the filename so // secure bundles are identifiable at a glance. The preview reflects it live @@ -616,6 +707,14 @@ export class ExportStashModal extends Modal { // Gate the Export button on a valid (matching, non-empty) password when // encryption is enabled. People are warned that a lost password = lost // export, but the button itself only blocks the typo/empty cases. + const renderStrength = () => { + const s = estimatePasswordStrength(pw1.value); + meter.style.visibility = pw1.value ? "visible" : "hidden"; + meterSegs.forEach((seg, i) => seg.toggleClass("is-on", pw1.value !== "" && i <= s.level)); + meterBar.dataset.level = String(s.level); + meterLabel.setText(s.label); + }; + const refresh = () => { const enc = cb.checked; pwArea.style.display = enc ? "" : "none"; @@ -625,32 +724,58 @@ export class ExportStashModal extends Modal { else if (pw1.value !== pw2.value) { hint.setText("Passwords don't match."); hint.addClass("is-error"); ok = false; } else { hint.setText("⚠️ If you lose this password, the export can't be recovered."); hint.removeClass("is-error"); } } + renderStrength(); + pwSyncers.forEach((fn) => fn()); // Paste↔Copy per field as values change go.disabled = !ok; go.toggleClass("is-disabled", !ok); renderPreview(); // keep the filename preview in sync with the toggle }; + + // Reveal/mask both fields together (so a generated passphrase is readable). + let shown = false; + const setShown = (v: boolean) => { + shown = v; + pw1.type = pw2.type = v ? "text" : "password"; + showBtn.setText(v ? "Hide" : "Show"); + }; + showBtn.onclick = (e) => { e.preventDefault(); setShown(!shown); }; + + // Generate fills both fields but keeps them HIDDEN (0.85.7): the user + // reveals with Show or grabs it with a Copy button. Save it somewhere — you + // need it to open this export and it can't be recovered if lost. + genBtn.onclick = (e) => { + e.preventDefault(); + pw1.value = pw2.value = generatePassphrase(); + setShown(false); + new Notice("Passphrase generated (hidden) — Show to view, or Copy to save it."); + refresh(); + }; + cb.onchange = refresh; pw1.oninput = refresh; pw2.oninput = refresh; refresh(); - go.onclick = () => this.commit(effectiveBase(), cb.checked ? pw1.value : null); + const deliver = () => + this.commit(effectiveBase(), cb.checked ? pw1.value : null, cb.checked && rememberCb.checked); + go.onclick = deliver; // Enter confirms (when not blocked); Esc / click-out cancels (modal // default). No Mod+Z registration → native input undo handles clears. this.scope.register([], "Enter", (e) => { e.preventDefault(); - if (!go.disabled) this.commit(effectiveBase(), cb.checked ? pw1.value : null); + if (!go.disabled) deliver(); }); // Focus + select-all so the prefilled name is ready to type over. requestAnimationFrame(() => { input.focus(); input.select(); }); } - private commit(raw: string, password: string | null): void { + private commit(raw: string, password: string | null, remember: boolean): void { const base = raw.trim() || this.defaultBaseName; + const pw = password && password.length ? password : null; this.delivered = true; this.close(); - this.onConfirm(base, password && password.length ? password : null); + this.onConfirm(base, pw, !!pw && remember); } onClose(): void { // No delivery on cancel/Esc/click-out — the export simply doesn't run. diff --git a/src/note-picker.ts b/src/note-picker.ts index 7be4c35..e48a6ec 100644 --- a/src/note-picker.ts +++ b/src/note-picker.ts @@ -216,6 +216,9 @@ export class StashpadSuggest extends SuggestModal<PickerItem> { const cb = this.pendingCleanups.pop(); try { if (cb) cb(); } catch {} } + // 0.85.10: notify the caller the picker closed (pick OR dismiss). The + // destination picker uses this to refocus the composer only on dismiss. + try { this.opts.onClose?.(); } catch {} } constructor( @@ -228,6 +231,9 @@ export class StashpadSuggest extends SuggestModal<PickerItem> { allowCreate?: boolean; onPick: (item: PickerItem) => void; onCreate?: (query: string) => void; + /** 0.85.10: fired from onClose (any close — pick or dismiss). The + * destination picker uses it to refocus the composer on dismiss. */ + onClose?: () => void; /** Optional source for cross-folder notes. Resolved lazily when * the user starts typing — local results from `tree` are returned * first, and this source is queried only after the local set is @@ -253,17 +259,23 @@ export class StashpadSuggest extends SuggestModal<PickerItem> { } private loadAll(): void { + const rootNode = this.tree.getRoot(); + // 0.85.15: label the LOCAL home like the cross-folder entries + // ("Home — <folder>") so searching a folder by name surfaces its home note + // whether you're inside that folder or not — consistent everywhere, and it + // becomes matchable by the folder name (so the home-pin floats it to top). + const folderName = rootNode.file?.parent?.name?.trim() ?? ""; + const localHomeTitle = folderName ? `Home — ${folderName}` : "Home"; const walk = (id: string, depth: number): void => { const node = this.tree.get(id); if (node?.file && id !== ROOT_ID) { this.notes.push({ node, title: `${" ".repeat(depth)}${this.titleFn(node)}`, body: "" }); } else if (node?.file && id === ROOT_ID) { - this.notes.push({ node, title: "Home", body: "" }); + this.notes.push({ node, title: localHomeTitle, body: "" }); } for (const c of this.tree.getChildren(id)) walk(c.id, depth + 1); }; - const rootNode = this.tree.getRoot(); - if (rootNode.file) this.notes.push({ node: rootNode, title: "Home", body: "" }); + if (rootNode.file) this.notes.push({ node: rootNode, title: localHomeTitle, body: "" }); for (const c of this.tree.getChildren(ROOT_ID)) walk(c.id, 1); // lazy-read bodies in background @@ -502,31 +514,51 @@ export class StashpadSuggest extends SuggestModal<PickerItem> { // crowded by N folder rows on a vault with many Stashpads. if (this.opts.folderResults) { const folders = this.opts.folderResults(); - // Show the collapsed entry when the query is empty (folder - // browsing) OR matches at least one folder name (same trigger - // condition as before, just collapsed to one row). - const anyMatch = !q || folders.some((folder) => { - const last = folder.split("/").pop() ?? folder; - return matchesAll(`${folder.toLowerCase()} ${last.toLowerCase()}`); - }); - if (folders.length > 0 && anyMatch) { - const collapsed: PickerItem = { - id: `__folder_picker__`, - label: `Open folder in a new tab…`, - node: null, - kind: "folder-open", - }; - // 0.64.7: filter-active queries push the folder shortcut down - // so real note rows lead the list. - const hasFilter = Object.keys(parsed.filters).length > 0; - if (hasFilter) items.push(collapsed); - else items.unshift(collapsed); + const collapsed: PickerItem = { + id: `__folder_picker__`, + label: `Open folder in a new tab…`, + node: null, + kind: "folder-open", + }; + // 0.85.14: empty query → show it at the TOP (folder browsing). Once + // typing, only show it when the query matches a folder name, and place it + // at the BOTTOM so it's never the first result — real note hits lead, and + // the matching folder's home note still pins to the top (0.85.12). + if (folders.length > 0) { + if (!q) { + items.unshift(collapsed); + } else if (folders.some((folder) => { + const last = folder.split("/").pop() ?? folder; + return matchesAll(`${folder.toLowerCase()} ${last.toLowerCase()}`); + })) { + items.push(collapsed); + } } } if (this.opts.allowCreate && q && !items.some((i) => i.label.trim().toLowerCase() === q)) { items.push({ id: `__create__`, label: `Create new: "${query}"`, node: null, kind: "create" }); } + + // 0.85.12: searching a Stashpad folder by name means you want its HOME + // note. Home notes are otherwise low-priority, but once there are ≥3 + // characters of search text, any home note whose TITLE matches the query + // (local home label "Home", or a cross-folder "Home — <folder>" whose + // folder name you've typed) is floated to the very top — "no matter what". + // Title-match (not body) keeps it to genuine folder-name hits, and the ≥3 + // gate keeps short/empty queries from surfacing every home. Backs every + // modal that uses this picker — find / destination / move / in-parent. + if (parsed.text.join("").length >= 3) { + const isHomeMatch = (i: PickerItem): boolean => + i.kind === "note" + && (i.id === ROOT_ID || i.id === `cross:${ROOT_ID}`) + && matchesAll(i.label.toLowerCase()); + const homes = items.filter(isHomeMatch); + if (homes.length > 0) { + const rest = items.filter((i) => !isHomeMatch(i)); + items.splice(0, items.length, ...homes, ...rest); + } + } return items; } diff --git a/src/panels-view.ts b/src/panels-view.ts index 8388375..8b8dda5 100644 --- a/src/panels-view.ts +++ b/src/panels-view.ts @@ -70,6 +70,10 @@ export class StashpadPanelsView extends ItemView { * Fixed buckets ("all"/"mine"/"others"/"byme"/"unassigned") or a * per-person filter encoded as "person:<authorId>" (0.78.3). */ private taskAssignFilter: string = "all"; + /** 0.88.1: folder sub-filter for the Tasks panel, AND-combined with the + * status + assignment filters. "all" = every Stashpad folder, else a + * specific folder path. */ + private taskFolderFilter: string = "all"; /** 0.73.11: programmatic panel switch. Called by the per-panel * command-palette entries so the sidebar lands on the right tab * when invoked from the keyboard. */ @@ -184,7 +188,8 @@ export class StashpadPanelsView extends ItemView { homeRow.createSpan({ cls: "stashpad-pinned-label", text: "Home" }); homeRow.onclick = () => this.openHomeFromPanel(); - const pins = this.plugin.settings.pinnedNotes ?? []; + // 0.86.3: pins now come from note frontmatter (synced), ordered by pinnedAt. + const pins = this.plugin.listPinnedNotes(); if (pins.length === 0) { const empty = list.createDiv({ cls: "stashpad-pinned-empty" }); empty.setText("No pinned notes yet — right-click a note and choose “Pin to sidebar.”"); @@ -311,15 +316,24 @@ export class StashpadPanelsView extends ItemView { } } - /** Move a pin from one index to another, updating settings + re-rendering. */ + /** Move a pin to a new position by rewriting its `pinnedAt` to fall between + * the items it lands between (0.86.3 — order is the synced pinnedAt key). */ private async reorderPin(fromIdx: number, toIdx: number): Promise<void> { - const list = (this.plugin.settings.pinnedNotes ?? []).slice(); + const list = this.plugin.listPinnedNotes(); if (fromIdx < 0 || fromIdx >= list.length) return; - const [moved] = list.splice(fromIdx, 1); - const adjusted = toIdx > fromIdx ? toIdx - 1 : toIdx; - list.splice(Math.max(0, Math.min(adjusted, list.length)), 0, moved); - this.plugin.settings.pinnedNotes = list; - await this.plugin.saveSettings(); + const moved = list[fromIdx]; + const without = list.filter((_, i) => i !== fromIdx); + const insertAt = Math.max(0, Math.min(toIdx > fromIdx ? toIdx - 1 : toIdx, without.length)); + const prev = without[insertAt - 1]; + const next = without[insertAt]; + let at: number; + if (!prev && !next) at = Date.now(); + else if (!prev) at = next.pinnedAt - 1000; + else if (!next) at = prev.pinnedAt + 1000; + else at = (prev.pinnedAt + next.pinnedAt) / 2; + try { + await this.app.fileManager.processFrontMatter(moved.file, (fm: any) => { fm.pinnedAt = at; }); + } catch (e) { console.warn("[Stashpad] pin reorder failed", e); } this.render(); } @@ -806,10 +820,27 @@ export class StashpadPanelsView extends ItemView { } sel.onchange = () => { this.taskAssignFilter = sel.value; this.render(); }; - const tasks = allTasks.filter(assignMatches); + // 0.88.1: Folder filter dropdown (AND-combined). Distinct folders across + // all tasks; "all" shows every folder. Reset to "all" if the previously + // selected folder no longer has any tasks. + const folders = [...new Set(allTasks.map((t) => t.folder))].sort((a, b) => a.localeCompare(b)); + if (this.taskFolderFilter !== "all" && !folders.includes(this.taskFolderFilter)) this.taskFolderFilter = "all"; + const folderBar = list.createDiv({ cls: "stashpad-task-assign-bar" }); + folderBar.createSpan({ cls: "stashpad-task-assign-label", text: "Folder" }); + const fsel = folderBar.createEl("select", { cls: "stashpad-task-assign-select" }); + const allOpt = fsel.createEl("option", { text: "All folders", value: "all" }); + if (this.taskFolderFilter === "all") allOpt.selected = true; + for (const f of folders) { + const o = fsel.createEl("option", { text: f.split("/").pop() || f, value: f }); + if (this.taskFolderFilter === f) o.selected = true; + } + fsel.onchange = () => { this.taskFolderFilter = fsel.value; this.render(); }; + const folderMatches = (t: TaskItem): boolean => this.taskFolderFilter === "all" || t.folder === this.taskFolderFilter; + + const tasks = allTasks.filter((t) => assignMatches(t) && folderMatches(t)); if (tasks.length === 0) { list.createDiv({ cls: "stashpad-tasks-empty" }) - .setText(`No tasks match "${labelFor(this.taskAssignFilter)}".`); + .setText(`No tasks match the current filters.`); return; } diff --git a/src/passphrase.ts b/src/passphrase.ts new file mode 100644 index 0000000..e3fe8bd --- /dev/null +++ b/src/passphrase.ts @@ -0,0 +1,160 @@ +/** 0.85.4: passphrase generation + password-strength estimation for the + * encrypted-.stash export flow, plus deterministic secret-storage IDs. + * + * - generatePassphrase(): xkcd-style "correct-horse-battery-staple" — N random + * words from a curated list joined by dashes, with a trailing number. Uses + * crypto.getRandomValues with rejection sampling (no modulo bias). + * - estimatePasswordStrength(): a lightweight, dependency-free nudge meter (NOT + * zxcvbn-grade). Pool-size entropy with a repetition penalty and a small + * common-password floor. Good enough to shame "cool bean"; honest enough not + * to call "aaaaaaaa" strong. + * - secretIdForStashName(): deterministic, collision-resistant id (lowercase + * alphanumeric + dashes, ≤64) so export-time setSecret and import-time + * getSecret agree from the filename alone. */ + +/** Curated word list for generated passphrases. Short, common, unambiguous + * (no profanity, no easily-confused homophones). ~280 words → log2 ≈ 8.13 + * bits/word, so the default 5-word passphrase + 2-digit number ≈ 47 bits of + * entropy — comfortably "strong" for a file password. */ +const WORDS = ( + "able acid acorn actor adept agile alarm album alert algae amber amble anchor angle ankle apple " + + "april arbor arc arctic arena armor arrow ascot aspen atlas atom attic auburn audio autumn award " + + "axis bacon badge bagel baker balmy bamboo banjo barge basil basin batch beach beam bean bear " + + "beaver begin belt bench berry birch bison black blade blaze bliss bloom blue board boat bold " + + "bolt bonus boost booth borax bother bottle boulder bounce bovine bowl brave bread breeze brick " + + "bridge brisk broad bronze brook broom brown brush bubble bucket bug bulb bundle burst cabin " + + "cable cacao cactus camel cameo candle canoe canvas canyon cargo carol carrot castle catch cedar " + + "cello chalk charm chart cheese cherry chess chime chirp cider cinder circle citrus clamp clay " + + "clever cliff cloak clock cloud clover coast cobra cocoa comet coral cosmos cotton couch cougar " + + "crane crater cream crest cricket crisp crown crumb crystal cube cumin curio dagger daisy dapper " + + "dawn deck deer delta denim depot desert dial diamond dingo ditch dock dodge dolphin domino donut " + + "draft dragon drift drum dune dusk eagle early earth easel ebony echo eclipse edge eel eagle " + + "elbow elder ember emboss emerald ember emu engine ermine ether ever fable falcon fancy farm " + + "fawn feather felt fennel fern ferry fiber fiddle field fig finch flame flask flax fleet flint " + + "float flock flora flute focus foam forest fossil fox frame frost fudge garden gecko ginger " + + "glacier glade glass glide globe glory glove gnat goat golden gopher gourd grape grass gravel " + + "grove guava gull hammer hamlet harbor hatch hazel heron hickory hippo honey hornet hostel ivory " + + "ivy jade jaguar jasmine jelly jetty jewel jolly jungle juniper kayak kelp kettle kiwi koala " + + "ladle lagoon lamp lantern larch lark lasso lava ledge lemon lentil leopard lever lilac lime " + + "linen lizard llama lobby locket lodge lotus lunar lupine lynx maple marble marsh meadow medal " + + "melon mellow mentor mesa metro mimic mint mirror mocha morsel moss mottle mural muslin nacho " + + "nectar nest noble nomad noodle nougat nutmeg oasis oat ocean ochre olive onyx opal orbit orca " + + "otter oval owl oxide oyster pace paddle palm panda pantry papaya parka parsley pasta pearl " + + "pebble pelican pepper pewter phantom piano picnic pigeon pilot pine pixel plank plaza plum " + + "pocket pollen pond poplar poppy portal potato pottery prairie prism puffin pumice quail quartz " + + "quill quilt quince rabbit radish raft rapid raven reed reef relish ribbon ridge rind ripple " + + "river robin rocket rope rover ruby rudder rust saffron sage salmon sandal sash satin sauce " + + "scout sedge sequin shadow shale shark shell shore shrub silk silo silver siren sketch slate " + + "sleet slope sloth smoke snail sonar sorrel spark sparrow spice spire sprig spruce squid stable " + + "stamp starling steam stem stilt stone stork storm stove straw stream stucco summit sundae " + + "sunset swan sweater syrup tabby talon tango tapir tassel tawny teal tempo thicket thimble " + + "thistle thorn thunder tidal tiger timber toffee token topaz torch totem trail tulip tundra " + + "turtle tusk twig umber unicorn valley vanilla velvet vermil violet viper vista vivid vortex " + + "waffle walnut warbler wasp water weasel wharf wheat whisk willow window winter wisp wombat " + + "wonder woven yam yarn yeast yew yodel yonder zebra zenith zephyr zigzag zinc zircon" +).split(/\s+/).filter(Boolean); + +/** Unbiased random integer in [0, n) via rejection sampling. */ +function randIndex(n: number): number { + const limit = Math.floor(0x100000000 / n) * n; // largest multiple of n ≤ 2^32 + const buf = new Uint32Array(1); + let x: number; + do { crypto.getRandomValues(buf); x = buf[0]; } while (x >= limit); + return x % n; +} + +/** xkcd-style passphrase: `words` random words + a trailing 2-digit number, + * dash-separated. Default 5 words ≈ 47 bits of entropy. */ +export function generatePassphrase(words = 5): string { + const parts: string[] = []; + for (let i = 0; i < words; i++) parts.push(WORDS[randIndex(WORDS.length)]); + parts.push(String(10 + randIndex(90))); // 10..99 — guarantees a digit class + return parts.join("-"); +} + +/** Approx. entropy (bits) of a generated passphrase, for honest UI labeling. */ +export function passphraseBits(words = 5): number { + return words * Math.log2(WORDS.length) + Math.log2(90); +} + +// A few of the most-abused passwords — floored so the meter never flatters them. +const COMMON = new Set([ + "password", "passw0rd", "password1", "123456", "12345678", "123456789", "qwerty", + "abc123", "letmein", "welcome", "admin", "iloveyou", "monkey", "dragon", "sunshine", + "princess", "football", "baseball", "trustno1", "000000", "111111", "secret", +]); + +export interface PasswordStrength { + /** Estimated entropy in bits (capped/penalized — not a precise figure). */ + bits: number; + /** 0 = weak, 1 = fair, 2 = good, 3 = strong. */ + level: 0 | 1 | 2 | 3; + label: string; +} + +/** Dependency-free strength estimate. Pool-size entropy scaled by a repetition + * penalty, with a hard floor for known-common passwords. Tuned to nudge, not + * to gate — the export button never blocks on strength. */ +export function estimatePasswordStrength(pw: string): PasswordStrength { + if (!pw) return { bits: 0, level: 0, label: "" }; + + let pool = 0; + if (/[a-z]/.test(pw)) pool += 26; + if (/[A-Z]/.test(pw)) pool += 26; + if (/[0-9]/.test(pw)) pool += 10; + if (/[^a-zA-Z0-9]/.test(pw)) pool += 32; + pool = Math.max(pool, 2); + + // Repetition penalty: a password using few distinct characters (e.g. "aaaa") + // gets credited closer to its unique-char count than its raw length. + const uniq = new Set(pw).size; + const effLen = pw.length * Math.min(1, uniq / pw.length + 0.25); + let bits = effLen * Math.log2(pool); + + // Word-phrase ceiling: pool-size entropy badly overcredits plain dictionary + // words ("cool bean" looks like ~53 random bits but is really a guessable + // word pair). When the input is purely space/dash/underscore-separated + // alphabetic tokens, cap at ~11 bits/word (a generous human-vocabulary + // assumption). A generated passphrase dodges this because its trailing number + // token isn't alphabetic, so it keeps the full (high) estimate. + const tokens = pw.split(/[\s\-_]+/).filter(Boolean); + if (tokens.length >= 1 && tokens.every((t) => /^[a-zA-Z]+$/.test(t))) { + bits = Math.min(bits, tokens.length * 11); + } + + if (COMMON.has(pw.toLowerCase())) bits = Math.min(bits, 12); + + const level: PasswordStrength["level"] = + bits < 36 ? 0 : bits < 56 ? 1 : bits < 76 ? 2 : 3; + const label = ["Weak — easily guessed", "Fair", "Good", "Strong"][level]; + return { bits, level, label }; +} + +/** Simple, fast FNV-1a → 8 hex chars. Used only to disambiguate truncated + * secret IDs; not security-sensitive. */ +function fnv1a(s: string): string { + let h = 0x811c9dc5; + for (let i = 0; i < s.length; i++) { + h ^= s.charCodeAt(i); + h = Math.imul(h, 0x01000193); + } + return (h >>> 0).toString(16).padStart(8, "0"); +} + +/** Deterministic Obsidian secretStorage id for a given .stash base name (the + * filename WITHOUT the `.stash` extension). Charset is lowercase alphanumeric + + * dashes, ≤64 chars (the SecretStorage constraint). Derived purely from the + * name + an FNV hash suffix so export-time set and import-time get agree and + * truncation collisions are vanishingly unlikely. */ +export function secretIdForStashName(baseName: string): string { + const prefix = "stashpad-"; + const hash = fnv1a(baseName); + const room = 64 - prefix.length - 1 - hash.length; // "-" + hash + const slug = baseName + .toLowerCase() + .replace(/[^a-z0-9]+/g, "-") + .replace(/^-+|-+$/g, "") + .slice(0, Math.max(0, room)) + .replace(/-+$/g, ""); + return `${prefix}${slug}-${hash}`; +} diff --git a/src/settings.ts b/src/settings.ts index 4cf9264..8b25395 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -59,7 +59,8 @@ export type CommandId = | "swapWithParent" | "togglePin" | "toggleTask" | "setDue" - | "jumpToTop" | "jumpToBottom"; + | "jumpToTop" | "jumpToBottom" + | "commandPalette"; /** Per-command bindings: up to two chord strings ("S" or "Mod+Enter"). * When BOTH are set, `preferRight` decides which actually fires. */ @@ -122,6 +123,7 @@ export const COMMAND_META: CommandMeta[] = [ { id: "setDue", label: "Set due date…", desc: "Default: D — 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" }, { id: "jumpToTop", label: "Jump to top of list", desc: "Default: Home — move the cursor to the first note in the current list.", defaultPrimary: "Home" }, { id: "jumpToBottom", label: "Jump to bottom of list", desc: "Default: End — move the cursor to the last note in the current list.", defaultPrimary: "End" }, + { id: "commandPalette", label: "Command palette (Stashpad only)", desc: "Default: Mod+K — open a command palette listing only Stashpad's commands, with Sift search.", defaultPrimary: "Mod+K" }, ]; export function buildDefaultBindings(): CommandBindingMap { @@ -144,6 +146,9 @@ export interface StashpadSettings { * honor Obsidian's "Excluded files" (userIgnoreFilters), so exclusions * are managed in one place. `.edtz` is always excluded regardless. */ inheritObsidianExclusions: boolean; + /** 0.86.2: folder panel — fraction of height given to the Pinned section + * (the rest goes to Folders). Set by dragging the divider. 0.15–0.85. */ + folderPanelPinnedFraction: number; /** 0.81.1: opt-in performance profiling — accumulates render/read/write * timing so the "Dump performance profile" command reports where the * time goes on a slow vault. Off by default. */ @@ -364,6 +369,7 @@ export const DEFAULT_SETTINGS: StashpadSettings = { exportFolder: "_exports", autoImport: false, inheritObsidianExclusions: true, + folderPanelPinnedFraction: 0.5, enablePerfProfiling: false, writeRecoveryLinks: true, useTemplatesFormat: false, diff --git a/src/stash-crypto.ts b/src/stash-crypto.ts index 038d614..2a19390 100644 --- a/src/stash-crypto.ts +++ b/src/stash-crypto.ts @@ -220,9 +220,23 @@ async function decryptV1(envelope: Uint8Array, password: string): Promise<Uint8A export async function resolveStashBytes( app: App, bytes: Uint8Array, - opts: { allowLater?: boolean; onLater?: () => void } = {}, + opts: { allowLater?: boolean; onLater?: () => void; secretId?: string } = {}, ): Promise<Uint8Array | null> { if (!isEncryptedStash(bytes)) return bytes; + + // 0.85.4: if this export's passphrase was remembered in this vault's secret + // storage (keyed by filename), try it silently before prompting. This goes + // through the SAME decryptStash path — no bypass of the zip-slip / collision + // guards downstream. A stored-but-wrong secret just falls through to prompt. + if (opts.secretId) { + const ss = (app as App & { secretStorage?: { getSecret(id: string): string | null } }).secretStorage; + let stored: string | null = null; + try { stored = ss?.getSecret(opts.secretId) ?? null; } catch { stored = null; } + if (stored) { + try { return await decryptStash(bytes, stored); } catch { /* fall through to prompt */ } + } + } + let errorMsg: string | undefined; for (;;) { const r = await new Promise<StashPasswordResult>((resolve) => { diff --git a/src/types.ts b/src/types.ts index 85a8592..6bb03d9 100644 --- a/src/types.ts +++ b/src/types.ts @@ -3,6 +3,8 @@ import type { TFile } from "obsidian"; export const STASHPAD_VIEW_TYPE = "stashpad-view"; /** 0.68.0: sidebar panels view (Pinned Notes + future panels). */ export const STASHPAD_PANELS_VIEW_TYPE = "stashpad-panels"; +/** 0.86.0: left-sidebar folder picker (pinned notes + folders, split). */ +export const STASHPAD_FOLDER_PANEL_VIEW_TYPE = "stashpad-folder-panel"; /** 0.74.1: right-sidebar detail panel. Shows the currently-cursored * note's body + metadata + children. Lives separately from the * left-sidebar panels view (Pinned/Shared/Tasks). */ @@ -99,6 +101,12 @@ export const RESERVED_FRONTMATTER: readonly string[] = [ // 0.78.1: task scheduling/assignment — Stashpad-managed, so clones / // templates must not carry someone else's due date or assignees. "due", "assignedTo", "assignedBy", + // 0.86.3: sidebar pin state lives on the note (so it SYNCS with the note + // across devices). Stashpad-managed; clones/templates must not inherit it. + "pinned", "pinnedAt", + // 0.88.0: marks a note that came in via import (used by the "imported only" + // view filter). Stashpad-managed; a clone of an imported note isn't imported. + "imported", ] as const; /** Reserved Stashpad subfolder names (machine-managed; not user notes). diff --git a/src/view.ts b/src/view.ts index 43bc38c..fca71d4 100644 --- a/src/view.ts +++ b/src/view.ts @@ -4,7 +4,7 @@ import { moment, setIcon, } from "obsidian"; import { - ROOT_ID, STASHPAD_VIEW_TYPE, RESERVED_FRONTMATTER, fmHasTag, fmAddTag, fmRemoveTag, parseAssignees, attachmentLinkPath, + ROOT_ID, STASHPAD_VIEW_TYPE, RESERVED_FRONTMATTER, fmHasTag, fmAddTag, fmRemoveTag, parseAssignees, parseAuthorRef, attachmentLinkPath, toAttachmentLink, type StashpadId, type TimeFilter, type TreeNode, type ViewConfigState, type ViewMode, type ScrollPolicy, } from "./types"; import { TreeIndex } from "./tree-index"; @@ -12,7 +12,7 @@ import { perf } from "./perf"; import { formatDateTime } from "./format"; import { OrderStore } from "./order-store"; import { SortStore, type SortMode, SORT_MODE_LABELS, SORT_MODES_ORDER } from "./sort-store"; -import { FrontmatterSyncQueue } from "./frontmatter-sync"; +import { FrontmatterSyncQueue, rebootstrapFolderFrontmatter } from "./frontmatter-sync"; import { buildFileActions } from "./notifications"; import { newId } from "./id-service"; import { bodyToSlug, buildFilename, parseIdFromFilename, DEFAULT_STOPWORDS } from "./slug-service"; @@ -20,6 +20,7 @@ import { StashpadLog } from "./log"; import { IntegrityWatcher } from "./integrity-watcher"; import { getSettings, getTemplatesFormats, onSettingsChange } from "./settings"; import { StashpadSuggest } from "./note-picker"; +import { StashpadCommandPalette } from "./command-palette"; import { setActiveView, clearActiveView } from "./active-view"; import { AssignModal, ColorPickerModal, ConfirmDeleteModal, ConfirmModal, DueDatePickerModal, SplitNoteModal } from "./modals"; import { ComposerAutocomplete } from "./composer-autocomplete"; @@ -110,6 +111,11 @@ export class StashpadView extends ItemView { /** Active color filter — null means show everything; otherwise the * hex string (e.g. "#E07A78") that visible notes must carry. */ private colorFilter: string | null = null; + /** 0.88.1: when true, show only notes that came in via import + * (frontmatter `imported: true`). Per-session, like tag/color. */ + private importedOnly = false; + /** 0.88.1: when set, show only notes whose author id matches. Per-session. */ + private authorFilter: string | null = null; /** public: read by AuthorshipTracker (the host interface). */ noteFolder = "Stashpad"; private folderOverride: string | null = null; @@ -155,6 +161,14 @@ export class StashpadView extends ItemView { private nextDestinationFolder: string | null = null; private nextDestinationLabel: string | null = null; private inListPicker: { activeIdx: number } | null = null; + /** 0.91.2: timestamp of the last Escape that cancelled the in-list picker. + * The picker-cancel and the multi-selection "collapse to one" live in TWO + * different Escape handlers (the keymap Scope handler + the document keydown + * handler) and their firing order isn't guaranteed — whichever runs first + * nulls `inListPicker`, so the other can't tell the picker was active and + * wrongly collapses the selection. Stamping this lets the collapse paths + * skip when a picker-cancel just happened (within ~350ms). */ + private pickerEscapeAt = 0; /** public: read by ViewDnD (the host interface). */ listEl: HTMLElement | null = null; private composerInputEl: HTMLTextAreaElement | null = null; @@ -213,6 +227,11 @@ export class StashpadView extends ItemView { * policy so the user lands looking at the same note they were on, even * when row heights shift between sessions. 0.56.14. */ private lastCursorByFocus = new Map<StashpadId, StashpadId>(); + /** Per-focus persisted MULTI-SELECTION (via plugin.saveLastSelection). + * Read on view open / folder switch; folded into pendingFocusIds so a + * reload restores the same notes selected — even when the tab was deferred + * (lazy-loaded) on reload. 0.91.0. */ + private lastSelectionByFocus = new Map<StashpadId, StashpadId[]>(); private expandedNotes = new Set<StashpadId>(); private focusComposerOnNextRender = false; /** 0.76.21: timestamp until which the activation auto-focus @@ -355,6 +374,22 @@ export class StashpadView extends ItemView { // user presses while focus is in the view gets swallowed. viewScope = new Scope((this.app as any).scope); viewScope.register([], "Escape", () => { + // 0.91.1: when the in-list parent picker is active, Escape CANCELS the + // picker without touching the selection. This Scope handler is what + // real Escape keypresses hit (it preempts the document keydown + // handler's picker-cancel branch), so without this guard pressing O + // then Escape would fall through to the collapse-below and drop every + // selected note but one — the exact repro the user reported. + if (this.inListPicker) { + this.inListPicker = null; + this.pickerEscapeAt = Date.now(); + this.repaintSelectionClasses(); // clears the pick-target highlight + return false; + } + // If the OTHER Escape handler just cancelled the picker (it nulled + // inListPicker before we ran), don't treat this same keypress as a + // selection-collapse. 0.91.2. + if (Date.now() - this.pickerEscapeAt < 350) return false; // List-mode Escape: collapse multi-selection if any. Otherwise // a no-op — but we still return false so the workspace's // "Escape returns to last leaf" never fires. @@ -417,15 +452,17 @@ export class StashpadView extends ItemView { if (file.extension !== "md") return; const fm = this.app.metadataCache.getFileCache(file)?.frontmatter as any; this.completedState.set(file.path, !!fm?.completed); + // 0.85.1: resync the task-ness override too, now that the cache is fresh. + this.taskTaggedState.set(file.path, this.taggedFromFm(fm)); })); this.registerEvent(this.app.vault.on("rename", (file, oldPath) => { - if (this.completedState.has(oldPath)) { - this.completedState.set(file.path, this.completedState.get(oldPath)!); - this.completedState.delete(oldPath); + for (const map of [this.completedState, this.taskTaggedState]) { + if (map.has(oldPath)) { map.set(file.path, map.get(oldPath)!); map.delete(oldPath); } } })); this.registerEvent(this.app.vault.on("delete", (file) => { this.completedState.delete(file.path); + this.taskTaggedState.delete(file.path); })); this.detachSettings = onSettingsChange(() => { this.loadConfig(); @@ -494,6 +531,8 @@ export class StashpadView extends ItemView { try { const loaded = this.plugin.loadLastCursor(this.noteFolder); for (const [focusId, noteId] of loaded) this.lastCursorByFocus.set(focusId, noteId); + // 0.91.0: hydrate the persisted multi-selection alongside the cursor. + this.lastSelectionByFocus = this.plugin.loadLastSelection(this.noteFolder); } catch {} // On a fresh mount (app reload, tab restore, first-ever open), scroll // to the end of the list so the newest notes are visible. Once the @@ -519,7 +558,16 @@ export class StashpadView extends ItemView { this.scrollToBottomOnNextRender = true; initialPolicy = { kind: "pin-bottom", until: "next-user-input" }; } + // 0.91.0: restore a persisted multi-selection (app reload / workspace + // restore). Obsidian may call onOpen BEFORE setState, in which case + // restoredSelectionIds isn't populated yet and this no-ops — setState's + // own render path runs the same fold. Whichever fires with the field set + // wins; the helper consumes it so it only applies once. + const restoredSel = this.foldRestoredSelection(savedCursorId); + if (restoredSel) this.pendingFocusIds = restoredSel; this.render(initialPolicy); + // 0.91.1: re-assert the selection after post-mount reconcile renders settle. + this.scheduleSelectionRestore(); // 0.61.7: defer the tiny resize to ~1s after launch. Obsidian's own // popout init grabs the BrowserWindow size during the first frames, // and racing it with rAF/150ms/600ms calls only sometimes won. Let @@ -609,6 +657,9 @@ export class StashpadView extends ItemView { // 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; + // 0.86.6: plugin-wide suppression — the folder panel sets this before + // revealing a leaf so tapping a pinned note doesn't pop the keyboard. + if (Date.now() < this.plugin.suppressComposerAutofocusUntil) 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; @@ -665,7 +716,7 @@ export class StashpadView extends ItemView { try { await this.fmSync.flush(); } catch {} // 0.56.17: eager-stamp last-selected cursor; sync localStorage means // it survives the reload that follows close. - this.stampSelectedCursor(true); + this.stampSelectedCursor(true); // 0.91.1: also persists the selection (piggybacked) // Tear down the fmSync failure-notice subscription so it doesn't // outlive the view. this.fmSyncUnsubscribe?.(); @@ -766,9 +817,12 @@ export class StashpadView extends ItemView { // against the default folder (state hadn't loaded yet); now that we // know the actual folder, hydrate + scroll-to-id again. this.lastCursorByFocus.clear(); + this.lastSelectionByFocus.clear(); try { const loaded = this.plugin.loadLastCursor(this.noteFolder); for (const [focusId, noteId] of loaded) this.lastCursorByFocus.set(focusId, noteId); + // 0.91.0: re-hydrate the persisted multi-selection for the new folder. + this.lastSelectionByFocus = this.plugin.loadLastSelection(this.noteFolder); } catch {} const savedCursorId = this.lastCursorByFocus.get(this.focusId); let policy: ScrollPolicy; @@ -778,11 +832,81 @@ export class StashpadView extends ItemView { } else { policy = { kind: "pin-bottom", until: "next-user-input" }; } + // 0.91.0: fold in a persisted multi-selection (overrides the single-id + // cursor restore above). This is the path that actually runs on a normal + // app reload, since Obsidian calls setState after onOpen. + const restoredSel = this.foldRestoredSelection(savedCursorId); + if (restoredSel) this.pendingFocusIds = restoredSel; this.render(policy); + // 0.91.1: re-assert the selection after post-mount reconcile renders. + this.scheduleSelectionRestore(); } } focus(): void { this.viewRoot?.focus({ preventScroll: true }); } + /** 0.91.0: fold a persisted multi-selection (from setState) into the list to + * hand render()'s pendingFocusIds path. Orders the saved cursor note first + * so the cursor lands where it left off; validates every id against the + * rebuilt tree (render's loop further prunes to children of the focus, so + * off-screen ids drop cleanly). Consumes `restoredSelectionIds` so it only + * applies once across the onOpen / setState restore races. Returns null when + * there's nothing to restore (leave pendingFocusIds untouched). */ + private foldRestoredSelection(savedCursorId: StashpadId | null | undefined): StashpadId[] | null { + // Source from localStorage only (stamped on EVERY selection change, so + // always fresh). The view-state `selectedIds` path was removed in 0.91.2: + // selection changes don't trigger a workspace-layout save, so getState() + // captured a STALE selection and restored the wrong notes — then a + // post-restore stamp overwrote the good localStorage value with it. + const ids = this.lastSelectionByFocus.get(this.focusId) ?? null; + if (!ids || !ids.length) return null; + const valid = ids.filter((id) => !!this.tree.get(id)); + if (!valid.length) return null; + return savedCursorId && valid.includes(savedCursorId) + ? [savedCursorId, ...valid.filter((id) => id !== savedCursorId)] + : valid; + } + + /** 0.91.0: persist the current multi-selection to localStorage for this + * (folder, focus) so a reload restores it. `eager` flushes synchronously + * (beforeunload/blur/onClose); otherwise it debounces like the cursor stamp. + * An empty selection clears the stored entry. */ + private stampSelection(eager = false): void { + const ids = [...this.selection]; + const flush = (): void => { + try { this.plugin.saveLastSelection(this.noteFolder, this.focusId, ids); } + catch { /* localStorage unavailable — non-fatal */ } + }; + if (this.stampSelectionTimer != null) { window.clearTimeout(this.stampSelectionTimer); this.stampSelectionTimer = null; } + if (eager) { flush(); return; } + this.stampSelectionTimer = window.setTimeout(() => { this.stampSelectionTimer = null; flush(); }, 400); + } + + /** 0.91.1: re-apply a persisted selection AFTER the list has actually loaded. + * The initial pendingFocusIds restore (during the first render) can be + * clobbered by a metadata-cache reconcile render that fires shortly after + * mount — which is why selection "didn't survive reload" despite being + * persisted. These staggered retries re-assert the saved selection until it + * sticks, but ONLY when the current selection is empty or a shrunk subset of + * the saved one, so we never fight a selection the user has begun building. */ + private scheduleSelectionRestore(): void { + const saved = this.lastSelectionByFocus.get(this.focusId); + if (!saved || !saved.length) return; + const apply = (): void => { + const valid = saved.filter((id) => this.currentChildren.some((n) => n.id === id)); + if (!valid.length) return; + const cur = [...this.selection]; + const savedSet = new Set(valid); + const lostOrShrunk = cur.length < valid.length && cur.every((id) => savedSet.has(id)); + if (!lostOrShrunk) return; // already fully restored, or the user changed it + this.selection.clear(); + for (const id of valid) this.selection.add(id); + this.firstSelectedId = valid[0]; + this.lastSelected = valid[valid.length - 1]; + this.repaintSelectionClasses(); + }; + for (const delay of [120, 400, 900, 1600]) window.setTimeout(apply, delay); + } + private loadConfig(): void { const settingsFolder = (this.plugin?.settings?.folder ?? "Stashpad").trim().replace(/^\/+|\/+$/g, ""); const overrideFolder = this.folderOverride?.trim().replace(/^\/+|\/+$/g, "") || null; @@ -1489,8 +1613,20 @@ export class StashpadView extends ItemView { const color = this.colorFilter?.toLowerCase() ?? null; const hideCompleted = this.currentHideCompleted(); const attachmentsOnly = this.currentAttachmentsOnly(); - if (!cutoff && !tag && !color && !hideCompleted && !attachmentsOnly) return children; + const importedOnly = this.importedOnly; + const authorId = this.authorFilter; + if (!cutoff && !tag && !color && !hideCompleted && !attachmentsOnly && !importedOnly && !authorId) return children; return children.filter((n) => { + // 0.88.1: imported-only + by-author filters (node-level, like tag/color). + if (importedOnly) { + if (!n.file) return false; + if (this.app.metadataCache.getFileCache(n.file)?.frontmatter?.imported !== true) return false; + } + if (authorId) { + if (!n.file) return false; + const a = parseAuthorRef(this.app.metadataCache.getFileCache(n.file)?.frontmatter?.author); + if (!a || a.id !== authorId) return false; + } if (cutoff && n.created) { const t = Date.parse(n.created); if (!Number.isNaN(t) && t < cutoff) return false; @@ -1623,7 +1759,14 @@ export class StashpadView extends ItemView { * the eager onClose / blur / navigateTo / navigateUp paths flush * immediately. 0.56.17. */ private stampLastCursorTimer: number | null = null; + private stampSelectionTimer: number | null = null; private stampSelectedCursor(eager = false): void { + // 0.91.1: persist the multi-selection on the same cadence as the cursor — + // stampSelectedCursor is already called at every selection-change site + // (eager on close/blur/reload, debounced otherwise), so piggybacking here + // keeps localStorage continuously fresh instead of relying on a single + // beforeunload stamp that can miss. + this.stampSelection(eager); const node = this.currentChildren[this.cursorIdx]; const id = node?.id ?? this.lastSelected; if (!id) return; @@ -2333,10 +2476,27 @@ export class StashpadView extends ItemView { menu.addItem((it: any) => it.setTitle("Split note…").setIcon("scissors").setDisabled(!hasTargets || !exactlyOne).onClick(() => void this.cmdSplit())); menu.addSeparator(); menu.addItem((it: any) => it.setTitle("Delete").setIcon("trash-2").setDisabled(!hasTargets).onClick(() => void this.cmdDelete())); + menu.addSeparator(); + // 0.87.0: escape hatch to the full command set — anything not surfaced + // here (or in the context menu) is reachable via the command palette. + menu.addItem((it: any) => it.setTitle("More commands…").setIcon("terminal").onClick(() => this.openCommandPalette())); const r = anchor.getBoundingClientRect(); menu.showAtPosition({ x: r.left, y: r.bottom + 4 }); } + /** Open Obsidian's command palette (the "more commands" escape hatch from the + * ⚡ + context menus). Type "Stashpad" to narrow to this plugin's commands. */ + private openCommandPalette(): void { + (this.app as any).commands?.executeCommandById?.("command-palette:open"); + } + + /** 0.90.0: open Stashpad's OWN command palette (default Mod+K) — only this + * plugin's commands, Sift-searchable, no "Stashpad: " prefix. Distinct from + * `openCommandPalette` above, which opens Obsidian's global palette. */ + openStashpadCommandPalette(): void { + new StashpadCommandPalette(this.app).open(); + } + /** Render the tag-filter <select>. Folder tags are tallied + sorted * here on each render so newly-added tags appear without a refresh. */ private renderTagFilterDropdown(bar: HTMLElement): void { @@ -2875,6 +3035,49 @@ export class StashpadView extends ItemView { await this.setIncludeAttachments(attCheck.checked); this.refreshList(); }; + + // 0.88.1: imported-only + by-author filters. Most useful in Flat/Everything + // (which flatten descendants), but they apply in every mode. + container.createDiv({ cls: "stashpad-view-popover-divider" }); + + const impRow = container.createDiv({ cls: "stashpad-view-popover-row stashpad-view-popover-toggle" }); + const impCheck = impRow.createEl("input", { type: "checkbox" }) as HTMLInputElement; + impCheck.checked = this.importedOnly; + impRow.createDiv({ cls: "stashpad-view-popover-main" }) + .createSpan({ cls: "stashpad-view-popover-label", text: "Imported notes only" }); + impRow.createDiv({ cls: "stashpad-view-popover-desc", text: "Show only notes that came in via import." }); + impRow.onclick = (e) => { + if (e.target !== impCheck) { e.preventDefault(); impCheck.checked = !impCheck.checked; } + this.importedOnly = impCheck.checked; + this.reconcileSelectionAfterFilter(); + this.refreshList(); + }; + + // By-author dropdown — distinct authors present in this folder. + const authors = new Map<string, string>(); + const dir = this.noteFolder.replace(/\/+$/, ""); + for (const f of this.app.vault.getMarkdownFiles()) { + if ((f.parent?.path?.replace(/\/+$/, "") ?? "") !== dir) continue; + const a = parseAuthorRef(this.app.metadataCache.getFileCache(f)?.frontmatter?.author); + if (a) authors.set(a.id, a.name); + } + const authRow = container.createDiv({ cls: "stashpad-view-popover-row stashpad-view-popover-toggle" }); + const authMain = authRow.createDiv({ cls: "stashpad-view-popover-main" }); + authMain.createSpan({ cls: "stashpad-view-popover-label", text: "By author" }); + const authSel = authMain.createEl("select", { cls: "stashpad-view-author-select" }); + const allO = authSel.createEl("option", { text: "All authors", value: "" }); + if (!this.authorFilter) allO.selected = true; + for (const [id, name] of [...authors.entries()].sort((a, b) => a[1].localeCompare(b[1]))) { + const o = authSel.createEl("option", { text: name, value: id }); + if (this.authorFilter === id) o.selected = true; + } + authSel.onclick = (e) => e.stopPropagation(); + authSel.onchange = () => { + this.authorFilter = authSel.value || null; + this.reconcileSelectionAfterFilter(); + this.refreshList(); + }; + authRow.createDiv({ cls: "stashpad-view-popover-desc", text: authors.size ? "Show only notes by the chosen author." : "No authored notes in this folder yet." }); } private setTagFilter(raw: string | null): void { @@ -3755,23 +3958,11 @@ export class StashpadView extends ItemView { // note is a task. Reflects `completed`; click toggles it in place // (no need to open the Tasks panel). Sits before the meta column. if (this.isTask(node)) { - row.addClass("is-task"); // adds the leading checkbox grid column - const cb = row.createSpan({ cls: "stashpad-note-task-checkbox" }); - const done = this.isCompleted(node); - setIcon(cb, done ? "check-square" : "square"); - cb.title = done ? "Mark not done" : "Mark done"; - // 0.76.12: the checkbox fully owns its pointer events so - // interacting with it never selects/focuses or navigates the - // row — like flicking a control on an unfocused window. We stop - // mousedown (row selection / focus), click (handleRowClick), AND - // dblclick (the double-click-to-open handler) at the checkbox. - cb.addEventListener("mousedown", (e) => e.stopPropagation()); - cb.addEventListener("dblclick", (e) => { e.preventDefault(); e.stopPropagation(); }); - cb.onclick = (e) => { - e.preventDefault(); - e.stopPropagation(); - void this.toggleCompletedForNode(node); - }; + row.addClass("is-task"); // desktop: adds the leading checkbox grid column + // 0.87.1: on mobile the checkbox moves into the meta column (left of the + // children-count arrow) so the single right-side action button doesn't + // wrap to the next line; on desktop it stays at the leftmost edge. + if (!Platform.isMobile) this.addTaskCheckbox(row, node); } const meta = row.createDiv({ cls: "stashpad-note-meta" }); @@ -3789,12 +3980,20 @@ export class StashpadView extends ItemView { grip.draggable = draggable; if (!draggable) grip.title = color ? "Right-click to change color · drag disabled in this view mode" : "Drag disabled in this view mode"; if (color) grip.style.setProperty("--stashpad-note-color", color); - if (childCount > 0) { - const enter = meta.createSpan({ cls: "stashpad-note-enter" }); - if (color) enter.style.color = color; - setIcon(enter.createSpan({ cls: "stashpad-btn-icon" }), "corner-down-right"); - enter.createSpan({ text: ` ${childCount}` }); - enter.onclick = (e) => { e.stopPropagation(); this.navigateTo(node.id); }; + // 0.87.1: the children-count arrow + (on mobile) the task checkbox share one + // horizontal line below the timestamp — the mobile checkbox sits just to the + // LEFT of the arrow (see the desktop addTaskCheckbox call above). + const mobileTask = this.isTask(node) && Platform.isMobile; + if (childCount > 0 || mobileTask) { + const metaBottom = meta.createDiv({ cls: "stashpad-note-meta-bottom" }); + if (mobileTask) this.addTaskCheckbox(metaBottom, node); + if (childCount > 0) { + const enter = metaBottom.createSpan({ cls: "stashpad-note-enter" }); + if (color) enter.style.color = color; + setIcon(enter.createSpan({ cls: "stashpad-btn-icon" }), "corner-down-right"); + enter.createSpan({ text: ` ${childCount}` }); + enter.onclick = (e) => { e.stopPropagation(); this.navigateTo(node.id); }; + } } if (color) { row.addClass("has-color"); @@ -3831,22 +4030,51 @@ export class StashpadView extends ItemView { // to renderNoteBody as the host/anchor for the Show More toggle — // the toggle then lands beside the pencil instead of below the body. const actions = row.createDiv({ cls: "stashpad-note-actions" }); - const pencil = actions.createEl("button", { cls: "stashpad-pencil" }); - setIcon(pencil, "pencil"); - pencil.title = "Edit in new tab"; - pencil.onclick = (e) => { e.stopPropagation(); void this.openFileAtEnd(file); }; - const enterBtn = actions.createEl("button", { cls: "stashpad-pencil stashpad-enter-btn" }); - setIcon(enterBtn, "arrow-right"); - enterBtn.title = "Open in Stashpad view"; - enterBtn.onclick = (e) => { e.stopPropagation(); this.navigateTo(node.id); }; + let toggleAnchor: HTMLElement; + if (Platform.isMobile) { + // 0.87.1: ONE button on mobile — it opens the context menu, which already + // carries Focus / Open in editor / everything (the two separate focus + + // edit buttons were too cramped on a phone). Press-and-hold is avoided + // deliberately (it would fight drag-reorder / nesting). + const moreBtn = actions.createEl("button", { cls: "stashpad-pencil stashpad-note-more" }); + setIcon(moreBtn, "ellipsis-vertical"); + moreBtn.title = "Actions"; + moreBtn.onclick = (e) => { e.stopPropagation(); this.openNoteMenu(e as unknown as MouseEvent, node); }; + toggleAnchor = moreBtn; + } else { + const pencil = actions.createEl("button", { cls: "stashpad-pencil" }); + setIcon(pencil, "pencil"); + pencil.title = "Edit in new tab"; + pencil.onclick = (e) => { e.stopPropagation(); void this.openFileAtEnd(file); }; + const enterBtn = actions.createEl("button", { cls: "stashpad-pencil stashpad-enter-btn" }); + setIcon(enterBtn, "arrow-right"); + enterBtn.title = "Open in Stashpad view"; + enterBtn.onclick = (e) => { e.stopPropagation(); this.navigateTo(node.id); }; + toggleAnchor = pencil; + } // Now the actions cluster exists, render the body and route the - // Show More toggle into that cluster (anchored before the pencil). - this.renderNoteBody(bodyContent, node, { clamp: true, toggleHost: actions, toggleAnchor: pencil }); + // Show More toggle into that cluster (anchored before the first button). + this.renderNoteBody(bodyContent, node, { clamp: true, toggleHost: actions, toggleAnchor }); row.oncontextmenu = (evt) => { evt.preventDefault(); this.openNoteMenu(evt, node); }; } + /** Create + wire the task checkbox (used at the row's left edge on desktop, + * or inside the meta column on mobile). 0.87.1. */ + private addTaskCheckbox(parent: HTMLElement, node: TreeNode): void { + const cb = parent.createSpan({ cls: "stashpad-note-task-checkbox" }); + const done = this.isCompleted(node); + setIcon(cb, done ? "check-square" : "square"); + cb.title = done ? "Mark not done" : "Mark done"; + // The checkbox owns its pointer events so toggling never selects/focuses or + // navigates the row (mousedown = selection, click = handleRowClick, + // dblclick = open). + cb.addEventListener("mousedown", (e) => e.stopPropagation()); + cb.addEventListener("dblclick", (e) => { e.preventDefault(); e.stopPropagation(); }); + cb.onclick = (e) => { e.preventDefault(); e.stopPropagation(); void this.toggleCompletedForNode(node); }; + } + /** Lazy-body render cache + IntersectionObserver machinery (0.82.1). * Owns renderCache / bodyObserver / lazyBodies; see NoteBodyRenderer. */ bodyRenderer: NoteBodyRenderer; @@ -4131,7 +4359,14 @@ export class StashpadView extends ItemView { if (Platform.isMobile) { 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(); }); + ta.addEventListener("blur", () => { + document.body.classList.remove("stashpad-keyboard-open"); + keyboardTransition(); + // 0.89.0: tapping the list to dismiss the composer should leave the + // selected note visible (it may have been hidden behind the composer). + // Re-reveal after the keyboard's close animation settles the layout. + if (Platform.isMobile && this.cursorIdx >= 0) setTimeout(() => this.revealCursorRow(), 350); + }); } this.composerInputEl = ta; // Tear down any previous autocomplete (the textarea was just rebuilt @@ -4232,15 +4467,13 @@ export class StashpadView extends ItemView { destBtn.onmousedown = (e) => e.preventDefault(); destBtn.onclick = (e) => { e.preventDefault(); + // 0.85.10: pass whether the composer had focus so the picker can + // refocus it ONLY when dismissed without a pick. The old blind + // setTimeout(ta.focus, 50/250) fired while the picker was still open + // and yanked focus/keyboard back to the composer — the reported + // "cursor stays in the composer" mobile bug. const wasFocused = document.activeElement === ta; - this.openDestinationPicker(); - // Refocus the composer once the picker dialog closes (covers the - // "tap dest, then dismiss" path without losing the keyboard). - if (wasFocused) { - const refocus = () => { ta.focus(); }; - setTimeout(refocus, 50); - setTimeout(refocus, 250); - } + this.openDestinationPicker(wasFocused); }; const enterBtn = expandedGroup.createEl("button", { cls: "stashpad-composer-btn" }); @@ -4623,14 +4856,25 @@ export class StashpadView extends ItemView { private revealCursorRow(): void { const doReveal = () => { + if (this.cursorIdx < 0) return; const row = this.listEl?.querySelector(`[data-idx="${this.cursorIdx}"]`) as HTMLElement | null; if (!row || !this.listEl) return; const list = this.listEl; const lr = list.getBoundingClientRect(); const rr = row.getBoundingClientRect(); const pad = 4; - if (rr.top < lr.top + pad) list.scrollTop += rr.top - lr.top - pad; - else if (rr.bottom > lr.bottom - pad) list.scrollTop += rr.bottom - lr.bottom + pad; + const topBound = lr.top + pad; + let bottomBound = lr.bottom - pad; + // 0.89.0 mobile: while the keyboard/composer is up the list extends BEHIND + // the composer, so a row that's technically "in the list rect" can still + // be hidden. Clamp the visible bottom to just above the composer so the + // tapped/selected row scrolls into the area you can actually see. + if (Platform.isMobile && document.body.classList.contains("stashpad-keyboard-open")) { + const comp = this.viewRoot?.querySelector(".stashpad-composer") as HTMLElement | null; + if (comp) bottomBound = Math.min(bottomBound, comp.getBoundingClientRect().top - pad); + } + if (rr.top < topBound) list.scrollTop += rr.top - topBound; + else if (rr.bottom > bottomBound) list.scrollTop += rr.bottom - bottomBound; }; doReveal(); requestAnimationFrame(doReveal); @@ -4660,6 +4904,7 @@ export class StashpadView extends ItemView { if (matchBinding(e, b.toggleSplit)) { e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); this.toggleSplit(); return; } if (matchBinding(e, b.pickDestination)) { e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); this.openDestinationPicker(); return; } if (matchBinding(e, b.search)) { e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); this.openSearchModal(); return; } + if (matchBinding(e, b.commandPalette)) { e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); this.openStashpadCommandPalette(); return; } if (matchBinding(e, b.searchInParent)) { e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); this.openSearchInParentModal(); return; } // Folder switch / .stash import-export bindings — fire from anywhere // in the view (composer or list). Default chord is empty; user binds @@ -4715,6 +4960,7 @@ export class StashpadView extends ItemView { e.preventDefault(); e.stopPropagation(); this.inListPicker = null; + this.pickerEscapeAt = Date.now(); // 0.91.2: suppress the sibling collapse handler // Pin scroll across the cancel-render so dismissing the highlight near // the bottom of the list doesn't bump the viewport up. (When the user // is at the very end, ResizeObserver settle picks a slightly smaller @@ -4764,6 +5010,18 @@ export class StashpadView extends ItemView { return; } if (e.key === "Enter") { e.preventDefault(); void this.commitInListPicker(); return; } + // 0.91.0: changed your mind? Pressing the Move (picker) key while the + // in-list picker is up cancels it and opens the fuzzy move modal on the + // SAME selection — so "I meant to hit M, not O" doesn't cost you the + // picker round-trip (or the selection). Honors the user's actual Move + // binding, not a hard-coded "M". + if (matchBinding(e, getSettings().bindings.move)) { + e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); + this.inListPicker = null; + this.repaintSelectionClasses(); // drop the pick-target highlight + this.cmdMovePicker(); + return; + } return; } @@ -4829,6 +5087,10 @@ export class StashpadView extends ItemView { if (e.key === "ArrowLeft" || e.key === "Backspace") { e.preventDefault(); this.navigateUp(); return; } if (e.key === "Escape") { e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); + // 0.91.2: if the in-list picker was just cancelled by the sibling Escape + // handler (it nulled inListPicker before this ran), don't also collapse + // the multi-selection on the same keypress. + if (Date.now() - this.pickerEscapeAt < 350) return; // Multi-selection → collapse down to the FIRST note that was // added (not the last). The last-was-anchor behavior was awkward // because shift-click extends FROM the original anchor — losing @@ -5009,7 +5271,7 @@ export class StashpadView extends ItemView { this.composerInputEl?.focus(); } - openDestinationPicker(): void { + openDestinationPicker(refocusComposerOnDismiss = false): 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 @@ -5017,6 +5279,11 @@ export class StashpadView extends ItemView { // 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.85.10: `picked` tracks whether a selection was made so onClose can + // refocus the composer ONLY on dismiss (Esc / tap-out) — never while + // the picker is open (which was stealing the keyboard back to the + // composer on mobile). + let picked = false; // 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 @@ -5026,6 +5293,7 @@ export class StashpadView extends ItemView { mode: "pick", placeholder: "Send next note(s) under which note?", allowCreate: true, onPick: async (item) => { + picked = true; if (item.crossFolder) { const targetId = item.id.replace(/^cross:/, ""); // 0.76.15: DON'T switch folders. Record the cross-folder @@ -5050,6 +5318,7 @@ export class StashpadView extends ItemView { this.composerInputEl?.focus(); }, onCreate: async (q) => { + picked = true; const id = await this.createNoteUnder(q, this.focusId); if (id) { this.nextDestination = id; @@ -5060,6 +5329,13 @@ export class StashpadView extends ItemView { } }, crossFolderNotes: () => this.collectCrossFolderDestinations(), + onClose: () => { + // Only when the picker was dismissed WITHOUT a pick: hop focus (and + // the mobile keyboard) back to the composer. This fires inside the + // dismiss gesture (Esc / tap-out), so iOS re-summons the keyboard. + // On a successful pick, onPick already refocused the composer. + if (refocusComposerOnDismiss && !picked) this.composerInputEl?.focus(); + }, }).open(); } @@ -5456,7 +5732,13 @@ export class StashpadView extends ItemView { return; } const newParent = item.id; - for (const t of targets) await this.changeParent(t, newParent); + // 0.91.1: quiet per-note moves + one consolidated persistent toast. + const childCounts = new Map(targets.map((t) => [t.id, this.tree.getChildren(t.id).length])); + const movedTargets: TreeNode[] = []; + for (const t of targets) { + if (await this.changeParent(t, newParent, { silentSuccess: true })) movedTargets.push(t); + } + this.notifyBatchMove(movedTargets, newParent, childCounts); this.selection.clear(); this.render(); // 0.72.6 / 0.73.8: optionally follow the moved note(s) into // the new parent. Skip only when the destination IS the @@ -5470,7 +5752,12 @@ export class StashpadView extends ItemView { onCreate: async (q) => { const newId = await this.createNoteUnder(q, this.focusId); if (!newId) return; - for (const t of targets) await this.changeParent(t, newId); + const childCounts = new Map(targets.map((t) => [t.id, this.tree.getChildren(t.id).length])); + const movedTargets: TreeNode[] = []; + for (const t of targets) { + if (await this.changeParent(t, newId, { silentSuccess: true })) movedTargets.push(t); + } + this.notifyBatchMove(movedTargets, newId, childCounts); this.selection.clear(); this.render(); if (this.plugin.settings.autoNavOnMoveOut) this.navigateTo(newId); }, @@ -5571,12 +5858,29 @@ export class StashpadView extends ItemView { } } + // 0.86.7: this loop only wrote the canonical `parent` id — the recovery + // wikilink fields (`parentLink` on the moved notes, `children` on the old + + // new parents) were left stale, so a moved note's parentLink kept pointing + // at the OLD folder. Refresh recovery fields for BOTH folders (source: + // drop the moved note from the old parent's children; dest: rebuild the + // moved note's parentLink + the new parent's children). Deferred so the + // metadata cache reflects the move; skip-if-equal so it only writes what + // changed; honours the writeRecoveryLinks setting. + if (getSettings().writeRecoveryLinks) { + const sourceFolder = this.noteFolder; + window.setTimeout(() => { + void rebootstrapFolderFrontmatter(this.app, sourceFolder); + void rebootstrapFolderFrontmatter(this.app, targetDir); + }, 350); + } + + // 0.91.2: name the moved notes from the pre-move `sources` (they're gone + // from this folder's tree after the move, so the old tree.get() lookup + // always came back empty → "N notes" with no titles). `sources` are the + // original TreeNodes, still resolvable for titles. + const titleSummary = this.titleList(sources); // Source view loses these notes; rebuild + render. this.tree.rebuild(this.noteFolder); - const crossMovedNodes = sources.map((s) => this.tree.get(s.id)).filter((n): n is TreeNode => !!n); - const titleSummary = crossMovedNodes.length > 0 - ? this.titleList(crossMovedNodes) - : `${sources.length} note${sources.length === 1 ? "" : "s"}`; // 0.59.0: cross-folder move notice gets a Jump-to-destination action // (intra-folder moves already had one). Action switches THIS view // to the target folder + navigates to the new parent (or Home when @@ -5584,10 +5888,19 @@ export class StashpadView extends ItemView { // 0.72.1: action labels are short verbs now — the destination // context already lives in the message body. const destLabel = newParentId === ROOT_ID ? "Open home" : "Open parent"; + // 0.91.2: PERSISTENT (duration 0). A cross-folder move renames files on + // disk, so Obsidian fires its own burst of "link update" notices that bury + // a 4s toast before the user can read it or click the button. Keep ours up + // until dismissed so the Open-destination button stays reachable. + const totalNested = Math.max(0, plan.length - sources.length); + const movedSummary = sources.length === 1 + ? `Moved ${titleSummary}${totalNested > 0 ? ` and its ${totalNested} nested note${totalNested === 1 ? "" : "s"}` : ""} → \`${targetDir}\`` + : `Moved ${titleSummary}${totalNested > 0 ? ` (${totalNested} nested)` : ""} → \`${targetDir}\``; this.plugin.notifications.show({ - message: `Moved ${titleSummary} → \`${targetDir}\``, + message: movedSummary, kind: "success", category: "move", + duration: 0, affectedIds: sources.map((s) => s.id), folder: this.noteFolder, actions: [{ @@ -5654,7 +5967,11 @@ export class StashpadView extends ItemView { start = up !== start ? up : this.nextPickableIdx(start, 1); } this.inListPicker = { activeIdx: start }; - new Notice("Arrows to pick parent, Enter confirms, Esc cancels."); + // 0.91.0: surface the "switch to the full move picker" shortcut, using the + // user's actual Move binding (default M) so the hint stays accurate. + const moveBind = getSettings().bindings.move; + const moveLabel = humanCombo(moveBind.primary || moveBind.secondary || "M"); + new Notice(`Arrows to pick parent, Enter confirms, ${moveLabel} for the full picker, Esc cancels.`); // Preserve scroll position across the activation render — the highlight is // a visual cue only; we shouldn't jump the viewport to reveal it. const keepScroll = this.listEl?.scrollTop ?? 0; @@ -5672,7 +5989,16 @@ export class StashpadView extends ItemView { this.inListPicker = null; if (!target) { this.render(); return; } const targets = this.getActionTargets().filter((n) => n.id !== target.id); - for (const t of targets) await this.changeParent(t, target.id); + // 0.91.1: move quietly (no per-note success toasts), then emit ONE + // consolidated persistent notification with a Jump-to-destination button. + // Capture child counts BEFORE moving so the summary is accurate even if a + // metadata-driven tree rebuild races the notification. + const childCounts = new Map(targets.map((t) => [t.id, this.tree.getChildren(t.id).length])); + const movedTargets: TreeNode[] = []; + for (const t of targets) { + if (await this.changeParent(t, target.id, { silentSuccess: true })) movedTargets.push(t); + } + this.notifyBatchMove(movedTargets, target.id, childCounts); // 0.72.6: optional auto-navigate INTO the destination parent so // the user follows their moved note. Skips the select-in-place // flow below because navigateTo rebuilds the view for the new @@ -6699,6 +7025,18 @@ export class StashpadView extends ItemView { * 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>(); + /** 0.85.1: task-TAG OVERRIDE per path — the exact analogue of + * `completedState`, for the SAME reason. The task TOGGLE read tag-ness + * (`isTaskTagged`) straight from the live metadataCache, both to DECIDE the + * toggle direction and to RENDER. On a slow/network drive the cache reparse + * lags well past the write, so the immediate `render()` showed stale state + * AND the next toggle re-read "not yet tagged" → re-toggled the same way (a + * no-op), so the change only landed on the *next* press ("n+1"). Our own + * writes set this authoritatively before the render; the "changed" listener + * resyncs it once the cache is fresh. Holds tag-ness (what `isTaskTagged` + * returns); `isTask` builds on it (+ the bare `completed` field). Reads fall + * back to the live cache when there's no override. */ + private taskTaggedState = new Map<string, boolean>(); private isCompleted(node: TreeNode): boolean { if (!node.file) return false; @@ -6708,6 +7046,13 @@ export class StashpadView extends ItemView { return !!fm?.completed; } + /** Tag-ness of a frontmatter shape: the `task` tag or the legacy `task: true` + * boolean (NOT the bare `completed` field — that's `isTask`, not tagged). */ + private taggedFromFm(fm: any): boolean { + if (!fm) return false; + return fmHasTag(fm, "task") || fm.task === true; + } + /** 0.76.1: open the due-date picker for the action targets and write * (or clear) the `due` frontmatter. Setting a due date also marks * the note(s) as a task so they surface in the Tasks panel. Bound @@ -6735,7 +7080,7 @@ export class StashpadView extends ItemView { * undo. Setting a date also flips `task: true`; clearing leaves the * task flag intact (clearing a due ≠ "no longer a task"). */ private async applyDue(targets: TreeNode[], iso: string | null, assignees: Array<{ id: string; name: string }> = []): Promise<void> { - const prior: { id: StashpadId; path: string; due: unknown; task: unknown; assignedTo: unknown; assignedBy: unknown }[] = []; + const prior: { id: StashpadId; path: string; due: unknown; task: unknown; assignedTo: unknown; assignedBy: unknown; wasTagged: boolean }[] = []; const changedIds: StashpadId[] = []; // 0.78.1: who is doing the assigning (the local user) — stamped as // assignedBy so the "assigned by me" filter works. Null if the user @@ -6750,7 +7095,8 @@ export class StashpadView extends ItemView { for (const t of targets) { if (!t.file) continue; const fm = this.app.metadataCache.getFileCache(t.file)?.frontmatter as any; - prior.push({ id: t.id, path: t.file.path, due: fm?.due, task: fm?.task, assignedTo: fm?.assignedTo, assignedBy: fm?.assignedBy }); + const wasTagged = this.isTaskTagged(t); + prior.push({ id: t.id, path: t.file.path, due: fm?.due, task: fm?.task, assignedTo: fm?.assignedTo, assignedBy: fm?.assignedBy, wasTagged }); await this.app.fileManager.processFrontMatter(t.file, (m) => { if (iso === null) delete m.due; else { m.due = iso; m.task = true; } @@ -6765,6 +7111,10 @@ export class StashpadView extends ItemView { delete m.assignedBy; } }); + // 0.85.1: a due date or an assignment makes it a task; clearing leaves + // task-ness unchanged. Set the override so the checkbox shows now, not n+1. + const becomesTask = iso !== null || assignLinks.length > 0; + this.taskTaggedState.set(t.file.path, becomesTask || wasTagged); changedIds.push(t.id); } this.render(); @@ -6794,6 +7144,7 @@ export class StashpadView extends ItemView { if (p.assignedTo === undefined) delete m.assignedTo; else m.assignedTo = p.assignedTo; if (p.assignedBy === undefined) delete m.assignedBy; else m.assignedBy = p.assignedBy; }); + this.taskTaggedState.set(p.path, p.wasTagged); // 0.85.1 } this.tree.rebuild(folder); this.render(); @@ -6829,12 +7180,13 @@ export class StashpadView extends ItemView { await this.plugin.ensureAuthorStubFor(this.noteFolder, a.id, a.name); } const assignLinks = assignees.map((a) => this.plugin.authorRefFor(this.noteFolder, a.id, a.name)); - const prior: { path: string; assignedTo: unknown; assignedBy: unknown; task: unknown }[] = []; + const prior: { path: string; assignedTo: unknown; assignedBy: unknown; task: unknown; wasTagged: boolean }[] = []; const changedIds: StashpadId[] = []; for (const t of targets) { if (!t.file) continue; const fm = this.app.metadataCache.getFileCache(t.file)?.frontmatter as any; - prior.push({ path: t.file.path, assignedTo: fm?.assignedTo, assignedBy: fm?.assignedBy, task: fm?.task }); + const wasTagged = this.isTaskTagged(t); + prior.push({ path: t.file.path, assignedTo: fm?.assignedTo, assignedBy: fm?.assignedBy, task: fm?.task, wasTagged }); await this.app.fileManager.processFrontMatter(t.file, (m) => { if (assignLinks.length > 0) { m.assignedTo = assignLinks; @@ -6845,6 +7197,8 @@ export class StashpadView extends ItemView { delete m.assignedBy; } }); + // 0.85.1: assigning makes it a task; clearing leaves task-ness unchanged. + this.taskTaggedState.set(t.file.path, assignLinks.length > 0 || wasTagged); changedIds.push(t.id); } this.render(); @@ -6874,6 +7228,7 @@ export class StashpadView extends ItemView { if (p.assignedBy === undefined) delete m.assignedBy; else m.assignedBy = p.assignedBy; if (p.task === undefined) delete m.task; else m.task = p.task; }); + this.taskTaggedState.set(p.path, p.wasTagged); // 0.85.1 } this.tree.rebuild(folder); this.render(); @@ -6888,9 +7243,12 @@ export class StashpadView extends ItemView { * (unfilled box), true = done (checked box). */ private isTask(node: TreeNode): boolean { if (!node.file) return false; + // Tag-ness from the override (fresh on slow drives), OR the bare `completed` + // field (panel inclusion) read live — that part still self-corrects via the + // metadataCache repaint, but it doesn't gate the task toggle. + if (this.isTaskTagged(node)) return true; const fm = this.app.metadataCache.getFileCache(node.file)?.frontmatter as any; - if (!fm) return false; - return fmHasTag(fm, "task") || fm.task === true || fm.completed !== undefined; + return fm?.completed !== undefined; } /** 0.76.3: mark/unmark the selection (or cursor row, or focused @@ -6910,13 +7268,13 @@ export class StashpadView extends ItemView { const makeTask = targets.some((t) => !this.isTaskTagged(t)); // Snapshot the full prior frontmatter shape we touch (tags + // completed + legacy task) so undo restores exactly. - const prior: { id: StashpadId; path: string; tags: unknown; completed: unknown; task: unknown }[] = []; + const prior: { id: StashpadId; path: string; tags: unknown; completed: unknown; task: unknown; wasTagged: boolean }[] = []; const changedIds: StashpadId[] = []; for (const t of targets) { if (!t.file) continue; const wasTagged = this.isTaskTagged(t); const fmNow = this.app.metadataCache.getFileCache(t.file)?.frontmatter as any; - prior.push({ id: t.id, path: t.file.path, tags: fmNow?.tags, completed: fmNow?.completed, task: fmNow?.task }); + prior.push({ id: t.id, path: t.file.path, tags: fmNow?.tags, completed: fmNow?.completed, task: fmNow?.task, wasTagged }); if (wasTagged === makeTask) continue; let nowCompleted = false; await this.app.fileManager.processFrontMatter(t.file, (m: any) => { @@ -6933,6 +7291,7 @@ export class StashpadView extends ItemView { } }); this.completedState.set(t.file.path, nowCompleted); // 0.76.11 + this.taskTaggedState.set(t.file.path, makeTask); // 0.85.1 changedIds.push(t.id); } this.render(); @@ -6966,6 +7325,8 @@ export class StashpadView extends ItemView { if (p.completed === undefined) delete m.completed; else m.completed = p.completed; if (p.task === undefined) delete m.task; else m.task = p.task; }); + this.completedState.set(p.path, !!p.completed); // 0.85.1: pre-cache-event + this.taskTaggedState.set(p.path, p.wasTagged); } this.tree.rebuild(folder); this.render(); @@ -6977,17 +7338,22 @@ export class StashpadView extends ItemView { for (const p of prior) { const f = this.app.vault.getAbstractFileByPath(p.path) as TFile | null; if (!f) continue; + let nowCompleted = false; await this.app.fileManager.processFrontMatter(f, (m: any) => { if (makeTask) { fmAddTag(m, "task"); if (m.completed === undefined) m.completed = false; + nowCompleted = m.completed === true; delete m.task; } else { fmRemoveTag(m, "task"); delete m.completed; delete m.task; + nowCompleted = false; } }); + this.completedState.set(p.path, nowCompleted); // 0.85.1 + this.taskTaggedState.set(p.path, makeTask); } this.tree.rebuild(folder); this.render(); @@ -7027,9 +7393,10 @@ export class StashpadView extends ItemView { * panel inclusion. */ private isTaskTagged(node: TreeNode): boolean { if (!node.file) return false; + const override = this.taskTaggedState.get(node.file.path); + if (override !== undefined) return override; const fm = this.app.metadataCache.getFileCache(node.file)?.frontmatter as any; - if (!fm) return false; - return fmHasTag(fm, "task") || fm.task === true; + return this.taggedFromFm(fm); } /** Return the per-note color from frontmatter (already validated as a @@ -8226,12 +8593,24 @@ export class StashpadView extends ItemView { private async syncAttachmentsFrontmatter(file: TFile): Promise<void> { const raw = await this.app.vault.cachedRead(file); const body = this.stripFrontmatter(raw); - const found = this.extractAttachments(body); + const found = this.extractAttachments(body); // bare paths from ![[...]] const fm = this.app.metadataCache.getFileCache(file)?.frontmatter; - const current: string[] = Array.isArray(fm?.attachments) ? (fm!.attachments as string[]) : []; - const same = current.length === found.length && current.every((v, i) => v === found[i]); + const currentRaw = Array.isArray(fm?.attachments) ? (fm!.attachments as unknown[]) : []; + // 0.85.9: compare by BARE PATH so a canonical `[[link]]` that already + // matches the body embed counts as equal. Comparing raw strings made the + // link form (written by import + the rebootstrap convert pass) look + // "different" from the plain body-derived paths, so this sync rewrote it to + // plain text every time the note was touched — silently reverting + // convertAttachmentsToLinks (the "do it then revert it" bug). + const currentPaths = currentRaw + .filter((x): x is string => typeof x === "string") + .map((x) => attachmentLinkPath(x)); + const same = currentPaths.length === found.length && currentPaths.every((v, i) => v === found[i]); if (same) return; - await this.app.fileManager.processFrontMatter(file, (front) => { front.attachments = found; }); + // Write the canonical `[[link]]` form so this sync agrees with import + + // convert and the three never fight over format. + const links = found.map((p) => toAttachmentLink(p)); + await this.app.fileManager.processFrontMatter(file, (front) => { front.attachments = links; }); } // --- Helpers --- @@ -8429,6 +8808,9 @@ export class StashpadView extends ItemView { menu.addItem((it: any) => it.setTitle("Delete").setIcon("trash").onClick(async () => { await this.deleteNote(node); })); + menu.addSeparator(); + // 0.87.0: "more commands" escape hatch (parity with the ⚡ menu). + menu.addItem((it: any) => it.setTitle("More commands…").setIcon("terminal").onClick(() => this.openCommandPalette())); menu.showAtMouseEvent(evt); } @@ -8827,8 +9209,8 @@ export class StashpadView extends ItemView { }); } - private async changeParent(node: TreeNode, newParent: StashpadId, opts: { record?: boolean; quiet?: boolean } = { record: true }): Promise<void> { - if (!node.file) return; + private async changeParent(node: TreeNode, newParent: StashpadId, opts: { record?: boolean; quiet?: boolean; silentSuccess?: boolean } = { record: true }): Promise<boolean> { + if (!node.file) return false; const file = node.file; const oldParent = node.parent; // 0.58.2: surface a warning when a move is a no-op so the user knows @@ -8848,7 +9230,7 @@ export class StashpadView extends ItemView { folder: this.noteFolder, }); } - return; + return false; } if (newParent === node.id) { if (!opts.quiet) { @@ -8860,7 +9242,7 @@ export class StashpadView extends ItemView { folder: this.noteFolder, }); } - return; + return false; } // 0.63.0 ouroboros: refuse to nest a note under one of its own // descendants — that creates a cycle in the parent chain and @@ -8870,7 +9252,7 @@ export class StashpadView extends ItemView { if (!opts.quiet) { this.offerSwapForDescendantMove(node, newParent); } - return; + return false; } const movedAuthorIds = this.authorship.collectAuthorIds([node]); await this.app.fileManager.processFrontMatter(file, (fm) => { fm.parent = newParent; }); @@ -8888,7 +9270,7 @@ export class StashpadView extends ItemView { this.cursorIdx = -1; this.pendingFocusIds = null; } - if (!opts.quiet) { + if (!opts.quiet && !opts.silentSuccess) { const dest = this.tree.get(newParent); const destTitle = dest ? this.titleForNode(dest) : "(root)"; this.plugin.notifications.show({ @@ -8975,6 +9357,48 @@ export class StashpadView extends ItemView { }, }); } + return true; + } + + /** 0.91.1: ONE consolidated, persistent notification for a batch reparent — + * replaces the per-note "Reparented …" toast spam. For a single moved note + * it calls out its child count ("…and its N children"); for several it + * summarises the count (+ nested total). Persistent (duration 0) when there's + * a destination to jump to, so the "Jump to destination" button is always + * clickable; root moves use the default duration (no jump target). */ + private notifyBatchMove(targets: TreeNode[], newParent: StashpadId, childCounts: Map<StashpadId, number>): void { + if (!targets.length) return; + const destNode = this.tree.get(newParent); + const destLabel = newParent === ROOT_ID + ? "Home" + : `"${destNode ? this.titleForNode(destNode) : "the destination"}"`; + const kidsOf = (t: TreeNode): number => childCounts.get(t.id) ?? 0; + let message: string; + if (targets.length === 1) { + const title = this.titleForNode(targets[0]); + const kids = kidsOf(targets[0]); + message = kids > 0 + ? `Moved "${title}" and its ${kids} ${kids === 1 ? "child" : "children"} → ${destLabel}` + : `Moved "${title}" → ${destLabel}`; + } else { + const nested = targets.reduce((sum, t) => sum + kidsOf(t), 0); + message = nested > 0 + ? `Moved ${targets.length} notes (${nested} nested) → ${destLabel}` + : `Moved ${targets.length} notes → ${destLabel}`; + } + this.plugin.notifications.show({ + message, + kind: "success", + category: "move", + duration: newParent === ROOT_ID ? undefined : 0, // persistent when there's a Jump target + affectedIds: targets.map((t) => t.id), + affectedAuthorIds: this.authorship.collectAuthorIds(targets), + folder: this.noteFolder, + actions: newParent === ROOT_ID ? [] : [{ + label: "Jump to destination", + onClick: () => this.navigateTo(newParent), + }], + }); } } diff --git a/styles.css b/styles.css index 529dae6..71d4ecc 100644 --- a/styles.css +++ b/styles.css @@ -1024,6 +1024,14 @@ } .stashpad-note-enter { cursor: pointer; color: var(--text-accent); } .stashpad-note-enter:hover { text-decoration: underline; } +/* 0.87.1: children-count arrow + (mobile) task checkbox on one line */ +.stashpad-note-meta-bottom { display: flex; align-items: center; gap: 6px; } +/* mobile: checkbox moves into the meta column, so the row drops the desktop + leading checkbox grid column — frees width so the single action button + doesn't wrap. */ +.is-mobile .stashpad-note.is-task { grid-template-columns: auto 1fr auto; } +.is-mobile .stashpad-note-meta-bottom .stashpad-note-task-checkbox { margin: 0; padding: 2px; } +.is-mobile .stashpad-note-meta-bottom .stashpad-note-task-checkbox svg { width: 18px; height: 18px; } .stashpad-note-body { min-width: 0; word-wrap: break-word; } .stashpad-note-body > :first-child { margin-top: 0; } @@ -2126,6 +2134,15 @@ .stashpad-export-field { display: flex; flex-direction: column; gap: 4px; } .stashpad-export-label { font-size: var(--font-ui-small); color: var(--text-muted); } .stashpad-export-name { width: 100%; } +/* 0.85.7: password field + inline Copy button */ +.stashpad-export-pw-row { + display: flex; + align-items: center; + gap: 6px; + margin-bottom: 6px; +} +.stashpad-export-pw-row .stashpad-export-name { flex: 1; min-width: 0; } +.stashpad-export-copy { flex: 0 0 auto; } .stashpad-export-preview { margin-top: 8px; font-family: var(--font-monospace); @@ -2168,6 +2185,63 @@ color: var(--text-faint); margin-top: 2px; } +.stashpad-export-pw-suite.is-weak { color: var(--text-warning); } + +/* 0.85.4: password strength meter (nudge), generate/show row, remember toggle */ +.stashpad-export-strength { + display: flex; + align-items: center; + gap: 8px; + margin-top: 6px; + visibility: hidden; +} +.stashpad-strength-bar { + display: flex; + gap: 3px; + flex: 0 0 auto; +} +.stashpad-strength-seg { + width: 26px; + height: 5px; + border-radius: 3px; + background: var(--background-modifier-border); +} +/* color the lit segments by the bar's data-level (0 weak … 3 strong) */ +.stashpad-strength-bar[data-level="0"] .stashpad-strength-seg.is-on { background: var(--text-error); } +.stashpad-strength-bar[data-level="1"] .stashpad-strength-seg.is-on { background: var(--text-warning); } +.stashpad-strength-bar[data-level="2"] .stashpad-strength-seg.is-on { background: var(--color-yellow); } +.stashpad-strength-bar[data-level="3"] .stashpad-strength-seg.is-on { background: var(--text-success); } +.stashpad-strength-label { + font-size: var(--font-ui-smaller); + color: var(--text-muted); +} +.stashpad-export-genrow { + display: flex; + gap: 8px; + margin-top: 8px; +} +.stashpad-export-show { flex: 0 0 auto; } +.stashpad-export-remember { + display: flex; + align-items: flex-start; + gap: 6px; + margin-top: 8px; +} +.stashpad-export-remember label { + font-size: var(--font-ui-smaller); + color: var(--text-muted); + line-height: 1.3; +} +.stashpad-export-remember-note { + margin-top: 4px; + padding: 6px 8px; + border-left: 2px solid var(--text-warning); + background: var(--background-modifier-hover); + border-radius: 4px; + font-size: var(--font-ui-smaller); + color: var(--text-muted); + line-height: 1.35; +} .stashpad-export-error { color: var(--text-error); font-size: var(--font-ui-small); @@ -3998,3 +4072,148 @@ font-size: var(--font-ui-smaller); text-align: center; } + +/* ============================================================ + Folder panel (0.86.0) — left-sidebar folder picker: + pinned notes (top) + Stashpad folders (bottom), each scrollable. + ============================================================ */ +.stashpad-folderpanel-root { + display: flex; + flex-direction: column; + height: 100%; + min-height: 0; + padding: 0; +} +.stashpad-folderpanel-section { + display: flex; + flex-direction: column; + min-height: 0; + flex: 1 1 50%; /* split the panel in half */ +} +/* draggable divider between Pinned and Folders */ +.stashpad-folderpanel-divider { + flex: 0 0 auto; + height: 9px; + display: flex; + align-items: center; + justify-content: center; + cursor: row-resize; + border-top: 1px solid var(--background-modifier-border); + touch-action: none; /* let pointer drag work on touch */ +} +.stashpad-folderpanel-divider:hover { background: var(--background-modifier-hover); } +.stashpad-folderpanel-divider-grip { + width: 28px; + height: 3px; + border-radius: 2px; + background: var(--background-modifier-border); +} +.stashpad-folderpanel-divider:hover .stashpad-folderpanel-divider-grip { background: var(--text-faint); } +body.stashpad-folderpanel-resizing { cursor: row-resize; user-select: none; } +.is-mobile .stashpad-folderpanel-divider { height: 16px; } /* easier to grab */ +.stashpad-folderpanel-heading { + flex: 0 0 auto; + padding: 8px 10px 4px; + font-size: var(--font-ui-smaller); + font-weight: var(--font-semibold); + text-transform: uppercase; + letter-spacing: 0.04em; + color: var(--text-faint); +} +.stashpad-folderpanel-list { + flex: 1 1 auto; + min-height: 0; + overflow-y: auto; + padding: 0 6px 8px; +} +.stashpad-folderpanel-row { + display: flex; + align-items: center; + gap: 7px; + width: 100%; + padding: 2px 8px; + min-height: 0; + line-height: 1.3; + border-radius: 5px; + background: transparent; + border: none; + box-shadow: none; + text-align: left; + cursor: pointer; + color: var(--text-normal); + font-size: var(--font-ui-small); +} +.stashpad-folderpanel-row:hover { background: var(--background-modifier-hover); } +.stashpad-folderpanel-row-icon { display: inline-flex; flex: 0 0 auto; color: var(--text-muted); } +.stashpad-folderpanel-row-icon svg { width: 15px; height: 15px; } +.stashpad-folderpanel-row-label { + flex: 1 1 auto; + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.stashpad-folderpanel-row-sub { + flex: 0 0 auto; + color: var(--text-faint); + font-size: var(--font-ui-smaller); + max-width: 38%; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +/* open indicator dot */ +.stashpad-folderpanel-dot { + flex: 0 0 auto; + width: 7px; + height: 7px; + border-radius: 50%; + background: transparent; + border: 1px solid var(--background-modifier-border); +} +.stashpad-folderpanel-folder-row.is-open .stashpad-folderpanel-dot { + background: var(--interactive-accent); + border-color: var(--interactive-accent); +} +.stashpad-folderpanel-folder-row.is-open .stashpad-folderpanel-row-label { font-weight: var(--font-medium); } +/* per-row action buttons (reveal / open in new tab) */ +.stashpad-folderpanel-actions { + flex: 0 0 auto; + display: flex; + gap: 2px; + opacity: 0; + transition: opacity 80ms ease; +} +.stashpad-folderpanel-folder-row:hover .stashpad-folderpanel-actions { opacity: 1; } +.stashpad-folderpanel-iconbtn { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 2px; + height: 22px; + width: 22px; + background: transparent; + border: none; + box-shadow: none; + border-radius: 4px; + color: var(--text-muted); + cursor: pointer; +} +.stashpad-folderpanel-iconbtn:hover { background: var(--background-modifier-hover); color: var(--text-normal); } +.stashpad-folderpanel-iconbtn svg { width: 15px; height: 15px; } +.stashpad-folderpanel-empty { + padding: 8px 10px; + color: var(--text-faint); + font-size: var(--font-ui-smaller); +} +/* rename modal */ +.stashpad-folderpanel-rename-input { width: 100%; margin-bottom: 12px; } +.stashpad-folderpanel-rename-footer { display: flex; justify-content: flex-end; gap: 8px; } + +/* mobile: a touch more height for tap targets, always-visible row actions */ +.is-mobile .stashpad-folderpanel-row { padding: 5px 10px; } +.is-mobile .stashpad-folderpanel-actions { opacity: 1; } +.is-mobile .stashpad-folderpanel-iconbtn { height: 28px; width: 28px; } + +/* 0.88.1: by-author select inside the View popover */ +.stashpad-view-author-select { margin-left: 8px; max-width: 160px; font-size: var(--font-ui-smaller); }