diff --git a/main.js b/main.js index 8433e30..77a59b4 100644 --- a/main.js +++ b/main.js @@ -1,178 +1,178 @@ -"use strict";var po=Object.defineProperty;var nc=Object.getOwnPropertyDescriptor;var oc=Object.getOwnPropertyNames;var ac=Object.prototype.hasOwnProperty;var de=(d,r)=>()=>(d&&(r=d(d=0)),r);var Ji=(d,r)=>{for(var e in r)po(d,e,{get:r[e],enumerable:!0})},rc=(d,r,e,t)=>{if(r&&typeof r=="object"||typeof r=="function")for(let i of oc(r))!ac.call(d,i)&&i!==e&&po(d,i,{get:()=>r[i],enumerable:!(t=nc(r,i))||t.enumerable});return d};var lc=d=>rc(po({},"__esModule",{value:!0}),d);var Co={};Ji(Co,{freshId:()=>mo,newId:()=>he});function he(d=6){let r="",e=new Uint8Array(d);crypto.getRandomValues(e);for(let t=0;t{"use strict";$a="abcdefghijkmnpqrstuvwxyz23456789"});function Bo(d){return Array.isArray(d)?d.filter(r=>typeof r=="string"):typeof d=="string"?d.split(/[,\s]+/).filter(Boolean):[]}function di(d,r){let e=r.replace(/^#/,"");return Bo(d?.tags).some(t=>t.replace(/^#/,"")===e)}function yo(d,r){let e=r.replace(/^#/,""),t=Bo(d.tags);t.some(i=>i.replace(/^#/,"")===e)||t.push(e),d.tags=t}function wo(d,r){let e=r.replace(/^#/,""),t=Bo(d.tags).filter(i=>i.replace(/^#/,"")!==e);t.length?d.tags=t:delete d.tags}function za(d){return Os.has(d)||Ya.has(d)}function Dt(d){return`${(d||"").replace(/\/+$/,"")}/archive`}function Ks(d){return(d||"").replace(/\/+$/,"").split("/").slice(1).includes("archive")}function qt(d){return d.split("/").some((r,e)=>Os.has(r)||e>0&&Ya.has(r))}function Va(d){return d.split("/").some(r=>r==="_archive"||r===".archive")}function tt(d){let r=(d??"").trim();return!r||/^\[\[.*\]\]$/.test(r)?r:`[[${r}]]`}function Jt(d){let r=(d??"").trim(),e=r.match(/^\[\[(.*)\]\]$/);return e&&(r=e[1]),r.split("|")[0].split("#")[0].split("^")[0].trim()}function Wa(d){let r=d.match(/\.([^./]+)$/);return!!r&&Ac.has(r[1].toLowerCase())}function Xa(d,r){if(!Array.isArray(r))return!1;for(let e of r){let t=(e??"").trim();if(t){if(t.length>2&&t.startsWith("/")&&t.endsWith("/"))try{if(new RegExp(t.slice(1,-1)).test(d))return!0}catch{}else if(d===t||d.startsWith(t.endsWith("/")?t:t+"/"))return!0}}return!1}function qs(d,r){let e=d.toLowerCase().split(/\s+/).filter(Boolean);if(e.length===0)return!0;let t=r.toLowerCase();return e.every(i=>t.includes(i))}function gt(d){if(typeof d!="string")return null;let r=d.replace(/^\[\[/,"").replace(/\]\]$/,""),[e,t]=r.split("|"),i=e.match(/_authors\/(.+?)-([a-z0-9]{4,12})(?:\.md)?$/i);if(!i)return null;let s=i[2],n=(t??"").trim()||i[1].replace(/-/g," ").trim();return{id:s,name:n}}function xt(d){let r=d?.assignedTo,e=Array.isArray(r)?r:r!=null?[r]:[],t=[];for(let i of e){let s=gt(i);s&&t.push(s)}return t}var z,St,bt,Kt,li,ci,S,et,Os,Ya,Ac,ce=de(()=>{"use strict";z="stashpad-view",St="stashpad-panels",bt="stashpad-folder-panel",Kt="stashpad-detail",li="stashpad-trash",ci="stashpad-aggregate",S="__root__";et=["id","parent","created","modified","attachments","position","author","contributors","parentLink","children","due","assignedTo","assignedBy","pinned","pinnedAt","listPinned","listPinnedAt","imported","okfParent","okfChildren"],Os=new Set(["_attachments","_authors","_exports","_imports","_processed","_archive",".archive"]),Ya=new Set(["archive","trash"]);Ac=new Set(["edtz"])});function Js(d){let r=(d.dateDisplayTimezone||"").trim();return r?{timeZone:r}:{}}function ut(d,r){try{return new Intl.DateTimeFormat(void 0,r).format(new Date(d))}catch{let{timeZone:e,...t}=r;return new Intl.DateTimeFormat(void 0,t).format(new Date(d))}}function it(d,r){let e=Js(r);switch(r.dateDisplayFormat??"locale"){case"iso":return Za(d,r,!0);case"us":return ut(d,{...e,month:"numeric",day:"numeric",year:"numeric",hour:"numeric",minute:"2-digit"});case"eu":return ut(d,{...e,day:"numeric",month:"numeric",year:"numeric",hour:"2-digit",minute:"2-digit",hourCycle:"h23"});case"long":return ut(d,{...e,dateStyle:"full",timeStyle:"short"});case"locale":default:return ut(d,{...e,dateStyle:"medium",timeStyle:"short"})}}function Nt(d,r){let e=Js(r);switch(r.dateDisplayFormat??"locale"){case"iso":return Za(d,r,!1);case"us":return ut(d,{...e,month:"numeric",day:"numeric",year:"numeric"});case"eu":return ut(d,{...e,day:"numeric",month:"numeric",year:"numeric"});case"long":return ut(d,{...e,dateStyle:"full"});case"locale":default:{let t=new Date,i=new Date(d).getFullYear()===t.getFullYear();return ut(d,i?{...e,month:"short",day:"numeric"}:{...e,month:"short",day:"numeric",year:"numeric"})}}}function Ai(d,r){let e=Js(r),t=r.dateDisplayFormat==="iso"||r.dateDisplayFormat==="eu";return ut(d,{...e,hour:t?"2-digit":"numeric",minute:"2-digit",...t?{hourCycle:"h23"}:{}})}function Za(d,r,e){let t=Js(r),i=new Intl.DateTimeFormat("en-CA",{...t,year:"numeric",month:"2-digit",day:"2-digit",...e?{hour:"2-digit",minute:"2-digit",hourCycle:"h23"}:{}}).formatToParts(new Date(d)),s=o=>i.find(a=>a.type===o)?.value??"",n=`${s("year")}-${s("month")}-${s("day")}`;return e?`${n} ${s("hour")}:${s("minute")}`:n}var Tt=de(()=>{"use strict"});function $t(d,r){let e=d.replace(/\r\n/g,` +"use strict";var fo=Object.defineProperty;var lc=Object.getOwnPropertyDescriptor;var cc=Object.getOwnPropertyNames;var dc=Object.prototype.hasOwnProperty;var de=(A,r)=>()=>(A&&(r=A(A=0)),r);var Yi=(A,r)=>{for(var e in r)fo(A,e,{get:r[e],enumerable:!0})},Ac=(A,r,e,t)=>{if(r&&typeof r=="object"||typeof r=="function")for(let i of cc(r))!dc.call(A,i)&&i!==e&&fo(A,i,{get:()=>r[i],enumerable:!(t=lc(r,i))||t.enumerable});return A};var hc=A=>Ac(fo({},"__esModule",{value:!0}),A);var wo={};Yi(wo,{freshId:()=>yo,newId:()=>he});function he(A=6){let r="",e=new Uint8Array(A);crypto.getRandomValues(e);for(let t=0;t{"use strict";Va="abcdefghijkmnpqrstuvwxyz23456789"});function Eo(A){return Array.isArray(A)?A.filter(r=>typeof r=="string"):typeof A=="string"?A.split(/[,\s]+/).filter(Boolean):[]}function Ai(A,r){let e=r.replace(/^#/,"");return Eo(A?.tags).some(t=>t.replace(/^#/,"")===e)}function vo(A,r){let e=r.replace(/^#/,""),t=Eo(A.tags);t.some(i=>i.replace(/^#/,"")===e)||t.push(e),A.tags=t}function Qo(A,r){let e=r.replace(/^#/,""),t=Eo(A.tags).filter(i=>i.replace(/^#/,"")!==e);t.length?A.tags=t:delete A.tags}function Xa(A){return Js.has(A)||Wa.has(A)}function Dt(A){return`${(A||"").replace(/\/+$/,"")}/archive`}function qs(A){return(A||"").replace(/\/+$/,"").split("/").slice(1).includes("archive")}function Jt(A){return A.split("/").some((r,e)=>Js.has(r)||e>0&&Wa.has(r))}function Za(A){return A.split("/").some(r=>r==="_archive"||r===".archive")}function tt(A){let r=(A??"").trim();return!r||/^\[\[.*\]\]$/.test(r)?r:`[[${r}]]`}function qt(A){let r=(A??"").trim(),e=r.match(/^\[\[(.*)\]\]$/);return e&&(r=e[1]),r.split("|")[0].split("#")[0].split("^")[0].trim()}function ja(A){let r=A.match(/\.([^./]+)$/);return!!r&&uc.has(r[1].toLowerCase())}function _a(A,r){if(!Array.isArray(r))return!1;for(let e of r){let t=(e??"").trim();if(t){if(t.length>2&&t.startsWith("/")&&t.endsWith("/"))try{if(new RegExp(t.slice(1,-1)).test(A))return!0}catch{}else if(A===t||A.startsWith(t.endsWith("/")?t:t+"/"))return!0}}return!1}function $s(A,r){let e=A.toLowerCase().split(/\s+/).filter(Boolean);if(e.length===0)return!0;let t=r.toLowerCase();return e.every(i=>t.includes(i))}function gt(A){if(typeof A!="string")return null;let r=A.replace(/^\[\[/,"").replace(/\]\]$/,""),[e,t]=r.split("|"),i=e.match(/_authors\/(.+?)-([a-z0-9]{4,12})(?:\.md)?$/i);if(!i)return null;let s=i[2],n=(t??"").trim()||i[1].replace(/-/g," ").trim();return{id:s,name:n}}function xt(A){let r=A?.assignedTo,e=Array.isArray(r)?r:r!=null?[r]:[],t=[];for(let i of e){let s=gt(i);s&&t.push(s)}return t}var $,St,bt,Kt,ci,di,S,et,Js,Wa,uc,ce=de(()=>{"use strict";$="stashpad-view",St="stashpad-panels",bt="stashpad-folder-panel",Kt="stashpad-detail",ci="stashpad-trash",di="stashpad-aggregate",S="__root__";et=["id","parent","created","modified","attachments","position","author","contributors","parentLink","children","due","assignedTo","assignedBy","pinned","pinnedAt","listPinned","listPinnedAt","imported","okfParent","okfChildren"],Js=new Set(["_attachments","_authors","_exports","_imports","_processed","_archive",".archive"]),Wa=new Set(["archive","trash"]);uc=new Set(["edtz"])});function Ys(A){let r=(A.dateDisplayTimezone||"").trim();return r?{timeZone:r}:{}}function ut(A,r){try{return new Intl.DateTimeFormat(void 0,r).format(new Date(A))}catch{let{timeZone:e,...t}=r;return new Intl.DateTimeFormat(void 0,t).format(new Date(A))}}function it(A,r){let e=Ys(r);switch(r.dateDisplayFormat??"locale"){case"iso":return er(A,r,!0);case"us":return ut(A,{...e,month:"numeric",day:"numeric",year:"numeric",hour:"numeric",minute:"2-digit"});case"eu":return ut(A,{...e,day:"numeric",month:"numeric",year:"numeric",hour:"2-digit",minute:"2-digit",hourCycle:"h23"});case"long":return ut(A,{...e,dateStyle:"full",timeStyle:"short"});case"locale":default:return ut(A,{...e,dateStyle:"medium",timeStyle:"short"})}}function Nt(A,r){let e=Ys(r);switch(r.dateDisplayFormat??"locale"){case"iso":return er(A,r,!1);case"us":return ut(A,{...e,month:"numeric",day:"numeric",year:"numeric"});case"eu":return ut(A,{...e,day:"numeric",month:"numeric",year:"numeric"});case"long":return ut(A,{...e,dateStyle:"full"});case"locale":default:{let t=new Date,i=new Date(A).getFullYear()===t.getFullYear();return ut(A,i?{...e,month:"short",day:"numeric"}:{...e,month:"short",day:"numeric",year:"numeric"})}}}function hi(A,r){let e=Ys(r),t=r.dateDisplayFormat==="iso"||r.dateDisplayFormat==="eu";return ut(A,{...e,hour:t?"2-digit":"numeric",minute:"2-digit",...t?{hourCycle:"h23"}:{}})}function er(A,r,e){let t=Ys(r),i=new Intl.DateTimeFormat("en-CA",{...t,year:"numeric",month:"2-digit",day:"2-digit",...e?{hour:"2-digit",minute:"2-digit",hourCycle:"h23"}:{}}).formatToParts(new Date(A)),s=o=>i.find(a=>a.type===o)?.value??"",n=`${s("year")}-${s("month")}-${s("day")}`;return e?`${n} ${s("hour")}:${s("minute")}`:n}var Tt=de(()=>{"use strict"});function $t(A,r){let e=A.replace(/\r\n/g,` `);if(r==="lines")return e.split(` `).map(n=>n.trim()).filter(Boolean);if(r==="paragraphs")return e.split(/\n[ \t]*\n+/).map(n=>n.trim()).filter(Boolean);let t=[],i=[],s=n=>/^#{1,6}\s/.test(n);for(let n of e.split(` `))s(n)&&i.some(o=>o.trim())&&(t.push(i.join(` `).trim()),i=[]),i.push(n);return i.some(n=>n.trim())&&t.push(i.join(` -`).trim()),t.filter(Boolean)}function De(d,r,e){d.empty();try{(0,ja.setIcon)(d,r)}catch{}let t=d.querySelector("svg");t&&t.querySelector("path, line, circle, rect, polyline, polygon, ellipse")||(d.empty(),d.createSpan({cls:"stashpad-icon-fallback",text:e}))}function _a(d){if(d instanceof Element&&d.closest(".modal, .modal-container, .suggestion-container, .menu, .prompt"))return!0;let r=new Set([document]);d instanceof Element&&d.ownerDocument&&r.add(d.ownerDocument);for(let e of r)if(e.body?.querySelector(".modal-bg")||e.body?.querySelector(".modal-container .modal")||e.body?.querySelector(".suggestion-container")||e.body?.querySelector(".menu.mod-active"))return!0;return!1}function er(d){let r=[],e=/^([ \t]*)(`{3,})[ \t]*([^\n`]*)\n([\s\S]*?)\n\1\2[ \t]*$/gm,t;for(;(t=e.exec(d))!=null;)r.push({lang:t[3].trim(),code:t[4]});return r}function Xi(d){return d.split("/").map(r=>r.split(" ").map(e=>e&&/^[a-z]/.test(e)?e[0].toUpperCase()+e.slice(1):e).join(" ")).join("/")}function tr(d,r,e){let t=new Set(r),i=d.filter(n=>!t.has(n)),s=d.findIndex(n=>t.has(n));if(s<0)return d.slice();switch(e){case"top":return[...r,...i];case"bottom":return[...i,...r];case"up":{let n=Math.max(0,s-1),o=i.slice();return o.splice(n,0,...r),o}case"down":{let n=(()=>{let c=-1;return d.forEach((A,h)=>{t.has(A)&&(c=h)}),c})(),o=0;for(let c=0;c0){let n=t[i-1];return(!/[a-z0-9]/.test(n)?600:500)-Math.min(i,99)}let s=0;for(let n=0;n({t,s:hc(e,t.raw)})).filter(t=>t.s>=0).sort((t,i)=>i.s-t.s||i.t.count-t.t.count||t.t.label.localeCompare(i.t.label)).map(t=>t.t):r}var ja,hi,Yt,zt,Zi=de(()=>{"use strict";ja=require("obsidian"),hi={lines:"Each line",paragraphs:"Paragraphs (blank line)",headings:"Headings"};Yt="__stashpad:tagged__",zt="__stashpad:untagged__"});function pc(d,r){return d===0?0:d>12?d>=24?0:d:r==="am"?d===12?0:d:d===12?12:d+12}function $s(d,r){d.addClass("stashpad-when-pop-time");let e=r.seedPeriod,t=d.createDiv({cls:"stashpad-when-time-display"}),i=t.createEl("input",{cls:"stashpad-when-time-field",attr:{type:"text",inputmode:"numeric",maxlength:"2"}});i.value=String(r.seedH),t.createSpan({cls:"stashpad-when-time-colon",text:":"});let s=t.createEl("input",{cls:"stashpad-when-time-field",attr:{type:"text",inputmode:"numeric",maxlength:"2"}});s.value=String(r.seedM).padStart(2,"0");let n=t.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 l=()=>{o.toggleClass("is-active",e==="am"),a.toggleClass("is-active",e==="pm")};l(),o.addEventListener("mousedown",B=>B.preventDefault()),a.addEventListener("mousedown",B=>B.preventDefault()),o.addEventListener("click",B=>{B.preventDefault(),e="am",l()}),a.addEventListener("click",B=>{B.preventDefault(),e="pm",l()});let c=i;i.addEventListener("focus",()=>{c=i,i.select()}),s.addEventListener("focus",()=>{c=s,s.select()});let A=()=>{let E=(parseInt(i.value||"0",10)||0)>12;o.toggleClass("is-disabled",E),a.toggleClass("is-disabled",E),o.disabled=E,a.disabled=E},h=B=>{let E=B.value.replace(/\D/g,"").slice(0,2);if(B.value=E,E===""){B===i&&A();return}let y=parseInt(E,10),v=B===i?24:59;y>v&&(B.value=String(v)),B===i&&A()};for(let B of[i,s])B.addEventListener("input",()=>h(B));A();let p=()=>{let B=parseInt(i.value,10),E=Number.isNaN(B)?12:B,y=parseInt(s.value||"0",10)||0,v=E>12||E===0;r.onFinalize({hours24:pc(E,e),minutes:y,raw:{hh:E,mm:y,period:e,is24:v}}),r.close()};r.setOnEnter?.(p);let f=[i,s,o,a],u=(B,E)=>{let y=f.indexOf(B);if(y===-1)return;let v=(y+E+f.length)%f.length;f[v].focus()},g=B=>{B.addEventListener("keydown",E=>{E.key==="Enter"?(E.preventDefault(),E.stopPropagation(),p()):E.key==="Escape"?(E.preventDefault(),E.stopPropagation(),r.close()):E.key==="Tab"&&(E.preventDefault(),E.stopPropagation(),u(B,E.shiftKey?-1:1))})},I=d.createDiv({cls:"stashpad-when-time-pad"}),m=["1","2","3","4","5","6","7","8","9","backspace","0","insert"],C=null;for(let B of m){let E=I.createEl("button",{cls:"stashpad-when-time-padbtn"});E.type="button",B==="backspace"?(0,sr.setIcon)(E,"delete"):B==="insert"?(E.setText("OK"),C=E):E.setText(B),B==="insert"&&E.addClass("is-go"),E.addEventListener("mousedown",y=>y.preventDefault()),E.addEventListener("click",y=>{if(y.preventDefault(),B==="insert"){p();return}if(B==="backspace"){c.value=c.value.slice(0,-1),h(c),c.focus();return}let v=c.selectionStart===0&&c.selectionEnd===c.value.length&&c.value.length>0,Q=2,w=v||c.value.length>=Q?B:c.value+B;c.value=w,h(c),c.focus(),c.setSelectionRange(c.value.length,c.value.length),c===i&&c.value.length>=Q&&(s.focus(),s.select())})}C&&f.push(C);for(let B of f)g(B);i.focus(),i.select()}function nr(d){let{hh:r,mm:e,period:t,is24:i}=d.raw;return i?`${r}:${String(e).padStart(2,"0")}`:`${r}:${String(e).padStart(2,"0")}${t}`}var sr,vo=de(()=>{"use strict";sr=require("obsidian")});function ar(d){let r=Math.floor(4294967296/d)*d,e=new Uint32Array(1),t;do crypto.getRandomValues(e),t=e[0];while(t>=r);return t%d}function Qo(d=5){let r=[];for(let e=0;e=1&&s.every(a=>/^[a-zA-Z]+$/.test(a))&&(i=Math.min(i,s.length*11)),gc.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 uc(d){let r=2166136261;for(let e=0;e>>0).toString(16).padStart(8,"0")}function pi(d){let r="stashpad-",e=uc(d),t=64-r.length-1-e.length,i=d.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,Math.max(0,t)).replace(/-+$/g,"");return`${r}${i}-${e}`}var or,gc,Ys=de(()=>{"use strict";or="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).filter((d,r,e)=>e.indexOf(d)===r);gc=new Set(["password","passw0rd","password1","123456","12345678","123456789","qwerty","abc123","letmein","welcome","admin","iloveyou","monkey","dragon","sunshine","princess","football","baseball","trustno1","000000","111111","secret"])});function xe(d,r=st){let e=r instanceof Set?r:new Set(r.map(o=>o.toLowerCase())),t=(d.split(/\r?\n/).find(o=>o.trim().length>0)??"").trim();if(!t)return"Untitled";let s=t.replace(/['‘-‛ʼ]/g,"").replace(/[^A-Za-z0-9\s]+/g," ").split(/\s+/).filter(o=>o&&!e.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 Ne(d,r){return`${d}-${r}.md`}function nt(d){let r=d.match(/-([abcdefghijkmnpqrstuvwxyz23456789]{6})$/);return r?r[1]:null}function ji(d){return typeof d=="string"&&/^[abcdefghijkmnpqrstuvwxyz23456789]{6}$/.test(d)}function zs(d,r){let e=d.lastIndexOf(".");return e>0?`${d.slice(0,e)}-${r}${d.slice(e)}`:`${d}-${r}`}function rr(d){let r=d.match(/^([0-9a-z]{7,9})-(.+)$/);if(!r)return null;let e=parseInt(r[1],36);return!Number.isFinite(e)||e<142e10||e>Date.now()+864e5?null:{stamp:r[1],rest:r[2]}}var st,gi=de(()=>{"use strict";st=["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 Xs={};Ji(Xs,{JdBuildConfirmModal:()=>_i,buildJdIndexNotes:()=>So,buildJdIndexPreview:()=>Vs,buildJdPreviewNotice:()=>Ws,scanForJdNotes:()=>ui});function ko(d,r){if(/^\d+-\d+$/.test(d))return null;if(d.includes(".")){let t=d.split(".").slice(0,-1).join(".");return r.has(t)?t:ko(t,r)}if(/^\d+$/.test(d)){let e=parseInt(d,10);for(let t of r){let i=t.match(/^(\d+)-(\d+)$/);if(!i)continue;let s=parseInt(i[1],10),n=parseInt(i[2],10);if(e>=s&&e<=n)return t}return null}return null}function ui(d,r,e){let t=d.vault.getMarkdownFiles(),i=Ic(t,e),s=e.jdIndexIncludeStashpadFolders===!0,n=s?new Set:new Set(r.discoverStashpadFolders()),o=f=>s?!1:Array.from(n).some(u=>f===u||f.startsWith(u+"/")),a=[],l=[],c=[];for(let f of i){let u=f.parent?.path?.replace(/\/+$/,"")??"";if(o(u)){c.push(f);continue}let g=f.basename.match(lr);g?a.push({prefix:g[1],segments:g[1].split("."),title:g[2],file:f,folder:null}):l.push(f)}let A=(e.jdIndexScope??"vault")==="folder"?(e.jdIndexScopeFolder??"").trim().replace(/^\/+|\/+$/g,""):"",h=f=>{let u=f.path.replace(/\/+$/,"");if(!(A&&u&&u!==A&&!u.startsWith(A+"/"))){if(u&&!o(u)){let g=f.name.match(lr);g&&a.push({prefix:g[1],segments:g[1].split("."),title:g[2],file:null,folder:f})}}for(let g of f.children)g instanceof Ee.TFolder&&h(g)};h(d.vault.getRoot());let p=e.jdIndexSort??"natural";return a.sort((f,u)=>mc(f,u,p)),{indexed:a,nonIndex:l,skippedStashpadNotes:c}}async function Vs(d,r,e){let t=bo(e.jdIndexStashpadFolder??"");if(!t)return{...ui(d,r,e),previewPath:null,error:"no-dest"};let i=ui(d,r,e),s=fc(d,t);if(!s)return{...i,previewPath:null,error:"no-home"};let n=Cc(i.indexed,i.nonIndex,i.skippedStashpadNotes),a=(await d.vault.read(s)).match(/^---\r?\n[\s\S]*?\r?\n---\r?\n/),l=a?`${a[0]}${n}`:n;return await d.vault.modify(s,l),{...i,previewPath:s.path}}function fc(d,r){let e=d.vault.getAbstractFileByPath(r);if(!(e instanceof Ee.TFolder))return null;for(let t of e.children){if(!(t instanceof Ee.TFile)||t.extension!=="md")continue;if((d.metadataCache.getFileCache(t)?.frontmatter??{}).id===S)return t}return null}async function So(d,r,e){let t=bo(e.jdIndexStashpadFolder??"");if(!t)return{created:0,updated:0,skipped:0,destFolder:"",error:"no-dest"};if(!new Set(r.discoverStashpadFolders()).has(t))return{created:0,updated:0,skipped:0,destFolder:t,error:"dest-not-stashpad"};let s=ui(d,r,e),n=new Map;for(let I of s.indexed)n.set(I.prefix,I);for(let I of s.indexed)if(I.prefix.includes("."))for(let m=1;m{l.push(I);for(let m of a.get(I)??[])c(m)};for(let I of o)c(I);let A=new Map,h=d.vault.getAbstractFileByPath(t);if(h instanceof Ee.TFolder)for(let I of h.children){if(!(I instanceof Ee.TFile)||I.extension!=="md")continue;let m=d.metadataCache.getFileCache(I)?.frontmatter??{};typeof m.jdPrefix=="string"&&A.set(m.jdPrefix,I)}let p=new Map,f=0,u=0,g=0;for(let I of l){let m=n.get(I)??null,C=ko(I,new Set(n.keys())),B=C?p.get(C)??S:S,E=m?`${I} ${m.title}`:I,y=m?.file?`[[${m.file.basename}]]`:"",v=y?`${y} +`).trim()),t.filter(Boolean)}function De(A,r,e){A.empty();try{(0,tr.setIcon)(A,r)}catch{}let t=A.querySelector("svg");t&&t.querySelector("path, line, circle, rect, polyline, polygon, ellipse")||(A.empty(),A.createSpan({cls:"stashpad-icon-fallback",text:e}))}function ir(A){if(A instanceof Element&&A.closest(".modal, .modal-container, .suggestion-container, .menu, .prompt"))return!0;let r=new Set([document]);A instanceof Element&&A.ownerDocument&&r.add(A.ownerDocument);for(let e of r)if(e.body?.querySelector(".modal-bg")||e.body?.querySelector(".modal-container .modal")||e.body?.querySelector(".suggestion-container")||e.body?.querySelector(".menu.mod-active"))return!0;return!1}function sr(A){let r=[],e=/^([ \t]*)(`{3,})[ \t]*([^\n`]*)\n([\s\S]*?)\n\1\2[ \t]*$/gm,t;for(;(t=e.exec(A))!=null;)r.push({lang:t[3].trim(),code:t[4]});return r}function ji(A){return A.split("/").map(r=>r.split(" ").map(e=>e&&/^[a-z]/.test(e)?e[0].toUpperCase()+e.slice(1):e).join(" ")).join("/")}function nr(A,r,e){let t=new Set(r),i=A.filter(n=>!t.has(n)),s=A.findIndex(n=>t.has(n));if(s<0)return A.slice();switch(e){case"top":return[...r,...i];case"bottom":return[...i,...r];case"up":{let n=Math.max(0,s-1),o=i.slice();return o.splice(n,0,...r),o}case"down":{let n=(()=>{let c=-1;return A.forEach((d,h)=>{t.has(d)&&(c=h)}),c})(),o=0;for(let c=0;c0){let n=t[i-1];return(!/[a-z0-9]/.test(n)?600:500)-Math.min(i,99)}let s=0;for(let n=0;n({t,s:fc(e,t.raw)})).filter(t=>t.s>=0).sort((t,i)=>i.s-t.s||i.t.count-t.t.count||t.t.label.localeCompare(i.t.label)).map(t=>t.t):r}var tr,pi,Yt,zt,_i=de(()=>{"use strict";tr=require("obsidian"),pi={lines:"Each line",paragraphs:"Paragraphs (blank line)",headings:"Headings"};Yt="__stashpad:tagged__",zt="__stashpad:untagged__"});function Ic(A,r){return A===0?0:A>12?A>=24?0:A:r==="am"?A===12?0:A:A===12?12:A+12}function zs(A,r){A.addClass("stashpad-when-pop-time");let e=r.seedPeriod,t=A.createDiv({cls:"stashpad-when-time-display"}),i=t.createEl("input",{cls:"stashpad-when-time-field",attr:{type:"text",inputmode:"numeric",maxlength:"2"}});i.value=String(r.seedH),t.createSpan({cls:"stashpad-when-time-colon",text:":"});let s=t.createEl("input",{cls:"stashpad-when-time-field",attr:{type:"text",inputmode:"numeric",maxlength:"2"}});s.value=String(r.seedM).padStart(2,"0");let n=t.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 l=()=>{o.toggleClass("is-active",e==="am"),a.toggleClass("is-active",e==="pm")};l(),o.addEventListener("mousedown",B=>B.preventDefault()),a.addEventListener("mousedown",B=>B.preventDefault()),o.addEventListener("click",B=>{B.preventDefault(),e="am",l()}),a.addEventListener("click",B=>{B.preventDefault(),e="pm",l()});let c=i;i.addEventListener("focus",()=>{c=i,i.select()}),s.addEventListener("focus",()=>{c=s,s.select()});let d=()=>{let E=(parseInt(i.value||"0",10)||0)>12;o.toggleClass("is-disabled",E),a.toggleClass("is-disabled",E),o.disabled=E,a.disabled=E},h=B=>{let E=B.value.replace(/\D/g,"").slice(0,2);if(B.value=E,E===""){B===i&&d();return}let y=parseInt(E,10),v=B===i?24:59;y>v&&(B.value=String(v)),B===i&&d()};for(let B of[i,s])B.addEventListener("input",()=>h(B));d();let p=()=>{let B=parseInt(i.value,10),E=Number.isNaN(B)?12:B,y=parseInt(s.value||"0",10)||0,v=E>12||E===0;r.onFinalize({hours24:Ic(E,e),minutes:y,raw:{hh:E,mm:y,period:e,is24:v}}),r.close()};r.setOnEnter?.(p);let f=[i,s,o,a],u=(B,E)=>{let y=f.indexOf(B);if(y===-1)return;let v=(y+E+f.length)%f.length;f[v].focus()},g=B=>{B.addEventListener("keydown",E=>{E.key==="Enter"?(E.preventDefault(),E.stopPropagation(),p()):E.key==="Escape"?(E.preventDefault(),E.stopPropagation(),r.close()):E.key==="Tab"&&(E.preventDefault(),E.stopPropagation(),u(B,E.shiftKey?-1:1))})},I=A.createDiv({cls:"stashpad-when-time-pad"}),m=["1","2","3","4","5","6","7","8","9","backspace","0","insert"],C=null;for(let B of m){let E=I.createEl("button",{cls:"stashpad-when-time-padbtn"});E.type="button",B==="backspace"?(0,ar.setIcon)(E,"delete"):B==="insert"?(E.setText("OK"),C=E):E.setText(B),B==="insert"&&E.addClass("is-go"),E.addEventListener("mousedown",y=>y.preventDefault()),E.addEventListener("click",y=>{if(y.preventDefault(),B==="insert"){p();return}if(B==="backspace"){c.value=c.value.slice(0,-1),h(c),c.focus();return}let v=c.selectionStart===0&&c.selectionEnd===c.value.length&&c.value.length>0,Q=2,w=v||c.value.length>=Q?B:c.value+B;c.value=w,h(c),c.focus(),c.setSelectionRange(c.value.length,c.value.length),c===i&&c.value.length>=Q&&(s.focus(),s.select())})}C&&f.push(C);for(let B of f)g(B);i.focus(),i.select()}function rr(A){let{hh:r,mm:e,period:t,is24:i}=A.raw;return i?`${r}:${String(e).padStart(2,"0")}`:`${r}:${String(e).padStart(2,"0")}${t}`}var ar,Fo=de(()=>{"use strict";ar=require("obsidian")});function cr(A){let r=Math.floor(4294967296/A)*A,e=new Uint32Array(1),t;do crypto.getRandomValues(e),t=e[0];while(t>=r);return t%A}function So(A=5){let r=[];for(let e=0;e=1&&s.every(a=>/^[a-zA-Z]+$/.test(a))&&(i=Math.min(i,s.length*11)),mc.has(A.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 Cc(A){let r=2166136261;for(let e=0;e>>0).toString(16).padStart(8,"0")}function gi(A){let r="stashpad-",e=Cc(A),t=64-r.length-1-e.length,i=A.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,Math.max(0,t)).replace(/-+$/g,"");return`${r}${i}-${e}`}var lr,mc,Vs=de(()=>{"use strict";lr="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).filter((A,r,e)=>e.indexOf(A)===r);mc=new Set(["password","passw0rd","password1","123456","12345678","123456789","qwerty","abc123","letmein","welcome","admin","iloveyou","monkey","dragon","sunshine","princess","football","baseball","trustno1","000000","111111","secret"])});function xe(A,r=st){let e=r instanceof Set?r:new Set(r.map(o=>o.toLowerCase())),t=(A.split(/\r?\n/).find(o=>o.trim().length>0)??"").trim();if(!t)return"Untitled";let s=t.replace(/['‘-‛ʼ]/g,"").replace(/[^A-Za-z0-9\s]+/g," ").split(/\s+/).filter(o=>o&&!e.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 Ne(A,r){return`${A}-${r}.md`}function nt(A){let r=A.match(/-([abcdefghijkmnpqrstuvwxyz23456789]{6})$/);return r?r[1]:null}function es(A){return typeof A=="string"&&/^[abcdefghijkmnpqrstuvwxyz23456789]{6}$/.test(A)}function Ws(A,r){let e=A.lastIndexOf(".");return e>0?`${A.slice(0,e)}-${r}${A.slice(e)}`:`${A}-${r}`}function dr(A){let r=A.match(/^([0-9a-z]{7,9})-(.+)$/);if(!r)return null;let e=parseInt(r[1],36);return!Number.isFinite(e)||e<142e10||e>Date.now()+864e5?null:{stamp:r[1],rest:r[2]}}var st,ui=de(()=>{"use strict";st=["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 js={};Yi(js,{JdBuildConfirmModal:()=>ts,buildJdIndexNotes:()=>xo,buildJdIndexPreview:()=>Xs,buildJdPreviewNotice:()=>Zs,scanForJdNotes:()=>fi});function Do(A,r){if(/^\d+-\d+$/.test(A))return null;if(A.includes(".")){let t=A.split(".").slice(0,-1).join(".");return r.has(t)?t:Do(t,r)}if(/^\d+$/.test(A)){let e=parseInt(A,10);for(let t of r){let i=t.match(/^(\d+)-(\d+)$/);if(!i)continue;let s=parseInt(i[1],10),n=parseInt(i[2],10);if(e>=s&&e<=n)return t}return null}return null}function fi(A,r,e){let t=A.vault.getMarkdownFiles(),i=yc(t,e),s=e.jdIndexIncludeStashpadFolders===!0,n=s?new Set:new Set(r.discoverStashpadFolders()),o=f=>s?!1:Array.from(n).some(u=>f===u||f.startsWith(u+"/")),a=[],l=[],c=[];for(let f of i){let u=f.parent?.path?.replace(/\/+$/,"")??"";if(o(u)){c.push(f);continue}let g=f.basename.match(Ar);g?a.push({prefix:g[1],segments:g[1].split("."),title:g[2],file:f,folder:null}):l.push(f)}let d=(e.jdIndexScope??"vault")==="folder"?(e.jdIndexScopeFolder??"").trim().replace(/^\/+|\/+$/g,""):"",h=f=>{let u=f.path.replace(/\/+$/,"");if(!(d&&u&&u!==d&&!u.startsWith(d+"/"))){if(u&&!o(u)){let g=f.name.match(Ar);g&&a.push({prefix:g[1],segments:g[1].split("."),title:g[2],file:null,folder:f})}}for(let g of f.children)g instanceof Ee.TFolder&&h(g)};h(A.vault.getRoot());let p=e.jdIndexSort??"natural";return a.sort((f,u)=>wc(f,u,p)),{indexed:a,nonIndex:l,skippedStashpadNotes:c}}async function Xs(A,r,e){let t=No(e.jdIndexStashpadFolder??"");if(!t)return{...fi(A,r,e),previewPath:null,error:"no-dest"};let i=fi(A,r,e),s=Bc(A,t);if(!s)return{...i,previewPath:null,error:"no-home"};let n=Ec(i.indexed,i.nonIndex,i.skippedStashpadNotes),a=(await A.vault.read(s)).match(/^---\r?\n[\s\S]*?\r?\n---\r?\n/),l=a?`${a[0]}${n}`:n;return await A.vault.modify(s,l),{...i,previewPath:s.path}}function Bc(A,r){let e=A.vault.getAbstractFileByPath(r);if(!(e instanceof Ee.TFolder))return null;for(let t of e.children){if(!(t instanceof Ee.TFile)||t.extension!=="md")continue;if((A.metadataCache.getFileCache(t)?.frontmatter??{}).id===S)return t}return null}async function xo(A,r,e){let t=No(e.jdIndexStashpadFolder??"");if(!t)return{created:0,updated:0,skipped:0,destFolder:"",error:"no-dest"};if(!new Set(r.discoverStashpadFolders()).has(t))return{created:0,updated:0,skipped:0,destFolder:t,error:"dest-not-stashpad"};let s=fi(A,r,e),n=new Map;for(let I of s.indexed)n.set(I.prefix,I);for(let I of s.indexed)if(I.prefix.includes("."))for(let m=1;m{l.push(I);for(let m of a.get(I)??[])c(m)};for(let I of o)c(I);let d=new Map,h=A.vault.getAbstractFileByPath(t);if(h instanceof Ee.TFolder)for(let I of h.children){if(!(I instanceof Ee.TFile)||I.extension!=="md")continue;let m=A.metadataCache.getFileCache(I)?.frontmatter??{};typeof m.jdPrefix=="string"&&d.set(m.jdPrefix,I)}let p=new Map,f=0,u=0,g=0;for(let I of l){let m=n.get(I)??null,C=Do(I,new Set(n.keys())),B=C?p.get(C)??S:S,E=m?`${I} ${m.title}`:I,y=m?.file?`[[${m.file.basename}]]`:"",v=y?`${y} `:`${E} -`,Q=A.get(I);if(Q){try{let w=null;await d.fileManager.processFrontMatter(Q,R=>{R.jdPrefix=I,B&&(R.parent=B),(!R.id||typeof R.id!="string")&&(R.id=r.mintNoteId()),R.created||(R.created=new Date().toISOString()),R.attachments||(R.attachments=[]),w=R.id});let D=(await d.vault.read(Q)).match(/^---\r?\n[\s\S]*?\r?\n---\r?\n/),H=D?`${D[0]}${v}`:v;await d.vault.modify(Q,H),w&&p.set(I,w),u++}catch(w){console.error("[stashpad] buildJdIndexNotes: update failed",w),g++}continue}try{let w=r.mintNoteId();p.set(I,w);let F=xe(E,e.slugStopWords),D=Ne(F,w),H=`${t}/${D}`,R=["---",`id: ${w}`,`parent: ${B}`,`created: "${new Date().toISOString()}"`,"attachments: []",`jdPrefix: "${I}"`,"---",""].join(` -`);await d.vault.create(H,R+v),f++}catch(w){console.error("[stashpad] buildJdIndexNotes: create failed for",I,w),g++}}return{created:f,updated:u,skipped:g,destFolder:t}}function bo(d){return(d||"").trim().replace(/^\/+|\/+$/g,"")}function Ic(d,r){if((r.jdIndexScope??"vault")==="vault")return d;let e=bo(r.jdIndexScopeFolder??"");return e?d.filter(t=>{let i=t.parent?.path?.replace(/\/+$/,"")??"";return i===e||i.startsWith(e+"/")}):d}function mc(d,r,e){if(e==="created"){let t=d.file?.stat?.ctime??0,i=r.file?.stat?.ctime??0;if(t!==i)return t-i}return dr(d.segments,r.segments)}function cr(d,r){let e=d.match(/^(\d+)-(\d+)$/),t=r.match(/^(\d+)-(\d+)$/),i=e?[e[1]]:d.split("."),s=t?[t[1]]:r.split(".");return dr(i,s)}function dr(d,r){let e=Math.min(d.length,r.length);for(let t=0;t{s.set(o,a);for(let l of t.get(o)??[])n(l,a+1)};for(let o of i)n(o,0);return{roots:i,childrenOf:t,depthOf:s}}function Cc(d,r,e){let t=[],i=s=>"#".repeat(Math.min(s+1,6));if(t.push("# Indexed"),t.push(""),d.length===0){let s=e.length>0?`_No notes matched. ${e.length} note${e.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._";t.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 A=1;A{let A=s.get(c),h=a.get(c)??0,p=" ".repeat(h),f=i(h),u=A?.folder?` ${A.title} _(folder)_`:(A?.file,"");A?.file?t.push(`${p}- ${f} [[${A.file.basename}|${A.prefix} ${A.title}]]`):A?.folder?t.push(`${p}- ${f} ${A.prefix}${u}`):t.push(`${p}- ${f} ${c}`);for(let g of o.get(c)??[])l(g)};for(let c of n)l(c)}if(r.length>0){t.push(""),t.push(`# Non-indexed (${r.length})`),t.push(""),t.push("_These notes don't match the JD-prefix convention. Rename them to ` ` and re-run to include them._"),t.push("");for(let s of r)t.push(`- # [[${s.basename}]] \xB7 \`${s.path}\``)}if(e.length>0){let s=new Map;for(let o of e){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]));t.push(""),t.push(`# Excluded folders (${n.length})`),t.push(""),t.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._`),t.push("");for(let[o,a]of n)t.push(`- # All ${a} file${a===1?"":"s"} in \`${o||"(vault root)"}\``)}return t.join(` +`,Q=d.get(I);if(Q){try{let w=null;await A.fileManager.processFrontMatter(Q,R=>{R.jdPrefix=I,B&&(R.parent=B),(!R.id||typeof R.id!="string")&&(R.id=r.mintNoteId()),R.created||(R.created=new Date().toISOString()),R.attachments||(R.attachments=[]),w=R.id});let D=(await A.vault.read(Q)).match(/^---\r?\n[\s\S]*?\r?\n---\r?\n/),H=D?`${D[0]}${v}`:v;await A.vault.modify(Q,H),w&&p.set(I,w),u++}catch(w){console.error("[stashpad] buildJdIndexNotes: update failed",w),g++}continue}try{let w=r.mintNoteId();p.set(I,w);let k=xe(E,e.slugStopWords),D=Ne(k,w),H=`${t}/${D}`,R=["---",`id: ${w}`,`parent: ${B}`,`created: "${new Date().toISOString()}"`,"attachments: []",`jdPrefix: "${I}"`,"---",""].join(` +`);await A.vault.create(H,R+v),f++}catch(w){console.error("[stashpad] buildJdIndexNotes: create failed for",I,w),g++}}return{created:f,updated:u,skipped:g,destFolder:t}}function No(A){return(A||"").trim().replace(/^\/+|\/+$/g,"")}function yc(A,r){if((r.jdIndexScope??"vault")==="vault")return A;let e=No(r.jdIndexScopeFolder??"");return e?A.filter(t=>{let i=t.parent?.path?.replace(/\/+$/,"")??"";return i===e||i.startsWith(e+"/")}):A}function wc(A,r,e){if(e==="created"){let t=A.file?.stat?.ctime??0,i=r.file?.stat?.ctime??0;if(t!==i)return t-i}return pr(A.segments,r.segments)}function hr(A,r){let e=A.match(/^(\d+)-(\d+)$/),t=r.match(/^(\d+)-(\d+)$/),i=e?[e[1]]:A.split("."),s=t?[t[1]]:r.split(".");return pr(i,s)}function pr(A,r){let e=Math.min(A.length,r.length);for(let t=0;t<e;t++){let i=A[t],s=r[t],n=/^\d+$/.test(i),o=/^\d+$/.test(s);if(n&&o){let a=parseInt(i,10)-parseInt(s,10);if(a!==0)return a}else{if(n&&!o)return-1;if(!n&&o)return 1;{let a=i.localeCompare(s,void 0,{numeric:!0,sensitivity:"base"});if(a!==0)return a}}}return A.length-r.length}function gr(A){let r=new Set(A.keys()),e=new Map,t=new Map;for(let o of r){let a=Do(o,r);if(e.set(o,a),a!==null){let l=t.get(a)??[];l.push(o),t.set(a,l)}}let i=[];for(let o of r)e.get(o)===null&&i.push(o);i.sort(hr);for(let o of t.values())o.sort(hr);let s=new Map,n=(o,a)=>{s.set(o,a);for(let l of t.get(o)??[])n(l,a+1)};for(let o of i)n(o,0);return{roots:i,childrenOf:t,depthOf:s}}function Ec(A,r,e){let t=[],i=s=>"#".repeat(Math.min(s+1,6));if(t.push("# Indexed"),t.push(""),A.length===0){let s=e.length>0?`_No notes matched. ${e.length} note${e.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._";t.push(s)}else{let s=new Map;for(let c of A)s.set(c.prefix,c);for(let c of A)if(c.prefix.includes("."))for(let d=1;d<c.segments.length;d++){let h=c.segments.slice(0,d).join(".");s.has(h)||s.set(h,null)}let{roots:n,childrenOf:o,depthOf:a}=gr(s),l=c=>{let d=s.get(c),h=a.get(c)??0,p=" ".repeat(h),f=i(h),u=d?.folder?` ${d.title} _(folder)_`:(d?.file,"");d?.file?t.push(`${p}- ${f} [[${d.file.basename}|${d.prefix} ${d.title}]]`):d?.folder?t.push(`${p}- ${f} ${d.prefix}${u}`):t.push(`${p}- ${f} ${c}`);for(let g of o.get(c)??[])l(g)};for(let c of n)l(c)}if(r.length>0){t.push(""),t.push(`# Non-indexed (${r.length})`),t.push(""),t.push("_These notes don't match the JD-prefix convention. Rename them to `<prefix> <title>` and re-run to include them._"),t.push("");for(let s of r)t.push(`- # [[${s.basename}]] \xB7 \`${s.path}\``)}if(e.length>0){let s=new Map;for(let o of e){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]));t.push(""),t.push(`# Excluded folders (${n.length})`),t.push(""),t.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._`),t.push("");for(let[o,a]of n)t.push(`- # All ${a} file${a===1?"":"s"} in \`${o||"(vault root)"}\``)}return t.join(` `)+` -`}function Ws(d,r){let e=document.createDocumentFragment();e.createEl("div",{text:"Home note updated"}).setCssStyles({fontWeight:"600",marginBottom:"6px"});let i=e.createEl("ul");i.setCssStyles({margin:"0 0 8px 0",paddingLeft:"18px"}),i.createEl("li",{text:`${r.indexed.length} indexed`}),i.createEl("li",{text:`${r.nonIndex.length+r.skippedStashpadNotes.length} excluded`});let s=e.createEl("button",{text:"Open",cls:"mod-cta"});s.setCssStyles({padding:"2px 10px",fontSize:"var(--font-ui-smaller)"});let n;return s.onclick=async o=>{if(o.stopPropagation(),r.previewPath){let a=d.vault.getAbstractFileByPath(r.previewPath);a instanceof Ee.TFile&&await d.workspace.getLeaf("tab").openFile(a)}n?.hide()},n=new Ee.Notice(e,0),n}var Ee,lr,_i,es=de(()=>{"use strict";Ee=require("obsidian");gi();ce();lr=/^(\d+-\d+|\d+|[A-Za-z0-9]+(?:\.[A-Za-z0-9]+)+)\s+(.+)$/;_i=class extends Ee.Modal{constructor(e,t,i,s,n){super(e);this.plugin=t;this.settings=i;this.indexedCount=s;this.onBuild=n;this.LARGE_BUILD=50;this.previewRan=!1;this.previewPath=null}onOpen(){let{contentEl:e,titleEl:t}=this,i=!this.settings.jdIndexHasBuilt,s=this.indexedCount>this.LARGE_BUILD;t.setText(i?"Build JD index \u2014 first time?":"Build JD index");let n=this.settings.jdIndexStashpadFolder,o=e.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."),e.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&&e.createEl("p",{cls:"setting-item-description"}).setText(`\u2713 Preview written to home note (${this.previewPath}). Open it before building if you haven't.`);let l=new Ee.Setting(e);(i||s)&&l.addButton(c=>{c.setButtonText(this.previewRan?"Re-run preview":"Run preview first"),c.setCta(),c.onClick(async()=>{try{let A=await Vs(this.app,this.plugin,this.settings);if(A.error==="no-dest"){new Ee.Notice("Set a Designated Stashpad folder for Index first.",5e3),this.close();return}if(A.error==="no-home"){new Ee.Notice(`"${this.settings.jdIndexStashpadFolder}" has no Stashpad home note. Open the folder in Stashpad first.`,7e3),this.close();return}this.previewRan=!0,this.previewPath=A.previewPath,Ws(this.app,A),this.contentEl.empty(),this.titleEl.empty(),this.onOpen()}catch(A){new Ee.Notice(`Preview failed: ${A?.message??A}`,8e3)}})}),l.addButton(c=>{c.setButtonText(i?"Build anyway":"Build"),!i&&!s&&c.setCta(),c.onClick(async()=>{this.close(),await this.onBuild()})}),l.addButton(c=>{c.setButtonText("Cancel"),c.onClick(()=>this.close())})}onClose(){this.contentEl.empty()}}});var Zs,fi,hr=de(()=>{"use strict";Zs=require("obsidian");ce();fi=class extends Zs.AbstractInputSuggest{constructor(e,t){super(e,t);this.inputEl=t}getSuggestions(e){let t=e.toLowerCase().split(/\s+/).filter(Boolean),i=o=>t.every(a=>o.toLowerCase().includes(a)),s=[],n=o=>{if(!(o.path!=="/"&&Os.has(o.name))){o.path!=="/"&&i(o.path)&&s.push(o);for(let a of o.children)a instanceof Zs.TFolder&&n(a)}};return n(this.app.vault.getRoot()),s.slice(0,100)}renderSuggestion(e,t){t.setText(e.path)}selectSuggestion(e){this.setValue(e.path),this.inputEl.dispatchEvent(new Event("input",{bubbles:!0})),this.close()}}});var Ii,js,pr=de(()=>{"use strict";Ii=require("obsidian"),js=class d extends Ii.AbstractInputSuggest{constructor(e,t){super(e,t);this.inputEl=t}static norm(e){return e.replace(/^lucide-/,"")}getSuggestions(e){let t=e.toLowerCase().split(/\s+/).filter(Boolean),i=new Set,s=[];for(let a of(0,Ii.getIconIds)()){let l=d.norm(a);i.has(l)||(i.add(l),s.push(l))}let n=a=>t.every(l=>a.toLowerCase().includes(l)),o=t.length?s.filter(n):s;return o.sort(),o.slice(0,t.length?50:300)}renderSuggestion(e,t){t.addClass("stashpad-icon-suggest-item");let i=t.createSpan({cls:"stashpad-icon-suggest-icon"});(0,Ii.setIcon)(i,e),t.createSpan({cls:"stashpad-icon-suggest-label",text:e})}selectSuggestion(e){this.setValue(e),this.inputEl.dispatchEvent(new Event("input",{bubbles:!0})),this.close()}}});function ts(d,r,e){let t=d.vault.getAbstractFileByPath(r);if(!(t instanceof ft.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?.(t)}}];if(!e){let s=ft.Platform.isMacOS?"Finder":ft.Platform.isWin?"File Explorer":"file manager";i.push({label:`Show in ${s}`,keepOpen:!0,onClick:()=>{try{let n=window.require?.("electron")?.shell,a=d.vault.adapter?.getFullPath?.(r);a&&n?.showItemInFolder&&n.showItemInFolder(a)}catch(n){console.warn("[Stashpad] showItemInFolder failed",n)}}})}return i}var ft,Do,Bc,gr,_s,en=de(()=>{"use strict";ft=require("obsidian"),Do={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)."},reminder:{label:"Reminder",desc:"Task due-date reminders \u2014 surfaced when a task comes due (fired at launch / periodically)."},system:{label:"System",desc:"Plumbing toasts: backfill progress, integrity warnings, errors not tied to a verb."}},Bc={info:4e3,success:4e3,warning:6e3,error:1e4},gr=5e3,_s=class{constructor(r){this.app=r;this.history=[];this.nextId=1;this.historyLimit=gr;this.changeListeners=new Set;this.muted=new Set;this.defaultAuthorId=null}setDefaultAuthorId(r){this.defaultAuthorId=r||null}show(r){let e=r.kind??"info",t=r.category??"system",i={id:this.nextId++,ts:Date.now(),message:r.message,kind:e,category:t,authorId:r.authorId??this.defaultAuthorId??void 0,affectedIds:r.affectedIds?r.affectedIds.slice():[],affectedPaths:r.affectedPaths?r.affectedPaths.slice():[],affectedAuthorIds:r.affectedAuthorIds?r.affectedAuthorIds.slice():[],folder:r.folder,actionLabels:(r.actions??[]).map(a=>a.label)};if(this.pushHistory(i),this.muted.has(t))return null;let s=this.buildContent(r,e),n=r.duration??Bc[e],o=new ft.Notice(s,n);if(r.onBodyClick){let a=r.onBodyClick,l=o.containerEl??o.noticeEl;if(l){l.classList.add("stashpad-notice-clickable"),l.setAttribute("tabindex","0"),l.setAttribute("role","button"),l.setAttribute("aria-label",`${r.message} \u2014 activate to open; use the button to snooze`);let c=()=>{Promise.resolve().then(()=>a()).catch(A=>console.warn("[Stashpad] notification body click failed",A)),o.hide()};l.addEventListener("click",A=>{A.target.closest(".stashpad-notice-action, .stashpad-notice-overlay")||c()}),l.addEventListener("keydown",A=>{A.target===l&&(A.key==="Enter"||A.key===" ")&&(A.preventDefault(),c())})}}return o}onChange(r){return this.changeListeners.add(r),()=>this.changeListeners.delete(r)}recent(){return this.history.slice().reverse()}clearHistory(){this.history=[],this.emit()}setMuted(r,e){e?this.muted.add(r):this.muted.delete(r)}isMuted(r){return this.muted.has(r)}loadMutedFromList(r){this.muted=new Set(r)}mutedList(){return Array.from(this.muted)}loadHistory(r){let e=this.applyLimit(r.slice());this.history=e;let t=0;for(let i of e)i.id>t&&(t=i.id);this.nextId=Math.max(this.nextId,t+1),this.emit()}setHistoryLimit(r){this.historyLimit=Number.isFinite(r)?r:gr,this.history=this.applyLimit(this.history),this.emit()}applyLimit(r){return this.historyLimit<=0||r.length<=this.historyLimit?r:r.slice(r.length-this.historyLimit)}pushHistory(r){this.history.push(r),this.history=this.applyLimit(this.history),this.emit()}emit(){for(let r of this.changeListeners)try{r()}catch(e){console.warn("[Stashpad] notification listener failed",e)}}buildContent(r,e){let t=document.createDocumentFragment(),i=document.createElement("div");i.className=`stashpad-notice stashpad-notice-${e}`;let s=document.createElement("div");s.className="stashpad-notice-message";let n=r.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),r.actions&&r.actions.length>0){let o=document.createElement("div");o.className="stashpad-notice-actions";for(let a of r.actions){let l=document.createElement("button");l.className="stashpad-notice-action",l.textContent=a.label,l.addEventListener("click",c=>{if(c.stopPropagation(),Promise.resolve().then(()=>a.onClick()).catch(A=>console.warn("[Stashpad] notification action failed",A)),!a.keepOpen){let A=l.closest(".notice");A&&A.parentElement&&A.parentElement.removeChild(A)}}),o.appendChild(l)}i.appendChild(o)}if(r.overlayAction){let o=r.overlayAction;i.classList.add("has-overlay");let a=document.createElement("button");a.className="stashpad-notice-overlay",o.icon&&(0,ft.setIcon)(a,o.icon);let l=document.createElement("span");l.textContent=o.label,a.appendChild(l),a.title=o.title??o.label,a.addEventListener("click",c=>{if(c.stopPropagation(),Promise.resolve().then(()=>o.onClick()).catch(A=>console.warn("[Stashpad] notification overlay action failed",A)),!o.keepOpen){let A=a.closest(".notice");A&&A.parentElement&&A.parentElement.removeChild(A)}}),i.appendChild(a)}return t.appendChild(i),t}}});function mi(d){if(!d)return"(none)";let r=d.replace(/\bMod\b/g,xo?"Cmd":"Ctrl");return xo&&(r=r.replace(/\bAlt\b/g,"Option")),r}function fr(d,r,e={allowSingleKey:!0}){let t=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=t,d.classList.remove("is-recording"),s||(d.value=i),d.removeEventListener("keydown",o,!0),d.removeEventListener("blur",a)},o=l=>{if(l.key==="Control"||l.key==="Shift"||l.key==="Alt"||l.key==="Meta"||l.key==="OS")return;let c=!!l.code&&(/^Key[A-Z]$/.test(l.code)||/^Digit\d$/.test(l.code));if((l.key==="Dead"||l.key==="Process"||l.key==="Unidentified")&&!c)return;if(l.preventDefault(),l.stopPropagation(),l.key==="Backspace"&&!l.metaKey&&!l.ctrlKey&&!l.altKey&&!l.shiftKey){n();return}let A=[];xo?(l.metaKey&&A.push("Mod"),l.ctrlKey&&A.push("Ctrl")):l.ctrlKey&&A.push("Mod"),l.altKey&&A.push("Alt"),l.shiftKey&&A.push("Shift");let h=yc(l.key,l.code);if(!h||A.length===0&&!e.allowSingleKey)return;A.push(h);let p=A.join("+");s=!0,n(),r(p)},a=()=>n();return d.addEventListener("keydown",o,!0),d.addEventListener("blur",a),n}function yc(d,r){if(!d)return"";if(r){let e=/^Key([A-Z])$/.exec(r);if(e)return e[1];let t=/^Digit(\d)$/.exec(r);if(t)return t[1]}return d.length===1?d.toUpperCase():d}var ur,xo,Ir=de(()=>{"use strict";ur=require("obsidian"),xo=ur.Platform.isMacOS});function Vt(d,r,e,t){function i(s){return s instanceof e?s:new e(function(n){n(s)})}return new(e||(e=Promise))(function(s,n){function o(c){try{l(t.next(c))}catch(A){n(A)}}function a(c){try{l(t.throw(c))}catch(A){n(A)}}function l(c){c.done?s(c.value):i(c.value).then(o,a)}l((t=t.apply(d,r||[])).next())})}function wc(){return typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:global}function Er(d,r){return(d&15)+(d>>6|d>>3&8)<<4|(r&15)+(r>>6|r>>3&8)}function vr(d,r){let e=r.length>>1;for(let t=0;t<e;t++){let i=t<<1;d[t]=Er(r.charCodeAt(i),r.charCodeAt(i+1))}}function vc(d,r){if(d.length!==r.length*2)return!1;for(let e=0;e<r.length;e++){let t=e<<1;if(r[e]!==Er(d.charCodeAt(t),d.charCodeAt(t+1)))return!1}return!0}function Ro(d,r,e){let t=0;for(let i=0;i<e;i++){let s=r[i]>>>4;d[t++]=s>9?s+mr:s+Cr,s=r[i]&15,d[t++]=s>9?s+mr:s+Cr}return String.fromCharCode.apply(null,d)}function Br(d,r=!0){let e=d.length,t=e%3,i=[],s=e-t;for(let n=0;n<s;n+=3){let o=(d[n]<<16&16711680)+(d[n+1]<<8&65280)+(d[n+2]&255),a=Je.charAt(o>>18&63)+Je.charAt(o>>12&63)+Je.charAt(o>>6&63)+Je.charAt(o&63);i.push(a)}if(t===1){let n=d[e-1],o=Je.charAt(n>>2),a=Je.charAt(n<<4&63);i.push(`${o}${a}`),r&&i.push("==")}else if(t===2){let n=(d[e-2]<<8)+d[e-1],o=Je.charAt(n>>10),a=Je.charAt(n>>4&63),l=Je.charAt(n<<2&63);i.push(`${o}${a}${l}`),r&&i.push("=")}return i.join("")}function Qc(d){let r=Math.floor(d.length*.75),e=d.length;return d[e-1]==="="&&(r-=1,d[e-2]==="="&&(r-=1)),r}function Fc(d){let r=Qc(d),e=d.length,t=new Uint8Array(r),i=0;for(let s=0;s<e;s+=4){let n=ss[d.charCodeAt(s)],o=ss[d.charCodeAt(s+1)],a=ss[d.charCodeAt(s+2)],l=ss[d.charCodeAt(s+3)];t[i]=n<<2|o>>4,i+=1,t[i]=(o&15)<<4|a>>2,i+=1,t[i]=(a&3)<<6|l&63,i+=1}return t}function Qr(d,r){return Vt(this,void 0,void 0,function*(){let e=null,t=null,i=!1;if(typeof WebAssembly>"u")throw new Error("WebAssembly is not supported in this environment!");let s=(y,v=0)=>{t.set(y,v)},n=()=>t,o=()=>e.exports,a=y=>{e.exports.Hash_SetMemorySize(y);let v=e.exports.Hash_GetBuffer(),Q=e.exports.memory.buffer;t=new Uint8Array(Q,v,y)},l=()=>new DataView(e.exports.memory.buffer).getUint32(e.exports.STATE_SIZE,!0),c=kc.dispatch(()=>Vt(this,void 0,void 0,function*(){if(!Mo.has(d.name)){let v=Fc(d.data),Q=WebAssembly.compile(v);Mo.set(d.name,Q)}let y=yield Mo.get(d.name);e=yield WebAssembly.instantiate(y,{})})),A=()=>Vt(this,void 0,void 0,function*(){e||(yield c);let y=e.exports.Hash_GetBuffer(),v=e.exports.memory.buffer;t=new Uint8Array(v,y,tn)}),h=(y=null)=>{i=!0,e.exports.Hash_Init(y)},p=y=>{let v=0;for(;v<y.length;){let Q=y.subarray(v,v+tn);v+=Q.length,t.set(Q),e.exports.Hash_Update(Q.length)}},f=y=>{if(!i)throw new Error("update() called before init()");let v=mt(y);p(v)},u=new Uint8Array(r*2),g=(y,v=null)=>{if(!i)throw new Error("digest() called before init()");return i=!1,e.exports.Hash_Final(v),y==="binary"?t.slice(0,r):Ro(u,t,r)},I=()=>{if(!i)throw new Error("save() can only be called after init() and before digest()");let y=e.exports.Hash_GetState(),v=l(),Q=e.exports.memory.buffer,w=new Uint8Array(Q,y,v),F=new Uint8Array(is+v);return vr(F,d.hash),F.set(w,is),F},m=y=>{if(!(y instanceof Uint8Array))throw new Error("load() expects an Uint8Array generated by save()");let v=e.exports.Hash_GetState(),Q=l(),w=is+Q,F=e.exports.memory.buffer;if(y.length!==w)throw new Error(`Bad state length (expected ${w} bytes, got ${y.length})`);if(!vc(d.hash,y.subarray(0,is)))throw new Error("This state was written by an incompatible hash implementation");let D=y.subarray(is);new Uint8Array(F,v,Q).set(D),i=!0},C=y=>typeof y=="string"?y.length<tn/4:y.byteLength<tn,B=C;switch(d.name){case"argon2":case"scrypt":B=()=>!0;break;case"blake2b":case"blake2s":B=(y,v)=>v<=512&&C(y);break;case"blake3":B=(y,v)=>v===0&&C(y);break;case"xxhash64":case"xxhash3":case"xxhash128":case"crc64":B=()=>!1;break}let E=(y,v=null,Q=null)=>{if(!B(y,v))return h(v),f(y),g("hex",Q);let w=mt(y);return t.set(w),e.exports.Hash_Calculate(w.length,v,Q),Ro(u,t,r)};return yield A(),{getMemory:n,writeMemory:s,getExports:o,setMemorySize:a,init:h,update:f,digest:g,save:I,load:m,calculate:E,hashLength:r}})}function yr(d){return!Number.isInteger(d)||d<8||d>512||d%8!==0?new Error("Invalid variant! Valid values: 8, 16, ..., 512"):null}function Hc(d,r){return d|r<<16}function Uo(d=512,r=null){if(yr(d))return Promise.reject(yr(d));let e=null,t=d;if(r!==null){if(e=mt(r),e.length>64)return Promise.reject(new Error("Max key length is 64 bytes"));t=Hc(d,e.length)}let i=d/8;return Qr(Pc,i).then(s=>{t>512&&s.writeMemory(e),s.init(t);let n={init:t>512?()=>(s.writeMemory(e),s.init(t),n):()=>(s.init(t),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 Rc(d,r,e){let t=[`m=${r.memorySize}`,`t=${r.iterations}`,`p=${r.parallelism}`].join(",");return`$argon2${r.hashType}$v=19$${t}$${Br(d,!1)}$${Br(e,!1)}`}function It(d){return wr.setInt32(0,d,!0),new Uint8Array(wr.buffer)}function Po(d,r,e){return Vt(this,void 0,void 0,function*(){if(e<=64){let a=yield Uo(e*8);return a.update(It(e)),a.update(r),a.digest("binary")}let t=Math.ceil(e/32)-2,i=new Uint8Array(e);d.init(),d.update(It(e)),d.update(r);let s=d.digest("binary");i.set(s.subarray(0,32),0);for(let a=1;a<t;a++)d.init(),d.update(s),s=d.digest("binary"),i.set(s.subarray(0,32),a*32);let n=e-32*t,o;return n===64?(o=d,o.init()):o=yield Uo(n*8),o.update(s),s=o.digest("binary"),i.set(s.subarray(0,n),t*32),i})}function Uc(d){switch(d){case"d":return 0;case"i":return 1;default:return 2}}function Lc(d){return Vt(this,void 0,void 0,function*(){var r;let{parallelism:e,iterations:t,hashLength:i}=d,s=mt(d.password),n=mt(d.salt),o=19,a=Uc(d.hashType),{memorySize:l}=d,c=mt((r=d.secret)!==null&&r!==void 0?r:""),[A,h]=yield Promise.all([Qr(xc,1024),Uo(512)]);A.setMemorySize(l*1024+1024);let p=new Uint8Array(24),f=new DataView(p.buffer);f.setInt32(0,e,!0),f.setInt32(4,i,!0),f.setInt32(8,l,!0),f.setInt32(12,t,!0),f.setInt32(16,o,!0),f.setInt32(20,a,!0),A.writeMemory(p,l*1024),h.init(),h.update(p),h.update(It(s.length)),h.update(s),h.update(It(n.length)),h.update(n),h.update(It(c.length)),h.update(c),h.update(It(0));let g=Math.floor(l/(e*4))*4,I=new Uint8Array(72),m=h.digest("binary");I.set(m);for(let E=0;E<e;E++){I.set(It(0),64),I.set(It(E),68);let y=E*g,v=yield Po(h,I,1024);A.writeMemory(v,y*1024),y+=1,I.set(It(1),64),v=yield Po(h,I,1024),A.writeMemory(v,y*1024)}let C=new Uint8Array(1024);vr(C,A.calculate(new Uint8Array([]),l));let B=yield Po(h,C,i);if(d.outputType==="hex"){let E=new Uint8Array(i*2);return Ro(E,B,i)}return d.outputType==="encoded"?Rc(n,d,B):B})}function Lo(d){return Vt(this,void 0,void 0,function*(){return Gc(d),Lc(Object.assign(Object.assign({},d),{hashType:"id"}))})}var le,No,Ho,To,Ec,mr,Cr,mt,Je,ss,tn,is,kc,Mo,SA,Sc,bc,Dc,xc,Nc,Tc,Mc,Pc,bA,wr,Gc,DA,xA,NA,TA,MA,PA,HA,RA,UA,LA,GA,OA,KA,qA,JA,$A,YA,zA,VA,WA,XA,ZA,jA,_A,Fr=de(()=>{le=class{constructor(){this.mutex=Promise.resolve()}lock(){let r=()=>{};return this.mutex=this.mutex.then(()=>new Promise(r)),new Promise(e=>{r=e})}dispatch(r){return Vt(this,void 0,void 0,function*(){let e=yield this.lock();try{return yield Promise.resolve(r())}finally{e()}})}};Ho=wc(),To=(No=Ho.Buffer)!==null&&No!==void 0?No:null,Ec=Ho.TextEncoder?new Ho.TextEncoder:null;mr=87,Cr=48;mt=To!==null?d=>{if(typeof d=="string"){let r=To.from(d,"utf8");return new Uint8Array(r.buffer,r.byteOffset,r.length)}if(To.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 Ec.encode(d);if(ArrayBuffer.isView(d))return new Uint8Array(d.buffer,d.byteOffset,d.byteLength);throw new Error("Invalid data type!")},Je="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",ss=new Uint8Array(256);for(let d=0;d<Je.length;d++)ss[Je.charCodeAt(d)]=d;tn=16*1024,is=4,kc=new le,Mo=new Map;SA=new le,Sc="argon2",bc="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",Dc="e4cdc523",xc={name:Sc,data:bc,hash:Dc},Nc="blake2b",Tc="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=",Mc="c6f286e6",Pc={name:Nc,data:Tc,hash:Mc},bA=new le;wr=new DataView(new ArrayBuffer(4));Gc=d=>{var r;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=mt(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=mt(d.salt),d.salt.length<8)throw new Error("Salt should be at least 8 bytes long");if(d.secret=mt((r=d.secret)!==null&&r!==void 0?r:""),!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']`)};DA=new le,xA=new le,NA=new le,TA=new le,MA=new Uint8Array(8),PA=new le,HA=new le,RA=new le,UA=new le,LA=new le,GA=new le,OA=new le,KA=new le,qA=new le,JA=new le,$A=new le,YA=new Uint8Array(8),zA=new le,VA=new Uint8Array(8),WA=new le,XA=new Uint8Array(8),ZA=new le,jA=new le,_A=new le});function Ue(d){if(d.length<$e.length+1)return!1;for(let r=0;r<$e.length;r++)if(d[r]!==$e[r])return!1;return!0}function kr(d,r,e){d[r]=e>>>24&255,d[r+1]=e>>>16&255,d[r+2]=e>>>8&255,d[r+3]=e&255}function Sr(d,r){return d[r]*16777216+(d[r+1]<<16)+(d[r+2]<<8)+d[r+3]}async function Oo(d,r,e){if(e.id===Jo)return await Lo({password:d,salt:r,parallelism:e.c,iterations:e.b,memorySize:e.a,hashLength:Go,outputType:"binary"});if(e.id===qo){let t=await crypto.subtle.importKey("raw",me(new TextEncoder().encode(d)),"PBKDF2",!1,["deriveBits"]),i=await crypto.subtle.deriveBits({name:"PBKDF2",salt:me(r),iterations:e.a,hash:"SHA-256"},t,Go*8);return new Uint8Array(i)}throw new Error(`Unsupported KDF id (${e.id}).`)}async function sn(d){return crypto.subtle.importKey("raw",me(d),{name:"AES-GCM"},!1,["encrypt","decrypt"])}async function Ct(d,r){let e=crypto.getRandomValues(new Uint8Array(Oc)),t=crypto.getRandomValues(new Uint8Array(Ci)),i,s,n;try{i={id:Jo,a:qc,b:Jc,c:$c},n=await Oo(r,e,i),s="argon2id"}catch(A){console.warn("[Stashpad] Argon2id unavailable \u2014 encrypting with PBKDF2 fallback.",A),i={id:qo,a:Kc,b:0,c:0},n=await Oo(r,e,i),s="pbkdf2"}let o=Dr(i,e,t),a=await sn(n),l=new Uint8Array(await crypto.subtle.encrypt({name:"AES-GCM",iv:me(t),additionalData:me(o)},a,me(d))),c=new Uint8Array(o.length+l.length);return c.set(o,0),c.set(l,o.length),{data:c,kdf:s}}async function os(){if(ns!==null)return ns;try{await Lo({password:"x",salt:new Uint8Array(16),parallelism:1,iterations:1,memorySize:8,hashLength:16,outputType:"binary"}),ns=!0}catch{ns=!1}return ns}function Dr(d,r,e){let t=new Uint8Array($e.length+1+1+4+4+1+1+r.length+e.length),i=0;return t.set($e,i),i+=$e.length,t[i++]=Ko,t[i++]=d.id,kr(t,i,d.a),i+=4,kr(t,i,d.b),i+=4,t[i++]=d.c,t[i++]=r.length,t.set(r,i),i+=r.length,t.set(e,i),i+=e.length,t}async function Bi(d,r){if(!Ue(d))throw new Error("Not an encrypted Stashpad file.");let e=d[$e.length];if(e===1)return Yc(d,r);if(e!==Ko)throw new Error(`Unsupported encrypted .stash version (${e}).`);let t=$e.length+1,i={id:d[t++],a:0,b:0,c:0};if(i.a=Sr(d,t),t+=4,i.b=Sr(d,t),t+=4,i.c=d[t++],i.id===Jo){if(i.a>2097152||i.b>64||i.c<1||i.c>8)throw new Error("Unsupported KDF parameters (file may be corrupted or malicious).")}else if(i.id===qo&&i.a>1e7)throw new Error("Unsupported KDF parameters (file may be corrupted or malicious).");let s=d[t++];if(s<8||s>64)throw new Error("Unsupported KDF parameters (file may be corrupted or malicious).");let n=d.slice(t,t+s);t+=s;let o=d.slice(t,t+Ci);t+=Ci;let a=d.slice(0,t),l=d.slice(t),c=await Oo(r,n,i),A=await sn(c),h=await crypto.subtle.decrypt({name:"AES-GCM",iv:me(o),additionalData:me(a)},A,me(l));return new Uint8Array(h)}async function Yc(d,r){let e=$e.length+1,t=d.slice(e,e+16);e+=16;let i=d.slice(e,e+12);e+=12;let s=d.slice(e),n=await crypto.subtle.importKey("raw",me(new TextEncoder().encode(r)),"PBKDF2",!1,["deriveKey"]),o=await crypto.subtle.deriveKey({name:"PBKDF2",salt:me(t),iterations:21e4,hash:"SHA-256"},n,{name:"AES-GCM",length:256},!1,["decrypt"]),a=await crypto.subtle.decrypt({name:"AES-GCM",iv:me(i)},o,me(s));return new Uint8Array(a)}async function as(d,r){if(r.length!==Go)throw new Error("Encryption key must be 32 bytes.");let e=crypto.getRandomValues(new Uint8Array(Ci)),i=Dr({id:br,a:0,b:0,c:0},new Uint8Array(0),e),s=await sn(r),n=new Uint8Array(await crypto.subtle.encrypt({name:"AES-GCM",iv:me(e),additionalData:me(i)},s,me(d))),o=new Uint8Array(i.length+n.length);return o.set(i,0),o.set(n,i.length),o}async function Ye(d,r){if(!Ue(d))throw new Error("Not an encrypted Stashpad file.");let e=d[$e.length];if(e!==Ko)throw new Error(`Unsupported encrypted version (${e}).`);let t=$e.length+1;if(d[t++]!==br)throw new Error("Not a raw-key (.stashenc) envelope.");t+=9;let s=d[t++];t+=s;let n=d.slice(t,t+Ci);t+=Ci;let o=d.slice(0,t),a=d.slice(t),l=await sn(r),c=await crypto.subtle.decrypt({name:"AES-GCM",iv:me(n),additionalData:me(o)},l,me(a));return new Uint8Array(c)}async function yi(d,r,e={}){if(!Ue(r))return r;if(e.secretId){let i=d.secretStorage,s=null;try{s=i?.getSecret(e.secretId)??null}catch{s=null}if(s)try{return await Bi(r,s)}catch{}}let t;for(;;){let i=await new Promise(s=>{new rs(d,t,!!e.allowLater,s).open()});if(i.kind==="cancel")return null;if(i.kind==="later")return e.onLater?.(),null;try{return await Bi(r,i.value)}catch{t="Wrong password or corrupted file. Try again."}}}var $e,Ko,qo,Jo,br,Oc,Ci,Go,Kc,qc,Jc,$c,me,$o,ns,Wt=de(()=>{"use strict";Fr();ve();$e=new Uint8Array([83,84,65,83,72,69,78,67]),Ko=2,qo=1,Jo=2,br=3,Oc=32,Ci=12,Go=32,Kc=6e5,qc=47104,Jc=3,$c=1,me=d=>d;$o={argon2id:{label:"Argon2id",strong:!0},pbkdf2:{label:"PBKDF2 (fallback)",strong:!1}};ns=null});var Xt,zc,wi,nn,xr=de(()=>{"use strict";Xt=".stashpad/keys.json",zc=".stashpad",wi="_keys",nn=class{constructor(r){this.app=r}get a(){return this.app.vault.adapter}validate(r){let e=r;return!!e&&e.v===2&&typeof e.keyId=="string"&&Array.isArray(e.identities)&&Array.isArray(e.slots)&&Array.isArray(e.joinRequests)}async readValid(r){try{if(!await this.a.exists(r))return null;let e=JSON.parse(await this.a.read(r));return this.validate(e)?e:null}catch{return null}}async load(){let r=await this.readValid(Xt);if(r)return r;try{let t=((await this.a.list(wi)).files||[]).filter(i=>/\/keys-\d+\.json$/.test(i)).sort();for(let i of t.reverse()){let s=await this.readValid(i);if(s)return s}}catch{}return null}async exists(){return await this.load()!==null}async hasAnyFile(){try{if(await this.a.exists(Xt))return!0}catch{}try{return((await this.a.list(wi)).files||[]).some(e=>/\/keys-\d+\.json$/.test(e))}catch{return!1}}async ensureDir(r){try{await this.a.exists(r)||await this.a.mkdir(r)}catch{}}async save(r){let e=JSON.stringify(r,null,2);await this.ensureDir(zc);let t=`${Xt}.tmp`,i=!1;try{await this.a.write(t,e);try{await this.a.rename(t,Xt)}catch{try{await this.a.remove(Xt)}catch{}await this.a.rename(t,Xt)}i=!0}catch{try{await this.a.exists(t)&&await this.a.remove(t)}catch{}}i||await this.a.write(Xt,e),await this.ensureDir(wi);for(let s=4;s>=1;s--){let n=`${wi}/keys-${s}.json`,o=`${wi}/keys-${s+1}.json`;try{await this.a.exists(n)&&await this.a.write(o,await this.a.read(n))}catch{}}try{await this.a.write(`${wi}/keys-1.json`,e)}catch{}}}});function Yo(d){let r="";for(let e=0;e<d.length;e++)r+=String.fromCharCode(d[e]);return btoa(r)}function Wc(d){let r=atob(d),e=new Uint8Array(r.length);for(let t=0;t<r.length;t++)e[t]=r.charCodeAt(t);return e}var Vc,Nr,on,an,Tr=de(()=>{"use strict";Wt();pt();Vc=".stashkey",Nr=32;on=()=>new Date().toISOString(),an=class{constructor(r){this.app=r}get a(){return this.app.vault.adapter}keyPath(r){return`${r.replace(/\/+$/,"")}/${Vc}`}validate(r){let e=r;return!!e&&e.v===1&&typeof e.keyId=="string"&&typeof e.folderPath=="string"&&Array.isArray(e.slots)&&e.slots.every(t=>t&&typeof t.wrapped=="string"&&typeof t.id=="string")}async read(r){let e=this.keyPath(r);try{if(!await this.a.exists(e))return null;let t=JSON.parse(await this.a.read(e));return this.validate(t)?t:null}catch{return null}}async hasFile(r){try{return await this.a.exists(this.keyPath(r))}catch{return!1}}async write(r,e){let t=this.keyPath(r),i=JSON.stringify(e,null,2),s=`${t}.tmp`,n=!1;try{await this.a.write(s,i);try{await this.a.rename(s,t)}catch{try{await this.a.remove(t)}catch{}await this.a.rename(s,t)}n=!0}catch{try{await this.a.exists(s)&&await this.a.remove(s)}catch{}}n||await this.a.write(t,i)}async remove(r){try{await this.a.remove(this.keyPath(r))}catch{}}async create(r,e,t){if(!e)throw new Error("Password required.");let i=crypto.getRandomValues(new Uint8Array(Nr)),s=await Ct(i,e);return{sk:{v:1,keyId:t??he(8),folderPath:r.replace(/\/+$/,""),slots:[{id:he(8),label:"Folder password",wrapped:Yo(s.data),kdf:s.kdf,createdAt:on()}],createdAt:on()},dek:i}}async unlock(r,e){for(let t of r.slots)try{let i=await Bi(Wc(t.wrapped),e);if(i.length!==Nr){i.fill(0);continue}return i}catch{}return null}async changePassword(r,e,t){if(!t)throw new Error("Password required.");let i=await Ct(e,t),s=r.slots.filter(o=>o.recovery),n={id:he(8),label:"Folder password",wrapped:Yo(i.data),kdf:i.kdf,createdAt:on()};return{...r,slots:[n,...s]}}async setRecovery(r,e,t){if(!t)throw new Error("Recovery password required.");let i=await Ct(e,t),s=r.slots.filter(o=>!o.recovery),n={id:he(8),label:"Recovery password",wrapped:Yo(i.data),kdf:i.kdf,createdAt:on(),recovery:!0};return{...r,slots:[...s,n]}}removeRecovery(r){return{...r,slots:r.slots.filter(e=>!e.recovery)}}hasRecovery(r){return r.slots.some(e=>e.recovery)}}});function ln(){return{}}function Zc(d){let r="";for(let e=0;e<d.length;e++)r+=String.fromCharCode(d[e]);return btoa(r)}function jc(d){let r=atob(d),e=new Uint8Array(r.length);for(let t=0;t<r.length;t++)e[t]=r.charCodeAt(t);return e}var Xc,rn,zo=de(()=>{"use strict";Wt();pt();xr();Tr();Xc="stashpad-vault-encryption";rn=class{constructor(r,e,t){this.app=r;this.load=e;this.save=t;this.folderSessionKeys=new Map;this.kf=null;this.folderKeyFiles=new Map;this.stashKeysIndexed=!1;this.parkedKeyMaterial=!1;this.keyfiles=new nn(r),this.folderKeystore=new an(r)}argonProbe(){return os()}async init(){await this.refresh(),this.parkedKeyMaterial=await this.detectParkedKeyMaterial()}async refresh(){this.kf=await this.keyfiles.load(),this.stashKeysIndexed||await this.indexStashKeys()}async detectParkedKeyMaterial(){let r=this.app.vault.adapter;try{let e=await r.list("_keys");if((e.files||[]).some(t=>/\.json$/.test(t))||(e.folders||[]).length)return!0}catch{}try{if(((await r.list(".stashpad")).folders||[]).some(t=>/\/retired-keyfile-/.test(t)))return!0}catch{}return!1}invalidateStashKeyIndex(){this.stashKeysIndexed=!1}async migrateKeyfileToStashKeys(){await this.refresh();let r=this.kf?.folderKeys;if(!r)return 0;let e=0;for(let[t,i]of Object.entries(r)){let s=this.cleanFolder(t);if(this.folderKeyFiles.has(s)||await this.folderKeystore.hasFile(s))continue;let n=(i.passwordSlots??[]).filter(a=>!a.label.startsWith("[deprecated]"));if(!n.length)continue;let o={v:1,keyId:i.keyId,folderPath:s,slots:n.map((a,l)=>({id:a.id,label:l===0?"Folder password":a.label,wrapped:a.wrapped,kdf:a.kdf,createdAt:a.createdAt})),createdAt:i.createdAt};try{await this.folderKeystore.write(s,o);let a=await this.folderKeystore.read(s);if(!a||a.slots[0]?.wrapped!==o.slots[0].wrapped){await this.folderKeystore.remove(s);continue}this.folderKeyFiles.set(s,o),e++}catch{}}return e}async indexStashKeys(){let r=new Map,e=new Set([".git",".obsidian","node_modules"]),t=async i=>{let s;try{s=await this.app.vault.adapter.list(i)}catch{return}for(let n of s.files??[])if(n===".stashkey"||n.endsWith("/.stashkey")){let o=n.includes("/")?n.slice(0,n.lastIndexOf("/")):"",a=await this.folderKeystore.read(o);a&&r.set(this.cleanFolder(o),a)}for(let n of s.folders??[])e.has(n.split("/").pop()??"")||await t(n)};await t(""),this.folderKeyFiles=r,this.stashKeysIndexed=!0}stashKeyToEntry(r,e){return{keyId:r.keyId,folderPath:this.cleanFolder(e),label:r.slots[0]?.label??"Folder password",kcId:this.folderKcId(e,r.keyId),passwordSlots:r.slots.map(t=>({id:t.id,label:t.label,wrapped:t.wrapped,kdf:t.kdf,createdAt:t.createdAt})),createdAt:r.createdAt}}secretStore(){return this.app.secretStorage??null}keychainAvailable(){return!!this.secretStore()}async parkThenSet(r,e){let t=this.secretStore();if(!t)return;let i=[r];try{let s=t.getSecret(r);if(s&&s!==e){let n=Date.now().toString(36),o=`${r.slice(0,64-(n.length+2))}-r${n}`;await t.setSecret(o,s),i.push(o)}}catch{}await t.setSecret(r,e),await this.recordKeychainIds(i)}async recordKeychainIds(r){try{let e=this.load(),t=new Set(e.knownKeychainIds??[]),i=!1;for(let s of r)s&&!t.has(s)&&(t.add(s),i=!0);i&&await this.save({...e,knownKeychainIds:[...t]})}catch{}}keychainCandidateIds(){return[...new Set(this.load().knownKeychainIds??[])]}hasAnyFolderKey(){return this.folderKeyFiles.size>0||Object.keys(this.kf?.folderKeys??{}).length>0}isConfigured(){return this.hasAnyFolderKey()}owningFolder(r){let e=this.kf?.folderKeys,t=this.cleanFolder(r);for(;t;){if(this.folderKeyFiles.has(t)||e&&Object.prototype.hasOwnProperty.call(e,t))return t;let i=t.lastIndexOf("/");if(i<0)break;t=t.slice(0,i)}return null}hasOwnFolderKey(r){let e=this.cleanFolder(r);if(this.folderKeyFiles.has(e))return!0;let t=this.kf?.folderKeys;return!!t&&Object.prototype.hasOwnProperty.call(t,e)}folderKeyEntry(r){let e=this.owningFolder(r);if(!e)return null;let t=this.folderKeyFiles.get(e);return t?this.stashKeyToEntry(t,e):this.kf?.folderKeys?.[e]??null}hasFolderKey(r){return this.owningFolder(r)!==null}folderPathByKeyId(r){for(let[e,t]of this.folderKeyFiles)if(t.keyId===r)return e;for(let[e,t]of Object.entries(this.kf?.folderKeys??{}))if(t.keyId===r)return e;return null}folderActiveSlots(r){return(r.passwordSlots??[]).filter(e=>!e.label.startsWith("[deprecated]"))}isFolderUnlocked(r){let e=this.owningFolder(r);return e?this.folderSessionKeys.has(e):!1}getFolderKey(r){let e=this.owningFolder(r);if(!e)return null;let t=this.folderSessionKeys.get(e);return t?t.slice():null}async setupFolderKey(r,e,t,i=!1){if(!e)throw new Error("Password required.");await this.refresh();let s=this.cleanFolder(r);if(this.hasOwnFolderKey(s))throw new Error("This folder already has its own key.");let n=this.owningFolder(s);if(n&&n!==s)throw new Error(`A parent folder (\u201C${n.split("/").pop()}\u201D) already has its own password; this folder inherits it.`);let{sk:o,dek:a}=await this.folderKeystore.create(s,e);await this.folderKeystore.write(s,o),this.folderKeyFiles.set(s,o),this.folderSessionKeys.set(s,a),i&&await this.rememberFolder(this.folderKcId(s,o.keyId),e)}async unlockFolder(r,e,t=!1){await this.refresh();let i=this.cleanFolder(r),s=this.folderKeyEntry(i);if(!s)return!1;for(let n of this.folderActiveSlots(s))try{let o=await Bi(jc(n.wrapped),e);this.folderSessionKeys.set(s.folderPath,o);let a=this.folderKcIdFor(s);return(t||this.isFolderRemembered(a))&&await this.rememberFolder(a,e),!0}catch{}return!1}async tryAutoUnlockFolder(r){let e=this.folderKeyEntry(r);if(!e||this.isFolderUnlocked(r))return this.isFolderUnlocked(r);let t=this.folderKcIdFor(e),i=this.rememberedFolderPassword(t);if(i&&await this.unlockFolder(r,i))return!0;let s=this.secretStore();if(!s)return!1;let n=new Set(i?[i]:[]);for(let o of this.keychainCandidateIds()){if(o===t)continue;let a=null;try{a=s.getSecret(o)??null}catch{a=null}if(!(!a||n.has(a))&&(n.add(a),await this.unlockFolder(r,a)))return await this.rememberFolder(t,a),!0}return!1}async changeFolderPassword(r,e,t=!1){if(!e)throw new Error("Password required.");let i=this.cleanFolder(r);await this.refresh();let s=this.folderKeyEntry(i);if(!s)throw new Error("This folder has no key.");let n=s.folderPath,o=this.folderSessionKeys.get(n);if(!o)throw new Error("Unlock this folder first.");let a=this.folderKeyFiles.get(n);if(a){let u=await this.folderKeystore.changePassword(a,o,e);await this.folderKeystore.write(n,u),this.folderKeyFiles.set(n,u);let g=this.folderKcId(n,u.keyId);(t||this.isFolderRemembered(g))&&await this.rememberFolder(g,e);return}if(!this.kf)throw new Error("This folder has no key.");let l=s.passwordSlots.filter(u=>!u.label.startsWith("[deprecated]")),c=this.folderKcIdFor(s),A=this.rememberedFolderPassword(c);if(A&&l[0])try{await this.parkThenSet(`${c}-d-${l[0].id}`,A)}catch{}let h=await Ct(o,e),p=s.passwordSlots.map(u=>u.label.startsWith("[deprecated]")?u:{...u,label:`[deprecated] ${u.label}`}),f={...s,kcId:s.kcId??this.folderKcId(s.label,s.keyId),passwordSlots:[{id:he(8),label:"Folder password",wrapped:Zc(h.data),kdf:h.kdf,createdAt:new Date().toISOString()},...p]};this.kf.folderKeys={...this.kf.folderKeys??{},[n]:f},await this.keyfiles.save(this.kf),(t||this.isFolderRemembered(c))&&await this.rememberFolder(this.folderKcIdFor(f),e)}folderHasRecovery(r){let e=this.owningFolder(r),t=e?this.folderKeyFiles.get(e):null;return!!t&&this.folderKeystore.hasRecovery(t)}async setFolderRecoveryPassword(r,e){if(!e)throw new Error("Recovery password required.");await this.refresh();let t=this.cleanFolder(r),i=this.folderKeyEntry(t);if(!i)throw new Error("This folder has no key.");let s=i.folderPath,n=this.folderKeyFiles.get(s);if(!n)throw new Error("This folder's key predates recovery passwords \u2014 change its folder password once to upgrade it, then try again.");let o=this.folderSessionKeys.get(s);if(!o)throw new Error("Unlock this folder first.");let a=await this.folderKeystore.setRecovery(n,o,e);await this.folderKeystore.write(s,a),this.folderKeyFiles.set(s,a)}async removeFolderRecoveryPassword(r){await this.refresh();let e=this.cleanFolder(r),t=this.folderKeyEntry(e);if(!t)return;let i=t.folderPath,s=this.folderKeyFiles.get(i);if(!s||!this.folderKeystore.hasRecovery(s))return;let n=this.folderKeystore.removeRecovery(s);await this.folderKeystore.write(i,n),this.folderKeyFiles.set(i,n)}folderKcId(r,e){return(`sp-${(r||"").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")}`.slice(0,44)+`-${e.slice(0,6)}`).replace(/-+/g,"-")}folderKcIdFor(r){return r.kcId||`${Xc}-f-${r.keyId}`}isFolderRemembered(r){try{return!!this.secretStore()?.getSecret(r)}catch{return!1}}rememberedFolderPassword(r){try{return this.secretStore()?.getSecret(r)||null}catch{return null}}async rememberFolder(r,e){try{await this.parkThenSet(r,e)}catch(t){console.warn("[Stashpad] couldn't save folder password to keychain",t)}}async forgetFolderKeychain(r){let e=this.folderKeyEntry(r);if(!e)return;let t=this.secretStore();if(!t)return;let i=this.folderKcIdFor(e);try{if(t.getSecret(i)){await this.parkThenSet(i,"");return}}catch{}try{t.removeSecret?await t.removeSecret(i):await t.setSecret(i,"")}catch(s){console.warn("[Stashpad] couldn't clear folder keychain",s)}}lock(){for(let r of this.folderSessionKeys.values())r.fill(0);this.folderSessionKeys.clear()}lockFolder(r){let e=this.owningFolder(r)??this.cleanFolder(r),t=this.folderSessionKeys.get(e);t&&(t.fill(0),this.folderSessionKeys.delete(e))}cleanFolder(r){return(r||"").replace(/\/+$/,"")}async clear(){this.lock();try{let r=this.app.vault.adapter;for(let e of[".stashpad/keys.json"])try{await r.exists(e)&&await r.remove(e)}catch{}try{let t=((await r.list("_keys")).files||[]).filter(i=>/\/keys-\d+\.json$/.test(i));if(t.length){let s=`_keys/removed-${new Date().toISOString().slice(0,19).replace(/[:T]/g,"-")}`;try{await r.exists(s)||await r.mkdir(s)}catch{}for(let n of t){let o=n.split("/").pop();try{await r.write(`${s}/${o}`,await r.read(n)),await r.remove(n)}catch{}}}}catch{}this.stashKeysIndexed||await this.indexStashKeys();for(let e of this.folderKeyFiles.keys())try{await this.folderKeystore.remove(e)}catch{}this.folderKeyFiles.clear()}catch{}this.kf=null}async removeFolderKeyFile(r){let e=this.cleanFolder(r);await this.folderKeystore.remove(e),this.folderKeyFiles.delete(e),this.folderSessionKeys.get(e)?.fill(0),this.folderSessionKeys.delete(e)}hasLegacyKeyfile(){return!!this.kf}unmigratedKeyfileFolders(){return Object.keys(this.kf?.folderKeys??{}).filter(r=>!this.folderKeyFiles.has(this.cleanFolder(r)))}async retireLegacyKeyfile(){await this.refresh();let r=this.unmigratedKeyfileFolders();if(r.length)throw new Error(`Can't retire the old keyfile yet \u2014 these folders' keys still live only in it: ${r.map(o=>o||"(vault root)").join(", ")}. Open each folder once (or change its password) to migrate it, then try again.`);let e=this.app.vault.adapter,i=`.stashpad/retired-keyfile-${new Date().toISOString().slice(0,19).replace(/[:T]/g,"-")}`,s=0;try{await e.exists(i)||await e.mkdir(i)}catch{}let n=async(o,a)=>{try{let l=await e.read(o);return await e.write(a,l),await e.read(a)!==l?!1:(await e.remove(o),!0)}catch{return!1}};try{await e.exists(".stashpad/keys.json")&&await n(".stashpad/keys.json",`${i}/keys.json`)&&s++}catch{}try{let o=await e.list("_keys");for(let a of(o.files||[]).filter(l=>/\/keys-\d+\.json$/.test(l)))await n(a,`${i}/${a.split("/").pop()}`)&&s++}catch{}return this.kf=null,this.parkedKeyMaterial=!0,s}hasRecoverableKeyMaterial(){return!!this.kf||this.parkedKeyMaterial}async wipeLegacyKeyMaterial(){let r=this.app.vault.adapter,e=0,t=async(i,s)=>{try{await r.exists(i)&&(s?await r.rmdir(i,!0):await r.remove(i),e++)}catch{}};await t(".stashpad/keys.json",!1),await t("_keys",!0);try{let i=await r.list(".stashpad");for(let s of i.folders||[])/\/retired-keyfile-/.test(s)&&await t(s,!0)}catch{}return this.kf=null,this.parkedKeyMaterial=!1,e}dispose(){this.lock()}}});function dn(d){if(ls!==d){ls=d;for(let r of cn)r()}}function Bt(){return ls}function Mr(d){if(ls===d){ls=null;for(let r of cn)r()}}function Pr(d){return cn.add(d),()=>cn.delete(d)}var ls,cn,An=de(()=>{"use strict";ls=null,cn=new Set});function _c(){return P.Platform.isMacOS?"Finder":P.Platform.isWin?"File Explorer":"file manager"}function Xo(){let d={};for(let r of Zt)d[r.id]={primary:r.defaultPrimary,secondary:r.defaultSecondary??"",preferRight:!1,useBoth:!!r.defaultUseBoth};return d}function X(){return Hr}function cs(d){Hr=d;for(let r of Wo)r()}function Rr(d){return Wo.add(d),()=>Wo.delete(d)}function gn(d){try{let r=d.internalPlugins?.plugins?.templates;if(!r?.enabled)return null;let e=r.instance?.options??{};return{dateFormat:e.dateFormat||"YYYY-MM-DD",timeFormat:e.timeFormat||"HH:mm"}}catch{return null}}function ed(d,r){return Vo||(Vo=class extends P.SettingPage{constructor(e,t){super(),this.title=e,this._renderFn=t}display(){this.containerEl.empty(),this._renderFn(this.containerEl)}}),new Vo(d,r)}var P,Zt,Mt,Hr,Wo,hn,Vo,pn,Qi=de(()=>{"use strict";P=require("obsidian");es();hr();pr();ce();ve();en();Ir();gi();pt();Tt();zo();An();Zt=[{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:"copyLink",label:"Copy Stashpad link",desc:"Copy an obsidian://stashpad deep link to the cursor row (or first selected note) \u2014 click it anywhere to jump back. No default chord.",defaultPrimary:""},{id:"openEditor",label:"Open in Obsidian editor",desc:"Open the cursor row (or focused note) in a regular Obsidian markdown tab.",defaultPrimary:"Mod+Shift+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:"edit",label:"Edit note in Stashpad",desc:"Edit the cursor row (or focused note) in Stashpad's own editor (with a Split toggle) instead of a full Obsidian tab.",defaultPrimary:"E"},{id:"editParent",label:"Edit parent note in Stashpad",desc:"Edit the focused parent note in Stashpad's own editor.",defaultPrimary:"Shift+E"},{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 or X \u2014 marks selected/focused notes as complete (both chords active).",defaultPrimary:"Mod+Enter",defaultSecondary:"X",defaultUseBoth:!0},{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+: or ; \u2014 open the color picker for the selection (both chords active).",defaultPrimary:"Shift+:",defaultSecondary:";",defaultUseBoth:!0},{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:"forkNote",label:"Fork into a separate note (under a chosen parent)",desc:'Duplicate the cursor row (with its subtree) as a separate note and pick which parent it nests under. Distinct from "Fork as a version" (a draft within a sheet group). No default chord.',defaultPrimary:""},{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:"expandAll",label:"Expand all (show every note's full body)",desc:"Un-clamp every note in the current list at once.",defaultPrimary:""},{id:"collapseAll",label:"Collapse all (clamp every note's body)",desc:"Re-clamp every note in the current list at once.",defaultPrimary:""},{id:"exportStash",label:"Export selection\u2026",desc:"Open the export dialog for the selected subtree(s) \u2014 pick .stash / OKF / plain .zip and full/frontmatter/body content.",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:"listPin",label:"Pin / unpin to top of list",desc:"Float the cursor row (or selection) to the TOP of its list \u2014 distinct from the sidebar pin. No default chord.",defaultPrimary:""},{id:"toggleTask",label:"Toggle task (todo)",desc:"Default: G \u2014 mark the selection (or cursor row) as a task / todo, or clear it. Tasks appear in the Tasks panel.",defaultPrimary:"G"},{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:"openAllTasks",label:"Open all tasks (aggregate view)",desc:"Default: Shift+T \u2014 open the aggregate \u201CAll tasks\u201D view collecting tasks across every Stashpad folder.",defaultPrimary:"Shift+T"},{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"},{id:"lockSelection",label:"Encrypt (lock) selection",desc:"Encrypt the selected note(s) + their children into a locked .stashenc bundle in place (prompts to unlock first if needed). No default chord.",defaultPrimary:""},{id:"unlockAll",label:"Decrypt (unlock) locked notes in view",desc:"Decrypt every locked stash shown in the current view back into place, skipping any that can't be read. No default chord.",defaultPrimary:""},{id:"moveToArchive",label:"Move selection to archive",desc:"Move the selected note(s) into this folder's own archive subfolder (drops out of search; plaintext unless this folder encrypts its archive). Undoable. No default chord.",defaultPrimary:""},{id:"encryptDelete",label:"Encrypt & delete selection",desc:"Send the selected note(s) to the encrypted trash (recoverable with your password, Ctrl/Cmd+Z undoable). No default chord.",defaultPrimary:""},{id:"copyNotes",label:"Copy notes (note clipboard)",desc:"Copy the selected note(s) as NOTES: paste in the list to duplicate them (new ids), or anywhere else to paste their text. Skipped when text is highlighted (normal copy wins).",defaultPrimary:"Mod+C"},{id:"cutNotes",label:"Cut notes",desc:"Cut the selected note(s): paste in the list to MOVE them, or in the composer to extract their text and delete the originals (undoable).",defaultPrimary:"Mod+X"},{id:"pasteNotes",label:"Paste notes",desc:"Paste previously copied/cut notes at the cursor row (after it, same parent). Does nothing if the note clipboard is empty.",defaultPrimary:"Mod+V"}];Mt={folder:"Stashpad",importDropFolder:"",exportFolder:"_exports",autoImport:!1,inheritObsidianExclusions:!0,folderPanelPinnedFraction:.5,folderPanelPinned:[],folderPanelPinnedAt:{},folderPanelGroupItemOrder:{},folderPanelDownranked:[],folderPanelHidden:[],folderPanelPinnedGrouping:"pin-order",enablePerfProfiling:!1,debugTrace:!1,writeRecoveryLinks:!0,useTemplatesFormat:!1,prefixTimestampsOnCopy:!0,splitOnLines:!1,splitMode:"lines",confirmCrossParentDrag:!0,confirmBulkDelete:!0,confirmAttachmentDelete:!0,autofocusComposerAfterSend:!0,focusComposerOnOpen:!1,searchOpensInContext:!0,popoutDuplicates:!0,encryption:ln(),encryptTrash:!1,encryptTrashFilenames:!1,migratedToggleTaskG:!1,migratedArchiveToSubfolders:!1,migratedTrashToSubfolders:!1,reEncryptWatch:[],reEncryptNudge:!1,reEncryptAfterMin:0,dueQuickAdjusts:["5m","15m","30m","1h","1d","1w"],archiveFolders:[],folderEncPrefs:{},folderIcons:{},folderSwitcherIncludePinned:!1,foldersAlwaysNewTab:!1,importExcludePrefixes:"_",lockedSubtrees:[],searchOpensInNewTab:!0,pinnedNotes:[],hideMobileToolbarInStashpad:!0,slugStopWords:[],searchIncludedFolders:[],searchExcludedFolders:[],shortcuts:{move:"M",pickMove:"O",merge:"&",copy:"C",copyTree:"Y",openEditor:"Mod+Shift+E",openTab:"T",split:"S",edit:"E",editParent:"Shift+E",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,notifiedDueKeys:[],autoNavOnMoveIn:!1,autoNavOnMoveOut:!1,autoExpandCursorRow:!1,expandBodiesByDefault:!1,autoOpenDetailPanel:!1,doubleClickToFocus:!0,enableSheetVersions:!1,dateDisplayFormat:"locale",dateDisplayTimezone:"",jdIndexScope:"vault",jdIndexScopeFolder:"",jdIndexStashpadFolder:"",jdIndexFile:"Index",jdIndexIncludeStashpadFolders:!1,jdIndexSort:"natural",jdIndexHasBuilt:!1,okfEnabled:!1,okfTemplatePath:"",drafts:{},lastSubmitted:{},bindings:Xo()},Hr=JSON.parse(JSON.stringify(Mt)),Wo=new Set;hn=[{id:"foldersStorage",label:"\u{1F4C1} Folders & Storage"},{id:"importExport",label:"\u{1F504} Import & Export"},{id:"datesTime",label:"\u{1F552} Dates & Time"},{id:"behaviors",label:"\u{1F39B}\uFE0F Behavior"},{id:"notifications",label:"\u{1F514} Notifications"},{id:"encryption",label:"\u{1F512} Encryption"},{id:"authorship",label:"\u2712\uFE0F Authorship"},{id:"templates",label:"\u{1F4C4} Templates"},{id:"organizationSystems",label:"\u{1F5C2}\uFE0F Organization Systems"},{id:"maintenance",label:"\u{1F6E0}\uFE0F Maintenance"},{id:"diagnostics",label:"\u{1FA7A} Diagnostics"},{id:"hotkeys",label:"\u2328\uFE0F Hotkeys"}].sort((d,r)=>{let e=t=>t.replace(/^[^\p{L}\p{N}]+/u,"");return e(d.label).localeCompare(e(r.label))}),Vo=null;pn=class extends P.PluginSettingTab{constructor(e,t){super(e,t);this.plugin=t;this.pfeSelected=null;this.pfeRerender=null;this.iconPickFolder=null}display(){let{containerEl:e}=this;e.empty();for(let t of hn){new P.Setting(e).setName(t.label).setHeading();let i=this.itemsForTab(t.id);if(i)for(let s of i){let n=new P.Setting(e);typeof s.render=="function"?s.render(n):(s.name&&n.setName(s.name),s.desc&&n.setDesc(s.desc))}else this.renderTabContent(e,t.id)}}getSettingDefinitions(){return hn.map(e=>{let t=this.itemsForTab(e.id);return t?{type:"page",name:e.label,items:t}:{type:"page",name:e.label,page:()=>ed(e.label,i=>this.renderTabContent(i,e.id))}})}itemsForTab(e){switch(e){case"hotkeys":return this.hotkeyItems();case"diagnostics":return this.diagnosticsItems();case"notifications":return this.notificationsItems();case"foldersStorage":return this.buildGeneralCategories().foldersStorage;case"importExport":return this.buildGeneralCategories().importExport;case"datesTime":return this.buildGeneralCategories().datesTime;case"maintenance":return this.buildGeneralCategories().maintenance;case"behaviors":{let t=this.buildGeneralCategories();return[this.headingDef("\u{1F4CB} List & Display"),...t.listDisplay,this.headingDef("\u2195\uFE0F Moving Notes"),...t.movingNotes,this.headingDef("\u270D\uFE0F Composer & Copying"),...t.composerCopy,this.headingDef("\u{1F5D1}\uFE0F Deleting"),...t.deleting,this.headingDef("\u{1FA9F} Windows & Tabs"),...t.windowsTabs,this.headingDef("\u2699\uFE0F Misc"),...t.misc]}case"organizationSystems":return[this.headingDef("\u{1F522} JD Index (Johnny Decimal)"),...this.jdIndexItems(),this.headingDef("\u{1F4DA} Open Knowledge Format (OKF)"),...this.okfItems()];case"encryption":return this.encryptionItems();case"authorship":return this.authorshipItems();case"templates":return this.templatesItems();default:return null}}renderTabContent(e,t){switch(t){case"authorship":this.renderAuthorshipSection(e);break;case"templates":this.renderTemplatesTab(e);break}}diagnosticsItems(){return[this.renderDef("Performance profiling","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.",e=>e.addToggle(t=>t.setValue(this.plugin.settings.enablePerfProfiling).onChange(async i=>{this.plugin.settings.enablePerfProfiling=i,await this.plugin.saveSettings()})),["perf","profiling","timing","slow"]),this.renderDef("Debug trace","Record low-level diagnostic lines (e.g. tap coordinates vs the row they resolve to) to an in-memory buffer while you reproduce a bug, then copy them below to share. Local only \u2014 no network, no file writes; zero overhead when off.",e=>e.addToggle(t=>t.setValue(this.plugin.settings.debugTrace).onChange(async i=>{this.plugin.settings.debugTrace=i,await this.plugin.saveSettings()})),["debug","trace","diagnostics","tap","log"]),this.renderDef("Copy / clear debug trace","Copy the captured debug lines to the clipboard (paste them back to share), or clear the buffer to start a fresh capture.",e=>{e.addButton(t=>t.setButtonText("Copy").onClick(async()=>{let i=this.plugin.getDebugTrace();if(!i){new P.Notice("Debug trace is empty \u2014 enable it and reproduce the issue first.");return}try{await navigator.clipboard.writeText(i),new P.Notice("Debug trace copied.")}catch{new P.Notice("Couldn't access clipboard.")}})),e.addButton(t=>t.setButtonText("Clear").onClick(()=>{this.plugin.clearDebugTrace(),new P.Notice("Debug trace cleared.")}))},["debug","trace","copy","clear"]),this.renderDef("Open log file","Append-only history of creates, deletes, parent changes, renames. Stored alongside the plugin's other private files.",e=>e.addButton(t=>t.setButtonText("Open log").onClick(async()=>{let i=this.app.vault.adapter,s=this.plugin.pluginPrivatePath("log.jsonl");if(!await i.exists(s)){new P.Notice("No log yet \u2014 make some changes first.");return}let n=await i.read(s);new Ei(this.app,n,s).open()})),["log","history","diagnostics"])]}notificationsItems(){let e=new Set(this.plugin.settings.mutedNotificationCategories??[]),t=Object.keys(Do);return[this.renderDef("Notification history limit","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.",i=>i.addText(s=>{s.setValue(String(this.plugin.settings.notificationHistoryLimit??5e3)).setPlaceholder("5000");let n=async()=>{let o=parseInt(s.getValue(),10);if(!Number.isFinite(o)||o<0){s.setValue(String(this.plugin.settings.notificationHistoryLimit??5e3));return}this.plugin.settings.notificationHistoryLimit=o,this.plugin.notifications.setHistoryLimit(o),await this.plugin.saveSettings()};s.inputEl.addEventListener("blur",()=>void n()),s.inputEl.addEventListener("keydown",o=>{o.key==="Enter"&&n()})}),["notification","history","limit"]),{type:"group",heading:"Mute notification categories",items:t.map(i=>{let s=Do[i];return this.renderDef(s.label,s.desc,n=>n.addToggle(o=>o.setValue(!e.has(i)).onChange(async a=>{let l=!a;l?e.add(i):e.delete(i),this.plugin.settings.mutedNotificationCategories=Array.from(e),this.plugin.notifications.setMuted(i,l),await this.plugin.saveSettings()})),["notification","mute","toast","category"])})},this.renderDef("Notification history","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.",i=>i.addButton(s=>s.setButtonText("View notification history").onClick(()=>{new ds(this.app,this.plugin.notifications,async n=>{let o=this.app.vault.adapter,a=this.plugin.pluginPrivatePath("log.jsonl");if(!await o.exists(a)){new P.Notice("No log yet \u2014 make some changes first.");return}let l=await o.read(a);new Ei(this.app,l,a).open()},this.plugin.settings.authorId||null,n=>this.plugin.lookupNoteAuthorIds(n)).open()})),["notification","history","panel"])]}renderTemplatesTab(e){this.renderColorAliasesSection(e),this.renderNoteTemplatesSection(e)}renderDef(e,t,i,s){return{name:e,desc:t,aliases:s,render:n=>{n.setName(e).setDesc(t);try{i(n)}catch(o){console.error(`[Stashpad] settings control "${e}" failed to render:`,o)}}}}sectionDef(e,t,i,s){return{name:e,desc:t,aliases:s,render:n=>{let o=n.settingEl;o.empty(),o.removeClass("setting-item"),o.addClass("stashpad-settings-section");try{i(o)}catch(a){console.error(`[Stashpad] settings section "${e}" failed to render:`,a)}}}}headingDef(e,t){return this.sectionDef(e,t??"",i=>{let s=new P.Setting(i).setName(e).setHeading();t&&s.setDesc(t)},[e.toLowerCase()])}folderKeyLabel(e){let t=new Date,i=a=>String(a).padStart(2,"0"),s=`${t.getFullYear()}${i(t.getMonth()+1)}${i(t.getDate())}-${i(t.getHours())}${i(t.getMinutes())}`,n=(this.plugin.settings.authorName||"").trim(),o=n?n.split(/\s+/).map(a=>a[0]).join(""):(this.plugin.settings.authorId||"anon").slice(0,4);return`${s} - ${e.split("/").pop()||e} - ${o}`}promptSetFolderPassword(e){new Le(this.app,{mode:"setup",offerKeychain:!0,title:`Set password for \u201C${e.split("/").pop()}\u201D`,intro:"A separate password just for this folder. Share it with collaborators out-of-band (a password manager, Signal, in person). There is NO recovery if it's lost.",onSubmit:async({next:t,remember:i})=>{if(!t)return"Enter a password.";try{await this.plugin.encryption.setupFolderKey(e,t,this.folderKeyLabel(e),i)}catch(s){return s.message}return new P.Notice("Folder password set \u2014 share it securely."),this.update?.(),this.pfeRerender?.(),null}}).open()}promptChangeFolderPassword(e){new Le(this.app,{mode:"setup",offerKeychain:!0,title:`Change password for \u201C${e.split("/").pop()}\u201D`,intro:"Re-wraps this folder's key under a new password. The OLD password stops working on THIS device right away (un-synced copies elsewhere keep working until they sync). To truly cut off someone who left, remove encryption and re-encrypt the folder under a fresh password.",onSubmit:async({next:t,remember:i})=>{if(!t)return"Enter a password.";try{await this.plugin.encryption.changeFolderPassword(e,t,i)}catch(s){return s.message}return new P.Notice("Folder password changed."),this.update?.(),this.pfeRerender?.(),null}}).open()}promptSetFolderRecovery(e){let t=e.split("/").pop()||e;new Le(this.app,{mode:"setup",offerKeychain:!1,title:`Recovery password for \u201C${t}\u201D`,intro:"A SECOND password that also unlocks this folder \u2014 a backup in case the main password is lost. It wraps the same key, so it's exactly as sensitive: store it somewhere safe and separate. Setting it again replaces any existing recovery password.",onSubmit:async({next:i})=>{if(!i)return"Enter a password.";try{await this.plugin.encryption.setFolderRecoveryPassword(e,i)}catch(s){return s.message}return new P.Notice("Recovery password set \u2014 keep it somewhere safe."),this.update?.(),this.pfeRerender?.(),null}}).open()}promptRemoveFolderRecovery(e){let t=e.split("/").pop()||e;new j(this.app,`Remove recovery password for \u201C${t}\u201D?`,"The recovery password will no longer unlock this folder. The main folder password is unchanged. You can add a new recovery password later.","Remove recovery",async i=>{if(i){try{await this.plugin.encryption.removeFolderRecoveryPassword(e)}catch(s){new P.Notice(s.message);return}new P.Notice("Recovery password removed."),this.update?.(),this.pfeRerender?.()}}).open()}promptUnlockFolder(e){new Le(this.app,{mode:"unlock",offerKeychain:!0,title:`Unlock \u201C${e.split("/").pop()}\u201D`,intro:"Enter this folder's password.",onSubmit:async({current:t,remember:i})=>await this.plugin.encryption.unlockFolder(e,t,i)?(new P.Notice("Folder unlocked."),this.update?.(),this.pfeRerender?.(),null):"Wrong password. Try again."}).open()}renderPerFolderEncryption(e){let t=this.plugin.discoverStashpadFolders();if(t.length===0){e.createEl("p",{cls:"setting-item-description"}).setText("No Stashpad folders found yet.");return}(!this.pfeSelected||!t.includes(this.pfeSelected))&&(this.pfeSelected=t[0]);let i=e.createDiv({cls:"stashpad-folderenc-panel"});this.pfeRerender=()=>{i.empty(),this.renderFolderEncPanel(i,this.pfeSelected)},new P.Setting(e).setName("Folder").setDesc("Pick a folder to configure its password, archive, and trash options. Everything below applies to the selected folder only.").setHeading().addDropdown(s=>{for(let n of t)s.addOption(n,n);s.setValue(this.pfeSelected),s.selectEl.addClass("stashpad-folderenc-picker"),s.onChange(n=>{this.pfeSelected=n,this.pfeRerender?.()})}),e.appendChild(i),this.renderFolderEncPanel(i,this.pfeSelected)}renderFolderEncPanel(e,t){let i=this.plugin.encryption,s=i.hasOwnFolderKey(t),n=i.folderKeyEntry(t)?.folderPath??null,o=!!n&&!s,a=i.isFolderUnlocked(t),l=(this.plugin.settings.folderEncPrefs??{})[t]??{},c=s?a?"Has its own password \xB7 unlocked":"Has its own password \xB7 locked":o?`Inherits \u201C${n.split("/").pop()||n}\u201D's password \xB7 ${a?"unlocked":"locked"}`:"Uses the vault password",A=new P.Setting(e).setName("Password").setDesc(c);if(o?A.addButton(u=>u.setButtonText("Manage on parent folder").onClick(()=>{this.pfeSelected=n,this.update?.(),this.pfeRerender?.()})):s?a?A.addButton(u=>u.setButtonText("Change password\u2026").onClick(()=>this.promptChangeFolderPassword(t))):A.addButton(u=>u.setButtonText("Unlock\u2026").setCta().onClick(()=>this.promptUnlockFolder(t))):A.addButton(u=>u.setButtonText("Set folder password\u2026").setCta().onClick(()=>this.promptSetFolderPassword(t))),s&&a){let u=this.plugin.encryption.folderHasRecovery(t),g=new P.Setting(e).setName("Recovery password").setDesc(u?"A second password that also unlocks this folder. Keep it somewhere safe and separate.":"Optional. Add a second password that also unlocks this folder, as a backup if the main one is lost.");g.addButton(I=>I.setButtonText(u?"Change recovery\u2026":"Add recovery\u2026").onClick(()=>this.promptSetFolderRecovery(t))),u&&g.addButton(I=>{I.setButtonText("Remove recovery").onClick(()=>this.promptRemoveFolderRecovery(t)),I.buttonEl.addClass("mod-warning")})}let h=async u=>{this.plugin.settings.folderEncPrefs={...this.plugin.settings.folderEncPrefs??{},[t]:{...(this.plugin.settings.folderEncPrefs??{})[t]??{},...u}},await this.plugin.saveSettings()};new P.Setting(e).setName("Trash handling").setDesc("Where notes deleted from this folder go.").addDropdown(u=>u.addOption("","Stashpad trash (default)").addOption("obsidian","Obsidian native trash").setValue(l.trashHandling==="obsidian"?"obsidian":"").onChange(g=>h({trashHandling:g||void 0})));let p=(u,g,I,m,C=!1)=>{new P.Setting(e).setName(u).addToggle(B=>B.setValue(!!l[g]).onChange(async E=>{if(E&&C){if(!this.plugin.encryption.hasFolderKey(t)){new P.Notice("Give this folder a password first (the \u201CSet folder password\u2026\u201D button above), then enable this."),this.pfeRerender?.();return}if(!await this.plugin.ensureFolderUnlocked(t)){this.pfeRerender?.();return}}let y={};y[g]=E,E||(y[I]=!1),await h(y),m&&await m(E),this.pfeRerender?.()})),new P.Setting(e).setName(`\u21B3 ${u} \u2014 hide filenames`).setClass("stashpad-subsetting").addToggle(B=>{B.setValue(!!l[I]),B.setDisabled(!l[g]),B.onChange(async E=>{let y={};y[I]=E,await h(y),this.pfeRerender?.()})})};p("Encrypt this folder's notes","encryptContent","encryptFilenames",async u=>{u?await this.plugin.lockFolder(t):await this.plugin.unlockFolder(t);let g=(this.plugin.settings.lockedSubtrees??[]).some(I=>(I.folder||"").replace(/\/+$/,"")===t);await h({encryptContent:g,...g?{}:{encryptFilenames:!1}})}),p("Encrypt archived notes","archiveEncryptContent","archiveEncryptFilenames",async u=>{if(!u)return;let g=this.plugin.archivedPlainNotesIn(`${t}/archive`).length;g!==0&&new j(this.app,`Encrypt the ${g} note${g===1?"":"s"} already archived?`,`\u201C${t.split("/").pop()}\u201D's archive already holds ${g} plaintext note${g===1?"":"s"}. Encrypt ${g===1?"it":"them"} now too? (Skipping leaves ${g===1?"it":"them"} readable; only notes archived from now on get encrypted.)`,"Encrypt them",async I=>{if(!I)return;let m=await this.plugin.encryptExistingArchiveNotes(t);new P.Notice(m>0?`Encrypted ${m} archived note${m===1?"":"s"}.`:"Nothing was encrypted (cancelled or already locked)."),this.pfeRerender?.()}).open()},!0),p("Encrypt trashed notes","trashEncryptContent","trashEncryptFilenames",void 0,!0),new P.Setting(e).setName("Auto re-encrypt after idle minutes").setDesc("Override the global auto-re-encrypt timer for this folder. Blank = use global; 0 = off for this folder. A cancellable countdown always shows first, and open notes are never touched.").addText(u=>{u.setPlaceholder("global"),u.setValue(l.reEncryptAfterMin==null?"":String(l.reEncryptAfterMin)),u.onChange(g=>{let I=g.trim();{let m=Number(I);I===""?h({reEncryptAfterMin:void 0}):Number.isFinite(m)&&m>=0?h({reEncryptAfterMin:Math.floor(m)}):u.setValue(l.reEncryptAfterMin==null?"":String(l.reEncryptAfterMin))}})});let f=this.plugin.discoverStashpadFolders().filter(u=>u!==t&&u.startsWith(t+"/")).sort();if(f.length){new P.Setting(e).setName("Subfolders").setDesc(`${f.length} subfolder${f.length===1?"":"s"} \u2014 they use \u201C${t.split("/").pop()}\u201D's password. Encrypt each individually.`).setHeading();for(let u of f){let g=(this.plugin.settings.folderEncPrefs??{})[u]??{},I=async B=>{this.plugin.settings.folderEncPrefs={...this.plugin.settings.folderEncPrefs??{},[u]:{...(this.plugin.settings.folderEncPrefs??{})[u]??{},...B}},await this.plugin.saveSettings()},m=(this.plugin.settings.lockedSubtrees??[]).some(B=>(B.folder||"").replace(/\/+$/,"")===u),C=u.slice(t.length+1);new P.Setting(e).setName(C).addToggle(B=>B.setValue(m).onChange(async E=>{E?await this.plugin.lockFolder(u):await this.plugin.unlockFolder(u);let y=(this.plugin.settings.lockedSubtrees??[]).some(v=>(v.folder||"").replace(/\/+$/,"")===u);await I({encryptContent:y,...y?{}:{encryptFilenames:!1}}),this.update?.(),this.pfeRerender?.()})),new P.Setting(e).setName(`\u21B3 ${C} \u2014 hide filenames`).setClass("stashpad-subsetting").addToggle(B=>{B.setValue(!!g.encryptFilenames),B.setDisabled(!m),B.onChange(E=>void I({encryptFilenames:E}))})}}}buildGeneralCategories(){let e=async()=>this.plugin.saveSettings(),t=(s,n,o,a,l)=>this.renderDef(s,n,c=>c.addToggle(A=>A.setValue(o()).onChange(async h=>{a(h),await e()})),l),i={foldersStorage:[],importExport:[],datesTime:[],listDisplay:[],movingNotes:[],deleting:[],composerCopy:[],windowsTabs:[],maintenance:[],misc:[]};i.foldersStorage.push(this.renderDef("Stashpad notes folder","Vault-relative folder where Stashpad stores its notes and attachments. Created on demand.",s=>{s.addText(n=>{new fi(this.app,n.inputEl),n.setValue(this.plugin.settings.folder).setPlaceholder("Stashpad");let o=async()=>{let a=(n.getValue()||"").trim().replace(/^\/+|\/+$/g,"")||Mt.folder,l=a.split("/").filter(Boolean),c=new Set([this.plugin.settings.importDropFolder,this.plugin.settings.exportFolder,"_attachments","_processed","_authors","_deleted","archive","trash",".stashpad"].map(A=>(A??"").trim().replace(/^\/+|\/+$/g,"")).filter(Boolean));if(l.some(A=>c.has(A))){new P.Notice(`"${a}" uses a reserved Stashpad subfolder name. Pick something else.`),n.setValue(this.plugin.settings.folder);return}a!==this.plugin.settings.folder&&(this.plugin.settings.folder=a,await e())};n.inputEl.addEventListener("blur",()=>void o()),n.inputEl.addEventListener("keydown",a=>{a.key==="Enter"&&o()})})},["folder","path","location","notes"])),i.importExport.push(t("Auto-import dropped files","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.",()=>this.plugin.settings.autoImport,s=>{this.plugin.settings.autoImport=s},["import","drop","auto"])),i.foldersStorage.push(t("Inherit Obsidian's excluded files","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.",()=>this.plugin.settings.inheritObsidianExclusions,s=>{this.plugin.settings.inheritObsidianExclusions=s},["excluded","ignore","files"])),i.foldersStorage.push(t("Include pinned notes in the folder switcher","When on, the folder switcher / creator (the folder button and the \u201COpen or switch Stashpad folder\u201D command) also lists your pinned notes, so you can jump straight to one. Off keeps the picker focused on folders.",()=>this.plugin.settings.folderSwitcherIncludePinned,s=>{this.plugin.settings.folderSwitcherIncludePinned=s},["pinned","switcher","folder","picker","jump"])),i.foldersStorage.push(this.renderDef("Folder tab icon","Give a folder its own Lucide icon (e.g. rocket, star, book-open) shown on its tab, the folder switcher, and its folder-panel row. Pick a folder, then start typing in the icon box \u2014 matching icons appear with previews; pick one. Blank = the default icon. Set per folder.",s=>{let n=this.plugin.discoverStashpadFolders();if(n.length===0){s.setDesc("No Stashpad folders found yet.");return}(!this.iconPickFolder||!n.includes(this.iconPickFolder))&&(this.iconPickFolder=n[0]);let o=null,a=s.controlEl.createSpan({cls:"stashpad-folder-icon-preview"}),l=c=>{a.empty();let A=c.trim();A&&(0,P.setIcon)(a,A)};s.addDropdown(c=>{for(let A of n)c.addOption(A,A.split("/").pop()||A);c.setValue(this.iconPickFolder),c.onChange(A=>{this.iconPickFolder=A;let h=this.plugin.getFolderIcon(A)??"";o?.setValue(h),l(h)})}),s.addText(c=>{o=c,c.setPlaceholder("type to search\u2026 (e.g. rocket)"),new js(this.app,c.inputEl),c.setValue(this.plugin.getFolderIcon(this.iconPickFolder)??""),c.onChange(async A=>{l(A),await this.plugin.setFolderIcon(this.iconPickFolder,A.trim())})}),l(this.plugin.getFolderIcon(this.iconPickFolder)??"")},["icon","folder","tab","lucide","emoji","switcher"])),i.importExport.push(this.renderDef("Dedicated import subfolder (optional)","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.",s=>s.addText(n=>n.setValue(this.plugin.settings.importDropFolder).setPlaceholder("_imports (leave blank to use the folder root)").onChange(async o=>{this.plugin.settings.importDropFolder=(o||"").trim().replace(/^\/+|\/+$/g,""),await e()})),["import","subfolder"])),i.importExport.push(this.renderDef("Stash export subfolder","Subfolder name (relative to each Stashpad folder) where exports land. Must differ from the import subfolder above.",s=>s.addText(n=>n.setValue(this.plugin.settings.exportFolder).setPlaceholder("_exports").onChange(async o=>{this.plugin.settings.exportFolder=(o||"").trim().replace(/^\/+|\/+$/g,"")||Mt.exportFolder,await e()})),["export","stash","subfolder"])),i.importExport.push(this.renderDef("Exclude subfolders by prefix","Comma-separated name prefixes (default \u201C_\u201D). A subfolder whose name starts with any of these \u2014 at any depth \u2014 is NOT surfaced as a Stashpad folder or imported (it stays local). To encrypt such a folder, right-click it in Obsidian's file explorer \u2192 \u201C\u{1F512} Encrypt with Stashpad\u201D.",s=>s.addText(n=>n.setValue(this.plugin.settings.importExcludePrefixes??"_").setPlaceholder("_").onChange(async o=>{this.plugin.settings.importExcludePrefixes=o,await e()})),["import","exclude","prefix","subfolder","underscore","ignore"])),i.maintenance.push(this.renderDef("Rebootstrap existing Stashpad folders","Walk every folder that has a home note: ensure infrastructure (_imports, _exports, drafts file), backfill the redundant parentLink + children frontmatter fields, rename any note whose filename slug no longer matches its body's first line, AND migrate legacy attachment filenames to the new name-first format (`photo-<id>.png`). Safe to run anytime; skip-if-equal means already-synced notes are no-op writes.",s=>s.addButton(n=>n.setButtonText("Rebootstrap now").onClick(async()=>{n.setDisabled(!0).setButtonText("Working\u2026");try{await this.plugin.runRebootstrapWithUI()}catch{}finally{n.setDisabled(!1).setButtonText("Rebootstrap now")}})),["rebootstrap","rebuild","repair","backfill","slug"])),i.maintenance.push(this.renderDef("Write recovery navigation links","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.",s=>s.addToggle(n=>n.setValue(this.plugin.settings.writeRecoveryLinks).onChange(async o=>{this.plugin.settings.writeRecoveryLinks=o,await e()})),["recovery","parentlink","children","frontmatter"]));{let s=null,n=()=>{s&&s.setText(`Sample: ${it(Date.now(),this.plugin.settings)}`)};i.datesTime.push(this.renderDef("Date display format","How created / edited timestamps and due dates are shown \u2014 in the notes list, the Tasks panel, and the detail panel. Overridden by the Templates-plugin formats when the option below is on.",o=>{o.addDropdown(a=>{a.addOption("locale","Locale, short (Mar 5, 9:00 AM)"),a.addOption("long","Locale, long (Thursday, March 5\u2026)"),a.addOption("iso","ISO (2026-03-05 09:00)"),a.addOption("us","US (3/5/2026, 9:00 AM)"),a.addOption("eu","EU (5/3/2026, 09:00)"),a.setValue(this.plugin.settings.dateDisplayFormat??"locale"),a.onChange(async l=>{this.plugin.settings.dateDisplayFormat=l,await e(),n()})})},["date","format","display"])),i.datesTime.push(this.renderDef("Use Templates plugin date/time formats","Use the date/time formats configured in the core Templates plugin instead of the Date display format above. Off = the Date display format above is used everywhere.",o=>{o.addToggle(l=>l.setValue(this.plugin.settings.useTemplatesFormat).onChange(async c=>{this.plugin.settings.useTemplatesFormat=c,await e(),n()}));let a=gn(this.app);o.descEl.createDiv({cls:"stashpad-settings-note"}).setText(a?`Templates plugin: date = "${a.dateFormat}", time = "${a.timeFormat}"`:"Templates plugin not enabled.")},["templates","date","time","format"])),i.datesTime.push(this.renderDef("Display timezone","IANA timezone name (e.g. America/New_York, Europe/London, Asia/Kolkata). Leave blank to use your system timezone.",o=>{o.addText(a=>{a.setPlaceholder("(system timezone)"),a.setValue(this.plugin.settings.dateDisplayTimezone??""),a.onChange(async l=>{this.plugin.settings.dateDisplayTimezone=(l||"").trim(),await e(),n()})})},["timezone","tz","date","iana"])),i.datesTime.push(this.renderDef("Quick due-date adjustments","Comma-separated relative amounts shown as quick +/- buttons in the due-date and snooze pickers (e.g. 5m, 15m, 1h, 1d, 1w). Units: m=minutes, h=hours, d=days, w=weeks. A +/- flip in the picker toggles add vs subtract. Leave blank to hide the row.",o=>{o.addText(a=>{a.setPlaceholder("5m, 15m, 1h, 1d, 1w"),a.setValue((this.plugin.settings.dueQuickAdjusts??[]).join(", ")),a.onChange(async l=>{let c=l.split(",").map(A=>A.trim()).filter(A=>/^\d+\s*[mhdw]$/i.test(A)).map(A=>A.replace(/\s+/g,"").toLowerCase());this.plugin.settings.dueQuickAdjusts=c,await e()})})},["quick","adjust","snooze","due","preset","increment","decrement"])),i.datesTime.push({name:"Date sample",searchable:!1,render:o=>{let a=o.settingEl;a.empty(),a.removeClass("setting-item"),a.addClass("stashpad-settings-section"),s=a.createDiv({cls:"setting-item-description stashpad-settings-note stashpad-date-sample"}),n()}})}return i.movingNotes.push(t("Navigate into parent after moving a note IN","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.",()=>this.plugin.settings.autoNavOnMoveIn,s=>{this.plugin.settings.autoNavOnMoveIn=s},["navigate","move","in"])),i.movingNotes.push(t("Navigate to destination after moving a note OUT","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.",()=>this.plugin.settings.autoNavOnMoveOut,s=>{this.plugin.settings.autoNavOnMoveOut=s},["navigate","move","out"])),i.listDisplay.push(t("Double-click a note to open it","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.",()=>this.plugin.settings.doubleClickToFocus,s=>{this.plugin.settings.doubleClickToFocus=s},["double","click","open","focus"])),i.misc.push(t("Sheet versions (alternate drafts)",`Treat notes that share a 'sheet-group' frontmatter id as alternate versions of one item: only the active version shows as a row, and its siblings collapse into a tab bar at the bottom of that row. Use "Fork as version" on a note to start. Off by default \u2014 when off, no note is ever hidden by this feature and the commands do nothing.`,()=>this.plugin.settings.enableSheetVersions,s=>{this.plugin.settings.enableSheetVersions=s},["sheet","version","draft","alternate","fork"])),i.listDisplay.push(t("Auto-open the detail panel","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.",()=>this.plugin.settings.autoOpenDetailPanel,s=>{this.plugin.settings.autoOpenDetailPanel=s},["detail","panel","sidebar"])),i.listDisplay.push(t("Expand the cursor row's body automatically","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.",()=>this.plugin.settings.autoExpandCursorRow,s=>{this.plugin.settings.autoExpandCursorRow=s},["expand","cursor","body"])),i.listDisplay.push(t("Expand note bodies by default","Show every note's full body by default instead of clamping long notes. The per-note 'Show more / show less' toggle and the Expand-all / Collapse-all commands then work in reverse \u2014 they let you collapse individual notes back down. Off = bodies clamp by default (expand is opt-in).",()=>this.plugin.settings.expandBodiesByDefault,s=>{this.plugin.settings.expandBodiesByDefault=s},["expand","collapse","default","body","clamp"])),i.movingNotes.push(t("Confirm cross-parent drag-and-drop","When dragging notes onto a note that has a different parent, ask before re-parenting (turn off to allow direct moves).",()=>this.plugin.settings.confirmCrossParentDrag,s=>{this.plugin.settings.confirmCrossParentDrag=s},["confirm","drag","drop","reparent"])),i.deleting.push(t("Confirm bulk deletes","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).",()=>this.plugin.settings.confirmBulkDelete,s=>{this.plugin.settings.confirmBulkDelete=s},["confirm","delete","bulk"])),i.deleting.push(t("Offer to delete attachments with note",`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.`,()=>this.plugin.settings.confirmAttachmentDelete,s=>{this.plugin.settings.confirmAttachmentDelete=s},["delete","attachment","orphan"])),i.foldersStorage.push(this.sectionDef("Cross-Stashpad Search Scope","Toggle each Stashpad's pill to choose whether its notes contribute to cross-folder search. Excluded folders are still valid move destinations. Also: create a new Stashpad.",s=>{let n=this.plugin.discoverStashpadFolders();if(new P.Setting(s).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."),n.length===0)s.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 a=s.createDiv({cls:"stashpad-folder-list"});for(let l of n)this.renderFolderScopeRow(a,l)}let o=null;new P.Setting(s).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(a=>{a.setPlaceholder("my-stashpad"),o=a.inputEl}).addButton(a=>a.setButtonText("Create").setCta().onClick(async()=>{let l=(o?.value??"").trim().replace(/^\/+|\/+$/g,"");if(!l){new P.Notice("Enter a folder name first.");return}try{await this.plugin.createNewStashpad(l),new P.Notice(`Created Stashpad "${l}".`),o&&(o.value=""),await this.plugin.waitForStashpadFolder(l,2e3),this.update?.()}catch(c){new P.Notice(`Couldn't create: ${c.message}`)}}))},["search","scope","exclude","include","create","new","stashpad","folder"])),i.foldersStorage.push(this.sectionDef("Folder Panel Placement","Pin, downrank, or hide folders in the Stashpad folder panel. Restore hidden folders here or from the panel's \u201CHidden\u201D section.",s=>{new P.Setting(s).setName("Folder Panel Placement").setDesc("Folders you've pinned, downranked, or hidden in the Stashpad folder panel. Pin/downrank from a folder's right-click menu in the panel; restore here or from the panel's \u201CHidden\u201D section."),this.renderFolderPlacementList(s)},["folder","panel","pin","pinned","downrank","hide","hidden","restore","placement"])),i.foldersStorage.push(this.headingDef("\u{1F3F7}\uFE0F Note Titles")),i.foldersStorage.push(this.renderDef("Slug stop-words","Words removed from auto-generated note titles (filenames). One per line.",s=>{let n=null,o=(this.plugin.settings.slugStopWords?.length?this.plugin.settings.slugStopWords:st).join(` +`}function Zs(A,r){let e=document.createDocumentFragment();e.createEl("div",{text:"Home note updated"}).setCssStyles({fontWeight:"600",marginBottom:"6px"});let i=e.createEl("ul");i.setCssStyles({margin:"0 0 8px 0",paddingLeft:"18px"}),i.createEl("li",{text:`${r.indexed.length} indexed`}),i.createEl("li",{text:`${r.nonIndex.length+r.skippedStashpadNotes.length} excluded`});let s=e.createEl("button",{text:"Open",cls:"mod-cta"});s.setCssStyles({padding:"2px 10px",fontSize:"var(--font-ui-smaller)"});let n;return s.onclick=async o=>{if(o.stopPropagation(),r.previewPath){let a=A.vault.getAbstractFileByPath(r.previewPath);a instanceof Ee.TFile&&await A.workspace.getLeaf("tab").openFile(a)}n?.hide()},n=new Ee.Notice(e,0),n}var Ee,Ar,ts,is=de(()=>{"use strict";Ee=require("obsidian");ui();ce();Ar=/^(\d+-\d+|\d+|[A-Za-z0-9]+(?:\.[A-Za-z0-9]+)+)\s+(.+)$/;ts=class extends Ee.Modal{constructor(e,t,i,s,n){super(e);this.plugin=t;this.settings=i;this.indexedCount=s;this.onBuild=n;this.LARGE_BUILD=50;this.previewRan=!1;this.previewPath=null}onOpen(){let{contentEl:e,titleEl:t}=this,i=!this.settings.jdIndexHasBuilt,s=this.indexedCount>this.LARGE_BUILD;t.setText(i?"Build JD index \u2014 first time?":"Build JD index");let n=this.settings.jdIndexStashpadFolder,o=e.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."),e.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&&e.createEl("p",{cls:"setting-item-description"}).setText(`\u2713 Preview written to home note (${this.previewPath}). Open it before building if you haven't.`);let l=new Ee.Setting(e);(i||s)&&l.addButton(c=>{c.setButtonText(this.previewRan?"Re-run preview":"Run preview first"),c.setCta(),c.onClick(async()=>{try{let d=await Xs(this.app,this.plugin,this.settings);if(d.error==="no-dest"){new Ee.Notice("Set a Designated Stashpad folder for Index first.",5e3),this.close();return}if(d.error==="no-home"){new Ee.Notice(`"${this.settings.jdIndexStashpadFolder}" has no Stashpad home note. Open the folder in Stashpad first.`,7e3),this.close();return}this.previewRan=!0,this.previewPath=d.previewPath,Zs(this.app,d),this.contentEl.empty(),this.titleEl.empty(),this.onOpen()}catch(d){new Ee.Notice(`Preview failed: ${d?.message??d}`,8e3)}})}),l.addButton(c=>{c.setButtonText(i?"Build anyway":"Build"),!i&&!s&&c.setCta(),c.onClick(async()=>{this.close(),await this.onBuild()})}),l.addButton(c=>{c.setButtonText("Cancel"),c.onClick(()=>this.close())})}onClose(){this.contentEl.empty()}}});var _s,Ii,ur=de(()=>{"use strict";_s=require("obsidian");ce();Ii=class extends _s.AbstractInputSuggest{constructor(e,t){super(e,t);this.inputEl=t}getSuggestions(e){let t=e.toLowerCase().split(/\s+/).filter(Boolean),i=o=>t.every(a=>o.toLowerCase().includes(a)),s=[],n=o=>{if(!(o.path!=="/"&&Js.has(o.name))){o.path!=="/"&&i(o.path)&&s.push(o);for(let a of o.children)a instanceof _s.TFolder&&n(a)}};return n(this.app.vault.getRoot()),s.slice(0,100)}renderSuggestion(e,t){t.setText(e.path)}selectSuggestion(e){this.setValue(e.path),this.inputEl.dispatchEvent(new Event("input",{bubbles:!0})),this.close()}}});var mi,en,fr=de(()=>{"use strict";mi=require("obsidian"),en=class A extends mi.AbstractInputSuggest{constructor(e,t){super(e,t);this.inputEl=t}static norm(e){return e.replace(/^lucide-/,"")}getSuggestions(e){let t=e.toLowerCase().split(/\s+/).filter(Boolean),i=new Set,s=[];for(let a of(0,mi.getIconIds)()){let l=A.norm(a);i.has(l)||(i.add(l),s.push(l))}let n=a=>t.every(l=>a.toLowerCase().includes(l)),o=t.length?s.filter(n):s;return o.sort(),o.slice(0,t.length?50:300)}renderSuggestion(e,t){t.addClass("stashpad-icon-suggest-item");let i=t.createSpan({cls:"stashpad-icon-suggest-icon"});(0,mi.setIcon)(i,e),t.createSpan({cls:"stashpad-icon-suggest-label",text:e})}selectSuggestion(e){this.setValue(e),this.inputEl.dispatchEvent(new Event("input",{bubbles:!0})),this.close()}}});function ss(A,r,e){let t=A.vault.getAbstractFileByPath(r);if(!(t instanceof ft.TFile))return[];let i=[{label:"Reveal",keepOpen:!0,onClick:()=>{let s=A.workspace.getLeavesOfType("file-explorer")[0];if(!s)return;A.workspace.revealLeaf(s),s.view?.revealInFolder?.(t)}}];if(!e){let s=ft.Platform.isMacOS?"Finder":ft.Platform.isWin?"File Explorer":"file manager";i.push({label:`Show in ${s}`,keepOpen:!0,onClick:()=>{try{let n=window.require?.("electron")?.shell,a=A.vault.adapter?.getFullPath?.(r);a&&n?.showItemInFolder&&n.showItemInFolder(a)}catch(n){console.warn("[Stashpad] showItemInFolder failed",n)}}})}return i}var ft,To,vc,Ir,tn,sn=de(()=>{"use strict";ft=require("obsidian"),To={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)."},reminder:{label:"Reminder",desc:"Task due-date reminders \u2014 surfaced when a task comes due (fired at launch / periodically)."},system:{label:"System",desc:"Plumbing toasts: backfill progress, integrity warnings, errors not tied to a verb."}},vc={info:4e3,success:4e3,warning:6e3,error:1e4},Ir=5e3,tn=class{constructor(r){this.app=r;this.history=[];this.nextId=1;this.historyLimit=Ir;this.changeListeners=new Set;this.muted=new Set;this.defaultAuthorId=null}setDefaultAuthorId(r){this.defaultAuthorId=r||null}show(r){let e=r.kind??"info",t=r.category??"system",i={id:this.nextId++,ts:Date.now(),message:r.message,kind:e,category:t,authorId:r.authorId??this.defaultAuthorId??void 0,affectedIds:r.affectedIds?r.affectedIds.slice():[],affectedPaths:r.affectedPaths?r.affectedPaths.slice():[],affectedAuthorIds:r.affectedAuthorIds?r.affectedAuthorIds.slice():[],folder:r.folder,actionLabels:(r.actions??[]).map(a=>a.label)};if(this.pushHistory(i),this.muted.has(t))return null;let s=this.buildContent(r,e),n=r.duration??vc[e],o=new ft.Notice(s,n);if(r.onBodyClick){let a=r.onBodyClick,l=o.containerEl??o.noticeEl;if(l){l.classList.add("stashpad-notice-clickable"),l.setAttribute("tabindex","0"),l.setAttribute("role","button"),l.setAttribute("aria-label",`${r.message} \u2014 activate to open; use the button to snooze`);let c=()=>{Promise.resolve().then(()=>a()).catch(d=>console.warn("[Stashpad] notification body click failed",d)),o.hide()};l.addEventListener("click",d=>{d.target.closest(".stashpad-notice-action, .stashpad-notice-overlay")||c()}),l.addEventListener("keydown",d=>{d.target===l&&(d.key==="Enter"||d.key===" ")&&(d.preventDefault(),c())})}}return o}onChange(r){return this.changeListeners.add(r),()=>this.changeListeners.delete(r)}recent(){return this.history.slice().reverse()}clearHistory(){this.history=[],this.emit()}setMuted(r,e){e?this.muted.add(r):this.muted.delete(r)}isMuted(r){return this.muted.has(r)}loadMutedFromList(r){this.muted=new Set(r)}mutedList(){return Array.from(this.muted)}loadHistory(r){let e=this.applyLimit(r.slice());this.history=e;let t=0;for(let i of e)i.id>t&&(t=i.id);this.nextId=Math.max(this.nextId,t+1),this.emit()}setHistoryLimit(r){this.historyLimit=Number.isFinite(r)?r:Ir,this.history=this.applyLimit(this.history),this.emit()}applyLimit(r){return this.historyLimit<=0||r.length<=this.historyLimit?r:r.slice(r.length-this.historyLimit)}pushHistory(r){this.history.push(r),this.history=this.applyLimit(this.history),this.emit()}emit(){for(let r of this.changeListeners)try{r()}catch(e){console.warn("[Stashpad] notification listener failed",e)}}buildContent(r,e){let t=document.createDocumentFragment(),i=document.createElement("div");i.className=`stashpad-notice stashpad-notice-${e}`;let s=document.createElement("div");s.className="stashpad-notice-message";let n=r.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),r.actions&&r.actions.length>0){let o=document.createElement("div");o.className="stashpad-notice-actions";for(let a of r.actions){let l=document.createElement("button");l.className="stashpad-notice-action",l.textContent=a.label,l.addEventListener("click",c=>{if(c.stopPropagation(),Promise.resolve().then(()=>a.onClick()).catch(d=>console.warn("[Stashpad] notification action failed",d)),!a.keepOpen){let d=l.closest(".notice");d&&d.parentElement&&d.parentElement.removeChild(d)}}),o.appendChild(l)}i.appendChild(o)}if(r.overlayAction){let o=r.overlayAction;i.classList.add("has-overlay");let a=document.createElement("button");a.className="stashpad-notice-overlay",o.icon&&(0,ft.setIcon)(a,o.icon);let l=document.createElement("span");l.textContent=o.label,a.appendChild(l),a.title=o.title??o.label,a.addEventListener("click",c=>{if(c.stopPropagation(),Promise.resolve().then(()=>o.onClick()).catch(d=>console.warn("[Stashpad] notification overlay action failed",d)),!o.keepOpen){let d=a.closest(".notice");d&&d.parentElement&&d.parentElement.removeChild(d)}}),i.appendChild(a)}return t.appendChild(i),t}}});function Ci(A){if(!A)return"(none)";let r=A.replace(/\bMod\b/g,Mo?"Cmd":"Ctrl");return Mo&&(r=r.replace(/\bAlt\b/g,"Option")),r}function Cr(A,r,e={allowSingleKey:!0}){let t=A.placeholder,i=A.value;A.placeholder="Press a key\u2026 (Backspace to cancel)",A.value="",A.classList.add("is-recording");let s=!1,n=()=>{A.placeholder=t,A.classList.remove("is-recording"),s||(A.value=i),A.removeEventListener("keydown",o,!0),A.removeEventListener("blur",a)},o=l=>{if(l.key==="Control"||l.key==="Shift"||l.key==="Alt"||l.key==="Meta"||l.key==="OS")return;let c=!!l.code&&(/^Key[A-Z]$/.test(l.code)||/^Digit\d$/.test(l.code));if((l.key==="Dead"||l.key==="Process"||l.key==="Unidentified")&&!c)return;if(l.preventDefault(),l.stopPropagation(),l.key==="Backspace"&&!l.metaKey&&!l.ctrlKey&&!l.altKey&&!l.shiftKey){n();return}let d=[];Mo?(l.metaKey&&d.push("Mod"),l.ctrlKey&&d.push("Ctrl")):l.ctrlKey&&d.push("Mod"),l.altKey&&d.push("Alt"),l.shiftKey&&d.push("Shift");let h=Qc(l.key,l.code);if(!h||d.length===0&&!e.allowSingleKey)return;d.push(h);let p=d.join("+");s=!0,n(),r(p)},a=()=>n();return A.addEventListener("keydown",o,!0),A.addEventListener("blur",a),n}function Qc(A,r){if(!A)return"";if(r){let e=/^Key([A-Z])$/.exec(r);if(e)return e[1];let t=/^Digit(\d)$/.exec(r);if(t)return t[1]}return A.length===1?A.toUpperCase():A}var mr,Mo,Br=de(()=>{"use strict";mr=require("obsidian"),Mo=mr.Platform.isMacOS});function Vt(A,r,e,t){function i(s){return s instanceof e?s:new e(function(n){n(s)})}return new(e||(e=Promise))(function(s,n){function o(c){try{l(t.next(c))}catch(d){n(d)}}function a(c){try{l(t.throw(c))}catch(d){n(d)}}function l(c){c.done?s(c.value):i(c.value).then(o,a)}l((t=t.apply(A,r||[])).next())})}function kc(){return typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:global}function kr(A,r){return(A&15)+(A>>6|A>>3&8)<<4|(r&15)+(r>>6|r>>3&8)}function Fr(A,r){let e=r.length>>1;for(let t=0;t<e;t++){let i=t<<1;A[t]=kr(r.charCodeAt(i),r.charCodeAt(i+1))}}function Sc(A,r){if(A.length!==r.length*2)return!1;for(let e=0;e<r.length;e++){let t=e<<1;if(r[e]!==kr(A.charCodeAt(t),A.charCodeAt(t+1)))return!1}return!0}function Go(A,r,e){let t=0;for(let i=0;i<e;i++){let s=r[i]>>>4;A[t++]=s>9?s+yr:s+wr,s=r[i]&15,A[t++]=s>9?s+yr:s+wr}return String.fromCharCode.apply(null,A)}function Er(A,r=!0){let e=A.length,t=e%3,i=[],s=e-t;for(let n=0;n<s;n+=3){let o=(A[n]<<16&16711680)+(A[n+1]<<8&65280)+(A[n+2]&255),a=qe.charAt(o>>18&63)+qe.charAt(o>>12&63)+qe.charAt(o>>6&63)+qe.charAt(o&63);i.push(a)}if(t===1){let n=A[e-1],o=qe.charAt(n>>2),a=qe.charAt(n<<4&63);i.push(`${o}${a}`),r&&i.push("==")}else if(t===2){let n=(A[e-2]<<8)+A[e-1],o=qe.charAt(n>>10),a=qe.charAt(n>>4&63),l=qe.charAt(n<<2&63);i.push(`${o}${a}${l}`),r&&i.push("=")}return i.join("")}function bc(A){let r=Math.floor(A.length*.75),e=A.length;return A[e-1]==="="&&(r-=1,A[e-2]==="="&&(r-=1)),r}function Dc(A){let r=bc(A),e=A.length,t=new Uint8Array(r),i=0;for(let s=0;s<e;s+=4){let n=os[A.charCodeAt(s)],o=os[A.charCodeAt(s+1)],a=os[A.charCodeAt(s+2)],l=os[A.charCodeAt(s+3)];t[i]=n<<2|o>>4,i+=1,t[i]=(o&15)<<4|a>>2,i+=1,t[i]=(a&3)<<6|l&63,i+=1}return t}function Sr(A,r){return Vt(this,void 0,void 0,function*(){let e=null,t=null,i=!1;if(typeof WebAssembly>"u")throw new Error("WebAssembly is not supported in this environment!");let s=(y,v=0)=>{t.set(y,v)},n=()=>t,o=()=>e.exports,a=y=>{e.exports.Hash_SetMemorySize(y);let v=e.exports.Hash_GetBuffer(),Q=e.exports.memory.buffer;t=new Uint8Array(Q,v,y)},l=()=>new DataView(e.exports.memory.buffer).getUint32(e.exports.STATE_SIZE,!0),c=xc.dispatch(()=>Vt(this,void 0,void 0,function*(){if(!Ro.has(A.name)){let v=Dc(A.data),Q=WebAssembly.compile(v);Ro.set(A.name,Q)}let y=yield Ro.get(A.name);e=yield WebAssembly.instantiate(y,{})})),d=()=>Vt(this,void 0,void 0,function*(){e||(yield c);let y=e.exports.Hash_GetBuffer(),v=e.exports.memory.buffer;t=new Uint8Array(v,y,nn)}),h=(y=null)=>{i=!0,e.exports.Hash_Init(y)},p=y=>{let v=0;for(;v<y.length;){let Q=y.subarray(v,v+nn);v+=Q.length,t.set(Q),e.exports.Hash_Update(Q.length)}},f=y=>{if(!i)throw new Error("update() called before init()");let v=mt(y);p(v)},u=new Uint8Array(r*2),g=(y,v=null)=>{if(!i)throw new Error("digest() called before init()");return i=!1,e.exports.Hash_Final(v),y==="binary"?t.slice(0,r):Go(u,t,r)},I=()=>{if(!i)throw new Error("save() can only be called after init() and before digest()");let y=e.exports.Hash_GetState(),v=l(),Q=e.exports.memory.buffer,w=new Uint8Array(Q,y,v),k=new Uint8Array(ns+v);return Fr(k,A.hash),k.set(w,ns),k},m=y=>{if(!(y instanceof Uint8Array))throw new Error("load() expects an Uint8Array generated by save()");let v=e.exports.Hash_GetState(),Q=l(),w=ns+Q,k=e.exports.memory.buffer;if(y.length!==w)throw new Error(`Bad state length (expected ${w} bytes, got ${y.length})`);if(!Sc(A.hash,y.subarray(0,ns)))throw new Error("This state was written by an incompatible hash implementation");let D=y.subarray(ns);new Uint8Array(k,v,Q).set(D),i=!0},C=y=>typeof y=="string"?y.length<nn/4:y.byteLength<nn,B=C;switch(A.name){case"argon2":case"scrypt":B=()=>!0;break;case"blake2b":case"blake2s":B=(y,v)=>v<=512&&C(y);break;case"blake3":B=(y,v)=>v===0&&C(y);break;case"xxhash64":case"xxhash3":case"xxhash128":case"crc64":B=()=>!1;break}let E=(y,v=null,Q=null)=>{if(!B(y,v))return h(v),f(y),g("hex",Q);let w=mt(y);return t.set(w),e.exports.Hash_Calculate(w.length,v,Q),Go(u,t,r)};return yield d(),{getMemory:n,writeMemory:s,getExports:o,setMemorySize:a,init:h,update:f,digest:g,save:I,load:m,calculate:E,hashLength:r}})}function vr(A){return!Number.isInteger(A)||A<8||A>512||A%8!==0?new Error("Invalid variant! Valid values: 8, 16, ..., 512"):null}function Gc(A,r){return A|r<<16}function Oo(A=512,r=null){if(vr(A))return Promise.reject(vr(A));let e=null,t=A;if(r!==null){if(e=mt(r),e.length>64)return Promise.reject(new Error("Max key length is 64 bytes"));t=Gc(A,e.length)}let i=A/8;return Sr(Lc,i).then(s=>{t>512&&s.writeMemory(e),s.init(t);let n={init:t>512?()=>(s.writeMemory(e),s.init(t),n):()=>(s.init(t),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 Oc(A,r,e){let t=[`m=${r.memorySize}`,`t=${r.iterations}`,`p=${r.parallelism}`].join(",");return`$argon2${r.hashType}$v=19$${t}$${Er(A,!1)}$${Er(e,!1)}`}function It(A){return Qr.setInt32(0,A,!0),new Uint8Array(Qr.buffer)}function Uo(A,r,e){return Vt(this,void 0,void 0,function*(){if(e<=64){let a=yield Oo(e*8);return a.update(It(e)),a.update(r),a.digest("binary")}let t=Math.ceil(e/32)-2,i=new Uint8Array(e);A.init(),A.update(It(e)),A.update(r);let s=A.digest("binary");i.set(s.subarray(0,32),0);for(let a=1;a<t;a++)A.init(),A.update(s),s=A.digest("binary"),i.set(s.subarray(0,32),a*32);let n=e-32*t,o;return n===64?(o=A,o.init()):o=yield Oo(n*8),o.update(s),s=o.digest("binary"),i.set(s.subarray(0,n),t*32),i})}function Kc(A){switch(A){case"d":return 0;case"i":return 1;default:return 2}}function Jc(A){return Vt(this,void 0,void 0,function*(){var r;let{parallelism:e,iterations:t,hashLength:i}=A,s=mt(A.password),n=mt(A.salt),o=19,a=Kc(A.hashType),{memorySize:l}=A,c=mt((r=A.secret)!==null&&r!==void 0?r:""),[d,h]=yield Promise.all([Sr(Pc,1024),Oo(512)]);d.setMemorySize(l*1024+1024);let p=new Uint8Array(24),f=new DataView(p.buffer);f.setInt32(0,e,!0),f.setInt32(4,i,!0),f.setInt32(8,l,!0),f.setInt32(12,t,!0),f.setInt32(16,o,!0),f.setInt32(20,a,!0),d.writeMemory(p,l*1024),h.init(),h.update(p),h.update(It(s.length)),h.update(s),h.update(It(n.length)),h.update(n),h.update(It(c.length)),h.update(c),h.update(It(0));let g=Math.floor(l/(e*4))*4,I=new Uint8Array(72),m=h.digest("binary");I.set(m);for(let E=0;E<e;E++){I.set(It(0),64),I.set(It(E),68);let y=E*g,v=yield Uo(h,I,1024);d.writeMemory(v,y*1024),y+=1,I.set(It(1),64),v=yield Uo(h,I,1024),d.writeMemory(v,y*1024)}let C=new Uint8Array(1024);Fr(C,d.calculate(new Uint8Array([]),l));let B=yield Uo(h,C,i);if(A.outputType==="hex"){let E=new Uint8Array(i*2);return Go(E,B,i)}return A.outputType==="encoded"?Oc(n,A,B):B})}function Ko(A){return Vt(this,void 0,void 0,function*(){return qc(A),Jc(Object.assign(Object.assign({},A),{hashType:"id"}))})}var le,Po,Lo,Ho,Fc,yr,wr,mt,qe,os,nn,ns,xc,Ro,PA,Nc,Tc,Mc,Pc,Hc,Rc,Uc,Lc,HA,Qr,qc,RA,UA,LA,GA,OA,KA,JA,qA,$A,YA,zA,VA,WA,XA,ZA,jA,_A,eh,th,ih,sh,nh,oh,ah,br=de(()=>{le=class{constructor(){this.mutex=Promise.resolve()}lock(){let r=()=>{};return this.mutex=this.mutex.then(()=>new Promise(r)),new Promise(e=>{r=e})}dispatch(r){return Vt(this,void 0,void 0,function*(){let e=yield this.lock();try{return yield Promise.resolve(r())}finally{e()}})}};Lo=kc(),Ho=(Po=Lo.Buffer)!==null&&Po!==void 0?Po:null,Fc=Lo.TextEncoder?new Lo.TextEncoder:null;yr=87,wr=48;mt=Ho!==null?A=>{if(typeof A=="string"){let r=Ho.from(A,"utf8");return new Uint8Array(r.buffer,r.byteOffset,r.length)}if(Ho.isBuffer(A))return new Uint8Array(A.buffer,A.byteOffset,A.length);if(ArrayBuffer.isView(A))return new Uint8Array(A.buffer,A.byteOffset,A.byteLength);throw new Error("Invalid data type!")}:A=>{if(typeof A=="string")return Fc.encode(A);if(ArrayBuffer.isView(A))return new Uint8Array(A.buffer,A.byteOffset,A.byteLength);throw new Error("Invalid data type!")},qe="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",os=new Uint8Array(256);for(let A=0;A<qe.length;A++)os[qe.charCodeAt(A)]=A;nn=16*1024,ns=4,xc=new le,Ro=new Map;PA=new le,Nc="argon2",Tc="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",Mc="e4cdc523",Pc={name:Nc,data:Tc,hash:Mc},Hc="blake2b",Rc="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=",Uc="c6f286e6",Lc={name:Hc,data:Rc,hash:Uc},HA=new le;Qr=new DataView(new ArrayBuffer(4));qc=A=>{var r;if(!A||typeof A!="object")throw new Error("Invalid options parameter. It requires an object.");if(!A.password)throw new Error("Password must be specified");if(A.password=mt(A.password),A.password.length<1)throw new Error("Password must be specified");if(!A.salt)throw new Error("Salt must be specified");if(A.salt=mt(A.salt),A.salt.length<8)throw new Error("Salt should be at least 8 bytes long");if(A.secret=mt((r=A.secret)!==null&&r!==void 0?r:""),!Number.isInteger(A.iterations)||A.iterations<1)throw new Error("Iterations should be a positive number");if(!Number.isInteger(A.parallelism)||A.parallelism<1)throw new Error("Parallelism should be a positive number");if(!Number.isInteger(A.hashLength)||A.hashLength<4)throw new Error("Hash length should be at least 4 bytes.");if(!Number.isInteger(A.memorySize))throw new Error("Memory size should be specified.");if(A.memorySize<8*A.parallelism)throw new Error("Memory size should be at least 8 * parallelism.");if(A.outputType===void 0&&(A.outputType="hex"),!["hex","binary","encoded"].includes(A.outputType))throw new Error(`Insupported output type ${A.outputType}. Valid values: ['hex', 'binary', 'encoded']`)};RA=new le,UA=new le,LA=new le,GA=new le,OA=new Uint8Array(8),KA=new le,JA=new le,qA=new le,$A=new le,YA=new le,zA=new le,VA=new le,WA=new le,XA=new le,ZA=new le,jA=new le,_A=new Uint8Array(8),eh=new le,th=new Uint8Array(8),ih=new le,sh=new Uint8Array(8),nh=new le,oh=new le,ah=new le});function Ue(A){if(A.length<$e.length+1)return!1;for(let r=0;r<$e.length;r++)if(A[r]!==$e[r])return!1;return!0}function Dr(A,r,e){A[r]=e>>>24&255,A[r+1]=e>>>16&255,A[r+2]=e>>>8&255,A[r+3]=e&255}function xr(A,r){return A[r]*16777216+(A[r+1]<<16)+(A[r+2]<<8)+A[r+3]}async function qo(A,r,e){if(e.id===zo)return await Ko({password:A,salt:r,parallelism:e.c,iterations:e.b,memorySize:e.a,hashLength:Jo,outputType:"binary"});if(e.id===Yo){let t=await crypto.subtle.importKey("raw",me(new TextEncoder().encode(A)),"PBKDF2",!1,["deriveBits"]),i=await crypto.subtle.deriveBits({name:"PBKDF2",salt:me(r),iterations:e.a,hash:"SHA-256"},t,Jo*8);return new Uint8Array(i)}throw new Error(`Unsupported KDF id (${e.id}).`)}async function on(A){return crypto.subtle.importKey("raw",me(A),{name:"AES-GCM"},!1,["encrypt","decrypt"])}async function Ct(A,r){let e=crypto.getRandomValues(new Uint8Array($c)),t=crypto.getRandomValues(new Uint8Array(Bi)),i,s,n;try{i={id:zo,a:zc,b:Vc,c:Wc},n=await qo(r,e,i),s="argon2id"}catch(d){console.warn("[Stashpad] Argon2id unavailable \u2014 encrypting with PBKDF2 fallback.",d),i={id:Yo,a:Yc,b:0,c:0},n=await qo(r,e,i),s="pbkdf2"}let o=Tr(i,e,t),a=await on(n),l=new Uint8Array(await crypto.subtle.encrypt({name:"AES-GCM",iv:me(t),additionalData:me(o)},a,me(A))),c=new Uint8Array(o.length+l.length);return c.set(o,0),c.set(l,o.length),{data:c,kdf:s}}async function rs(){if(as!==null)return as;try{await Ko({password:"x",salt:new Uint8Array(16),parallelism:1,iterations:1,memorySize:8,hashLength:16,outputType:"binary"}),as=!0}catch{as=!1}return as}function Tr(A,r,e){let t=new Uint8Array($e.length+1+1+4+4+1+1+r.length+e.length),i=0;return t.set($e,i),i+=$e.length,t[i++]=$o,t[i++]=A.id,Dr(t,i,A.a),i+=4,Dr(t,i,A.b),i+=4,t[i++]=A.c,t[i++]=r.length,t.set(r,i),i+=r.length,t.set(e,i),i+=e.length,t}async function yi(A,r){if(!Ue(A))throw new Error("Not an encrypted Stashpad file.");let e=A[$e.length];if(e===1)return Xc(A,r);if(e!==$o)throw new Error(`Unsupported encrypted .stash version (${e}).`);let t=$e.length+1,i={id:A[t++],a:0,b:0,c:0};if(i.a=xr(A,t),t+=4,i.b=xr(A,t),t+=4,i.c=A[t++],i.id===zo){if(i.a>2097152||i.b>64||i.c<1||i.c>8)throw new Error("Unsupported KDF parameters (file may be corrupted or malicious).")}else if(i.id===Yo&&i.a>1e7)throw new Error("Unsupported KDF parameters (file may be corrupted or malicious).");let s=A[t++];if(s<8||s>64)throw new Error("Unsupported KDF parameters (file may be corrupted or malicious).");let n=A.slice(t,t+s);t+=s;let o=A.slice(t,t+Bi);t+=Bi;let a=A.slice(0,t),l=A.slice(t),c=await qo(r,n,i),d=await on(c),h=await crypto.subtle.decrypt({name:"AES-GCM",iv:me(o),additionalData:me(a)},d,me(l));return new Uint8Array(h)}async function Xc(A,r){let e=$e.length+1,t=A.slice(e,e+16);e+=16;let i=A.slice(e,e+12);e+=12;let s=A.slice(e),n=await crypto.subtle.importKey("raw",me(new TextEncoder().encode(r)),"PBKDF2",!1,["deriveKey"]),o=await crypto.subtle.deriveKey({name:"PBKDF2",salt:me(t),iterations:21e4,hash:"SHA-256"},n,{name:"AES-GCM",length:256},!1,["decrypt"]),a=await crypto.subtle.decrypt({name:"AES-GCM",iv:me(i)},o,me(s));return new Uint8Array(a)}async function ls(A,r){if(r.length!==Jo)throw new Error("Encryption key must be 32 bytes.");let e=crypto.getRandomValues(new Uint8Array(Bi)),i=Tr({id:Nr,a:0,b:0,c:0},new Uint8Array(0),e),s=await on(r),n=new Uint8Array(await crypto.subtle.encrypt({name:"AES-GCM",iv:me(e),additionalData:me(i)},s,me(A))),o=new Uint8Array(i.length+n.length);return o.set(i,0),o.set(n,i.length),o}async function Ye(A,r){if(!Ue(A))throw new Error("Not an encrypted Stashpad file.");let e=A[$e.length];if(e!==$o)throw new Error(`Unsupported encrypted version (${e}).`);let t=$e.length+1;if(A[t++]!==Nr)throw new Error("Not a raw-key (.stashenc) envelope.");t+=9;let s=A[t++];t+=s;let n=A.slice(t,t+Bi);t+=Bi;let o=A.slice(0,t),a=A.slice(t),l=await on(r),c=await crypto.subtle.decrypt({name:"AES-GCM",iv:me(n),additionalData:me(o)},l,me(a));return new Uint8Array(c)}async function wi(A,r,e={}){if(!Ue(r))return r;if(e.secretId){let i=A.secretStorage,s=null;try{s=i?.getSecret(e.secretId)??null}catch{s=null}if(s)try{return await yi(r,s)}catch{}}let t;for(;;){let i=await new Promise(s=>{new cs(A,t,!!e.allowLater,s).open()});if(i.kind==="cancel")return null;if(i.kind==="later")return e.onLater?.(),null;try{return await yi(r,i.value)}catch{t="Wrong password or corrupted file. Try again."}}}var $e,$o,Yo,zo,Nr,$c,Bi,Jo,Yc,zc,Vc,Wc,me,Vo,as,Wt=de(()=>{"use strict";br();ve();$e=new Uint8Array([83,84,65,83,72,69,78,67]),$o=2,Yo=1,zo=2,Nr=3,$c=32,Bi=12,Jo=32,Yc=6e5,zc=47104,Vc=3,Wc=1,me=A=>A;Vo={argon2id:{label:"Argon2id",strong:!0},pbkdf2:{label:"PBKDF2 (fallback)",strong:!1}};as=null});var Xt,Zc,Ei,an,Mr=de(()=>{"use strict";Xt=".stashpad/keys.json",Zc=".stashpad",Ei="_keys",an=class{constructor(r){this.app=r}get a(){return this.app.vault.adapter}validate(r){let e=r;return!!e&&e.v===2&&typeof e.keyId=="string"&&Array.isArray(e.identities)&&Array.isArray(e.slots)&&Array.isArray(e.joinRequests)}async readValid(r){try{if(!await this.a.exists(r))return null;let e=JSON.parse(await this.a.read(r));return this.validate(e)?e:null}catch{return null}}async load(){let r=await this.readValid(Xt);if(r)return r;try{let t=((await this.a.list(Ei)).files||[]).filter(i=>/\/keys-\d+\.json$/.test(i)).sort();for(let i of t.reverse()){let s=await this.readValid(i);if(s)return s}}catch{}return null}async exists(){return await this.load()!==null}async hasAnyFile(){try{if(await this.a.exists(Xt))return!0}catch{}try{return((await this.a.list(Ei)).files||[]).some(e=>/\/keys-\d+\.json$/.test(e))}catch{return!1}}async ensureDir(r){try{await this.a.exists(r)||await this.a.mkdir(r)}catch{}}async save(r){let e=JSON.stringify(r,null,2);await this.ensureDir(Zc);let t=`${Xt}.tmp`,i=!1;try{await this.a.write(t,e);try{await this.a.rename(t,Xt)}catch{try{await this.a.remove(Xt)}catch{}await this.a.rename(t,Xt)}i=!0}catch{try{await this.a.exists(t)&&await this.a.remove(t)}catch{}}i||await this.a.write(Xt,e),await this.ensureDir(Ei);for(let s=4;s>=1;s--){let n=`${Ei}/keys-${s}.json`,o=`${Ei}/keys-${s+1}.json`;try{await this.a.exists(n)&&await this.a.write(o,await this.a.read(n))}catch{}}try{await this.a.write(`${Ei}/keys-1.json`,e)}catch{}}}});function Wo(A){let r="";for(let e=0;e<A.length;e++)r+=String.fromCharCode(A[e]);return btoa(r)}function _c(A){let r=atob(A),e=new Uint8Array(r.length);for(let t=0;t<r.length;t++)e[t]=r.charCodeAt(t);return e}var jc,Pr,rn,ln,Hr=de(()=>{"use strict";Wt();pt();jc=".stashkey",Pr=32;rn=()=>new Date().toISOString(),ln=class{constructor(r){this.app=r}get a(){return this.app.vault.adapter}keyPath(r){return`${r.replace(/\/+$/,"")}/${jc}`}validate(r){let e=r;return!!e&&e.v===1&&typeof e.keyId=="string"&&typeof e.folderPath=="string"&&Array.isArray(e.slots)&&e.slots.every(t=>t&&typeof t.wrapped=="string"&&typeof t.id=="string")}async read(r){let e=this.keyPath(r);try{if(!await this.a.exists(e))return null;let t=JSON.parse(await this.a.read(e));return this.validate(t)?t:null}catch{return null}}async hasFile(r){try{return await this.a.exists(this.keyPath(r))}catch{return!1}}async write(r,e){let t=this.keyPath(r),i=JSON.stringify(e,null,2),s=`${t}.tmp`,n=!1;try{await this.a.write(s,i);try{await this.a.rename(s,t)}catch{try{await this.a.remove(t)}catch{}await this.a.rename(s,t)}n=!0}catch{try{await this.a.exists(s)&&await this.a.remove(s)}catch{}}n||await this.a.write(t,i)}async remove(r){try{await this.a.remove(this.keyPath(r))}catch{}}async create(r,e,t){if(!e)throw new Error("Password required.");let i=crypto.getRandomValues(new Uint8Array(Pr)),s=await Ct(i,e);return{sk:{v:1,keyId:t??he(8),folderPath:r.replace(/\/+$/,""),slots:[{id:he(8),label:"Folder password",wrapped:Wo(s.data),kdf:s.kdf,createdAt:rn()}],createdAt:rn()},dek:i}}async unlock(r,e){for(let t of r.slots)try{let i=await yi(_c(t.wrapped),e);if(i.length!==Pr){i.fill(0);continue}return i}catch{}return null}async changePassword(r,e,t){if(!t)throw new Error("Password required.");let i=await Ct(e,t),s=r.slots.filter(o=>o.recovery),n={id:he(8),label:"Folder password",wrapped:Wo(i.data),kdf:i.kdf,createdAt:rn()};return{...r,slots:[n,...s]}}async setRecovery(r,e,t){if(!t)throw new Error("Recovery password required.");let i=await Ct(e,t),s=r.slots.filter(o=>!o.recovery),n={id:he(8),label:"Recovery password",wrapped:Wo(i.data),kdf:i.kdf,createdAt:rn(),recovery:!0};return{...r,slots:[...s,n]}}removeRecovery(r){return{...r,slots:r.slots.filter(e=>!e.recovery)}}hasRecovery(r){return r.slots.some(e=>e.recovery)}}});function dn(){return{}}function td(A){let r="";for(let e=0;e<A.length;e++)r+=String.fromCharCode(A[e]);return btoa(r)}function id(A){let r=atob(A),e=new Uint8Array(r.length);for(let t=0;t<r.length;t++)e[t]=r.charCodeAt(t);return e}var ed,cn,Xo=de(()=>{"use strict";Wt();pt();Mr();Hr();ed="stashpad-vault-encryption";cn=class{constructor(r,e,t){this.app=r;this.load=e;this.save=t;this.folderSessionKeys=new Map;this.kf=null;this.folderKeyFiles=new Map;this.stashKeysIndexed=!1;this.parkedKeyMaterial=!1;this.keyfiles=new an(r),this.folderKeystore=new ln(r)}argonProbe(){return rs()}async init(){await this.refresh(),this.parkedKeyMaterial=await this.detectParkedKeyMaterial()}async refresh(){this.kf=await this.keyfiles.load(),this.stashKeysIndexed||await this.indexStashKeys()}async detectParkedKeyMaterial(){let r=this.app.vault.adapter;try{let e=await r.list("_keys");if((e.files||[]).some(t=>/\.json$/.test(t))||(e.folders||[]).length)return!0}catch{}try{if(((await r.list(".stashpad")).folders||[]).some(t=>/\/retired-keyfile-/.test(t)))return!0}catch{}return!1}invalidateStashKeyIndex(){this.stashKeysIndexed=!1}async migrateKeyfileToStashKeys(){await this.refresh();let r=this.kf?.folderKeys;if(!r)return 0;let e=0;for(let[t,i]of Object.entries(r)){let s=this.cleanFolder(t);if(this.folderKeyFiles.has(s)||await this.folderKeystore.hasFile(s))continue;let n=(i.passwordSlots??[]).filter(a=>!a.label.startsWith("[deprecated]"));if(!n.length)continue;let o={v:1,keyId:i.keyId,folderPath:s,slots:n.map((a,l)=>({id:a.id,label:l===0?"Folder password":a.label,wrapped:a.wrapped,kdf:a.kdf,createdAt:a.createdAt})),createdAt:i.createdAt};try{await this.folderKeystore.write(s,o);let a=await this.folderKeystore.read(s);if(!a||a.slots[0]?.wrapped!==o.slots[0].wrapped){await this.folderKeystore.remove(s);continue}this.folderKeyFiles.set(s,o),e++}catch{}}return e}async indexStashKeys(){let r=new Map,e=new Set([".git",".obsidian","node_modules"]),t=async i=>{let s;try{s=await this.app.vault.adapter.list(i)}catch{return}for(let n of s.files??[])if(n===".stashkey"||n.endsWith("/.stashkey")){let o=n.includes("/")?n.slice(0,n.lastIndexOf("/")):"",a=await this.folderKeystore.read(o);a&&r.set(this.cleanFolder(o),a)}for(let n of s.folders??[])e.has(n.split("/").pop()??"")||await t(n)};await t(""),this.folderKeyFiles=r,this.stashKeysIndexed=!0}stashKeyToEntry(r,e){return{keyId:r.keyId,folderPath:this.cleanFolder(e),label:r.slots[0]?.label??"Folder password",kcId:this.folderKcId(e,r.keyId),passwordSlots:r.slots.map(t=>({id:t.id,label:t.label,wrapped:t.wrapped,kdf:t.kdf,createdAt:t.createdAt})),createdAt:r.createdAt}}secretStore(){return this.app.secretStorage??null}keychainAvailable(){return!!this.secretStore()}async parkThenSet(r,e){let t=this.secretStore();if(!t)return;let i=[r];try{let s=t.getSecret(r);if(s&&s!==e){let n=Date.now().toString(36),o=`${r.slice(0,64-(n.length+2))}-r${n}`;await t.setSecret(o,s),i.push(o)}}catch{}await t.setSecret(r,e),await this.recordKeychainIds(i)}async recordKeychainIds(r){try{let e=this.load(),t=new Set(e.knownKeychainIds??[]),i=!1;for(let s of r)s&&!t.has(s)&&(t.add(s),i=!0);i&&await this.save({...e,knownKeychainIds:[...t]})}catch{}}keychainCandidateIds(){return[...new Set(this.load().knownKeychainIds??[])]}hasAnyFolderKey(){return this.folderKeyFiles.size>0||Object.keys(this.kf?.folderKeys??{}).length>0}isConfigured(){return this.hasAnyFolderKey()}owningFolder(r){let e=this.kf?.folderKeys,t=this.cleanFolder(r);for(;t;){if(this.folderKeyFiles.has(t)||e&&Object.prototype.hasOwnProperty.call(e,t))return t;let i=t.lastIndexOf("/");if(i<0)break;t=t.slice(0,i)}return null}hasOwnFolderKey(r){let e=this.cleanFolder(r);if(this.folderKeyFiles.has(e))return!0;let t=this.kf?.folderKeys;return!!t&&Object.prototype.hasOwnProperty.call(t,e)}folderKeyEntry(r){let e=this.owningFolder(r);if(!e)return null;let t=this.folderKeyFiles.get(e);return t?this.stashKeyToEntry(t,e):this.kf?.folderKeys?.[e]??null}hasFolderKey(r){return this.owningFolder(r)!==null}folderPathByKeyId(r){for(let[e,t]of this.folderKeyFiles)if(t.keyId===r)return e;for(let[e,t]of Object.entries(this.kf?.folderKeys??{}))if(t.keyId===r)return e;return null}folderActiveSlots(r){return(r.passwordSlots??[]).filter(e=>!e.label.startsWith("[deprecated]"))}isFolderUnlocked(r){let e=this.owningFolder(r);return e?this.folderSessionKeys.has(e):!1}getFolderKey(r){let e=this.owningFolder(r);if(!e)return null;let t=this.folderSessionKeys.get(e);return t?t.slice():null}async setupFolderKey(r,e,t,i=!1){if(!e)throw new Error("Password required.");await this.refresh();let s=this.cleanFolder(r);if(this.hasOwnFolderKey(s))throw new Error("This folder already has its own key.");let n=this.owningFolder(s);if(n&&n!==s)throw new Error(`A parent folder (\u201C${n.split("/").pop()}\u201D) already has its own password; this folder inherits it.`);let{sk:o,dek:a}=await this.folderKeystore.create(s,e);await this.folderKeystore.write(s,o),this.folderKeyFiles.set(s,o),this.folderSessionKeys.set(s,a),i&&await this.rememberFolder(this.folderKcId(s,o.keyId),e)}async unlockFolder(r,e,t=!1){await this.refresh();let i=this.cleanFolder(r),s=this.folderKeyEntry(i);if(!s)return!1;for(let n of this.folderActiveSlots(s))try{let o=await yi(id(n.wrapped),e);this.folderSessionKeys.set(s.folderPath,o);let a=this.folderKcIdFor(s);return(t||this.isFolderRemembered(a))&&await this.rememberFolder(a,e),!0}catch{}return!1}async tryAutoUnlockFolder(r){let e=this.folderKeyEntry(r);if(!e||this.isFolderUnlocked(r))return this.isFolderUnlocked(r);let t=this.folderKcIdFor(e),i=this.rememberedFolderPassword(t);if(i&&await this.unlockFolder(r,i))return!0;let s=this.secretStore();if(!s)return!1;let n=new Set(i?[i]:[]);for(let o of this.keychainCandidateIds()){if(o===t)continue;let a=null;try{a=s.getSecret(o)??null}catch{a=null}if(!(!a||n.has(a))&&(n.add(a),await this.unlockFolder(r,a)))return await this.rememberFolder(t,a),!0}return!1}async changeFolderPassword(r,e,t=!1){if(!e)throw new Error("Password required.");let i=this.cleanFolder(r);await this.refresh();let s=this.folderKeyEntry(i);if(!s)throw new Error("This folder has no key.");let n=s.folderPath,o=this.folderSessionKeys.get(n);if(!o)throw new Error("Unlock this folder first.");let a=this.folderKeyFiles.get(n);if(a){let u=await this.folderKeystore.changePassword(a,o,e);await this.folderKeystore.write(n,u),this.folderKeyFiles.set(n,u);let g=this.folderKcId(n,u.keyId);(t||this.isFolderRemembered(g))&&await this.rememberFolder(g,e);return}if(!this.kf)throw new Error("This folder has no key.");let l=s.passwordSlots.filter(u=>!u.label.startsWith("[deprecated]")),c=this.folderKcIdFor(s),d=this.rememberedFolderPassword(c);if(d&&l[0])try{await this.parkThenSet(`${c}-d-${l[0].id}`,d)}catch{}let h=await Ct(o,e),p=s.passwordSlots.map(u=>u.label.startsWith("[deprecated]")?u:{...u,label:`[deprecated] ${u.label}`}),f={...s,kcId:s.kcId??this.folderKcId(s.label,s.keyId),passwordSlots:[{id:he(8),label:"Folder password",wrapped:td(h.data),kdf:h.kdf,createdAt:new Date().toISOString()},...p]};this.kf.folderKeys={...this.kf.folderKeys??{},[n]:f},await this.keyfiles.save(this.kf),(t||this.isFolderRemembered(c))&&await this.rememberFolder(this.folderKcIdFor(f),e)}folderHasRecovery(r){let e=this.owningFolder(r),t=e?this.folderKeyFiles.get(e):null;return!!t&&this.folderKeystore.hasRecovery(t)}async setFolderRecoveryPassword(r,e){if(!e)throw new Error("Recovery password required.");await this.refresh();let t=this.cleanFolder(r),i=this.folderKeyEntry(t);if(!i)throw new Error("This folder has no key.");let s=i.folderPath,n=this.folderKeyFiles.get(s);if(!n)throw new Error("This folder's key predates recovery passwords \u2014 change its folder password once to upgrade it, then try again.");let o=this.folderSessionKeys.get(s);if(!o)throw new Error("Unlock this folder first.");let a=await this.folderKeystore.setRecovery(n,o,e);await this.folderKeystore.write(s,a),this.folderKeyFiles.set(s,a)}async removeFolderRecoveryPassword(r){await this.refresh();let e=this.cleanFolder(r),t=this.folderKeyEntry(e);if(!t)return;let i=t.folderPath,s=this.folderKeyFiles.get(i);if(!s||!this.folderKeystore.hasRecovery(s))return;let n=this.folderKeystore.removeRecovery(s);await this.folderKeystore.write(i,n),this.folderKeyFiles.set(i,n)}folderKcId(r,e){return(`sp-${(r||"").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")}`.slice(0,44)+`-${e.slice(0,6)}`).replace(/-+/g,"-")}folderKcIdFor(r){return r.kcId||`${ed}-f-${r.keyId}`}isFolderRemembered(r){try{return!!this.secretStore()?.getSecret(r)}catch{return!1}}rememberedFolderPassword(r){try{return this.secretStore()?.getSecret(r)||null}catch{return null}}async rememberFolder(r,e){try{await this.parkThenSet(r,e)}catch(t){console.warn("[Stashpad] couldn't save folder password to keychain",t)}}async forgetFolderKeychain(r){let e=this.folderKeyEntry(r);if(!e)return;let t=this.secretStore();if(!t)return;let i=this.folderKcIdFor(e);try{if(t.getSecret(i)){await this.parkThenSet(i,"");return}}catch{}try{t.removeSecret?await t.removeSecret(i):await t.setSecret(i,"")}catch(s){console.warn("[Stashpad] couldn't clear folder keychain",s)}}lock(){for(let r of this.folderSessionKeys.values())r.fill(0);this.folderSessionKeys.clear()}lockFolder(r){let e=this.owningFolder(r)??this.cleanFolder(r),t=this.folderSessionKeys.get(e);t&&(t.fill(0),this.folderSessionKeys.delete(e))}cleanFolder(r){return(r||"").replace(/\/+$/,"")}async clear(){this.lock();try{let r=this.app.vault.adapter;for(let e of[".stashpad/keys.json"])try{await r.exists(e)&&await r.remove(e)}catch{}try{let t=((await r.list("_keys")).files||[]).filter(i=>/\/keys-\d+\.json$/.test(i));if(t.length){let s=`_keys/removed-${new Date().toISOString().slice(0,19).replace(/[:T]/g,"-")}`;try{await r.exists(s)||await r.mkdir(s)}catch{}for(let n of t){let o=n.split("/").pop();try{await r.write(`${s}/${o}`,await r.read(n)),await r.remove(n)}catch{}}}}catch{}this.stashKeysIndexed||await this.indexStashKeys();for(let e of this.folderKeyFiles.keys())try{await this.folderKeystore.remove(e)}catch{}this.folderKeyFiles.clear()}catch{}this.kf=null}async removeFolderKeyFile(r){let e=this.cleanFolder(r);await this.folderKeystore.remove(e),this.folderKeyFiles.delete(e),this.folderSessionKeys.get(e)?.fill(0),this.folderSessionKeys.delete(e)}hasLegacyKeyfile(){return!!this.kf}unmigratedKeyfileFolders(){return Object.keys(this.kf?.folderKeys??{}).filter(r=>!this.folderKeyFiles.has(this.cleanFolder(r)))}async retireLegacyKeyfile(){await this.refresh();let r=this.unmigratedKeyfileFolders();if(r.length)throw new Error(`Can't retire the old keyfile yet \u2014 these folders' keys still live only in it: ${r.map(o=>o||"(vault root)").join(", ")}. Open each folder once (or change its password) to migrate it, then try again.`);let e=this.app.vault.adapter,i=`.stashpad/retired-keyfile-${new Date().toISOString().slice(0,19).replace(/[:T]/g,"-")}`,s=0;try{await e.exists(i)||await e.mkdir(i)}catch{}let n=async(o,a)=>{try{let l=await e.read(o);return await e.write(a,l),await e.read(a)!==l?!1:(await e.remove(o),!0)}catch{return!1}};try{await e.exists(".stashpad/keys.json")&&await n(".stashpad/keys.json",`${i}/keys.json`)&&s++}catch{}try{let o=await e.list("_keys");for(let a of(o.files||[]).filter(l=>/\/keys-\d+\.json$/.test(l)))await n(a,`${i}/${a.split("/").pop()}`)&&s++}catch{}return this.kf=null,this.parkedKeyMaterial=!0,s}hasRecoverableKeyMaterial(){return!!this.kf||this.parkedKeyMaterial}async wipeLegacyKeyMaterial(){let r=this.app.vault.adapter,e=0,t=async(i,s)=>{try{await r.exists(i)&&(s?await r.rmdir(i,!0):await r.remove(i),e++)}catch{}};await t(".stashpad/keys.json",!1),await t("_keys",!0);try{let i=await r.list(".stashpad");for(let s of i.folders||[])/\/retired-keyfile-/.test(s)&&await t(s,!0)}catch{}return this.kf=null,this.parkedKeyMaterial=!1,e}dispose(){this.lock()}}});function hn(A){if(ds!==A){ds=A;for(let r of An)r()}}function Bt(){return ds}function Rr(A){if(ds===A){ds=null;for(let r of An)r()}}function Ur(A){return An.add(A),()=>An.delete(A)}var ds,An,pn=de(()=>{"use strict";ds=null,An=new Set});function sd(){return P.Platform.isMacOS?"Finder":P.Platform.isWin?"File Explorer":"file manager"}function _o(){let A={};for(let r of Zt)A[r.id]={primary:r.defaultPrimary,secondary:r.defaultSecondary??"",preferRight:!1,useBoth:!!r.defaultUseBoth};return A}function X(){return Lr}function As(A){Lr=A;for(let r of jo)r()}function Gr(A){return jo.add(A),()=>jo.delete(A)}function fn(A){try{let r=A.internalPlugins?.plugins?.templates;if(!r?.enabled)return null;let e=r.instance?.options??{};return{dateFormat:e.dateFormat||"YYYY-MM-DD",timeFormat:e.timeFormat||"HH:mm"}}catch{return null}}function nd(A,r){return Zo||(Zo=class extends P.SettingPage{constructor(e,t){super(),this.title=e,this._renderFn=t}display(){this.containerEl.empty(),this._renderFn(this.containerEl)}}),new Zo(A,r)}var P,Zt,Mt,Lr,jo,gn,Zo,un,ki=de(()=>{"use strict";P=require("obsidian");is();ur();fr();ce();ve();sn();Br();ui();pt();Tt();Xo();pn();Zt=[{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:"copyLink",label:"Copy Stashpad link",desc:"Copy an obsidian://stashpad deep link to the cursor row (or first selected note) \u2014 click it anywhere to jump back. No default chord.",defaultPrimary:""},{id:"openEditor",label:"Open in Obsidian editor",desc:"Open the cursor row (or focused note) in a regular Obsidian markdown tab.",defaultPrimary:"Mod+Shift+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:"edit",label:"Edit note in Stashpad",desc:"Edit the cursor row (or focused note) in Stashpad's own editor (with a Split toggle) instead of a full Obsidian tab.",defaultPrimary:"E"},{id:"editParent",label:"Edit parent note in Stashpad",desc:"Edit the focused parent note in Stashpad's own editor.",defaultPrimary:"Shift+E"},{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 or X \u2014 marks selected/focused notes as complete (both chords active).",defaultPrimary:"Mod+Enter",defaultSecondary:"X",defaultUseBoth:!0},{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+: or ; \u2014 open the color picker for the selection (both chords active).",defaultPrimary:"Shift+:",defaultSecondary:";",defaultUseBoth:!0},{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:"forkNote",label:"Fork into a separate note (under a chosen parent)",desc:'Duplicate the cursor row (with its subtree) as a separate note and pick which parent it nests under. Distinct from "Fork as a version" (a draft within a sheet group). No default chord.',defaultPrimary:""},{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:"expandAll",label:"Expand all (show every note's full body)",desc:"Un-clamp every note in the current list at once.",defaultPrimary:""},{id:"collapseAll",label:"Collapse all (clamp every note's body)",desc:"Re-clamp every note in the current list at once.",defaultPrimary:""},{id:"exportStash",label:"Export selection\u2026",desc:"Open the export dialog for the selected subtree(s) \u2014 pick .stash / OKF / plain .zip and full/frontmatter/body content.",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:"listPin",label:"Pin / unpin to top of list",desc:"Float the cursor row (or selection) to the TOP of its list \u2014 distinct from the sidebar pin. No default chord.",defaultPrimary:""},{id:"toggleTask",label:"Toggle task (todo)",desc:"Default: G \u2014 mark the selection (or cursor row) as a task / todo, or clear it. Tasks appear in the Tasks panel.",defaultPrimary:"G"},{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:"openAllTasks",label:"Open all tasks (aggregate view)",desc:"Default: Shift+T \u2014 open the aggregate \u201CAll tasks\u201D view collecting tasks across every Stashpad folder.",defaultPrimary:"Shift+T"},{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"},{id:"lockSelection",label:"Encrypt (lock) selection",desc:"Encrypt the selected note(s) + their children into a locked .stashenc bundle in place (prompts to unlock first if needed). No default chord.",defaultPrimary:""},{id:"unlockAll",label:"Decrypt (unlock) locked notes in view",desc:"Decrypt every locked stash shown in the current view back into place, skipping any that can't be read. No default chord.",defaultPrimary:""},{id:"moveToArchive",label:"Move selection to archive",desc:"Move the selected note(s) into this folder's own archive subfolder (drops out of search; plaintext unless this folder encrypts its archive). Undoable. No default chord.",defaultPrimary:""},{id:"encryptDelete",label:"Encrypt & delete selection",desc:"Send the selected note(s) to the encrypted trash (recoverable with your password, Ctrl/Cmd+Z undoable). No default chord.",defaultPrimary:""},{id:"copyNotes",label:"Copy notes (note clipboard)",desc:"Copy the selected note(s) as NOTES: paste in the list to duplicate them (new ids), or anywhere else to paste their text. Skipped when text is highlighted (normal copy wins).",defaultPrimary:"Mod+C"},{id:"cutNotes",label:"Cut notes",desc:"Cut the selected note(s): paste in the list to MOVE them, or in the composer to extract their text and delete the originals (undoable).",defaultPrimary:"Mod+X"},{id:"pasteNotes",label:"Paste notes",desc:"Paste previously copied/cut notes at the cursor row (after it, same parent). Does nothing if the note clipboard is empty.",defaultPrimary:"Mod+V"}];Mt={folder:"Stashpad",importDropFolder:"",exportFolder:"_exports",autoImport:!1,inheritObsidianExclusions:!0,folderPanelPinnedFraction:.5,folderPanelPinned:[],folderPanelPinnedAt:{},folderPanelGroupItemOrder:{},folderPanelDownranked:[],folderPanelHidden:[],folderPanelPinnedGrouping:"pin-order",enablePerfProfiling:!1,debugTrace:!1,writeRecoveryLinks:!0,useTemplatesFormat:!1,prefixTimestampsOnCopy:!0,splitOnLines:!1,splitMode:"lines",confirmCrossParentDrag:!0,confirmBulkDelete:!0,confirmAttachmentDelete:!0,autofocusComposerAfterSend:!0,focusComposerOnOpen:!1,searchOpensInContext:!0,popoutDuplicates:!0,encryption:dn(),encryptTrash:!1,encryptTrashFilenames:!1,migratedToggleTaskG:!1,migratedArchiveToSubfolders:!1,migratedTrashToSubfolders:!1,reEncryptWatch:[],reEncryptNudge:!1,reEncryptAfterMin:0,dueQuickAdjusts:["5m","15m","30m","1h","1d","1w"],archiveFolders:[],folderEncPrefs:{},folderIcons:{},folderSwitcherIncludePinned:!1,foldersAlwaysNewTab:!1,importExcludePrefixes:"_",lockedSubtrees:[],searchOpensInNewTab:!0,pinnedNotes:[],hideMobileToolbarInStashpad:!0,slugStopWords:[],searchIncludedFolders:[],searchExcludedFolders:[],shortcuts:{move:"M",pickMove:"O",merge:"&",copy:"C",copyTree:"Y",openEditor:"Mod+Shift+E",openTab:"T",split:"S",edit:"E",editParent:"Shift+E",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,notifiedDueKeys:[],autoNavOnMoveIn:!1,openParentTabOnMoveIn:!0,autoNavOnMoveOut:!1,autoExpandCursorRow:!1,expandBodiesByDefault:!1,autoOpenDetailPanel:!1,doubleClickToFocus:!0,enableSheetVersions:!1,dateDisplayFormat:"locale",dateDisplayTimezone:"",jdIndexScope:"vault",jdIndexScopeFolder:"",jdIndexStashpadFolder:"",jdIndexFile:"Index",jdIndexIncludeStashpadFolders:!1,jdIndexSort:"natural",jdIndexHasBuilt:!1,okfEnabled:!1,okfTemplatePath:"",drafts:{},lastSubmitted:{},bindings:_o()},Lr=JSON.parse(JSON.stringify(Mt)),jo=new Set;gn=[{id:"foldersStorage",label:"\u{1F4C1} Folders & Storage"},{id:"importExport",label:"\u{1F504} Import & Export"},{id:"datesTime",label:"\u{1F552} Dates & Time"},{id:"behaviors",label:"\u{1F39B}\uFE0F Behavior"},{id:"notifications",label:"\u{1F514} Notifications"},{id:"encryption",label:"\u{1F512} Encryption"},{id:"authorship",label:"\u2712\uFE0F Authorship"},{id:"templates",label:"\u{1F4C4} Templates"},{id:"organizationSystems",label:"\u{1F5C2}\uFE0F Organization Systems"},{id:"maintenance",label:"\u{1F6E0}\uFE0F Maintenance"},{id:"diagnostics",label:"\u{1FA7A} Diagnostics"},{id:"hotkeys",label:"\u2328\uFE0F Hotkeys"}].sort((A,r)=>{let e=t=>t.replace(/^[^\p{L}\p{N}]+/u,"");return e(A.label).localeCompare(e(r.label))}),Zo=null;un=class extends P.PluginSettingTab{constructor(e,t){super(e,t);this.plugin=t;this.pfeSelected=null;this.pfeRerender=null;this.iconPickFolder=null}display(){let{containerEl:e}=this;e.empty();for(let t of gn){new P.Setting(e).setName(t.label).setHeading();let i=this.itemsForTab(t.id);if(i)for(let s of i){let n=new P.Setting(e);typeof s.render=="function"?s.render(n):(s.name&&n.setName(s.name),s.desc&&n.setDesc(s.desc))}else this.renderTabContent(e,t.id)}}getSettingDefinitions(){return gn.map(e=>{let t=this.itemsForTab(e.id);return t?{type:"page",name:e.label,items:t}:{type:"page",name:e.label,page:()=>nd(e.label,i=>this.renderTabContent(i,e.id))}})}itemsForTab(e){switch(e){case"hotkeys":return this.hotkeyItems();case"diagnostics":return this.diagnosticsItems();case"notifications":return this.notificationsItems();case"foldersStorage":return this.buildGeneralCategories().foldersStorage;case"importExport":return this.buildGeneralCategories().importExport;case"datesTime":return this.buildGeneralCategories().datesTime;case"maintenance":return this.buildGeneralCategories().maintenance;case"behaviors":{let t=this.buildGeneralCategories();return[this.headingDef("\u{1F4CB} List & Display"),...t.listDisplay,this.headingDef("\u2195\uFE0F Moving Notes"),...t.movingNotes,this.headingDef("\u270D\uFE0F Composer & Copying"),...t.composerCopy,this.headingDef("\u{1F5D1}\uFE0F Deleting"),...t.deleting,this.headingDef("\u{1FA9F} Windows & Tabs"),...t.windowsTabs,this.headingDef("\u2699\uFE0F Misc"),...t.misc]}case"organizationSystems":return[this.headingDef("\u{1F522} JD Index (Johnny Decimal)"),...this.jdIndexItems(),this.headingDef("\u{1F4DA} Open Knowledge Format (OKF)"),...this.okfItems()];case"encryption":return this.encryptionItems();case"authorship":return this.authorshipItems();case"templates":return this.templatesItems();default:return null}}renderTabContent(e,t){switch(t){case"authorship":this.renderAuthorshipSection(e);break;case"templates":this.renderTemplatesTab(e);break}}diagnosticsItems(){return[this.renderDef("Performance profiling","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.",e=>e.addToggle(t=>t.setValue(this.plugin.settings.enablePerfProfiling).onChange(async i=>{this.plugin.settings.enablePerfProfiling=i,await this.plugin.saveSettings()})),["perf","profiling","timing","slow"]),this.renderDef("Debug trace","Record low-level diagnostic lines (e.g. tap coordinates vs the row they resolve to) to an in-memory buffer while you reproduce a bug, then copy them below to share. Local only \u2014 no network, no file writes; zero overhead when off.",e=>e.addToggle(t=>t.setValue(this.plugin.settings.debugTrace).onChange(async i=>{this.plugin.settings.debugTrace=i,await this.plugin.saveSettings()})),["debug","trace","diagnostics","tap","log"]),this.renderDef("Copy / clear debug trace","Copy the captured debug lines to the clipboard (paste them back to share), or clear the buffer to start a fresh capture.",e=>{e.addButton(t=>t.setButtonText("Copy").onClick(async()=>{let i=this.plugin.getDebugTrace();if(!i){new P.Notice("Debug trace is empty \u2014 enable it and reproduce the issue first.");return}try{await navigator.clipboard.writeText(i),new P.Notice("Debug trace copied.")}catch{new P.Notice("Couldn't access clipboard.")}})),e.addButton(t=>t.setButtonText("Clear").onClick(()=>{this.plugin.clearDebugTrace(),new P.Notice("Debug trace cleared.")}))},["debug","trace","copy","clear"]),this.renderDef("Open log file","Append-only history of creates, deletes, parent changes, renames. Stored alongside the plugin's other private files.",e=>e.addButton(t=>t.setButtonText("Open log").onClick(async()=>{let i=this.app.vault.adapter,s=this.plugin.pluginPrivatePath("log.jsonl");if(!await i.exists(s)){new P.Notice("No log yet \u2014 make some changes first.");return}let n=await i.read(s);new vi(this.app,n,s).open()})),["log","history","diagnostics"])]}notificationsItems(){let e=new Set(this.plugin.settings.mutedNotificationCategories??[]),t=Object.keys(To);return[this.renderDef("Notification history limit","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.",i=>i.addText(s=>{s.setValue(String(this.plugin.settings.notificationHistoryLimit??5e3)).setPlaceholder("5000");let n=async()=>{let o=parseInt(s.getValue(),10);if(!Number.isFinite(o)||o<0){s.setValue(String(this.plugin.settings.notificationHistoryLimit??5e3));return}this.plugin.settings.notificationHistoryLimit=o,this.plugin.notifications.setHistoryLimit(o),await this.plugin.saveSettings()};s.inputEl.addEventListener("blur",()=>void n()),s.inputEl.addEventListener("keydown",o=>{o.key==="Enter"&&n()})}),["notification","history","limit"]),{type:"group",heading:"Mute notification categories",items:t.map(i=>{let s=To[i];return this.renderDef(s.label,s.desc,n=>n.addToggle(o=>o.setValue(!e.has(i)).onChange(async a=>{let l=!a;l?e.add(i):e.delete(i),this.plugin.settings.mutedNotificationCategories=Array.from(e),this.plugin.notifications.setMuted(i,l),await this.plugin.saveSettings()})),["notification","mute","toast","category"])})},this.renderDef("Notification history","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.",i=>i.addButton(s=>s.setButtonText("View notification history").onClick(()=>{new hs(this.app,this.plugin.notifications,async n=>{let o=this.app.vault.adapter,a=this.plugin.pluginPrivatePath("log.jsonl");if(!await o.exists(a)){new P.Notice("No log yet \u2014 make some changes first.");return}let l=await o.read(a);new vi(this.app,l,a).open()},this.plugin.settings.authorId||null,n=>this.plugin.lookupNoteAuthorIds(n)).open()})),["notification","history","panel"])]}renderTemplatesTab(e){this.renderColorAliasesSection(e),this.renderNoteTemplatesSection(e)}renderDef(e,t,i,s){return{name:e,desc:t,aliases:s,render:n=>{n.setName(e).setDesc(t);try{i(n)}catch(o){console.error(`[Stashpad] settings control "${e}" failed to render:`,o)}}}}sectionDef(e,t,i,s){return{name:e,desc:t,aliases:s,render:n=>{let o=n.settingEl;o.empty(),o.removeClass("setting-item"),o.addClass("stashpad-settings-section");try{i(o)}catch(a){console.error(`[Stashpad] settings section "${e}" failed to render:`,a)}}}}headingDef(e,t){return this.sectionDef(e,t??"",i=>{let s=new P.Setting(i).setName(e).setHeading();t&&s.setDesc(t)},[e.toLowerCase()])}folderKeyLabel(e){let t=new Date,i=a=>String(a).padStart(2,"0"),s=`${t.getFullYear()}${i(t.getMonth()+1)}${i(t.getDate())}-${i(t.getHours())}${i(t.getMinutes())}`,n=(this.plugin.settings.authorName||"").trim(),o=n?n.split(/\s+/).map(a=>a[0]).join(""):(this.plugin.settings.authorId||"anon").slice(0,4);return`${s} - ${e.split("/").pop()||e} - ${o}`}promptSetFolderPassword(e){new Le(this.app,{mode:"setup",offerKeychain:!0,title:`Set password for \u201C${e.split("/").pop()}\u201D`,intro:"A separate password just for this folder. Share it with collaborators out-of-band (a password manager, Signal, in person). There is NO recovery if it's lost.",onSubmit:async({next:t,remember:i})=>{if(!t)return"Enter a password.";try{await this.plugin.encryption.setupFolderKey(e,t,this.folderKeyLabel(e),i)}catch(s){return s.message}return new P.Notice("Folder password set \u2014 share it securely."),this.update?.(),this.pfeRerender?.(),null}}).open()}promptChangeFolderPassword(e){new Le(this.app,{mode:"setup",offerKeychain:!0,title:`Change password for \u201C${e.split("/").pop()}\u201D`,intro:"Re-wraps this folder's key under a new password. The OLD password stops working on THIS device right away (un-synced copies elsewhere keep working until they sync). To truly cut off someone who left, remove encryption and re-encrypt the folder under a fresh password.",onSubmit:async({next:t,remember:i})=>{if(!t)return"Enter a password.";try{await this.plugin.encryption.changeFolderPassword(e,t,i)}catch(s){return s.message}return new P.Notice("Folder password changed."),this.update?.(),this.pfeRerender?.(),null}}).open()}promptSetFolderRecovery(e){let t=e.split("/").pop()||e;new Le(this.app,{mode:"setup",offerKeychain:!1,title:`Recovery password for \u201C${t}\u201D`,intro:"A SECOND password that also unlocks this folder \u2014 a backup in case the main password is lost. It wraps the same key, so it's exactly as sensitive: store it somewhere safe and separate. Setting it again replaces any existing recovery password.",onSubmit:async({next:i})=>{if(!i)return"Enter a password.";try{await this.plugin.encryption.setFolderRecoveryPassword(e,i)}catch(s){return s.message}return new P.Notice("Recovery password set \u2014 keep it somewhere safe."),this.update?.(),this.pfeRerender?.(),null}}).open()}promptRemoveFolderRecovery(e){let t=e.split("/").pop()||e;new j(this.app,`Remove recovery password for \u201C${t}\u201D?`,"The recovery password will no longer unlock this folder. The main folder password is unchanged. You can add a new recovery password later.","Remove recovery",async i=>{if(i){try{await this.plugin.encryption.removeFolderRecoveryPassword(e)}catch(s){new P.Notice(s.message);return}new P.Notice("Recovery password removed."),this.update?.(),this.pfeRerender?.()}}).open()}promptUnlockFolder(e){new Le(this.app,{mode:"unlock",offerKeychain:!0,title:`Unlock \u201C${e.split("/").pop()}\u201D`,intro:"Enter this folder's password.",onSubmit:async({current:t,remember:i})=>await this.plugin.encryption.unlockFolder(e,t,i)?(new P.Notice("Folder unlocked."),this.update?.(),this.pfeRerender?.(),null):"Wrong password. Try again."}).open()}renderPerFolderEncryption(e){let t=this.plugin.discoverStashpadFolders();if(t.length===0){e.createEl("p",{cls:"setting-item-description"}).setText("No Stashpad folders found yet.");return}(!this.pfeSelected||!t.includes(this.pfeSelected))&&(this.pfeSelected=t[0]);let i=e.createDiv({cls:"stashpad-folderenc-panel"});this.pfeRerender=()=>{i.empty(),this.renderFolderEncPanel(i,this.pfeSelected)},new P.Setting(e).setName("Folder").setDesc("Pick a folder to configure its password, archive, and trash options. Everything below applies to the selected folder only.").setHeading().addDropdown(s=>{for(let n of t)s.addOption(n,n);s.setValue(this.pfeSelected),s.selectEl.addClass("stashpad-folderenc-picker"),s.onChange(n=>{this.pfeSelected=n,this.pfeRerender?.()})}),e.appendChild(i),this.renderFolderEncPanel(i,this.pfeSelected)}renderFolderEncPanel(e,t){let i=this.plugin.encryption,s=i.hasOwnFolderKey(t),n=i.folderKeyEntry(t)?.folderPath??null,o=!!n&&!s,a=i.isFolderUnlocked(t),l=(this.plugin.settings.folderEncPrefs??{})[t]??{},c=s?a?"Has its own password \xB7 unlocked":"Has its own password \xB7 locked":o?`Inherits \u201C${n.split("/").pop()||n}\u201D's password \xB7 ${a?"unlocked":"locked"}`:"Uses the vault password",d=new P.Setting(e).setName("Password").setDesc(c);if(o?d.addButton(u=>u.setButtonText("Manage on parent folder").onClick(()=>{this.pfeSelected=n,this.update?.(),this.pfeRerender?.()})):s?a?d.addButton(u=>u.setButtonText("Change password\u2026").onClick(()=>this.promptChangeFolderPassword(t))):d.addButton(u=>u.setButtonText("Unlock\u2026").setCta().onClick(()=>this.promptUnlockFolder(t))):d.addButton(u=>u.setButtonText("Set folder password\u2026").setCta().onClick(()=>this.promptSetFolderPassword(t))),s&&a){let u=this.plugin.encryption.folderHasRecovery(t),g=new P.Setting(e).setName("Recovery password").setDesc(u?"A second password that also unlocks this folder. Keep it somewhere safe and separate.":"Optional. Add a second password that also unlocks this folder, as a backup if the main one is lost.");g.addButton(I=>I.setButtonText(u?"Change recovery\u2026":"Add recovery\u2026").onClick(()=>this.promptSetFolderRecovery(t))),u&&g.addButton(I=>{I.setButtonText("Remove recovery").onClick(()=>this.promptRemoveFolderRecovery(t)),I.buttonEl.addClass("mod-warning")})}let h=async u=>{this.plugin.settings.folderEncPrefs={...this.plugin.settings.folderEncPrefs??{},[t]:{...(this.plugin.settings.folderEncPrefs??{})[t]??{},...u}},await this.plugin.saveSettings()};new P.Setting(e).setName("Trash handling").setDesc("Where notes deleted from this folder go.").addDropdown(u=>u.addOption("","Stashpad trash (default)").addOption("obsidian","Obsidian native trash").setValue(l.trashHandling==="obsidian"?"obsidian":"").onChange(g=>h({trashHandling:g||void 0})));let p=(u,g,I,m,C=!1)=>{new P.Setting(e).setName(u).addToggle(B=>B.setValue(!!l[g]).onChange(async E=>{if(E&&C){if(!this.plugin.encryption.hasFolderKey(t)){new P.Notice("Give this folder a password first (the \u201CSet folder password\u2026\u201D button above), then enable this."),this.pfeRerender?.();return}if(!await this.plugin.ensureFolderUnlocked(t)){this.pfeRerender?.();return}}let y={};y[g]=E,E||(y[I]=!1),await h(y),m&&await m(E),this.pfeRerender?.()})),new P.Setting(e).setName(`\u21B3 ${u} \u2014 hide filenames`).setClass("stashpad-subsetting").addToggle(B=>{B.setValue(!!l[I]),B.setDisabled(!l[g]),B.onChange(async E=>{let y={};y[I]=E,await h(y),this.pfeRerender?.()})})};p("Encrypt this folder's notes","encryptContent","encryptFilenames",async u=>{u?await this.plugin.lockFolder(t):await this.plugin.unlockFolder(t);let g=(this.plugin.settings.lockedSubtrees??[]).some(I=>(I.folder||"").replace(/\/+$/,"")===t);await h({encryptContent:g,...g?{}:{encryptFilenames:!1}})}),p("Encrypt archived notes","archiveEncryptContent","archiveEncryptFilenames",async u=>{if(!u)return;let g=this.plugin.archivedPlainNotesIn(`${t}/archive`).length;g!==0&&new j(this.app,`Encrypt the ${g} note${g===1?"":"s"} already archived?`,`\u201C${t.split("/").pop()}\u201D's archive already holds ${g} plaintext note${g===1?"":"s"}. Encrypt ${g===1?"it":"them"} now too? (Skipping leaves ${g===1?"it":"them"} readable; only notes archived from now on get encrypted.)`,"Encrypt them",async I=>{if(!I)return;let m=await this.plugin.encryptExistingArchiveNotes(t);new P.Notice(m>0?`Encrypted ${m} archived note${m===1?"":"s"}.`:"Nothing was encrypted (cancelled or already locked)."),this.pfeRerender?.()}).open()},!0),p("Encrypt trashed notes","trashEncryptContent","trashEncryptFilenames",void 0,!0),new P.Setting(e).setName("Auto re-encrypt after idle minutes").setDesc("Override the global auto-re-encrypt timer for this folder. Blank = use global; 0 = off for this folder. A cancellable countdown always shows first, and open notes are never touched.").addText(u=>{u.setPlaceholder("global"),u.setValue(l.reEncryptAfterMin==null?"":String(l.reEncryptAfterMin)),u.onChange(g=>{let I=g.trim();{let m=Number(I);I===""?h({reEncryptAfterMin:void 0}):Number.isFinite(m)&&m>=0?h({reEncryptAfterMin:Math.floor(m)}):u.setValue(l.reEncryptAfterMin==null?"":String(l.reEncryptAfterMin))}})});let f=this.plugin.discoverStashpadFolders().filter(u=>u!==t&&u.startsWith(t+"/")).sort();if(f.length){new P.Setting(e).setName("Subfolders").setDesc(`${f.length} subfolder${f.length===1?"":"s"} \u2014 they use \u201C${t.split("/").pop()}\u201D's password. Encrypt each individually.`).setHeading();for(let u of f){let g=(this.plugin.settings.folderEncPrefs??{})[u]??{},I=async B=>{this.plugin.settings.folderEncPrefs={...this.plugin.settings.folderEncPrefs??{},[u]:{...(this.plugin.settings.folderEncPrefs??{})[u]??{},...B}},await this.plugin.saveSettings()},m=(this.plugin.settings.lockedSubtrees??[]).some(B=>(B.folder||"").replace(/\/+$/,"")===u),C=u.slice(t.length+1);new P.Setting(e).setName(C).addToggle(B=>B.setValue(m).onChange(async E=>{E?await this.plugin.lockFolder(u):await this.plugin.unlockFolder(u);let y=(this.plugin.settings.lockedSubtrees??[]).some(v=>(v.folder||"").replace(/\/+$/,"")===u);await I({encryptContent:y,...y?{}:{encryptFilenames:!1}}),this.update?.(),this.pfeRerender?.()})),new P.Setting(e).setName(`\u21B3 ${C} \u2014 hide filenames`).setClass("stashpad-subsetting").addToggle(B=>{B.setValue(!!g.encryptFilenames),B.setDisabled(!m),B.onChange(E=>void I({encryptFilenames:E}))})}}}buildGeneralCategories(){let e=async()=>this.plugin.saveSettings(),t=(s,n,o,a,l)=>this.renderDef(s,n,c=>c.addToggle(d=>d.setValue(o()).onChange(async h=>{a(h),await e()})),l),i={foldersStorage:[],importExport:[],datesTime:[],listDisplay:[],movingNotes:[],deleting:[],composerCopy:[],windowsTabs:[],maintenance:[],misc:[]};i.foldersStorage.push(this.renderDef("Stashpad notes folder","Vault-relative folder where Stashpad stores its notes and attachments. Created on demand.",s=>{s.addText(n=>{new Ii(this.app,n.inputEl),n.setValue(this.plugin.settings.folder).setPlaceholder("Stashpad");let o=async()=>{let a=(n.getValue()||"").trim().replace(/^\/+|\/+$/g,"")||Mt.folder,l=a.split("/").filter(Boolean),c=new Set([this.plugin.settings.importDropFolder,this.plugin.settings.exportFolder,"_attachments","_processed","_authors","_deleted","archive","trash",".stashpad"].map(d=>(d??"").trim().replace(/^\/+|\/+$/g,"")).filter(Boolean));if(l.some(d=>c.has(d))){new P.Notice(`"${a}" uses a reserved Stashpad subfolder name. Pick something else.`),n.setValue(this.plugin.settings.folder);return}a!==this.plugin.settings.folder&&(this.plugin.settings.folder=a,await e())};n.inputEl.addEventListener("blur",()=>void o()),n.inputEl.addEventListener("keydown",a=>{a.key==="Enter"&&o()})})},["folder","path","location","notes"])),i.importExport.push(t("Auto-import dropped files","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.",()=>this.plugin.settings.autoImport,s=>{this.plugin.settings.autoImport=s},["import","drop","auto"])),i.foldersStorage.push(t("Inherit Obsidian's excluded files","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.",()=>this.plugin.settings.inheritObsidianExclusions,s=>{this.plugin.settings.inheritObsidianExclusions=s},["excluded","ignore","files"])),i.foldersStorage.push(t("Include pinned notes in the folder switcher","When on, the folder switcher / creator (the folder button and the \u201COpen or switch Stashpad folder\u201D command) also lists your pinned notes, so you can jump straight to one. Off keeps the picker focused on folders.",()=>this.plugin.settings.folderSwitcherIncludePinned,s=>{this.plugin.settings.folderSwitcherIncludePinned=s},["pinned","switcher","folder","picker","jump"])),i.foldersStorage.push(this.renderDef("Folder tab icon","Give a folder its own Lucide icon (e.g. rocket, star, book-open) shown on its tab, the folder switcher, and its folder-panel row. Pick a folder, then start typing in the icon box \u2014 matching icons appear with previews; pick one. Blank = the default icon. Set per folder.",s=>{let n=this.plugin.discoverStashpadFolders();if(n.length===0){s.setDesc("No Stashpad folders found yet.");return}(!this.iconPickFolder||!n.includes(this.iconPickFolder))&&(this.iconPickFolder=n[0]);let o=null,a=s.controlEl.createSpan({cls:"stashpad-folder-icon-preview"}),l=c=>{a.empty();let d=c.trim();d&&(0,P.setIcon)(a,d)};s.addDropdown(c=>{for(let d of n)c.addOption(d,d.split("/").pop()||d);c.setValue(this.iconPickFolder),c.onChange(d=>{this.iconPickFolder=d;let h=this.plugin.getFolderIcon(d)??"";o?.setValue(h),l(h)})}),s.addText(c=>{o=c,c.setPlaceholder("type to search\u2026 (e.g. rocket)"),new en(this.app,c.inputEl),c.setValue(this.plugin.getFolderIcon(this.iconPickFolder)??""),c.onChange(async d=>{l(d),await this.plugin.setFolderIcon(this.iconPickFolder,d.trim())})}),l(this.plugin.getFolderIcon(this.iconPickFolder)??"")},["icon","folder","tab","lucide","emoji","switcher"])),i.importExport.push(this.renderDef("Dedicated import subfolder (optional)","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.",s=>s.addText(n=>n.setValue(this.plugin.settings.importDropFolder).setPlaceholder("_imports (leave blank to use the folder root)").onChange(async o=>{this.plugin.settings.importDropFolder=(o||"").trim().replace(/^\/+|\/+$/g,""),await e()})),["import","subfolder"])),i.importExport.push(this.renderDef("Stash export subfolder","Subfolder name (relative to each Stashpad folder) where exports land. Must differ from the import subfolder above.",s=>s.addText(n=>n.setValue(this.plugin.settings.exportFolder).setPlaceholder("_exports").onChange(async o=>{this.plugin.settings.exportFolder=(o||"").trim().replace(/^\/+|\/+$/g,"")||Mt.exportFolder,await e()})),["export","stash","subfolder"])),i.importExport.push(this.renderDef("Exclude subfolders by prefix","Comma-separated name prefixes (default \u201C_\u201D). A subfolder whose name starts with any of these \u2014 at any depth \u2014 is NOT surfaced as a Stashpad folder or imported (it stays local). To encrypt such a folder, right-click it in Obsidian's file explorer \u2192 \u201C\u{1F512} Encrypt with Stashpad\u201D.",s=>s.addText(n=>n.setValue(this.plugin.settings.importExcludePrefixes??"_").setPlaceholder("_").onChange(async o=>{this.plugin.settings.importExcludePrefixes=o,await e()})),["import","exclude","prefix","subfolder","underscore","ignore"])),i.maintenance.push(this.renderDef("Rebootstrap existing Stashpad folders","Walk every folder that has a home note: ensure infrastructure (_imports, _exports, drafts file), backfill the redundant parentLink + children frontmatter fields, rename any note whose filename slug no longer matches its body's first line, AND migrate legacy attachment filenames to the new name-first format (`photo-<id>.png`). Safe to run anytime; skip-if-equal means already-synced notes are no-op writes.",s=>s.addButton(n=>n.setButtonText("Rebootstrap now").onClick(async()=>{n.setDisabled(!0).setButtonText("Working\u2026");try{await this.plugin.runRebootstrapWithUI()}catch{}finally{n.setDisabled(!1).setButtonText("Rebootstrap now")}})),["rebootstrap","rebuild","repair","backfill","slug"])),i.maintenance.push(this.renderDef("Write recovery navigation links","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.",s=>s.addToggle(n=>n.setValue(this.plugin.settings.writeRecoveryLinks).onChange(async o=>{this.plugin.settings.writeRecoveryLinks=o,await e()})),["recovery","parentlink","children","frontmatter"]));{let s=null,n=()=>{s&&s.setText(`Sample: ${it(Date.now(),this.plugin.settings)}`)};i.datesTime.push(this.renderDef("Date display format","How created / edited timestamps and due dates are shown \u2014 in the notes list, the Tasks panel, and the detail panel. Overridden by the Templates-plugin formats when the option below is on.",o=>{o.addDropdown(a=>{a.addOption("locale","Locale, short (Mar 5, 9:00 AM)"),a.addOption("long","Locale, long (Thursday, March 5\u2026)"),a.addOption("iso","ISO (2026-03-05 09:00)"),a.addOption("us","US (3/5/2026, 9:00 AM)"),a.addOption("eu","EU (5/3/2026, 09:00)"),a.setValue(this.plugin.settings.dateDisplayFormat??"locale"),a.onChange(async l=>{this.plugin.settings.dateDisplayFormat=l,await e(),n()})})},["date","format","display"])),i.datesTime.push(this.renderDef("Use Templates plugin date/time formats","Use the date/time formats configured in the core Templates plugin instead of the Date display format above. Off = the Date display format above is used everywhere.",o=>{o.addToggle(l=>l.setValue(this.plugin.settings.useTemplatesFormat).onChange(async c=>{this.plugin.settings.useTemplatesFormat=c,await e(),n()}));let a=fn(this.app);o.descEl.createDiv({cls:"stashpad-settings-note"}).setText(a?`Templates plugin: date = "${a.dateFormat}", time = "${a.timeFormat}"`:"Templates plugin not enabled.")},["templates","date","time","format"])),i.datesTime.push(this.renderDef("Display timezone","IANA timezone name (e.g. America/New_York, Europe/London, Asia/Kolkata). Leave blank to use your system timezone.",o=>{o.addText(a=>{a.setPlaceholder("(system timezone)"),a.setValue(this.plugin.settings.dateDisplayTimezone??""),a.onChange(async l=>{this.plugin.settings.dateDisplayTimezone=(l||"").trim(),await e(),n()})})},["timezone","tz","date","iana"])),i.datesTime.push(this.renderDef("Quick due-date adjustments","Comma-separated relative amounts shown as quick +/- buttons in the due-date and snooze pickers (e.g. 5m, 15m, 1h, 1d, 1w). Units: m=minutes, h=hours, d=days, w=weeks. A +/- flip in the picker toggles add vs subtract. Leave blank to hide the row.",o=>{o.addText(a=>{a.setPlaceholder("5m, 15m, 1h, 1d, 1w"),a.setValue((this.plugin.settings.dueQuickAdjusts??[]).join(", ")),a.onChange(async l=>{let c=l.split(",").map(d=>d.trim()).filter(d=>/^\d+\s*[mhdw]$/i.test(d)).map(d=>d.replace(/\s+/g,"").toLowerCase());this.plugin.settings.dueQuickAdjusts=c,await e()})})},["quick","adjust","snooze","due","preset","increment","decrement"])),i.datesTime.push({name:"Date sample",searchable:!1,render:o=>{let a=o.settingEl;a.empty(),a.removeClass("setting-item"),a.addClass("stashpad-settings-section"),s=a.createDiv({cls:"setting-item-description stashpad-settings-note stashpad-date-sample"}),n()}})}return i.movingNotes.push(t("Navigate into parent after moving a note IN","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.",()=>this.plugin.settings.autoNavOnMoveIn,s=>{this.plugin.settings.autoNavOnMoveIn=s},["navigate","move","in"])),i.movingNotes.push(t("Open the new parent in a background tab after moving a note IN","When you nest a note into another note, open that parent in a background Stashpad tab so its new home is one click away \u2014 without stealing focus from what you're doing. Skipped when the destination is Home or already open in a tab. On by default.",()=>this.plugin.settings.openParentTabOnMoveIn,s=>{this.plugin.settings.openParentTabOnMoveIn=s},["background","tab","move","in","parent"])),i.movingNotes.push(t("Navigate to destination after moving a note OUT","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.",()=>this.plugin.settings.autoNavOnMoveOut,s=>{this.plugin.settings.autoNavOnMoveOut=s},["navigate","move","out"])),i.listDisplay.push(t("Double-click a note to open it","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.",()=>this.plugin.settings.doubleClickToFocus,s=>{this.plugin.settings.doubleClickToFocus=s},["double","click","open","focus"])),i.misc.push(t("Sheet versions (alternate drafts)",`Treat notes that share a 'sheet-group' frontmatter id as alternate versions of one item: only the active version shows as a row, and its siblings collapse into a tab bar at the bottom of that row. Use "Fork as version" on a note to start. Off by default \u2014 when off, no note is ever hidden by this feature and the commands do nothing.`,()=>this.plugin.settings.enableSheetVersions,s=>{this.plugin.settings.enableSheetVersions=s},["sheet","version","draft","alternate","fork"])),i.listDisplay.push(t("Auto-open the detail panel","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.",()=>this.plugin.settings.autoOpenDetailPanel,s=>{this.plugin.settings.autoOpenDetailPanel=s},["detail","panel","sidebar"])),i.listDisplay.push(t("Expand the cursor row's body automatically","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.",()=>this.plugin.settings.autoExpandCursorRow,s=>{this.plugin.settings.autoExpandCursorRow=s},["expand","cursor","body"])),i.listDisplay.push(t("Expand note bodies by default","Show every note's full body by default instead of clamping long notes. The per-note 'Show more / show less' toggle and the Expand-all / Collapse-all commands then work in reverse \u2014 they let you collapse individual notes back down. Off = bodies clamp by default (expand is opt-in).",()=>this.plugin.settings.expandBodiesByDefault,s=>{this.plugin.settings.expandBodiesByDefault=s},["expand","collapse","default","body","clamp"])),i.movingNotes.push(t("Confirm cross-parent drag-and-drop","When dragging notes onto a note that has a different parent, ask before re-parenting (turn off to allow direct moves).",()=>this.plugin.settings.confirmCrossParentDrag,s=>{this.plugin.settings.confirmCrossParentDrag=s},["confirm","drag","drop","reparent"])),i.deleting.push(t("Confirm bulk deletes","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).",()=>this.plugin.settings.confirmBulkDelete,s=>{this.plugin.settings.confirmBulkDelete=s},["confirm","delete","bulk"])),i.deleting.push(t("Offer to delete attachments with note",`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.`,()=>this.plugin.settings.confirmAttachmentDelete,s=>{this.plugin.settings.confirmAttachmentDelete=s},["delete","attachment","orphan"])),i.foldersStorage.push(this.sectionDef("Cross-Stashpad Search Scope","Toggle each Stashpad's pill to choose whether its notes contribute to cross-folder search. Excluded folders are still valid move destinations. Also: create a new Stashpad.",s=>{let n=this.plugin.discoverStashpadFolders();if(new P.Setting(s).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."),n.length===0)s.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 a=s.createDiv({cls:"stashpad-folder-list"});for(let l of n)this.renderFolderScopeRow(a,l)}let o=null;new P.Setting(s).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(a=>{a.setPlaceholder("my-stashpad"),o=a.inputEl}).addButton(a=>a.setButtonText("Create").setCta().onClick(async()=>{let l=(o?.value??"").trim().replace(/^\/+|\/+$/g,"");if(!l){new P.Notice("Enter a folder name first.");return}try{await this.plugin.createNewStashpad(l),new P.Notice(`Created Stashpad "${l}".`),o&&(o.value=""),await this.plugin.waitForStashpadFolder(l,2e3),this.update?.()}catch(c){new P.Notice(`Couldn't create: ${c.message}`)}}))},["search","scope","exclude","include","create","new","stashpad","folder"])),i.foldersStorage.push(this.sectionDef("Folder Panel Placement","Pin, downrank, or hide folders in the Stashpad folder panel. Restore hidden folders here or from the panel's \u201CHidden\u201D section.",s=>{new P.Setting(s).setName("Folder Panel Placement").setDesc("Folders you've pinned, downranked, or hidden in the Stashpad folder panel. Pin/downrank from a folder's right-click menu in the panel; restore here or from the panel's \u201CHidden\u201D section."),this.renderFolderPlacementList(s)},["folder","panel","pin","pinned","downrank","hide","hidden","restore","placement"])),i.foldersStorage.push(this.headingDef("\u{1F3F7}\uFE0F Note Titles")),i.foldersStorage.push(this.renderDef("Slug stop-words","Words removed from auto-generated note titles (filenames). One per line.",s=>{let n=null,o=(this.plugin.settings.slugStopWords?.length?this.plugin.settings.slugStopWords:st).join(` `);s.addTextArea(a=>{a.setValue(o),n=a.inputEl,n.rows=6,n.setCssStyles({fontFamily:"var(--font-monospace)"}),a.onChange(async l=>{this.plugin.settings.slugStopWords=(l||"").split(/\r?\n/).map(c=>c.trim().toLowerCase()).filter(Boolean),await e()})}).addExtraButton(a=>a.setIcon("rotate-ccw").setTooltip("Reset to defaults").onClick(async()=>{this.plugin.settings.slugStopWords=[...st],n&&(n.value=st.join(` -`)),await e()}))},["slug","stopwords","filename","title","note titles"])),i.composerCopy.push(t("Autofocus composer after sending","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.",()=>this.plugin.settings.autofocusComposerAfterSend,s=>{this.plugin.settings.autofocusComposerAfterSend=s},["composer","focus","send"])),i.composerCopy.push(t("Focus composer when opening a note","Focus the composer when you open or switch into a Stashpad view. OFF (default) focuses the LIST instead, so arrow-key navigation works right away instead of the composer grabbing focus every time. (Separate from 'after sending' above.)",()=>this.plugin.settings.focusComposerOnOpen,s=>{this.plugin.settings.focusComposerOnOpen=s},["composer","focus","open","navigate","list"])),i.windowsTabs.push(t("Search opens the note in its list (in context)","When you pick a search result, open the LIST that contains the note (focus its parent) and scroll to the note \u2014 so you see it in context instead of landing on the focused-note header. On by default.",()=>this.plugin.settings.searchOpensInContext,s=>{this.plugin.settings.searchOpensInContext=s},["search","context","list","scroll","parent"])),i.windowsTabs.push(t("Open in new window \u2014 duplicate tab","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.",()=>this.plugin.settings.popoutDuplicates,s=>{this.plugin.settings.popoutDuplicates=s},["popout","window","duplicate"])),i.windowsTabs.push(t("Search results open in a new tab","When you pick a result in the Search modal, open it in a new Stashpad tab instead of navigating the current tab. Applies to same-folder and cross-Stashpad results alike. On by default.",()=>this.plugin.settings.searchOpensInNewTab,s=>{this.plugin.settings.searchOpensInNewTab=s},["search","new tab","results","open"])),i.windowsTabs.push(t("Folders always open in a new tab","When you open a folder (folders panel, folder switcher, or the file-explorer \u201COpen folder in Stashpad\u201D), always open a NEW tab at the home note instead of reusing an already-open tab. The folder switcher also drops its \u201CReveal <folder> tab\u201D option. Off by default (reuses an existing tab when there is one).",()=>this.plugin.settings.foldersAlwaysNewTab,s=>{this.plugin.settings.foldersAlwaysNewTab=s},["folder","new tab","reveal","open","panel"])),i.composerCopy.push(t("Prefix timestamps when copying","Include each note's timestamp before its body when copying with C or Y.",()=>this.plugin.settings.prefixTimestampsOnCopy,s=>{this.plugin.settings.prefixTimestampsOnCopy=s},["copy","timestamp","prefix"])),i}encryptionItems(){let e=this.plugin.encryption,t=[];return t.push(this.sectionDef("Vault Encryption","Set one password to encrypt content in this vault. Stored only on this device \u2014 there is no recovery if you lose it.",i=>{i.addClass("stashpad-encryption-section");let s=i.createDiv({cls:"stashpad-beta-row"});s.createEl("span",{cls:"stashpad-beta-badge",text:"BETA"}),s.createEl("span",{cls:"stashpad-beta-note",text:"Encryption is in beta \u2014 keep your own backups of anything important."});let n=i.createEl("div",{cls:"stashpad-enc-warning"});n.createEl("p").setText("\u26A0\uFE0F AI-built, NOT human-audited. This encryption was written by an AI assistant \u2014 not reviewed or security-audited by a human. Treat it as best-effort protection against a casual snoop, not a guarantee \u2014 and always keep your own unencrypted backups of anything important."),n.createEl("p").setText("There is NO recovery. If you lose a password, anything encrypted under it (notes, archived items, encrypted-trash items) is gone for good. Locking, encrypted archiving, and secure-deleting permanently remove the plaintext \u2014 the encrypted copy is the only one left. (A plaintext archive only de-indexes notes from search; it does NOT encrypt them.)"),n.createEl("p").setText("Each device unlocks with its own password (it never leaves the device); collaborators get access by device approval, not a shared password. If everyone with access loses their password, the content is unrecoverable. While encrypting or decrypting, avoid having a sync/cloud service write the vault mid-operation \u2014 it can corrupt files.");let o=i.createEl("details",{cls:"stashpad-enc-info"});o.createEl("summary",{text:"\u2139\uFE0F How Stashpad encryption works (concepts)"});let a=(c,A)=>{let h=o.createEl("p",{cls:"stashpad-enc-info-item"});h.createEl("strong",{text:`${c} \u2014 `}),h.appendText(A)};a("Per-folder passwords","Encryption is per folder: give a folder its OWN password (a separate key) and its notes lock under that key. Subfolders inherit their nearest keyed ancestor's password. A folder with no password of its own (or inherited) is not encrypted. Share a folder by handing over its password out-of-band."),a("Encrypt notes vs Hide filenames","\u201CEncrypt \u2026 notes\u201D scrambles the note body into a locked .stashenc blob (the plaintext is removed). \u201CHide filenames\u201D goes further: it replaces the on-disk name AND the placeholder title with a generic label, so a glance at the vault doesn't reveal WHAT is locked. Whether a title is hidden is decided when the note is locked."),a("Archive: plaintext vs encrypted","Every folder has its own \u201Carchive\u201D subfolder. Archiving is a plain move by default \u2014 the notes drop out of cross-folder search but stay readable. Turn on \u201CEncrypt archived notes\u201D for a folder to lock notes as they're archived instead."),a("Trash: Stashpad vs Obsidian","Deleting a note normally sends it to that folder's own \u201Ctrash\u201D subfolder \u2014 encrypted if the folder encrypts its trash \u2014 and it's recoverable from the Trash view. Set a folder's \u201CTrash handling\u201D to \u201CObsidian native trash\u201D to use Obsidian's plain deleted-files behavior instead (Stashpad can't encrypt or recover those)."),a("No recovery","There is no backdoor and no reset. If a password is lost, everything encrypted under it is gone \u2014 so keep your own unencrypted backups of anything you can't afford to lose."),e.hasAnyFolderKey()?new P.Setting(i).setName("Remove all encryption").setDesc("Decrypts everything back to plaintext and deletes every folder's password/key. If anything is still locked, you'll be offered to decrypt it (needs each folder's password) or \u2014 if a password is lost \u2014 permanently delete it. Then type the confirmation phrase.").addButton(c=>{let A=async()=>{let p=await this.plugin.encryptionStateStrict();if(p.live){let u=()=>{new j(this.app,"Delete all locked content forever?","This PERMANENTLY destroys every locked note and folder \u2014 there is NO decrypted copy and NO recovery. Only do this if you've lost the password and want to start fresh.","Delete locked content forever",async I=>{if(!I)return;let m=await this.plugin.purgeAllLockedContent();new P.Notice(`Deleted ${m} locked item${m===1?"":"s"}.`),A()},"Cancel",!0).open()},g=async()=>{if(await this.plugin.unlockAllInVault(),(await this.plugin.encryptionStateStrict()).live){new P.Notice("Some notes are still locked (decryption was cancelled or failed) \u2014 removal cancelled.",1e4);return}A()};new j(this.app,"Encrypted notes are still locked",`Some notes or folders are still encrypted (locked) and have no plaintext copy. Before removing encryption: +`)),await e()}))},["slug","stopwords","filename","title","note titles"])),i.composerCopy.push(t("Autofocus composer after sending","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.",()=>this.plugin.settings.autofocusComposerAfterSend,s=>{this.plugin.settings.autofocusComposerAfterSend=s},["composer","focus","send"])),i.composerCopy.push(t("Focus composer when opening a note","Focus the composer when you open or switch into a Stashpad view. OFF (default) focuses the LIST instead, so arrow-key navigation works right away instead of the composer grabbing focus every time. (Separate from 'after sending' above.)",()=>this.plugin.settings.focusComposerOnOpen,s=>{this.plugin.settings.focusComposerOnOpen=s},["composer","focus","open","navigate","list"])),i.windowsTabs.push(t("Search opens the note in its list (in context)","When you pick a search result, open the LIST that contains the note (focus its parent) and scroll to the note \u2014 so you see it in context instead of landing on the focused-note header. On by default.",()=>this.plugin.settings.searchOpensInContext,s=>{this.plugin.settings.searchOpensInContext=s},["search","context","list","scroll","parent"])),i.windowsTabs.push(t("Open in new window \u2014 duplicate tab","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.",()=>this.plugin.settings.popoutDuplicates,s=>{this.plugin.settings.popoutDuplicates=s},["popout","window","duplicate"])),i.windowsTabs.push(t("Search results open in a new tab","When you pick a result in the Search modal, open it in a new Stashpad tab instead of navigating the current tab. Applies to same-folder and cross-Stashpad results alike. On by default.",()=>this.plugin.settings.searchOpensInNewTab,s=>{this.plugin.settings.searchOpensInNewTab=s},["search","new tab","results","open"])),i.windowsTabs.push(t("Folders always open in a new tab","When you open a folder (folders panel, folder switcher, or the file-explorer \u201COpen folder in Stashpad\u201D), always open a NEW tab at the home note instead of reusing an already-open tab. The folder switcher also drops its \u201CReveal <folder> tab\u201D option. Off by default (reuses an existing tab when there is one).",()=>this.plugin.settings.foldersAlwaysNewTab,s=>{this.plugin.settings.foldersAlwaysNewTab=s},["folder","new tab","reveal","open","panel"])),i.composerCopy.push(t("Prefix timestamps when copying","Include each note's timestamp before its body when copying with C or Y.",()=>this.plugin.settings.prefixTimestampsOnCopy,s=>{this.plugin.settings.prefixTimestampsOnCopy=s},["copy","timestamp","prefix"])),i}encryptionItems(){let e=this.plugin.encryption,t=[];return t.push(this.sectionDef("Vault Encryption","Set one password to encrypt content in this vault. Stored only on this device \u2014 there is no recovery if you lose it.",i=>{i.addClass("stashpad-encryption-section");let s=i.createDiv({cls:"stashpad-beta-row"});s.createEl("span",{cls:"stashpad-beta-badge",text:"BETA"}),s.createEl("span",{cls:"stashpad-beta-note",text:"Encryption is in beta \u2014 keep your own backups of anything important."});let n=i.createEl("div",{cls:"stashpad-enc-warning"});n.createEl("p").setText("\u26A0\uFE0F AI-built, NOT human-audited. This encryption was written by an AI assistant \u2014 not reviewed or security-audited by a human. Treat it as best-effort protection against a casual snoop, not a guarantee \u2014 and always keep your own unencrypted backups of anything important."),n.createEl("p").setText("There is NO recovery. If you lose a password, anything encrypted under it (notes, archived items, encrypted-trash items) is gone for good. Locking, encrypted archiving, and secure-deleting permanently remove the plaintext \u2014 the encrypted copy is the only one left. (A plaintext archive only de-indexes notes from search; it does NOT encrypt them.)"),n.createEl("p").setText("Each device unlocks with its own password (it never leaves the device); collaborators get access by device approval, not a shared password. If everyone with access loses their password, the content is unrecoverable. While encrypting or decrypting, avoid having a sync/cloud service write the vault mid-operation \u2014 it can corrupt files.");let o=i.createEl("details",{cls:"stashpad-enc-info"});o.createEl("summary",{text:"\u2139\uFE0F How Stashpad encryption works (concepts)"});let a=(c,d)=>{let h=o.createEl("p",{cls:"stashpad-enc-info-item"});h.createEl("strong",{text:`${c} \u2014 `}),h.appendText(d)};a("Per-folder passwords","Encryption is per folder: give a folder its OWN password (a separate key) and its notes lock under that key. Subfolders inherit their nearest keyed ancestor's password. A folder with no password of its own (or inherited) is not encrypted. Share a folder by handing over its password out-of-band."),a("Encrypt notes vs Hide filenames","\u201CEncrypt \u2026 notes\u201D scrambles the note body into a locked .stashenc blob (the plaintext is removed). \u201CHide filenames\u201D goes further: it replaces the on-disk name AND the placeholder title with a generic label, so a glance at the vault doesn't reveal WHAT is locked. Whether a title is hidden is decided when the note is locked."),a("Archive: plaintext vs encrypted","Every folder has its own \u201Carchive\u201D subfolder. Archiving is a plain move by default \u2014 the notes drop out of cross-folder search but stay readable. Turn on \u201CEncrypt archived notes\u201D for a folder to lock notes as they're archived instead."),a("Trash: Stashpad vs Obsidian","Deleting a note normally sends it to that folder's own \u201Ctrash\u201D subfolder \u2014 encrypted if the folder encrypts its trash \u2014 and it's recoverable from the Trash view. Set a folder's \u201CTrash handling\u201D to \u201CObsidian native trash\u201D to use Obsidian's plain deleted-files behavior instead (Stashpad can't encrypt or recover those)."),a("No recovery","There is no backdoor and no reset. If a password is lost, everything encrypted under it is gone \u2014 so keep your own unencrypted backups of anything you can't afford to lose."),e.hasAnyFolderKey()?new P.Setting(i).setName("Remove all encryption").setDesc("Decrypts everything back to plaintext and deletes every folder's password/key. If anything is still locked, you'll be offered to decrypt it (needs each folder's password) or \u2014 if a password is lost \u2014 permanently delete it. Then type the confirmation phrase.").addButton(c=>{let d=async()=>{let p=await this.plugin.encryptionStateStrict();if(p.live){let u=()=>{new j(this.app,"Delete all locked content forever?","This PERMANENTLY destroys every locked note and folder \u2014 there is NO decrypted copy and NO recovery. Only do this if you've lost the password and want to start fresh.","Delete locked content forever",async I=>{if(!I)return;let m=await this.plugin.purgeAllLockedContent();new P.Notice(`Deleted ${m} locked item${m===1?"":"s"}.`),d()},"Cancel",!0).open()},g=async()=>{if(await this.plugin.unlockAllInVault(),(await this.plugin.encryptionStateStrict()).live){new P.Notice("Some notes are still locked (decryption was cancelled or failed) \u2014 removal cancelled.",1e4);return}d()};new j(this.app,"Encrypted notes are still locked",`Some notes or folders are still encrypted (locked) and have no plaintext copy. Before removing encryption: \u2022 Decrypt everything \u2014 unlock them back to normal notes (needs your password). -\u2022 Delete locked content \u2014 permanently destroy them (only if you've lost the password).`,"Decrypt everything",I=>{I?g():u()},"Delete locked content").open();return}let f=(u,g)=>{new vi(this.app,{title:"Remove encryption?",body:`This erases the encryption key for this vault. No locked notes/folders exist, so your live content is safe.${u} You'll need to set a new password to encrypt again later, and anything previously exported with this key stays locked to its passphrase.`,phrase:"REMOVE ENCRYPTION",confirmText:"Remove encryption",onConfirm:async()=>{let I=await this.plugin.encryptionStateStrict();if(I.live){new P.Notice("Locked notes appeared while this dialog was open \u2014 removal cancelled. Decrypt everything first.",1e4);return}if(I.trash&&!g){new P.Notice("Encrypted trash appeared while this dialog was open \u2014 removal cancelled. Re-open Remove encryption to handle it.",1e4);return}let m=await this.plugin.listDeletedTrash();for(let C of m)await this.plugin.purgeDeletedAt(C.blob);await e.clear(),new P.Notice("Encryption removed."),this.update?.()}}).open()};if(p.trash){let u=async()=>{let I=await this.plugin.restoreAllTrash();if((await this.plugin.encryptionStateStrict()).trash){new P.Notice("Some encrypted-trash items couldn't be decrypted \u2014 removal cancelled. Check the trash tab and try again.",1e4);return}f(I>0?` (${I} trash item${I===1?"":"s"} were decrypted back to their folders.)`:"",!0)},g=()=>{new j(this.app,"Discard encrypted trash?","The encrypted-trash items will be PERMANENTLY lost the moment the key is erased \u2014 there is no recovery. Continue?","Confirm",I=>{I&&f(" \u26A0\uFE0F The encrypted trash is being permanently discarded.",!0)},"Cancel",!0).open()};new j(this.app,"Encrypted notes in the trash",`There are encrypted, deleted notes in the trash. Removing encryption makes them PERMANENTLY unreadable. +\u2022 Delete locked content \u2014 permanently destroy them (only if you've lost the password).`,"Decrypt everything",I=>{I?g():u()},"Delete locked content").open();return}let f=(u,g)=>{new Qi(this.app,{title:"Remove encryption?",body:`This erases the encryption key for this vault. No locked notes/folders exist, so your live content is safe.${u} You'll need to set a new password to encrypt again later, and anything previously exported with this key stays locked to its passphrase.`,phrase:"REMOVE ENCRYPTION",confirmText:"Remove encryption",onConfirm:async()=>{let I=await this.plugin.encryptionStateStrict();if(I.live){new P.Notice("Locked notes appeared while this dialog was open \u2014 removal cancelled. Decrypt everything first.",1e4);return}if(I.trash&&!g){new P.Notice("Encrypted trash appeared while this dialog was open \u2014 removal cancelled. Re-open Remove encryption to handle it.",1e4);return}let m=await this.plugin.listDeletedTrash();for(let C of m)await this.plugin.purgeDeletedAt(C.blob);await e.clear(),new P.Notice("Encryption removed."),this.update?.()}}).open()};if(p.trash){let u=async()=>{let I=await this.plugin.restoreAllTrash();if((await this.plugin.encryptionStateStrict()).trash){new P.Notice("Some encrypted-trash items couldn't be decrypted \u2014 removal cancelled. Check the trash tab and try again.",1e4);return}f(I>0?` (${I} trash item${I===1?"":"s"} were decrypted back to their folders.)`:"",!0)},g=()=>{new j(this.app,"Discard encrypted trash?","The encrypted-trash items will be PERMANENTLY lost the moment the key is erased \u2014 there is no recovery. Continue?","Confirm",I=>{I&&f(" \u26A0\uFE0F The encrypted trash is being permanently discarded.",!0)},"Cancel",!0).open()};new j(this.app,"Encrypted notes in the trash",`There are encrypted, deleted notes in the trash. Removing encryption makes them PERMANENTLY unreadable. \u2022 Decrypt Trash \u2014 restore them to their original folders first (recommended). -\u2022 Discard trash \u2014 let them be permanently erased with the key.`,"Decrypt Trash",I=>{I?u():g()},"Discard trash").open();return}f("",!1)},h=!1;c.setButtonText("Remove\u2026").onClick(async()=>{if(!h){h=!0,c.setDisabled(!0),c.buttonEl.addClass("stashpad-btn-loading");try{await A()}finally{h=!1,c.setDisabled(!1),c.buttonEl.removeClass("stashpad-btn-loading")}}}),c.buttonEl.addClass("mod-warning")}):new P.Setting(i).setName("Remove all encryption").setDesc("Nothing is encrypted in this vault yet. Give a folder a password under \u201CPer-Folder Passwords\u201D below to start.");let l=()=>{new vi(this.app,{title:"Permanently delete the old key material?",body:"This PERMANENTLY deletes the old central keyfile (.stashpad/keys.json), its _keys/ backups, and any retired-keyfile backups \u2014 with NO copy kept and NO way to recover them. It does NOT touch your per-folder passwords or currently-encrypted content (use \u201CRemove all encryption\u201D above for those). Only do this if you're sure you'll never need the old key material back.",phrase:"DELETE KEY MATERIAL",confirmText:"Permanently delete",onConfirm:async()=>{let c=await e.wipeLegacyKeyMaterial();new P.Notice(c>0?`Permanently deleted the old key material (${c} item${c===1?"":"s"}). Not recoverable.`:"No old key material found to delete.",9e3),this.update?.()}}).open()};e.hasLegacyKeyfile()?new P.Setting(i).setName("Retire the old encryption keyfile").setDesc("This vault still has the old central keyfile (.stashpad/keys.json), kept only as a read-only backup now that encryption is per-folder. \u201CRetire\u201D MOVES it and its _keys/ backups into .stashpad/retired-keyfile-<date>/ \u2014 reversible, and a recoverable copy is KEPT (nothing is deleted). \u201CPermanently delete\u201D instead removes all old key material with no backup. Retire is blocked if any folder's key still lives only in the old keyfile.").addButton(c=>c.setButtonText("Retire (keep backup)").onClick(async()=>{try{let A=await e.retireLegacyKeyfile();new P.Notice(`Retired the old keyfile \u2014 ${A} file${A===1?"":"s"} moved into .stashpad/retired-keyfile-\u2026 Reversible; a copy is kept.`,9e3),this.update?.()}catch(A){new P.Notice(A.message,12e3)}})).addButton(c=>{c.setButtonText("Permanently delete\u2026").onClick(l),c.buttonEl.addClass("mod-warning")}):e.hasRecoverableKeyMaterial()&&new P.Setting(i).setName("Delete retired keyfile backups").setDesc("The old keyfile was retired, but a recoverable backup is still on disk (.stashpad/retired-keyfile-\u2026 / _keys/). Permanently delete it if you no longer want it recoverable. Doesn't touch your per-folder passwords or encrypted content.").addButton(c=>{c.setButtonText("Permanently delete\u2026").onClick(l),c.buttonEl.addClass("mod-warning")})},["encryption","encrypt","password","passphrase","lock","unlock","key","security","private","folder","share","keyfile","retire"])),t.push(this.headingDef("Encrypted-note defaults","Global defaults for previously-encrypted notes. Per-folder encryption + trash options live under \u201CPer-Folder Passwords\u201D below.")),t.push(this.renderDef("Remind me about unlocked encrypted notes","On startup, if notes that WERE encrypted are still sitting plaintext (you unlocked them, or restored them from the trash), show a notice with a Review button that opens the \u201CPreviously encrypted\u201D view. Nothing is ever re-encrypted automatically.",i=>i.addToggle(s=>s.setValue(this.plugin.settings.reEncryptNudge??!1).onChange(async n=>{this.plugin.settings.reEncryptNudge=n,await this.plugin.saveSettings()})),["remind","nudge","re-encrypt","watchlist","unlocked","sweep"])),t.push(this.renderDef("Auto re-encrypt after idle minutes (global)","0 = OFF (default). After an unlocked, previously-encrypted note sits idle this long, Stashpad shows a \u201CRe-encrypting in 10s\u2026 [Keep unlocked]\u201D countdown you can cancel, then re-locks it. It NEVER re-encrypts a note you have open in an editor. Set per-folder overrides under \u201CPer-Folder Passwords\u201D; per-note in the \u201CPreviously encrypted\u201D view.",i=>i.addText(s=>s.setValue(String(this.plugin.settings.reEncryptAfterMin??0)).onChange(async n=>{{let o=Number(n.trim());if(n.trim()==="")this.plugin.settings.reEncryptAfterMin=0;else if(Number.isFinite(o)&&o>=0)this.plugin.settings.reEncryptAfterMin=Math.floor(o);else{s.setValue(String(this.plugin.settings.reEncryptAfterMin??0));return}await this.plugin.saveSettings()}})),["auto","re-encrypt","idle","timer","peek","lock"])),t.push(this.headingDef("Archive","Every folder has its own \u201Carchive\u201D subfolder: \u201CMove selection to archive\u201D tucks notes into it, archived notes drop out of search, and everything shows up in the aggregated Archived view. Whether a folder's archive is encrypted is set per folder under \u201CPer-Folder Passwords\u201D below (\u201CEncrypt archived notes\u201D).")),t.push(this.sectionDef("Per-Folder Passwords","Give a folder its own password (a separate key) so you can share just that folder with collaborators. Folders without their own password use the vault password.",i=>{this.renderPerFolderEncryption(i)},["folder","per-folder","password","encrypt","key","share","collaborator","archive","unlock","lock"])),t}hotkeyItems(){let e={name:"Hotkeys",desc:"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. A \u21BA icon appears on any slot that differs from its shipped default \u2014 click it to revert that slot. When both slots are set, the pill on the right decides which one is active.",searchable:!1},t=Zt.map(i=>({name:i.label,desc:i.desc,aliases:["hotkey","shortcut","keybind","binding","key"],render:s=>this.renderBindingRow(s,i)}));return[e,...t]}renderJdIndexSection(e){let t=new P.Setting(e).setName("JD Index Builder").setHeading();t.settingEl.id="stashpad-jd-index-section";let i=e.createEl("div",{cls:"stashpad-settings-section"}).createEl("p",{cls:"setting-item-description"});i.appendText("Builds a Johnny-Decimal-style index inside a designated Stashpad folder. Two commands:"),i.createEl("br"),i.createEl("strong",{text:"Preview"}),i.appendText(" overwrites the designated folder\u2019s HOME note body with the would-be hierarchy + everything that didn\u2019t match. Frontmatter is preserved; everything below it is replaced."),i.createEl("br"),i.createEl("strong",{text:"Build"}),i.appendText(" creates an actual hierarchy of Stashpad notes (one per prefix), with child\u2192parent relationships matching the dotted segments."),i.createEl("br"),i.appendText("Matches strict prefixes only: all-digits ("),i.createEl("code",{text:"10 Life"}),i.appendText(") or alphanumeric-with-dots ("),i.createEl("code",{text:"1.2 Family"}),i.appendText(", "),i.createEl("code",{text:"animal.duck.yellow Eggs"}),i.appendText("). Mixed schemes sort numbers first, then alphabetically.");let s=this.plugin.discoverStashpadFolders();new P.Setting(e).setName("Scope").setDesc("Scan the whole vault, or restrict to a single folder + its descendants.").addDropdown(l=>{l.addOption("vault","Entire vault"),l.addOption("folder","Single folder"),l.setValue(this.plugin.settings.jdIndexScope??"vault"),l.onChange(async c=>{this.plugin.settings.jdIndexScope=c==="folder"?"folder":"vault",await this.plugin.saveSettings(),this.display()})}),(this.plugin.settings.jdIndexScope??"vault")==="folder"&&new P.Setting(e).setName("Scope folder").setDesc("Vault-relative path. Leave empty to fall back to the entire vault.").addText(l=>{new fi(this.app,l.inputEl),l.setPlaceholder("Path/To/Folder"),l.setValue(this.plugin.settings.jdIndexScopeFolder??""),l.onChange(async c=>{this.plugin.settings.jdIndexScopeFolder=(c||"").trim().replace(/^\/+|\/+$/g,""),await this.plugin.saveSettings()})}),new P.Setting(e).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(l=>{l.setValue(this.plugin.settings.jdIndexIncludeStashpadFolders===!0),l.onChange(async c=>{this.plugin.settings.jdIndexIncludeStashpadFolders=c,await this.plugin.saveSettings(),this.display()})}),new P.Setting(e).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(l=>{new fi(this.app,l.inputEl),l.setPlaceholder(s[0]??"(pick a Stashpad folder)"),l.setValue(this.plugin.settings.jdIndexStashpadFolder??""),l.onChange(async c=>{this.plugin.settings.jdIndexStashpadFolder=(c||"").trim().replace(/^\/+|\/+$/g,""),await this.plugin.saveSettings()})}),new P.Setting(e).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(l=>{l.addOption("natural","Natural (numeric \u2192 alphabetical)"),l.addOption("created","By creation time"),l.setValue(this.plugin.settings.jdIndexSort??"natural"),l.onChange(async c=>{this.plugin.settings.jdIndexSort=c==="created"?"created":"natural",await this.plugin.saveSettings()})});let n=ui(this.app,this.plugin,this.plugin.settings),o=e.createEl("div",{cls:"stashpad-settings-section"}).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 P.Setting(e).setName("Actions").setClass("stashpad-jd-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(l=>{l.setButtonText("Preview"),l.setTooltip("Overwrites the designated Stashpad folder's HOME note body with the preview."),l.onClick(async()=>{try{let c=await Vs(this.app,this.plugin,this.plugin.settings);if(c.error==="no-dest"){new P.Notice("Set a Designated Stashpad folder for Index first.",5e3);return}if(c.error==="no-home"){new P.Notice(`"${this.plugin.settings.jdIndexStashpadFolder}" doesn't have a Stashpad home note. Open the folder in Stashpad first (it creates one automatically).`,7e3);return}Ws(this.app,c),this.display()}catch(c){console.error("[stashpad] preview failed",c),new P.Notice(`Preview failed: ${c?.message??c}`,8e3)}})}).addButton(l=>{l.setButtonText("Build Stashpad notes"),l.setCta(),l.setTooltip("Create the Stashpad-note hierarchy. Existing notes with matching jdPrefix are updated."),l.onClick(()=>{if(!(this.plugin.settings.jdIndexStashpadFolder??"").trim().replace(/^\/+|\/+$/g,"")){new P.Notice("Set a Designated Stashpad folder for Index first.",5e3);return}new _i(this.app,this.plugin,this.plugin.settings,n.indexed.length,async()=>{try{let h=await So(this.app,this.plugin,this.plugin.settings);if(h.error==="no-dest"){new P.Notice("Set a Designated Stashpad folder for Index first.",5e3);return}if(h.error==="dest-not-stashpad"){new P.Notice(`"${h.destFolder}" isn't a known Stashpad folder. Pick a real Stashpad folder (or create one first).`,7e3);return}this.plugin.settings.jdIndexHasBuilt=!0,await this.plugin.saveSettings(),new P.Notice(`Built: ${h.created} created, ${h.updated} updated, ${h.skipped} skipped \u2192 ${h.destFolder}`,6e3),this.display()}catch(h){console.error("[stashpad] build failed",h),new P.Notice(`Build failed: ${h?.message??h}`,8e3)}}).open()})}).addButton(l=>{l.setButtonText(`Reveal in ${_c()}`),l.setTooltip("Open the designated Stashpad folder in your OS file browser."),l.onClick(async()=>{let c=(this.plugin.settings.jdIndexStashpadFolder??"").trim().replace(/^\/+|\/+$/g,"");if(!c){new P.Notice("Set a Designated Stashpad folder for Index first.",5e3);return}if(!this.app.vault.getAbstractFileByPath(c)){new P.Notice(`Folder "${c}" doesn't exist yet.`,5e3);return}try{let h=this.app.vault.adapter.basePath;if(h){let{shell:p}=window.require?.("electron")??{},f=`${h}/${c}`;p?.openPath?.(f)}else new P.Notice("Reveal in file system not supported on this platform.",4e3)}catch(h){new P.Notice(`Couldn't open folder: ${h?.message??h}`,5e3)}})})}renderColorAliasesSection(e){let t=this.plugin.discoverStashpadFolders();if(t.length===0){new P.Setting(e).setName("Color aliases per Stashpad").setDesc("No Stashpads discovered yet \u2014 create one above first.");return}let i=(()=>{let o=Bt()?.noteFolder;return o&&t.includes(o)?o:t[0]})();new P.Setting(e).setName("Color aliases per Stashpad").setDesc("Which Stashpad's colors to label.").addDropdown(o=>{for(let a of t)o.addOption(a,a);o.setValue(i),o.onChange(a=>{i=a,n()})}),e.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=e.createDiv({cls:"stashpad-color-aliases-list"}),n=()=>{s.empty();let o=this.plugin.collectColorsInFolder(i),a=new Map(o.map(h=>[h.hex,h.count])),l=this.plugin.settings.colorAliases?.[i.replace(/\/+$/,"")]??{},c=new Set([...a.keys(),...Object.keys(l)]);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 A=[...c].map(h=>({hex:h,count:a.get(h)??0}));A.sort((h,p)=>p.count-h.count||h.hex.localeCompare(p.hex));for(let h of A)this.renderColorAliasRow(s,i,h.hex,h.count,n)};n()}authorshipItems(){let e=[];e.push(this.renderDef("Author name","Your display name. Used in the note footer + as the author/contributor link target. Leave blank to opt out (notes won't be stamped).",i=>i.addText(s=>{s.setValue(this.plugin.settings.authorName).onChange(async o=>{this.plugin.settings.authorName=o.trim(),this.plugin.settings.authorName&&!this.plugin.settings.authorId&&(this.plugin.settings.authorId=he()),await this.plugin.saveSettings()});let n=()=>void this.plugin.syncAuthorFilesToName();s.inputEl.addEventListener("blur",n),s.inputEl.addEventListener("keydown",o=>{o.key==="Enter"&&n()})}),["author","name","identity","stamp"])),e.push(this.renderDef("Author id (auto-assigned)","Stable id appended to your name on links so coworkers with the same name don't collide. Generated once and shouldn't change. To reset it, clear and retype your author name.",i=>i.addText(s=>s.setValue(this.plugin.settings.authorId).setDisabled(!0)),["author","id"])),e.push(this.renderDef("Title / role",'Optional. Shown on your author page (e.g. "Engineer", "PM", "Designer").',i=>i.addText(s=>{s.setValue(this.plugin.settings.authorRole).onChange(async o=>{this.plugin.settings.authorRole=o.trim(),await this.plugin.saveSettings()});let n=()=>void this.plugin.syncAuthorFilesToName();s.inputEl.addEventListener("blur",n),s.inputEl.addEventListener("keydown",o=>{o.key==="Enter"&&n()})}),["role","title","job"])),e.push(this.renderDef("Department / team",'Optional. Shown on your author page (e.g. "Engineering", "Growth").',i=>i.addText(s=>{s.setValue(this.plugin.settings.authorDepartment).onChange(async o=>{this.plugin.settings.authorDepartment=o.trim(),await this.plugin.saveSettings()});let n=()=>void this.plugin.syncAuthorFilesToName();s.inputEl.addEventListener("blur",n),s.inputEl.addEventListener("keydown",o=>{o.key==="Enter"&&n()})}),["department","team"]));let t=(i,s,n,o)=>this.renderDef(i,"",a=>a.addToggle(l=>l.setValue(s()).onChange(async c=>{n(c),await this.plugin.saveSettings()})),o);return e.push(t("Show author in note footer",()=>this.plugin.settings.showAuthor,i=>{this.plugin.settings.showAuthor=i},["author","footer","show"])),e.push(t("Show contributors in note footer",()=>this.plugin.settings.showContributors,i=>{this.plugin.settings.showContributors=i},["contributors","footer","show"])),e.push(t("Show last edit time in note footer",()=>this.plugin.settings.showLastEdit,i=>{this.plugin.settings.showLastEdit=i},["last edit","modified","footer","time"])),e.push(this.sectionDef("Folders You've Worked In","Folders where you've authored or contributed notes. Click one to open it.",i=>this.renderAuthoredFolders(i),["folders","authored","contributed","worked"])),e.push(this.sectionDef("Known Authors","Everyone the plugin has seen, with role/department + rename history; rebuild/restore the registry.",i=>this.renderKnownAuthorsSection(i),["authors","registry","rename","known","rebuild"])),e}renderAuthoredFolders(e){new P.Setting(e).setName("Folders you've worked in").setHeading();let t=this.plugin.collectAuthoredFolders();if(t.length===0){e.createEl("p",{cls:"setting-item-description",text:"No authored or contributed folders yet."});return}let i=e.createDiv({cls:"stashpad-authored-folders-list"});for(let s of t){let n=i.createDiv({cls:"stashpad-authored-folder-row"}),o=n.createEl("a",{cls:"stashpad-authored-folder-link",text:s.folder});o.onclick=l=>{l.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(", ")}`})}}templatesItems(){return[this.sectionDef("Color Aliases","Give your note colors friendly names, per Stashpad folder.",e=>this.renderColorAliasesSection(e),["color","colour","alias","name","swatch","palette","label"]),this.sectionDef("Note Templates","Per-Stashpad note templates \u2014 content stamped into new notes.",e=>this.renderNoteTemplatesSection(e),["template","note","default","boilerplate","snippet"])]}jdIndexItems(){return[this.sectionDef("JD Index (Johnny Decimal)","Build a Johnny-Decimal-style index from dotted-prefix note titles \u2014 set the scope, preview, then build.",e=>this.renderJdIndexSection(e),["jd","johnny","decimal","index","scope","build","preview","hierarchy","folder"])]}okfItems(){return[this.sectionDef("Open Knowledge Format (OKF)","Turn a Stashpad folder into a browsable OKF bundle \u2014 markdown concept files with OKF frontmatter, a generated index.md, and relative-markdown cross-links \u2014 that LLMs/agents can read. Complements (never replaces) Stashpad's own frontmatter and links.",e=>this.renderOkfSection(e),["okf","open knowledge format","knowledge","catalog","index","export","bundle","tarball","agent","google"])]}appendCode(e,t){t.split(/`([^`]+)`/g).forEach((i,s)=>{s%2===1?e.createEl("code",{text:i}):i&&e.appendText(i)})}codeDesc(e){let t=document.createDocumentFragment();return this.appendCode(t,e),t}renderOkfSection(e){if(e.createDiv({cls:"stashpad-beta-row"}).createEl("span",{cls:"stashpad-beta-badge",text:"BETA"}),new P.Setting(e).setName("Enable OKF").setDesc(this.codeDesc("Master switch. When on, you choose which folders use OKF by assigning the OKF template to them in Stashpad's own Templates section (the \u{1F4C4} Templates settings here \u2014 NOT Obsidian's core Templates plugin) \u2014 all / some / none, your call. Those folders then get OKF frontmatter and a maintained `index.md`. Turning this off leaves existing OKF files in place; it just stops maintaining them.")).addToggle(i=>i.setValue(this.plugin.settings.okfEnabled).onChange(async s=>{if(this.plugin.settings.okfEnabled=s,await this.plugin.saveSettings(),s)try{await this.plugin.ensureOkfTemplate()}catch(n){console.warn("[Stashpad] OKF template create failed",n)}new P.Notice(s?`OKF on. Next: assign the template "${this.plugin.okfTemplatePathOrDefault()}" to a folder \u2014 use \u201CCreate template + open Templates\u201D below. Heads-up: OKF frontmatter + index.md refresh automatically but NOT instantly (a few seconds after changes); hit Rebuild for an immediate pass.`:"OKF disabled.",s?0:4e3),this.update?.()})),this.plugin.settings.okfEnabled){let i=this.plugin.okfTemplatePathOrDefault(),s=this.plugin.okfActiveFolders().length,n=e.createEl("div",{cls:"setting-item-description stashpad-okf-howto"});n.createEl("p",{text:"How to use OKF in a folder:"});let o=n.createEl("ol");if(this.appendCode(o.createEl("li"),`Open Stashpad's \u{1F4C4} Templates section (here in Stashpad's settings \u2014 not Obsidian's core Templates plugin) and set a folder's template to \`${i}\` (archive folders are skipped).`),this.appendCode(o.createEl("li"),"Hit Rebuild below to write OKF frontmatter (`okfParent`/`okfChildren` + `okfType`/`okfTitle`/`okfTimestamp`) and generate that folder's `index.md`."),this.appendCode(o.createEl("li"),"Right-click a note (or a selection) \u2192 \u201CExport as OKF\u2026\u201D to save a `.zip` / `.tar.gz` bundle (or `.stash`)."),n.createEl("p",{cls:"stashpad-okf-soon",text:"OKF frontmatter + index.md refresh automatically a few seconds after you add, move, or delete notes \u2014 NOT instantly. Use Rebuild for an immediate pass."}),s===0){let a=e.createEl("p",{cls:"stashpad-okf-cta"});this.appendCode(a,"\u{1F449} No folder is using OKF yet. Click \u201CCreate template + open Templates\u201D below, then set a folder's template to `"+i+"`.")}else n.createEl("p",{cls:"stashpad-okf-soon",text:`Currently ${s} folder${s===1?"":"s"} actively using OKF.`});new P.Setting(e).setName("Assign OKF to folders").setDesc(this.codeDesc(`Creates the OKF template if needed (never duplicates it), then opens Templates \u2014 set a folder's template to \`${i}\` there.`)).addButton(a=>{a.setButtonText("Create template + open Templates").setCta(),a.onClick(async()=>{let l;try{l=await this.plugin.ensureOkfTemplate()}catch(c){new P.Notice(`Couldn't create the OKF template: ${c.message}`);return}new P.Notice(`OKF template ready at "${l}" \u2014 set a folder's template to that path.`),this.update?.(),this.openSettingsPage("Templates")})}),new P.Setting(e).setName("Rebuild OKF frontmatter").setDesc(this.codeDesc("Write/refresh OKF fields for every folder using the OKF template \u2014 `okfParent`/`okfChildren` relative links (managed) plus `okfType`/`okfTitle`/`okfTimestamp` defaults (yours to edit after). Heads-up: adding, moving, or deleting notes already auto-refreshes the folder, but NOT instantly \u2014 it waits ~a few seconds after you stop. Use this button for an immediate rebuild (e.g. right after first assigning the template). Complements Stashpad's own links; nothing is removed.")).addButton(a=>a.setButtonText("Rebuild now").onClick(async()=>{let l=await this.plugin.rebuildAllOkf();new P.Notice(l.folders===0?"No folders use the OKF template yet \u2014 assign it in Templates first.":`OKF: updated ${l.written} of ${l.checked} notes across ${l.folders} folder${l.folders===1?"":"s"}.`),this.update?.()}))}let t=new P.Setting(e).setName("Learn about OKF").setDesc("Google's open, vendor-neutral spec for sharing curated knowledge with agents.");t.addButton(i=>i.setButtonText("Spec / repo").onClick(()=>window.open("https://github.com/GoogleCloudPlatform/knowledge-catalog/tree/main/okf"))),t.addButton(i=>i.setButtonText("Announcement").onClick(()=>window.open("https://cloud.google.com/blog/products/data-analytics/how-the-open-knowledge-format-can-improve-data-sharing/")))}openSettingsPage(e){let t=()=>new P.Notice(`Open Settings \u2192 Stashpad \u2192 ${e}.`);try{let i=this.app.setting;if(!i?.openTabById){t();return}i.openTabById("stashpad"),window.setTimeout(()=>{let s=i.modalEl?.querySelector(".vertical-tab-content");if(!s){t();return}let o=Array.from(s.querySelectorAll("*")).find(a=>a.childElementCount===0&&a.textContent?.trim()===e&&!a.closest(".vertical-tab-header"))?.closest("[class*='nav'], .setting-item, button, a");o&&!o.closest(".vertical-tab-header")?o.click():t()},60)}catch{t()}}renderAuthorshipSection(e){new P.Setting(e).setName("Authorship").setHeading(),e.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 P.Setting(e).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=he()),await this.plugin.saveSettings(),await this.plugin.syncAuthorFilesToName()})}),new P.Setting(e).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 P.Setting(e).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 P.Setting(e).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 P.Setting(e).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 P.Setting(e).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 P.Setting(e).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 t=this.plugin.collectAuthoredFolders();if(t.length>0){new P.Setting(e).setName("Folders You've Worked In").setHeading();let i=e.createDiv({cls:"stashpad-authored-folders-list"});for(let s of t){let n=i.createDiv({cls:"stashpad-authored-folder-row"}),o=n.createEl("a",{cls:"stashpad-authored-folder-link",text:s.folder});o.onclick=l=>{l.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(e)}renderKnownAuthorsSection(e){new P.Setting(e).setName("Known Authors (registry)").setHeading(),e.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 P.Setting(e).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 P.Notice(`Author registry rebuilt: ${n.total} author(s).`)}catch(n){new P.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 P.Notice(n.created>0?`Restored ${n.created} author page(s).`:"No missing author pages.")}catch(n){new P.Notice(`Restore failed: ${n.message}`)}s.setDisabled(!1).setButtonText("Restore missing pages")}));let t=this.plugin.authorRegistry.all();if(t.length===0){e.createEl("div",{cls:"setting-item-description",text:"No authors recorded yet. Rebuild to scan the vault."});return}let i=e.createDiv({cls:"stashpad-known-authors-list"});for(let s of t){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 l=n.createDiv({cls:"stashpad-known-author-history"}),c=s.renames.map(A=>`${A.from} \u2192 ${A.to}`).join(", ");l.setText(`Renamed: ${c}`)}}}renderNoteTemplatesSection(e){let t=this.plugin.discoverStashpadFolders();if(t.length===0)return;if(new P.Setting(e).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."),this.plugin.settings.okfEnabled){let n=this.plugin.okfTemplatePathOrDefault();this.appendCode(e.createEl("p",{cls:"setting-item-description"}),`\u{1F4A1} OKF tip: type \`${n}\` into a folder's template field below to turn that folder into an OKF bundle (OKF frontmatter + a maintained \`index.md\`). Assign it to all, some, or none of your folders \u2014 it's per-folder. Manage OKF itself in Settings \u2192 OKF.`)}let i=e.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"}),A=c.createEl("input",{type:"text",cls:"stashpad-note-template-input",attr:{placeholder:"path/to/template.md (leave blank to disable)"}});A.value=(this.plugin.settings.noteTemplates??{})[o]??"";let h=c.createDiv({cls:"stashpad-note-template-suggest"});h.setCssStyles({display:"none"});let p=[],f=[],u=-1,g=()=>h.style.display!=="none"&&p.length>0,I=w=>{u=w,f.forEach((F,D)=>F.toggleClass("is-active",D===w)),w>=0&&f[w]&&f[w].scrollIntoView({block:"nearest"})},m=()=>{h.setCssStyles({display:"none"}),u=-1},C=async w=>{A.value=w,await v(),m()},B=a.createDiv({cls:"stashpad-note-template-warn"});B.setCssStyles({display:"none"});let E=()=>this.app.vault.getMarkdownFiles().map(w=>w.path).filter(w=>!/\/(_imports|_exports|_attachments|\.stashpad)\//.test(w)).sort(),y=()=>{h.empty(),f=[];let w=A.value.trim().toLowerCase().split(/\s+/).filter(Boolean),F=D=>{let H=D.toLowerCase();return w.every(R=>H.includes(R))};if(p=E().filter(D=>F(D)).slice(0,12),p.length===0){m();return}h.setCssStyles({display:""}),p.forEach((D,H)=>{let R=h.createDiv({cls:"stashpad-note-template-suggest-item",text:D});f.push(R),R.addEventListener("mousemove",()=>I(H)),R.addEventListener("mousedown",async L=>{L.preventDefault(),await C(D)})}),u=u>=0&&u<p.length?u:-1,u>=0&&I(u)},v=async()=>{let w=A.value.trim(),F={...this.plugin.settings.noteTemplates??{}};w?F[o]=w:delete F[o],this.plugin.settings.noteTemplates=F,await this.plugin.saveSettings(),Q()},Q=()=>{B.empty(),B.setCssStyles({display:"none"});let w=A.value.trim();if(!w)return;let F=this.app.vault.getAbstractFileByPath(w);if(!F||F.extension!=="md"){B.setCssStyles({display:""}),B.setText(`\u26A0 "${w}" is not a markdown file in this vault.`);return}let D=this.app.metadataCache.getFileCache(F)?.frontmatter??{},R=et.filter(L=>{let x=D[L];return!(x==null||typeof x=="string"&&x.trim()===""||Array.isArray(x)&&x.length===0)});R.length!==0&&(B.setCssStyles({display:""}),B.setText(`\u26A0 Template defines ${R.join(", ")} \u2014 Stashpad always sets ${R.length===1?"this":"these"} on new notes, so the template value${R.length===1?"":"s"} will be ignored.`))};A.addEventListener("focus",y),A.addEventListener("input",()=>{u=-1,y()}),A.addEventListener("blur",()=>{setTimeout(m,150)}),A.addEventListener("change",()=>{v()}),A.addEventListener("keydown",w=>{if(w.key==="ArrowDown")w.preventDefault(),g()?I((u+1)%p.length):(y(),p.length&&I(0));else if(w.key==="ArrowUp"){if(!g())return;w.preventDefault(),I((u-1+p.length)%p.length)}else if(w.key==="Enter")g()&&u>=0&&(w.preventDefault(),C(p[u]));else if(w.key==="Escape")g()&&(w.preventDefault(),m());else if(w.key==="Tab"&&!w.shiftKey){if(!g())return;let F=p[u>=0?u:0],D=A.value,H;if(F.toLowerCase().startsWith(D.toLowerCase())){let R=F.indexOf("/",D.length);H=R>=0?F.slice(0,R+1):F}else H=F;H&&H!==D&&(w.preventDefault(),A.value=H,u=-1,y(),p.length===1&&I(0))}}),Q()};for(let n of t)s(n)}renderColorAliasRow(e,t,i,s,n){let o=e.createDiv({cls:"stashpad-color-alias-row"});s===0&&o.addClass("is-unused");let a=o.createSpan({cls:"stashpad-color-alias-swatch"});a.setCssStyles({background:i}),a.title="Click to bulk-recolor every note of this color in this Stashpad",a.onclick=()=>{let h=this.plugin.settings.customPalette??[];new jt(this.app,i,h,async p=>{if((p??null)===null&&s===0){await this.plugin.setColorAlias(t,i,""),n();return}if(p&&p.toLowerCase()===i){n();return}let f=await this.plugin.recolorAllInFolder(t,i,p??null);if(f>0)new P.Notice(`Recolored ${f} note${f===1?"":"s"}.`);else if(s===0){let u=this.plugin.getColorAlias(t,i);u&&(await this.plugin.setColorAlias(t,i,""),p&&await this.plugin.setColorAlias(t,p,u))}n()},async p=>{let f=(this.plugin.settings.customPalette??[]).filter(u=>u.toLowerCase()!==p.toLowerCase());return this.plugin.settings.customPalette=f,await this.plugin.saveSettings(),f}).open()};let l=o.createDiv({cls:"stashpad-color-alias-meta"});l.createSpan({cls:"stashpad-color-alias-hex",text:i}),l.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(t,i)??"",c.onchange=async()=>{await this.plugin.setColorAlias(t,i,c.value),!c.value.trim()&&s===0&&n()};let A=o.createEl("button",{cls:"stashpad-color-alias-del",text:"\xD7",attr:{title:"Delete alias"}});c.value||A.setCssStyles({visibility:"hidden"}),A.onclick=async()=>{await this.plugin.setColorAlias(t,i,""),s===0?n():(c.value="",A.setCssStyles({visibility:"hidden"}))}}renderFolderScopeRow(e,t){let i=e.createDiv({cls:"stashpad-folder-row"});i.createSpan({cls:"stashpad-folder-row-label",text:t});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(t),l=()=>{let A=a();n.toggleClass("is-right",A),n.setAttribute("aria-checked",String(A)),o.setText(A?"X":"\u2713"),s.setText(A?"Excluded":"Included"),s.toggleClass("is-excluded",A),n.title=A?"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 A=new Set(this.plugin.settings.searchExcludedFolders??[]);A.has(t)?A.delete(t):A.add(t),this.plugin.settings.searchExcludedFolders=[...A].sort(),l(),await this.plugin.saveSettings()};n.onclick=()=>void c(),n.onkeydown=A=>{(A.key===" "||A.key==="Enter")&&(A.preventDefault(),c())},l()}renderFolderPlacementList(e){let t=this.plugin.settings,i=[{key:"folderPanelPinned",label:"Pinned",action:"Unpin"},{key:"folderPanelDownranked",label:"Downranked",action:"Reset"},{key:"folderPanelHidden",label:"Hidden",action:"Unhide"}];if(!i.some(o=>(t[o.key]??[]).length>0)){e.createEl("p",{cls:"setting-item-description"}).setText("No folders customized yet. Right-click a folder in the Stashpad folder panel to pin, downrank, or hide it.");return}let n=async o=>{t.folderPanelPinned=(t.folderPanelPinned??[]).filter(a=>a!==o),t.folderPanelDownranked=(t.folderPanelDownranked??[]).filter(a=>a!==o),t.folderPanelHidden=(t.folderPanelHidden??[]).filter(a=>a!==o),await this.plugin.saveSettings(),this.update?.()};for(let o of i){let a=[...t[o.key]??[]].sort();if(a.length===0)continue;e.createEl("div",{cls:"stashpad-folder-placement-group",text:`${o.label} (${a.length})`});let l=e.createDiv({cls:"stashpad-folder-list"});for(let c of a){let A=l.createDiv({cls:"stashpad-folder-row"});A.createSpan({cls:"stashpad-folder-row-label",text:c});let h=A.createEl("button",{text:o.action});h.onclick=()=>void n(c)}}}renderBindingRow(e,t){e.setName(t.label).setDesc(t.desc),e.settingEl.addClass("stashpad-binding-row");let i=()=>this.plugin.settings.bindings[t.id],s,n,o=()=>{},a=async p=>{},l=e.controlEl.createDiv({cls:"stashpad-binding-seg",attr:{role:"group","aria-label":"Active binding"}}),c={left:l.createEl("button",{cls:"stashpad-binding-seg-btn",text:"Left"}),both:l.createEl("button",{cls:"stashpad-binding-seg-btn",text:"Both"}),right:l.createEl("button",{cls:"stashpad-binding-seg-btn",text:"Right"})};["left","both","right"].forEach(p=>{c[p].onclick=()=>void a(p)});let A=e.controlEl.createDiv({cls:"stashpad-binding-slots"}),h=p=>{let f=A.createDiv({cls:"stashpad-binding-slot"}),u=f.createEl("input",{type:"text"});u.readOnly=!0,u.placeholder="Click & press a key",u.value=mi(i()[p]),u.classList.add("stashpad-binding-input");let g=()=>{u.size=Math.max(3,u.value.length||u.placeholder.length)};g();let I=p==="primary"?t.defaultPrimary:t.defaultSecondary??"";u.onclick=()=>{fr(u,async y=>{let v=Zt.find(Q=>{if(Q.id===t.id)return!1;let w=this.plugin.settings.bindings[Q.id];return!!w&&(w.primary===y||w.secondary===y)});v&&new P.Notice(`Note: ${mi(y)} is also bound to "${v.label}". Both will trigger; the first match wins.`,6e3),this.plugin.settings.bindings[t.id][p]=y,u.value=mi(y),g(),await this.plugin.saveSettings(),o(),E()})};let m=f.createDiv({cls:"stashpad-binding-slot-btns"}),C=m.createEl("button",{cls:"stashpad-binding-clear",text:"\xD7"});C.title="Clear this slot",C.onclick=async()=>{this.plugin.settings.bindings[t.id][p]="",u.value="",g(),await this.plugin.saveSettings(),o(),E()};let B=m.createEl("button",{cls:"stashpad-binding-revert"});(0,P.setIcon)(B,"rotate-ccw");let E=()=>{let v=i()[p]!==I;B.toggleClass("is-hidden",!v),B.title=I?`Revert to default (${mi(I)})`:"Revert to default (no binding)"};return B.onclick=async()=>{this.plugin.settings.bindings[t.id][p]=I,u.value=mi(I),g(),await this.plugin.saveSettings(),o(),E()},E(),u};s=h("primary"),n=h("secondary"),a=async p=>{let f=this.plugin.settings.bindings[t.id];f.primary&&f.secondary&&(p==="both"?f.useBoth=!0:(f.useBoth=!1,f.preferRight=p==="right"),await this.plugin.saveSettings(),o())},o=()=>{let p=i(),f=!!(p.primary&&p.secondary),u=p.useBoth?"both":p.preferRight?"right":"left";["left","both","right"].forEach(g=>{c[g].toggleClass("is-active",f&&g===u),c[g].disabled=!f}),l.toggleClass("is-disabled",!f),l.title=f?"Which binding is active \u2014 Left, Both, or Right":"Bind both slots to choose Left / Both / Right"},o()}}});var Ur,Pt,un=de(()=>{"use strict";Ur=require("obsidian");ce();Qi();Pt=class{constructor(r,e){this.app=r;this.ta=e;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 r=this.detectTrigger();if(!r){this.close();return}this.openFor(r)};this.onBlur=()=>{setTimeout(()=>this.close(),120)};this.onDocEscape=r=>{r.key==="Escape"&&(!this.state||!this.items.length||(r.preventDefault(),r.stopPropagation(),r.stopImmediatePropagation(),this.close()))};this.onKeyDown=r=>{if(!(!this.state||!this.items.length))if(r.key==="ArrowDown")r.preventDefault(),this.activeIdx=(this.activeIdx+1)%this.items.length,this.refreshActive();else if(r.key==="ArrowUp")r.preventDefault(),this.activeIdx=(this.activeIdx-1+this.items.length)%this.items.length,this.refreshActive();else if(r.key==="Enter"||r.key==="Tab")r.preventDefault(),r.stopPropagation(),this.commit();else if(r.key===" "&&this.state.kind==="tag"){let e=this.items[this.activeIdx],t="#"+this.state.query.toLowerCase();e&&e.insert.toLowerCase().startsWith(t)?(r.preventDefault(),r.stopPropagation(),this.commit(" ")):this.close()}else r.key==="Escape"&&(r.preventDefault(),r.stopPropagation(),r.stopImmediatePropagation(),this.close())}}attach(){this.ta.addEventListener("input",this.onInput),this.ta.addEventListener("keydown",this.onKeyDown,!0),this.ta.addEventListener("blur",this.onBlur);let r=this.ta.ownerDocument??document;r.addEventListener("keydown",this.onDocEscape,!0),this.vaultListeners.push(()=>r.removeEventListener("keydown",this.onDocEscape,!0)),this.buildIndex();let e=()=>{this.indexBuilt=!1},t=this.app.vault;t.on("create",e),t.on("delete",e),t.on("rename",e),this.vaultListeners.push(()=>t.off("create",e),()=>t.off("delete",e),()=>t.off("rename",e))}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 r of this.vaultListeners)r();this.vaultListeners=[]}buildIndex(){if(this.indexBuilt)return;let r=X().inheritObsidianExclusions,e=r?this.app.vault.getConfig?.("userIgnoreFilters"):void 0;this.fileIndex=this.app.vault.getFiles().filter(i=>!Va(i.path)&&!Wa(i.path)&&!(r&&Xa(i.path,e))).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 t=this.app.metadataCache.getTags?.()??{};this.tagIndex=Object.keys(t).sort((i,s)=>(t[s]||0)-(t[i]||0)),this.indexBuilt=!0}detectTrigger(){let r=this.ta.value,e=this.ta.selectionStart;if(e==null)return null;let t=r.slice(0,e),i=t.match(/\[\[([^\]\[\n]*)$/);if(i){let o=i[1];return{kind:"link",query:o,replaceStart:e-o.length-2,replaceEnd:e}}let s=t.match(/(^|\s)#([A-Za-z0-9_/\-]+)$/);if(s){let o=s[2];return{kind:"tag",query:o,replaceStart:e-o.length-1,replaceEnd:e}}let n=t.match(/(^|\s)@([^\n@[#]{0,24})$/);if(n){let o=n[2];return{kind:"at",query:o,replaceStart:e-o.length-1,replaceEnd:e}}return null}nldParse(r){let e=r.trim();if(!e)return null;let t=this.app.plugins?.plugins??{};for(let i of["nldates-obsidian","nldates-redux"]){let s=t[i];if(!(!s||typeof s.parseDate!="function"))try{let n=s.parseDate(e);if(!n)continue;if((n.moment&&typeof n.moment.isValid=="function"?n.moment.isValid():!!n.formattedString&&n.formattedString!=="Invalid date")&&n.formattedString)return n.formattedString}catch{}}return null}buildItems(r){this.buildIndex();let e=r.query.toLowerCase().trim(),t=e?e.split(/\s+/).filter(Boolean):[],i=a=>{if(!t.length)return!0;for(let l of t)if(!a.includes(l))return!1;return!0},s=a=>this.fileIndex.filter(l=>i(l.lower)).slice(0,a).map(l=>({label:l.label,insert:`[[${l.insertText}]]`,subtitle:l.file.path}));if(r.kind==="link")return s(50);if(r.kind==="tag")return this.tagIndex.filter(a=>i(a.toLowerCase())).slice(0,30).map(a=>({label:a,insert:a,subtitle:""}));let n=[];if(e==="")for(let a of["today","tomorrow","next week"]){let l=this.nldParse(a);l&&n.push({label:`\u{1F4C5} ${a}`,insert:l,subtitle:`\u2192 ${l}`})}else{let a=this.nldParse(r.query);a&&n.push({label:`\u{1F4C5} ${r.query.trim()}`,insert:a,subtitle:`\u2192 ${a}`})}let o=e===""?n.length?[]:s(15):s(30);return[...n,...o]}openFor(r){if(this.state=r,this.items=this.buildItems(r),this.activeIdx=0,!this.items.length){this.close();return}this.renderPopup(),this.pushScope()}pushScope(){if(this.scope)return;let r=new Ur.Scope(this.app.scope);r.register([],"Escape",e=>(e.preventDefault(),this.close(),!1)),this.scope=r,this.app.keymap?.pushScope(r)}popScope(){if(this.scope){try{this.app.keymap?.popScope(this.scope)}catch{}this.scope=null}}renderPopup(){if(!this.popupEl){let e=this.ta.ownerDocument??document;this.popupEl=e.body.createDiv({cls:"stashpad-composer-suggest"}),this.popupEl.tabIndex=-1,this.popupEl.addEventListener("mousedown",t=>t.preventDefault())}let r=this.popupEl;r.empty();for(let e=0;e<this.items.length;e++){let t=this.items[e],i=r.createDiv({cls:"stashpad-composer-suggest-row"});e===this.activeIdx&&i.addClass("is-active"),i.createSpan({cls:"stashpad-composer-suggest-label",text:t.label}),t.subtitle&&i.createSpan({cls:"stashpad-composer-suggest-sub",text:t.subtitle}),i.onmousedown=s=>{s.preventDefault(),this.activeIdx=e,this.commit()}}this.position()}refreshActive(){if(!this.popupEl)return;let r=this.popupEl.children;for(let t=0;t<r.length;t++)r[t].toggleClass("is-active",t===this.activeIdx);let e=r[this.activeIdx];e&&e.scrollIntoView({block:"nearest"})}position(){if(!this.popupEl)return;let r=this.ta.getBoundingClientRect(),e=this.popupEl.offsetHeight||200,t=r.top-e-4,i=r.left;this.popupEl.style.left=`${Math.max(8,i)}px`,this.popupEl.style.top=`${Math.max(8,t)}px`,this.popupEl.style.minWidth=`${Math.min(360,r.width)}px`}commit(r=""){if(!this.state||!this.items.length)return;let e=this.items[this.activeIdx];if(!e)return;let t=this.ta.value.slice(0,this.state.replaceStart),i=this.ta.value.slice(this.state.replaceEnd),s=e.insert+r;this.ta.value=t+s+i;let n=t.length+s.length;this.ta.setSelectionRange(n,n),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()}}});var ms={};Ji(ms,{BreadcrumbLevelsModal:()=>gs,ColorPickerModal:()=>jt,ConfirmDeleteModal:()=>Fi,ConfirmModal:()=>j,CustomColorModal:()=>fn,DEFAULT_QUICK_ADJUSTS:()=>Gr,DueDatePickerModal:()=>ze,EncryptionPasswordModal:()=>Le,ExportStashModal:()=>bi,ImportDupChoiceModal:()=>us,ImportLogModal:()=>Zo,LogModal:()=>Ei,NoteWorkbench:()=>hs,NoteWorkbenchModal:()=>ki,NoteWorkbenchView:()=>Si,NotificationHistoryModal:()=>ds,OpenDeepLinkModal:()=>ps,ReEncryptReviewModal:()=>fs,StashPasswordModal:()=>rs,TypeToConfirmModal:()=>vi,WORKBENCH_VIEW_TYPE:()=>Is,buildAssigneePicker:()=>Kr,parseAdjustMinutes:()=>Or});function Or(d){let r=/^\s*(\d+)\s*(m|h|d|w)\s*$/i.exec(d);if(!r)return null;let e=parseInt(r[1],10);if(!Number.isFinite(e)||e<=0)return null;let t={m:1,h:60,d:1440,w:10080}[r[2].toLowerCase()]??1;return e*t}function Lr(d,r){let e=d.split(/(\s+)/),t=r.split(/(\s+)/),i=e.length,s=t.length,n=Array.from({length:i+1},()=>new Array(s+1).fill(0));for(let A=i-1;A>=0;A--)for(let h=s-1;h>=0;h--)n[A][h]=e[A]===t[h]?n[A+1][h+1]+1:Math.max(n[A+1][h],n[A][h+1]);let o=[],a=(A,h)=>{let p=o[o.length-1];p&&p.t===A?p.s+=h:o.push({t:A,s:h})},l=0,c=0;for(;l<i&&c<s;)e[l]===t[c]?(a("eq",e[l]),l++,c++):n[l+1][c]>=n[l][c+1]?(a("del",e[l]),l++):(a("ins",t[c]),c++);for(;l<i;)a("del",e[l]),l++;for(;c<s;)a("ins",t[c]),c++;return o}function id(d,r){switch(r){case"lower":return d.toLowerCase();case"upper":return d.toUpperCase();case"title":return d.toLowerCase().replace(/\b\w/g,e=>e.toUpperCase());case"sentence":return d.toLowerCase().replace(/(^\s*\w|[.!?]\s+\w)/g,e=>e.toUpperCase())}}function sd(d,r){let e=d.createDiv({cls:"stashpad-export-content"});e.createEl("label",{cls:"stashpad-export-label",text:"Content"});let t=e.createDiv({cls:"stashpad-export-content-seg"}),i=[{id:"full",label:"Full note"},{id:"frontmatter",label:"Frontmatter only"},{id:"body",label:"Body only"}],s=new Map,n=o=>{s.forEach((a,l)=>a.toggleClass("is-active",l===o)),r(o)};for(let o of i){let a=t.createEl("button",{cls:"stashpad-export-content-opt",text:o.label});a.onclick=l=>{l.preventDefault(),n(o.id)},s.set(o.id,a)}n("full")}function Kr(d,r){let e=[...r.initial],t=r.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"}}),a=n.createDiv({cls:"stashpad-assign-suggest"});a.setCssStyles({display:"none"});let l=()=>r.onChange([...e]),c=()=>{s.empty(),e.length===0&&s.createSpan({cls:"stashpad-assign-empty",text:"No one yet"});for(let p of e){let f=s.createSpan({cls:"stashpad-assign-chip"});f.createSpan({cls:"stashpad-assign-chip-name",text:p.name});let u=f.createSpan({cls:"stashpad-assign-chip-x",text:"\xD7"});u.title=`Remove ${p.name}`,u.onclick=()=>{e=e.filter(g=>g.id!==p.id),l(),c()}}},A=p=>{p.name.trim()&&(e.some(f=>f.id===p.id)||e.push(p),o.value="",a.setCssStyles({display:"none"}),l(),c(),o.focus())},h=()=>{let p=o.value.trim();a.empty();let f=new Set(e.map(I=>I.id)),g=t.filter(I=>!f.has(I.id)&&qs(p,I.name)).slice(0,6).map(I=>({label:I.name,onPick:()=>A(I)}));if(p&&!t.some(I=>I.name.toLowerCase()===p.toLowerCase())&&g.push({label:`Create \u201C${p}\u201D`,onPick:()=>A({id:he(6),name:p})}),g.length===0){a.setCssStyles({display:"none"});return}a.setCssStyles({display:""});for(let I of g){let m=a.createDiv({cls:"stashpad-assign-suggest-item",text:I.label});m.onmousedown=C=>{C.preventDefault(),I.onPick()}}};o.addEventListener("input",h),o.addEventListener("focus",h),o.addEventListener("keydown",p=>{if(p.key==="Enter"){p.preventDefault();let f=a.querySelector(".stashpad-assign-suggest-item");f&&f.dispatchEvent(new MouseEvent("mousedown"))}else p.key==="Escape"&&a.style.display!=="none"&&(p.stopPropagation(),a.setCssStyles({display:"none"}))}),o.addEventListener("blur",()=>{window.setTimeout(()=>{a.setCssStyles({display:"none"})},120)}),c()}var G,Gr,td,_t,Ei,Fi,hs,Is,ki,Si,bi,rs,Le,vi,ps,fn,As,jt,j,gs,ze,ei,ds,Zo,us,fs,ve=de(()=>{"use strict";G=require("obsidian");Zi();vo();ce();Ys();pt();un();Gr=["5m","15m","30m","1h","1d","1w"];td=G.moment,_t=class _t extends G.Modal{constructor(e,t,i){super(e);this.text=t;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 o of this.text.trim().split(/\r?\n/))if(o)try{this.events.push(JSON.parse(o))}catch{}this.events.reverse();let e=this.contentEl.createDiv({cls:"stashpad-log-toolbar"});if(this.countEl=e.createSpan({cls:"stashpad-log-count"}),this.updateCount(),this.filterSelEl=e.createEl("select",{cls:"stashpad-log-type-filter"}),this.filterSelEl.onchange=()=>this.setTypeFilter(this.filterSelEl.value||null),this.refreshTypeFilter(),!G.Platform.isMobile){let o=e.createEl("button",{text:"Reveal JSONL"});o.onclick=()=>this.shellAct("reveal");let a=e.createEl("button",{text:"Open in default app"});a.onclick=()=>this.shellAct("open")}let t=e.createEl("button",{text:"Copy raw JSONL"}),i=null;t.onclick=async()=>{await navigator.clipboard.writeText(this.text),t.setText("Copied"),i!=null&&window.clearTimeout(i),i=window.setTimeout(()=>{t.setText("Copy raw JSONL"),i=null},1500)};let s=e.createEl("button",{text:"Export copy"});s.onclick=()=>this.exportCopy();let n=e.createEl("button",{cls:"mod-warning",text:"Clear log"});n.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(e=>e.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(_t.PAGE)}}setTypeFilter(e){(this.typeFilter??null)!==(e??null)&&(this.typeFilter=e,this.refreshList(),this.renderFooter())}refreshTypeFilter(){if(!this.filterSelEl)return;let e=this.filterSelEl;e.empty();let t=new Map;for(let n of this.events)t.set(n.type,(t.get(n.type)??0)+1);let i=[...t.entries()].sort((n,o)=>o[1]-n[1]||n[0].localeCompare(o[0])),s=e.createEl("option",{text:`All types (${this.events.length})`});s.value="";for(let[n,o]of i){let a=e.createEl("option",{text:`${n} (${o})`});a.value=n}this.typeFilter&&!t.has(this.typeFilter)&&(this.typeFilter=null),e.value=this.typeFilter??""}updateCount(){if(!this.countEl)return;let e=this.visible.length,t=this.typeFilter?`${e} ${this.typeFilter} event${e===1?"":"s"}`:`${e} event${e===1?"":"s"}`;this.shownCount===0||this.shownCount>=e?this.countEl.setText(t):this.countEl.setText(`Showing ${this.shownCount} of ${t}`)}appendMore(e){if(!this.listEl)return;let t=Math.min(this.visible.length,this.shownCount+e);for(let i=this.shownCount;i<t;i++)this.listEl.appendChild(this.renderEvent(this.visible[i]));this.shownCount=t,this.updateCount()}renderFooter(){if(!this.footerEl)return;this.footerEl.empty();let e=this.visible.length-this.shownCount;if(e<=0)return;let t=this.footerEl.createEl("button",{text:`Load ${Math.min(_t.PAGE,e)} more`});if(t.onclick=()=>{this.appendMore(_t.PAGE),this.renderFooter()},e>_t.PAGE){let i=this.footerEl.createEl("button",{text:`Load all (${e})`});i.onclick=()=>{this.appendMore(e),this.renderFooter()}}}shellAct(e){try{let t=this.app.vault.adapter.getFullPath?.(this.jsonlPath);if(!t)throw new Error("no full path");let{shell:i}=window.require("electron");e==="reveal"?i.showItemInFolder(t):i.openPath(t)}catch(t){new G.Notice(`Couldn't ${e}: ${t.message}`)}}async exportCopy(){try{let e=(0,G.moment)().format("YYYY-MM-DD_HHmmss"),t=this.jsonlPath.replace(/\/[^/]+$/,"")||"",i=t?`${t}/${e}-log.jsonl`:`${e}-log.jsonl`;return await this.app.vault.adapter.write(i,this.text),new G.Notice(`Exported log \u2192 ${i}`),i}catch(e){return new G.Notice(`Export failed: ${e.message}`),null}}clearLog(){new j(this.app,"Clear log?","A timestamped copy will be saved alongside the active log before it's truncated.","Export & clear",async e=>{if(!(!e||!await this.exportCopy())){try{await this.app.vault.adapter.write(this.jsonlPath,"")}catch(i){new G.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 G.Notice("Log cleared.")}},"Cancel",!0).open()}renderEvent(e){let t=document.createElement("div");t.className=`stashpad-log-row stashpad-log-${e.type}`;let i=(0,G.moment)(e.ts).isValid()?(0,G.moment)(e.ts).format("YYYY-MM-DD HH:mm:ss"):e.ts,s=document.createElement("span");s.className="stashpad-log-ts",s.textContent=i,t.appendChild(s);let n=document.createElement("span");n.className="stashpad-log-type",n.textContent=e.type,t.appendChild(n);let o=document.createElement("span");o.className="stashpad-log-author",o.textContent=e.author?e.author:"\u2014",e.author||o.classList.add("is-empty"),t.appendChild(o);let a=document.createElement("span");return a.className="stashpad-log-msg",a.textContent=this.describe(e),t.appendChild(a),t}describe(e){let t=e.payload??{};switch(e.type){case"create":return`Created "${t.path??e.id}" under ${t.parent??"?"}`;case"delete":{let i=Array.isArray(t.attachmentsRemoved)?t.attachmentsRemoved.length:0,s=t.mergedInto?` (merged into ${t.mergedInto})`:"",n=t.to==="trash"?" \u2192 Trash":"";return`Deleted ${e.id}${n}${s}${i?` \u2014 also removed ${i} attachment${i===1?"":"s"}`:""}`}case"missing":return`Missing: ${t.lastPath??e.id}`;case"parent_change":{let i=t.reason?` (${t.reason})`:"";return`Moved ${e.id} from ${t.from??"null"} \u2192 ${t.to??"null"}${i}`}case"rename":return`Renamed ${t.from??"?"} \u2192 ${t.to??"?"}`;case"reorder":{let i=t.count??1,s=t.dir??"?",n=t.parent??e.id??"?";return`Reordered ${i} note${i===1?"":"s"} (${s}) under ${n}`}case"complete":{let i=t.count??1,s=t.undo?" (undo)":t.redo?" (redo)":"";return`Marked ${i} note${i===1?"":"s"} complete${s}`}case"uncomplete":{let i=t.count??1,s=t.undo?" (undo)":t.redo?" (redo)":"";return`Unmarked ${i} note${i===1?"":"s"}${s}`}case"stash_export":{let i=t.noteCount??"?";return`Exported ${i} note${i===1?"":"s"} \u2192 ${t.path??"?"}`}case"stash_import":{let i=t.noteCount??"?",s=[];t.attachmentsWritten&&s.push(`${t.attachmentsWritten} attachment${t.attachmentsWritten===1?"":"s"}`),t.collisionsRenamed&&s.push(`${t.collisionsRenamed} renamed`);let n=s.length?` (${s.join(", ")})`:"";return`Imported ${i} note${i===1?"":"s"} from ${t.from??"?"} \u2192 ${t.into??"?"}${n}`}case"attachment_add":return`Added attachment ${t.path??e.id}`;case"attachment_remove":return`Removed attachment ${t.path??e.id}`;case"palette_color_add":return`Added palette color ${t.color??e.id}`;case"palette_color_remove":return`Removed palette color ${t.color??e.id}`;case"lock":return`Locked (encrypted) ${e.id}`;case"unlock":return`Unlocked ${e.id}`;case"archive":return`Archived ${e.id}${t.to?` \u2192 ${t.to}`:""}${t.encrypted===!1?" (plaintext)":""}`;case"restore":return`Restored ${e.id}${t.to?` \u2192 ${t.to}`:""} from trash`;default:return JSON.stringify(t)}}onClose(){this.contentEl.empty()}};_t.PAGE=100;Ei=_t,Fi=class extends G.Modal{constructor(e,t,i,s,n,o){super(e);this.noteTitle=t;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 e=[];this.descendantCount>0&&e.push(`${this.descendantCount} descendant note${this.descendantCount===1?"":"s"} will also be deleted.`),this.attachmentCount>0&&e.push(`${this.attachmentCount} attachment${this.attachmentCount===1?"":"s"} found across these notes.`),this.contentEl.createEl("p",{text:e.join(" ")});let t=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=t,a.onchange=()=>{t=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(t)}}onClose(){this.contentEl.empty()}};hs=class{constructor(r,e,t,i,s){this.app=r;this.host=e;this.body=t;this.cb=s;this.surface="split";this.mode="line";this.presetMode="paragraphs";this.nest=!1;this.cursorTextarea=null;this.autocomplete=null;this.caseCycleIndex=0;this.cursorText=i.cursorText??t,this.collapsed={orig:G.Platform.isMobile,changes:G.Platform.isMobile,edit:!1},this.lines=t.replace(/\r\n/g,` +\u2022 Discard trash \u2014 let them be permanently erased with the key.`,"Decrypt Trash",I=>{I?u():g()},"Discard trash").open();return}f("",!1)},h=!1;c.setButtonText("Remove\u2026").onClick(async()=>{if(!h){h=!0,c.setDisabled(!0),c.buttonEl.addClass("stashpad-btn-loading");try{await d()}finally{h=!1,c.setDisabled(!1),c.buttonEl.removeClass("stashpad-btn-loading")}}}),c.buttonEl.addClass("mod-warning")}):new P.Setting(i).setName("Remove all encryption").setDesc("Nothing is encrypted in this vault yet. Give a folder a password under \u201CPer-Folder Passwords\u201D below to start.");let l=()=>{new Qi(this.app,{title:"Permanently delete the old key material?",body:"This PERMANENTLY deletes the old central keyfile (.stashpad/keys.json), its _keys/ backups, and any retired-keyfile backups \u2014 with NO copy kept and NO way to recover them. It does NOT touch your per-folder passwords or currently-encrypted content (use \u201CRemove all encryption\u201D above for those). Only do this if you're sure you'll never need the old key material back.",phrase:"DELETE KEY MATERIAL",confirmText:"Permanently delete",onConfirm:async()=>{let c=await e.wipeLegacyKeyMaterial();new P.Notice(c>0?`Permanently deleted the old key material (${c} item${c===1?"":"s"}). Not recoverable.`:"No old key material found to delete.",9e3),this.update?.()}}).open()};e.hasLegacyKeyfile()?new P.Setting(i).setName("Retire the old encryption keyfile").setDesc("This vault still has the old central keyfile (.stashpad/keys.json), kept only as a read-only backup now that encryption is per-folder. \u201CRetire\u201D MOVES it and its _keys/ backups into .stashpad/retired-keyfile-<date>/ \u2014 reversible, and a recoverable copy is KEPT (nothing is deleted). \u201CPermanently delete\u201D instead removes all old key material with no backup. Retire is blocked if any folder's key still lives only in the old keyfile.").addButton(c=>c.setButtonText("Retire (keep backup)").onClick(async()=>{try{let d=await e.retireLegacyKeyfile();new P.Notice(`Retired the old keyfile \u2014 ${d} file${d===1?"":"s"} moved into .stashpad/retired-keyfile-\u2026 Reversible; a copy is kept.`,9e3),this.update?.()}catch(d){new P.Notice(d.message,12e3)}})).addButton(c=>{c.setButtonText("Permanently delete\u2026").onClick(l),c.buttonEl.addClass("mod-warning")}):e.hasRecoverableKeyMaterial()&&new P.Setting(i).setName("Delete retired keyfile backups").setDesc("The old keyfile was retired, but a recoverable backup is still on disk (.stashpad/retired-keyfile-\u2026 / _keys/). Permanently delete it if you no longer want it recoverable. Doesn't touch your per-folder passwords or encrypted content.").addButton(c=>{c.setButtonText("Permanently delete\u2026").onClick(l),c.buttonEl.addClass("mod-warning")})},["encryption","encrypt","password","passphrase","lock","unlock","key","security","private","folder","share","keyfile","retire"])),t.push(this.headingDef("Encrypted-note defaults","Global defaults for previously-encrypted notes. Per-folder encryption + trash options live under \u201CPer-Folder Passwords\u201D below.")),t.push(this.renderDef("Remind me about unlocked encrypted notes","On startup, if notes that WERE encrypted are still sitting plaintext (you unlocked them, or restored them from the trash), show a notice with a Review button that opens the \u201CPreviously encrypted\u201D view. Nothing is ever re-encrypted automatically.",i=>i.addToggle(s=>s.setValue(this.plugin.settings.reEncryptNudge??!1).onChange(async n=>{this.plugin.settings.reEncryptNudge=n,await this.plugin.saveSettings()})),["remind","nudge","re-encrypt","watchlist","unlocked","sweep"])),t.push(this.renderDef("Auto re-encrypt after idle minutes (global)","0 = OFF (default). After an unlocked, previously-encrypted note sits idle this long, Stashpad shows a \u201CRe-encrypting in 10s\u2026 [Keep unlocked]\u201D countdown you can cancel, then re-locks it. It NEVER re-encrypts a note you have open in an editor. Set per-folder overrides under \u201CPer-Folder Passwords\u201D; per-note in the \u201CPreviously encrypted\u201D view.",i=>i.addText(s=>s.setValue(String(this.plugin.settings.reEncryptAfterMin??0)).onChange(async n=>{{let o=Number(n.trim());if(n.trim()==="")this.plugin.settings.reEncryptAfterMin=0;else if(Number.isFinite(o)&&o>=0)this.plugin.settings.reEncryptAfterMin=Math.floor(o);else{s.setValue(String(this.plugin.settings.reEncryptAfterMin??0));return}await this.plugin.saveSettings()}})),["auto","re-encrypt","idle","timer","peek","lock"])),t.push(this.headingDef("Archive","Every folder has its own \u201Carchive\u201D subfolder: \u201CMove selection to archive\u201D tucks notes into it, archived notes drop out of search, and everything shows up in the aggregated Archived view. Whether a folder's archive is encrypted is set per folder under \u201CPer-Folder Passwords\u201D below (\u201CEncrypt archived notes\u201D).")),t.push(this.sectionDef("Per-Folder Passwords","Give a folder its own password (a separate key) so you can share just that folder with collaborators. Folders without their own password use the vault password.",i=>{this.renderPerFolderEncryption(i)},["folder","per-folder","password","encrypt","key","share","collaborator","archive","unlock","lock"])),t}hotkeyItems(){let e={name:"Hotkeys",desc:"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. A \u21BA icon appears on any slot that differs from its shipped default \u2014 click it to revert that slot. When both slots are set, the pill on the right decides which one is active.",searchable:!1},t=Zt.map(i=>({name:i.label,desc:i.desc,aliases:["hotkey","shortcut","keybind","binding","key"],render:s=>this.renderBindingRow(s,i)}));return[e,...t]}renderJdIndexSection(e){let t=new P.Setting(e).setName("JD Index Builder").setHeading();t.settingEl.id="stashpad-jd-index-section";let i=e.createEl("div",{cls:"stashpad-settings-section"}).createEl("p",{cls:"setting-item-description"});i.appendText("Builds a Johnny-Decimal-style index inside a designated Stashpad folder. Two commands:"),i.createEl("br"),i.createEl("strong",{text:"Preview"}),i.appendText(" overwrites the designated folder\u2019s HOME note body with the would-be hierarchy + everything that didn\u2019t match. Frontmatter is preserved; everything below it is replaced."),i.createEl("br"),i.createEl("strong",{text:"Build"}),i.appendText(" creates an actual hierarchy of Stashpad notes (one per prefix), with child\u2192parent relationships matching the dotted segments."),i.createEl("br"),i.appendText("Matches strict prefixes only: all-digits ("),i.createEl("code",{text:"10 Life"}),i.appendText(") or alphanumeric-with-dots ("),i.createEl("code",{text:"1.2 Family"}),i.appendText(", "),i.createEl("code",{text:"animal.duck.yellow Eggs"}),i.appendText("). Mixed schemes sort numbers first, then alphabetically.");let s=this.plugin.discoverStashpadFolders();new P.Setting(e).setName("Scope").setDesc("Scan the whole vault, or restrict to a single folder + its descendants.").addDropdown(l=>{l.addOption("vault","Entire vault"),l.addOption("folder","Single folder"),l.setValue(this.plugin.settings.jdIndexScope??"vault"),l.onChange(async c=>{this.plugin.settings.jdIndexScope=c==="folder"?"folder":"vault",await this.plugin.saveSettings(),this.display()})}),(this.plugin.settings.jdIndexScope??"vault")==="folder"&&new P.Setting(e).setName("Scope folder").setDesc("Vault-relative path. Leave empty to fall back to the entire vault.").addText(l=>{new Ii(this.app,l.inputEl),l.setPlaceholder("Path/To/Folder"),l.setValue(this.plugin.settings.jdIndexScopeFolder??""),l.onChange(async c=>{this.plugin.settings.jdIndexScopeFolder=(c||"").trim().replace(/^\/+|\/+$/g,""),await this.plugin.saveSettings()})}),new P.Setting(e).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(l=>{l.setValue(this.plugin.settings.jdIndexIncludeStashpadFolders===!0),l.onChange(async c=>{this.plugin.settings.jdIndexIncludeStashpadFolders=c,await this.plugin.saveSettings(),this.display()})}),new P.Setting(e).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(l=>{new Ii(this.app,l.inputEl),l.setPlaceholder(s[0]??"(pick a Stashpad folder)"),l.setValue(this.plugin.settings.jdIndexStashpadFolder??""),l.onChange(async c=>{this.plugin.settings.jdIndexStashpadFolder=(c||"").trim().replace(/^\/+|\/+$/g,""),await this.plugin.saveSettings()})}),new P.Setting(e).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(l=>{l.addOption("natural","Natural (numeric \u2192 alphabetical)"),l.addOption("created","By creation time"),l.setValue(this.plugin.settings.jdIndexSort??"natural"),l.onChange(async c=>{this.plugin.settings.jdIndexSort=c==="created"?"created":"natural",await this.plugin.saveSettings()})});let n=fi(this.app,this.plugin,this.plugin.settings),o=e.createEl("div",{cls:"stashpad-settings-section"}).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 P.Setting(e).setName("Actions").setClass("stashpad-jd-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(l=>{l.setButtonText("Preview"),l.setTooltip("Overwrites the designated Stashpad folder's HOME note body with the preview."),l.onClick(async()=>{try{let c=await Xs(this.app,this.plugin,this.plugin.settings);if(c.error==="no-dest"){new P.Notice("Set a Designated Stashpad folder for Index first.",5e3);return}if(c.error==="no-home"){new P.Notice(`"${this.plugin.settings.jdIndexStashpadFolder}" doesn't have a Stashpad home note. Open the folder in Stashpad first (it creates one automatically).`,7e3);return}Zs(this.app,c),this.display()}catch(c){console.error("[stashpad] preview failed",c),new P.Notice(`Preview failed: ${c?.message??c}`,8e3)}})}).addButton(l=>{l.setButtonText("Build Stashpad notes"),l.setCta(),l.setTooltip("Create the Stashpad-note hierarchy. Existing notes with matching jdPrefix are updated."),l.onClick(()=>{if(!(this.plugin.settings.jdIndexStashpadFolder??"").trim().replace(/^\/+|\/+$/g,"")){new P.Notice("Set a Designated Stashpad folder for Index first.",5e3);return}new ts(this.app,this.plugin,this.plugin.settings,n.indexed.length,async()=>{try{let h=await xo(this.app,this.plugin,this.plugin.settings);if(h.error==="no-dest"){new P.Notice("Set a Designated Stashpad folder for Index first.",5e3);return}if(h.error==="dest-not-stashpad"){new P.Notice(`"${h.destFolder}" isn't a known Stashpad folder. Pick a real Stashpad folder (or create one first).`,7e3);return}this.plugin.settings.jdIndexHasBuilt=!0,await this.plugin.saveSettings(),new P.Notice(`Built: ${h.created} created, ${h.updated} updated, ${h.skipped} skipped \u2192 ${h.destFolder}`,6e3),this.display()}catch(h){console.error("[stashpad] build failed",h),new P.Notice(`Build failed: ${h?.message??h}`,8e3)}}).open()})}).addButton(l=>{l.setButtonText(`Reveal in ${sd()}`),l.setTooltip("Open the designated Stashpad folder in your OS file browser."),l.onClick(async()=>{let c=(this.plugin.settings.jdIndexStashpadFolder??"").trim().replace(/^\/+|\/+$/g,"");if(!c){new P.Notice("Set a Designated Stashpad folder for Index first.",5e3);return}if(!this.app.vault.getAbstractFileByPath(c)){new P.Notice(`Folder "${c}" doesn't exist yet.`,5e3);return}try{let h=this.app.vault.adapter.basePath;if(h){let{shell:p}=window.require?.("electron")??{},f=`${h}/${c}`;p?.openPath?.(f)}else new P.Notice("Reveal in file system not supported on this platform.",4e3)}catch(h){new P.Notice(`Couldn't open folder: ${h?.message??h}`,5e3)}})})}renderColorAliasesSection(e){let t=this.plugin.discoverStashpadFolders();if(t.length===0){new P.Setting(e).setName("Color aliases per Stashpad").setDesc("No Stashpads discovered yet \u2014 create one above first.");return}let i=(()=>{let o=Bt()?.noteFolder;return o&&t.includes(o)?o:t[0]})();new P.Setting(e).setName("Color aliases per Stashpad").setDesc("Which Stashpad's colors to label.").addDropdown(o=>{for(let a of t)o.addOption(a,a);o.setValue(i),o.onChange(a=>{i=a,n()})}),e.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=e.createDiv({cls:"stashpad-color-aliases-list"}),n=()=>{s.empty();let o=this.plugin.collectColorsInFolder(i),a=new Map(o.map(h=>[h.hex,h.count])),l=this.plugin.settings.colorAliases?.[i.replace(/\/+$/,"")]??{},c=new Set([...a.keys(),...Object.keys(l)]);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 d=[...c].map(h=>({hex:h,count:a.get(h)??0}));d.sort((h,p)=>p.count-h.count||h.hex.localeCompare(p.hex));for(let h of d)this.renderColorAliasRow(s,i,h.hex,h.count,n)};n()}authorshipItems(){let e=[];e.push(this.renderDef("Author name","Your display name. Used in the note footer + as the author/contributor link target. Leave blank to opt out (notes won't be stamped).",i=>i.addText(s=>{s.setValue(this.plugin.settings.authorName).onChange(async o=>{this.plugin.settings.authorName=o.trim(),this.plugin.settings.authorName&&!this.plugin.settings.authorId&&(this.plugin.settings.authorId=he()),await this.plugin.saveSettings()});let n=()=>void this.plugin.syncAuthorFilesToName();s.inputEl.addEventListener("blur",n),s.inputEl.addEventListener("keydown",o=>{o.key==="Enter"&&n()})}),["author","name","identity","stamp"])),e.push(this.renderDef("Author id (auto-assigned)","Stable id appended to your name on links so coworkers with the same name don't collide. Generated once and shouldn't change. To reset it, clear and retype your author name.",i=>i.addText(s=>s.setValue(this.plugin.settings.authorId).setDisabled(!0)),["author","id"])),e.push(this.renderDef("Title / role",'Optional. Shown on your author page (e.g. "Engineer", "PM", "Designer").',i=>i.addText(s=>{s.setValue(this.plugin.settings.authorRole).onChange(async o=>{this.plugin.settings.authorRole=o.trim(),await this.plugin.saveSettings()});let n=()=>void this.plugin.syncAuthorFilesToName();s.inputEl.addEventListener("blur",n),s.inputEl.addEventListener("keydown",o=>{o.key==="Enter"&&n()})}),["role","title","job"])),e.push(this.renderDef("Department / team",'Optional. Shown on your author page (e.g. "Engineering", "Growth").',i=>i.addText(s=>{s.setValue(this.plugin.settings.authorDepartment).onChange(async o=>{this.plugin.settings.authorDepartment=o.trim(),await this.plugin.saveSettings()});let n=()=>void this.plugin.syncAuthorFilesToName();s.inputEl.addEventListener("blur",n),s.inputEl.addEventListener("keydown",o=>{o.key==="Enter"&&n()})}),["department","team"]));let t=(i,s,n,o)=>this.renderDef(i,"",a=>a.addToggle(l=>l.setValue(s()).onChange(async c=>{n(c),await this.plugin.saveSettings()})),o);return e.push(t("Show author in note footer",()=>this.plugin.settings.showAuthor,i=>{this.plugin.settings.showAuthor=i},["author","footer","show"])),e.push(t("Show contributors in note footer",()=>this.plugin.settings.showContributors,i=>{this.plugin.settings.showContributors=i},["contributors","footer","show"])),e.push(t("Show last edit time in note footer",()=>this.plugin.settings.showLastEdit,i=>{this.plugin.settings.showLastEdit=i},["last edit","modified","footer","time"])),e.push(this.sectionDef("Folders You've Worked In","Folders where you've authored or contributed notes. Click one to open it.",i=>this.renderAuthoredFolders(i),["folders","authored","contributed","worked"])),e.push(this.sectionDef("Known Authors","Everyone the plugin has seen, with role/department + rename history; rebuild/restore the registry.",i=>this.renderKnownAuthorsSection(i),["authors","registry","rename","known","rebuild"])),e}renderAuthoredFolders(e){new P.Setting(e).setName("Folders you've worked in").setHeading();let t=this.plugin.collectAuthoredFolders();if(t.length===0){e.createEl("p",{cls:"setting-item-description",text:"No authored or contributed folders yet."});return}let i=e.createDiv({cls:"stashpad-authored-folders-list"});for(let s of t){let n=i.createDiv({cls:"stashpad-authored-folder-row"}),o=n.createEl("a",{cls:"stashpad-authored-folder-link",text:s.folder});o.onclick=l=>{l.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(", ")}`})}}templatesItems(){return[this.sectionDef("Color Aliases","Give your note colors friendly names, per Stashpad folder.",e=>this.renderColorAliasesSection(e),["color","colour","alias","name","swatch","palette","label"]),this.sectionDef("Note Templates","Per-Stashpad note templates \u2014 content stamped into new notes.",e=>this.renderNoteTemplatesSection(e),["template","note","default","boilerplate","snippet"])]}jdIndexItems(){return[this.sectionDef("JD Index (Johnny Decimal)","Build a Johnny-Decimal-style index from dotted-prefix note titles \u2014 set the scope, preview, then build.",e=>this.renderJdIndexSection(e),["jd","johnny","decimal","index","scope","build","preview","hierarchy","folder"])]}okfItems(){return[this.sectionDef("Open Knowledge Format (OKF)","Turn a Stashpad folder into a browsable OKF bundle \u2014 markdown concept files with OKF frontmatter, a generated index.md, and relative-markdown cross-links \u2014 that LLMs/agents can read. Complements (never replaces) Stashpad's own frontmatter and links.",e=>this.renderOkfSection(e),["okf","open knowledge format","knowledge","catalog","index","export","bundle","tarball","agent","google"])]}appendCode(e,t){t.split(/`([^`]+)`/g).forEach((i,s)=>{s%2===1?e.createEl("code",{text:i}):i&&e.appendText(i)})}codeDesc(e){let t=document.createDocumentFragment();return this.appendCode(t,e),t}renderOkfSection(e){if(e.createDiv({cls:"stashpad-beta-row"}).createEl("span",{cls:"stashpad-beta-badge",text:"BETA"}),new P.Setting(e).setName("Enable OKF").setDesc(this.codeDesc("Master switch. When on, you choose which folders use OKF by assigning the OKF template to them in Stashpad's own Templates section (the \u{1F4C4} Templates settings here \u2014 NOT Obsidian's core Templates plugin) \u2014 all / some / none, your call. Those folders then get OKF frontmatter and a maintained `index.md`. Turning this off leaves existing OKF files in place; it just stops maintaining them.")).addToggle(i=>i.setValue(this.plugin.settings.okfEnabled).onChange(async s=>{if(this.plugin.settings.okfEnabled=s,await this.plugin.saveSettings(),s)try{await this.plugin.ensureOkfTemplate()}catch(n){console.warn("[Stashpad] OKF template create failed",n)}new P.Notice(s?`OKF on. Next: assign the template "${this.plugin.okfTemplatePathOrDefault()}" to a folder \u2014 use \u201CCreate template + open Templates\u201D below. Heads-up: OKF frontmatter + index.md refresh automatically but NOT instantly (a few seconds after changes); hit Rebuild for an immediate pass.`:"OKF disabled.",s?0:4e3),this.update?.()})),this.plugin.settings.okfEnabled){let i=this.plugin.okfTemplatePathOrDefault(),s=this.plugin.okfActiveFolders().length,n=e.createEl("div",{cls:"setting-item-description stashpad-okf-howto"});n.createEl("p",{text:"How to use OKF in a folder:"});let o=n.createEl("ol");if(this.appendCode(o.createEl("li"),`Open Stashpad's \u{1F4C4} Templates section (here in Stashpad's settings \u2014 not Obsidian's core Templates plugin) and set a folder's template to \`${i}\` (archive folders are skipped).`),this.appendCode(o.createEl("li"),"Hit Rebuild below to write OKF frontmatter (`okfParent`/`okfChildren` + `okfType`/`okfTitle`/`okfTimestamp`) and generate that folder's `index.md`."),this.appendCode(o.createEl("li"),"Right-click a note (or a selection) \u2192 \u201CExport as OKF\u2026\u201D to save a `.zip` / `.tar.gz` bundle (or `.stash`)."),n.createEl("p",{cls:"stashpad-okf-soon",text:"OKF frontmatter + index.md refresh automatically a few seconds after you add, move, or delete notes \u2014 NOT instantly. Use Rebuild for an immediate pass."}),s===0){let a=e.createEl("p",{cls:"stashpad-okf-cta"});this.appendCode(a,"\u{1F449} No folder is using OKF yet. Click \u201CCreate template + open Templates\u201D below, then set a folder's template to `"+i+"`.")}else n.createEl("p",{cls:"stashpad-okf-soon",text:`Currently ${s} folder${s===1?"":"s"} actively using OKF.`});new P.Setting(e).setName("Assign OKF to folders").setDesc(this.codeDesc(`Creates the OKF template if needed (never duplicates it), then opens Templates \u2014 set a folder's template to \`${i}\` there.`)).addButton(a=>{a.setButtonText("Create template + open Templates").setCta(),a.onClick(async()=>{let l;try{l=await this.plugin.ensureOkfTemplate()}catch(c){new P.Notice(`Couldn't create the OKF template: ${c.message}`);return}new P.Notice(`OKF template ready at "${l}" \u2014 set a folder's template to that path.`),this.update?.(),this.openSettingsPage("Templates")})}),new P.Setting(e).setName("Rebuild OKF frontmatter").setDesc(this.codeDesc("Write/refresh OKF fields for every folder using the OKF template \u2014 `okfParent`/`okfChildren` relative links (managed) plus `okfType`/`okfTitle`/`okfTimestamp` defaults (yours to edit after). Heads-up: adding, moving, or deleting notes already auto-refreshes the folder, but NOT instantly \u2014 it waits ~a few seconds after you stop. Use this button for an immediate rebuild (e.g. right after first assigning the template). Complements Stashpad's own links; nothing is removed.")).addButton(a=>a.setButtonText("Rebuild now").onClick(async()=>{let l=await this.plugin.rebuildAllOkf();new P.Notice(l.folders===0?"No folders use the OKF template yet \u2014 assign it in Templates first.":`OKF: updated ${l.written} of ${l.checked} notes across ${l.folders} folder${l.folders===1?"":"s"}.`),this.update?.()}))}let t=new P.Setting(e).setName("Learn about OKF").setDesc("Google's open, vendor-neutral spec for sharing curated knowledge with agents.");t.addButton(i=>i.setButtonText("Spec / repo").onClick(()=>window.open("https://github.com/GoogleCloudPlatform/knowledge-catalog/tree/main/okf"))),t.addButton(i=>i.setButtonText("Announcement").onClick(()=>window.open("https://cloud.google.com/blog/products/data-analytics/how-the-open-knowledge-format-can-improve-data-sharing/")))}openSettingsPage(e){let t=()=>new P.Notice(`Open Settings \u2192 Stashpad \u2192 ${e}.`);try{let i=this.app.setting;if(!i?.openTabById){t();return}i.openTabById("stashpad"),window.setTimeout(()=>{let s=i.modalEl?.querySelector(".vertical-tab-content");if(!s){t();return}let o=Array.from(s.querySelectorAll("*")).find(a=>a.childElementCount===0&&a.textContent?.trim()===e&&!a.closest(".vertical-tab-header"))?.closest("[class*='nav'], .setting-item, button, a");o&&!o.closest(".vertical-tab-header")?o.click():t()},60)}catch{t()}}renderAuthorshipSection(e){new P.Setting(e).setName("Authorship").setHeading(),e.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 P.Setting(e).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=he()),await this.plugin.saveSettings(),await this.plugin.syncAuthorFilesToName()})}),new P.Setting(e).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 P.Setting(e).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 P.Setting(e).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 P.Setting(e).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 P.Setting(e).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 P.Setting(e).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 t=this.plugin.collectAuthoredFolders();if(t.length>0){new P.Setting(e).setName("Folders You've Worked In").setHeading();let i=e.createDiv({cls:"stashpad-authored-folders-list"});for(let s of t){let n=i.createDiv({cls:"stashpad-authored-folder-row"}),o=n.createEl("a",{cls:"stashpad-authored-folder-link",text:s.folder});o.onclick=l=>{l.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(e)}renderKnownAuthorsSection(e){new P.Setting(e).setName("Known Authors (registry)").setHeading(),e.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 P.Setting(e).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 P.Notice(`Author registry rebuilt: ${n.total} author(s).`)}catch(n){new P.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 P.Notice(n.created>0?`Restored ${n.created} author page(s).`:"No missing author pages.")}catch(n){new P.Notice(`Restore failed: ${n.message}`)}s.setDisabled(!1).setButtonText("Restore missing pages")}));let t=this.plugin.authorRegistry.all();if(t.length===0){e.createEl("div",{cls:"setting-item-description",text:"No authors recorded yet. Rebuild to scan the vault."});return}let i=e.createDiv({cls:"stashpad-known-authors-list"});for(let s of t){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 l=n.createDiv({cls:"stashpad-known-author-history"}),c=s.renames.map(d=>`${d.from} \u2192 ${d.to}`).join(", ");l.setText(`Renamed: ${c}`)}}}renderNoteTemplatesSection(e){let t=this.plugin.discoverStashpadFolders();if(t.length===0)return;if(new P.Setting(e).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."),this.plugin.settings.okfEnabled){let n=this.plugin.okfTemplatePathOrDefault();this.appendCode(e.createEl("p",{cls:"setting-item-description"}),`\u{1F4A1} OKF tip: type \`${n}\` into a folder's template field below to turn that folder into an OKF bundle (OKF frontmatter + a maintained \`index.md\`). Assign it to all, some, or none of your folders \u2014 it's per-folder. Manage OKF itself in Settings \u2192 OKF.`)}let i=e.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"}),d=c.createEl("input",{type:"text",cls:"stashpad-note-template-input",attr:{placeholder:"path/to/template.md (leave blank to disable)"}});d.value=(this.plugin.settings.noteTemplates??{})[o]??"";let h=c.createDiv({cls:"stashpad-note-template-suggest"});h.setCssStyles({display:"none"});let p=[],f=[],u=-1,g=()=>h.style.display!=="none"&&p.length>0,I=w=>{u=w,f.forEach((k,D)=>k.toggleClass("is-active",D===w)),w>=0&&f[w]&&f[w].scrollIntoView({block:"nearest"})},m=()=>{h.setCssStyles({display:"none"}),u=-1},C=async w=>{d.value=w,await v(),m()},B=a.createDiv({cls:"stashpad-note-template-warn"});B.setCssStyles({display:"none"});let E=()=>this.app.vault.getMarkdownFiles().map(w=>w.path).filter(w=>!/\/(_imports|_exports|_attachments|\.stashpad)\//.test(w)).sort(),y=()=>{h.empty(),f=[];let w=d.value.trim().toLowerCase().split(/\s+/).filter(Boolean),k=D=>{let H=D.toLowerCase();return w.every(R=>H.includes(R))};if(p=E().filter(D=>k(D)).slice(0,12),p.length===0){m();return}h.setCssStyles({display:""}),p.forEach((D,H)=>{let R=h.createDiv({cls:"stashpad-note-template-suggest-item",text:D});f.push(R),R.addEventListener("mousemove",()=>I(H)),R.addEventListener("mousedown",async L=>{L.preventDefault(),await C(D)})}),u=u>=0&&u<p.length?u:-1,u>=0&&I(u)},v=async()=>{let w=d.value.trim(),k={...this.plugin.settings.noteTemplates??{}};w?k[o]=w:delete k[o],this.plugin.settings.noteTemplates=k,await this.plugin.saveSettings(),Q()},Q=()=>{B.empty(),B.setCssStyles({display:"none"});let w=d.value.trim();if(!w)return;let k=this.app.vault.getAbstractFileByPath(w);if(!k||k.extension!=="md"){B.setCssStyles({display:""}),B.setText(`\u26A0 "${w}" is not a markdown file in this vault.`);return}let D=this.app.metadataCache.getFileCache(k)?.frontmatter??{},R=et.filter(L=>{let x=D[L];return!(x==null||typeof x=="string"&&x.trim()===""||Array.isArray(x)&&x.length===0)});R.length!==0&&(B.setCssStyles({display:""}),B.setText(`\u26A0 Template defines ${R.join(", ")} \u2014 Stashpad always sets ${R.length===1?"this":"these"} on new notes, so the template value${R.length===1?"":"s"} will be ignored.`))};d.addEventListener("focus",y),d.addEventListener("input",()=>{u=-1,y()}),d.addEventListener("blur",()=>{setTimeout(m,150)}),d.addEventListener("change",()=>{v()}),d.addEventListener("keydown",w=>{if(w.key==="ArrowDown")w.preventDefault(),g()?I((u+1)%p.length):(y(),p.length&&I(0));else if(w.key==="ArrowUp"){if(!g())return;w.preventDefault(),I((u-1+p.length)%p.length)}else if(w.key==="Enter")g()&&u>=0&&(w.preventDefault(),C(p[u]));else if(w.key==="Escape")g()&&(w.preventDefault(),m());else if(w.key==="Tab"&&!w.shiftKey){if(!g())return;let k=p[u>=0?u:0],D=d.value,H;if(k.toLowerCase().startsWith(D.toLowerCase())){let R=k.indexOf("/",D.length);H=R>=0?k.slice(0,R+1):k}else H=k;H&&H!==D&&(w.preventDefault(),d.value=H,u=-1,y(),p.length===1&&I(0))}}),Q()};for(let n of t)s(n)}renderColorAliasRow(e,t,i,s,n){let o=e.createDiv({cls:"stashpad-color-alias-row"});s===0&&o.addClass("is-unused");let a=o.createSpan({cls:"stashpad-color-alias-swatch"});a.setCssStyles({background:i}),a.title="Click to bulk-recolor every note of this color in this Stashpad",a.onclick=()=>{let h=this.plugin.settings.customPalette??[];new jt(this.app,i,h,async p=>{if((p??null)===null&&s===0){await this.plugin.setColorAlias(t,i,""),n();return}if(p&&p.toLowerCase()===i){n();return}let f=await this.plugin.recolorAllInFolder(t,i,p??null);if(f>0)new P.Notice(`Recolored ${f} note${f===1?"":"s"}.`);else if(s===0){let u=this.plugin.getColorAlias(t,i);u&&(await this.plugin.setColorAlias(t,i,""),p&&await this.plugin.setColorAlias(t,p,u))}n()},async p=>{let f=(this.plugin.settings.customPalette??[]).filter(u=>u.toLowerCase()!==p.toLowerCase());return this.plugin.settings.customPalette=f,await this.plugin.saveSettings(),f}).open()};let l=o.createDiv({cls:"stashpad-color-alias-meta"});l.createSpan({cls:"stashpad-color-alias-hex",text:i}),l.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(t,i)??"",c.onchange=async()=>{await this.plugin.setColorAlias(t,i,c.value),!c.value.trim()&&s===0&&n()};let d=o.createEl("button",{cls:"stashpad-color-alias-del",text:"\xD7",attr:{title:"Delete alias"}});c.value||d.setCssStyles({visibility:"hidden"}),d.onclick=async()=>{await this.plugin.setColorAlias(t,i,""),s===0?n():(c.value="",d.setCssStyles({visibility:"hidden"}))}}renderFolderScopeRow(e,t){let i=e.createDiv({cls:"stashpad-folder-row"});i.createSpan({cls:"stashpad-folder-row-label",text:t});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(t),l=()=>{let d=a();n.toggleClass("is-right",d),n.setAttribute("aria-checked",String(d)),o.setText(d?"X":"\u2713"),s.setText(d?"Excluded":"Included"),s.toggleClass("is-excluded",d),n.title=d?"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 d=new Set(this.plugin.settings.searchExcludedFolders??[]);d.has(t)?d.delete(t):d.add(t),this.plugin.settings.searchExcludedFolders=[...d].sort(),l(),await this.plugin.saveSettings()};n.onclick=()=>void c(),n.onkeydown=d=>{(d.key===" "||d.key==="Enter")&&(d.preventDefault(),c())},l()}renderFolderPlacementList(e){let t=this.plugin.settings,i=[{key:"folderPanelPinned",label:"Pinned",action:"Unpin"},{key:"folderPanelDownranked",label:"Downranked",action:"Reset"},{key:"folderPanelHidden",label:"Hidden",action:"Unhide"}];if(!i.some(o=>(t[o.key]??[]).length>0)){e.createEl("p",{cls:"setting-item-description"}).setText("No folders customized yet. Right-click a folder in the Stashpad folder panel to pin, downrank, or hide it.");return}let n=async o=>{t.folderPanelPinned=(t.folderPanelPinned??[]).filter(a=>a!==o),t.folderPanelDownranked=(t.folderPanelDownranked??[]).filter(a=>a!==o),t.folderPanelHidden=(t.folderPanelHidden??[]).filter(a=>a!==o),await this.plugin.saveSettings(),this.update?.()};for(let o of i){let a=[...t[o.key]??[]].sort();if(a.length===0)continue;e.createEl("div",{cls:"stashpad-folder-placement-group",text:`${o.label} (${a.length})`});let l=e.createDiv({cls:"stashpad-folder-list"});for(let c of a){let d=l.createDiv({cls:"stashpad-folder-row"});d.createSpan({cls:"stashpad-folder-row-label",text:c});let h=d.createEl("button",{text:o.action});h.onclick=()=>void n(c)}}}renderBindingRow(e,t){e.setName(t.label).setDesc(t.desc),e.settingEl.addClass("stashpad-binding-row");let i=()=>this.plugin.settings.bindings[t.id],s,n,o=()=>{},a=async p=>{},l=e.controlEl.createDiv({cls:"stashpad-binding-seg",attr:{role:"group","aria-label":"Active binding"}}),c={left:l.createEl("button",{cls:"stashpad-binding-seg-btn",text:"Left"}),both:l.createEl("button",{cls:"stashpad-binding-seg-btn",text:"Both"}),right:l.createEl("button",{cls:"stashpad-binding-seg-btn",text:"Right"})};["left","both","right"].forEach(p=>{c[p].onclick=()=>void a(p)});let d=e.controlEl.createDiv({cls:"stashpad-binding-slots"}),h=p=>{let f=d.createDiv({cls:"stashpad-binding-slot"}),u=f.createEl("input",{type:"text"});u.readOnly=!0,u.placeholder="Click & press a key",u.value=Ci(i()[p]),u.classList.add("stashpad-binding-input");let g=()=>{u.size=Math.max(3,u.value.length||u.placeholder.length)};g();let I=p==="primary"?t.defaultPrimary:t.defaultSecondary??"";u.onclick=()=>{Cr(u,async y=>{let v=Zt.find(Q=>{if(Q.id===t.id)return!1;let w=this.plugin.settings.bindings[Q.id];return!!w&&(w.primary===y||w.secondary===y)});v&&new P.Notice(`Note: ${Ci(y)} is also bound to "${v.label}". Both will trigger; the first match wins.`,6e3),this.plugin.settings.bindings[t.id][p]=y,u.value=Ci(y),g(),await this.plugin.saveSettings(),o(),E()})};let m=f.createDiv({cls:"stashpad-binding-slot-btns"}),C=m.createEl("button",{cls:"stashpad-binding-clear",text:"\xD7"});C.title="Clear this slot",C.onclick=async()=>{this.plugin.settings.bindings[t.id][p]="",u.value="",g(),await this.plugin.saveSettings(),o(),E()};let B=m.createEl("button",{cls:"stashpad-binding-revert"});(0,P.setIcon)(B,"rotate-ccw");let E=()=>{let v=i()[p]!==I;B.toggleClass("is-hidden",!v),B.title=I?`Revert to default (${Ci(I)})`:"Revert to default (no binding)"};return B.onclick=async()=>{this.plugin.settings.bindings[t.id][p]=I,u.value=Ci(I),g(),await this.plugin.saveSettings(),o(),E()},E(),u};s=h("primary"),n=h("secondary"),a=async p=>{let f=this.plugin.settings.bindings[t.id];f.primary&&f.secondary&&(p==="both"?f.useBoth=!0:(f.useBoth=!1,f.preferRight=p==="right"),await this.plugin.saveSettings(),o())},o=()=>{let p=i(),f=!!(p.primary&&p.secondary),u=p.useBoth?"both":p.preferRight?"right":"left";["left","both","right"].forEach(g=>{c[g].toggleClass("is-active",f&&g===u),c[g].disabled=!f}),l.toggleClass("is-disabled",!f),l.title=f?"Which binding is active \u2014 Left, Both, or Right":"Bind both slots to choose Left / Both / Right"},o()}}});var Or,Pt,In=de(()=>{"use strict";Or=require("obsidian");ce();ki();Pt=class{constructor(r,e){this.app=r;this.ta=e;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 r=this.detectTrigger();if(!r){this.close();return}this.openFor(r)};this.onBlur=()=>{setTimeout(()=>this.close(),120)};this.onDocEscape=r=>{r.key==="Escape"&&(!this.state||!this.items.length||(r.preventDefault(),r.stopPropagation(),r.stopImmediatePropagation(),this.close()))};this.onKeyDown=r=>{if(!(!this.state||!this.items.length))if(r.key==="ArrowDown")r.preventDefault(),this.activeIdx=(this.activeIdx+1)%this.items.length,this.refreshActive();else if(r.key==="ArrowUp")r.preventDefault(),this.activeIdx=(this.activeIdx-1+this.items.length)%this.items.length,this.refreshActive();else if(r.key==="Enter"||r.key==="Tab")r.preventDefault(),r.stopPropagation(),this.commit();else if(r.key===" "&&this.state.kind==="tag"){let e=this.items[this.activeIdx],t="#"+this.state.query.toLowerCase();e&&e.insert.toLowerCase().startsWith(t)?(r.preventDefault(),r.stopPropagation(),this.commit(" ")):this.close()}else r.key==="Escape"&&(r.preventDefault(),r.stopPropagation(),r.stopImmediatePropagation(),this.close())}}attach(){this.ta.addEventListener("input",this.onInput),this.ta.addEventListener("keydown",this.onKeyDown,!0),this.ta.addEventListener("blur",this.onBlur);let r=this.ta.ownerDocument??document;r.addEventListener("keydown",this.onDocEscape,!0),this.vaultListeners.push(()=>r.removeEventListener("keydown",this.onDocEscape,!0)),this.buildIndex();let e=()=>{this.indexBuilt=!1},t=this.app.vault;t.on("create",e),t.on("delete",e),t.on("rename",e),this.vaultListeners.push(()=>t.off("create",e),()=>t.off("delete",e),()=>t.off("rename",e))}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 r of this.vaultListeners)r();this.vaultListeners=[]}buildIndex(){if(this.indexBuilt)return;let r=X().inheritObsidianExclusions,e=r?this.app.vault.getConfig?.("userIgnoreFilters"):void 0;this.fileIndex=this.app.vault.getFiles().filter(i=>!Za(i.path)&&!ja(i.path)&&!(r&&_a(i.path,e))).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 t=this.app.metadataCache.getTags?.()??{};this.tagIndex=Object.keys(t).sort((i,s)=>(t[s]||0)-(t[i]||0)),this.indexBuilt=!0}detectTrigger(){let r=this.ta.value,e=this.ta.selectionStart;if(e==null)return null;let t=r.slice(0,e),i=t.match(/\[\[([^\]\[\n]*)$/);if(i){let o=i[1];return{kind:"link",query:o,replaceStart:e-o.length-2,replaceEnd:e}}let s=t.match(/(^|\s)#([A-Za-z0-9_/\-]+)$/);if(s){let o=s[2];return{kind:"tag",query:o,replaceStart:e-o.length-1,replaceEnd:e}}let n=t.match(/(^|\s)@([^\n@[#]{0,24})$/);if(n){let o=n[2];return{kind:"at",query:o,replaceStart:e-o.length-1,replaceEnd:e}}return null}nldParse(r){let e=r.trim();if(!e)return null;let t=this.app.plugins?.plugins??{};for(let i of["nldates-obsidian","nldates-redux"]){let s=t[i];if(!(!s||typeof s.parseDate!="function"))try{let n=s.parseDate(e);if(!n)continue;if((n.moment&&typeof n.moment.isValid=="function"?n.moment.isValid():!!n.formattedString&&n.formattedString!=="Invalid date")&&n.formattedString)return n.formattedString}catch{}}return null}buildItems(r){this.buildIndex();let e=r.query.toLowerCase().trim(),t=e?e.split(/\s+/).filter(Boolean):[],i=a=>{if(!t.length)return!0;for(let l of t)if(!a.includes(l))return!1;return!0},s=a=>this.fileIndex.filter(l=>i(l.lower)).slice(0,a).map(l=>({label:l.label,insert:`[[${l.insertText}]]`,subtitle:l.file.path}));if(r.kind==="link")return s(50);if(r.kind==="tag")return this.tagIndex.filter(a=>i(a.toLowerCase())).slice(0,30).map(a=>({label:a,insert:a,subtitle:""}));let n=[];if(e==="")for(let a of["today","tomorrow","next week"]){let l=this.nldParse(a);l&&n.push({label:`\u{1F4C5} ${a}`,insert:l,subtitle:`\u2192 ${l}`})}else{let a=this.nldParse(r.query);a&&n.push({label:`\u{1F4C5} ${r.query.trim()}`,insert:a,subtitle:`\u2192 ${a}`})}let o=e===""?n.length?[]:s(15):s(30);return[...n,...o]}openFor(r){if(this.state=r,this.items=this.buildItems(r),this.activeIdx=0,!this.items.length){this.close();return}this.renderPopup(),this.pushScope()}pushScope(){if(this.scope)return;let r=new Or.Scope(this.app.scope);r.register([],"Escape",e=>(e.preventDefault(),this.close(),!1)),this.scope=r,this.app.keymap?.pushScope(r)}popScope(){if(this.scope){try{this.app.keymap?.popScope(this.scope)}catch{}this.scope=null}}renderPopup(){if(!this.popupEl){let e=this.ta.ownerDocument??document;this.popupEl=e.body.createDiv({cls:"stashpad-composer-suggest"}),this.popupEl.tabIndex=-1,this.popupEl.addEventListener("mousedown",t=>t.preventDefault())}let r=this.popupEl;r.empty();for(let e=0;e<this.items.length;e++){let t=this.items[e],i=r.createDiv({cls:"stashpad-composer-suggest-row"});e===this.activeIdx&&i.addClass("is-active"),i.createSpan({cls:"stashpad-composer-suggest-label",text:t.label}),t.subtitle&&i.createSpan({cls:"stashpad-composer-suggest-sub",text:t.subtitle}),i.onmousedown=s=>{s.preventDefault(),this.activeIdx=e,this.commit()}}this.position()}refreshActive(){if(!this.popupEl)return;let r=this.popupEl.children;for(let t=0;t<r.length;t++)r[t].toggleClass("is-active",t===this.activeIdx);let e=r[this.activeIdx];e&&e.scrollIntoView({block:"nearest"})}position(){if(!this.popupEl)return;let r=this.ta.getBoundingClientRect(),e=this.popupEl.offsetHeight||200,t=r.top-e-4,i=r.left;this.popupEl.style.left=`${Math.max(8,i)}px`,this.popupEl.style.top=`${Math.max(8,t)}px`,this.popupEl.style.minWidth=`${Math.min(360,r.width)}px`}commit(r=""){if(!this.state||!this.items.length)return;let e=this.items[this.activeIdx];if(!e)return;let t=this.ta.value.slice(0,this.state.replaceStart),i=this.ta.value.slice(this.state.replaceEnd),s=e.insert+r;this.ta.value=t+s+i;let n=t.length+s.length;this.ta.setSelectionRange(n,n),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()}}});var Bs={};Yi(Bs,{BreadcrumbLevelsModal:()=>fs,ColorPickerModal:()=>jt,ConfirmDeleteModal:()=>Fi,ConfirmModal:()=>j,CustomColorModal:()=>mn,DEFAULT_QUICK_ADJUSTS:()=>Jr,DueDatePickerModal:()=>ze,EncryptionPasswordModal:()=>Le,ExportStashModal:()=>Di,ImportDupChoiceModal:()=>Is,ImportLogModal:()=>ea,LogModal:()=>vi,NoteWorkbench:()=>gs,NoteWorkbenchModal:()=>Si,NoteWorkbenchView:()=>bi,NotificationHistoryModal:()=>hs,OpenDeepLinkModal:()=>us,ReEncryptReviewModal:()=>ms,StashPasswordModal:()=>cs,TypeToConfirmModal:()=>Qi,WORKBENCH_VIEW_TYPE:()=>Cs,buildAssigneePicker:()=>$r,parseAdjustMinutes:()=>qr});function qr(A){let r=/^\s*(\d+)\s*(m|h|d|w)\s*$/i.exec(A);if(!r)return null;let e=parseInt(r[1],10);if(!Number.isFinite(e)||e<=0)return null;let t={m:1,h:60,d:1440,w:10080}[r[2].toLowerCase()]??1;return e*t}function Kr(A,r){let e=A.split(/(\s+)/),t=r.split(/(\s+)/),i=e.length,s=t.length,n=Array.from({length:i+1},()=>new Array(s+1).fill(0));for(let d=i-1;d>=0;d--)for(let h=s-1;h>=0;h--)n[d][h]=e[d]===t[h]?n[d+1][h+1]+1:Math.max(n[d+1][h],n[d][h+1]);let o=[],a=(d,h)=>{let p=o[o.length-1];p&&p.t===d?p.s+=h:o.push({t:d,s:h})},l=0,c=0;for(;l<i&&c<s;)e[l]===t[c]?(a("eq",e[l]),l++,c++):n[l+1][c]>=n[l][c+1]?(a("del",e[l]),l++):(a("ins",t[c]),c++);for(;l<i;)a("del",e[l]),l++;for(;c<s;)a("ins",t[c]),c++;return o}function ad(A,r){switch(r){case"lower":return A.toLowerCase();case"upper":return A.toUpperCase();case"title":return A.toLowerCase().replace(/\b\w/g,e=>e.toUpperCase());case"sentence":return A.toLowerCase().replace(/(^\s*\w|[.!?]\s+\w)/g,e=>e.toUpperCase())}}function rd(A,r){let e=A.createDiv({cls:"stashpad-export-content"});e.createEl("label",{cls:"stashpad-export-label",text:"Content"});let t=e.createDiv({cls:"stashpad-export-content-seg"}),i=[{id:"full",label:"Full note"},{id:"frontmatter",label:"Frontmatter only"},{id:"body",label:"Body only"}],s=new Map,n=o=>{s.forEach((a,l)=>a.toggleClass("is-active",l===o)),r(o)};for(let o of i){let a=t.createEl("button",{cls:"stashpad-export-content-opt",text:o.label});a.onclick=l=>{l.preventDefault(),n(o.id)},s.set(o.id,a)}n("full")}function $r(A,r){let e=[...r.initial],t=r.knownAuthors,i=A.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.setCssStyles({display:"none"});let l=()=>r.onChange([...e]),c=()=>{s.empty(),e.length===0&&s.createSpan({cls:"stashpad-assign-empty",text:"No one yet"});for(let p of e){let f=s.createSpan({cls:"stashpad-assign-chip"});f.createSpan({cls:"stashpad-assign-chip-name",text:p.name});let u=f.createSpan({cls:"stashpad-assign-chip-x",text:"\xD7"});u.title=`Remove ${p.name}`,u.onclick=()=>{e=e.filter(g=>g.id!==p.id),l(),c()}}},d=p=>{p.name.trim()&&(e.some(f=>f.id===p.id)||e.push(p),o.value="",a.setCssStyles({display:"none"}),l(),c(),o.focus())},h=()=>{let p=o.value.trim();a.empty();let f=new Set(e.map(I=>I.id)),g=t.filter(I=>!f.has(I.id)&&$s(p,I.name)).slice(0,6).map(I=>({label:I.name,onPick:()=>d(I)}));if(p&&!t.some(I=>I.name.toLowerCase()===p.toLowerCase())&&g.push({label:`Create \u201C${p}\u201D`,onPick:()=>d({id:he(6),name:p})}),g.length===0){a.setCssStyles({display:"none"});return}a.setCssStyles({display:""});for(let I of g){let m=a.createDiv({cls:"stashpad-assign-suggest-item",text:I.label});m.onmousedown=C=>{C.preventDefault(),I.onPick()}}};o.addEventListener("input",h),o.addEventListener("focus",h),o.addEventListener("keydown",p=>{if(p.key==="Enter"){p.preventDefault();let f=a.querySelector(".stashpad-assign-suggest-item");f&&f.dispatchEvent(new MouseEvent("mousedown"))}else p.key==="Escape"&&a.style.display!=="none"&&(p.stopPropagation(),a.setCssStyles({display:"none"}))}),o.addEventListener("blur",()=>{window.setTimeout(()=>{a.setCssStyles({display:"none"})},120)}),c()}var G,Jr,od,_t,vi,Fi,gs,Cs,Si,bi,Di,cs,Le,Qi,us,mn,ps,jt,j,fs,ze,ei,hs,ea,Is,ms,ve=de(()=>{"use strict";G=require("obsidian");_i();Fo();ce();Vs();pt();In();Jr=["5m","15m","30m","1h","1d","1w"];od=G.moment,_t=class _t extends G.Modal{constructor(e,t,i){super(e);this.text=t;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 o of this.text.trim().split(/\r?\n/))if(o)try{this.events.push(JSON.parse(o))}catch{}this.events.reverse();let e=this.contentEl.createDiv({cls:"stashpad-log-toolbar"});if(this.countEl=e.createSpan({cls:"stashpad-log-count"}),this.updateCount(),this.filterSelEl=e.createEl("select",{cls:"stashpad-log-type-filter"}),this.filterSelEl.onchange=()=>this.setTypeFilter(this.filterSelEl.value||null),this.refreshTypeFilter(),!G.Platform.isMobile){let o=e.createEl("button",{text:"Reveal JSONL"});o.onclick=()=>this.shellAct("reveal");let a=e.createEl("button",{text:"Open in default app"});a.onclick=()=>this.shellAct("open")}let t=e.createEl("button",{text:"Copy raw JSONL"}),i=null;t.onclick=async()=>{await navigator.clipboard.writeText(this.text),t.setText("Copied"),i!=null&&window.clearTimeout(i),i=window.setTimeout(()=>{t.setText("Copy raw JSONL"),i=null},1500)};let s=e.createEl("button",{text:"Export copy"});s.onclick=()=>this.exportCopy();let n=e.createEl("button",{cls:"mod-warning",text:"Clear log"});n.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(e=>e.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(_t.PAGE)}}setTypeFilter(e){(this.typeFilter??null)!==(e??null)&&(this.typeFilter=e,this.refreshList(),this.renderFooter())}refreshTypeFilter(){if(!this.filterSelEl)return;let e=this.filterSelEl;e.empty();let t=new Map;for(let n of this.events)t.set(n.type,(t.get(n.type)??0)+1);let i=[...t.entries()].sort((n,o)=>o[1]-n[1]||n[0].localeCompare(o[0])),s=e.createEl("option",{text:`All types (${this.events.length})`});s.value="";for(let[n,o]of i){let a=e.createEl("option",{text:`${n} (${o})`});a.value=n}this.typeFilter&&!t.has(this.typeFilter)&&(this.typeFilter=null),e.value=this.typeFilter??""}updateCount(){if(!this.countEl)return;let e=this.visible.length,t=this.typeFilter?`${e} ${this.typeFilter} event${e===1?"":"s"}`:`${e} event${e===1?"":"s"}`;this.shownCount===0||this.shownCount>=e?this.countEl.setText(t):this.countEl.setText(`Showing ${this.shownCount} of ${t}`)}appendMore(e){if(!this.listEl)return;let t=Math.min(this.visible.length,this.shownCount+e);for(let i=this.shownCount;i<t;i++)this.listEl.appendChild(this.renderEvent(this.visible[i]));this.shownCount=t,this.updateCount()}renderFooter(){if(!this.footerEl)return;this.footerEl.empty();let e=this.visible.length-this.shownCount;if(e<=0)return;let t=this.footerEl.createEl("button",{text:`Load ${Math.min(_t.PAGE,e)} more`});if(t.onclick=()=>{this.appendMore(_t.PAGE),this.renderFooter()},e>_t.PAGE){let i=this.footerEl.createEl("button",{text:`Load all (${e})`});i.onclick=()=>{this.appendMore(e),this.renderFooter()}}}shellAct(e){try{let t=this.app.vault.adapter.getFullPath?.(this.jsonlPath);if(!t)throw new Error("no full path");let{shell:i}=window.require("electron");e==="reveal"?i.showItemInFolder(t):i.openPath(t)}catch(t){new G.Notice(`Couldn't ${e}: ${t.message}`)}}async exportCopy(){try{let e=(0,G.moment)().format("YYYY-MM-DD_HHmmss"),t=this.jsonlPath.replace(/\/[^/]+$/,"")||"",i=t?`${t}/${e}-log.jsonl`:`${e}-log.jsonl`;return await this.app.vault.adapter.write(i,this.text),new G.Notice(`Exported log \u2192 ${i}`),i}catch(e){return new G.Notice(`Export failed: ${e.message}`),null}}clearLog(){new j(this.app,"Clear log?","A timestamped copy will be saved alongside the active log before it's truncated.","Export & clear",async e=>{if(!(!e||!await this.exportCopy())){try{await this.app.vault.adapter.write(this.jsonlPath,"")}catch(i){new G.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 G.Notice("Log cleared.")}},"Cancel",!0).open()}renderEvent(e){let t=document.createElement("div");t.className=`stashpad-log-row stashpad-log-${e.type}`;let i=(0,G.moment)(e.ts).isValid()?(0,G.moment)(e.ts).format("YYYY-MM-DD HH:mm:ss"):e.ts,s=document.createElement("span");s.className="stashpad-log-ts",s.textContent=i,t.appendChild(s);let n=document.createElement("span");n.className="stashpad-log-type",n.textContent=e.type,t.appendChild(n);let o=document.createElement("span");o.className="stashpad-log-author",o.textContent=e.author?e.author:"\u2014",e.author||o.classList.add("is-empty"),t.appendChild(o);let a=document.createElement("span");return a.className="stashpad-log-msg",a.textContent=this.describe(e),t.appendChild(a),t}describe(e){let t=e.payload??{};switch(e.type){case"create":return`Created "${t.path??e.id}" under ${t.parent??"?"}`;case"delete":{let i=Array.isArray(t.attachmentsRemoved)?t.attachmentsRemoved.length:0,s=t.mergedInto?` (merged into ${t.mergedInto})`:"",n=t.to==="trash"?" \u2192 Trash":"";return`Deleted ${e.id}${n}${s}${i?` \u2014 also removed ${i} attachment${i===1?"":"s"}`:""}`}case"missing":return`Missing: ${t.lastPath??e.id}`;case"parent_change":{let i=t.reason?` (${t.reason})`:"";return`Moved ${e.id} from ${t.from??"null"} \u2192 ${t.to??"null"}${i}`}case"rename":return`Renamed ${t.from??"?"} \u2192 ${t.to??"?"}`;case"reorder":{let i=t.count??1,s=t.dir??"?",n=t.parent??e.id??"?";return`Reordered ${i} note${i===1?"":"s"} (${s}) under ${n}`}case"complete":{let i=t.count??1,s=t.undo?" (undo)":t.redo?" (redo)":"";return`Marked ${i} note${i===1?"":"s"} complete${s}`}case"uncomplete":{let i=t.count??1,s=t.undo?" (undo)":t.redo?" (redo)":"";return`Unmarked ${i} note${i===1?"":"s"}${s}`}case"stash_export":{let i=t.noteCount??"?";return`Exported ${i} note${i===1?"":"s"} \u2192 ${t.path??"?"}`}case"stash_import":{let i=t.noteCount??"?",s=[];t.attachmentsWritten&&s.push(`${t.attachmentsWritten} attachment${t.attachmentsWritten===1?"":"s"}`),t.collisionsRenamed&&s.push(`${t.collisionsRenamed} renamed`);let n=s.length?` (${s.join(", ")})`:"";return`Imported ${i} note${i===1?"":"s"} from ${t.from??"?"} \u2192 ${t.into??"?"}${n}`}case"attachment_add":return`Added attachment ${t.path??e.id}`;case"attachment_remove":return`Removed attachment ${t.path??e.id}`;case"palette_color_add":return`Added palette color ${t.color??e.id}`;case"palette_color_remove":return`Removed palette color ${t.color??e.id}`;case"lock":return`Locked (encrypted) ${e.id}`;case"unlock":return`Unlocked ${e.id}`;case"archive":return`Archived ${e.id}${t.to?` \u2192 ${t.to}`:""}${t.encrypted===!1?" (plaintext)":""}`;case"restore":return`Restored ${e.id}${t.to?` \u2192 ${t.to}`:""} from trash`;default:return JSON.stringify(t)}}onClose(){this.contentEl.empty()}};_t.PAGE=100;vi=_t,Fi=class extends G.Modal{constructor(e,t,i,s,n,o){super(e);this.noteTitle=t;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 e=[];this.descendantCount>0&&e.push(`${this.descendantCount} descendant note${this.descendantCount===1?"":"s"} will also be deleted.`),this.attachmentCount>0&&e.push(`${this.attachmentCount} attachment${this.attachmentCount===1?"":"s"} found across these notes.`),this.contentEl.createEl("p",{text:e.join(" ")});let t=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=t,a.onchange=()=>{t=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(t)}}onClose(){this.contentEl.empty()}};gs=class{constructor(r,e,t,i,s){this.app=r;this.host=e;this.body=t;this.cb=s;this.surface="split";this.mode="line";this.presetMode="paragraphs";this.nest=!1;this.cursorTextarea=null;this.autocomplete=null;this.caseCycleIndex=0;this.cursorText=i.cursorText??t,this.collapsed={orig:G.Platform.isMobile,changes:G.Platform.isMobile,edit:!1},this.lines=t.replace(/\r\n/g,` `).split(` `),this.lineCursorIdx=i.lineCursorIdx??Math.max(1,Math.min(this.lines.length-1,Math.floor(this.lines.length/2))),i.mode?this.mode=i.mode:this.lines.length<2&&(this.mode="cursor"),i.presetMode&&(this.presetMode=i.presetMode),i.nest!=null&&(this.nest=i.nest),i.surface&&(this.surface=i.surface),this.host.addEventListener("keydown",n=>this.onTabKey(n)),this.render()}visibleFocusables(){return Array.from(this.host.querySelectorAll('button:not([disabled]), input:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])')).filter(e=>e.offsetParent!==null)}onTabKey(r){if(r.key!=="Tab")return;let e=this.visibleFocusables();if(e.length===0)return;let t=e[0],i=e[e.length-1],s=document.activeElement;r.shiftKey&&s===t?(r.preventDefault(),i.focus()):!r.shiftKey&&s===i&&(r.preventDefault(),t.focus())}getState(){return{surface:this.surface,mode:this.mode,presetMode:this.presetMode,nest:this.nest,cursorText:this.cursorTextarea?.value??this.cursorText,lineCursorIdx:this.lineCursorIdx}}enhanceTextarea(r){this.autocomplete?.detach(),this.autocomplete=new Pt(this.app,r),this.autocomplete.attach();let e=this.cb.onImportFile;if(!e)return;let t=async i=>{let s="";for(let p of i){let f=await e(p);f&&(s+=(s?` -`:"")+f)}if(!s)return;let n=r.selectionStart,o=r.selectionEnd,a=r.value.slice(0,n),l=r.value.slice(o),A=(a&&!a.endsWith(` +`:"")+f)}if(!s)return;let n=r.selectionStart,o=r.selectionEnd,a=r.value.slice(0,n),l=r.value.slice(o),d=(a&&!a.endsWith(` `)?` `:"")+s+` -`;r.value=a+A+l,this.cursorText=r.value;let h=a.length+A.length;r.setSelectionRange(h,h),r.dispatchEvent(new Event("input")),r.focus()};r.addEventListener("paste",i=>{let s=i.clipboardData;if(!s)return;let n=[];for(let o of Array.from(s.files??[]))n.push(o);if(n.length===0){for(let o of Array.from(s.items??[]))if(o.kind==="file"){let a=o.getAsFile();a&&n.push(a)}}n.length!==0&&(i.preventDefault(),i.stopPropagation(),t(n))}),r.addEventListener("dragover",i=>{if(!(!i.dataTransfer||!Array.from(i.dataTransfer.types).includes("Files"))){i.preventDefault(),i.stopPropagation();try{i.dataTransfer.dropEffect="copy"}catch{}}}),r.addEventListener("drop",i=>{let s=Array.from(i.dataTransfer?.files??[]);s.length!==0&&(i.preventDefault(),i.stopPropagation(),t(s))})}destroy(){this.autocomplete?.detach(),this.autocomplete=null}async commit(){if(this.surface==="edit"){await this.saveEdit();return}this.mode==="line"?await this.commitLine():this.mode==="cursor"?await this.commitCursor():await this.commitPreset()}async saveEdit(){let r=this.cursorTextarea;r&&(await this.cb.onSave(r.value),this.cb.onDone())}isDirty(){return(this.cursorTextarea?.value??this.cursorText)!==this.body}setSurface(r){this.surface!==r&&(this.surface=r,this.render())}moveDivider(r){return this.mode!=="line"?!1:(this.lineCursorIdx=Math.max(1,Math.min(this.lines.length-1,this.lineCursorIdx+r)),this.render(),!0)}async commitLine(){await this.cb.onSplitAtLine(this.lineCursorIdx,this.nest),this.cb.onDone()}async commitCursor(){let r=this.cursorTextarea;if(!r)return;let e=r.selectionStart;if(e<=0||e>=r.value.length){new G.Notice("Move the cursor inside the text \u2014 neither end can be empty.");return}await this.cb.onSplitAtChar(r.value,e,this.nest),this.cb.onDone()}async commitPreset(){let r=$t(this.body,this.presetMode);if(r.length<2){new G.Notice("That delimiter wouldn't split this note.");return}await this.cb.onSplitMany(r,this.nest),this.cb.onDone()}render(){if(this.autocomplete?.detach(),this.autocomplete=null,this.host.empty(),this.host.toggleClass("stashpad-edit-surface",this.surface==="edit"),this.cb.onTitle?.(this.surface==="edit"?"Edit note":"Split note"),this.renderSurfaceToggle(),this.surface==="edit"){this.renderEditSurface();return}this.renderSplitSurface()}renderSurfaceToggle(){let r=this.host.createDiv({cls:"stashpad-split-surface"}),e=G.Platform.isMacOS?"\u2318":"Ctrl+",t=(i,s,n,o)=>{let a=r.createEl("button",{cls:"stashpad-split-surface-btn"});(0,G.setIcon)(a.createSpan({cls:"stashpad-split-btn-icon"}),n),a.createSpan({text:i}),a.createSpan({cls:"stashpad-split-kbd-hint",text:`${e}${o}`}),a.toggleClass("is-active",this.surface===s),a.onmousedown=l=>l.preventDefault(),a.onclick=()=>this.setSurface(s)};t("Edit","edit","pencil-line","E"),t("Split","split","split","S")}renderPopOut(r){if(!this.cb.popOut)return;let e=r.createEl("button",{cls:"stashpad-split-popout-btn"});(0,G.setIcon)(e.createSpan({cls:"stashpad-split-popout-icon"}),"maximize-2"),e.createSpan({text:G.Platform.isMobile?"Pop-out":"Open in a tab"}),e.setAttr("aria-label","Open in a full tab"),e.onmousedown=t=>t.preventDefault(),e.onclick=()=>this.cb.popOut(this.getState())}renderOpenExternal(r){if(!this.cb.onOpenExternal)return;let e=r.createEl("button",{cls:"stashpad-split-popout-btn"});(0,G.setIcon)(e.createSpan({cls:"stashpad-split-popout-icon"}),"pencil"),e.createSpan({text:G.Platform.isMobile?"Advanced":"Obsidian editor"}),e.setAttr("aria-label","Open in a full Obsidian editor tab"),e.onmousedown=t=>t.preventDefault(),e.onclick=()=>{this.cb.onOpenExternal(),this.cb.close()}}renderEditSurface(){this.renderEditorSections();let r=this.host.createDiv({cls:"stashpad-split-edit-tools"}),e=r.createSpan({cls:"stashpad-split-count"}),t=()=>{let c=this.cursorTextarea?.value??"",A=(c.trim().match(/\S+/g)||[]).length;e.setText(`${A} word${A===1?"":"s"} \xB7 ${c.length} char${c.length===1?"":"s"}`)},i=r.createEl("button",{cls:"stashpad-split-case-btn"});(0,G.setIcon)(i.createSpan({cls:"stashpad-split-btn-icon"}),"case-sensitive"),i.createSpan({text:"Case"}),i.setAttr("aria-label","Cycle case of the selection (or all text): lower \u2192 UPPER \u2192 Title \u2192 Sentence"),i.onmousedown=c=>c.preventDefault(),i.onclick=()=>this.cycleCase(t),this.cursorTextarea?.addEventListener("input",t),t();let s=this.host.createDiv({cls:"stashpad-split-help"});G.Platform.isPhone||s.setText("Edit the note, then Save. \xB7 \u2318/Ctrl+Enter or Save to write \xB7 \u2318/Ctrl+S \u2192 Split \xB7 Esc discards.");let n=this.host.createDiv({cls:"stashpad-split-actions"}),o=n.createEl("button",{cls:"stashpad-split-cancel-btn"});(0,G.setIcon)(o.createSpan({cls:"stashpad-split-btn-icon"}),"x"),o.createSpan({text:"Cancel"}),o.createSpan({cls:"stashpad-split-esc-hint",text:" (Esc)"}),o.onmousedown=c=>c.preventDefault(),o.onclick=()=>this.cb.close(),this.renderPopOut(n),this.renderOpenExternal(n);let l=n.createDiv({cls:"stashpad-split-actions-right"}).createEl("button",{cls:"stashpad-split-confirm-btn mod-cta"});(0,G.setIcon)(l.createSpan({cls:"stashpad-split-btn-icon"}),"save"),l.createSpan({text:"Save"}),l.onmousedown=c=>c.preventDefault(),l.onclick=()=>void this.commit()}cycleCase(r){let e=this.cursorTextarea;if(!e)return;let t=e.selectionStart!==e.selectionEnd,i=t?e.selectionStart:0,s=t?e.selectionEnd:e.value.length,n=e.value.slice(i,s),o=["lower","upper","title","sentence"],a=o[this.caseCycleIndex%o.length];this.caseCycleIndex+=1;let l=id(n,a);e.value=e.value.slice(0,i)+l+e.value.slice(s),e.setSelectionRange(i,i+l.length),this.cursorText=e.value,e.dispatchEvent(new Event("input")),r(),e.focus()}renderSplitSurface(){let r=this.host.createDiv({cls:"stashpad-split-modes"}),e=(p,f,u,g,I=!1)=>{let m=r.createEl("button",{cls:"stashpad-split-mode-btn"});(0,G.setIcon)(m.createSpan({cls:"stashpad-split-btn-icon"}),g),m.createSpan({text:p}),m.toggleClass("is-active",f),m.disabled=I,m.onmousedown=C=>C.preventDefault(),I||(m.onclick=u)};this.lines.length>=2&&e("Line",this.mode==="line",()=>{this.mode="line",this.render()},"separator-horizontal"),e("Cursor",this.mode==="cursor",()=>{this.mode="cursor",this.render()},"text-cursor-input");let t={lines:"list",paragraphs:"pilcrow",headings:"heading"};["lines","paragraphs","headings"].forEach(p=>{let f=$t(this.body,p).length,u=f<2,g=p==="paragraphs"?"Blank line(s)":hi[p],I=u?g:`${g} (${f})`;e(I,this.mode==="preset"&&this.presetMode===p,()=>{this.mode="preset",this.presetMode=p,this.render()},t[p],u)}),this.mode==="line"?this.renderLineMode():this.mode==="cursor"?this.renderEditorSections():this.renderPresetMode();let i=this.host.createDiv({cls:"stashpad-split-help"}),s=()=>{if(G.Platform.isPhone){i.setCssStyles({display:"none"});return}i.setCssStyles({display:""});let p=this.nest?"New part nested under the original.":"New part added as a sibling.",f=this.nest?"New parts nested under the original.":"New parts added as siblings.",u="\u2318/Ctrl+Enter or Split to confirm";i.setText(this.mode==="line"?`\u2191/\u2193 or click to pick the split line \xB7 ${u} \xB7 ${p}`:this.mode==="cursor"?`Click or arrow to position the cursor \xB7 ${u} \xB7 ${p}`:`Preview of the resulting parts \xB7 ${u} \xB7 ${f}`)};s();let n=this.host.createDiv({cls:"stashpad-split-actions"}),o=n.createEl("button",{cls:"stashpad-split-cancel-btn"});(0,G.setIcon)(o.createSpan({cls:"stashpad-split-btn-icon"}),"x"),o.createSpan({text:"Cancel"}),o.createSpan({cls:"stashpad-split-esc-hint",text:" (Esc)"}),o.onmousedown=p=>p.preventDefault(),o.onclick=()=>this.cb.close(),this.renderPopOut(n),this.renderOpenExternal(n);let a=n.createDiv({cls:"stashpad-split-actions-right"}),l=a.createEl("label",{cls:"stashpad-split-nest"}),c=l.createEl("input",{type:"checkbox"});c.checked=this.nest,l.createSpan({text:"Nest under original"}),c.onchange=()=>{this.nest=c.checked,s()};let A=this.mode==="preset"?$t(this.body,this.presetMode).length:0,h=a.createEl("button",{cls:"stashpad-split-confirm-btn mod-cta"});(0,G.setIcon)(h.createSpan({cls:"stashpad-split-btn-icon"}),"split"),h.createSpan({text:this.mode==="preset"&&A>=2?`Split into ${A}`:"Split"}),h.onmousedown=p=>p.preventDefault(),h.onclick=()=>this.commit()}renderPresetMode(){let r=$t(this.body,this.presetMode),e=this.host.createDiv({cls:"stashpad-split-preset-list"});if(r.length<2){e.createDiv({cls:"stashpad-split-empty",text:"This delimiter wouldn't split the note into more than one part."});return}r.forEach((t,i)=>{let s=e.createDiv({cls:"stashpad-split-part-card"}),n=s.createDiv({cls:"stashpad-split-part-num"});n.createSpan({cls:"stashpad-split-part-title",text:`Part ${i+1}`}),n.appendChild(this.makeCopyButton(()=>t,`Copy part ${i+1}`)),s.createDiv({cls:"stashpad-split-part-body",text:t})})}renderLineMode(){let r=this.host.createDiv({cls:"stashpad-split-list"}),e=null;for(let t=0;t<this.lines.length;t++){t===this.lineCursorIdx&&(e=r.createDiv({cls:"stashpad-split-divider",text:"\u2500\u2500 split here \u2500\u2500"}));let i=r.createDiv({cls:"stashpad-split-line"});i.createSpan({cls:"stashpad-split-lineno",text:String(t+1)}),i.createSpan({cls:"stashpad-split-text",text:this.lines[t]||" "}),i.onclick=()=>{let s=Math.max(1,Math.min(this.lines.length-1,t+1));s!==this.lineCursorIdx&&(this.lineCursorIdx=s,this.render())}}e&&window.requestAnimationFrame(()=>e.scrollIntoView({block:"center"}))}buildSplitSection(r,e,t){let i=r.createDiv({cls:`stashpad-split-section stashpad-split-${e}`}),s=i.createEl("button",{cls:"stashpad-split-section-header"});s.setAttr("type","button");let n=s.createSpan({cls:"stashpad-split-chevron"});(0,G.setIcon)(n,"chevron-down"),s.createSpan({cls:"stashpad-split-section-title",text:t});let o=i.createDiv({cls:"stashpad-split-section-body"}),a=()=>{i.toggleClass("is-collapsed",this.collapsed[e]),s.setAttr("aria-expanded",String(!this.collapsed[e]))};return s.onmousedown=l=>l.preventDefault(),s.onclick=l=>{l.preventDefault(),this.collapsed[e]=!this.collapsed[e],a()},a(),{section:i,body:o}}makeCopyButton(r,e,t="stashpad-split-copy-btn"){let i=createEl("button",{cls:t});return(0,G.setIcon)(i,"copy"),i.setAttr("aria-label",e),i.onmousedown=s=>s.preventDefault(),i.onclick=s=>{s.preventDefault(),s.stopPropagation();let n=r();navigator.clipboard?.writeText(n).then(()=>new G.Notice("Copied to clipboard."),()=>new G.Notice("Couldn't access the clipboard."))},i}renderEditorSections(){if(G.Platform.isMobile){this.renderEditorTabbed();return}let r=this.buildSplitSection(this.host,"orig","Original \u2014 will be replaced");r.body.createDiv({cls:"stashpad-split-panel-body",text:this.body}),r.section.appendChild(this.makeCopyButton(()=>this.body,"Copy the original text","stashpad-split-copy-btn stashpad-split-section-copy"));let e=this.buildSplitSection(this.host,"changes","Changes"),t=e.body.createDiv({cls:"stashpad-split-panel-body stashpad-split-diff-body"}),s=this.buildSplitSection(this.host,"edit",this.surface==="edit"?"Your edit":"Your edit \u2014 the split uses this").body.createEl("textarea",{cls:"stashpad-split-cursor-ta"});s.value=this.cursorText,s.readOnly=!1,this.cursorTextarea=s,this.enhanceTextarea(s);let n=()=>{t.empty();for(let h of Lr(this.body,s.value)){let p=h.t==="ins"?"stashpad-diff-ins":h.t==="del"?"stashpad-diff-del":"stashpad-diff-eq";t.createSpan({cls:p,text:h.s})}},o=()=>{let h=s.value!==this.body;r.section.setCssStyles({display:h?"":"none"}),e.section.setCssStyles({display:h?"":"none"}),h&&n()},a=parseFloat(getComputedStyle(s).lineHeight)||22,l=this.surface==="edit"?G.Platform.isMobile?10:40:G.Platform.isMobile?3:12,c=2,A=()=>{s.setCssStyles({height:"auto"});let h=Math.min(a*l+16,Math.round(window.innerHeight*.5)),p=Math.min(s.scrollHeight,h);s.setCssStyles({height:`${Math.max(p,a*c+16)}px`,overflowY:"auto"})};o(),requestAnimationFrame(()=>{A(),s.focus();let h=this.surface==="edit"?s.value.length:Math.floor(s.value.length/2);s.setSelectionRange(h,h)}),s.addEventListener("input",()=>{this.cursorText=s.value,A(),o()})}renderEditorTabbed(){let r=this.host.createDiv({cls:"stashpad-split-tabs"}),e=r.createDiv({cls:"stashpad-split-tabbar"}),t=r.createDiv({cls:"stashpad-split-tabbody"}),i=t.createDiv({cls:"stashpad-split-tabpanel stashpad-split-tabpanel-edit"}),s=i.createEl("textarea",{cls:"stashpad-split-cursor-ta"});s.value=this.cursorText,s.readOnly=!1,this.cursorTextarea=s,this.enhanceTextarea(s);let n=t.createDiv({cls:"stashpad-split-tabpanel"});n.createDiv({cls:"stashpad-split-tab-copybar"}).appendChild(this.makeCopyButton(()=>this.body,"Copy the original text","stashpad-split-copy-btn stashpad-split-tab-copy")),n.createDiv({cls:"stashpad-split-panel-body",text:this.body});let a=t.createDiv({cls:"stashpad-split-tabpanel"}),l=a.createDiv({cls:"stashpad-split-panel-body stashpad-split-diff-body"}),c=[{key:"edit",label:this.surface==="edit"?"Your edit":"Edit",panel:i},{key:"orig",label:"Original",panel:n},{key:"changes",label:"Changes",panel:a}],A={},h="edit",p=g=>{h=g;for(let I of c)I.panel.toggleClass("is-active",I.key===g),A[I.key]?.toggleClass("is-active",I.key===g);g==="edit"&&s.focus()};for(let g of c){let I=e.createEl("button",{cls:"stashpad-split-tab",text:g.label});I.onmousedown=m=>m.preventDefault(),I.onclick=()=>p(g.key),A[g.key]=I}let f=()=>{l.empty();for(let g of Lr(this.body,s.value)){let I=g.t==="ins"?"stashpad-diff-ins":g.t==="del"?"stashpad-diff-del":"stashpad-diff-eq";l.createSpan({cls:I,text:g.s})}},u=()=>{let g=s.value!==this.body;A.orig.toggleClass("is-hidden",!g),A.changes.toggleClass("is-hidden",!g),g&&f(),!g&&(h==="orig"||h==="changes")&&p("edit")};s.setCssStyles({overflowY:"auto"}),u(),p("edit"),requestAnimationFrame(()=>{s.focus();let g=this.surface==="edit"?s.value.length:Math.floor(s.value.length/2);s.setSelectionRange(g,g)}),s.addEventListener("input",()=>{this.cursorText=s.value,u()})}},Is="stashpad-split-view",ki=class extends G.Modal{constructor(e,t,i,s={}){super(e);this.body=t;this.cbs=i;this.init=s;this.ui=null;this.committing=!1}onOpen(){this.modalEl.addClass("stashpad-split-modal"),this.ui=new hs(this.app,this.contentEl,this.body,this.init,{onSplitAtLine:this.cbs.onSplitAtLine,onSplitAtChar:this.cbs.onSplitAtChar,onSplitMany:this.cbs.onSplitMany,onSave:this.cbs.onSave,onOpenExternal:this.cbs.onOpenExternal,onImportFile:this.cbs.onImportFile,close:()=>this.close(),onDone:()=>{this.committing=!0,this.close()},onTitle:e=>this.titleEl.setText(e),popOut:this.cbs.popOut?e=>{this.committing=!0,this.close(),this.cbs.popOut(e)}:void 0}),this.scope.register(["Mod"],"Enter",e=>{e.preventDefault(),this.ui?.commit()}),this.scope.register([],"ArrowUp",e=>{this.ui?.moveDivider(-1)&&e.preventDefault()}),this.scope.register([],"ArrowDown",e=>{this.ui?.moveDivider(1)&&e.preventDefault()}),this.scope.register(["Mod"],"e",e=>{e.preventDefault(),this.ui?.setSurface("edit")}),this.scope.register(["Mod"],"s",e=>{e.preventDefault(),this.ui?.setSurface("split")}),this.scope.register(["Mod","Shift"],"e",e=>{e.preventDefault(),this.cbs.onOpenExternal&&(this.cbs.onOpenExternal(),this.close())})}close(){if(this.committing||!this.ui?.isDirty()){super.close();return}new j(this.app,"Discard unsaved edits?","You've edited this note but haven't saved. Close and discard your changes?","Discard",e=>{e&&(this.committing=!0,this.close())},"Keep editing",!0).open()}onClose(){this.ui?.destroy(),this.ui=null,this.contentEl.empty()}},Si=class extends G.ItemView{constructor(e){super(e);this.ui=null;this.ctx=null;this.prevLeaf=null;this.autoCloseTimer=null;this.expiredGrace=null;this.title="Note";this.viewIcon="pencil-line";this.closingIntentionally=!1}getViewType(){return Is}getDisplayText(){return this.title}getIcon(){return this.viewIcon}setHeader(e,t){this.title=e,this.viewIcon=t,this.leaf.updateHeader?.()}setContext(e){this.expiredGrace!=null&&(window.clearTimeout(this.expiredGrace),this.expiredGrace=null),this.ctx=e,this.prevLeaf=e.prevLeaf??null;let t=e.init.surface==="edit";this.setHeader(t?"Edit note":"Split note",t?"pencil-line":"split"),this.renderUI()}async onOpen(){this.contentEl.addClass("stashpad-split-modal","stashpad-split-view"),this.ctx||(this.expiredGrace=window.setTimeout(()=>{this.expiredGrace=null,this.ctx||this.renderExpired()},800))}renderUI(){let e=this.contentEl;e.empty(),e.addClass("stashpad-split-modal","stashpad-split-view"),this.ctx&&(this.ui=new hs(this.app,e,this.ctx.body,this.ctx.init,{onSplitAtLine:this.ctx.cbs.onSplitAtLine,onSplitAtChar:this.ctx.cbs.onSplitAtChar,onSplitMany:this.ctx.cbs.onSplitMany,onSave:this.ctx.cbs.onSave,onOpenExternal:this.ctx.cbs.onOpenExternal,onImportFile:this.ctx.cbs.onImportFile,close:()=>this.guardedDetach(),onDone:()=>this.startClosePanel("\u2713 Done.",null,!0),onTitle:t=>this.setHeader(t,t.startsWith("Edit")?"pencil-line":"split")}),this.registerDomEvent(e,"keydown",t=>{let i=t.metaKey||t.ctrlKey;i&&t.shiftKey&&(t.key==="e"||t.key==="E")?(t.preventDefault(),this.ctx?.cbs.onOpenExternal?.(),this.guardedDetach()):i&&t.key==="Enter"?(t.preventDefault(),this.ui?.commit()):i&&!t.shiftKey&&(t.key==="e"||t.key==="E")?(t.preventDefault(),this.ui?.setSurface("edit")):i&&(t.key==="s"||t.key==="S")?(t.preventDefault(),this.ui?.setSurface("split")):t.key==="ArrowUp"?this.ui?.moveDivider(-1)&&t.preventDefault():t.key==="ArrowDown"&&this.ui?.moveDivider(1)&&t.preventDefault()}))}renderExpired(){this.setHeader("Expired","clock"),this.startClosePanel("This session has expired.","It can't be restored \u2014 closing this tab\u2026",!1)}startClosePanel(e,t,i){let s=this.contentEl;s.empty(),this.ui?.destroy(),this.ui=null;let n=s.createDiv({cls:"stashpad-split-done"});n.createDiv({cls:"stashpad-split-done-title",text:e}),t&&n.createDiv({cls:"stashpad-split-countdown",text:t});let o=n.createDiv({cls:"stashpad-split-countdown"}),a=n.createDiv({cls:"stashpad-split-done-btns"}),l=a.createEl("button",{cls:"mod-cta",text:"Close now"}),c=a.createEl("button",{text:"Keep tab open"}),A=4,h=()=>o.setText(`Closing this tab in ${A}\u2026`),p=()=>{this.autoCloseTimer!=null&&(window.clearInterval(this.autoCloseTimer),this.autoCloseTimer=null)},f=()=>{p(),i?this.closeAndRefocus():this.leaf.detach()};h(),this.autoCloseTimer=window.setInterval(()=>{A-=1,A<=0?f():h()},1e3),l.onclick=f,c.onclick=()=>{p(),o.setText("Close this tab whenever you're ready."),c.remove(),l.setText("Close tab")}}guardedDetach(){if(!this.ui?.isDirty()){this.closingIntentionally=!0,this.leaf.detach();return}new j(this.app,"Discard unsaved edits?","You've edited this note but haven't saved. Close this tab and discard your changes?","Discard",e=>{e&&(this.closingIntentionally=!0,this.leaf.detach())},"Keep editing",!0).open()}leafStillOpen(e){let t=!1;return this.app.workspace.iterateAllLeaves(i=>{i===e&&(t=!0)}),t}closeAndRefocus(){let e=this.prevLeaf;this.closingIntentionally=!0,this.leaf.detach(),e&&this.leafStillOpen(e)&&this.app.workspace.setActiveLeaf(e,{focus:!0})}async onClose(){!this.closingIntentionally&&this.ui?.isDirty()&&new G.Notice("Closed the Stashpad editor with unsaved changes \u2014 they were discarded. Use Save (\u2318/Ctrl+Enter) next time.",7e3),this.autoCloseTimer!=null&&(window.clearInterval(this.autoCloseTimer),this.autoCloseTimer=null),this.expiredGrace!=null&&(window.clearTimeout(this.expiredGrace),this.expiredGrace=null),this.ui?.destroy(),this.ui=null,this.contentEl.empty()}};bi=class extends G.Modal{constructor(e,t,i,s,n={}){super(e);this.defaultBaseName=t;this.noteCount=i;this.onConfirm=s;this.opts=n;this.delivered=!1}onOpen(){this.contentEl.empty();let e=!!this.opts.locked;this.titleEl.setText(e?"Export encrypted bundle":"Export"),this.modalEl.addClass("stashpad-export-modal"),this.contentEl.createEl("p",{cls:"stashpad-export-desc",text:e?`Re-export this locked bundle (${this.noteCount} note${this.noteCount===1?"":"s"}) as a shareable .stash.`:`Export ${this.noteCount} note${this.noteCount===1?"":"s"}.`});let t=this.contentEl.createDiv({cls:"stashpad-export-field"});t.createEl("label",{cls:"stashpad-export-label",text:"File name"});let i=t.createEl("input",{type:"text"});i.addClass("stashpad-export-name"),i.value=this.defaultBaseName;let s=this.contentEl.createEl("div",{cls:"stashpad-export-preview"}),n="full",o=()=>{},a=this.contentEl.createDiv();sd(a,Y=>{n=Y,o()}),e&&a.setCssStyles({display:"none"});let l="stash",c=this.contentEl.createDiv({cls:"stashpad-export-format"});c.createEl("label",{cls:"stashpad-export-label",text:"Format"});let A=c.createDiv({cls:"stashpad-export-content-seg"}),h=[{id:"stash",label:"Stashpad .stash"},...this.opts.okfEnabled?[{id:"okf",label:"OKF bundle"}]:[],{id:"zip",label:"Plain .zip"}],p=new Map;for(let Y of h){let be=A.createEl("button",{cls:"stashpad-export-content-opt",text:Y.label});be.toggleClass("is-active",Y.id===l),be.onclick=Be=>{Be.preventDefault(),l=Y.id,p.forEach((Pe,Ze)=>Pe.toggleClass("is-active",Ze===l)),o()},p.set(Y.id,be)}let f=this.contentEl.createDiv({cls:"stashpad-okf-formats"}),u=(Y,be)=>{let Be=f.createDiv({cls:"stashpad-okf-fmt"}),Pe=Be.createEl("input",{type:"checkbox"});return Pe.checked=be,Be.createEl("label",{text:Y}),Pe.onchange=()=>o(),Pe},g=u(".zip \u2014 OKF bundle (portable)",!0),I=u(".tar.gz \u2014 OKF bundle (tarball)",!1),m=f.createDiv({cls:"stashpad-export-pw-hint is-error"});m.setText("Pick at least one OKF format."),m.setCssStyles({display:"none"}),e&&c.setCssStyles({display:"none"});let C=this.contentEl.createDiv({cls:"stashpad-export-zipwarn"});C.setText("Frontmatter-only / body-only exports save as a plain .zip of the selected markdown (with referenced attachments) \u2014 not a re-importable .stash."),C.setCssStyles({display:"none"});let B=this.contentEl.createDiv({cls:"stashpad-export-encrypt"}),E=B.createDiv({cls:"stashpad-export-toggle"}),y=E.createEl("input",{type:"checkbox"});y.id="stashpad-export-encrypt-cb";let v=E.createEl("label",{text:"Encrypt with a password"});v.htmlFor=y.id;let Q=B.createDiv({cls:"stashpad-export-pw-area"});Q.setCssStyles({display:"none"});let w=[],F=Y=>{let be=Q.createDiv({cls:"stashpad-export-pw-row"}),Be=be.createEl("input",{type:"password"});Be.addClass("stashpad-export-name"),Be.placeholder=Y;let Pe=be.createEl("button",{cls:"stashpad-export-copy"}),Ze=()=>{let kt=Be.value.length===0;Pe.setText(kt?"Paste":"Copy"),Pe.toggleClass("is-paste",kt),Pe.setAttr("aria-label",`${kt?"Paste into":"Copy"} ${Y.toLowerCase()}`)};return Pe.onclick=async kt=>{if(kt.preventDefault(),Be.value.length===0)try{let Ls=(await navigator.clipboard?.readText())?.trim();if(!Ls){new G.Notice("Clipboard is empty.");return}Be.value=Ls,Be.dispatchEvent(new Event("input")),new G.Notice("Pasted from clipboard.")}catch{new G.Notice("Couldn't read the clipboard.")}else navigator.clipboard?.writeText(Be.value).then(()=>new G.Notice("Passphrase copied to clipboard."),()=>new G.Notice("Couldn't access the clipboard."))},Ze(),w.push(Ze),Be},D=F("Password"),H=F("Confirm password"),R=Q.createDiv({cls:"stashpad-export-strength"}),L=R.createDiv({cls:"stashpad-strength-bar"}),x=[0,1,2,3].map(()=>L.createDiv({cls:"stashpad-strength-seg"})),U=R.createEl("span",{cls:"stashpad-strength-label"}),T=Q.createDiv({cls:"stashpad-export-genrow"}),b=T.createEl("button",{cls:"stashpad-export-gen",text:"Generate strong passphrase"}),M=T.createEl("button",{cls:"stashpad-export-show",text:"Show"}),O=Q.createEl("div",{cls:"stashpad-export-pw-hint"}),K=Q.createEl("div",{cls:"stashpad-export-pw-suite"});K.setText("Encryption: AES-256-GCM. Checking key-derivation suite for this device\u2026"),this.opts.kdfProbe?this.opts.kdfProbe().then(Y=>{K.toggleClass("is-weak",!Y),K.setText(Y?"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(()=>{K.setText("Encryption: AES-256-GCM with a password-derived key.")}):K.setText("Encryption: Argon2id + AES-256-GCM (falls back to PBKDF2 if Argon2 can't run here).");let $=this.app.secretStorage,Z=Q.createDiv({cls:"stashpad-export-remember"}),V=Z.createEl("input",{type:"checkbox"});V.checked=!0,V.id="stashpad-export-remember-cb";let J=Z.createEl("label",{text:"Remember in this vault (this device) \u2014 skips the prompt when you re-import here."});J.htmlFor=V.id;let ee=Q.createDiv({cls:"stashpad-export-remember-note"});ee.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."),ee.setCssStyles({display:V.checked?"":"none"}),V.onchange=()=>{ee.setCssStyles({display:V.checked?"":"none"})},$||Z.setCssStyles({display:"none"});let ue=()=>e?"stash":n!=="full"?"zip":l,oe=()=>{let Y=i.value.trim()||this.defaultBaseName;return!e&&n!=="full"?`${Y}-${n}`:ue()==="stash"&&y.checked?`${Y}-encrypted`:Y},ie=()=>{let Y=ue();if(Y==="stash"){s.setText(`Saves as: ${oe()}-<timestamp>.stash`);return}if(Y==="okf"){s.setText(`Saves as: ${oe()}-<timestamp>.zip / .tar.gz (OKF bundle)`);return}s.setText(`Saves as: ${oe()}-<timestamp>.zip (plain archive \u2014 not re-importable)`)};i.oninput=ie;let te=this.contentEl.createDiv({cls:"stashpad-export-footer"}),fe=te.createEl("button",{text:"Cancel"});fe.onclick=()=>this.close();let we=te.createEl("button",{cls:"mod-cta",text:"Export"}),se=()=>{let Y=Fo(D.value);R.style.visibility=D.value?"visible":"hidden",x.forEach((be,Be)=>be.toggleClass("is-on",D.value!==""&&Be<=Y.level)),L.dataset.level=String(Y.level),U.setText(Y.label)},Ae=()=>{let Y=!e&&n!=="full",be=ue();c.setCssStyles({display:!e&&!Y?"":"none"}),f.setCssStyles({display:!e&&!Y&&l==="okf"?"":"none"}),C.setCssStyles({display:Y?"":"none"});let Be=be==="stash";B.setCssStyles({display:Be?"":"none"});let Pe=Be&&y.checked;Q.setCssStyles({display:Pe?"":"none"});let Ze=!0;Pe&&(D.value?D.value!==H.value?(O.setText("Passwords don't match."),O.addClass("is-error"),Ze=!1):(O.setText("\u26A0\uFE0F If you lose this password, the export can't be recovered."),O.removeClass("is-error")):(O.setText("Enter a password to encrypt this export."),O.removeClass("is-error"),Ze=!1));let kt=!e&&!Y&&l==="okf"&&!g.checked&&!I.checked;m.setCssStyles({display:kt?"":"none"}),kt&&(Ze=!1),se(),w.forEach(Ls=>Ls()),we.disabled=!Ze,we.toggleClass("is-disabled",!Ze),ie()},Xe=!1,ai=Y=>{Xe=Y,D.type=H.type=Y?"text":"password",M.setText(Y?"Hide":"Show")};M.onclick=Y=>{Y.preventDefault(),ai(!Xe)},b.onclick=Y=>{Y.preventDefault(),D.value=H.value=Qo(),ai(!1),new G.Notice("Passphrase generated (hidden) \u2014 Show to view, or Copy to save it."),Ae()},y.onchange=Ae,D.oninput=Ae,H.oninput=Ae,o=Ae,Ae();let Us=()=>{let Y=ue(),be=Y==="stash"&&y.checked?D.value:null;this.commit({baseName:oe(),content:n,format:Y,okf:{zip:g.checked,targz:I.checked},password:be,remember:!!be&&V.checked})};we.onclick=Us,this.scope.register([],"Enter",Y=>{Y.preventDefault(),we.disabled||Us()}),requestAnimationFrame(()=>{i.focus(),i.select()})}commit(e){let t=e.baseName.trim()||this.defaultBaseName,i=e.password&&e.password.length?e.password:null;this.delivered=!0,this.close(),this.onConfirm({...e,baseName:t,password:i,remember:!!i&&e.remember})}onClose(){this.contentEl.empty()}},rs=class extends G.Modal{constructor(e,t,i,s){super(e);this.errorMsg=t;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 e=this.contentEl.createEl("input",{type:"password"});e.addClass("stashpad-export-name"),e.placeholder="Password";let t=this.contentEl.createDiv({cls:"stashpad-export-footer"});if(t.createEl("button",{text:"Cancel"}).onclick=()=>this.close(),this.allowLater){let s=t.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=t.createEl("button",{cls:"mod-cta",text:"Decrypt & import"});i.onclick=()=>this.submit(e.value),this.scope.register([],"Enter",s=>{s.preventDefault(),this.submit(e.value)}),requestAnimationFrame(()=>e.focus())}submit(e){e&&this.finish({kind:"password",value:e})}finish(e){this.delivered=!0,this.close(),this.onResult(e)}onClose(){this.delivered||(this.delivered=!0,this.onResult({kind:"cancel"})),this.contentEl.empty()}},Le=class extends G.Modal{constructor(e,t){super(e);this.opts=t;this.succeeded=!1}onOpen(){let{mode:e}=this.opts;this.contentEl.empty(),this.modalEl.addClass("stashpad-export-modal","stashpad-encryption-modal"),this.titleEl.setText(this.opts.title??(e==="setup"?"Set up encryption password":e==="change"?"Change encryption password":"Unlock encryption")),this.contentEl.createDiv({cls:"stashpad-beta-row"}).createEl("span",{cls:"stashpad-beta-badge",text:"BETA"}),this.opts.intro?this.contentEl.createEl("p",{cls:"stashpad-export-desc",text:this.opts.intro}):e==="setup"&&this.contentEl.createEl("p",{cls:"stashpad-export-desc",text:"This single password protects everything you encrypt in this vault. It is stored only on this device. There is NO recovery \u2014 if you lose it, anything you've encrypted is gone for good."});let t=[],i=g=>{let I=this.contentEl.createDiv({cls:"stashpad-export-pw-row stashpad-encryption-row"}),m=I.createEl("input",{type:"password"});m.addClass("stashpad-export-name","stashpad-encryption-field"),m.placeholder=g;let C=I.createEl("button",{cls:"stashpad-export-copy"}),B=()=>{let E=m.value.length===0;C.setText(E?"Paste":"Copy"),C.toggleClass("is-paste",E),C.setAttr("aria-label",`${E?"Paste into":"Copy"} ${g.toLowerCase()}`)};return C.onclick=async E=>{if(E.preventDefault(),m.value.length===0)try{let y=(await navigator.clipboard?.readText())?.trim();if(!y){new G.Notice("Clipboard is empty.");return}m.value=y,m.dispatchEvent(new Event("input")),new G.Notice("Pasted from clipboard.")}catch{new G.Notice("Couldn't read the clipboard.")}else navigator.clipboard?.writeText(m.value).then(()=>new G.Notice("Copied to clipboard."),()=>new G.Notice("Couldn't access the clipboard."))},m.addEventListener("input",B),B(),t.push(B),m},s=null,n=null,o=null;if((e==="unlock"||e==="change")&&(s=i("Current password")),(e==="setup"||e==="change")&&(n=i(e==="change"?"New password":"Password"),o=i("Confirm password")),n){let g=this.contentEl.createDiv({cls:"stashpad-export-strength"}),I=g.createDiv({cls:"stashpad-strength-bar"}),m=[0,1,2,3].map(()=>I.createDiv({cls:"stashpad-strength-seg"})),C=g.createEl("span",{cls:"stashpad-strength-label"}),B=this.contentEl.createDiv({cls:"stashpad-encryption-counter"}),E=()=>{let w=n.value,F=Fo(w);m.forEach((D,H)=>D.toggleClass("is-on",H<F.level)),C.setText(w?F.label:""),B.setText(`${w.length} character${w.length===1?"":"s"}${w.length>0&&w.length<6?" \u2014 use at least 6":""}`),B.toggleClass("is-weak",w.length>0&&w.length<6)};n.addEventListener("input",E),E();let y=this.contentEl.createDiv({cls:"stashpad-export-genrow"});y.createEl("button",{cls:"stashpad-export-gen",text:"Generate strong passphrase"}).onclick=w=>{w.preventDefault();let F=Qo(5);n.value=F,o&&(o.value=F),E(),t.forEach(D=>D()),new G.Notice("Generated \u2014 copy it somewhere safe; there's no recovery."),navigator.clipboard?.writeText(F).catch(()=>{})};let v=y.createEl("button",{cls:"stashpad-export-show",text:"Show"});v.onclick=w=>{w.preventDefault();let F=n.type==="password";n.type=F?"text":"password",o&&(o.type=F?"text":"password"),v.setText(F?"Hide":"Show")};let Q=this.contentEl.createEl("div",{cls:"stashpad-export-pw-suite"});Q.setText("Encryption: AES-256-GCM. Checking key-derivation suite\u2026"),this.opts.kdfProbe?this.opts.kdfProbe().then(w=>{Q.toggleClass("is-weak",!w),Q.setText(w?"Encryption: Argon2id + AES-256-GCM \u2014 the strongest suite (used on this device).":"\u26A0\uFE0F Argon2id can't run here, so this will use the weaker PBKDF2 (600k) + AES-256-GCM fallback.")}).catch(()=>Q.setText("Encryption: AES-256-GCM with a password-derived key.")):Q.setText("Encryption: Argon2id + AES-256-GCM (PBKDF2 fallback if Argon2 can't run here).")}let a=null,l=this.app.secretStorage;if(this.opts.offerKeychain&&l){let g=this.contentEl.createDiv({cls:"stashpad-export-remember"});a=g.createEl("input",{type:"checkbox"}),a.id="stashpad-enc-remember",a.checked=!0;let I=g.createEl("label",{text:"Remember on this device (keychain) \u2014 auto-unlock here without re-typing."});I.htmlFor=a.id;let m=this.contentEl.createDiv({cls:"stashpad-export-remember-note"});m.setText("Stored only in this device's keychain \u2014 doesn't sync to your other devices. Anyone with access to this unlocked device + keychain could decrypt."),m.setCssStyles({display:a.checked?"":"none"}),a.onchange=()=>{m.setCssStyles({display:a.checked?"":"none"})}}let c=this.contentEl.createEl("div",{cls:"stashpad-export-error"});c.setCssStyles({display:"none"});let A=g=>{c.setText(g),c.setCssStyles({display:""})},h=this.contentEl.createDiv({cls:"stashpad-export-footer"});h.createEl("button",{text:"Cancel"}).onclick=()=>this.close();let p=h.createEl("button",{cls:"mod-cta",text:e==="setup"?"Set up":e==="change"?"Change":"Unlock"}),f=!1,u=async()=>{if(f)return;let g=s?.value??void 0,I=n?.value??void 0;if((e==="unlock"||e==="change")&&!g){A("Enter your current password.");return}if(e==="setup"||e==="change"){if(!I){A("Enter a password.");return}if(I.length<6){A("Use at least 6 characters.");return}if(I!==o?.value){A("Passwords don't match.");return}}f=!0,p.disabled=!0,c.setCssStyles({display:"none"});let m=p.textContent;p.setText("Working\u2026");try{let C=await this.opts.onSubmit({current:g,next:I,remember:!!a?.checked});if(C){A(C),f=!1,p.disabled=!1,p.setText(m??"OK");return}this.succeeded=!0,this.close()}catch(C){A(`Failed: ${C.message}`),f=!1,p.disabled=!1,p.setText(m??"OK")}};p.onclick=()=>void u(),this.scope.register([],"Enter",g=>{g.preventDefault(),u()}),requestAnimationFrame(()=>(s??n)?.focus())}onClose(){this.contentEl.empty(),this.succeeded||this.opts.onCancel?.()}},vi=class extends G.Modal{constructor(e,t){super(e);this.opts=t}onOpen(){this.contentEl.empty(),this.modalEl.addClass("stashpad-export-modal","stashpad-encryption-modal"),this.titleEl.setText(this.opts.title),this.contentEl.createEl("p",{cls:"stashpad-export-desc",text:this.opts.body});let e=null;this.opts.requirePassword&&(this.contentEl.createEl("p",{cls:"stashpad-export-desc"}).setText("Enter your encryption password:"),e=this.contentEl.createEl("input",{type:"password"}),e.addClass("stashpad-export-name","stashpad-encryption-field"),e.placeholder="Password"),this.contentEl.createEl("p",{cls:"stashpad-export-desc"}).setText(`Type "${this.opts.phrase}" to confirm.`);let t=this.contentEl.createEl("input",{type:"text"});t.addClass("stashpad-export-name","stashpad-encryption-field"),t.placeholder=this.opts.phrase;let i=this.contentEl.createEl("div",{cls:"stashpad-export-error"});i.setCssStyles({display:"none"});let s=this.contentEl.createDiv({cls:"stashpad-export-footer"});s.createEl("button",{text:"Cancel"}).onclick=()=>this.close();let n=s.createEl("button",{cls:"mod-cta mod-warning",text:this.opts.confirmText}),o=()=>t.value.trim().toLowerCase()===this.opts.phrase.trim().toLowerCase(),a=()=>{n.disabled=!o()||!!this.opts.requirePassword&&!e?.value};t.addEventListener("input",a),e?.addEventListener("input",a),a();let l=!1,c=async()=>{if(!(l||!o())){if(this.opts.requirePassword&&(l=!0,n.disabled=!0,i.setCssStyles({display:"none"}),!await this.opts.requirePassword(e.value))){i.setText("Wrong password."),i.setCssStyles({display:""}),l=!1,a();return}this.close(),await this.opts.onConfirm()}};n.onclick=()=>void c(),this.scope.register([],"Enter",A=>{A.preventDefault(),c()}),requestAnimationFrame(()=>(e??t).focus())}onClose(){this.contentEl.empty()}},ps=class extends G.Modal{constructor(e,t){super(e);this.onSubmit=t}onOpen(){this.contentEl.empty(),this.modalEl.addClass("stashpad-export-modal"),this.titleEl.setText("Open Stashpad link"),this.contentEl.createEl("p",{cls:"stashpad-export-desc",text:"Paste one or more obsidian://stashpad links (one per line) to jump to the notes they point to. Multiple links each open in their own tab."});let e=this.contentEl.createDiv({cls:"stashpad-open-link-row"}),t=e.createEl("button",{cls:"stashpad-open-link-paste"});(0,G.setIcon)(t.createSpan({cls:"stashpad-open-link-paste-icon"}),"clipboard-paste"),t.createSpan({text:"Paste"}),t.title="Paste from clipboard";let i=e.createEl("textarea",{attr:{rows:"3"}});i.addClass("stashpad-export-name"),i.placeholder="obsidian://stashpad?folder=\u2026¬e=\u2026",t.onclick=async()=>{try{let l=(await navigator.clipboard?.readText?.())?.trim();l&&(i.value=l,s.hide()),i.focus()}catch{new G.Notice("Couldn't read the clipboard \u2014 paste manually.")}},i.addEventListener("input",()=>s.hide());let s=this.contentEl.createEl("div",{cls:"stashpad-open-link-autohint"});(0,G.setIcon)(s.createSpan({cls:"stashpad-open-link-autohint-icon"}),"clipboard-check"),s.createSpan({text:"Link automatically pasted from your clipboard."}),s.hide();let n=this.contentEl.createDiv({cls:"stashpad-export-footer"});n.createEl("button",{text:"Cancel"}).onclick=()=>this.close();let o=n.createEl("button",{cls:"mod-cta",text:"Open"}),a=()=>{let l=i.value.trim();l&&(this.close(),this.onSubmit(l))};o.onclick=()=>a(),this.scope.register([],"Enter",l=>{l.preventDefault(),a()}),requestAnimationFrame(()=>{i.focus(),navigator.clipboard?.readText?.().then(l=>{!i.value&&l&&/obsidian:\/\/stashpad\?/i.test(l.trim())&&(i.value=l.trim(),i.select(),s.show())}).catch(()=>{})})}onClose(){this.contentEl.empty()}},fn=class extends G.Modal{constructor(e,t,i){super(e);this.onResult=i;this.delivered=!1;this.touched=!1;this.value=t&&/^#[0-9a-f]{6}$/i.test(t)?t:"#888888"}onOpen(){this.contentEl.empty(),this.titleEl.setText("Custom color"),this.modalEl.addClass("stashpad-custom-color-modal");let e=this.contentEl.createDiv({cls:"stashpad-custom-color-row"}),t=e.createDiv({cls:"stashpad-custom-color-preview"});t.style.background=this.value;let i=e.createEl("input",{type:"color"});i.value=this.value,i.addClass("stashpad-custom-color-wheel"),t.onclick=()=>i.click();let s=e.createEl("input",{type:"text"});s.addClass("stashpad-custom-color-hex"),s.placeholder="#RRGGBB",s.value=this.value,s.maxLength=7;let n=A=>{let h=A.startsWith("#")?A:"#"+A;/^#[0-9a-f]{6}$/i.test(h)&&(this.touched=!0,this.value=h,t.style.background=h,i.value=h,s.value!==h&&(s.value=h))};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 l=o.createEl("button",{cls:"mod-cta",text:"Save"});l.title="Apply this color to the selection (without adding to your palette).",l.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",A=>{A.preventDefault(),this.commit({addToPalette:!1})}),this.scope.register(["Mod"],"Enter",A=>{A.preventDefault(),this.commit({addToPalette:!0})}),requestAnimationFrame(()=>s.focus())}commit(e){this.delivered=!0,this.close(),this.onResult(this.value,e)}onClose(){!this.delivered&&this.touched&&(this.delivered=!0,this.onResult(this.value,{addToPalette:!1})),this.contentEl.empty()}},As=class As extends G.Modal{constructor(e,t,i,s,n){super(e);this.currentColor=t;this.customPalette=i;this.onPick=s;this.onDeleteCustom=n;this.focusIdx=-1;this.scopeBound=!1;this.items=[]}onOpen(){this.contentEl.empty(),this.titleEl.setText("Pick a color"),this.modalEl.addClass("stashpad-color-modal");let e=this.contentEl.createDiv({cls:"stashpad-color-grid"});this.items=[];let t=e.createDiv({cls:"stashpad-color-tile stashpad-color-none"});t.title="No color",t.onclick=()=>this.activate(0),this.items.push({kind:"none",color:null,el:t});let i=[...As.DEFAULT_PALETTE,...this.customPalette];for(let a of i){let l=e.createDiv({cls:"stashpad-color-tile"});l.style.background=a,l.title=a;let c=!As.DEFAULT_PALETTE.some(h=>h.toLowerCase()===a.toLowerCase()),A=this.items.length;if(l.onclick=()=>this.activate(A),c&&this.onDeleteCustom){let h=l.createSpan({cls:"stashpad-color-tile-del",text:"\xD7"});h.title="Remove from palette",h.onclick=p=>{p.stopPropagation(),this.handleDelete(a)}}this.items.push({kind:c?"custom":"preset",color:a,el:l})}let s=e.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.scopeBound||(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)}),this.scopeBound=!0),requestAnimationFrame(()=>this.modalEl.focus())}activate(e){if(e<0||e>=this.items.length)return;this.focusIdx=e,this.refreshActive();let t=this.items[e];if(t.kind==="add"){this.close(),new fn(this.app,this.currentColor,(i,s)=>{this.onPick(i,s)}).open();return}this.close(),this.onPick(t.color,{addToPalette:!1})}columns(){if(!this.items.length)return 1;let e=this.items[0].el.parentElement;if(!e)return 1;let t=e.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(e){if(this.onDeleteCustom)try{let t=await this.onDeleteCustom(e);this.customPalette=Array.isArray(t)?t:this.customPalette.filter(i=>i.toLowerCase()!==e.toLowerCase()),this.onOpen()}catch(t){console.warn("Stashpad: palette delete failed",t)}}moveFocus(e){if(!this.items.length)return;let t=Math.max(0,Math.min(this.items.length-1,this.focusIdx+e));this.focusIdx=t,this.refreshActive()}refreshActive(){for(let e=0;e<this.items.length;e++)this.items[e].el.toggleClass("is-active",e===this.focusIdx)}onClose(){this.contentEl.empty()}};As.DEFAULT_PALETTE=["#E07A78","#E08A47","#E0A744","#B0CC6E","#6BC07A","#5BA9CE","#9B82C9","#C57AB5","#D75AA8"];jt=As,j=class extends G.Modal{constructor(e,t,i,s,n,o="Cancel",a=!1){super(e);this.titleText=t;this.message=i;this.confirmText=s;this.onChoose=n;this.cancelText=o;this.dangerous=a;this.didChoose=!1}onOpen(){this.modalEl?.addClass("stashpad-compact-modal"),this.contentEl.empty(),this.titleEl.setText(this.titleText);let e=this.contentEl.createDiv({cls:"stashpad-confirm-body"});for(let n of this.message.split(` -`))e.createDiv({cls:"stashpad-confirm-line",text:n});let t=this.contentEl.createDiv({cls:"stashpad-modal-btns"}),i=t.createEl("button",{text:this.cancelText});i.onclick=()=>{this.didChoose=!0,this.close(),this.onChoose(!1)};let s=t.createEl("button",{cls:"mod-cta",text:this.confirmText});s.onclick=()=>{this.didChoose=!0,this.close(),this.onChoose(!0)},requestAnimationFrame(()=>(this.dangerous?i:s).focus())}onClose(){this.contentEl.empty(),this.didChoose||(this.didChoose=!0,this.onChoose(!1))}},gs=class extends G.Modal{constructor(e,t,i,s={}){super(e);this.levels=t;this.onPick=i;this.opts=s}onOpen(){this.modalEl?.addClass("stashpad-compact-modal"),this.modalEl?.addClass("stashpad-breadcrumb-modal"),this.contentEl.empty(),this.titleEl.setText("Jump to level");let e=this.contentEl.createDiv({cls:"stashpad-bc-levels"});for(let t of this.levels){let i=e.createDiv({cls:"stashpad-bc-level-row"});if(t.isCurrent&&i.addClass("is-current"),i.createSpan({cls:"stashpad-bc-level-num",text:String(t.level)}),i.createSpan({cls:"stashpad-bc-level-label",text:t.label}),!t.isCurrent){i.setAttribute("role","button"),i.setAttribute("tabindex","0");let s=()=>{this.close(),this.onPick(t.id)};i.onclick=s,i.onkeydown=n=>{(n.key==="Enter"||n.key===" ")&&(n.preventDefault(),s())}}this.opts.onContext&&(i.oncontextmenu=s=>{s.preventDefault(),this.opts.onContext(t.id,s,i,()=>this.close())},this.opts.attachLongPress?.(i,()=>this.opts.onContext(t.id,null,i,()=>this.close())))}}onClose(){this.contentEl.empty()}};ze=class extends G.Modal{constructor(e,t,i,s={}){super(e);this.current=t;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(this.opts.title??"Set due date");let e=null;if(this.current){let Q=Date.parse(this.current);Number.isNaN(Q)||(e=new Date(Q))}let t=this.contentEl.createDiv({cls:"stashpad-due-picker"}),i=t.createDiv({cls:"stashpad-due-fields"}),s=i.createDiv({cls:"stashpad-due-field"}),n=s.createSpan({cls:"stashpad-due-field-icon"});(0,G.setIcon)(n,"calendar");let o=s.createEl("input",{type:"date",cls:"stashpad-due-date"}),a=s.createSpan({cls:"stashpad-due-clear",attr:{"aria-label":"Clear date"}});(0,G.setIcon)(a,"x"),a.onclick=()=>{o.value="",o.focus()};let l=i.createDiv({cls:"stashpad-due-field"}),c=l.createSpan({cls:"stashpad-due-field-icon"});(0,G.setIcon)(c,"clock");let A=l.createEl("input",{type:"time",cls:"stashpad-due-time"}),h=l.createSpan({cls:"stashpad-due-clear",attr:{"aria-label":"Clear time"}});(0,G.setIcon)(h,"x"),h.onclick=()=>{A.value="",A.focus()},n.onclick=()=>{try{o.showPicker?.()}catch{}},c.onclick=()=>this.openTimeNumpad(c,A),e&&(o.value=this.toDateValue(e),A.value=this.toTimeValue(e));let p=(this.opts.quickAdjusts??Gr).map(Q=>({raw:Q,min:Or(Q)})).filter(Q=>Q.min!=null);if(p.length>0){let Q=1,w=t.createDiv({cls:"stashpad-due-quickadjust"}),F=w.createEl("button",{cls:"stashpad-due-adjust-flip",attr:{type:"button"}}),D=()=>{F.setText(Q>0?"+":"\u2212"),F.toggleClass("is-minus",Q<0),F.title=Q>0?"Adding time (click to subtract)":"Subtracting time (click to add)"};D(),F.onclick=()=>{Q=-Q,D()};let H=R=>{let L=new Date,x,U,T;if(o.value){let[K,$,Z]=o.value.split("-").map(V=>parseInt(V,10));x=K,U=$-1,T=Z}else x=L.getFullYear(),U=L.getMonth(),T=L.getDate();let b,M;if(A.value){let[K,$]=A.value.split(":").map(Z=>parseInt(Z,10));b=K,M=$}else b=L.getHours(),M=L.getMinutes();let O=new Date(x,U,T,b,M,0,0);O.setMinutes(O.getMinutes()+Q*R),o.value=this.toDateValue(O),A.value=this.toTimeValue(O)};for(let R of p){let L=w.createEl("button",{cls:"stashpad-due-adjust-btn",text:R.raw,attr:{type:"button"}});L.onclick=()=>H(R.min)}}this.opts.hideAssignees||this.renderAssignSection(t);let f=t.createDiv({cls:"stashpad-due-grid"}),u=(Q,w)=>{let F=f.createEl("button",{cls:"stashpad-due-btn stashpad-due-preset",text:Q});F.onclick=()=>{let D=w();o.value=this.toDateValue(D),A.value||(A.value=this.toTimeValue(D))}},g=Q=>(Q.setHours(9,0,0,0),Q);u("Today",()=>g(this.startOfTodayLocal())),u("Tomorrow",()=>{let Q=this.startOfTodayLocal();return Q.setDate(Q.getDate()+1),g(Q)}),u("Next week",()=>{let Q=this.startOfTodayLocal();return Q.setDate(Q.getDate()+7),g(Q)});let I=f.createEl("button",{cls:"stashpad-due-btn",text:"Clear"});I.onclick=()=>{o.value="",A.value="",o.focus()};let m=null,C=null,B=null;if(this.opts.showRecurrence){let Q=t.createEl("details",{cls:"stashpad-due-recur"});(this.opts.currentRepeat||this.opts.currentAutoDoneAfter||this.opts.currentRemindEvery)&&(Q.open=!0),Q.createEl("summary",{text:"\u{1F501} Repeat & reminders"});let w=(F,D,H)=>{let R=Q.createDiv({cls:"stashpad-due-recur-row"});R.createEl("label",{text:F});let L=R.createEl("input",{type:"text",attr:{placeholder:D}});return H&&(L.value=H),L};m=w("Repeat",'e.g. "every weekday", "every 30 days when done"',this.opts.currentRepeat),C=w("Auto-complete after",'e.g. "1d" \u2014 mark done once this overdue',this.opts.currentAutoDoneAfter),B=w("Remind every",'e.g. "2h" \u2014 re-notify until done',this.opts.currentRemindEvery)}let E=()=>this.opts.showRecurrence?{repeat:m.value.trim(),autoDoneAfter:C.value.trim(),remindEvery:B.value.trim()}:{},y=f.createEl("button",{cls:"stashpad-due-btn",text:"Cancel"});y.onclick=()=>{this.didChoose=!0,this.close()};let v=f.createEl("button",{cls:"stashpad-due-btn mod-cta",text:"Set"});v.onclick=()=>{if(!o.value){this.didChoose=!0,this.close(),this.onPick({iso:null,assignees:this.assignees,...E()});return}let[Q,w,F]=o.value.split("-").map(L=>parseInt(L,10)),D=9,H=0;if(A.value){let[L,x]=A.value.split(":").map(U=>parseInt(U,10));D=L,H=x}let R=new Date(Q,w-1,F,D,H,0,0);this.didChoose=!0,this.close(),this.onPick({iso:R.toISOString(),assignees:this.assignees,...E()})},requestAnimationFrame(()=>o.focus())}onClose(){this.tinyClosePopover?.(),this.contentEl.empty(),this.didChoose}renderAssignSection(e){Kr(e,{knownAuthors:this.opts.knownAuthors??[],initial:this.assignees,onChange:t=>{this.assignees=t}})}openTimeNumpad(e,t){this.tinyClosePopover?.();let i=e.ownerDocument??document,s=i.defaultView??window,n=9,o=0;if(t.value){let[I,m]=t.value.split(":").map(C=>parseInt(C,10));Number.isFinite(I)&&(n=I),Number.isFinite(m)&&(o=m)}else{let I=new Date;n=I.getHours(),o=I.getMinutes()}let a=n>=12?"pm":"am",l=n===0?12:n>12?n-12:n,A=(this.modalEl??i.body).createDiv({cls:"stashpad-when-popover stashpad-due-time-pop"});A.setCssStyles({position:"fixed",zIndex:"9999"});let h=null,p=()=>{A.remove(),i.removeEventListener("mousedown",f,!0),i.removeEventListener("keydown",u,!0),this.tinyClosePopover===p&&(this.tinyClosePopover=null)},f=I=>{!A.contains(I.target)&&I.target!==e&&!e.contains(I.target)&&p()},u=I=>{I.key==="Escape"?(I.preventDefault(),I.stopPropagation(),p()):I.key==="Enter"&&h&&(I.preventDefault(),I.stopPropagation(),h())};this.tinyClosePopover=p,$s(A,{seedH:l,seedM:o,seedPeriod:a,close:p,setOnEnter:I=>{h=I},onFinalize:I=>{t.value=`${String(I.hours24).padStart(2,"0")}:${String(I.minutes).padStart(2,"0")}`}});let g=e.getBoundingClientRect();A.setCssStyles({left:`${Math.max(8,Math.min(g.left,s.innerWidth-220))}px`,top:`${g.bottom+4}px`}),setTimeout(()=>{i.addEventListener("mousedown",f,!0),i.addEventListener("keydown",u,!0),A.querySelector(".stashpad-when-time-field")?.focus()},0)}startOfTodayLocal(){let e=new Date;return e.setHours(0,0,0,0),e}toDateValue(e){let t=e.getFullYear(),i=String(e.getMonth()+1).padStart(2,"0"),s=String(e.getDate()).padStart(2,"0");return`${t}-${i}-${s}`}toTimeValue(e){let t=String(e.getHours()).padStart(2,"0"),i=String(e.getMinutes()).padStart(2,"0");return`${t}:${i}`}},ei=class ei extends G.Modal{constructor(e,t,i,s=null,n){super(e);this.service=t;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 e=this.contentEl.createDiv({cls:"stashpad-log-toolbar"});if(this.countEl=e.createSpan({cls:"stashpad-log-count"}),this.updateCount(),this.filterSelEl=e.createEl("select",{cls:"stashpad-log-type-filter"}),this.filterSelEl.onchange=()=>this.setCategoryFilter(this.filterSelEl.value||null),this.refreshCategoryFilter(),this.authorSelEl=e.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=e.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 t=e.createEl("button",{cls:"mod-warning",text:"Clear history"});t.onclick=()=>{new j(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()},"Cancel",!0).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(e){this.authorFilter!==e&&(this.authorFilter=e,this.refreshList(),this.renderFooter())}refreshAuthorFilter(){if(!this.authorSelEl)return;let e=this.authorSelEl;e.empty(),e.createEl("option",{text:"All authors"}).value="all",this.currentAuthorId&&(e.createEl("option",{text:"Me"}).value="me"),e.createEl("option",{text:"Cross-author"}).value="cross";let t=new Set;for(let s of this.records)s.authorId&&s.authorId!==this.currentAuthorId&&t.add(s.authorId);if(t.size>0){let s=e.createEl("option",{text:"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"});s.disabled=!0;for(let n of[...t].sort())e.createEl("option",{text:n}).value=n}new Set(["all","cross",...this.currentAuthorId?["me"]:[],...t]).has(this.authorFilter)||(this.authorFilter="all"),e.value=this.authorFilter}isCrossAuthor(e){let t=e.authorId??null;if(!t)return!1;for(let i of e.affectedAuthorIds??[])if(i&&i!==t)return!0;if(!this.getNoteAuthorIds)return!1;for(let i of e.affectedIds){let s=this.getNoteAuthorIds(i);for(let n of s)if(n&&n!==t)return!0}return!1}onClose(){this.unsubscribe?.(),this.unsubscribe=null,this.contentEl.empty()}setCategoryFilter(e){(this.categoryFilter??null)!==(e??null)&&(this.categoryFilter=e,this.refreshList(),this.renderFooter())}refreshCategoryFilter(){if(!this.filterSelEl)return;let e=this.filterSelEl;e.empty();let t=new Map;for(let n of this.records)t.set(n.category,(t.get(n.category)??0)+1);let i=[...t.entries()].sort((n,o)=>o[1]-n[1]||n[0].localeCompare(o[0])),s=e.createEl("option",{text:`All categories (${this.records.length})`});s.value="";for(let[n,o]of i){let a=e.createEl("option",{text:`${n} (${o})`});a.value=n}this.categoryFilter&&!t.has(this.categoryFilter)&&(this.categoryFilter=null),e.value=this.categoryFilter??""}refreshList(){if(this.listEl){if(this.visible=this.records.filter(e=>{if(this.categoryFilter&&e.category!==this.categoryFilter)return!1;switch(this.authorFilter){case"all":return!0;case"me":return!!this.currentAuthorId&&e.authorId===this.currentAuthorId;case"cross":return this.isCrossAuthor(e);default:return e.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(ei.PAGE)}}appendMore(e){if(!this.listEl)return;let t=Math.min(this.visible.length,this.shownCount+e);for(let i=this.shownCount;i<t;i++)this.renderRow(this.listEl,this.visible[i]);this.shownCount=t,this.updateCount()}renderRow(e,t){let i=e.createDiv({cls:`stashpad-notif-row stashpad-notif-row-${t.kind}`}),s=i.createDiv({cls:"stashpad-notif-meta"}),n=s.createSpan({cls:"stashpad-notif-time"}),o=td(t.ts);if(n.setText(o.fromNow()),n.title=o.format("YYYY-MM-DD HH:mm:ss"),s.createSpan({cls:`stashpad-notif-cat stashpad-notif-cat-${t.category}`}).setText(t.category),i.createDiv({cls:"stashpad-notif-msg"}).setText(t.message),t.actionLabels.length>0){let c=i.createDiv({cls:"stashpad-notif-actions-snapshot"});for(let A of t.actionLabels){let h=c.createSpan({cls:"stashpad-notif-action-chip"});h.setText(A),h.title="Action button was shown on the original toast (handler not retained)."}}}updateCount(){if(!this.countEl)return;let e=this.visible.length,t=this.categoryFilter?`${e} ${this.categoryFilter} notification${e===1?"":"s"}`:`${e} notification${e===1?"":"s"}`;this.shownCount===0||this.shownCount>=e?this.countEl.setText(t):this.countEl.setText(`Showing ${this.shownCount} of ${t}`)}renderFooter(){if(!this.footerEl)return;this.footerEl.empty();let e=this.visible.length-this.shownCount;if(e<=0)return;let t=this.footerEl.createEl("button",{text:`Load ${Math.min(ei.PAGE,e)} more`});if(t.onclick=()=>{this.appendMore(ei.PAGE),this.renderFooter()},e>ei.PAGE){let i=this.footerEl.createEl("button",{text:`Load all (${e})`});i.onclick=()=>{this.appendMore(e),this.renderFooter()}}}};ei.PAGE=100;ds=ei,Zo=class extends G.Modal{constructor(e,t){super(e);this.entries=t}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 e=this.contentEl.createDiv({cls:"stashpad-import-log-list"});for(let t of this.entries){let i=e.createDiv({cls:"stashpad-import-log-row"}),s=(0,G.moment)(t.ts).format("YYYY-MM-DD HH:mm");i.createSpan({cls:"stashpad-import-log-when",text:s});let n=t.kind==="folder"?"folder":t.kind==="md"?"note":"file";i.createSpan({cls:`stashpad-import-log-kind is-${t.kind}`,text:n}),i.createSpan({cls:"stashpad-import-log-name",text:t.originalName});let o=[t.folder.split("/").pop()||t.folder];t.notePaths.length>1&&o.push(`${t.notePaths.length} notes`),i.createSpan({cls:"stashpad-import-log-meta",text:o.join(" \xB7 ")})}}onClose(){this.contentEl.empty()}},us=class extends G.Modal{constructor(e,t,i){super(e);this.message=t;this.onChoose=i;this.chose=!1}onOpen(){this.modalEl?.addClass("stashpad-compact-modal"),this.contentEl.empty(),this.titleEl.setText("Possible duplicate import");let e=this.contentEl.createDiv({cls:"stashpad-confirm-body"});for(let o of this.message.split(` -`))e.createDiv({cls:"stashpad-confirm-line",text:o});let t=this.contentEl.createDiv({cls:"stashpad-modal-btns"}),i=t.createEl("button",{text:"Skip duplicates"});i.onclick=()=>{this.chose=!0,this.close(),this.onChoose("skip")};let s=t.createEl("button",{text:"Replace existing"});s.onclick=()=>{this.chose=!0,this.close(),this.onChoose("replace")};let n=t.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()}},fs=class extends G.Modal{constructor(e,t,i){super(e);this.items=t;this.onConfirm=i}onOpen(){this.titleEl.setText("Re-encrypt everything applicable?");let{contentEl:e}=this;e.createEl("p",{cls:"setting-item-description",text:"These notes should be encrypted (they were unlocked/restored, or their folder is set to encrypt) but are currently plaintext. Untick anything you want to leave readable."});let t=e.createDiv({cls:"stashpad-reenc-list"}),i=[];this.items.forEach(o=>{let a=t.createEl("label",{cls:"stashpad-reenc-row"}),l=a.createEl("input",{type:"checkbox"});l.checked=!0,i.push(l);let c=a.createDiv({cls:"stashpad-reenc-body"});c.createDiv({cls:"stashpad-reenc-label",text:o.label}),c.createDiv({cls:"stashpad-reenc-detail",text:o.detail})});let s=e.createDiv({cls:"modal-button-container"}),n=s.createEl("button",{cls:"mod-cta",text:"Re-encrypt checked"});n.onclick=()=>{let o=i.map((a,l)=>a.checked?l:-1).filter(a=>a>=0);this.close(),o.length&&this.onConfirm(o)},s.createEl("button",{text:"Cancel"}).onclick=()=>this.close()}onClose(){this.contentEl.empty()}}});function kd(d,r){return Fd(d,r||{},0,0)}function Sd(d,r){return yd(d,{i:2},r&&r.out,r&&r.dictionary)}function Ln(d,r){if(r){for(var e=new pe(d.length),t=0;t<d.length;++t)e[t]=d.charCodeAt(t);return e}if(Al)return Al.encode(d);for(var i=d.length,s=new pe(d.length+(d.length>>1)),n=0,o=function(c){s[n++]=c},t=0;t<i;++t){if(n+5>s.length){var a=new pe(n+8+(i-t<<1));a.set(s),s=a}var l=d.charCodeAt(t);l<128||r?o(l):l<2048?(o(192|l>>6),o(128|l&63)):l>55295&&l<57344?(l=65536+(l&1047552)|d.charCodeAt(++t)&1023,o(240|l>>18),o(128|l>>12&63),o(128|l>>6&63),o(128|l&63)):(o(224|l>>12),o(128|l>>6&63),o(128|l&63))}return Fs(s,0,n)}function ya(d,r){if(r){for(var e="",t=0;t<d.length;t+=16384)e+=String.fromCharCode.apply(null,d.subarray(t,t+16384));return e}else{if(Ia)return Ia.decode(d);var i=Dd(d),s=i.s,e=i.r;return e.length&&Se(8),s}}function yl(d,r){r||(r={});var e={},t=[];Bl(d,"",e,r);var i=0,s=0;for(var n in e){var o=e[n],a=o[0],l=o[1],c=l.level==0?0:8,A=Ln(n),h=A.length,p=l.comment,f=p&&Ln(p),u=f&&f.length,g=ma(l.extra);h>65535&&Se(11);var I=c?kd(a,l):a,m=I.length,C=Qd();C.p(a),t.push(Cl(l,{size:a.length,crc:C.d(),c:I,f:A,m:f,u:h!=n.length||f&&p.length!=u,o:i,compression:c})),i+=30+h+g+m,s+=76+2*(h+g)+(u||0)+m}for(var B=new pe(s+22),E=i,y=s-i,v=0;v<t.length;++v){var A=t[v];hl(B,A.o,A,A.f,A.u,A.c.length);var Q=30+A.f.length+ma(A.extra);B.set(A.c,A.o+Q),hl(B,i,A,A.f,A.u,A.c.length,A.o,A.m),i+=16+Q+(A.m?A.m.length:0)}return Md(B,i,t.length,y,E),B}function wl(d,r){for(var e={},t=d.length-22;Ke(d,t)!=101010256;--t)(!t||d.length-t>65558)&&Se(13);var i=rt(d,t+8);if(!i)return{};var s=Ke(d,t+16),n=Ke(d,t-20)==117853008;if(n){var o=Ke(d,t-12);n=Ke(d,o)==101075792,n&&(i=Ke(d,o+32),s=Ke(d,o+48))}for(var a=r&&r.filter,l=0;l<i;++l){var c=Nd(d,s,n),A=c[0],h=c[1],p=c[2],f=c[3],u=c[4],g=c[5],I=xd(d,g);s=u,(!a||a({name:f,size:h,originalSize:p,compression:A}))&&(A?A==8?e[f]=Sd(d.subarray(I,I+h),{out:new pe(p)}):Se(14,"unknown compression type "+A):e[f]=Fs(d,I,I+h))}return e}var pe,Re,Ca,Gn,On,pa,pl,gl,ul,ga,fl,ud,ll,ua,wt,_,lt,Gt,_,_,_,_,Qs,_,fd,Id,md,Cd,ca,Ve,da,Ba,Fs,Bd,Se,yd,Et,Es,Aa,fa,cl,vs,Il,dl,wd,ml,Ed,vd,Qd,Fd,Cl,rt,Ke,ha,Fe,Bl,Al,Ia,bd,Dd,xd,Nd,Td,ma,hl,Md,El=de(()=>{pe=Uint8Array,Re=Uint16Array,Ca=Int32Array,Gn=new pe([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,0,0,0]),On=new pe([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,0,0]),pa=new pe([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),pl=function(d,r){for(var e=new Re(31),t=0;t<31;++t)e[t]=r+=1<<d[t-1];for(var i=new Ca(e[30]),t=1;t<30;++t)for(var s=e[t];s<e[t+1];++s)i[s]=s-e[t]<<5|t;return{b:e,r:i}},gl=pl(Gn,2),ul=gl.b,ga=gl.r;ul[28]=258,ga[258]=28;fl=pl(On,0),ud=fl.b,ll=fl.r,ua=new Re(32768);for(_=0;_<32768;++_)wt=(_&43690)>>1|(_&21845)<<1,wt=(wt&52428)>>2|(wt&13107)<<2,wt=(wt&61680)>>4|(wt&3855)<<4,ua[_]=((wt&65280)>>8|(wt&255)<<8)>>1;lt=function(d,r,e){for(var t=d.length,i=0,s=new Re(r);i<t;++i)d[i]&&++s[d[i]-1];var n=new Re(r);for(i=1;i<r;++i)n[i]=n[i-1]+s[i-1]<<1;var o;if(e){o=new Re(1<<r);var a=15-r;for(i=0;i<t;++i)if(d[i])for(var l=i<<4|d[i],c=r-d[i],A=n[d[i]-1]++<<c,h=A|(1<<c)-1;A<=h;++A)o[ua[A]>>a]=l}else for(o=new Re(t),i=0;i<t;++i)d[i]&&(o[i]=ua[n[d[i]-1]++]>>15-d[i]);return o},Gt=new pe(288);for(_=0;_<144;++_)Gt[_]=8;for(_=144;_<256;++_)Gt[_]=9;for(_=256;_<280;++_)Gt[_]=7;for(_=280;_<288;++_)Gt[_]=8;Qs=new pe(32);for(_=0;_<32;++_)Qs[_]=5;fd=lt(Gt,9,0),Id=lt(Gt,9,1),md=lt(Qs,5,0),Cd=lt(Qs,5,1),ca=function(d){for(var r=d[0],e=1;e<d.length;++e)d[e]>r&&(r=d[e]);return r},Ve=function(d,r,e){var t=r/8|0;return(d[t]|d[t+1]<<8)>>(r&7)&e},da=function(d,r){var e=r/8|0;return(d[e]|d[e+1]<<8|d[e+2]<<16)>>(r&7)},Ba=function(d){return(d+7)/8|0},Fs=function(d,r,e){return(r==null||r<0)&&(r=0),(e==null||e>d.length)&&(e=d.length),new pe(d.subarray(r,e))},Bd=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],Se=function(d,r,e){var t=new Error(r||Bd[d]);if(t.code=d,Error.captureStackTrace&&Error.captureStackTrace(t,Se),!e)throw t;return t},yd=function(d,r,e,t){var i=d.length,s=t?t.length:0;if(!i||r.f&&!r.l)return e||new pe(0);var n=!e,o=n||r.i!=2,a=r.i;n&&(e=new pe(i*3));var l=function(fe){var we=e.length;if(fe>we){var se=new pe(Math.max(we*2,fe));se.set(e),e=se}},c=r.f||0,A=r.p||0,h=r.b||0,p=r.l,f=r.d,u=r.m,g=r.n,I=i*8;do{if(!p){c=Ve(d,A,1);var m=Ve(d,A+1,3);if(A+=3,m)if(m==1)p=Id,f=Cd,u=9,g=5;else if(m==2){var y=Ve(d,A,31)+257,v=Ve(d,A+10,15)+4,Q=y+Ve(d,A+5,31)+1;A+=14;for(var w=new pe(Q),F=new pe(19),D=0;D<v;++D)F[pa[D]]=Ve(d,A+D*3,7);A+=v*3;for(var H=ca(F),R=(1<<H)-1,L=lt(F,H,1),D=0;D<Q;){var x=L[Ve(d,A,R)];A+=x&15;var C=x>>4;if(C<16)w[D++]=C;else{var U=0,T=0;for(C==16?(T=3+Ve(d,A,3),A+=2,U=w[D-1]):C==17?(T=3+Ve(d,A,7),A+=3):C==18&&(T=11+Ve(d,A,127),A+=7);T--;)w[D++]=U}}var b=w.subarray(0,y),M=w.subarray(y);u=ca(b),g=ca(M),p=lt(b,u,1),f=lt(M,g,1)}else Se(1);else{var C=Ba(A)+4,B=d[C-4]|d[C-3]<<8,E=C+B;if(E>i){a&&Se(0);break}o&&l(h+B),e.set(d.subarray(C,E),h),r.b=h+=B,r.p=A=E*8,r.f=c;continue}if(A>I){a&&Se(0);break}}o&&l(h+131072);for(var O=(1<<u)-1,K=(1<<g)-1,$=A;;$=A){var U=p[da(d,A)&O],Z=U>>4;if(A+=U&15,A>I){a&&Se(0);break}if(U||Se(2),Z<256)e[h++]=Z;else if(Z==256){$=A,p=null;break}else{var V=Z-254;if(Z>264){var D=Z-257,J=Gn[D];V=Ve(d,A,(1<<J)-1)+ul[D],A+=J}var ee=f[da(d,A)&K],ue=ee>>4;ee||Se(3),A+=ee&15;var M=ud[ue];if(ue>3){var J=On[ue];M+=da(d,A)&(1<<J)-1,A+=J}if(A>I){a&&Se(0);break}o&&l(h+131072);var oe=h+V;if(h<M){var ie=s-M,te=Math.min(M,oe);for(ie+h<0&&Se(3);h<te;++h)e[h]=t[ie+h]}for(;h<oe;++h)e[h]=e[h-M]}}r.l=p,r.p=$,r.b=h,r.f=c,p&&(c=1,r.m=u,r.d=f,r.n=g)}while(!c);return h!=e.length&&n?Fs(e,0,h):e.subarray(0,h)},Et=function(d,r,e){e<<=r&7;var t=r/8|0;d[t]|=e,d[t+1]|=e>>8},Es=function(d,r,e){e<<=r&7;var t=r/8|0;d[t]|=e,d[t+1]|=e>>8,d[t+2]|=e>>16},Aa=function(d,r){for(var e=[],t=0;t<d.length;++t)d[t]&&e.push({s:t,f:d[t]});var i=e.length,s=e.slice();if(!i)return{t:ml,l:0};if(i==1){var n=new pe(e[0].s+1);return n[e[0].s]=1,{t:n,l:1}}e.sort(function(E,y){return E.f-y.f}),e.push({s:-1,f:25001});var o=e[0],a=e[1],l=0,c=1,A=2;for(e[0]={s:-1,f:o.f+a.f,l:o,r:a};c!=i-1;)o=e[e[l].f<e[A].f?l++:A++],a=e[l!=c&&e[l].f<e[A].f?l++:A++],e[c++]={s:-1,f:o.f+a.f,l:o,r:a};for(var h=s[0].s,t=1;t<i;++t)s[t].s>h&&(h=s[t].s);var p=new Re(h+1),f=fa(e[c-1],p,0);if(f>r){var t=0,u=0,g=f-r,I=1<<g;for(s.sort(function(y,v){return p[v.s]-p[y.s]||y.f-v.f});t<i;++t){var m=s[t].s;if(p[m]>r)u+=I-(1<<f-p[m]),p[m]=r;else break}for(u>>=g;u>0;){var C=s[t].s;p[C]<r?u-=1<<r-p[C]++-1:++t}for(;t>=0&&u;--t){var B=s[t].s;p[B]==r&&(--p[B],++u)}f=r}return{t:new pe(p),l:f}},fa=function(d,r,e){return d.s==-1?Math.max(fa(d.l,r,e+1),fa(d.r,r,e+1)):r[d.s]=e},cl=function(d){for(var r=d.length;r&&!d[--r];);for(var e=new Re(++r),t=0,i=d[0],s=1,n=function(a){e[t++]=a},o=1;o<=r;++o)if(d[o]==i&&o!=r)++s;else{if(!i&&s>2){for(;s>138;s-=138)n(32754);s>2&&(n(s>10?s-11<<5|28690:s-3<<5|12305),s=0)}else if(s>3){for(n(i),--s;s>6;s-=6)n(8304);s>2&&(n(s-3<<5|8208),s=0)}for(;s--;)n(i);s=1,i=d[o]}return{c:e.subarray(0,t),n:r}},vs=function(d,r){for(var e=0,t=0;t<r.length;++t)e+=d[t]*r[t];return e},Il=function(d,r,e){var t=e.length,i=Ba(r+2);d[i]=t&255,d[i+1]=t>>8,d[i+2]=d[i]^255,d[i+3]=d[i+1]^255;for(var s=0;s<t;++s)d[i+s+4]=e[s];return(i+4+t)*8},dl=function(d,r,e,t,i,s,n,o,a,l,c){Et(r,c++,e),++i[256];for(var A=Aa(i,15),h=A.t,p=A.l,f=Aa(s,15),u=f.t,g=f.l,I=cl(h),m=I.c,C=I.n,B=cl(u),E=B.c,y=B.n,v=new Re(19),Q=0;Q<m.length;++Q)++v[m[Q]&31];for(var Q=0;Q<E.length;++Q)++v[E[Q]&31];for(var w=Aa(v,7),F=w.t,D=w.l,H=19;H>4&&!F[pa[H-1]];--H);var R=l+5<<3,L=vs(i,Gt)+vs(s,Qs)+n,x=vs(i,h)+vs(s,u)+n+14+3*H+vs(v,F)+2*v[16]+3*v[17]+7*v[18];if(a>=0&&R<=L&&R<=x)return Il(r,c,d.subarray(a,a+l));var U,T,b,M;if(Et(r,c,1+(x<L)),c+=2,x<L){U=lt(h,p,0),T=h,b=lt(u,g,0),M=u;var O=lt(F,D,0);Et(r,c,C-257),Et(r,c+5,y-1),Et(r,c+10,H-4),c+=14;for(var Q=0;Q<H;++Q)Et(r,c+3*Q,F[pa[Q]]);c+=3*H;for(var K=[m,E],$=0;$<2;++$)for(var Z=K[$],Q=0;Q<Z.length;++Q){var V=Z[Q]&31;Et(r,c,O[V]),c+=F[V],V>15&&(Et(r,c,Z[Q]>>5&127),c+=Z[Q]>>12)}}else U=fd,T=Gt,b=md,M=Qs;for(var Q=0;Q<o;++Q){var J=t[Q];if(J>255){var V=J>>18&31;Es(r,c,U[V+257]),c+=T[V+257],V>7&&(Et(r,c,J>>23&31),c+=Gn[V]);var ee=J&31;Es(r,c,b[ee]),c+=M[ee],ee>3&&(Es(r,c,J>>5&8191),c+=On[ee])}else Es(r,c,U[J]),c+=T[J]}return Es(r,c,U[256]),c+T[256]},wd=new Ca([65540,131080,131088,131104,262176,1048704,1048832,2114560,2117632]),ml=new pe(0),Ed=function(d,r,e,t,i,s){var n=s.z||d.length,o=new pe(t+n+5*(1+Math.ceil(n/7e3))+i),a=o.subarray(t,o.length-i),l=s.l,c=(s.r||0)&7;if(r){c&&(a[0]=s.r>>3);for(var A=wd[r-1],h=A>>13,p=A&8191,f=(1<<e)-1,u=s.p||new Re(32768),g=s.h||new Re(f+1),I=Math.ceil(e/3),m=2*I,C=function(Ae){return(d[Ae]^d[Ae+1]<<I^d[Ae+2]<<m)&f},B=new Ca(25e3),E=new Re(288),y=new Re(32),v=0,Q=0,w=s.i||0,F=0,D=s.w||0,H=0;w+2<n;++w){var R=C(w),L=w&32767,x=g[R];if(u[L]=x,g[R]=L,D<=w){var U=n-w;if((v>7e3||F>24576)&&(U>423||!l)){c=dl(d,a,0,B,E,y,Q,F,H,w-H,c),F=v=Q=0,H=w;for(var T=0;T<286;++T)E[T]=0;for(var T=0;T<30;++T)y[T]=0}var b=2,M=0,O=p,K=L-x&32767;if(U>2&&R==C(w-K))for(var $=Math.min(h,U)-1,Z=Math.min(32767,w),V=Math.min(258,U);K<=Z&&--O&&L!=x;){if(d[w+b]==d[w+b-K]){for(var J=0;J<V&&d[w+J]==d[w+J-K];++J);if(J>b){if(b=J,M=K,J>$)break;for(var ee=Math.min(K,J-2),ue=0,T=0;T<ee;++T){var oe=w-K+T&32767,ie=u[oe],te=oe-ie&32767;te>ue&&(ue=te,x=oe)}}}L=x,x=u[L],K+=L-x&32767}if(M){B[F++]=268435456|ga[b]<<18|ll[M];var fe=ga[b]&31,we=ll[M]&31;Q+=Gn[fe]+On[we],++E[257+fe],++y[we],D=w+b,++v}else B[F++]=d[w],++E[d[w]]}}for(w=Math.max(w,D);w<n;++w)B[F++]=d[w],++E[d[w]];c=dl(d,a,l,B,E,y,Q,F,H,w-H,c),l||(s.r=c&7|a[c/8|0]<<3,c-=7,s.h=g,s.p=u,s.i=w,s.w=D)}else{for(var w=s.w||0;w<n+l;w+=65535){var se=w+65535;se>=n&&(a[c/8|0]=l,se=n),c=Il(a,c+1,d.subarray(w,se))}s.i=n}return Fs(o,0,t+Ba(c)+i)},vd=function(){for(var d=new Int32Array(256),r=0;r<256;++r){for(var e=r,t=9;--t;)e=(e&1&&-306674912)^e>>>1;d[r]=e}return d}(),Qd=function(){var d=-1;return{p:function(r){for(var e=d,t=0;t<r.length;++t)e=vd[e&255^r[t]]^e>>>8;d=e},d:function(){return~d}}},Fd=function(d,r,e,t,i){if(!i&&(i={l:1},r.dictionary)){var s=r.dictionary.subarray(-32768),n=new pe(s.length+d.length);n.set(s),n.set(d,s.length),d=n,i.w=s.length}return Ed(d,r.level==null?6:r.level,r.mem==null?i.l?Math.ceil(Math.max(8,Math.min(13,Math.log(d.length)))*1.5):20:12+r.mem,e,t,i)},Cl=function(d,r){var e={};for(var t in d)e[t]=d[t];for(var t in r)e[t]=r[t];return e},rt=function(d,r){return d[r]|d[r+1]<<8},Ke=function(d,r){return(d[r]|d[r+1]<<8|d[r+2]<<16|d[r+3]<<24)>>>0},ha=function(d,r){return Ke(d,r)+Ke(d,r+4)*4294967296},Fe=function(d,r,e){for(;e;++r)d[r]=e,e>>>=8};Bl=function(d,r,e,t){for(var i in d){var s=d[i],n=r+i,o=t;Array.isArray(s)&&(o=Cl(t,s[1]),s=s[0]),ArrayBuffer.isView(s)?e[n]=[s,o]:(e[n+="/"]=[new pe(0),o],Bl(s,n,e,t))}},Al=typeof TextEncoder<"u"&&new TextEncoder,Ia=typeof TextDecoder<"u"&&new TextDecoder,bd=0;try{Ia.decode(ml,{stream:!0}),bd=1}catch{}Dd=function(d){for(var r="",e=0;;){var t=d[e++],i=(t>127)+(t>223)+(t>239);if(e+i>d.length)return{s:r,r:Fs(d,e-1)};i?i==3?(t=((t&15)<<18|(d[e++]&63)<<12|(d[e++]&63)<<6|d[e++]&63)-65536,r+=String.fromCharCode(55296|t>>10,56320|t&1023)):i&1?r+=String.fromCharCode((t&31)<<6|d[e++]&63):r+=String.fromCharCode((t&15)<<12|(d[e++]&63)<<6|d[e++]&63):r+=String.fromCharCode(t)}};xd=function(d,r){return r+30+rt(d,r+26)+rt(d,r+28)},Nd=function(d,r,e){var t=rt(d,r+28),i=rt(d,r+30),s=ya(d.subarray(r+46,r+46+t),!(rt(d,r+8)&2048)),n=r+46+t,o=Td(d,n,i,e,Ke(d,r+20),Ke(d,r+24),Ke(d,r+42)),a=o[0],l=o[1],c=o[2];return[rt(d,r+10),a,l,s,n+i+rt(d,r+32),c]},Td=function(d,r,e,t,i,s,n){var o=i==4294967295,a=s==4294967295,l=n==4294967295,c=r+e,A=o+a+l;if(t&&A){for(;r+4<c;r+=4+rt(d,r+2))if(rt(d,r)==1)return[o?ha(d,r+4+8*a):i,a?ha(d,r+4):s,l?ha(d,r+4+8*(a+o)):n,1];t<2&&Se(13)}return[i,s,n,0]},ma=function(d){var r=0;if(d)for(var e in d){var t=d[e].length;t>65535&&Se(9),r+=t+4}return r},hl=function(d,r,e,t,i,s,n,o){var a=t.length,l=e.extra,c=o&&o.length,A=ma(l);Fe(d,r,n!=null?33639248:67324752),r+=4,n!=null&&(d[r++]=20,d[r++]=e.os),d[r]=20,r+=2,d[r++]=e.flag<<1|(s<0&&8),d[r++]=i&&8,d[r++]=e.compression&255,d[r++]=e.compression>>8;var h=new Date(e.mtime==null?Date.now():e.mtime),p=h.getFullYear()-1980;if((p<0||p>119)&&Se(10),Fe(d,r,p<<25|h.getMonth()+1<<21|h.getDate()<<16|h.getHours()<<11|h.getMinutes()<<5|h.getSeconds()>>1),r+=4,s!=-1&&(Fe(d,r,e.crc),Fe(d,r+4,s<0?-s-2:s),Fe(d,r+8,e.size)),Fe(d,r+12,a),Fe(d,r+14,A),r+=16,n!=null&&(Fe(d,r,c),Fe(d,r+6,e.attrs),Fe(d,r+10,n),r+=14),d.set(t,r),r+=a,A)for(var f in l){var u=l[f],g=u.length;Fe(d,r,+f),Fe(d,r+2,g),d.set(u,r+4),r+=4+g}return c&&(d.set(o,r),r+=c),r},Md=function(d,r,e,t,i){Fe(d,r,101010256),Fe(d,r+8,e),Fe(d,r+10,e),Fe(d,r+12,t),Fe(d,r+16,i)}});var Fl={};Ji(Fl,{bytesToStr:()=>Kn,unzipFiles:()=>Li,zipFiles:()=>Ui});function Hd(d){return typeof d=="string"?Ln(d):d instanceof Uint8Array?d:new Uint8Array(d)}function Ui(d,r=6){let e={};for(let t of d)e[t.name]=[Hd(t.data),{level:r}];return Promise.resolve(yl(e,{level:r}))}function Kn(d){return ya(d)}function Li(d){let r=d instanceof Uint8Array?d:new Uint8Array(d),e=0,t=0,i=s=>{if(t+=1,t>Ql)throw new Error(`Refusing to unzip: too many entries (>${Ql}) \u2014 possible zip bomb.`);if(s.originalSize>Pd)throw new Error(`Refusing to unzip: entry "${s.name}" is ${Math.round(s.originalSize/1048576)} MiB \u2014 possible zip bomb.`);if(e+=s.originalSize,e>vl)throw new Error(`Refusing to unzip: total size >${Math.round(vl/1048576)} MiB \u2014 possible zip bomb.`);return!0};return Promise.resolve(wl(r,{filter:i}))}var vl,Pd,Ql,qn=de(()=>{"use strict";El();vl=512*1024*1024,Pd=256*1024*1024,Ql=2e4});var cA={};Ji(cA,{default:()=>ho});module.exports=lc(cA);var N=require("obsidian");var $i="sheet-group",ht="sheet-order",ri="sheet-final",La="sheet-label",Yi="sheet-origin",zi="forked-from",je="fork-siblings",uo="forked-at",fo=[$i,ht,ri,La,Yi,zi,je,uo];function _e(d){if(!d)return null;let r=d[$i];return typeof r=="string"&&r.trim()?r:null}function go(d){let r=d?.[ht];return typeof r=="number"?r:null}function Vi(d){return _e(d)!==null&&go(d)!==null}function Wi(d){return d?.[ri]===!0}function Ga(d){return d?.[Yi]===!0}function cc(d){let r=d?.[zi];return typeof r=="string"&&r.trim()?r:null}function Gs(d){return typeof d!="string"?null:d.replace(/^\[\[/,"").replace(/\]\]$/,"").split("|")[0].split("#")[0].trim()||null}function Oa(d){return Gs(cc(d))}function dc(d){let r=d?.[La];return typeof r=="string"&&r.trim()?r:null}function Ka(){let d=Date.now().toString(36),r=Math.floor(Math.random()*1e6).toString(36);return`s-${d}-${r}`}function ke(d,r){return r.file?d.metadataCache.getFileCache(r.file)?.frontmatter:null}function Io(d,r){return r.slice().sort((e,t)=>{let i=go(ke(d,e)),s=go(ke(d,t));if(i!=null&&s!=null&&i!==s)return i-s;if(i!=null&&s==null)return-1;if(i==null&&s!=null)return 1;let n=e.created??"",o=t.created??"";return n!==o?n<o?-1:1:e.id<t.id?-1:e.id>t.id?1:0})}function qa(d,r){if(r.length===0)return null;let e=Io(d,r);return e.find(t=>Wi(ke(d,t)))??e[0]}function Ja(d,r,e){let t=dc(ke(d,r));return t||e}pt();ce();var Qe=require("obsidian");var re=require("obsidian");ce();Tt();ve();ce();function jo(d,r){let e=d.basename;return r&&e.endsWith(`-${r}`)?e=e.slice(0,-(r.length+1)):r||(e=e.replace(/-[abcdefghijkmnpqrstuvwxyz23456789]{6}$/,"")),e.replace(/-/g," ").trim()||d.basename}function In(d,r){let e=new Set(r.discoverStashpadFolders()),t=[];for(let i of d.vault.getMarkdownFiles()){let s=i.parent?.path?.replace(/\/+$/,"")??"";if(!e.has(s))continue;let n=d.metadataCache.getFileCache(i)?.frontmatter??{},o=typeof n.id=="string"?n.id:null;if(!o||o===S)continue;let a=n.completed===!0,l=di(n,"task")||n.task===!0||n.completed!==void 0,c=typeof n.due=="string"||typeof n.due=="number"?String(n.due):null,A=null;if(typeof n.due=="number")Number.isFinite(n.due)&&n.due>=1e11&&(A=n.due);else if(c){let h=Date.parse(c);Number.isNaN(h)||(A=h)}!l&&!a&&A==null&&!c||t.push({file:i,folder:s,id:o,title:jo(i,o),task:l,completed:a,due:A,dueRaw:c,color:typeof n.color=="string"?n.color:null,assignedTo:xt(n),assignedBy:gt(n.assignedBy),author:gt(n.author)})}return t}var qr=require("obsidian");var ot=require("obsidian");ve();Tt();var nd=0,_o=[{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"}];function mn(){return{assign:"all",person:"",folder:"all",status:"all"}}function Cs(d,r,e,t,i){let s=()=>Cs(d,r,e,t,i);d.empty(),d.addClass("stashpad-task-triage");let n=In(r,e),o=(e.settings.authorId??"").trim(),a=b=>!!o&&b.assignedTo.some(M=>M.id===o),l=b=>{switch(t.assign){case"mine":return a(b);case"others":return b.assignedTo.length>0&&!a(b);case"byme":return!!o&&b.assignedBy?.id===o;case"unassigned":return b.assignedTo.length===0;default:return!0}},c=b=>!t.person||b.assignedTo.some(M=>M.id===t.person)||b.author?.id===t.person||b.assignedBy?.id===t.person,A=new Map;for(let b of n){for(let M of b.assignedTo)A.set(M.id,M.name);b.assignedBy&&A.set(b.assignedBy.id,b.assignedBy.name),b.author&&A.set(b.author.id,b.author.name)}let h=[...A.entries()].map(([b,M])=>({id:b,name:M})).sort((b,M)=>b.name.localeCompare(M.name)),p=[...new Set(n.map(b=>b.folder))].sort((b,M)=>b.localeCompare(M));t.folder!=="all"&&!p.includes(t.folder)&&(t.folder="all");let f=b=>t.folder==="all"||b.folder===t.folder,u=d.createDiv({cls:"stashpad-triage-filters"}),g=u.createEl("button",{cls:"stashpad-triage-reset",attr:{"aria-label":"Reset filters"}});(0,ot.setIcon)(g,"rotate-ccw"),g.onclick=()=>{t.assign="all",t.person="",t.folder="all",s()};let I=u.createEl("select",{cls:"stashpad-triage-select"}),m={all:"Everyone",mine:"Assigned to me",others:"Assigned to others",byme:"Assigned by me",unassigned:"Unassigned"};for(let b of["all","mine","others","byme","unassigned"]){let M=I.createEl("option",{text:m[b],value:b});t.assign===b&&(M.selected=!0)}I.onchange=()=>{t.assign=I.value,s()};let C=u.createEl("select",{cls:"stashpad-triage-select"}),B=C.createEl("option",{text:"All folders",value:"all"});t.folder==="all"&&(B.selected=!0);for(let b of p){let M=C.createEl("option",{text:b.split("/").pop()||b,value:b});t.folder===b&&(M.selected=!0)}if(C.onchange=()=>{t.folder=C.value,s()},h.length>0){let b=new Map;for(let J of h)b.has(J.name)||b.set(J.name,J.id);let M=`stashpad-task-authors-${++nd}`,O=u.createDiv({cls:"stashpad-triage-authorwrap"}),K=O.createEl("input",{cls:"stashpad-triage-authorsearch",attr:{type:"text",list:M,placeholder:"Any person\u2026",spellcheck:"false"}}),$=O.createEl("button",{cls:"stashpad-triage-authorclear",attr:{"aria-label":"Clear person filter"}});(0,ot.setIcon)($,"x"),$.onclick=()=>{K.value="",t.person?(t.person="",s()):K.focus()};let Z=O.createEl("datalist");Z.id=M;for(let J of h)Z.createEl("option",{value:J.name});t.person&&(K.value=A.get(t.person)??"");let V=()=>{let J=K.value.trim();if(J===""){t.person&&(t.person="",s());return}let ee=b.get(J);ee&&t.person!==ee&&(t.person=ee,s())};K.onchange=V,K.addEventListener("keydown",J=>{J.key==="Enter"&&V()})}let E=Date.now(),y=new Date;y.setHours(0,0,0,0);let v=y.getTime(),Q=v+864e5,w=n.filter(b=>l(b)&&c(b)&&f(b)),F={overdue:[],today:[],upcoming:[],nodate:[],completed:[]};for(let b of w){if(b.completed){F.completed.push(b);continue}if(b.due==null){F.nodate.push(b);continue}b.due<v?F.overdue.push(b):b.due<Q?F.today.push(b):F.upcoming.push(b)}let D=(b,M)=>b.due==null&&M.due==null?b.title.localeCompare(M.title):b.due==null?1:M.due==null?-1:b.due-M.due,H=d.createDiv({cls:"stashpad-triage-chips"}),R=(b,M,O)=>{let K=H.createEl("button",{cls:"stashpad-triage-chip"});t.status===b&&K.addClass("is-active"),K.createSpan({text:M}),K.createSpan({cls:"stashpad-triage-chip-count",text:String(O)}),K.onclick=()=>{t.status=b,s()}};R("all","All",w.length);for(let b of _o)R(b.key,b.label,F[b.key].length);if(w.length===0){d.createDiv({cls:"stashpad-tasks-empty"}).setText(n.length===0?"No tasks yet \u2014 press G on a note to make it a task, or D to give it a due date.":"No tasks match the current filters.");return}let L=async b=>{try{await r.fileManager.processFrontMatter(b.file,M=>{M.completed=M.completed!==!0})}catch(M){new ot.Notice(`Couldn't update task: ${M.message}`);return}s()},x=b=>{let M=b.dueRaw??(b.due!=null?new Date(b.due).toISOString():null);new ze(r,M,O=>{r.fileManager.processFrontMatter(b.file,K=>{O.iso===null?delete K.due:(K.due=O.iso,K.task=!0)}).then(s).catch(K=>new ot.Notice(`Couldn't snooze: ${K.message}`))},{title:"Snooze \u2014 reschedule",hideAssignees:!0,quickAdjusts:e.settings.dueQuickAdjusts}).open()},U=t.status==="all"?_o:_o.filter(b=>b.key===t.status),T=!1;for(let b of U){let M=F[b.key];if(M.length===0)continue;if(T=!0,M.sort(b.key==="completed"?(K,$)=>D($,K):D),t.status==="all"){let K=d.createDiv({cls:`stashpad-review-section is-${b.key}`});(0,ot.setIcon)(K.createSpan({cls:"stashpad-review-section-icon"}),b.icon),K.createSpan({cls:"stashpad-review-section-name",text:b.label}),K.createSpan({cls:"stashpad-review-section-count",text:String(M.length)})}let O=d.createDiv({cls:"stashpad-review-list"});for(let K of M)od(O,K,E,e,{toggleCompleted:L,snooze:x,onOpen:i.onOpen})}T||d.createDiv({cls:"stashpad-tasks-empty"}).setText("Nothing in this view.")}function od(d,r,e,t,i){let s=d.createDiv({cls:"stashpad-review-row"});r.completed&&s.addClass("is-completed");let n=s.createSpan({cls:"stashpad-review-check"});(0,ot.setIcon)(n,r.completed?"check-square":"square"),r.color&&(n.style.color=r.color),n.title=r.completed?"Mark not done":"Mark done",n.onclick=()=>i.toggleCompleted(r);let o=s.createDiv({cls:"stashpad-review-main"}),a=o.createDiv({cls:"stashpad-review-title",text:r.title});a.onclick=()=>i.onOpen(r.folder,r.id);let l=o.createDiv({cls:"stashpad-review-meta"});if(l.createSpan({cls:"stashpad-review-folder",text:r.folder.split("/").pop()||r.folder}),r.author&&l.createSpan({cls:"stashpad-review-author",text:`by ${r.author.name}`}),r.due!=null){let p=r.due<e&&!r.completed,f=new Date(e);f.setHours(0,0,0,0);let u=f.getTime(),g=r.due>=u&&r.due<u+864e5,I=l.createSpan({cls:"stashpad-review-due",text:g?Ai(r.due,t.settings):Nt(r.due,t.settings)});p&&I.addClass("is-overdue")}else r.dueRaw?l.createSpan({cls:"stashpad-review-due",text:r.dueRaw}):l.createSpan({cls:"stashpad-review-due is-none",text:"no date"});for(let p of r.assignedTo)l.createSpan({cls:"stashpad-review-assignee",text:p.name});let c=s.createDiv({cls:"stashpad-review-actions"}),A=c.createEl("button",{cls:"stashpad-review-btn"});(0,ot.setIcon)(A,"alarm-clock"),A.title="Snooze \u2014 reschedule",A.onclick=()=>i.snooze(r);let h=c.createEl("button",{cls:"stashpad-review-btn"});(0,ot.setIcon)(h,"arrow-right"),h.title="Open note",h.onclick=()=>i.onOpen(r.folder,r.id)}var Di=class extends qr.Modal{constructor(e,t){super(e);this.plugin=t;this.state=mn()}onOpen(){this.modalEl.addClass("stashpad-task-review-modal"),this.titleEl.setText("Daily task review"),Cs(this.contentEl,this.app,this.plugin,this.state,{onOpen:(e,t)=>{this.plugin.revealNoteByRef(e,t),this.close()}})}onClose(){this.contentEl.empty()}};function Ht(d,r,e){let t=d.createSpan({cls:"stashpad-count-badge"});e&&t.addClass("is-expanded"),t.setText(r>99?"99+":String(r))}var Bs={pinned:{label:"Pinned",icon:"pin"},shared:{label:"Shared",icon:"users"},tasks:{label:"Tasks",icon:"check-circle-2"}},Cn=class extends re.ItemView{constructor(e,t){super(e);this.plugin=t;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(e){this.activePanel=e,this.containerEl.isConnected&&this.render()}getViewType(){return St}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",e=>{e&&e.view.getViewType()===z&&this.scheduleRender()}))}scheduleRender(){this.renderTimer==null&&(this.renderTimer=window.setTimeout(()=>{this.renderTimer=null,this.containerEl.isConnected&&this.render()},80))}render(){let e=this.contentEl;e.empty(),e.addClass("stashpad-panels-root");let t=e.createDiv({cls:"stashpad-panels-globals"}),i=t.createEl("button",{cls:"stashpad-panels-global-btn"});(0,re.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=t.createEl("button",{cls:"stashpad-panels-global-btn"});(0,re.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=t.createDiv({cls:"stashpad-panels-globals-row"}),o=n.createEl("button",{cls:"stashpad-panels-global-btn"});(0,re.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,re.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 l=e.createDiv({cls:"stashpad-panels-bar"});for(let A of Object.keys(Bs)){let h=Bs[A],p=l.createEl("button",{cls:"stashpad-panels-bar-btn"});(0,re.setIcon)(p.createSpan({cls:"stashpad-panels-bar-btn-icon"}),h.icon),p.createSpan({cls:"stashpad-panels-bar-btn-text",text:h.label}),this.activePanel===A&&p.addClass("is-active"),p.onclick=()=>{this.activePanel!==A&&(this.activePanel=A,this.render())}}let c=e.createDiv({cls:"stashpad-panels-body"});this.activePanel==="pinned"?this.renderPinnedPanel(c):this.activePanel==="shared"?this.renderSharedPanel(c):this.activePanel==="tasks"&&this.renderTasksPanel(c)}openPinnedOptionsMenu(e){let t=this.plugin.settings.folderPanelPinnedGrouping??"pin-order",i=new re.Menu;i.addItem(s=>s.setTitle("Sort by pin order").setChecked(t==="pin-order").onClick(()=>void this.setPinnedGrouping("pin-order"))),i.addItem(s=>s.setTitle("Group by folder").setChecked(t==="folder").onClick(()=>void this.setPinnedGrouping("folder"))),i.showAtMouseEvent(e)}async setPinnedGrouping(e){(this.plugin.settings.folderPanelPinnedGrouping??"pin-order")!==e&&(this.plugin.settings.folderPanelPinnedGrouping=e,await this.plugin.saveSettings(),this.render())}renderPinnedPanel(e){let t=e.createDiv({cls:"stashpad-panel-pinned"});(this.plugin.settings.folderPanelPinnedGrouping??"pin-order")!=="folder"&&t.addClass("is-flat");let i=t.createDiv({cls:"stashpad-pinned-headrow"}),s=i.createEl("button",{cls:"stashpad-pinned-row stashpad-pinned-home"}),n=s.createSpan({cls:"stashpad-pinned-icon"});(0,re.setIcon)(n,"home"),s.createSpan({cls:"stashpad-pinned-label",text:"Home"}),s.onclick=()=>this.openHomeFromPanel();let o=i.createEl("button",{cls:"stashpad-folderpanel-iconbtn stashpad-pinned-opts"});(0,re.setIcon)(o,"list"),o.setAttr("aria-label","Pinned view options"),o.onclick=p=>{p.stopPropagation(),this.openPinnedOptionsMenu(p)};let a=this.plugin.listPinnedNotes();if(a.length===0){t.createDiv({cls:"stashpad-pinned-empty"}).setText("No pinned notes yet \u2014 right-click a note and choose \u201CPin to sidebar.\u201D");return}if((this.plugin.settings.folderPanelPinnedGrouping??"pin-order")!=="folder"){a.forEach((p,f)=>this.renderPinnedRow(t,p,f));return}let c=new Map;a.forEach((p,f)=>{let u=c.get(p.folder);u||(u=[],c.set(p.folder,u)),u.push({pin:p,idx:f})});let A=this.plugin.lastActiveStashpadLeaf?.view?.noteFolder,h=Array.from(c.keys());A&&c.has(A)&&(h.splice(h.indexOf(A),1),h.unshift(A));for(let p of h){let f=p.split("/").pop()||p,u=t.createDiv({cls:"stashpad-pinned-group-header"});p===A&&u.addClass("is-active-folder"),u.createSpan({cls:"stashpad-pinned-group-name",text:f});let g=c.get(p)??[];for(let{pin:I,idx:m}of g)this.renderPinnedRow(t,I,m)}}renderPinnedRow(e,t,i){let s=this.findFileFor(t);if(!s)return;let n=this.app.metadataCache.getFileCache(s)?.frontmatter??{},o=this.titleFromFile(s),a=typeof n.color=="string"?n.color:null,l=n.completed===!0,c=this.childrenOf(t.folder,t.id).length,A=c>0,h=this.expanded.has(`${t.folder}|${t.id}`),p=e.createDiv({cls:"stashpad-pinned-row"});a&&p.addClass("has-color"),l&&p.addClass("is-completed"),p.draggable=!0,p.dataset.pinIdx=String(i),p.addEventListener("dragstart",m=>{m.dataTransfer?.setData("text/plain",String(i)),m.dataTransfer&&(m.dataTransfer.effectAllowed="move"),p.addClass("is-dragging")}),p.addEventListener("dragend",()=>p.removeClass("is-dragging")),p.addEventListener("dragover",m=>{m.preventDefault(),m.dataTransfer&&(m.dataTransfer.dropEffect="move");let C=p.getBoundingClientRect(),B=m.clientY-C.top<C.height/2;p.toggleClass("drop-before",B),p.toggleClass("drop-after",!B)}),p.addEventListener("dragleave",()=>{p.removeClass("drop-before"),p.removeClass("drop-after")}),p.addEventListener("drop",m=>{m.preventDefault(),p.removeClass("drop-before"),p.removeClass("drop-after");let C=parseInt(m.dataTransfer?.getData("text/plain")??"",10);if(!Number.isFinite(C)||C===i)return;let B=p.getBoundingClientRect(),E=m.clientY-B.top<B.height/2;this.reorderPin(C,E?i:i+1)});let f=p.createSpan({cls:"stashpad-pinned-toggle"});A&&(Ht(f,c,h),f.onclick=m=>{m.stopPropagation();let C=`${t.folder}|${t.id}`;this.expanded.has(C)?this.expanded.delete(C):this.expanded.add(C),this.render()});let u=p.createSpan({cls:"stashpad-pinned-icon"});(0,re.setIcon)(u,A?"folder-tree":"file-text"),a&&(u.style.color=a);let g=p.createSpan({cls:"stashpad-pinned-label",text:o});g.onclick=()=>this.openPinFromPanel(t);let I=t.folder.split("/").pop()||t.folder;if(p.createSpan({cls:"stashpad-pinned-folder",text:I}),p.oncontextmenu=m=>{m.preventDefault();let C=new re.Menu;C.addItem(B=>B.setTitle("Unpin from sidebar").setIcon("pin-off").onClick(()=>{this.plugin.unpinNote(t)})),C.showAtMouseEvent(m)},A&&h){let m=e.createDiv({cls:"stashpad-pinned-children"});this.renderPinnedSubtree(m,t.folder,t.id,1)}}async reorderPin(e,t){let i=this.plugin.listPinnedNotes();if(e<0||e>=i.length)return;let s=i[e],n=i.filter((A,h)=>h!==e),o=Math.max(0,Math.min(t>e?t-1:t,n.length)),a=n[o-1],l=n[o],c;!a&&!l?c=Date.now():a?l?c=(a.pinnedAt+l.pinnedAt)/2:c=a.pinnedAt+1e3:c=l.pinnedAt-1e3;try{await this.app.fileManager.processFrontMatter(s.file,A=>{A.pinnedAt=c})}catch(A){console.warn("[Stashpad] pin reorder failed",A)}this.render()}renderPinnedSubtree(e,t,i,s){let n=this.childrenOf(t,i);for(let o of n){let a=this.app.metadataCache.getFileCache(o)?.frontmatter??{},l=typeof a.id=="string"?a.id:null;if(!l)continue;let c=typeof a.color=="string"?a.color:null,A=a.completed===!0,h=this.childrenOf(t,l).length,p=h>0,f=this.expanded.has(`${t}|${l}`),u=e.createDiv({cls:"stashpad-pinned-subrow"});A&&u.addClass("is-completed"),u.style.paddingLeft=`${s*16}px`;let g=u.createSpan({cls:"stashpad-pinned-toggle"});p&&(Ht(g,h,f),g.onclick=C=>{C.stopPropagation();let B=`${t}|${l}`;this.expanded.has(B)?this.expanded.delete(B):this.expanded.add(B),this.render()});let I=u.createSpan({cls:"stashpad-pinned-icon"});(0,re.setIcon)(I,"file-text"),c&&(I.style.color=c);let m=u.createSpan({cls:"stashpad-pinned-label",text:this.titleFromFile(o)});m.onclick=()=>this.openPinFromPanel({folder:t,id:l}),p&&f&&this.renderPinnedSubtree(e,t,l,s+1)}}findFileFor(e){for(let t of this.app.vault.getMarkdownFiles()){if((t.parent?.path?.replace(/\/+$/,"")??"")!==e.folder)continue;if(this.app.metadataCache.getFileCache(t)?.frontmatter?.id===e.id)return t}return null}childrenOf(e,t){let i=[];for(let s of this.app.vault.getMarkdownFiles()){if((s.parent?.path?.replace(/\/+$/,"")??"")!==e)continue;let o=this.app.metadataCache.getFileCache(s)?.frontmatter;if(!o||typeof o.id!="string")continue;let a=o.parent;if(a===t||t===S&&(a==null||a===S)){if(o.id===S)continue;i.push(s)}}return i.sort((s,n)=>{let o=this.app.metadataCache.getFileCache(s)?.frontmatter,a=this.app.metadataCache.getFileCache(n)?.frontmatter,l=o?.created??"",c=a?.created??"";return l.localeCompare(c)}),i}titleFromFile(e){let t=this.app.metadataCache.getFileCache(e)?.frontmatter?.id;return jo(e,typeof t=="string"?t:null)}async openSearchFromPanel(){let e=await this.resolveTargetStashpad();e&&typeof e.openSearchModal=="function"&&e.openSearchModal()}async openLogFromPanel(){let e=this.app.vault.adapter,t=this.plugin.pluginPrivatePath("log.jsonl");if(!await e.exists(t)){new re.Notice("No log yet \u2014 make some changes first.");return}let i=await e.read(t),{LogModal:s}=await Promise.resolve().then(()=>(ve(),ms));new s(this.app,i,t).open()}openNotificationsFromPanel(){this.app.commands?.executeCommandById?.("stashpad:stashpad-open-notification-history")}async openHomeFromPanel(){let e=await this.resolveTargetStashpad();e&&typeof e.navigateTo=="function"&&e.navigateTo(S)}async openPinFromPanel(e){await this.plugin.revealNoteByRef(e.folder,e.id)}async resolveTargetStashpad(){let e=this.plugin.lastActiveStashpadLeaf;if(e&&e.view.getViewType()===z)return this.app.workspace.revealLeaf(e),e.view;let t=this.findActiveStashpad();if(t)return t;let i=this.app.workspace.getLeavesOfType(z);return i.length>0?(this.app.workspace.revealLeaf(i[0]),i[0].view):(await this.plugin.activateView({reveal:!0}),this.findActiveStashpad())}findActiveStashpad(){let e=this.app.workspace.activeLeaf;return e&&e.view.getViewType()===z?e.view:null}renderSharedPanel(e){let t=e.createDiv({cls:"stashpad-panel-shared"}),i=(this.plugin.settings.authorId??"").trim();if(!i){t.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 A of s){let h=A.authorId;h&&!n.has(h)&&n.set(h,A.authorDisplay||h)}let o=t.createDiv({cls:"stashpad-shared-filters"}),a=(A,h,p)=>{let f=o.createEl("button",{cls:"stashpad-shared-chip",text:A});return h&&f.addClass("is-active"),f.onclick=p,f};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 A=o.createEl("select",{cls:"stashpad-shared-author-select"}),h=A.createEl("option",{text:"Any author"});h.value="__any__";for(let[f,u]of n){let g=A.createEl("option",{text:u});g.value=f}let p=["all","mine","others"].includes(this.sharedAuthorFilter)?"__any__":this.sharedAuthorFilter;A.value=p,A.onchange=()=>{let f=A.value;f==="__any__"?this.sharedAuthorFilter="all":this.sharedAuthorFilter=f,this.render()}}let l=o.createEl("button",{cls:"stashpad-shared-chip",text:"Has contributors"});this.sharedContribOnly&&l.addClass("is-active"),l.onclick=()=>{this.sharedContribOnly=!this.sharedContribOnly,this.render()};let c=s.filter(A=>{if(this.sharedContribOnly&&A.contributorCount===0)return!1;switch(this.sharedAuthorFilter){case"all":return!0;case"mine":return A.authorId===i;case"others":return A.authorId!==i;default:return A.authorId===this.sharedAuthorFilter}});if(c.length===0){t.createDiv({cls:"stashpad-shared-empty"}).setText("No shared notes match the current filters.");return}for(let A of c){let h=t.createDiv({cls:"stashpad-pinned-row stashpad-shared-row"}),p=h.createSpan({cls:"stashpad-pinned-icon"});(0,re.setIcon)(p,"users"),A.color&&(p.style.color=A.color);let f=h.createSpan({cls:"stashpad-pinned-label",text:A.title});f.onclick=()=>this.openSharedFromPanel(A.folder,A.id);let u=A.folder.split("/").pop()||A.folder;h.createSpan({cls:"stashpad-pinned-folder",text:u}),A.authorDisplay&&h.createSpan({cls:"stashpad-shared-meta"}).setText(A.authorId===i?`you \xB7 ${A.contributorCount} contributor${A.contributorCount===1?"":"s"}`:`by ${A.authorDisplay}${A.contributorCount>0?` \xB7 ${A.contributorCount} contributor${A.contributorCount===1?"":"s"}`:""}`)}}collectSharedNotes(e){let t=this.plugin.discoverStashpadFolders(),i=new Set(t),s=new Map;for(let o of this.app.vault.getMarkdownFiles()){let a=o.parent?.path?.replace(/\/+$/,"")??"";if(!i.has(a))continue;let l=this.app.metadataCache.getFileCache(o)?.frontmatter??{};l.id===S&&s.set(a,this.extractAuthorId(l.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 l=this.app.metadataCache.getFileCache(o)?.frontmatter??{};if(typeof l.id!="string"||l.id===S)continue;let c=this.extractAuthorId(l.author),A=Array.isArray(l.contributors)?l.contributors.filter(C=>typeof C=="string"):[],h=s.get(a)??null;if(!(A.length>0||h===e&&(c!==null&&c!==e)))continue;let I=this.titleFromFile(o),m=typeof l.color=="string"?l.color:null;n.push({file:o,folder:a,id:l.id,title:I,color:m,authorId:c,authorDisplay:this.extractAuthorDisplay(l.author)||(c??""),contributorCount:A.length})}return n.sort((o,a)=>{let l=this.app.metadataCache.getFileCache(o.file)?.frontmatter??{},c=this.app.metadataCache.getFileCache(a.file)?.frontmatter??{},A=l.modified??l.created??"";return(c.modified??c.created??"").localeCompare(A)}),n}extractAuthorId(e){if(typeof e!="string")return null;let t=e.match(/-([a-z0-9]{4,12})(?:\.md)?(?:\||\]\])/i);return t?t[1]:null}extractAuthorDisplay(e){if(typeof e!="string")return"";let t=e.match(/\|([^\]]+)\]\]/);if(t)return t[1].trim();let i=e.match(/_authors\/([^\]|]+)-[a-z0-9]{4,12}/i);return i?i[1].replace(/[-_]/g," ").trim():""}async openSharedFromPanel(e,t){await this.plugin.revealNoteByRef(e,t)}renderTasksPanel(e){let t=e.createDiv({cls:"stashpad-panel-tasks"}),s=t.createDiv({cls:"stashpad-task-review-bar"}).createEl("button",{cls:"stashpad-task-review-open"});(0,re.setIcon)(s.createSpan({cls:"stashpad-btn-icon"}),"maximize-2"),s.createSpan({text:"Daily review"}),s.onclick=()=>new Di(this.app,this.plugin).open();let n=this.collectTasks();if(n.length===0){t.createDiv({cls:"stashpad-tasks-empty"}).setText("No tasks yet \u2014 press G on a note to mark it a task, or D to give it a due date.");return}let o=(this.plugin.settings.authorId??"").trim(),a=T=>!!o&&T.assignedTo.some(b=>b.id===o),l=T=>{let b=this.taskAssignFilter;if(b.startsWith("person:")){let M=b.slice(7);return T.assignedTo.some(O=>O.id===M)}switch(b){case"mine":return a(T);case"others":return T.assignedTo.length>0&&!a(T);case"byme":return!!o&&T.assignedBy?.id===o;case"unassigned":return T.assignedTo.length===0;default:return!0}},c=new Map;for(let T of n){for(let b of T.assignedTo)b.id!==o&&c.set(b.id,b.name);T.assignedBy&&T.assignedBy.id!==o&&c.set(T.assignedBy.id,T.assignedBy.name)}let A=[...c.entries()].map(([T,b])=>({id:T,name:b})).sort((T,b)=>T.name.localeCompare(b.name)),h=t.createDiv({cls:"stashpad-task-assign-bar"});h.createSpan({cls:"stashpad-task-assign-label",text:"Assignment"});let p=h.createEl("select",{cls:"stashpad-task-assign-select"}),f=T=>{let b={all:"Everyone",mine:"Assigned to me",others:"Assigned to others",byme:"Assigned by me",unassigned:"Unassigned"};return T.startsWith("person:")?c.get(T.slice(7))??"Person":b[T]??T},u=T=>{let b=p.createEl("option",{text:f(T),value:T});this.taskAssignFilter===T&&(b.selected=!0)};for(let T of["all","mine","others","byme","unassigned"])u(T);if(A.length>0){let T=p.createEl("optgroup");T.setAttr("label","By person");for(let b of A){let M=T.createEl("option",{text:b.name,value:`person:${b.id}`});this.taskAssignFilter===`person:${b.id}`&&(M.selected=!0)}}p.onchange=()=>{this.taskAssignFilter=p.value,this.render()};let g=[...new Set(n.map(T=>T.folder))].sort((T,b)=>T.localeCompare(b));this.taskFolderFilter!=="all"&&!g.includes(this.taskFolderFilter)&&(this.taskFolderFilter="all");let I=t.createDiv({cls:"stashpad-task-assign-bar"});I.createSpan({cls:"stashpad-task-assign-label",text:"Folder"});let m=I.createEl("select",{cls:"stashpad-task-assign-select"}),C=m.createEl("option",{text:"All folders",value:"all"});this.taskFolderFilter==="all"&&(C.selected=!0);for(let T of g){let b=m.createEl("option",{text:T.split("/").pop()||T,value:T});this.taskFolderFilter===T&&(b.selected=!0)}m.onchange=()=>{this.taskFolderFilter=m.value,this.render()};let B=T=>this.taskFolderFilter==="all"||T.folder===this.taskFolderFilter,E=n.filter(T=>l(T)&&B(T));if(E.length===0){t.createDiv({cls:"stashpad-tasks-empty"}).setText("No tasks match the current filters.");return}let y=new Date;y.setHours(0,0,0,0);let v=y.getTime(),Q=v+24*60*60*1e3,w={overdue:[],today:[],upcoming:[],nodate:[],completed:[]};for(let T of E){if(T.completed){w.completed.push(T);continue}if(T.due==null){w.nodate.push(T);continue}T.due<v?w.overdue.push(T):T.due<Q?w.today.push(T):w.upcoming.push(T)}let F=(T,b)=>T.due==null&&b.due==null?T.title.localeCompare(b.title):T.due==null?1:b.due==null?-1:T.due-b.due,D=[{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"}],H=t.createDiv({cls:"stashpad-task-filters"}),R=E.length,L=(T,b,M)=>{let O=H.createEl("button",{cls:"stashpad-task-filter"});this.taskFilter===T&&O.addClass("is-active"),O.createSpan({cls:"stashpad-task-filter-label",text:b}),O.createSpan({cls:"stashpad-task-filter-count",text:String(M)}),O.onclick=()=>{this.taskFilter=T,this.render()}};L("all","All",R),L("overdue","Overdue",w.overdue.length),L("today","Today",w.today.length),L("upcoming","Upcoming",w.upcoming.length),L("nodate","No date",w.nodate.length),L("completed","Done",w.completed.length);let x=this.taskFilter==="all"?D:D.filter(T=>T.key===this.taskFilter),U=!1;for(let T of x){let b=w[T.key];if(b.length!==0){if(U=!0,b.sort(T.key==="completed"?(M,O)=>F(O,M):F),this.taskFilter==="all"){let M=t.createDiv({cls:`stashpad-task-section-header is-${T.key}`});(0,re.setIcon)(M.createSpan({cls:"stashpad-task-section-icon"}),T.icon),M.createSpan({cls:"stashpad-task-section-name",text:T.label}),M.createSpan({cls:"stashpad-task-section-count",text:String(b.length)})}for(let M of b)this.renderTaskRow(t,M,T.key==="today")}}if(!U&&this.taskFilter!=="all"){t.createDiv({cls:"stashpad-tasks-empty"}).setText(`Nothing in "${x[0]?.label??this.taskFilter}".`);return}U||t.createDiv({cls:"stashpad-tasks-empty"}).setText("No tasks to show.")}renderTaskRow(e,t,i){let s=e.createDiv({cls:"stashpad-pinned-row stashpad-task-row"});t.color&&s.addClass("has-color"),t.completed&&s.addClass("is-completed");let n=s.createSpan({cls:"stashpad-pinned-icon stashpad-task-checkbox"});(0,re.setIcon)(n,t.completed?"check-square":"square"),t.color&&(n.style.color=t.color),n.title=t.completed?"Mark not done":"Mark done",n.onclick=l=>{l.stopPropagation(),this.toggleTaskCompleted(t)};let o=s.createSpan({cls:"stashpad-pinned-label",text:t.title});if(o.onclick=()=>this.openTaskFromPanel(t.folder,t.id),s.createSpan({cls:"stashpad-task-folder",text:t.folder.split("/").pop()||t.folder}),t.due!=null){let l=s.createSpan({cls:"stashpad-task-due",text:this.formatDueShort(t.due,i)});t.due<Date.now()&&!t.completed&&l.addClass("is-overdue")}else t.dueRaw&&s.createSpan({cls:"stashpad-task-due",text:t.dueRaw});if(t.assignedTo.length>0){let l=(this.plugin.settings.authorId??"").trim(),c=s.createSpan({cls:"stashpad-task-assignees"});for(let A of t.assignedTo){let h=c.createSpan({cls:"stashpad-task-assignee"});l&&A.id===l&&h.addClass("is-me"),h.setText(this.initials(A.name)),h.title=l&&A.id===l?`${A.name} (you)`:A.name}}let a=s.createEl("button",{cls:"stashpad-task-snooze"});(0,re.setIcon)(a,"alarm-clock"),a.title="Snooze \u2014 reschedule due date",a.onclick=l=>{l.stopPropagation(),this.snoozeTask(t)},s.oncontextmenu=l=>{l.preventDefault();let c=new re.Menu;c.addItem(A=>A.setTitle("Open").setIcon("arrow-right").onClick(()=>{this.openTaskFromPanel(t.folder,t.id)})),c.addItem(A=>A.setTitle("Snooze (reschedule)\u2026").setIcon("alarm-clock").onClick(()=>{this.snoozeTask(t)})),c.showAtMouseEvent(l)}}snoozeTask(e){let t=e.dueRaw??(e.due!=null?new Date(e.due).toISOString():null);new ze(this.app,t,i=>{this.app.fileManager.processFrontMatter(e.file,s=>{i.iso===null?delete s.due:(s.due=i.iso,s.task=!0)}).then(()=>this.scheduleRender()).catch(s=>new re.Notice(`Couldn't snooze: ${s.message}`))},{title:"Snooze \u2014 reschedule",hideAssignees:!0,quickAdjusts:this.plugin.settings.dueQuickAdjusts}).open()}formatDueShort(e,t){return t?Ai(e,this.plugin.settings):Nt(e,this.plugin.settings)}async openTaskFromPanel(e,t){await this.plugin.revealNoteByRef(e,t)}async toggleTaskCompleted(e){try{await this.app.fileManager.processFrontMatter(e.file,t=>{t.completed=t.completed!==!0})}catch(t){new re.Notice(`Couldn't update task: ${t.message}`);return}this.scheduleRender()}initials(e){let t=e.trim().split(/\s+/).filter(Boolean);return t.length===0?"?":t.length===1?t[0].slice(0,2).toUpperCase():(t[0][0]+t[t.length-1][0]).toUpperCase()}collectTasks(){return In(this.app,this.plugin)}};async function Bn(d){let r=d.workspace.getLeavesOfType(St);if(r.length>0){d.workspace.revealLeaf(r[0]);return}let e=d.workspace.getLeftLeaf(!1);if(!e){new re.Notice("Stashpad: couldn't open the panels view.");return}await e.setViewState({type:St,active:!0}),d.workspace.revealLeaf(e)}un();Tt();ce();function Jr(d){return/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(d)}var yn=class extends Qe.ItemView{constructor(e,t){super(e);this.plugin=t;this.displayedPath=null;this.bodyComponent=null;this.unsubscribeSelection=null;this.renderTimer=null;this.renderToken=0;this.expanded=new Set;this.composerAutocomplete=null;this.composerInputEl=null;this.composerDraft="";this.composerDraftForId=null;this.displayedId=null;this.unsubscribeContent=null}getViewType(){return Kt}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",e=>{!e||e===this.leaf||e.view?.getViewType?.()===z&&this.scheduleRender()})),this.registerEvent(this.app.vault.on("modify",e=>{this.displayedPath&&e.path===this.displayedPath&&this.scheduleRender()})),this.registerEvent(this.app.vault.on("rename",(e,t)=>{this.displayedPath&&t===this.displayedPath&&(this.displayedPath=e.path,this.scheduleRender())})),this.registerEvent(this.app.metadataCache.on("changed",e=>{this.displayedPath&&e.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 i=this.plugin.lastActiveStashpadLeaf?.view;if(i?.getViewType?.()===z&&i.tree?.get){let s=i.tree.get(this.displayedId);if(s?.file)return{folder:i.noteFolder,id:this.displayedId,file:s.file}}this.displayedId=null}let e=this.plugin.getActiveStashpadSelection();if(e)return this.displayedId=e.id,e;let t=this.plugin.lastActiveStashpadLeaf?.view;if(t?.getViewType?.()===z&&t.tree?.get&&t.focusId){let i=t.tree.get(t.focusId);if(i?.file)return{folder:t.noteFolder,id:t.focusId,file:i.file}}return null}async render(){let e=++this.renderToken,t=this.contentEl,i=!!this.composerInputEl&&document.activeElement===this.composerInputEl,s=this.composerInputEl?.selectionStart??null;this.composerAutocomplete?.detach(),this.composerAutocomplete=null,this.composerInputEl=null,t.empty(),t.addClass("stashpad-detail-root");let n=this.resolveDisplayed();if(!n){this.displayedPath=null;let g=t.createDiv({cls:"stashpad-detail-empty"});(0,Qe.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 o=n.file;this.displayedPath=o.path;let a=this.app.metadataCache.getFileCache(o)?.frontmatter??{},l=t.createDiv({cls:"stashpad-detail-scroll"}),c=l.createDiv({cls:"stashpad-detail-header"}),A=c.createDiv({cls:"stashpad-detail-titlerow"});A.createDiv({cls:"stashpad-detail-title",text:this.titleFor(o)});let h=A.createEl("button",{cls:"stashpad-detail-open-btn",attr:{"aria-label":"Open in Stashpad tab"}});(0,Qe.setIcon)(h,"arrow-up-right"),h.title="Open this note in a new Stashpad tab",h.onclick=()=>{this.openInStashpad(n.folder,n.id)};let p=c.createDiv({cls:"stashpad-detail-metarow"});if(n.folder&&p.createSpan({cls:"stashpad-detail-meta-chip",text:n.folder.split("/").pop()||n.folder}),typeof a.color=="string"&&Jr(a.color)){let g=p.createSpan({cls:"stashpad-detail-meta-color"});g.style.background=a.color,g.title=a.color}if(a.completed===!0&&p.createSpan({cls:"stashpad-detail-meta-chip is-completed",text:"\u2713 completed"}),typeof a.due=="string"||typeof a.due=="number"){let g=Date.parse(String(a.due)),I=Number.isNaN(g)?String(a.due):it(g,this.plugin.settings);p.createSpan({cls:"stashpad-detail-meta-chip is-due",text:`due ${I}`})}if(Array.isArray(a.tags))for(let g of a.tags.filter(I=>typeof I=="string"))p.createSpan({cls:"stashpad-detail-meta-tag",text:`#${g.replace(/^#/,"")}`});let f=l.createDiv({cls:"stashpad-detail-body"});try{let g=await this.app.vault.cachedRead(o),I=this.stripFrontmatter(g);this.bodyComponent&&(this.removeChild(this.bodyComponent),this.bodyComponent=null);let m=new Qe.Component;this.addChild(m),this.bodyComponent=m,await Qe.MarkdownRenderer.render(this.app,I,f,o.path,m)}catch(g){f.createDiv({cls:"stashpad-detail-error",text:`Couldn't read \`${o.path}\`: ${g.message}`})}if(e!==this.renderToken)return;this.renderFooterMeta(l,o,a,n),this.renderChildren(l,n.folder,n.id),this.renderComposer(t,n);let u=this.composerInputEl;if(i&&u&&(u.focus(),s!=null)){let g=Math.min(s,u.value.length);try{u.setSelectionRange(g,g)}catch{}}}renderComposer(e,t){let i=e.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===t.id?s.value=this.composerDraft:(this.composerDraft="",this.composerDraftForId=t.id),s.addEventListener("input",()=>{this.composerDraft=s.value,this.composerDraftForId=t.id}),s.addEventListener("keydown",o=>{if(o.key==="Enter"&&!o.shiftKey&&!o.isComposing){if(this.composerAutocomplete?.isOpen?.())return;o.preventDefault(),this.submitComposer(t)}});let n=i.createEl("button",{cls:"stashpad-detail-composer-send",attr:{"aria-label":"Add child note"}});(0,Qe.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(t),this.composerAutocomplete=new Pt(this.app,s),this.composerAutocomplete.attach()}async submitComposer(e){let t=(this.composerInputEl?.value??"").trim();if(!t)return;let i=this.plugin.lastActiveStashpadLeaf?.view;if(!i||i.getViewType?.()!==z||typeof i.createNoteUnder!="function"){new Qe.Notice("Open a Stashpad view to add notes.");return}try{await i.createNoteUnder(t,e.id)}catch(s){new Qe.Notice(`Couldn't add note: ${s.message}`);return}this.composerDraft="",this.composerDraftForId=e.id,this.composerInputEl&&(this.composerInputEl.value=""),await this.render(),setTimeout(()=>this.composerInputEl?.focus(),0)}renderChildren(e,t,i){let s=this.plugin.lastActiveStashpadLeaf?.view;if(!s||s.getViewType?.()!==z)return;let n=s.tree;if(!n?.getChildren)return;let o=n.getChildren(i);if(!o||o.length===0)return;let a=e.createDiv({cls:"stashpad-detail-children"});a.createDiv({cls:"stashpad-detail-children-header",text:`Children (${o.length})`});let l=a.createDiv({cls:"stashpad-detail-children-list"});for(let c of o)c.file&&this.renderDetailChildRow(l,s,n,t,c,0)}renderDetailChildRow(e,t,i,s,n,o,a=new Set){if(!n.file||a.has(n.id))return;let l=this.app.metadataCache.getFileCache(n.file)?.frontmatter??{},c=typeof l.color=="string"&&Jr(l.color)?l.color:null,A=l.completed===!0,h=i.getChildren(n.id),p=h.length>0,f=`${s}|${n.id}`,u=this.expanded.has(f),g=e.createDiv({cls:"stashpad-detail-child-row"});A&&g.addClass("is-completed"),o>0&&(g.style.paddingLeft=`${o*16}px`),g.draggable=!0,g.dataset.id=n.id,g.addEventListener("dragstart",E=>{E.dataTransfer?.setData("text/plain",n.id),E.dataTransfer&&(E.dataTransfer.effectAllowed="move"),g.addClass("is-dragging")}),g.addEventListener("dragend",()=>g.removeClass("is-dragging")),g.addEventListener("dragover",E=>{E.preventDefault(),E.dataTransfer&&(E.dataTransfer.dropEffect="move");let y=g.getBoundingClientRect(),v=E.clientY-y.top<y.height/2;g.toggleClass("drop-before",v),g.toggleClass("drop-after",!v)}),g.addEventListener("dragleave",()=>{g.removeClass("drop-before"),g.removeClass("drop-after")}),g.addEventListener("drop",E=>{E.preventDefault(),g.removeClass("drop-before"),g.removeClass("drop-after");let y=E.dataTransfer?.getData("text/plain");if(!y||y===n.id)return;let v=g.getBoundingClientRect(),Q=E.clientY-v.top<v.height/2;typeof t.reorderToTarget=="function"&&t.reorderToTarget([y],n.id,Q?"before":"after")}),g.oncontextmenu=E=>{E.preventDefault();let y=i.get(n.id);y&&typeof t.openNoteMenu=="function"&&t.openNoteMenu(E,y)};let I=g.createSpan({cls:"stashpad-detail-child-toggle"});if(p&&(Ht(I,h.length,u),I.onclick=E=>{E.stopPropagation(),this.expanded.has(f)?this.expanded.delete(f):this.expanded.add(f),this.render()}),di(l,"task")||l.task===!0||l.completed!==void 0){let E=g.createSpan({cls:"stashpad-detail-child-checkbox"});(0,Qe.setIcon)(E,A?"check-square":"square"),E.title=A?"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 t.toggleCompletedForNode=="function"&&t.toggleCompletedForNode(v)}}let C=g.createSpan({cls:"stashpad-detail-child-icon"});(0,Qe.setIcon)(C,p?"folder-tree":"file-text"),c&&(C.style.color=c);let B=g.createSpan({cls:"stashpad-detail-child-title",text:this.titleFor(n.file)});if(B.onclick=()=>{t?.navigateTo&&t.navigateTo(n.id)},p&&u){let E=new Set(a).add(n.id);for(let y of h)this.renderDetailChildRow(e,t,i,s,y,o+1,E)}}renderFooterMeta(e,t,i,s){let n=e.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(l=>typeof l=="string").map(l=>this.stripWikiLink(l));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:t.path}),o.push({label:"ID",value:s.id}),o.length===0){n.remove();return}for(let a of o){let l=n.createDiv({cls:"stashpad-detail-meta-line"});l.createSpan({cls:"stashpad-detail-meta-key",text:a.label}),l.createSpan({cls:"stashpad-detail-meta-val",text:a.value})}}titleFor(e){return e.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ")}stripFrontmatter(e){if(!e.startsWith("---"))return e;let t=e.indexOf(` ----`,3);return t<0?e:e.slice(t+4).replace(/^\n+/,"")}stripWikiLink(e){let t=e.match(/^\[\[(.+?)(?:\|(.+))?\]\]$/);return t?t[2]??(t[1].split("/").pop()??t[1]).replace(/\.md$/,""):e}formatTime(e){let t=Date.parse(e);return Number.isFinite(t)?it(t,this.plugin.settings):e}async openInStashpad(e,t){try{let i=await this.plugin.activateViewForFolder(e);t!==S&&this.plugin.navigateLeafTo(i,e,t)}catch(i){new Qe.Notice(`Couldn't open: ${i.message}`)}}};async function wn(d){let r=d.workspace.getLeavesOfType(Kt);if(r.length>0){d.workspace.revealLeaf(r[0]);return}let e=d.workspace.getRightLeaf(!1);if(!e){new Qe.Notice("Stashpad: couldn't open the detail panel.");return}await e.setViewState({type:Kt,active:!0}),d.workspace.revealLeaf(e)}var k=require("obsidian");ce();var Rt=require("obsidian");ce();function ad(d,r){let e=d.vault.getAbstractFileByPath(r);if(!(e instanceof Rt.TFolder))return[];let t=[],i=[e];for(;i.length;){let s=i.pop();for(let n of s.children)n instanceof Rt.TFile?n.extension==="md"&&t.push(n):n instanceof Rt.TFolder&&(za(n.name)||i.push(n))}return t}var En=class{constructor(r){this.app=r;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(S,{id:S,parent:null,children:[],file:null,created:""})}setOrderProvider(r){this.orderProvider=r}onChange(r){return this.listeners.add(r),()=>this.listeners.delete(r)}emit(){for(let r of this.listeners)r()}rebuild(r){r!==void 0&&(this.currentFolder=r);let e=this.currentFolder,t=this.byPath,i=this.nodes;this.nodes=new Map,this.byPath=new Map,this.nodes.set(S,{id:S,parent:null,children:[],file:null,created:""});let s=e?ad(this.app,e):this.app.vault.getMarkdownFiles();for(let n of s){let o=this.app.metadataCache.getFileCache(n)?.frontmatter,a=o?.id;if(!a){let c=t.get(n.path),A=c?i.get(c):void 0,h=this.synthetic.get(n.path),p=A??h;p&&(this.nodes.set(p.id,{...p,children:[],file:n}),this.byPath.set(n.path,p.id));continue}if(this.synthetic.delete(n.path),a===S){let c=this.nodes.get(S);c.file=n,c.created=o?.created??"",this.byPath.set(n.path,S);continue}let l=o?.parent??null;l===a&&(l=null),this.nodes.set(a,{id:a,parent:l??S,children:[],file:n,created:o?.created??""}),this.byPath.set(n.path,a)}for(let n of this.nodes.values()){if(n.id===S)continue;let o=new Set([n.id]),a=n.parent??S;for(;a!==S&&this.nodes.has(a);){if(o.has(a)){n.parent=S;break}o.add(a),a=this.nodes.get(a).parent??S}}for(let n of this.nodes.values()){if(n.id===S)continue;let o=n.parent??S;(this.nodes.get(o)??this.nodes.get(S)).children.push(n.id)}for(let n of this.nodes.values())if(n.children.sort((o,a)=>{let l=this.nodes.get(o),c=this.nodes.get(a);return(l.created||"").localeCompare(c.created||"")}),this.orderProvider){let o=this.orderProvider(n.id);if(o.length>0){let a=new Map;o.forEach((l,c)=>a.set(l,c)),n.children.sort((l,c)=>{let A=a.has(l)?a.get(l):1/0,h=a.has(c)?a.get(c):1/0;return A===h?0:A-h})}}this.emit()}insertSynthetic(r){if(!r.file)return;let e=r.file.path;this.synthetic.set(e,r),this.nodes.set(r.id,r),this.byPath.set(e,r.id);let t=r.parent??S,i=this.nodes.get(t);i&&!i.children.includes(r.id)&&i.children.push(r.id),this.emit()}get(r){return this.nodes.get(r)}getRoot(){return this.nodes.get(S)}getChildren(r){let e=this.nodes.get(r);return e?e.children.map(t=>this.nodes.get(t)).filter(t=>!!t):[]}fileBackedCount(){let r=0;for(let e of this.nodes.values())e.file&&r++;return r}pathTo(r){let e=[],t=new Set,i=this.nodes.get(r);for(;i&&i.id!==S&&!t.has(i.id);)t.add(i.id),e.unshift(i),i=i.parent?this.nodes.get(i.parent):void 0;return e}idForPath(r){return this.byPath.get(r)}snapshot(){let r={};for(let e of this.nodes.values())e.id===S||!e.file||(r[e.id]={parent:e.parent===S?null:e.parent,path:e.file.path});return r}hookMetadataCache(r){let e=l=>{let c=this.currentFolder;return c?typeof l!="string"?!1:l===c||l.startsWith(c+"/"):!0},t=!1,i=()=>{t=!0,this.coalesceTimer==null&&(this.coalesceTimer=window.setTimeout(()=>{this.coalesceTimer=null,t&&(t=!1,this.emit(),r())},16))},s=l=>{l instanceof Rt.TFile&&e(l.path)&&l.extension==="md"&&(this.applyChange(l),i())},n=l=>{l instanceof Rt.TFile&&e(l.path)&&l.extension==="md"&&this.applyChange(l)&&i()},o=l=>{let c=l?.path;typeof c=="string"&&e(c)&&this.applyDelete(c)&&i()},a=(l,c)=>{if(!(l instanceof Rt.TFile))return;let A=typeof c=="string"?c:null;!e(l.path)&&!e(A)||this.applyRename(l,A??"")&&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(r){if(qt(r.path))return this.byPath.has(r.path)?this.applyDelete(r.path):!1;let e=this.app.metadataCache.getFileCache(r)?.frontmatter,t=e?.id,i=this.byPath.get(r.path);if(!t){if(i){let c=this.nodes.get(i);if(c&&c.file!==r)return c.file=r,!0}return!1}if(this.synthetic.delete(r.path),t===S){let c=this.nodes.get(S),A=e?.created??"",h=!1;return c.file!==r&&(c.file=r,h=!0),c.created!==A&&(c.created=A,h=!0),this.byPath.get(r.path)!==S&&(this.byPath.set(r.path,S),h=!0),h}let s=e?.parent??S;s===t&&(s=S);let n=e?.created??"";if(!(s===S||this.nodes.has(s)))return this.rebuild(),!0;if(i&&i!==t)return this.rebuild(),!0;let a=this.nodes.get(t);if(!a){let c={id:t,parent:s,children:[],file:r,created:n};return this.nodes.set(t,c),this.byPath.set(r.path,t),this.attachToParent(c),this.resortChildrenOf(s),!0}let l=!1;if(a.file!==r&&(a.file=r,l=!0),a.created!==n&&(a.created=n,this.resortChildrenOf(a.parent??S),l=!0),a.parent!==s){let c=a.parent??S;this.detachFromParent(a),a.parent=s,this.attachToParent(a),this.resortChildrenOf(c),this.resortChildrenOf(s),l=!0}return l}applyDelete(r){let e=this.byPath.get(r);if(!e)return!1;let t=this.nodes.get(e);if(!t)return this.byPath.delete(r),this.synthetic.delete(r),!0;this.detachFromParent(t);let i=this.nodes.get(S);for(let s of t.children){let n=this.nodes.get(s);n&&(n.parent=S,i.children.includes(s)||i.children.push(s))}return t.children.length>0&&this.resortChildrenOf(S),this.nodes.delete(e),this.byPath.delete(r),this.synthetic.delete(r),!0}applyRename(r,e){let t=this.currentFolder,i=!t||e===t||e.startsWith(t+"/"),s=!t||r.path===t||r.path.startsWith(t+"/");if(!i&&!s)return!1;if(i&&!s)return this.applyDelete(e);if(!i&&s)return this.applyChange(r);if(qt(r.path))return this.byPath.has(e)?this.applyDelete(e):!1;let n=this.byPath.get(e);if(!n)return this.applyChange(r);this.byPath.delete(e),this.byPath.set(r.path,n);let o=this.nodes.get(n);return o&&(o.file=r),!0}detachFromParent(r){let e=this.nodes.get(r.parent??S);if(!e)return;let t=e.children.indexOf(r.id);t>=0&&e.children.splice(t,1)}attachToParent(r){let e=this.nodes.get(r.parent??S);e||(e=this.nodes.get(S)),e.children.includes(r.id)||e.children.push(r.id)}resortChildrenOf(r){let e=this.nodes.get(r);if(e&&(e.children.sort((t,i)=>{let s=this.nodes.get(t),n=this.nodes.get(i);return(s.created||"").localeCompare(n.created||"")}),this.orderProvider)){let t=this.orderProvider(r);if(t.length>0){let i=new Map;t.forEach((s,n)=>i.set(s,n)),e.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 ea=class{constructor(){this.enabled=!1;this.buckets=new Map}record(r,e){if(!this.enabled)return;let t=this.buckets.get(r);t||(t={count:0,total:0,max:0},this.buckets.set(r,t)),t.count+=1,t.total+=e,e>t.max&&(t.max=e)}time(r,e){if(!this.enabled)return e();let t=performance.now();try{return e()}finally{this.record(r,performance.now()-t)}}async timeAsync(r,e){if(!this.enabled)return e();let t=performance.now();try{return await e()}finally{this.record(r,performance.now()-t)}}reset(){this.buckets.clear()}hasData(){return this.buckets.size>0}report(){let r=[...this.buckets.entries()].map(([t,i])=>({label:t,...i,avg:i.total/i.count})).sort((t,i)=>i.total-t.total);if(r.length===0)return"Stashpad perf: no samples (enable profiling, then use the app).";let e=["**Stashpad performance profile**","","| label | count | total (ms) | avg (ms) | max (ms) |","| --- | ---: | ---: | ---: | ---: |"];for(let t of r)e.push(`| \`${t.label}\` | ${t.count} | ${t.total.toFixed(0)} | ${t.avg.toFixed(1)} | ${t.max.toFixed(0)} |`);return e.join(` -`)}},Te=new ea;Tt();var Ut={min:6e4,minute:6e4,m:6e4,h:36e5,hr:36e5,hour:36e5,d:864e5,day:864e5,w:6048e5,wk:6048e5,week:6048e5};function ta(d){if(typeof d=="number")return d>0?d:null;if(!d)return null;let r=String(d).trim().toLowerCase().match(/^(\d+(?:\.\d+)?)\s*([a-z]+)?$/);if(!r)return null;let e=parseFloat(r[1]),t=(r[2]||"min").replace(/s$/,""),i=Ut[t];return i&&e>0?e*i:null}var $r=["sunday","monday","tuesday","wednesday","thursday","friday","saturday"];function Yr(d,r){let e=new Date(d),t=e.getDate();return e.setMonth(e.getMonth()+r),e.getDate()<t&&e.setDate(0),e.getTime()}function zr(d,r){let e=new Date(d);return e.setFullYear(e.getFullYear()+r),e.getTime()}function rd(d,r){let e=new Date(d);do e.setDate(e.getDate()+1);while(e.getDay()!==r);return e.getTime()}function ld(d){let r=new Date(d);do r.setDate(r.getDate()+1);while(r.getDay()===0||r.getDay()===6);return r.getTime()}function vn(d){if(!d)return null;let r=String(d).trim().toLowerCase();if(!r)return null;let e="due";/\b(when done|after completion|on completion|from completion)\b/.test(r)&&(e="completion",r=r.replace(/\b(when done|after completion|on completion|from completion)\b/g,"").trim()),r=r.replace(/^every\s+/,"").replace(/\s+/g," ").trim();let t=(n,o)=>({next:n,anchor:e,label:o});if(/^(first|1st) of (the )?month$/.test(r))return t(n=>{let o=new Date(n);return o.setMonth(o.getMonth()+1,1),o.getTime()},"first of the month");let i=$r.indexOf(r.replace(/s$/,""));if(i>=0)return t(n=>rd(n,i),`every ${$r[i]}`);if(r==="weekday"||r==="weekdays"||r==="business day"||r==="business days")return t(ld,"every weekday");if(r==="daily"||r==="day")return t(n=>n+Ut.day,"every day");if(r==="weekly"||r==="week")return t(n=>n+Ut.week,"every week");if(r==="monthly"||r==="month")return t(n=>Yr(n,1),"every month");if(r==="yearly"||r==="annually"||r==="year")return t(n=>zr(n,1),"every year");if(r==="hourly"||r==="hour")return t(n=>n+Ut.h,"every hour");let s=r.match(/^(\d+)\s*([a-z]+)$/);if(s){let n=parseInt(s[1],10),o=s[2].replace(/s$/,"");if(n>0){if(o==="day")return t(a=>a+n*Ut.day,`every ${n} days`);if(o==="week"||o==="wk")return t(a=>a+n*Ut.week,`every ${n} weeks`);if(o==="month"||o==="mo")return t(a=>Yr(a,n),`every ${n} months`);if(o==="year"||o==="yr")return t(a=>zr(a,n),`every ${n} years`);if(o==="hour"||o==="hr"||o==="h")return t(a=>a+n*Ut.h,`every ${n} hours`);if(o==="min"||o==="minute"||o==="m")return t(a=>a+n*Ut.min,`every ${n} minutes`)}}return null}function Qn(d,r,e){let t=d.anchor==="completion"?e:r??e,i=d.next(t),s=0;for(;i<=e&&s++<5e3;)i=d.next(i);if(i<=e){i=d.next(e);let n=0;for(;i<=e&&n++<5e3;)i=d.next(i)}return i}var Vr=".stashpad-order.json",xi=class{constructor(r){this.app=r;this.cache=new Map;this.pendingTimers=new Map;this.writeInFlight=new Map}async load(r){if(this.cache.has(r))return this.cache.get(r);let e=`${r}/${Vr}`,t=this.app.vault.adapter,i={};try{if(await t.exists(e)){let s=await t.read(e),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(l=>typeof l=="string")&&(i[o]=a)}}catch(s){console.warn("Stashpad: order load failed",s)}return this.cache.set(r,i),i}async save(r){this.scheduleWrite(r)}async flush(r){let e=this.pendingTimers.get(r);e!=null&&(window.clearTimeout(e),this.pendingTimers.delete(r)),await this.writeNow(r)}scheduleWrite(r){let e=this.pendingTimers.get(r);e!=null&&window.clearTimeout(e);let t=window.setTimeout(()=>{this.pendingTimers.delete(r),this.writeNow(r)},150);this.pendingTimers.set(r,t)}async writeNow(r){let t=(this.writeInFlight.get(r)??Promise.resolve()).then(()=>this.doWrite(r));this.writeInFlight.set(r,t);try{await t}finally{this.writeInFlight.get(r)===t&&this.writeInFlight.delete(r)}}async doWrite(r){let e=this.cache.get(r)??{},t=`${r}/${Vr}`,i=this.app.vault.adapter;try{if(await i.exists(t)){let n=JSON.parse(await i.read(t));if(n&&typeof n=="object"&&!Array.isArray(n))for(let[o,a]of Object.entries(n))!(o in e)&&Array.isArray(a)&&a.every(l=>typeof l=="string")&&(e[o]=a)}}catch{}let s={};for(let[n,o]of Object.entries(e))o.length>0&&(s[n]=o);this.cache.set(r,s);try{if(Object.keys(s).length===0)try{await i.remove(t)}catch{}else await i.write(t,JSON.stringify(s,null,2))}catch(n){console.warn("Stashpad: order save failed",n)}}getOrder(r,e){return this.cache.get(r)?.[e]?.slice()??[]}setOrder(r,e,t){let i=this.cache.get(r)??{};i[e]=t.slice(),this.cache.set(r,i)}appendChild(r,e,t){let i=this.cache.get(r)??{},s=i[e]??[];s.includes(t)||s.push(t),i[e]=s,this.cache.set(r,i)}removeChild(r,e){let t=this.cache.get(r);if(t)for(let i of Object.values(t)){let s=i.indexOf(e);s>=0&&i.splice(s,1)}}invalidate(r){this.cache.delete(r)}};var Ni={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"},ia=["manual","created-asc","created-desc","modified-asc","modified-desc","title-az","title-za"],Wr=new Set(ia),Xr=".stashpad-sort.json",Fn=class{constructor(r){this.app=r;this.cache=new Map;this.pendingTimers=new Map;this.writeInFlight=new Map}async load(r){if(this.cache.has(r))return this.cache.get(r);let e=`${r}/${Xr}`,t=this.app.vault.adapter,i={};try{if(await t.exists(e)){let s=JSON.parse(await t.read(e));if(s&&typeof s=="object"&&!Array.isArray(s))for(let[n,o]of Object.entries(s))typeof o=="string"&&Wr.has(o)&&(i[n]=o)}}catch(s){console.warn("Stashpad: sort load failed",s)}return this.cache.set(r,i),i}async save(r){this.scheduleWrite(r)}async flush(r){let e=this.pendingTimers.get(r);e!=null&&(window.clearTimeout(e),this.pendingTimers.delete(r)),await this.writeNow(r)}scheduleWrite(r){let e=this.pendingTimers.get(r);e!=null&&window.clearTimeout(e);let t=window.setTimeout(()=>{this.pendingTimers.delete(r),this.writeNow(r)},150);this.pendingTimers.set(r,t)}async writeNow(r){let t=(this.writeInFlight.get(r)??Promise.resolve()).then(()=>this.doWrite(r));this.writeInFlight.set(r,t);try{await t}finally{this.writeInFlight.get(r)===t&&this.writeInFlight.delete(r)}}async doWrite(r){let e=this.cache.get(r)??{},t=`${r}/${Xr}`,i=this.app.vault.adapter;try{if(await i.exists(t)){let s=JSON.parse(await i.read(t));if(s&&typeof s=="object"&&!Array.isArray(s))for(let[n,o]of Object.entries(s))!(n in e)&&typeof o=="string"&&Wr.has(o)&&(e[n]=o)}}catch{}try{if(Object.keys(e).length===0)try{await i.remove(t)}catch{}else await i.write(t,JSON.stringify(e,null,2))}catch(s){console.warn("Stashpad: sort save failed",s)}}getMode(r,e){return this.cache.get(r)?.[e]??"manual"}setMode(r,e,t){let i=this.cache.get(r)??{};t==="manual"?delete i[e]:i[e]=t,this.cache.set(r,i)}removeParent(r,e){let t=this.cache.get(r);t&&delete t[e]}invalidate(r){this.cache.delete(r)}};ce();Qi();var Lt="parentLink",Mi="children";var Ti=class Ti{constructor(r,e){this.app=r;this.getTree=e;this.pending=new Set;this.timer=null;this.activityListeners=new Set;this.recentSelfWrites=new Map;this.errorListeners=new Set}onActivity(r){return this.activityListeners.add(r),()=>this.activityListeners.delete(r)}emitActivity(){let r=this.pending.size;for(let e of this.activityListeners)try{e(r)}catch(t){console.warn("[Stashpad] fmSync activity listener failed",t)}}wasRecentSelfWrite(r){let e=this.recentSelfWrites.get(r);return e==null?!1:(this.recentSelfWrites.delete(r),Date.now()-e<Ti.SELF_WRITE_GRACE_MS)}schedule(r){if(!r||!X().writeRecoveryLinks)return;let e=this.pending.size;this.pending.add(r),this.pending.size!==e&&this.emitActivity(),this.kick()}scheduleParentChange(r,e,t){this.schedule(r),e&&this.schedule(e),this.schedule(t)}scheduleSubtree(r){let e=this.getTree(),t=i=>{this.schedule(i);for(let s of e.getChildren(i))t(s.id)};t(r)}scheduleParentOfDeleted(r){r&&this.schedule(r)}async flush(){for(this.timer!=null&&(window.clearTimeout(this.timer),this.timer=null);this.pending.size>0;){let r=this.pending.values().next().value;if(r===void 0)break;this.pending.delete(r),this.emitActivity(),await this.syncOne(r)}}pendingCount(){return this.pending.size}onError(r){return this.errorListeners.add(r),()=>this.errorListeners.delete(r)}emitError(r,e){for(let t of this.errorListeners)try{t(r,e)}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 r=this.pending.values().next().value;if(r!==void 0){this.pending.delete(r),this.emitActivity();try{await this.syncOne(r)}catch(e){console.warn("[Stashpad] frontmatter sync tick failed",e)}this.pending.size>0&&this.kick()}}wouldWrite(r){let t=this.getTree().get(r);if(!t||!t.file)return!1;let i=this.computeParentLink(t),s=this.computeChildrenLinks(t),n=this.app.metadataCache.getFileCache(t.file)?.frontmatter,o=n&&typeof n[Lt]=="string"?n[Lt]:null,a=n?.[Mi],l=Array.isArray(a)?a.filter(c=>typeof c=="string"):[];if((o??null)!==(i??null)||l.length!==s.length)return!0;for(let c=0;c<l.length;c++)if(l[c]!==s[c])return!0;return!1}async syncOne(r){let t=this.getTree().get(r);if(!t||!t.file||!this.wouldWrite(r))return;let i=this.computeParentLink(t),s=this.computeChildrenLinks(t);try{this.recentSelfWrites.set(t.file.path,Date.now()),await Te.timeAsync("write.fmSync",()=>this.app.fileManager.processFrontMatter(t.file,n=>{i?n[Lt]=i:delete n[Lt],s.length>0?n[Mi]=s:delete n[Mi]}))}catch(n){console.warn("[Stashpad] frontmatter sync failed",t.file?.path,n),this.emitError(t.file.path,n)}}computeParentLink(r){if(r.id===S)return null;let e=this.getTree();if(!r.parent||r.parent===S){let i=e.getRoot();return i&&i.id!==r.id&&i.file?kn(i.file.path):null}let t=e.get(r.parent);return t?.file?kn(t.file.path):null}computeChildrenLinks(r){return this.getTree().getChildren(r.id).filter(t=>!!t.file).map(t=>kn(t.file.path))}};Ti.PACING_MS=100,Ti.SELF_WRITE_GRACE_MS=2500;var Sn=Ti;async function Pi(d,r){let e=r.endsWith("/")?r:r+"/",t=new Map,i=new Map;for(let c of d.vault.getMarkdownFiles()){if(c.path!==r&&!c.path.startsWith(e))continue;let A=d.metadataCache.getFileCache(c)?.frontmatter,h=typeof A?.id=="string"?A.id:null;if(!h)continue;let p=typeof A?.parent=="string"?A.parent:S;t.set(h,{file:c,id:h,parent:p});let f=i.get(p)??[];f.push(h),i.set(p,f)}let s=c=>kn(c.file.path),n=c=>{if(c.id===S)return null;if(c.parent===S||!c.parent){let h=t.get(S);return h?s(h):null}let A=t.get(c.parent);return A?s(A):null},o=c=>{let A=i.get(c.id)??[],h=[];for(let p of A){let f=t.get(p);f&&h.push(s(f))}return h},a=0,l=0;for(let c of t.values()){a+=1;let A=n(c),h=o(c),p=d.metadataCache.getFileCache(c.file)?.frontmatter,f=p&&typeof p[Lt]=="string"?p[Lt]:null,u=p?.[Mi],g=Array.isArray(u)?u.filter(C=>typeof C=="string"):[],I=(f??null)===(A??null),m=g.length===h.length&&g.every((C,B)=>C===h[B]);if(!(I&&m))try{await d.fileManager.processFrontMatter(c.file,C=>{A?C[Lt]=A:delete C[Lt],h.length>0?C[Mi]=h:delete C[Mi]}),l+=1,await new Promise(C=>setTimeout(C,50))}catch(C){console.warn("[Stashpad] rebootstrap fm sync failed",c.file.path,C)}}return{checked:a,written:l}}function kn(d){return`[[${d.replace(/\.md$/i,"")}]]`}en();gi();var bn=class{constructor(r,e){this.tree=r;this.log=e;this.sweepChain=Promise.resolve()}async sweep(r){let e=this.sweepChain.then(()=>this.doSweep(r),()=>this.doSweep(r));return this.sweepChain=e.catch(()=>{}),e}async doSweep(r){let e=await this.log.readState(),t=this.tree.snapshot(),i=n=>{if(!r)return!0;let o=r.replace(/\/+$/,"");return n===o||n.startsWith(o+"/")};for(let[n,o]of Object.entries(t)){let a=e[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(e))!t[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(e))i(o.path)||(s[n]=o);for(let[n,o]of Object.entries(t))s[n]=o;await this.log.writeState(s)}};Qi();var Ie=require("obsidian");ce();vo();var ye=Ie.moment;function sa(d){let r=d.trim().toLowerCase();if(!r)return null;let e=Date.now(),t=u=>ye(u).startOf("day").valueOf(),i=/\b(\d{1,2})(?::(\d{2}))?\s*(am|pm)?\b/gi,s=0,n=!1,o=r,a=null;for(let u=i.exec(r);u!=null;u=i.exec(r))if(u[3]||u[2]){a=u;break}if(a){let u=parseInt(a[1],10),g=a[2]?parseInt(a[2],10):0,I=a[3]?.toLowerCase();I==="pm"&&u<12&&(u+=12),I==="am"&&u===12&&(u=0),u>=0&&u<24&&g>=0&&g<60&&(s=(u*3600+g*60)*1e3,n=!0,o=r.replace(a[0]," ").replace(/\s+/g," ").trim())}let l=u=>n?u+s:u;if(o===""||o==="today")return l(t(e));if(o==="yesterday")return l(ye(e).startOf("day").subtract(1,"day").valueOf());if(o==="tomorrow")return l(ye(e).startOf("day").add(1,"day").valueOf());let c=["sunday","monday","tuesday","wednesday","thursday","friday","saturday"],A=["sun","mon","tue","wed","thu","fri","sat"],h=c.indexOf(o)>=0?c.indexOf(o):A.indexOf(o);if(h>=0){let u=ye().startOf("day"),I=(u.day()-h+7)%7;return l(u.subtract(I,"days").valueOf())}let p=/^(\d+)\s*([dwmy])$/.exec(o);if(p){let u=parseInt(p[1],10),g={d:"days",w:"weeks",m:"months",y:"years"}[p[2]];return l(ye().subtract(u,g).startOf("day").valueOf())}let f=ye(o,["YYYY-MM-DD","YYYY/MM/DD","MM-DD-YYYY","MM/DD/YYYY","M-D-YYYY","M/D/YYYY"],!0);return f.isValid()?l(f.startOf("day").valueOf()):null}function na(d){let r={text:[],filters:{}},e=(d||"").trim();if(!e)return r;let t=/(?<![\w-])(in|before|after|on):\s*(?:\[([^\]]*)\]|([^]*?)(?=\s+(?:in|before|after|on):|$))/gi,i=e.split(""),s;for(;(s=t.exec(e))!=null;){let n=s[1].toLowerCase(),o=(s[2]!==void 0?s[2]:s[3]??"").trim();if(!o)continue;let a=!1;if(n==="in")r.filters.in=o.toLowerCase(),a=!0;else if(n==="before"){let l=sa(o);l!=null&&(r.filters.before=l,a=!0)}else if(n==="after"){let l=sa(o);l!=null&&(r.filters.after=l,a=!0)}else if(n==="on"){let l=sa(o);if(l!=null)if(a=!0,/\b\d{1,2}:\d{2}\b|\b\d{1,2}\s*(?:am|pm)\b/i.test(o))r.filters.on={start:l-6e4,end:l+6e4};else{let A=ye(l).startOf("day");r.filters.on={start:A.valueOf(),end:A.clone().add(1,"day").valueOf()}}}if(a)for(let l=s.index;l<s.index+s[0].length;l++)i[l]=" "}for(let n of i.join("").split(/\s+/))n&&r.text.push(n.toLowerCase());return r}var at=class d extends Ie.SuggestModal{constructor(e,t,i,s){super(e);this.tree=t;this.titleFn=i;this.opts=s;this.notes=[];this.includeExcluded=!1;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 e=this.pendingCleanups.pop();try{e&&e()}catch{}}try{this.opts.onClose?.()}catch{}}loadAll(){let e=this.tree.getRoot(),t=e.file?.parent?.name?.trim()??"",i=t?`Home \u2014 ${t}`:"Home",s=(n,o)=>{let a=this.tree.get(n);a?.file&&n!==S?this.notes.push({node:a,title:`${" ".repeat(o)}${this.titleFn(a)}`,body:""}):a?.file&&n===S&&this.notes.push({node:a,title:i,body:""});for(let l of this.tree.getChildren(n))s(l.id,o+1)};e.file&&this.notes.push({node:e,title:i,body:""});for(let n of this.tree.getChildren(S))s(n.id,1);if(this.opts.lockedNotes)for(let n of this.opts.lockedNotes()){let o=(this.opts.hideLockedTitles??!1)||!n.title;this.notes.push({node:null,title:o?"Locked note":n.title,body:"",locked:n})}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(a=>{o.body=this.stripFm(a)})}}createdMsFor(e){if(e.node?.created){let t=Date.parse(e.node.created);if(!Number.isNaN(t))return t}if(e.locked?.created){let t=Date.parse(e.locked.created);if(!Number.isNaN(t))return t}return e.cross?.file?.stat?.ctime!=null?e.cross.file.stat.ctime:null}stripFm(e){if(!e.startsWith("---"))return e;let t=e.indexOf(` ----`,3);return t===-1?e:e.slice(t+4).replace(/^\r?\n/,"")}getSuggestions(e){let t=e.trim().toLowerCase(),i=na(e),s=i.text,n=y=>{if(!s.length)return!0;for(let v of s)if(!y.includes(v))return!1;return!0},o=null,a=null;if(i.filters.in){let y=i.filters.in.split(/\s+/).filter(Boolean);o=new Set,a=new Map;let v=F=>y.every(D=>F.toLowerCase().includes(D)),Q=F=>{if(!o.has(F)){o.add(F);for(let D of this.tree.getChildren(F))Q(D.id)}};for(let F of this.notes)!F.node||F.cross||v(F.title)&&Q(F.node.id);let w=new Map;for(let F of this.notes){if(!F.cross)continue;let D=w.get(F.cross.folder)??[];D.push(F),w.set(F.cross.folder,D)}for(let[F,D]of w){let H=new Map;for(let x of D){let U=x.cross?.parentId??null;if(!U)continue;let T=H.get(U)??[];T.push(x.cross.id),H.set(U,T)}let R=new Set;a.set(F,R);let L=x=>{if(!R.has(x)){R.add(x);for(let U of H.get(x)??[])L(U)}};for(let x of D)v(x.title)&&L(x.cross.id)}}let l=y=>{let v=i.filters;if(o||a)if(y.cross){let Q=a?.get(y.cross.folder);if(!Q||!Q.has(y.cross.id))return!1}else if(y.node){if(!o||!o.has(y.node.id))return!1}else return!1;if(v.before||v.after||v.on){let Q=this.createdMsFor(y);if(Q==null||v.before!=null&&Q>=v.before||v.after!=null&&Q<=v.after||v.on&&(Q<v.on.start||Q>=v.on.end))return!1}return!0},c=y=>n(y.toLowerCase()),A=this.notes.filter(y=>!y.cross),h=this.notes.filter(y=>y.cross),p=(y,v)=>({id:y.locked?`locked:${y.locked.blob}`:y.cross?`cross:${y.cross.folder}:${y.cross.id}`:y.node.id,label:y.title,node:y.node,kind:"note",bodyPreview:this.previewFromBody(y.body,v),matchLine:v,crossFolder:y.cross?.folder,crossFile:y.cross?.file,crossId:y.cross?.id,locked:y.locked}),f=y=>y.node?.file?.stat?.mtime??y.cross?.file?.stat?.mtime??0,u=y=>y.node?.id===S||y.cross?.id===S,g=this.opts.mode==="pick",I=y=>{let v;if(!t)v=0;else{let Q=y.title.toLowerCase(),w=y.body.toLowerCase();Q===t?v=6:Q.startsWith(t)?v=5:Q.includes(t)?v=4:s.every(F=>Q.includes(F))?v=3:w.includes(t)?v=2:v=1}return g&&u(y)&&(v+=.5),v},m=y=>{let v=[];for(let F of y)if(l(F))if(this.opts.mode==="search"){if(!t){v.push({n:F,matchLines:[]});continue}let D=n(F.title.toLowerCase()),H=F.body.split(/\r?\n/),R=[];for(let x=0;x<H.length;x++)c(H[x])&&R.push(x);let L=R.length>0||n(F.body.toLowerCase());if(!D&&!L)continue;v.push({n:F,matchLines:R})}else{if(t&&!n(F.title.toLowerCase())&&!n(F.body.toLowerCase()))continue;v.push({n:F,matchLines:[]})}let Q=v.map(F=>({...F,band:I(F.n),mtime:f(F.n)}));Q.sort((F,D)=>D.band-F.band||D.mtime-F.mtime);let w=[];for(let{n:F,matchLines:D}of Q)if(this.opts.mode==="search"&&t&&D.length>0){let H=[],R=-100;for(let x of D)x-R>5&&H.push(x),R=x;let L=5;for(let x of H.slice(0,L))w.push(p(F,x))}else w.push(p(F,-1));return w},C=m(A),B=[...C];if(this.opts.mode==="search"?t?!0:C.length<10:!!t){let y=m(h);this.opts.mode==="search"&&!t&&(B.length=Math.min(B.length,50)),B.push(...y)}if(this.opts.folderResults){let y=this.opts.folderResults(),v={id:"__folder_picker__",label:"Open folder in a new tab\u2026",node:null,kind:"folder-open"};y.length>0&&(t?y.some(Q=>{let w=Q.split("/").pop()??Q;return n(`${Q.toLowerCase()} ${w.toLowerCase()}`)})&&B.push(v):B.unshift(v))}if(this.opts.allowCreate&&t&&!B.some(y=>y.label.trim().toLowerCase()===t)&&B.push({id:"__create__",label:`Create new: "${e}"`,node:null,kind:"create"}),i.text.join("").length>=3){let y=Q=>Q.kind==="note"&&(Q.id===S||Q.crossId===S)&&n(Q.label.toLowerCase()),v=B.filter(y);if(v.length>0){let Q=B.filter(w=>!y(w));B.splice(0,B.length,...v,...Q)}}return this.opts.excludedFolderNotes&&!this.includeExcluded&&B.push({id:"__search_excluded__",label:"Search excluded Stashpad folders",node:null,kind:"search-excluded"}),B}loadExcludedNotes(){if(this.includeExcluded||!this.opts.excludedFolderNotes)return;this.includeExcluded=!0;for(let t of this.opts.excludedFolderNotes())this.notes.push({node:null,title:t.title,body:t.body,cross:t});this.crossFolderIndex=null;for(let t of this.notes)!t.cross||t.body||!t.cross.file||this.app.vault.cachedRead(t.cross.file).then(i=>{t.body=this.stripFm(i)});let e=this.inputEl;e&&(e.dispatchEvent(new Event("input",{bubbles:!0})),setTimeout(()=>e.dispatchEvent(new Event("input",{bubbles:!0})),250))}previewFromBody(e,t){let i=e.split(/\r?\n/);if(t<0)return i.filter(a=>a.trim().length>0).slice(0,3).join(` +`;r.value=a+d+l,this.cursorText=r.value;let h=a.length+d.length;r.setSelectionRange(h,h),r.dispatchEvent(new Event("input")),r.focus()};r.addEventListener("paste",i=>{let s=i.clipboardData;if(!s)return;let n=[];for(let o of Array.from(s.files??[]))n.push(o);if(n.length===0){for(let o of Array.from(s.items??[]))if(o.kind==="file"){let a=o.getAsFile();a&&n.push(a)}}n.length!==0&&(i.preventDefault(),i.stopPropagation(),t(n))}),r.addEventListener("dragover",i=>{if(!(!i.dataTransfer||!Array.from(i.dataTransfer.types).includes("Files"))){i.preventDefault(),i.stopPropagation();try{i.dataTransfer.dropEffect="copy"}catch{}}}),r.addEventListener("drop",i=>{let s=Array.from(i.dataTransfer?.files??[]);s.length!==0&&(i.preventDefault(),i.stopPropagation(),t(s))})}destroy(){this.autocomplete?.detach(),this.autocomplete=null}async commit(){if(this.surface==="edit"){await this.saveEdit();return}this.mode==="line"?await this.commitLine():this.mode==="cursor"?await this.commitCursor():await this.commitPreset()}async saveEdit(){let r=this.cursorTextarea;r&&(await this.cb.onSave(r.value),this.cb.onDone())}isDirty(){return(this.cursorTextarea?.value??this.cursorText)!==this.body}setSurface(r){this.surface!==r&&(this.surface=r,this.render())}moveDivider(r){return this.mode!=="line"?!1:(this.lineCursorIdx=Math.max(1,Math.min(this.lines.length-1,this.lineCursorIdx+r)),this.render(),!0)}async commitLine(){await this.cb.onSplitAtLine(this.lineCursorIdx,this.nest),this.cb.onDone()}async commitCursor(){let r=this.cursorTextarea;if(!r)return;let e=r.selectionStart;if(e<=0||e>=r.value.length){new G.Notice("Move the cursor inside the text \u2014 neither end can be empty.");return}await this.cb.onSplitAtChar(r.value,e,this.nest),this.cb.onDone()}async commitPreset(){let r=$t(this.body,this.presetMode);if(r.length<2){new G.Notice("That delimiter wouldn't split this note.");return}await this.cb.onSplitMany(r,this.nest),this.cb.onDone()}render(){if(this.autocomplete?.detach(),this.autocomplete=null,this.host.empty(),this.host.toggleClass("stashpad-edit-surface",this.surface==="edit"),this.cb.onTitle?.(this.surface==="edit"?"Edit note":"Split note"),this.renderSurfaceToggle(),this.surface==="edit"){this.renderEditSurface();return}this.renderSplitSurface()}renderSurfaceToggle(){let r=this.host.createDiv({cls:"stashpad-split-surface"}),e=G.Platform.isMacOS?"\u2318":"Ctrl+",t=(i,s,n,o)=>{let a=r.createEl("button",{cls:"stashpad-split-surface-btn"});(0,G.setIcon)(a.createSpan({cls:"stashpad-split-btn-icon"}),n),a.createSpan({text:i}),a.createSpan({cls:"stashpad-split-kbd-hint",text:`${e}${o}`}),a.toggleClass("is-active",this.surface===s),a.onmousedown=l=>l.preventDefault(),a.onclick=()=>this.setSurface(s)};t("Edit","edit","pencil-line","E"),t("Split","split","split","S")}renderPopOut(r){if(!this.cb.popOut)return;let e=r.createEl("button",{cls:"stashpad-split-popout-btn"});(0,G.setIcon)(e.createSpan({cls:"stashpad-split-popout-icon"}),"maximize-2"),e.createSpan({text:G.Platform.isMobile?"Pop-out":"Open in a tab"}),e.setAttr("aria-label","Open in a full tab"),e.onmousedown=t=>t.preventDefault(),e.onclick=()=>this.cb.popOut(this.getState())}renderOpenExternal(r){if(!this.cb.onOpenExternal)return;let e=r.createEl("button",{cls:"stashpad-split-popout-btn"});(0,G.setIcon)(e.createSpan({cls:"stashpad-split-popout-icon"}),"pencil"),e.createSpan({text:G.Platform.isMobile?"Advanced":"Obsidian editor"}),e.setAttr("aria-label","Open in a full Obsidian editor tab"),e.onmousedown=t=>t.preventDefault(),e.onclick=()=>{this.cb.onOpenExternal(),this.cb.close()}}renderEditSurface(){this.renderEditorSections();let r=this.host.createDiv({cls:"stashpad-split-edit-tools"}),e=r.createSpan({cls:"stashpad-split-count"}),t=()=>{let c=this.cursorTextarea?.value??"",d=(c.trim().match(/\S+/g)||[]).length;e.setText(`${d} word${d===1?"":"s"} \xB7 ${c.length} char${c.length===1?"":"s"}`)},i=r.createEl("button",{cls:"stashpad-split-case-btn"});(0,G.setIcon)(i.createSpan({cls:"stashpad-split-btn-icon"}),"case-sensitive"),i.createSpan({text:"Case"}),i.setAttr("aria-label","Cycle case of the selection (or all text): lower \u2192 UPPER \u2192 Title \u2192 Sentence"),i.onmousedown=c=>c.preventDefault(),i.onclick=()=>this.cycleCase(t),this.cursorTextarea?.addEventListener("input",t),t();let s=this.host.createDiv({cls:"stashpad-split-help"});G.Platform.isPhone||s.setText("Edit the note, then Save. \xB7 \u2318/Ctrl+Enter or Save to write \xB7 \u2318/Ctrl+S \u2192 Split \xB7 Esc discards.");let n=this.host.createDiv({cls:"stashpad-split-actions"}),o=n.createEl("button",{cls:"stashpad-split-cancel-btn"});(0,G.setIcon)(o.createSpan({cls:"stashpad-split-btn-icon"}),"x"),o.createSpan({text:"Cancel"}),o.createSpan({cls:"stashpad-split-esc-hint",text:" (Esc)"}),o.onmousedown=c=>c.preventDefault(),o.onclick=()=>this.cb.close(),this.renderPopOut(n),this.renderOpenExternal(n);let l=n.createDiv({cls:"stashpad-split-actions-right"}).createEl("button",{cls:"stashpad-split-confirm-btn mod-cta"});(0,G.setIcon)(l.createSpan({cls:"stashpad-split-btn-icon"}),"save"),l.createSpan({text:"Save"}),l.onmousedown=c=>c.preventDefault(),l.onclick=()=>void this.commit()}cycleCase(r){let e=this.cursorTextarea;if(!e)return;let t=e.selectionStart!==e.selectionEnd,i=t?e.selectionStart:0,s=t?e.selectionEnd:e.value.length,n=e.value.slice(i,s),o=["lower","upper","title","sentence"],a=o[this.caseCycleIndex%o.length];this.caseCycleIndex+=1;let l=ad(n,a);e.value=e.value.slice(0,i)+l+e.value.slice(s),e.setSelectionRange(i,i+l.length),this.cursorText=e.value,e.dispatchEvent(new Event("input")),r(),e.focus()}renderSplitSurface(){let r=this.host.createDiv({cls:"stashpad-split-modes"}),e=(p,f,u,g,I=!1)=>{let m=r.createEl("button",{cls:"stashpad-split-mode-btn"});(0,G.setIcon)(m.createSpan({cls:"stashpad-split-btn-icon"}),g),m.createSpan({text:p}),m.toggleClass("is-active",f),m.disabled=I,m.onmousedown=C=>C.preventDefault(),I||(m.onclick=u)};this.lines.length>=2&&e("Line",this.mode==="line",()=>{this.mode="line",this.render()},"separator-horizontal"),e("Cursor",this.mode==="cursor",()=>{this.mode="cursor",this.render()},"text-cursor-input");let t={lines:"list",paragraphs:"pilcrow",headings:"heading"};["lines","paragraphs","headings"].forEach(p=>{let f=$t(this.body,p).length,u=f<2,g=p==="paragraphs"?"Blank line(s)":pi[p],I=u?g:`${g} (${f})`;e(I,this.mode==="preset"&&this.presetMode===p,()=>{this.mode="preset",this.presetMode=p,this.render()},t[p],u)}),this.mode==="line"?this.renderLineMode():this.mode==="cursor"?this.renderEditorSections():this.renderPresetMode();let i=this.host.createDiv({cls:"stashpad-split-help"}),s=()=>{if(G.Platform.isPhone){i.setCssStyles({display:"none"});return}i.setCssStyles({display:""});let p=this.nest?"New part nested under the original.":"New part added as a sibling.",f=this.nest?"New parts nested under the original.":"New parts added as siblings.",u="\u2318/Ctrl+Enter or Split to confirm";i.setText(this.mode==="line"?`\u2191/\u2193 or click to pick the split line \xB7 ${u} \xB7 ${p}`:this.mode==="cursor"?`Click or arrow to position the cursor \xB7 ${u} \xB7 ${p}`:`Preview of the resulting parts \xB7 ${u} \xB7 ${f}`)};s();let n=this.host.createDiv({cls:"stashpad-split-actions"}),o=n.createEl("button",{cls:"stashpad-split-cancel-btn"});(0,G.setIcon)(o.createSpan({cls:"stashpad-split-btn-icon"}),"x"),o.createSpan({text:"Cancel"}),o.createSpan({cls:"stashpad-split-esc-hint",text:" (Esc)"}),o.onmousedown=p=>p.preventDefault(),o.onclick=()=>this.cb.close(),this.renderPopOut(n),this.renderOpenExternal(n);let a=n.createDiv({cls:"stashpad-split-actions-right"}),l=a.createEl("label",{cls:"stashpad-split-nest"}),c=l.createEl("input",{type:"checkbox"});c.checked=this.nest,l.createSpan({text:"Nest under original"}),c.onchange=()=>{this.nest=c.checked,s()};let d=this.mode==="preset"?$t(this.body,this.presetMode).length:0,h=a.createEl("button",{cls:"stashpad-split-confirm-btn mod-cta"});(0,G.setIcon)(h.createSpan({cls:"stashpad-split-btn-icon"}),"split"),h.createSpan({text:this.mode==="preset"&&d>=2?`Split into ${d}`:"Split"}),h.onmousedown=p=>p.preventDefault(),h.onclick=()=>this.commit()}renderPresetMode(){let r=$t(this.body,this.presetMode),e=this.host.createDiv({cls:"stashpad-split-preset-list"});if(r.length<2){e.createDiv({cls:"stashpad-split-empty",text:"This delimiter wouldn't split the note into more than one part."});return}r.forEach((t,i)=>{let s=e.createDiv({cls:"stashpad-split-part-card"}),n=s.createDiv({cls:"stashpad-split-part-num"});n.createSpan({cls:"stashpad-split-part-title",text:`Part ${i+1}`}),n.appendChild(this.makeCopyButton(()=>t,`Copy part ${i+1}`)),s.createDiv({cls:"stashpad-split-part-body",text:t})})}renderLineMode(){let r=this.host.createDiv({cls:"stashpad-split-list"}),e=null;for(let t=0;t<this.lines.length;t++){t===this.lineCursorIdx&&(e=r.createDiv({cls:"stashpad-split-divider",text:"\u2500\u2500 split here \u2500\u2500"}));let i=r.createDiv({cls:"stashpad-split-line"});i.createSpan({cls:"stashpad-split-lineno",text:String(t+1)}),i.createSpan({cls:"stashpad-split-text",text:this.lines[t]||" "}),i.onclick=()=>{let s=Math.max(1,Math.min(this.lines.length-1,t+1));s!==this.lineCursorIdx&&(this.lineCursorIdx=s,this.render())}}e&&window.requestAnimationFrame(()=>e.scrollIntoView({block:"center"}))}buildSplitSection(r,e,t){let i=r.createDiv({cls:`stashpad-split-section stashpad-split-${e}`}),s=i.createEl("button",{cls:"stashpad-split-section-header"});s.setAttr("type","button");let n=s.createSpan({cls:"stashpad-split-chevron"});(0,G.setIcon)(n,"chevron-down"),s.createSpan({cls:"stashpad-split-section-title",text:t});let o=i.createDiv({cls:"stashpad-split-section-body"}),a=()=>{i.toggleClass("is-collapsed",this.collapsed[e]),s.setAttr("aria-expanded",String(!this.collapsed[e]))};return s.onmousedown=l=>l.preventDefault(),s.onclick=l=>{l.preventDefault(),this.collapsed[e]=!this.collapsed[e],a()},a(),{section:i,body:o}}makeCopyButton(r,e,t="stashpad-split-copy-btn"){let i=createEl("button",{cls:t});return(0,G.setIcon)(i,"copy"),i.setAttr("aria-label",e),i.onmousedown=s=>s.preventDefault(),i.onclick=s=>{s.preventDefault(),s.stopPropagation();let n=r();navigator.clipboard?.writeText(n).then(()=>new G.Notice("Copied to clipboard."),()=>new G.Notice("Couldn't access the clipboard."))},i}renderEditorSections(){if(G.Platform.isMobile){this.renderEditorTabbed();return}let r=this.buildSplitSection(this.host,"orig","Original \u2014 will be replaced");r.body.createDiv({cls:"stashpad-split-panel-body",text:this.body}),r.section.appendChild(this.makeCopyButton(()=>this.body,"Copy the original text","stashpad-split-copy-btn stashpad-split-section-copy"));let e=this.buildSplitSection(this.host,"changes","Changes"),t=e.body.createDiv({cls:"stashpad-split-panel-body stashpad-split-diff-body"}),s=this.buildSplitSection(this.host,"edit",this.surface==="edit"?"Your edit":"Your edit \u2014 the split uses this").body.createEl("textarea",{cls:"stashpad-split-cursor-ta"});s.value=this.cursorText,s.readOnly=!1,this.cursorTextarea=s,this.enhanceTextarea(s);let n=()=>{t.empty();for(let h of Kr(this.body,s.value)){let p=h.t==="ins"?"stashpad-diff-ins":h.t==="del"?"stashpad-diff-del":"stashpad-diff-eq";t.createSpan({cls:p,text:h.s})}},o=()=>{let h=s.value!==this.body;r.section.setCssStyles({display:h?"":"none"}),e.section.setCssStyles({display:h?"":"none"}),h&&n()},a=parseFloat(getComputedStyle(s).lineHeight)||22,l=this.surface==="edit"?G.Platform.isMobile?10:40:G.Platform.isMobile?3:12,c=2,d=()=>{s.setCssStyles({height:"auto"});let h=Math.min(a*l+16,Math.round(window.innerHeight*.5)),p=Math.min(s.scrollHeight,h);s.setCssStyles({height:`${Math.max(p,a*c+16)}px`,overflowY:"auto"})};o(),requestAnimationFrame(()=>{d(),s.focus();let h=this.surface==="edit"?s.value.length:Math.floor(s.value.length/2);s.setSelectionRange(h,h)}),s.addEventListener("input",()=>{this.cursorText=s.value,d(),o()})}renderEditorTabbed(){let r=this.host.createDiv({cls:"stashpad-split-tabs"}),e=r.createDiv({cls:"stashpad-split-tabbar"}),t=r.createDiv({cls:"stashpad-split-tabbody"}),i=t.createDiv({cls:"stashpad-split-tabpanel stashpad-split-tabpanel-edit"}),s=i.createEl("textarea",{cls:"stashpad-split-cursor-ta"});s.value=this.cursorText,s.readOnly=!1,this.cursorTextarea=s,this.enhanceTextarea(s);let n=t.createDiv({cls:"stashpad-split-tabpanel"});n.createDiv({cls:"stashpad-split-tab-copybar"}).appendChild(this.makeCopyButton(()=>this.body,"Copy the original text","stashpad-split-copy-btn stashpad-split-tab-copy")),n.createDiv({cls:"stashpad-split-panel-body",text:this.body});let a=t.createDiv({cls:"stashpad-split-tabpanel"}),l=a.createDiv({cls:"stashpad-split-panel-body stashpad-split-diff-body"}),c=[{key:"edit",label:this.surface==="edit"?"Your edit":"Edit",panel:i},{key:"orig",label:"Original",panel:n},{key:"changes",label:"Changes",panel:a}],d={},h="edit",p=g=>{h=g;for(let I of c)I.panel.toggleClass("is-active",I.key===g),d[I.key]?.toggleClass("is-active",I.key===g);g==="edit"&&s.focus()};for(let g of c){let I=e.createEl("button",{cls:"stashpad-split-tab",text:g.label});I.onmousedown=m=>m.preventDefault(),I.onclick=()=>p(g.key),d[g.key]=I}let f=()=>{l.empty();for(let g of Kr(this.body,s.value)){let I=g.t==="ins"?"stashpad-diff-ins":g.t==="del"?"stashpad-diff-del":"stashpad-diff-eq";l.createSpan({cls:I,text:g.s})}},u=()=>{let g=s.value!==this.body;d.orig.toggleClass("is-hidden",!g),d.changes.toggleClass("is-hidden",!g),g&&f(),!g&&(h==="orig"||h==="changes")&&p("edit")};s.setCssStyles({overflowY:"auto"}),u(),p("edit"),requestAnimationFrame(()=>{s.focus();let g=this.surface==="edit"?s.value.length:Math.floor(s.value.length/2);s.setSelectionRange(g,g)}),s.addEventListener("input",()=>{this.cursorText=s.value,u()})}},Cs="stashpad-split-view",Si=class extends G.Modal{constructor(e,t,i,s={}){super(e);this.body=t;this.cbs=i;this.init=s;this.ui=null;this.committing=!1}onOpen(){this.modalEl.addClass("stashpad-split-modal"),this.ui=new gs(this.app,this.contentEl,this.body,this.init,{onSplitAtLine:this.cbs.onSplitAtLine,onSplitAtChar:this.cbs.onSplitAtChar,onSplitMany:this.cbs.onSplitMany,onSave:this.cbs.onSave,onOpenExternal:this.cbs.onOpenExternal,onImportFile:this.cbs.onImportFile,close:()=>this.close(),onDone:()=>{this.committing=!0,this.close()},onTitle:e=>this.titleEl.setText(e),popOut:this.cbs.popOut?e=>{this.committing=!0,this.close(),this.cbs.popOut(e)}:void 0}),this.scope.register(["Mod"],"Enter",e=>{e.preventDefault(),this.ui?.commit()}),this.scope.register([],"ArrowUp",e=>{this.ui?.moveDivider(-1)&&e.preventDefault()}),this.scope.register([],"ArrowDown",e=>{this.ui?.moveDivider(1)&&e.preventDefault()}),this.scope.register(["Mod"],"e",e=>{e.preventDefault(),this.ui?.setSurface("edit")}),this.scope.register(["Mod"],"s",e=>{e.preventDefault(),this.ui?.setSurface("split")}),this.scope.register(["Mod","Shift"],"e",e=>{e.preventDefault(),this.cbs.onOpenExternal&&(this.cbs.onOpenExternal(),this.close())})}close(){if(this.committing||!this.ui?.isDirty()){super.close();return}new j(this.app,"Discard unsaved edits?","You've edited this note but haven't saved. Close and discard your changes?","Discard",e=>{e&&(this.committing=!0,this.close())},"Keep editing",!0).open()}onClose(){this.ui?.destroy(),this.ui=null,this.contentEl.empty()}},bi=class extends G.ItemView{constructor(e){super(e);this.ui=null;this.ctx=null;this.prevLeaf=null;this.autoCloseTimer=null;this.expiredGrace=null;this.title="Note";this.viewIcon="pencil-line";this.closingIntentionally=!1}getViewType(){return Cs}getDisplayText(){return this.title}getIcon(){return this.viewIcon}setHeader(e,t){this.title=e,this.viewIcon=t,this.leaf.updateHeader?.()}setContext(e){this.expiredGrace!=null&&(window.clearTimeout(this.expiredGrace),this.expiredGrace=null),this.ctx=e,this.prevLeaf=e.prevLeaf??null;let t=e.init.surface==="edit";this.setHeader(t?"Edit note":"Split note",t?"pencil-line":"split"),this.renderUI()}async onOpen(){this.contentEl.addClass("stashpad-split-modal","stashpad-split-view"),this.ctx||(this.expiredGrace=window.setTimeout(()=>{this.expiredGrace=null,this.ctx||this.renderExpired()},800))}renderUI(){let e=this.contentEl;e.empty(),e.addClass("stashpad-split-modal","stashpad-split-view"),this.ctx&&(this.ui=new gs(this.app,e,this.ctx.body,this.ctx.init,{onSplitAtLine:this.ctx.cbs.onSplitAtLine,onSplitAtChar:this.ctx.cbs.onSplitAtChar,onSplitMany:this.ctx.cbs.onSplitMany,onSave:this.ctx.cbs.onSave,onOpenExternal:this.ctx.cbs.onOpenExternal,onImportFile:this.ctx.cbs.onImportFile,close:()=>this.guardedDetach(),onDone:()=>this.startClosePanel("\u2713 Done.",null,!0),onTitle:t=>this.setHeader(t,t.startsWith("Edit")?"pencil-line":"split")}),this.registerDomEvent(e,"keydown",t=>{let i=t.metaKey||t.ctrlKey;i&&t.shiftKey&&(t.key==="e"||t.key==="E")?(t.preventDefault(),this.ctx?.cbs.onOpenExternal?.(),this.guardedDetach()):i&&t.key==="Enter"?(t.preventDefault(),this.ui?.commit()):i&&!t.shiftKey&&(t.key==="e"||t.key==="E")?(t.preventDefault(),this.ui?.setSurface("edit")):i&&(t.key==="s"||t.key==="S")?(t.preventDefault(),this.ui?.setSurface("split")):t.key==="ArrowUp"?this.ui?.moveDivider(-1)&&t.preventDefault():t.key==="ArrowDown"&&this.ui?.moveDivider(1)&&t.preventDefault()}))}renderExpired(){this.setHeader("Expired","clock"),this.startClosePanel("This session has expired.","It can't be restored \u2014 closing this tab\u2026",!1)}startClosePanel(e,t,i){let s=this.contentEl;s.empty(),this.ui?.destroy(),this.ui=null;let n=s.createDiv({cls:"stashpad-split-done"});n.createDiv({cls:"stashpad-split-done-title",text:e}),t&&n.createDiv({cls:"stashpad-split-countdown",text:t});let o=n.createDiv({cls:"stashpad-split-countdown"}),a=n.createDiv({cls:"stashpad-split-done-btns"}),l=a.createEl("button",{cls:"mod-cta",text:"Close now"}),c=a.createEl("button",{text:"Keep tab open"}),d=4,h=()=>o.setText(`Closing this tab in ${d}\u2026`),p=()=>{this.autoCloseTimer!=null&&(window.clearInterval(this.autoCloseTimer),this.autoCloseTimer=null)},f=()=>{p(),i?this.closeAndRefocus():this.leaf.detach()};h(),this.autoCloseTimer=window.setInterval(()=>{d-=1,d<=0?f():h()},1e3),l.onclick=f,c.onclick=()=>{p(),o.setText("Close this tab whenever you're ready."),c.remove(),l.setText("Close tab")}}guardedDetach(){if(!this.ui?.isDirty()){this.closingIntentionally=!0,this.leaf.detach();return}new j(this.app,"Discard unsaved edits?","You've edited this note but haven't saved. Close this tab and discard your changes?","Discard",e=>{e&&(this.closingIntentionally=!0,this.leaf.detach())},"Keep editing",!0).open()}leafStillOpen(e){let t=!1;return this.app.workspace.iterateAllLeaves(i=>{i===e&&(t=!0)}),t}closeAndRefocus(){let e=this.prevLeaf;this.closingIntentionally=!0,this.leaf.detach(),e&&this.leafStillOpen(e)&&this.app.workspace.setActiveLeaf(e,{focus:!0})}async onClose(){!this.closingIntentionally&&this.ui?.isDirty()&&new G.Notice("Closed the Stashpad editor with unsaved changes \u2014 they were discarded. Use Save (\u2318/Ctrl+Enter) next time.",7e3),this.autoCloseTimer!=null&&(window.clearInterval(this.autoCloseTimer),this.autoCloseTimer=null),this.expiredGrace!=null&&(window.clearTimeout(this.expiredGrace),this.expiredGrace=null),this.ui?.destroy(),this.ui=null,this.contentEl.empty()}};Di=class extends G.Modal{constructor(e,t,i,s,n={}){super(e);this.defaultBaseName=t;this.noteCount=i;this.onConfirm=s;this.opts=n;this.delivered=!1}onOpen(){this.contentEl.empty();let e=!!this.opts.locked;this.titleEl.setText(e?"Export encrypted bundle":"Export"),this.modalEl.addClass("stashpad-export-modal"),this.contentEl.createEl("p",{cls:"stashpad-export-desc",text:e?`Re-export this locked bundle (${this.noteCount} note${this.noteCount===1?"":"s"}) as a shareable .stash.`:`Export ${this.noteCount} note${this.noteCount===1?"":"s"}.`});let t=this.contentEl.createDiv({cls:"stashpad-export-field"});t.createEl("label",{cls:"stashpad-export-label",text:"File name"});let i=t.createEl("input",{type:"text"});i.addClass("stashpad-export-name"),i.value=this.defaultBaseName;let s=this.contentEl.createEl("div",{cls:"stashpad-export-preview"}),n="full",o=()=>{},a=this.contentEl.createDiv();rd(a,z=>{n=z,o()}),e&&a.setCssStyles({display:"none"});let l="stash",c=this.contentEl.createDiv({cls:"stashpad-export-format"});c.createEl("label",{cls:"stashpad-export-label",text:"Format"});let d=c.createDiv({cls:"stashpad-export-content-seg"}),h=[{id:"stash",label:"Stashpad .stash"},...this.opts.okfEnabled?[{id:"okf",label:"OKF bundle"}]:[],{id:"zip",label:"Plain .zip"}],p=new Map;for(let z of h){let be=d.createEl("button",{cls:"stashpad-export-content-opt",text:z.label});be.toggleClass("is-active",z.id===l),be.onclick=Be=>{Be.preventDefault(),l=z.id,p.forEach((Pe,Ze)=>Pe.toggleClass("is-active",Ze===l)),o()},p.set(z.id,be)}let f=this.contentEl.createDiv({cls:"stashpad-okf-formats"}),u=(z,be)=>{let Be=f.createDiv({cls:"stashpad-okf-fmt"}),Pe=Be.createEl("input",{type:"checkbox"});return Pe.checked=be,Be.createEl("label",{text:z}),Pe.onchange=()=>o(),Pe},g=u(".zip \u2014 OKF bundle (portable)",!0),I=u(".tar.gz \u2014 OKF bundle (tarball)",!1),m=f.createDiv({cls:"stashpad-export-pw-hint is-error"});m.setText("Pick at least one OKF format."),m.setCssStyles({display:"none"}),e&&c.setCssStyles({display:"none"});let C=this.contentEl.createDiv({cls:"stashpad-export-zipwarn"});C.setText("Frontmatter-only / body-only exports save as a plain .zip of the selected markdown (with referenced attachments) \u2014 not a re-importable .stash."),C.setCssStyles({display:"none"});let B=this.contentEl.createDiv({cls:"stashpad-export-encrypt"}),E=B.createDiv({cls:"stashpad-export-toggle"}),y=E.createEl("input",{type:"checkbox"});y.id="stashpad-export-encrypt-cb";let v=E.createEl("label",{text:"Encrypt with a password"});v.htmlFor=y.id;let Q=B.createDiv({cls:"stashpad-export-pw-area"});Q.setCssStyles({display:"none"});let w=[],k=z=>{let be=Q.createDiv({cls:"stashpad-export-pw-row"}),Be=be.createEl("input",{type:"password"});Be.addClass("stashpad-export-name"),Be.placeholder=z;let Pe=be.createEl("button",{cls:"stashpad-export-copy"}),Ze=()=>{let Ft=Be.value.length===0;Pe.setText(Ft?"Paste":"Copy"),Pe.toggleClass("is-paste",Ft),Pe.setAttr("aria-label",`${Ft?"Paste into":"Copy"} ${z.toLowerCase()}`)};return Pe.onclick=async Ft=>{if(Ft.preventDefault(),Be.value.length===0)try{let Os=(await navigator.clipboard?.readText())?.trim();if(!Os){new G.Notice("Clipboard is empty.");return}Be.value=Os,Be.dispatchEvent(new Event("input")),new G.Notice("Pasted from clipboard.")}catch{new G.Notice("Couldn't read the clipboard.")}else navigator.clipboard?.writeText(Be.value).then(()=>new G.Notice("Passphrase copied to clipboard."),()=>new G.Notice("Couldn't access the clipboard."))},Ze(),w.push(Ze),Be},D=k("Password"),H=k("Confirm password"),R=Q.createDiv({cls:"stashpad-export-strength"}),L=R.createDiv({cls:"stashpad-strength-bar"}),x=[0,1,2,3].map(()=>L.createDiv({cls:"stashpad-strength-seg"})),U=R.createEl("span",{cls:"stashpad-strength-label"}),T=Q.createDiv({cls:"stashpad-export-genrow"}),b=T.createEl("button",{cls:"stashpad-export-gen",text:"Generate strong passphrase"}),M=T.createEl("button",{cls:"stashpad-export-show",text:"Show"}),O=Q.createEl("div",{cls:"stashpad-export-pw-hint"}),K=Q.createEl("div",{cls:"stashpad-export-pw-suite"});K.setText("Encryption: AES-256-GCM. Checking key-derivation suite for this device\u2026"),this.opts.kdfProbe?this.opts.kdfProbe().then(z=>{K.toggleClass("is-weak",!z),K.setText(z?"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(()=>{K.setText("Encryption: AES-256-GCM with a password-derived key.")}):K.setText("Encryption: Argon2id + AES-256-GCM (falls back to PBKDF2 if Argon2 can't run here).");let Y=this.app.secretStorage,Z=Q.createDiv({cls:"stashpad-export-remember"}),V=Z.createEl("input",{type:"checkbox"});V.checked=!0,V.id="stashpad-export-remember-cb";let q=Z.createEl("label",{text:"Remember in this vault (this device) \u2014 skips the prompt when you re-import here."});q.htmlFor=V.id;let ee=Q.createDiv({cls:"stashpad-export-remember-note"});ee.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."),ee.setCssStyles({display:V.checked?"":"none"}),V.onchange=()=>{ee.setCssStyles({display:V.checked?"":"none"})},Y||Z.setCssStyles({display:"none"});let ue=()=>e?"stash":n!=="full"?"zip":l,oe=()=>{let z=i.value.trim()||this.defaultBaseName;return!e&&n!=="full"?`${z}-${n}`:ue()==="stash"&&y.checked?`${z}-encrypted`:z},ie=()=>{let z=ue();if(z==="stash"){s.setText(`Saves as: ${oe()}-<timestamp>.stash`);return}if(z==="okf"){s.setText(`Saves as: ${oe()}-<timestamp>.zip / .tar.gz (OKF bundle)`);return}s.setText(`Saves as: ${oe()}-<timestamp>.zip (plain archive \u2014 not re-importable)`)};i.oninput=ie;let te=this.contentEl.createDiv({cls:"stashpad-export-footer"}),fe=te.createEl("button",{text:"Cancel"});fe.onclick=()=>this.close();let we=te.createEl("button",{cls:"mod-cta",text:"Export"}),se=()=>{let z=bo(D.value);R.style.visibility=D.value?"visible":"hidden",x.forEach((be,Be)=>be.toggleClass("is-on",D.value!==""&&Be<=z.level)),L.dataset.level=String(z.level),U.setText(z.label)},Ae=()=>{let z=!e&&n!=="full",be=ue();c.setCssStyles({display:!e&&!z?"":"none"}),f.setCssStyles({display:!e&&!z&&l==="okf"?"":"none"}),C.setCssStyles({display:z?"":"none"});let Be=be==="stash";B.setCssStyles({display:Be?"":"none"});let Pe=Be&&y.checked;Q.setCssStyles({display:Pe?"":"none"});let Ze=!0;Pe&&(D.value?D.value!==H.value?(O.setText("Passwords don't match."),O.addClass("is-error"),Ze=!1):(O.setText("\u26A0\uFE0F If you lose this password, the export can't be recovered."),O.removeClass("is-error")):(O.setText("Enter a password to encrypt this export."),O.removeClass("is-error"),Ze=!1));let Ft=!e&&!z&&l==="okf"&&!g.checked&&!I.checked;m.setCssStyles({display:Ft?"":"none"}),Ft&&(Ze=!1),se(),w.forEach(Os=>Os()),we.disabled=!Ze,we.toggleClass("is-disabled",!Ze),ie()},Xe=!1,ri=z=>{Xe=z,D.type=H.type=z?"text":"password",M.setText(z?"Hide":"Show")};M.onclick=z=>{z.preventDefault(),ri(!Xe)},b.onclick=z=>{z.preventDefault(),D.value=H.value=So(),ri(!1),new G.Notice("Passphrase generated (hidden) \u2014 Show to view, or Copy to save it."),Ae()},y.onchange=Ae,D.oninput=Ae,H.oninput=Ae,o=Ae,Ae();let Gs=()=>{let z=ue(),be=z==="stash"&&y.checked?D.value:null;this.commit({baseName:oe(),content:n,format:z,okf:{zip:g.checked,targz:I.checked},password:be,remember:!!be&&V.checked})};we.onclick=Gs,this.scope.register([],"Enter",z=>{z.preventDefault(),we.disabled||Gs()}),requestAnimationFrame(()=>{i.focus(),i.select()})}commit(e){let t=e.baseName.trim()||this.defaultBaseName,i=e.password&&e.password.length?e.password:null;this.delivered=!0,this.close(),this.onConfirm({...e,baseName:t,password:i,remember:!!i&&e.remember})}onClose(){this.contentEl.empty()}},cs=class extends G.Modal{constructor(e,t,i,s){super(e);this.errorMsg=t;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 e=this.contentEl.createEl("input",{type:"password"});e.addClass("stashpad-export-name"),e.placeholder="Password";let t=this.contentEl.createDiv({cls:"stashpad-export-footer"});if(t.createEl("button",{text:"Cancel"}).onclick=()=>this.close(),this.allowLater){let s=t.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=t.createEl("button",{cls:"mod-cta",text:"Decrypt & import"});i.onclick=()=>this.submit(e.value),this.scope.register([],"Enter",s=>{s.preventDefault(),this.submit(e.value)}),requestAnimationFrame(()=>e.focus())}submit(e){e&&this.finish({kind:"password",value:e})}finish(e){this.delivered=!0,this.close(),this.onResult(e)}onClose(){this.delivered||(this.delivered=!0,this.onResult({kind:"cancel"})),this.contentEl.empty()}},Le=class extends G.Modal{constructor(e,t){super(e);this.opts=t;this.succeeded=!1}onOpen(){let{mode:e}=this.opts;this.contentEl.empty(),this.modalEl.addClass("stashpad-export-modal","stashpad-encryption-modal"),this.titleEl.setText(this.opts.title??(e==="setup"?"Set up encryption password":e==="change"?"Change encryption password":"Unlock encryption")),this.contentEl.createDiv({cls:"stashpad-beta-row"}).createEl("span",{cls:"stashpad-beta-badge",text:"BETA"}),this.opts.intro?this.contentEl.createEl("p",{cls:"stashpad-export-desc",text:this.opts.intro}):e==="setup"&&this.contentEl.createEl("p",{cls:"stashpad-export-desc",text:"This single password protects everything you encrypt in this vault. It is stored only on this device. There is NO recovery \u2014 if you lose it, anything you've encrypted is gone for good."});let t=[],i=g=>{let I=this.contentEl.createDiv({cls:"stashpad-export-pw-row stashpad-encryption-row"}),m=I.createEl("input",{type:"password"});m.addClass("stashpad-export-name","stashpad-encryption-field"),m.placeholder=g;let C=I.createEl("button",{cls:"stashpad-export-copy"}),B=()=>{let E=m.value.length===0;C.setText(E?"Paste":"Copy"),C.toggleClass("is-paste",E),C.setAttr("aria-label",`${E?"Paste into":"Copy"} ${g.toLowerCase()}`)};return C.onclick=async E=>{if(E.preventDefault(),m.value.length===0)try{let y=(await navigator.clipboard?.readText())?.trim();if(!y){new G.Notice("Clipboard is empty.");return}m.value=y,m.dispatchEvent(new Event("input")),new G.Notice("Pasted from clipboard.")}catch{new G.Notice("Couldn't read the clipboard.")}else navigator.clipboard?.writeText(m.value).then(()=>new G.Notice("Copied to clipboard."),()=>new G.Notice("Couldn't access the clipboard."))},m.addEventListener("input",B),B(),t.push(B),m},s=null,n=null,o=null;if((e==="unlock"||e==="change")&&(s=i("Current password")),(e==="setup"||e==="change")&&(n=i(e==="change"?"New password":"Password"),o=i("Confirm password")),n){let g=this.contentEl.createDiv({cls:"stashpad-export-strength"}),I=g.createDiv({cls:"stashpad-strength-bar"}),m=[0,1,2,3].map(()=>I.createDiv({cls:"stashpad-strength-seg"})),C=g.createEl("span",{cls:"stashpad-strength-label"}),B=this.contentEl.createDiv({cls:"stashpad-encryption-counter"}),E=()=>{let w=n.value,k=bo(w);m.forEach((D,H)=>D.toggleClass("is-on",H<k.level)),C.setText(w?k.label:""),B.setText(`${w.length} character${w.length===1?"":"s"}${w.length>0&&w.length<6?" \u2014 use at least 6":""}`),B.toggleClass("is-weak",w.length>0&&w.length<6)};n.addEventListener("input",E),E();let y=this.contentEl.createDiv({cls:"stashpad-export-genrow"});y.createEl("button",{cls:"stashpad-export-gen",text:"Generate strong passphrase"}).onclick=w=>{w.preventDefault();let k=So(5);n.value=k,o&&(o.value=k),E(),t.forEach(D=>D()),new G.Notice("Generated \u2014 copy it somewhere safe; there's no recovery."),navigator.clipboard?.writeText(k).catch(()=>{})};let v=y.createEl("button",{cls:"stashpad-export-show",text:"Show"});v.onclick=w=>{w.preventDefault();let k=n.type==="password";n.type=k?"text":"password",o&&(o.type=k?"text":"password"),v.setText(k?"Hide":"Show")};let Q=this.contentEl.createEl("div",{cls:"stashpad-export-pw-suite"});Q.setText("Encryption: AES-256-GCM. Checking key-derivation suite\u2026"),this.opts.kdfProbe?this.opts.kdfProbe().then(w=>{Q.toggleClass("is-weak",!w),Q.setText(w?"Encryption: Argon2id + AES-256-GCM \u2014 the strongest suite (used on this device).":"\u26A0\uFE0F Argon2id can't run here, so this will use the weaker PBKDF2 (600k) + AES-256-GCM fallback.")}).catch(()=>Q.setText("Encryption: AES-256-GCM with a password-derived key.")):Q.setText("Encryption: Argon2id + AES-256-GCM (PBKDF2 fallback if Argon2 can't run here).")}let a=null,l=this.app.secretStorage;if(this.opts.offerKeychain&&l){let g=this.contentEl.createDiv({cls:"stashpad-export-remember"});a=g.createEl("input",{type:"checkbox"}),a.id="stashpad-enc-remember",a.checked=!0;let I=g.createEl("label",{text:"Remember on this device (keychain) \u2014 auto-unlock here without re-typing."});I.htmlFor=a.id;let m=this.contentEl.createDiv({cls:"stashpad-export-remember-note"});m.setText("Stored only in this device's keychain \u2014 doesn't sync to your other devices. Anyone with access to this unlocked device + keychain could decrypt."),m.setCssStyles({display:a.checked?"":"none"}),a.onchange=()=>{m.setCssStyles({display:a.checked?"":"none"})}}let c=this.contentEl.createEl("div",{cls:"stashpad-export-error"});c.setCssStyles({display:"none"});let d=g=>{c.setText(g),c.setCssStyles({display:""})},h=this.contentEl.createDiv({cls:"stashpad-export-footer"});h.createEl("button",{text:"Cancel"}).onclick=()=>this.close();let p=h.createEl("button",{cls:"mod-cta",text:e==="setup"?"Set up":e==="change"?"Change":"Unlock"}),f=!1,u=async()=>{if(f)return;let g=s?.value??void 0,I=n?.value??void 0;if((e==="unlock"||e==="change")&&!g){d("Enter your current password.");return}if(e==="setup"||e==="change"){if(!I){d("Enter a password.");return}if(I.length<6){d("Use at least 6 characters.");return}if(I!==o?.value){d("Passwords don't match.");return}}f=!0,p.disabled=!0,c.setCssStyles({display:"none"});let m=p.textContent;p.setText("Working\u2026");try{let C=await this.opts.onSubmit({current:g,next:I,remember:!!a?.checked});if(C){d(C),f=!1,p.disabled=!1,p.setText(m??"OK");return}this.succeeded=!0,this.close()}catch(C){d(`Failed: ${C.message}`),f=!1,p.disabled=!1,p.setText(m??"OK")}};p.onclick=()=>void u(),this.scope.register([],"Enter",g=>{g.preventDefault(),u()}),requestAnimationFrame(()=>(s??n)?.focus())}onClose(){this.contentEl.empty(),this.succeeded||this.opts.onCancel?.()}},Qi=class extends G.Modal{constructor(e,t){super(e);this.opts=t}onOpen(){this.contentEl.empty(),this.modalEl.addClass("stashpad-export-modal","stashpad-encryption-modal"),this.titleEl.setText(this.opts.title),this.contentEl.createEl("p",{cls:"stashpad-export-desc",text:this.opts.body});let e=null;this.opts.requirePassword&&(this.contentEl.createEl("p",{cls:"stashpad-export-desc"}).setText("Enter your encryption password:"),e=this.contentEl.createEl("input",{type:"password"}),e.addClass("stashpad-export-name","stashpad-encryption-field"),e.placeholder="Password"),this.contentEl.createEl("p",{cls:"stashpad-export-desc"}).setText(`Type "${this.opts.phrase}" to confirm.`);let t=this.contentEl.createEl("input",{type:"text"});t.addClass("stashpad-export-name","stashpad-encryption-field"),t.placeholder=this.opts.phrase;let i=this.contentEl.createEl("div",{cls:"stashpad-export-error"});i.setCssStyles({display:"none"});let s=this.contentEl.createDiv({cls:"stashpad-export-footer"});s.createEl("button",{text:"Cancel"}).onclick=()=>this.close();let n=s.createEl("button",{cls:"mod-cta mod-warning",text:this.opts.confirmText}),o=()=>t.value.trim().toLowerCase()===this.opts.phrase.trim().toLowerCase(),a=()=>{n.disabled=!o()||!!this.opts.requirePassword&&!e?.value};t.addEventListener("input",a),e?.addEventListener("input",a),a();let l=!1,c=async()=>{if(!(l||!o())){if(this.opts.requirePassword&&(l=!0,n.disabled=!0,i.setCssStyles({display:"none"}),!await this.opts.requirePassword(e.value))){i.setText("Wrong password."),i.setCssStyles({display:""}),l=!1,a();return}this.close(),await this.opts.onConfirm()}};n.onclick=()=>void c(),this.scope.register([],"Enter",d=>{d.preventDefault(),c()}),requestAnimationFrame(()=>(e??t).focus())}onClose(){this.contentEl.empty()}},us=class extends G.Modal{constructor(e,t){super(e);this.onSubmit=t}onOpen(){this.contentEl.empty(),this.modalEl.addClass("stashpad-export-modal"),this.titleEl.setText("Open Stashpad link"),this.contentEl.createEl("p",{cls:"stashpad-export-desc",text:"Paste one or more obsidian://stashpad links (one per line) to jump to the notes they point to. Multiple links each open in their own tab."});let e=this.contentEl.createDiv({cls:"stashpad-open-link-row"}),t=e.createEl("button",{cls:"stashpad-open-link-paste"});(0,G.setIcon)(t.createSpan({cls:"stashpad-open-link-paste-icon"}),"clipboard-paste"),t.createSpan({text:"Paste"}),t.title="Paste from clipboard";let i=e.createEl("textarea",{attr:{rows:"3"}});i.addClass("stashpad-export-name"),i.placeholder="obsidian://stashpad?folder=\u2026¬e=\u2026",t.onclick=async()=>{try{let l=(await navigator.clipboard?.readText?.())?.trim();l&&(i.value=l,s.hide()),i.focus()}catch{new G.Notice("Couldn't read the clipboard \u2014 paste manually.")}},i.addEventListener("input",()=>s.hide());let s=this.contentEl.createEl("div",{cls:"stashpad-open-link-autohint"});(0,G.setIcon)(s.createSpan({cls:"stashpad-open-link-autohint-icon"}),"clipboard-check"),s.createSpan({text:"Link automatically pasted from your clipboard."}),s.hide();let n=this.contentEl.createDiv({cls:"stashpad-export-footer"});n.createEl("button",{text:"Cancel"}).onclick=()=>this.close();let o=n.createEl("button",{cls:"mod-cta",text:"Open"}),a=()=>{let l=i.value.trim();l&&(this.close(),this.onSubmit(l))};o.onclick=()=>a(),this.scope.register([],"Enter",l=>{l.preventDefault(),a()}),requestAnimationFrame(()=>{i.focus(),navigator.clipboard?.readText?.().then(l=>{!i.value&&l&&/obsidian:\/\/stashpad\?/i.test(l.trim())&&(i.value=l.trim(),i.select(),s.show())}).catch(()=>{})})}onClose(){this.contentEl.empty()}},mn=class extends G.Modal{constructor(e,t,i){super(e);this.onResult=i;this.delivered=!1;this.touched=!1;this.value=t&&/^#[0-9a-f]{6}$/i.test(t)?t:"#888888"}onOpen(){this.contentEl.empty(),this.titleEl.setText("Custom color"),this.modalEl.addClass("stashpad-custom-color-modal");let e=this.contentEl.createDiv({cls:"stashpad-custom-color-row"}),t=e.createDiv({cls:"stashpad-custom-color-preview"});t.style.background=this.value;let i=e.createEl("input",{type:"color"});i.value=this.value,i.addClass("stashpad-custom-color-wheel"),t.onclick=()=>i.click();let s=e.createEl("input",{type:"text"});s.addClass("stashpad-custom-color-hex"),s.placeholder="#RRGGBB",s.value=this.value,s.maxLength=7;let n=d=>{let h=d.startsWith("#")?d:"#"+d;/^#[0-9a-f]{6}$/i.test(h)&&(this.touched=!0,this.value=h,t.style.background=h,i.value=h,s.value!==h&&(s.value=h))};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 l=o.createEl("button",{cls:"mod-cta",text:"Save"});l.title="Apply this color to the selection (without adding to your palette).",l.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",d=>{d.preventDefault(),this.commit({addToPalette:!1})}),this.scope.register(["Mod"],"Enter",d=>{d.preventDefault(),this.commit({addToPalette:!0})}),requestAnimationFrame(()=>s.focus())}commit(e){this.delivered=!0,this.close(),this.onResult(this.value,e)}onClose(){!this.delivered&&this.touched&&(this.delivered=!0,this.onResult(this.value,{addToPalette:!1})),this.contentEl.empty()}},ps=class ps extends G.Modal{constructor(e,t,i,s,n){super(e);this.currentColor=t;this.customPalette=i;this.onPick=s;this.onDeleteCustom=n;this.focusIdx=-1;this.scopeBound=!1;this.items=[]}onOpen(){this.contentEl.empty(),this.titleEl.setText("Pick a color"),this.modalEl.addClass("stashpad-color-modal");let e=this.contentEl.createDiv({cls:"stashpad-color-grid"});this.items=[];let t=e.createDiv({cls:"stashpad-color-tile stashpad-color-none"});t.title="No color",t.onclick=()=>this.activate(0),this.items.push({kind:"none",color:null,el:t});let i=[...ps.DEFAULT_PALETTE,...this.customPalette];for(let a of i){let l=e.createDiv({cls:"stashpad-color-tile"});l.style.background=a,l.title=a;let c=!ps.DEFAULT_PALETTE.some(h=>h.toLowerCase()===a.toLowerCase()),d=this.items.length;if(l.onclick=()=>this.activate(d),c&&this.onDeleteCustom){let h=l.createSpan({cls:"stashpad-color-tile-del",text:"\xD7"});h.title="Remove from palette",h.onclick=p=>{p.stopPropagation(),this.handleDelete(a)}}this.items.push({kind:c?"custom":"preset",color:a,el:l})}let s=e.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.scopeBound||(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)}),this.scopeBound=!0),requestAnimationFrame(()=>this.modalEl.focus())}activate(e){if(e<0||e>=this.items.length)return;this.focusIdx=e,this.refreshActive();let t=this.items[e];if(t.kind==="add"){this.close(),new mn(this.app,this.currentColor,(i,s)=>{this.onPick(i,s)}).open();return}this.close(),this.onPick(t.color,{addToPalette:!1})}columns(){if(!this.items.length)return 1;let e=this.items[0].el.parentElement;if(!e)return 1;let t=e.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(e){if(this.onDeleteCustom)try{let t=await this.onDeleteCustom(e);this.customPalette=Array.isArray(t)?t:this.customPalette.filter(i=>i.toLowerCase()!==e.toLowerCase()),this.onOpen()}catch(t){console.warn("Stashpad: palette delete failed",t)}}moveFocus(e){if(!this.items.length)return;let t=Math.max(0,Math.min(this.items.length-1,this.focusIdx+e));this.focusIdx=t,this.refreshActive()}refreshActive(){for(let e=0;e<this.items.length;e++)this.items[e].el.toggleClass("is-active",e===this.focusIdx)}onClose(){this.contentEl.empty()}};ps.DEFAULT_PALETTE=["#E07A78","#E08A47","#E0A744","#B0CC6E","#6BC07A","#5BA9CE","#9B82C9","#C57AB5","#D75AA8"];jt=ps,j=class extends G.Modal{constructor(e,t,i,s,n,o="Cancel",a=!1){super(e);this.titleText=t;this.message=i;this.confirmText=s;this.onChoose=n;this.cancelText=o;this.dangerous=a;this.didChoose=!1}onOpen(){this.modalEl?.addClass("stashpad-compact-modal"),this.contentEl.empty(),this.titleEl.setText(this.titleText);let e=this.contentEl.createDiv({cls:"stashpad-confirm-body"});for(let n of this.message.split(` +`))e.createDiv({cls:"stashpad-confirm-line",text:n});let t=this.contentEl.createDiv({cls:"stashpad-modal-btns"}),i=t.createEl("button",{text:this.cancelText});i.onclick=()=>{this.didChoose=!0,this.close(),this.onChoose(!1)};let s=t.createEl("button",{cls:"mod-cta",text:this.confirmText});s.onclick=()=>{this.didChoose=!0,this.close(),this.onChoose(!0)},requestAnimationFrame(()=>(this.dangerous?i:s).focus())}onClose(){this.contentEl.empty(),this.didChoose||(this.didChoose=!0,this.onChoose(!1))}},fs=class extends G.Modal{constructor(e,t,i,s={}){super(e);this.levels=t;this.onPick=i;this.opts=s}onOpen(){this.modalEl?.addClass("stashpad-compact-modal"),this.modalEl?.addClass("stashpad-breadcrumb-modal"),this.contentEl.empty(),this.titleEl.setText("Jump to level");let e=this.contentEl.createDiv({cls:"stashpad-bc-levels"});for(let t of this.levels){let i=e.createDiv({cls:"stashpad-bc-level-row"});if(t.isCurrent&&i.addClass("is-current"),i.createSpan({cls:"stashpad-bc-level-num",text:String(t.level)}),i.createSpan({cls:"stashpad-bc-level-label",text:t.label}),!t.isCurrent){i.setAttribute("role","button"),i.setAttribute("tabindex","0");let s=()=>{this.close(),this.onPick(t.id)};i.onclick=s,i.onkeydown=n=>{(n.key==="Enter"||n.key===" ")&&(n.preventDefault(),s())}}this.opts.onContext&&(i.oncontextmenu=s=>{s.preventDefault(),this.opts.onContext(t.id,s,i,()=>this.close())},this.opts.attachLongPress?.(i,()=>this.opts.onContext(t.id,null,i,()=>this.close())))}}onClose(){this.contentEl.empty()}};ze=class extends G.Modal{constructor(e,t,i,s={}){super(e);this.current=t;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(this.opts.title??"Set due date");let e=null;if(this.current){let Q=Date.parse(this.current);Number.isNaN(Q)||(e=new Date(Q))}let t=this.contentEl.createDiv({cls:"stashpad-due-picker"}),i=t.createDiv({cls:"stashpad-due-fields"}),s=i.createDiv({cls:"stashpad-due-field"}),n=s.createSpan({cls:"stashpad-due-field-icon"});(0,G.setIcon)(n,"calendar");let o=s.createEl("input",{type:"date",cls:"stashpad-due-date"}),a=s.createSpan({cls:"stashpad-due-clear",attr:{"aria-label":"Clear date"}});(0,G.setIcon)(a,"x"),a.onclick=()=>{o.value="",o.focus()};let l=i.createDiv({cls:"stashpad-due-field"}),c=l.createSpan({cls:"stashpad-due-field-icon"});(0,G.setIcon)(c,"clock");let d=l.createEl("input",{type:"time",cls:"stashpad-due-time"}),h=l.createSpan({cls:"stashpad-due-clear",attr:{"aria-label":"Clear time"}});(0,G.setIcon)(h,"x"),h.onclick=()=>{d.value="",d.focus()},n.onclick=()=>{try{o.showPicker?.()}catch{}},c.onclick=()=>this.openTimeNumpad(c,d),e&&(o.value=this.toDateValue(e),d.value=this.toTimeValue(e));let p=(this.opts.quickAdjusts??Jr).map(Q=>({raw:Q,min:qr(Q)})).filter(Q=>Q.min!=null);if(p.length>0){let Q=1,w=t.createDiv({cls:"stashpad-due-quickadjust"}),k=w.createEl("button",{cls:"stashpad-due-adjust-flip",attr:{type:"button"}}),D=()=>{k.setText(Q>0?"+":"\u2212"),k.toggleClass("is-minus",Q<0),k.title=Q>0?"Adding time (click to subtract)":"Subtracting time (click to add)"};D(),k.onclick=()=>{Q=-Q,D()};let H=R=>{let L=new Date,x,U,T;if(o.value){let[K,Y,Z]=o.value.split("-").map(V=>parseInt(V,10));x=K,U=Y-1,T=Z}else x=L.getFullYear(),U=L.getMonth(),T=L.getDate();let b,M;if(d.value){let[K,Y]=d.value.split(":").map(Z=>parseInt(Z,10));b=K,M=Y}else b=L.getHours(),M=L.getMinutes();let O=new Date(x,U,T,b,M,0,0);O.setMinutes(O.getMinutes()+Q*R),o.value=this.toDateValue(O),d.value=this.toTimeValue(O)};for(let R of p){let L=w.createEl("button",{cls:"stashpad-due-adjust-btn",text:R.raw,attr:{type:"button"}});L.onclick=()=>H(R.min)}}this.opts.hideAssignees||this.renderAssignSection(t);let f=t.createDiv({cls:"stashpad-due-grid"}),u=(Q,w)=>{let k=f.createEl("button",{cls:"stashpad-due-btn stashpad-due-preset",text:Q});k.onclick=()=>{let D=w();o.value=this.toDateValue(D),d.value||(d.value=this.toTimeValue(D))}},g=Q=>(Q.setHours(9,0,0,0),Q);u("Today",()=>g(this.startOfTodayLocal())),u("Tomorrow",()=>{let Q=this.startOfTodayLocal();return Q.setDate(Q.getDate()+1),g(Q)}),u("Next week",()=>{let Q=this.startOfTodayLocal();return Q.setDate(Q.getDate()+7),g(Q)});let I=f.createEl("button",{cls:"stashpad-due-btn",text:"Clear"});I.onclick=()=>{o.value="",d.value="",o.focus()};let m=null,C=null,B=null;if(this.opts.showRecurrence){let Q=t.createEl("details",{cls:"stashpad-due-recur"});(this.opts.currentRepeat||this.opts.currentAutoDoneAfter||this.opts.currentRemindEvery)&&(Q.open=!0),Q.createEl("summary",{text:"\u{1F501} Repeat & reminders"});let w=(k,D,H)=>{let R=Q.createDiv({cls:"stashpad-due-recur-row"});R.createEl("label",{text:k});let L=R.createEl("input",{type:"text",attr:{placeholder:D}});return H&&(L.value=H),L};m=w("Repeat",'e.g. "every weekday", "every 30 days when done"',this.opts.currentRepeat),C=w("Auto-complete after",'e.g. "1d" \u2014 mark done once this overdue',this.opts.currentAutoDoneAfter),B=w("Remind every",'e.g. "2h" \u2014 re-notify until done',this.opts.currentRemindEvery)}let E=()=>this.opts.showRecurrence?{repeat:m.value.trim(),autoDoneAfter:C.value.trim(),remindEvery:B.value.trim()}:{},y=f.createEl("button",{cls:"stashpad-due-btn",text:"Cancel"});y.onclick=()=>{this.didChoose=!0,this.close()};let v=f.createEl("button",{cls:"stashpad-due-btn mod-cta",text:"Set"});v.onclick=()=>{if(!o.value){this.didChoose=!0,this.close(),this.onPick({iso:null,assignees:this.assignees,...E()});return}let[Q,w,k]=o.value.split("-").map(L=>parseInt(L,10)),D=9,H=0;if(d.value){let[L,x]=d.value.split(":").map(U=>parseInt(U,10));D=L,H=x}let R=new Date(Q,w-1,k,D,H,0,0);this.didChoose=!0,this.close(),this.onPick({iso:R.toISOString(),assignees:this.assignees,...E()})},requestAnimationFrame(()=>o.focus())}onClose(){this.tinyClosePopover?.(),this.contentEl.empty(),this.didChoose}renderAssignSection(e){$r(e,{knownAuthors:this.opts.knownAuthors??[],initial:this.assignees,onChange:t=>{this.assignees=t}})}openTimeNumpad(e,t){this.tinyClosePopover?.();let i=e.ownerDocument??document,s=i.defaultView??window,n=9,o=0;if(t.value){let[I,m]=t.value.split(":").map(C=>parseInt(C,10));Number.isFinite(I)&&(n=I),Number.isFinite(m)&&(o=m)}else{let I=new Date;n=I.getHours(),o=I.getMinutes()}let a=n>=12?"pm":"am",l=n===0?12:n>12?n-12:n,d=(this.modalEl??i.body).createDiv({cls:"stashpad-when-popover stashpad-due-time-pop"});d.setCssStyles({position:"fixed",zIndex:"9999"});let h=null,p=()=>{d.remove(),i.removeEventListener("mousedown",f,!0),i.removeEventListener("keydown",u,!0),this.tinyClosePopover===p&&(this.tinyClosePopover=null)},f=I=>{!d.contains(I.target)&&I.target!==e&&!e.contains(I.target)&&p()},u=I=>{I.key==="Escape"?(I.preventDefault(),I.stopPropagation(),p()):I.key==="Enter"&&h&&(I.preventDefault(),I.stopPropagation(),h())};this.tinyClosePopover=p,zs(d,{seedH:l,seedM:o,seedPeriod:a,close:p,setOnEnter:I=>{h=I},onFinalize:I=>{t.value=`${String(I.hours24).padStart(2,"0")}:${String(I.minutes).padStart(2,"0")}`}});let g=e.getBoundingClientRect();d.setCssStyles({left:`${Math.max(8,Math.min(g.left,s.innerWidth-220))}px`,top:`${g.bottom+4}px`}),setTimeout(()=>{i.addEventListener("mousedown",f,!0),i.addEventListener("keydown",u,!0),d.querySelector(".stashpad-when-time-field")?.focus()},0)}startOfTodayLocal(){let e=new Date;return e.setHours(0,0,0,0),e}toDateValue(e){let t=e.getFullYear(),i=String(e.getMonth()+1).padStart(2,"0"),s=String(e.getDate()).padStart(2,"0");return`${t}-${i}-${s}`}toTimeValue(e){let t=String(e.getHours()).padStart(2,"0"),i=String(e.getMinutes()).padStart(2,"0");return`${t}:${i}`}},ei=class ei extends G.Modal{constructor(e,t,i,s=null,n){super(e);this.service=t;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 e=this.contentEl.createDiv({cls:"stashpad-log-toolbar"});if(this.countEl=e.createSpan({cls:"stashpad-log-count"}),this.updateCount(),this.filterSelEl=e.createEl("select",{cls:"stashpad-log-type-filter"}),this.filterSelEl.onchange=()=>this.setCategoryFilter(this.filterSelEl.value||null),this.refreshCategoryFilter(),this.authorSelEl=e.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=e.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 t=e.createEl("button",{cls:"mod-warning",text:"Clear history"});t.onclick=()=>{new j(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()},"Cancel",!0).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(e){this.authorFilter!==e&&(this.authorFilter=e,this.refreshList(),this.renderFooter())}refreshAuthorFilter(){if(!this.authorSelEl)return;let e=this.authorSelEl;e.empty(),e.createEl("option",{text:"All authors"}).value="all",this.currentAuthorId&&(e.createEl("option",{text:"Me"}).value="me"),e.createEl("option",{text:"Cross-author"}).value="cross";let t=new Set;for(let s of this.records)s.authorId&&s.authorId!==this.currentAuthorId&&t.add(s.authorId);if(t.size>0){let s=e.createEl("option",{text:"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"});s.disabled=!0;for(let n of[...t].sort())e.createEl("option",{text:n}).value=n}new Set(["all","cross",...this.currentAuthorId?["me"]:[],...t]).has(this.authorFilter)||(this.authorFilter="all"),e.value=this.authorFilter}isCrossAuthor(e){let t=e.authorId??null;if(!t)return!1;for(let i of e.affectedAuthorIds??[])if(i&&i!==t)return!0;if(!this.getNoteAuthorIds)return!1;for(let i of e.affectedIds){let s=this.getNoteAuthorIds(i);for(let n of s)if(n&&n!==t)return!0}return!1}onClose(){this.unsubscribe?.(),this.unsubscribe=null,this.contentEl.empty()}setCategoryFilter(e){(this.categoryFilter??null)!==(e??null)&&(this.categoryFilter=e,this.refreshList(),this.renderFooter())}refreshCategoryFilter(){if(!this.filterSelEl)return;let e=this.filterSelEl;e.empty();let t=new Map;for(let n of this.records)t.set(n.category,(t.get(n.category)??0)+1);let i=[...t.entries()].sort((n,o)=>o[1]-n[1]||n[0].localeCompare(o[0])),s=e.createEl("option",{text:`All categories (${this.records.length})`});s.value="";for(let[n,o]of i){let a=e.createEl("option",{text:`${n} (${o})`});a.value=n}this.categoryFilter&&!t.has(this.categoryFilter)&&(this.categoryFilter=null),e.value=this.categoryFilter??""}refreshList(){if(this.listEl){if(this.visible=this.records.filter(e=>{if(this.categoryFilter&&e.category!==this.categoryFilter)return!1;switch(this.authorFilter){case"all":return!0;case"me":return!!this.currentAuthorId&&e.authorId===this.currentAuthorId;case"cross":return this.isCrossAuthor(e);default:return e.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(ei.PAGE)}}appendMore(e){if(!this.listEl)return;let t=Math.min(this.visible.length,this.shownCount+e);for(let i=this.shownCount;i<t;i++)this.renderRow(this.listEl,this.visible[i]);this.shownCount=t,this.updateCount()}renderRow(e,t){let i=e.createDiv({cls:`stashpad-notif-row stashpad-notif-row-${t.kind}`}),s=i.createDiv({cls:"stashpad-notif-meta"}),n=s.createSpan({cls:"stashpad-notif-time"}),o=od(t.ts);if(n.setText(o.fromNow()),n.title=o.format("YYYY-MM-DD HH:mm:ss"),s.createSpan({cls:`stashpad-notif-cat stashpad-notif-cat-${t.category}`}).setText(t.category),i.createDiv({cls:"stashpad-notif-msg"}).setText(t.message),t.actionLabels.length>0){let c=i.createDiv({cls:"stashpad-notif-actions-snapshot"});for(let d of t.actionLabels){let h=c.createSpan({cls:"stashpad-notif-action-chip"});h.setText(d),h.title="Action button was shown on the original toast (handler not retained)."}}}updateCount(){if(!this.countEl)return;let e=this.visible.length,t=this.categoryFilter?`${e} ${this.categoryFilter} notification${e===1?"":"s"}`:`${e} notification${e===1?"":"s"}`;this.shownCount===0||this.shownCount>=e?this.countEl.setText(t):this.countEl.setText(`Showing ${this.shownCount} of ${t}`)}renderFooter(){if(!this.footerEl)return;this.footerEl.empty();let e=this.visible.length-this.shownCount;if(e<=0)return;let t=this.footerEl.createEl("button",{text:`Load ${Math.min(ei.PAGE,e)} more`});if(t.onclick=()=>{this.appendMore(ei.PAGE),this.renderFooter()},e>ei.PAGE){let i=this.footerEl.createEl("button",{text:`Load all (${e})`});i.onclick=()=>{this.appendMore(e),this.renderFooter()}}}};ei.PAGE=100;hs=ei,ea=class extends G.Modal{constructor(e,t){super(e);this.entries=t}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 e=this.contentEl.createDiv({cls:"stashpad-import-log-list"});for(let t of this.entries){let i=e.createDiv({cls:"stashpad-import-log-row"}),s=(0,G.moment)(t.ts).format("YYYY-MM-DD HH:mm");i.createSpan({cls:"stashpad-import-log-when",text:s});let n=t.kind==="folder"?"folder":t.kind==="md"?"note":"file";i.createSpan({cls:`stashpad-import-log-kind is-${t.kind}`,text:n}),i.createSpan({cls:"stashpad-import-log-name",text:t.originalName});let o=[t.folder.split("/").pop()||t.folder];t.notePaths.length>1&&o.push(`${t.notePaths.length} notes`),i.createSpan({cls:"stashpad-import-log-meta",text:o.join(" \xB7 ")})}}onClose(){this.contentEl.empty()}},Is=class extends G.Modal{constructor(e,t,i){super(e);this.message=t;this.onChoose=i;this.chose=!1}onOpen(){this.modalEl?.addClass("stashpad-compact-modal"),this.contentEl.empty(),this.titleEl.setText("Possible duplicate import");let e=this.contentEl.createDiv({cls:"stashpad-confirm-body"});for(let o of this.message.split(` +`))e.createDiv({cls:"stashpad-confirm-line",text:o});let t=this.contentEl.createDiv({cls:"stashpad-modal-btns"}),i=t.createEl("button",{text:"Skip duplicates"});i.onclick=()=>{this.chose=!0,this.close(),this.onChoose("skip")};let s=t.createEl("button",{text:"Replace existing"});s.onclick=()=>{this.chose=!0,this.close(),this.onChoose("replace")};let n=t.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()}},ms=class extends G.Modal{constructor(e,t,i){super(e);this.items=t;this.onConfirm=i}onOpen(){this.titleEl.setText("Re-encrypt everything applicable?");let{contentEl:e}=this;e.createEl("p",{cls:"setting-item-description",text:"These notes should be encrypted (they were unlocked/restored, or their folder is set to encrypt) but are currently plaintext. Untick anything you want to leave readable."});let t=e.createDiv({cls:"stashpad-reenc-list"}),i=[];this.items.forEach(o=>{let a=t.createEl("label",{cls:"stashpad-reenc-row"}),l=a.createEl("input",{type:"checkbox"});l.checked=!0,i.push(l);let c=a.createDiv({cls:"stashpad-reenc-body"});c.createDiv({cls:"stashpad-reenc-label",text:o.label}),c.createDiv({cls:"stashpad-reenc-detail",text:o.detail})});let s=e.createDiv({cls:"modal-button-container"}),n=s.createEl("button",{cls:"mod-cta",text:"Re-encrypt checked"});n.onclick=()=>{let o=i.map((a,l)=>a.checked?l:-1).filter(a=>a>=0);this.close(),o.length&&this.onConfirm(o)},s.createEl("button",{text:"Cancel"}).onclick=()=>this.close()}onClose(){this.contentEl.empty()}}});function xd(A,r){return Dd(A,r||{},0,0)}function Nd(A,r){return Qd(A,{i:2},r&&r.out,r&&r.dictionary)}function On(A,r){if(r){for(var e=new pe(A.length),t=0;t<A.length;++t)e[t]=A.charCodeAt(t);return e}if(gl)return gl.encode(A);for(var i=A.length,s=new pe(A.length+(A.length>>1)),n=0,o=function(c){s[n++]=c},t=0;t<i;++t){if(n+5>s.length){var a=new pe(n+8+(i-t<<1));a.set(s),s=a}var l=A.charCodeAt(t);l<128||r?o(l):l<2048?(o(192|l>>6),o(128|l&63)):l>55295&&l<57344?(l=65536+(l&1047552)|A.charCodeAt(++t)&1023,o(240|l>>18),o(128|l>>12&63),o(128|l>>6&63),o(128|l&63)):(o(224|l>>12),o(128|l>>6&63),o(128|l&63))}return Ss(s,0,n)}function va(A,r){if(r){for(var e="",t=0;t<A.length;t+=16384)e+=String.fromCharCode.apply(null,A.subarray(t,t+16384));return e}else{if(Ba)return Ba.decode(A);var i=Md(A),s=i.s,e=i.r;return e.length&&Se(8),s}}function vl(A,r){r||(r={});var e={},t=[];El(A,"",e,r);var i=0,s=0;for(var n in e){var o=e[n],a=o[0],l=o[1],c=l.level==0?0:8,d=On(n),h=d.length,p=l.comment,f=p&&On(p),u=f&&f.length,g=ya(l.extra);h>65535&&Se(11);var I=c?xd(a,l):a,m=I.length,C=bd();C.p(a),t.push(wl(l,{size:a.length,crc:C.d(),c:I,f:d,m:f,u:h!=n.length||f&&p.length!=u,o:i,compression:c})),i+=30+h+g+m,s+=76+2*(h+g)+(u||0)+m}for(var B=new pe(s+22),E=i,y=s-i,v=0;v<t.length;++v){var d=t[v];ul(B,d.o,d,d.f,d.u,d.c.length);var Q=30+d.f.length+ya(d.extra);B.set(d.c,d.o+Q),ul(B,i,d,d.f,d.u,d.c.length,d.o,d.m),i+=16+Q+(d.m?d.m.length:0)}return Ud(B,i,t.length,y,E),B}function Ql(A,r){for(var e={},t=A.length-22;Ke(A,t)!=101010256;--t)(!t||A.length-t>65558)&&Se(13);var i=rt(A,t+8);if(!i)return{};var s=Ke(A,t+16),n=Ke(A,t-20)==117853008;if(n){var o=Ke(A,t-12);n=Ke(A,o)==101075792,n&&(i=Ke(A,o+32),s=Ke(A,o+48))}for(var a=r&&r.filter,l=0;l<i;++l){var c=Hd(A,s,n),d=c[0],h=c[1],p=c[2],f=c[3],u=c[4],g=c[5],I=Pd(A,g);s=u,(!a||a({name:f,size:h,originalSize:p,compression:d}))&&(d?d==8?e[f]=Nd(A.subarray(I,I+h),{out:new pe(p)}):Se(14,"unknown compression type "+d):e[f]=Ss(A,I,I+h))}return e}var pe,Re,wa,Kn,Jn,fa,fl,Il,ml,Ia,Cl,Cd,Al,ma,wt,_,lt,Gt,_,_,_,_,Fs,_,Bd,yd,wd,Ed,ha,Ve,pa,Ea,Ss,vd,Se,Qd,Et,Qs,ga,Ca,hl,ks,Bl,pl,kd,yl,Fd,Sd,bd,Dd,wl,rt,Ke,ua,ke,El,gl,Ba,Td,Md,Pd,Hd,Rd,ya,ul,Ud,kl=de(()=>{pe=Uint8Array,Re=Uint16Array,wa=Int32Array,Kn=new pe([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,0,0,0]),Jn=new pe([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,0,0]),fa=new pe([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),fl=function(A,r){for(var e=new Re(31),t=0;t<31;++t)e[t]=r+=1<<A[t-1];for(var i=new wa(e[30]),t=1;t<30;++t)for(var s=e[t];s<e[t+1];++s)i[s]=s-e[t]<<5|t;return{b:e,r:i}},Il=fl(Kn,2),ml=Il.b,Ia=Il.r;ml[28]=258,Ia[258]=28;Cl=fl(Jn,0),Cd=Cl.b,Al=Cl.r,ma=new Re(32768);for(_=0;_<32768;++_)wt=(_&43690)>>1|(_&21845)<<1,wt=(wt&52428)>>2|(wt&13107)<<2,wt=(wt&61680)>>4|(wt&3855)<<4,ma[_]=((wt&65280)>>8|(wt&255)<<8)>>1;lt=function(A,r,e){for(var t=A.length,i=0,s=new Re(r);i<t;++i)A[i]&&++s[A[i]-1];var n=new Re(r);for(i=1;i<r;++i)n[i]=n[i-1]+s[i-1]<<1;var o;if(e){o=new Re(1<<r);var a=15-r;for(i=0;i<t;++i)if(A[i])for(var l=i<<4|A[i],c=r-A[i],d=n[A[i]-1]++<<c,h=d|(1<<c)-1;d<=h;++d)o[ma[d]>>a]=l}else for(o=new Re(t),i=0;i<t;++i)A[i]&&(o[i]=ma[n[A[i]-1]++]>>15-A[i]);return o},Gt=new pe(288);for(_=0;_<144;++_)Gt[_]=8;for(_=144;_<256;++_)Gt[_]=9;for(_=256;_<280;++_)Gt[_]=7;for(_=280;_<288;++_)Gt[_]=8;Fs=new pe(32);for(_=0;_<32;++_)Fs[_]=5;Bd=lt(Gt,9,0),yd=lt(Gt,9,1),wd=lt(Fs,5,0),Ed=lt(Fs,5,1),ha=function(A){for(var r=A[0],e=1;e<A.length;++e)A[e]>r&&(r=A[e]);return r},Ve=function(A,r,e){var t=r/8|0;return(A[t]|A[t+1]<<8)>>(r&7)&e},pa=function(A,r){var e=r/8|0;return(A[e]|A[e+1]<<8|A[e+2]<<16)>>(r&7)},Ea=function(A){return(A+7)/8|0},Ss=function(A,r,e){return(r==null||r<0)&&(r=0),(e==null||e>A.length)&&(e=A.length),new pe(A.subarray(r,e))},vd=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],Se=function(A,r,e){var t=new Error(r||vd[A]);if(t.code=A,Error.captureStackTrace&&Error.captureStackTrace(t,Se),!e)throw t;return t},Qd=function(A,r,e,t){var i=A.length,s=t?t.length:0;if(!i||r.f&&!r.l)return e||new pe(0);var n=!e,o=n||r.i!=2,a=r.i;n&&(e=new pe(i*3));var l=function(fe){var we=e.length;if(fe>we){var se=new pe(Math.max(we*2,fe));se.set(e),e=se}},c=r.f||0,d=r.p||0,h=r.b||0,p=r.l,f=r.d,u=r.m,g=r.n,I=i*8;do{if(!p){c=Ve(A,d,1);var m=Ve(A,d+1,3);if(d+=3,m)if(m==1)p=yd,f=Ed,u=9,g=5;else if(m==2){var y=Ve(A,d,31)+257,v=Ve(A,d+10,15)+4,Q=y+Ve(A,d+5,31)+1;d+=14;for(var w=new pe(Q),k=new pe(19),D=0;D<v;++D)k[fa[D]]=Ve(A,d+D*3,7);d+=v*3;for(var H=ha(k),R=(1<<H)-1,L=lt(k,H,1),D=0;D<Q;){var x=L[Ve(A,d,R)];d+=x&15;var C=x>>4;if(C<16)w[D++]=C;else{var U=0,T=0;for(C==16?(T=3+Ve(A,d,3),d+=2,U=w[D-1]):C==17?(T=3+Ve(A,d,7),d+=3):C==18&&(T=11+Ve(A,d,127),d+=7);T--;)w[D++]=U}}var b=w.subarray(0,y),M=w.subarray(y);u=ha(b),g=ha(M),p=lt(b,u,1),f=lt(M,g,1)}else Se(1);else{var C=Ea(d)+4,B=A[C-4]|A[C-3]<<8,E=C+B;if(E>i){a&&Se(0);break}o&&l(h+B),e.set(A.subarray(C,E),h),r.b=h+=B,r.p=d=E*8,r.f=c;continue}if(d>I){a&&Se(0);break}}o&&l(h+131072);for(var O=(1<<u)-1,K=(1<<g)-1,Y=d;;Y=d){var U=p[pa(A,d)&O],Z=U>>4;if(d+=U&15,d>I){a&&Se(0);break}if(U||Se(2),Z<256)e[h++]=Z;else if(Z==256){Y=d,p=null;break}else{var V=Z-254;if(Z>264){var D=Z-257,q=Kn[D];V=Ve(A,d,(1<<q)-1)+ml[D],d+=q}var ee=f[pa(A,d)&K],ue=ee>>4;ee||Se(3),d+=ee&15;var M=Cd[ue];if(ue>3){var q=Jn[ue];M+=pa(A,d)&(1<<q)-1,d+=q}if(d>I){a&&Se(0);break}o&&l(h+131072);var oe=h+V;if(h<M){var ie=s-M,te=Math.min(M,oe);for(ie+h<0&&Se(3);h<te;++h)e[h]=t[ie+h]}for(;h<oe;++h)e[h]=e[h-M]}}r.l=p,r.p=Y,r.b=h,r.f=c,p&&(c=1,r.m=u,r.d=f,r.n=g)}while(!c);return h!=e.length&&n?Ss(e,0,h):e.subarray(0,h)},Et=function(A,r,e){e<<=r&7;var t=r/8|0;A[t]|=e,A[t+1]|=e>>8},Qs=function(A,r,e){e<<=r&7;var t=r/8|0;A[t]|=e,A[t+1]|=e>>8,A[t+2]|=e>>16},ga=function(A,r){for(var e=[],t=0;t<A.length;++t)A[t]&&e.push({s:t,f:A[t]});var i=e.length,s=e.slice();if(!i)return{t:yl,l:0};if(i==1){var n=new pe(e[0].s+1);return n[e[0].s]=1,{t:n,l:1}}e.sort(function(E,y){return E.f-y.f}),e.push({s:-1,f:25001});var o=e[0],a=e[1],l=0,c=1,d=2;for(e[0]={s:-1,f:o.f+a.f,l:o,r:a};c!=i-1;)o=e[e[l].f<e[d].f?l++:d++],a=e[l!=c&&e[l].f<e[d].f?l++:d++],e[c++]={s:-1,f:o.f+a.f,l:o,r:a};for(var h=s[0].s,t=1;t<i;++t)s[t].s>h&&(h=s[t].s);var p=new Re(h+1),f=Ca(e[c-1],p,0);if(f>r){var t=0,u=0,g=f-r,I=1<<g;for(s.sort(function(y,v){return p[v.s]-p[y.s]||y.f-v.f});t<i;++t){var m=s[t].s;if(p[m]>r)u+=I-(1<<f-p[m]),p[m]=r;else break}for(u>>=g;u>0;){var C=s[t].s;p[C]<r?u-=1<<r-p[C]++-1:++t}for(;t>=0&&u;--t){var B=s[t].s;p[B]==r&&(--p[B],++u)}f=r}return{t:new pe(p),l:f}},Ca=function(A,r,e){return A.s==-1?Math.max(Ca(A.l,r,e+1),Ca(A.r,r,e+1)):r[A.s]=e},hl=function(A){for(var r=A.length;r&&!A[--r];);for(var e=new Re(++r),t=0,i=A[0],s=1,n=function(a){e[t++]=a},o=1;o<=r;++o)if(A[o]==i&&o!=r)++s;else{if(!i&&s>2){for(;s>138;s-=138)n(32754);s>2&&(n(s>10?s-11<<5|28690:s-3<<5|12305),s=0)}else if(s>3){for(n(i),--s;s>6;s-=6)n(8304);s>2&&(n(s-3<<5|8208),s=0)}for(;s--;)n(i);s=1,i=A[o]}return{c:e.subarray(0,t),n:r}},ks=function(A,r){for(var e=0,t=0;t<r.length;++t)e+=A[t]*r[t];return e},Bl=function(A,r,e){var t=e.length,i=Ea(r+2);A[i]=t&255,A[i+1]=t>>8,A[i+2]=A[i]^255,A[i+3]=A[i+1]^255;for(var s=0;s<t;++s)A[i+s+4]=e[s];return(i+4+t)*8},pl=function(A,r,e,t,i,s,n,o,a,l,c){Et(r,c++,e),++i[256];for(var d=ga(i,15),h=d.t,p=d.l,f=ga(s,15),u=f.t,g=f.l,I=hl(h),m=I.c,C=I.n,B=hl(u),E=B.c,y=B.n,v=new Re(19),Q=0;Q<m.length;++Q)++v[m[Q]&31];for(var Q=0;Q<E.length;++Q)++v[E[Q]&31];for(var w=ga(v,7),k=w.t,D=w.l,H=19;H>4&&!k[fa[H-1]];--H);var R=l+5<<3,L=ks(i,Gt)+ks(s,Fs)+n,x=ks(i,h)+ks(s,u)+n+14+3*H+ks(v,k)+2*v[16]+3*v[17]+7*v[18];if(a>=0&&R<=L&&R<=x)return Bl(r,c,A.subarray(a,a+l));var U,T,b,M;if(Et(r,c,1+(x<L)),c+=2,x<L){U=lt(h,p,0),T=h,b=lt(u,g,0),M=u;var O=lt(k,D,0);Et(r,c,C-257),Et(r,c+5,y-1),Et(r,c+10,H-4),c+=14;for(var Q=0;Q<H;++Q)Et(r,c+3*Q,k[fa[Q]]);c+=3*H;for(var K=[m,E],Y=0;Y<2;++Y)for(var Z=K[Y],Q=0;Q<Z.length;++Q){var V=Z[Q]&31;Et(r,c,O[V]),c+=k[V],V>15&&(Et(r,c,Z[Q]>>5&127),c+=Z[Q]>>12)}}else U=Bd,T=Gt,b=wd,M=Fs;for(var Q=0;Q<o;++Q){var q=t[Q];if(q>255){var V=q>>18&31;Qs(r,c,U[V+257]),c+=T[V+257],V>7&&(Et(r,c,q>>23&31),c+=Kn[V]);var ee=q&31;Qs(r,c,b[ee]),c+=M[ee],ee>3&&(Qs(r,c,q>>5&8191),c+=Jn[ee])}else Qs(r,c,U[q]),c+=T[q]}return Qs(r,c,U[256]),c+T[256]},kd=new wa([65540,131080,131088,131104,262176,1048704,1048832,2114560,2117632]),yl=new pe(0),Fd=function(A,r,e,t,i,s){var n=s.z||A.length,o=new pe(t+n+5*(1+Math.ceil(n/7e3))+i),a=o.subarray(t,o.length-i),l=s.l,c=(s.r||0)&7;if(r){c&&(a[0]=s.r>>3);for(var d=kd[r-1],h=d>>13,p=d&8191,f=(1<<e)-1,u=s.p||new Re(32768),g=s.h||new Re(f+1),I=Math.ceil(e/3),m=2*I,C=function(Ae){return(A[Ae]^A[Ae+1]<<I^A[Ae+2]<<m)&f},B=new wa(25e3),E=new Re(288),y=new Re(32),v=0,Q=0,w=s.i||0,k=0,D=s.w||0,H=0;w+2<n;++w){var R=C(w),L=w&32767,x=g[R];if(u[L]=x,g[R]=L,D<=w){var U=n-w;if((v>7e3||k>24576)&&(U>423||!l)){c=pl(A,a,0,B,E,y,Q,k,H,w-H,c),k=v=Q=0,H=w;for(var T=0;T<286;++T)E[T]=0;for(var T=0;T<30;++T)y[T]=0}var b=2,M=0,O=p,K=L-x&32767;if(U>2&&R==C(w-K))for(var Y=Math.min(h,U)-1,Z=Math.min(32767,w),V=Math.min(258,U);K<=Z&&--O&&L!=x;){if(A[w+b]==A[w+b-K]){for(var q=0;q<V&&A[w+q]==A[w+q-K];++q);if(q>b){if(b=q,M=K,q>Y)break;for(var ee=Math.min(K,q-2),ue=0,T=0;T<ee;++T){var oe=w-K+T&32767,ie=u[oe],te=oe-ie&32767;te>ue&&(ue=te,x=oe)}}}L=x,x=u[L],K+=L-x&32767}if(M){B[k++]=268435456|Ia[b]<<18|Al[M];var fe=Ia[b]&31,we=Al[M]&31;Q+=Kn[fe]+Jn[we],++E[257+fe],++y[we],D=w+b,++v}else B[k++]=A[w],++E[A[w]]}}for(w=Math.max(w,D);w<n;++w)B[k++]=A[w],++E[A[w]];c=pl(A,a,l,B,E,y,Q,k,H,w-H,c),l||(s.r=c&7|a[c/8|0]<<3,c-=7,s.h=g,s.p=u,s.i=w,s.w=D)}else{for(var w=s.w||0;w<n+l;w+=65535){var se=w+65535;se>=n&&(a[c/8|0]=l,se=n),c=Bl(a,c+1,A.subarray(w,se))}s.i=n}return Ss(o,0,t+Ea(c)+i)},Sd=function(){for(var A=new Int32Array(256),r=0;r<256;++r){for(var e=r,t=9;--t;)e=(e&1&&-306674912)^e>>>1;A[r]=e}return A}(),bd=function(){var A=-1;return{p:function(r){for(var e=A,t=0;t<r.length;++t)e=Sd[e&255^r[t]]^e>>>8;A=e},d:function(){return~A}}},Dd=function(A,r,e,t,i){if(!i&&(i={l:1},r.dictionary)){var s=r.dictionary.subarray(-32768),n=new pe(s.length+A.length);n.set(s),n.set(A,s.length),A=n,i.w=s.length}return Fd(A,r.level==null?6:r.level,r.mem==null?i.l?Math.ceil(Math.max(8,Math.min(13,Math.log(A.length)))*1.5):20:12+r.mem,e,t,i)},wl=function(A,r){var e={};for(var t in A)e[t]=A[t];for(var t in r)e[t]=r[t];return e},rt=function(A,r){return A[r]|A[r+1]<<8},Ke=function(A,r){return(A[r]|A[r+1]<<8|A[r+2]<<16|A[r+3]<<24)>>>0},ua=function(A,r){return Ke(A,r)+Ke(A,r+4)*4294967296},ke=function(A,r,e){for(;e;++r)A[r]=e,e>>>=8};El=function(A,r,e,t){for(var i in A){var s=A[i],n=r+i,o=t;Array.isArray(s)&&(o=wl(t,s[1]),s=s[0]),ArrayBuffer.isView(s)?e[n]=[s,o]:(e[n+="/"]=[new pe(0),o],El(s,n,e,t))}},gl=typeof TextEncoder<"u"&&new TextEncoder,Ba=typeof TextDecoder<"u"&&new TextDecoder,Td=0;try{Ba.decode(yl,{stream:!0}),Td=1}catch{}Md=function(A){for(var r="",e=0;;){var t=A[e++],i=(t>127)+(t>223)+(t>239);if(e+i>A.length)return{s:r,r:Ss(A,e-1)};i?i==3?(t=((t&15)<<18|(A[e++]&63)<<12|(A[e++]&63)<<6|A[e++]&63)-65536,r+=String.fromCharCode(55296|t>>10,56320|t&1023)):i&1?r+=String.fromCharCode((t&31)<<6|A[e++]&63):r+=String.fromCharCode((t&15)<<12|(A[e++]&63)<<6|A[e++]&63):r+=String.fromCharCode(t)}};Pd=function(A,r){return r+30+rt(A,r+26)+rt(A,r+28)},Hd=function(A,r,e){var t=rt(A,r+28),i=rt(A,r+30),s=va(A.subarray(r+46,r+46+t),!(rt(A,r+8)&2048)),n=r+46+t,o=Rd(A,n,i,e,Ke(A,r+20),Ke(A,r+24),Ke(A,r+42)),a=o[0],l=o[1],c=o[2];return[rt(A,r+10),a,l,s,n+i+rt(A,r+32),c]},Rd=function(A,r,e,t,i,s,n){var o=i==4294967295,a=s==4294967295,l=n==4294967295,c=r+e,d=o+a+l;if(t&&d){for(;r+4<c;r+=4+rt(A,r+2))if(rt(A,r)==1)return[o?ua(A,r+4+8*a):i,a?ua(A,r+4):s,l?ua(A,r+4+8*(a+o)):n,1];t<2&&Se(13)}return[i,s,n,0]},ya=function(A){var r=0;if(A)for(var e in A){var t=A[e].length;t>65535&&Se(9),r+=t+4}return r},ul=function(A,r,e,t,i,s,n,o){var a=t.length,l=e.extra,c=o&&o.length,d=ya(l);ke(A,r,n!=null?33639248:67324752),r+=4,n!=null&&(A[r++]=20,A[r++]=e.os),A[r]=20,r+=2,A[r++]=e.flag<<1|(s<0&&8),A[r++]=i&&8,A[r++]=e.compression&255,A[r++]=e.compression>>8;var h=new Date(e.mtime==null?Date.now():e.mtime),p=h.getFullYear()-1980;if((p<0||p>119)&&Se(10),ke(A,r,p<<25|h.getMonth()+1<<21|h.getDate()<<16|h.getHours()<<11|h.getMinutes()<<5|h.getSeconds()>>1),r+=4,s!=-1&&(ke(A,r,e.crc),ke(A,r+4,s<0?-s-2:s),ke(A,r+8,e.size)),ke(A,r+12,a),ke(A,r+14,d),r+=16,n!=null&&(ke(A,r,c),ke(A,r+6,e.attrs),ke(A,r+10,n),r+=14),A.set(t,r),r+=a,d)for(var f in l){var u=l[f],g=u.length;ke(A,r,+f),ke(A,r+2,g),A.set(u,r+4),r+=4+g}return c&&(A.set(o,r),r+=c),r},Ud=function(A,r,e,t,i){ke(A,r,101010256),ke(A,r+8,e),ke(A,r+10,e),ke(A,r+12,t),ke(A,r+16,i)}});var bl={};Yi(bl,{bytesToStr:()=>qn,unzipFiles:()=>Gi,zipFiles:()=>Li});function Gd(A){return typeof A=="string"?On(A):A instanceof Uint8Array?A:new Uint8Array(A)}function Li(A,r=6){let e={};for(let t of A)e[t.name]=[Gd(t.data),{level:r}];return Promise.resolve(vl(e,{level:r}))}function qn(A){return va(A)}function Gi(A){let r=A instanceof Uint8Array?A:new Uint8Array(A),e=0,t=0,i=s=>{if(t+=1,t>Sl)throw new Error(`Refusing to unzip: too many entries (>${Sl}) \u2014 possible zip bomb.`);if(s.originalSize>Ld)throw new Error(`Refusing to unzip: entry "${s.name}" is ${Math.round(s.originalSize/1048576)} MiB \u2014 possible zip bomb.`);if(e+=s.originalSize,e>Fl)throw new Error(`Refusing to unzip: total size >${Math.round(Fl/1048576)} MiB \u2014 possible zip bomb.`);return!0};return Promise.resolve(Ql(r,{filter:i}))}var Fl,Ld,Sl,$n=de(()=>{"use strict";kl();Fl=512*1024*1024,Ld=256*1024*1024,Sl=2e4});var fA={};Yi(fA,{default:()=>uo});module.exports=hc(fA);var N=require("obsidian");var zi="sheet-group",ht="sheet-order",li="sheet-final",Ka="sheet-label",Vi="sheet-origin",Wi="forked-from",je="fork-siblings",mo="forked-at",Co=[zi,ht,li,Ka,Vi,Wi,je,mo];function _e(A){if(!A)return null;let r=A[zi];return typeof r=="string"&&r.trim()?r:null}function Io(A){let r=A?.[ht];return typeof r=="number"?r:null}function Xi(A){return _e(A)!==null&&Io(A)!==null}function Zi(A){return A?.[li]===!0}function Ja(A){return A?.[Vi]===!0}function pc(A){let r=A?.[Wi];return typeof r=="string"&&r.trim()?r:null}function Ks(A){return typeof A!="string"?null:A.replace(/^\[\[/,"").replace(/\]\]$/,"").split("|")[0].split("#")[0].trim()||null}function qa(A){return Ks(pc(A))}function gc(A){let r=A?.[Ka];return typeof r=="string"&&r.trim()?r:null}function $a(){let A=Date.now().toString(36),r=Math.floor(Math.random()*1e6).toString(36);return`s-${A}-${r}`}function Fe(A,r){return r.file?A.metadataCache.getFileCache(r.file)?.frontmatter:null}function Bo(A,r){return r.slice().sort((e,t)=>{let i=Io(Fe(A,e)),s=Io(Fe(A,t));if(i!=null&&s!=null&&i!==s)return i-s;if(i!=null&&s==null)return-1;if(i==null&&s!=null)return 1;let n=e.created??"",o=t.created??"";return n!==o?n<o?-1:1:e.id<t.id?-1:e.id>t.id?1:0})}function Ya(A,r){if(r.length===0)return null;let e=Bo(A,r);return e.find(t=>Zi(Fe(A,t)))??e[0]}function za(A,r,e){let t=gc(Fe(A,r));return t||e}pt();ce();var Qe=require("obsidian");var re=require("obsidian");ce();Tt();ve();ce();function ta(A,r){let e=A.basename;return r&&e.endsWith(`-${r}`)?e=e.slice(0,-(r.length+1)):r||(e=e.replace(/-[abcdefghijkmnpqrstuvwxyz23456789]{6}$/,"")),e.replace(/-/g," ").trim()||A.basename}function Cn(A,r){let e=new Set(r.discoverStashpadFolders()),t=[];for(let i of A.vault.getMarkdownFiles()){let s=i.parent?.path?.replace(/\/+$/,"")??"";if(!e.has(s))continue;let n=A.metadataCache.getFileCache(i)?.frontmatter??{},o=typeof n.id=="string"?n.id:null;if(!o||o===S)continue;let a=n.completed===!0,l=Ai(n,"task")||n.task===!0||n.completed!==void 0,c=typeof n.due=="string"||typeof n.due=="number"?String(n.due):null,d=null;if(typeof n.due=="number")Number.isFinite(n.due)&&n.due>=1e11&&(d=n.due);else if(c){let h=Date.parse(c);Number.isNaN(h)||(d=h)}!l&&!a&&d==null&&!c||t.push({file:i,folder:s,id:o,title:ta(i,o),task:l,completed:a,due:d,dueRaw:c,color:typeof n.color=="string"?n.color:null,assignedTo:xt(n),assignedBy:gt(n.assignedBy),author:gt(n.author)})}return t}var Yr=require("obsidian");var ot=require("obsidian");ve();Tt();var ld=0,ia=[{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"}];function Bn(){return{assign:"all",person:"",folder:"all",status:"all"}}function ys(A,r,e,t,i){let s=()=>ys(A,r,e,t,i);A.empty(),A.addClass("stashpad-task-triage");let n=Cn(r,e),o=(e.settings.authorId??"").trim(),a=b=>!!o&&b.assignedTo.some(M=>M.id===o),l=b=>{switch(t.assign){case"mine":return a(b);case"others":return b.assignedTo.length>0&&!a(b);case"byme":return!!o&&b.assignedBy?.id===o;case"unassigned":return b.assignedTo.length===0;default:return!0}},c=b=>!t.person||b.assignedTo.some(M=>M.id===t.person)||b.author?.id===t.person||b.assignedBy?.id===t.person,d=new Map;for(let b of n){for(let M of b.assignedTo)d.set(M.id,M.name);b.assignedBy&&d.set(b.assignedBy.id,b.assignedBy.name),b.author&&d.set(b.author.id,b.author.name)}let h=[...d.entries()].map(([b,M])=>({id:b,name:M})).sort((b,M)=>b.name.localeCompare(M.name)),p=[...new Set(n.map(b=>b.folder))].sort((b,M)=>b.localeCompare(M));t.folder!=="all"&&!p.includes(t.folder)&&(t.folder="all");let f=b=>t.folder==="all"||b.folder===t.folder,u=A.createDiv({cls:"stashpad-triage-filters"}),g=u.createEl("button",{cls:"stashpad-triage-reset",attr:{"aria-label":"Reset filters"}});(0,ot.setIcon)(g,"rotate-ccw"),g.onclick=()=>{t.assign="all",t.person="",t.folder="all",s()};let I=u.createEl("select",{cls:"stashpad-triage-select"}),m={all:"Everyone",mine:"Assigned to me",others:"Assigned to others",byme:"Assigned by me",unassigned:"Unassigned"};for(let b of["all","mine","others","byme","unassigned"]){let M=I.createEl("option",{text:m[b],value:b});t.assign===b&&(M.selected=!0)}I.onchange=()=>{t.assign=I.value,s()};let C=u.createEl("select",{cls:"stashpad-triage-select"}),B=C.createEl("option",{text:"All folders",value:"all"});t.folder==="all"&&(B.selected=!0);for(let b of p){let M=C.createEl("option",{text:b.split("/").pop()||b,value:b});t.folder===b&&(M.selected=!0)}if(C.onchange=()=>{t.folder=C.value,s()},h.length>0){let b=new Map;for(let q of h)b.has(q.name)||b.set(q.name,q.id);let M=`stashpad-task-authors-${++ld}`,O=u.createDiv({cls:"stashpad-triage-authorwrap"}),K=O.createEl("input",{cls:"stashpad-triage-authorsearch",attr:{type:"text",list:M,placeholder:"Any person\u2026",spellcheck:"false"}}),Y=O.createEl("button",{cls:"stashpad-triage-authorclear",attr:{"aria-label":"Clear person filter"}});(0,ot.setIcon)(Y,"x"),Y.onclick=()=>{K.value="",t.person?(t.person="",s()):K.focus()};let Z=O.createEl("datalist");Z.id=M;for(let q of h)Z.createEl("option",{value:q.name});t.person&&(K.value=d.get(t.person)??"");let V=()=>{let q=K.value.trim();if(q===""){t.person&&(t.person="",s());return}let ee=b.get(q);ee&&t.person!==ee&&(t.person=ee,s())};K.onchange=V,K.addEventListener("keydown",q=>{q.key==="Enter"&&V()})}let E=Date.now(),y=new Date;y.setHours(0,0,0,0);let v=y.getTime(),Q=v+864e5,w=n.filter(b=>l(b)&&c(b)&&f(b)),k={overdue:[],today:[],upcoming:[],nodate:[],completed:[]};for(let b of w){if(b.completed){k.completed.push(b);continue}if(b.due==null){k.nodate.push(b);continue}b.due<v?k.overdue.push(b):b.due<Q?k.today.push(b):k.upcoming.push(b)}let D=(b,M)=>b.due==null&&M.due==null?b.title.localeCompare(M.title):b.due==null?1:M.due==null?-1:b.due-M.due,H=A.createDiv({cls:"stashpad-triage-chips"}),R=(b,M,O)=>{let K=H.createEl("button",{cls:"stashpad-triage-chip"});t.status===b&&K.addClass("is-active"),K.createSpan({text:M}),K.createSpan({cls:"stashpad-triage-chip-count",text:String(O)}),K.onclick=()=>{t.status=b,s()}};R("all","All",w.length);for(let b of ia)R(b.key,b.label,k[b.key].length);if(w.length===0){A.createDiv({cls:"stashpad-tasks-empty"}).setText(n.length===0?"No tasks yet \u2014 press G on a note to make it a task, or D to give it a due date.":"No tasks match the current filters.");return}let L=async b=>{try{await r.fileManager.processFrontMatter(b.file,M=>{M.completed=M.completed!==!0})}catch(M){new ot.Notice(`Couldn't update task: ${M.message}`);return}s()},x=b=>{let M=b.dueRaw??(b.due!=null?new Date(b.due).toISOString():null);new ze(r,M,O=>{r.fileManager.processFrontMatter(b.file,K=>{O.iso===null?delete K.due:(K.due=O.iso,K.task=!0)}).then(s).catch(K=>new ot.Notice(`Couldn't snooze: ${K.message}`))},{title:"Snooze \u2014 reschedule",hideAssignees:!0,quickAdjusts:e.settings.dueQuickAdjusts}).open()},U=t.status==="all"?ia:ia.filter(b=>b.key===t.status),T=!1;for(let b of U){let M=k[b.key];if(M.length===0)continue;if(T=!0,M.sort(b.key==="completed"?(K,Y)=>D(Y,K):D),t.status==="all"){let K=A.createDiv({cls:`stashpad-review-section is-${b.key}`});(0,ot.setIcon)(K.createSpan({cls:"stashpad-review-section-icon"}),b.icon),K.createSpan({cls:"stashpad-review-section-name",text:b.label}),K.createSpan({cls:"stashpad-review-section-count",text:String(M.length)})}let O=A.createDiv({cls:"stashpad-review-list"});for(let K of M)cd(O,K,E,e,{toggleCompleted:L,snooze:x,onOpen:i.onOpen})}T||A.createDiv({cls:"stashpad-tasks-empty"}).setText("Nothing in this view.")}function cd(A,r,e,t,i){let s=A.createDiv({cls:"stashpad-review-row"});r.completed&&s.addClass("is-completed");let n=s.createSpan({cls:"stashpad-review-check"});(0,ot.setIcon)(n,r.completed?"check-square":"square"),r.color&&(n.style.color=r.color),n.title=r.completed?"Mark not done":"Mark done",n.onclick=()=>i.toggleCompleted(r);let o=s.createDiv({cls:"stashpad-review-main"}),a=o.createDiv({cls:"stashpad-review-title",text:r.title});a.onclick=()=>i.onOpen(r.folder,r.id);let l=o.createDiv({cls:"stashpad-review-meta"});if(l.createSpan({cls:"stashpad-review-folder",text:r.folder.split("/").pop()||r.folder}),r.author&&l.createSpan({cls:"stashpad-review-author",text:`by ${r.author.name}`}),r.due!=null){let p=r.due<e&&!r.completed,f=new Date(e);f.setHours(0,0,0,0);let u=f.getTime(),g=r.due>=u&&r.due<u+864e5,I=l.createSpan({cls:"stashpad-review-due",text:g?hi(r.due,t.settings):Nt(r.due,t.settings)});p&&I.addClass("is-overdue")}else r.dueRaw?l.createSpan({cls:"stashpad-review-due",text:r.dueRaw}):l.createSpan({cls:"stashpad-review-due is-none",text:"no date"});for(let p of r.assignedTo)l.createSpan({cls:"stashpad-review-assignee",text:p.name});let c=s.createDiv({cls:"stashpad-review-actions"}),d=c.createEl("button",{cls:"stashpad-review-btn"});(0,ot.setIcon)(d,"alarm-clock"),d.title="Snooze \u2014 reschedule",d.onclick=()=>i.snooze(r);let h=c.createEl("button",{cls:"stashpad-review-btn"});(0,ot.setIcon)(h,"arrow-right"),h.title="Open note",h.onclick=()=>i.onOpen(r.folder,r.id)}var xi=class extends Yr.Modal{constructor(e,t){super(e);this.plugin=t;this.state=Bn()}onOpen(){this.modalEl.addClass("stashpad-task-review-modal"),this.titleEl.setText("Daily task review"),ys(this.contentEl,this.app,this.plugin,this.state,{onOpen:(e,t)=>{this.plugin.revealNoteByRef(e,t),this.close()}})}onClose(){this.contentEl.empty()}};function Ht(A,r,e){let t=A.createSpan({cls:"stashpad-count-badge"});e&&t.addClass("is-expanded"),t.setText(r>99?"99+":String(r))}var ws={pinned:{label:"Pinned",icon:"pin"},shared:{label:"Shared",icon:"users"},tasks:{label:"Tasks",icon:"check-circle-2"}},yn=class extends re.ItemView{constructor(e,t){super(e);this.plugin=t;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(e){this.activePanel=e,this.containerEl.isConnected&&this.render()}getViewType(){return St}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",e=>{e&&e.view.getViewType()===$&&this.scheduleRender()}))}scheduleRender(){this.renderTimer==null&&(this.renderTimer=window.setTimeout(()=>{this.renderTimer=null,this.containerEl.isConnected&&this.render()},80))}render(){let e=this.contentEl;e.empty(),e.addClass("stashpad-panels-root");let t=e.createDiv({cls:"stashpad-panels-globals"}),i=t.createEl("button",{cls:"stashpad-panels-global-btn"});(0,re.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=t.createEl("button",{cls:"stashpad-panels-global-btn"});(0,re.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=t.createDiv({cls:"stashpad-panels-globals-row"}),o=n.createEl("button",{cls:"stashpad-panels-global-btn"});(0,re.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,re.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 l=e.createDiv({cls:"stashpad-panels-bar"});for(let d of Object.keys(ws)){let h=ws[d],p=l.createEl("button",{cls:"stashpad-panels-bar-btn"});(0,re.setIcon)(p.createSpan({cls:"stashpad-panels-bar-btn-icon"}),h.icon),p.createSpan({cls:"stashpad-panels-bar-btn-text",text:h.label}),this.activePanel===d&&p.addClass("is-active"),p.onclick=()=>{this.activePanel!==d&&(this.activePanel=d,this.render())}}let c=e.createDiv({cls:"stashpad-panels-body"});this.activePanel==="pinned"?this.renderPinnedPanel(c):this.activePanel==="shared"?this.renderSharedPanel(c):this.activePanel==="tasks"&&this.renderTasksPanel(c)}openPinnedOptionsMenu(e){let t=this.plugin.settings.folderPanelPinnedGrouping??"pin-order",i=new re.Menu;i.addItem(s=>s.setTitle("Sort by pin order").setChecked(t==="pin-order").onClick(()=>void this.setPinnedGrouping("pin-order"))),i.addItem(s=>s.setTitle("Group by folder").setChecked(t==="folder").onClick(()=>void this.setPinnedGrouping("folder"))),i.showAtMouseEvent(e)}async setPinnedGrouping(e){(this.plugin.settings.folderPanelPinnedGrouping??"pin-order")!==e&&(this.plugin.settings.folderPanelPinnedGrouping=e,await this.plugin.saveSettings(),this.render())}renderPinnedPanel(e){let t=e.createDiv({cls:"stashpad-panel-pinned"});(this.plugin.settings.folderPanelPinnedGrouping??"pin-order")!=="folder"&&t.addClass("is-flat");let i=t.createDiv({cls:"stashpad-pinned-headrow"}),s=i.createEl("button",{cls:"stashpad-pinned-row stashpad-pinned-home"}),n=s.createSpan({cls:"stashpad-pinned-icon"});(0,re.setIcon)(n,"home"),s.createSpan({cls:"stashpad-pinned-label",text:"Home"}),s.onclick=()=>this.openHomeFromPanel();let o=i.createEl("button",{cls:"stashpad-folderpanel-iconbtn stashpad-pinned-opts"});(0,re.setIcon)(o,"list"),o.setAttr("aria-label","Pinned view options"),o.onclick=p=>{p.stopPropagation(),this.openPinnedOptionsMenu(p)};let a=this.plugin.listPinnedNotes();if(a.length===0){t.createDiv({cls:"stashpad-pinned-empty"}).setText("No pinned notes yet \u2014 right-click a note and choose \u201CPin to sidebar.\u201D");return}if((this.plugin.settings.folderPanelPinnedGrouping??"pin-order")!=="folder"){a.forEach((p,f)=>this.renderPinnedRow(t,p,f));return}let c=new Map;a.forEach((p,f)=>{let u=c.get(p.folder);u||(u=[],c.set(p.folder,u)),u.push({pin:p,idx:f})});let d=this.plugin.lastActiveStashpadLeaf?.view?.noteFolder,h=Array.from(c.keys());d&&c.has(d)&&(h.splice(h.indexOf(d),1),h.unshift(d));for(let p of h){let f=p.split("/").pop()||p,u=t.createDiv({cls:"stashpad-pinned-group-header"});p===d&&u.addClass("is-active-folder"),u.createSpan({cls:"stashpad-pinned-group-name",text:f});let g=c.get(p)??[];for(let{pin:I,idx:m}of g)this.renderPinnedRow(t,I,m)}}renderPinnedRow(e,t,i){let s=this.findFileFor(t);if(!s)return;let n=this.app.metadataCache.getFileCache(s)?.frontmatter??{},o=this.titleFromFile(s),a=typeof n.color=="string"?n.color:null,l=n.completed===!0,c=this.childrenOf(t.folder,t.id).length,d=c>0,h=this.expanded.has(`${t.folder}|${t.id}`),p=e.createDiv({cls:"stashpad-pinned-row"});a&&p.addClass("has-color"),l&&p.addClass("is-completed"),p.draggable=!0,p.dataset.pinIdx=String(i),p.addEventListener("dragstart",m=>{m.dataTransfer?.setData("text/plain",String(i)),m.dataTransfer&&(m.dataTransfer.effectAllowed="move"),p.addClass("is-dragging")}),p.addEventListener("dragend",()=>p.removeClass("is-dragging")),p.addEventListener("dragover",m=>{m.preventDefault(),m.dataTransfer&&(m.dataTransfer.dropEffect="move");let C=p.getBoundingClientRect(),B=m.clientY-C.top<C.height/2;p.toggleClass("drop-before",B),p.toggleClass("drop-after",!B)}),p.addEventListener("dragleave",()=>{p.removeClass("drop-before"),p.removeClass("drop-after")}),p.addEventListener("drop",m=>{m.preventDefault(),p.removeClass("drop-before"),p.removeClass("drop-after");let C=parseInt(m.dataTransfer?.getData("text/plain")??"",10);if(!Number.isFinite(C)||C===i)return;let B=p.getBoundingClientRect(),E=m.clientY-B.top<B.height/2;this.reorderPin(C,E?i:i+1)});let f=p.createSpan({cls:"stashpad-pinned-toggle"});d&&(Ht(f,c,h),f.onclick=m=>{m.stopPropagation();let C=`${t.folder}|${t.id}`;this.expanded.has(C)?this.expanded.delete(C):this.expanded.add(C),this.render()});let u=p.createSpan({cls:"stashpad-pinned-icon"});(0,re.setIcon)(u,d?"folder-tree":"file-text"),a&&(u.style.color=a);let g=p.createSpan({cls:"stashpad-pinned-label",text:o});g.onclick=()=>this.openPinFromPanel(t);let I=t.folder.split("/").pop()||t.folder;if(p.createSpan({cls:"stashpad-pinned-folder",text:I}),p.oncontextmenu=m=>{m.preventDefault();let C=new re.Menu;C.addItem(B=>B.setTitle("Unpin from sidebar").setIcon("pin-off").onClick(()=>{this.plugin.unpinNote(t)})),C.showAtMouseEvent(m)},d&&h){let m=e.createDiv({cls:"stashpad-pinned-children"});this.renderPinnedSubtree(m,t.folder,t.id,1)}}async reorderPin(e,t){let i=this.plugin.listPinnedNotes();if(e<0||e>=i.length)return;let s=i[e],n=i.filter((d,h)=>h!==e),o=Math.max(0,Math.min(t>e?t-1:t,n.length)),a=n[o-1],l=n[o],c;!a&&!l?c=Date.now():a?l?c=(a.pinnedAt+l.pinnedAt)/2:c=a.pinnedAt+1e3:c=l.pinnedAt-1e3;try{await this.app.fileManager.processFrontMatter(s.file,d=>{d.pinnedAt=c})}catch(d){console.warn("[Stashpad] pin reorder failed",d)}this.render()}renderPinnedSubtree(e,t,i,s){let n=this.childrenOf(t,i);for(let o of n){let a=this.app.metadataCache.getFileCache(o)?.frontmatter??{},l=typeof a.id=="string"?a.id:null;if(!l)continue;let c=typeof a.color=="string"?a.color:null,d=a.completed===!0,h=this.childrenOf(t,l).length,p=h>0,f=this.expanded.has(`${t}|${l}`),u=e.createDiv({cls:"stashpad-pinned-subrow"});d&&u.addClass("is-completed"),u.style.paddingLeft=`${s*16}px`;let g=u.createSpan({cls:"stashpad-pinned-toggle"});p&&(Ht(g,h,f),g.onclick=C=>{C.stopPropagation();let B=`${t}|${l}`;this.expanded.has(B)?this.expanded.delete(B):this.expanded.add(B),this.render()});let I=u.createSpan({cls:"stashpad-pinned-icon"});(0,re.setIcon)(I,"file-text"),c&&(I.style.color=c);let m=u.createSpan({cls:"stashpad-pinned-label",text:this.titleFromFile(o)});m.onclick=()=>this.openPinFromPanel({folder:t,id:l}),p&&f&&this.renderPinnedSubtree(e,t,l,s+1)}}findFileFor(e){for(let t of this.app.vault.getMarkdownFiles()){if((t.parent?.path?.replace(/\/+$/,"")??"")!==e.folder)continue;if(this.app.metadataCache.getFileCache(t)?.frontmatter?.id===e.id)return t}return null}childrenOf(e,t){let i=[];for(let s of this.app.vault.getMarkdownFiles()){if((s.parent?.path?.replace(/\/+$/,"")??"")!==e)continue;let o=this.app.metadataCache.getFileCache(s)?.frontmatter;if(!o||typeof o.id!="string")continue;let a=o.parent;if(a===t||t===S&&(a==null||a===S)){if(o.id===S)continue;i.push(s)}}return i.sort((s,n)=>{let o=this.app.metadataCache.getFileCache(s)?.frontmatter,a=this.app.metadataCache.getFileCache(n)?.frontmatter,l=o?.created??"",c=a?.created??"";return l.localeCompare(c)}),i}titleFromFile(e){let t=this.app.metadataCache.getFileCache(e)?.frontmatter?.id;return ta(e,typeof t=="string"?t:null)}async openSearchFromPanel(){let e=await this.resolveTargetStashpad();e&&typeof e.openSearchModal=="function"&&e.openSearchModal()}async openLogFromPanel(){let e=this.app.vault.adapter,t=this.plugin.pluginPrivatePath("log.jsonl");if(!await e.exists(t)){new re.Notice("No log yet \u2014 make some changes first.");return}let i=await e.read(t),{LogModal:s}=await Promise.resolve().then(()=>(ve(),Bs));new s(this.app,i,t).open()}openNotificationsFromPanel(){this.app.commands?.executeCommandById?.("stashpad:stashpad-open-notification-history")}async openHomeFromPanel(){let e=await this.resolveTargetStashpad();e&&typeof e.navigateTo=="function"&&e.navigateTo(S)}async openPinFromPanel(e){await this.plugin.revealNoteByRef(e.folder,e.id)}async resolveTargetStashpad(){let e=this.plugin.lastActiveStashpadLeaf;if(e&&e.view.getViewType()===$)return this.app.workspace.revealLeaf(e),e.view;let t=this.findActiveStashpad();if(t)return t;let i=this.app.workspace.getLeavesOfType($);return i.length>0?(this.app.workspace.revealLeaf(i[0]),i[0].view):(await this.plugin.activateView({reveal:!0}),this.findActiveStashpad())}findActiveStashpad(){let e=this.app.workspace.activeLeaf;return e&&e.view.getViewType()===$?e.view:null}renderSharedPanel(e){let t=e.createDiv({cls:"stashpad-panel-shared"}),i=(this.plugin.settings.authorId??"").trim();if(!i){t.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 d of s){let h=d.authorId;h&&!n.has(h)&&n.set(h,d.authorDisplay||h)}let o=t.createDiv({cls:"stashpad-shared-filters"}),a=(d,h,p)=>{let f=o.createEl("button",{cls:"stashpad-shared-chip",text:d});return h&&f.addClass("is-active"),f.onclick=p,f};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 d=o.createEl("select",{cls:"stashpad-shared-author-select"}),h=d.createEl("option",{text:"Any author"});h.value="__any__";for(let[f,u]of n){let g=d.createEl("option",{text:u});g.value=f}let p=["all","mine","others"].includes(this.sharedAuthorFilter)?"__any__":this.sharedAuthorFilter;d.value=p,d.onchange=()=>{let f=d.value;f==="__any__"?this.sharedAuthorFilter="all":this.sharedAuthorFilter=f,this.render()}}let l=o.createEl("button",{cls:"stashpad-shared-chip",text:"Has contributors"});this.sharedContribOnly&&l.addClass("is-active"),l.onclick=()=>{this.sharedContribOnly=!this.sharedContribOnly,this.render()};let c=s.filter(d=>{if(this.sharedContribOnly&&d.contributorCount===0)return!1;switch(this.sharedAuthorFilter){case"all":return!0;case"mine":return d.authorId===i;case"others":return d.authorId!==i;default:return d.authorId===this.sharedAuthorFilter}});if(c.length===0){t.createDiv({cls:"stashpad-shared-empty"}).setText("No shared notes match the current filters.");return}for(let d of c){let h=t.createDiv({cls:"stashpad-pinned-row stashpad-shared-row"}),p=h.createSpan({cls:"stashpad-pinned-icon"});(0,re.setIcon)(p,"users"),d.color&&(p.style.color=d.color);let f=h.createSpan({cls:"stashpad-pinned-label",text:d.title});f.onclick=()=>this.openSharedFromPanel(d.folder,d.id);let u=d.folder.split("/").pop()||d.folder;h.createSpan({cls:"stashpad-pinned-folder",text:u}),d.authorDisplay&&h.createSpan({cls:"stashpad-shared-meta"}).setText(d.authorId===i?`you \xB7 ${d.contributorCount} contributor${d.contributorCount===1?"":"s"}`:`by ${d.authorDisplay}${d.contributorCount>0?` \xB7 ${d.contributorCount} contributor${d.contributorCount===1?"":"s"}`:""}`)}}collectSharedNotes(e){let t=this.plugin.discoverStashpadFolders(),i=new Set(t),s=new Map;for(let o of this.app.vault.getMarkdownFiles()){let a=o.parent?.path?.replace(/\/+$/,"")??"";if(!i.has(a))continue;let l=this.app.metadataCache.getFileCache(o)?.frontmatter??{};l.id===S&&s.set(a,this.extractAuthorId(l.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 l=this.app.metadataCache.getFileCache(o)?.frontmatter??{};if(typeof l.id!="string"||l.id===S)continue;let c=this.extractAuthorId(l.author),d=Array.isArray(l.contributors)?l.contributors.filter(C=>typeof C=="string"):[],h=s.get(a)??null;if(!(d.length>0||h===e&&(c!==null&&c!==e)))continue;let I=this.titleFromFile(o),m=typeof l.color=="string"?l.color:null;n.push({file:o,folder:a,id:l.id,title:I,color:m,authorId:c,authorDisplay:this.extractAuthorDisplay(l.author)||(c??""),contributorCount:d.length})}return n.sort((o,a)=>{let l=this.app.metadataCache.getFileCache(o.file)?.frontmatter??{},c=this.app.metadataCache.getFileCache(a.file)?.frontmatter??{},d=l.modified??l.created??"";return(c.modified??c.created??"").localeCompare(d)}),n}extractAuthorId(e){if(typeof e!="string")return null;let t=e.match(/-([a-z0-9]{4,12})(?:\.md)?(?:\||\]\])/i);return t?t[1]:null}extractAuthorDisplay(e){if(typeof e!="string")return"";let t=e.match(/\|([^\]]+)\]\]/);if(t)return t[1].trim();let i=e.match(/_authors\/([^\]|]+)-[a-z0-9]{4,12}/i);return i?i[1].replace(/[-_]/g," ").trim():""}async openSharedFromPanel(e,t){await this.plugin.revealNoteByRef(e,t)}renderTasksPanel(e){let t=e.createDiv({cls:"stashpad-panel-tasks"}),s=t.createDiv({cls:"stashpad-task-review-bar"}).createEl("button",{cls:"stashpad-task-review-open"});(0,re.setIcon)(s.createSpan({cls:"stashpad-btn-icon"}),"maximize-2"),s.createSpan({text:"Daily review"}),s.onclick=()=>new xi(this.app,this.plugin).open();let n=this.collectTasks();if(n.length===0){t.createDiv({cls:"stashpad-tasks-empty"}).setText("No tasks yet \u2014 press G on a note to mark it a task, or D to give it a due date.");return}let o=(this.plugin.settings.authorId??"").trim(),a=T=>!!o&&T.assignedTo.some(b=>b.id===o),l=T=>{let b=this.taskAssignFilter;if(b.startsWith("person:")){let M=b.slice(7);return T.assignedTo.some(O=>O.id===M)}switch(b){case"mine":return a(T);case"others":return T.assignedTo.length>0&&!a(T);case"byme":return!!o&&T.assignedBy?.id===o;case"unassigned":return T.assignedTo.length===0;default:return!0}},c=new Map;for(let T of n){for(let b of T.assignedTo)b.id!==o&&c.set(b.id,b.name);T.assignedBy&&T.assignedBy.id!==o&&c.set(T.assignedBy.id,T.assignedBy.name)}let d=[...c.entries()].map(([T,b])=>({id:T,name:b})).sort((T,b)=>T.name.localeCompare(b.name)),h=t.createDiv({cls:"stashpad-task-assign-bar"});h.createSpan({cls:"stashpad-task-assign-label",text:"Assignment"});let p=h.createEl("select",{cls:"stashpad-task-assign-select"}),f=T=>{let b={all:"Everyone",mine:"Assigned to me",others:"Assigned to others",byme:"Assigned by me",unassigned:"Unassigned"};return T.startsWith("person:")?c.get(T.slice(7))??"Person":b[T]??T},u=T=>{let b=p.createEl("option",{text:f(T),value:T});this.taskAssignFilter===T&&(b.selected=!0)};for(let T of["all","mine","others","byme","unassigned"])u(T);if(d.length>0){let T=p.createEl("optgroup");T.setAttr("label","By person");for(let b of d){let M=T.createEl("option",{text:b.name,value:`person:${b.id}`});this.taskAssignFilter===`person:${b.id}`&&(M.selected=!0)}}p.onchange=()=>{this.taskAssignFilter=p.value,this.render()};let g=[...new Set(n.map(T=>T.folder))].sort((T,b)=>T.localeCompare(b));this.taskFolderFilter!=="all"&&!g.includes(this.taskFolderFilter)&&(this.taskFolderFilter="all");let I=t.createDiv({cls:"stashpad-task-assign-bar"});I.createSpan({cls:"stashpad-task-assign-label",text:"Folder"});let m=I.createEl("select",{cls:"stashpad-task-assign-select"}),C=m.createEl("option",{text:"All folders",value:"all"});this.taskFolderFilter==="all"&&(C.selected=!0);for(let T of g){let b=m.createEl("option",{text:T.split("/").pop()||T,value:T});this.taskFolderFilter===T&&(b.selected=!0)}m.onchange=()=>{this.taskFolderFilter=m.value,this.render()};let B=T=>this.taskFolderFilter==="all"||T.folder===this.taskFolderFilter,E=n.filter(T=>l(T)&&B(T));if(E.length===0){t.createDiv({cls:"stashpad-tasks-empty"}).setText("No tasks match the current filters.");return}let y=new Date;y.setHours(0,0,0,0);let v=y.getTime(),Q=v+24*60*60*1e3,w={overdue:[],today:[],upcoming:[],nodate:[],completed:[]};for(let T of E){if(T.completed){w.completed.push(T);continue}if(T.due==null){w.nodate.push(T);continue}T.due<v?w.overdue.push(T):T.due<Q?w.today.push(T):w.upcoming.push(T)}let k=(T,b)=>T.due==null&&b.due==null?T.title.localeCompare(b.title):T.due==null?1:b.due==null?-1:T.due-b.due,D=[{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"}],H=t.createDiv({cls:"stashpad-task-filters"}),R=E.length,L=(T,b,M)=>{let O=H.createEl("button",{cls:"stashpad-task-filter"});this.taskFilter===T&&O.addClass("is-active"),O.createSpan({cls:"stashpad-task-filter-label",text:b}),O.createSpan({cls:"stashpad-task-filter-count",text:String(M)}),O.onclick=()=>{this.taskFilter=T,this.render()}};L("all","All",R),L("overdue","Overdue",w.overdue.length),L("today","Today",w.today.length),L("upcoming","Upcoming",w.upcoming.length),L("nodate","No date",w.nodate.length),L("completed","Done",w.completed.length);let x=this.taskFilter==="all"?D:D.filter(T=>T.key===this.taskFilter),U=!1;for(let T of x){let b=w[T.key];if(b.length!==0){if(U=!0,b.sort(T.key==="completed"?(M,O)=>k(O,M):k),this.taskFilter==="all"){let M=t.createDiv({cls:`stashpad-task-section-header is-${T.key}`});(0,re.setIcon)(M.createSpan({cls:"stashpad-task-section-icon"}),T.icon),M.createSpan({cls:"stashpad-task-section-name",text:T.label}),M.createSpan({cls:"stashpad-task-section-count",text:String(b.length)})}for(let M of b)this.renderTaskRow(t,M,T.key==="today")}}if(!U&&this.taskFilter!=="all"){t.createDiv({cls:"stashpad-tasks-empty"}).setText(`Nothing in "${x[0]?.label??this.taskFilter}".`);return}U||t.createDiv({cls:"stashpad-tasks-empty"}).setText("No tasks to show.")}renderTaskRow(e,t,i){let s=e.createDiv({cls:"stashpad-pinned-row stashpad-task-row"});t.color&&s.addClass("has-color"),t.completed&&s.addClass("is-completed");let n=s.createSpan({cls:"stashpad-pinned-icon stashpad-task-checkbox"});(0,re.setIcon)(n,t.completed?"check-square":"square"),t.color&&(n.style.color=t.color),n.title=t.completed?"Mark not done":"Mark done",n.onclick=l=>{l.stopPropagation(),this.toggleTaskCompleted(t)};let o=s.createSpan({cls:"stashpad-pinned-label",text:t.title});if(o.onclick=()=>this.openTaskFromPanel(t.folder,t.id),s.createSpan({cls:"stashpad-task-folder",text:t.folder.split("/").pop()||t.folder}),t.due!=null){let l=s.createSpan({cls:"stashpad-task-due",text:this.formatDueShort(t.due,i)});t.due<Date.now()&&!t.completed&&l.addClass("is-overdue")}else t.dueRaw&&s.createSpan({cls:"stashpad-task-due",text:t.dueRaw});if(t.assignedTo.length>0){let l=(this.plugin.settings.authorId??"").trim(),c=s.createSpan({cls:"stashpad-task-assignees"});for(let d of t.assignedTo){let h=c.createSpan({cls:"stashpad-task-assignee"});l&&d.id===l&&h.addClass("is-me"),h.setText(this.initials(d.name)),h.title=l&&d.id===l?`${d.name} (you)`:d.name}}let a=s.createEl("button",{cls:"stashpad-task-snooze"});(0,re.setIcon)(a,"alarm-clock"),a.title="Snooze \u2014 reschedule due date",a.onclick=l=>{l.stopPropagation(),this.snoozeTask(t)},s.oncontextmenu=l=>{l.preventDefault();let c=new re.Menu;c.addItem(d=>d.setTitle("Open").setIcon("arrow-right").onClick(()=>{this.openTaskFromPanel(t.folder,t.id)})),c.addItem(d=>d.setTitle("Snooze (reschedule)\u2026").setIcon("alarm-clock").onClick(()=>{this.snoozeTask(t)})),c.showAtMouseEvent(l)}}snoozeTask(e){let t=e.dueRaw??(e.due!=null?new Date(e.due).toISOString():null);new ze(this.app,t,i=>{this.app.fileManager.processFrontMatter(e.file,s=>{i.iso===null?delete s.due:(s.due=i.iso,s.task=!0)}).then(()=>this.scheduleRender()).catch(s=>new re.Notice(`Couldn't snooze: ${s.message}`))},{title:"Snooze \u2014 reschedule",hideAssignees:!0,quickAdjusts:this.plugin.settings.dueQuickAdjusts}).open()}formatDueShort(e,t){return t?hi(e,this.plugin.settings):Nt(e,this.plugin.settings)}async openTaskFromPanel(e,t){await this.plugin.revealNoteByRef(e,t)}async toggleTaskCompleted(e){try{await this.app.fileManager.processFrontMatter(e.file,t=>{t.completed=t.completed!==!0})}catch(t){new re.Notice(`Couldn't update task: ${t.message}`);return}this.scheduleRender()}initials(e){let t=e.trim().split(/\s+/).filter(Boolean);return t.length===0?"?":t.length===1?t[0].slice(0,2).toUpperCase():(t[0][0]+t[t.length-1][0]).toUpperCase()}collectTasks(){return Cn(this.app,this.plugin)}};async function wn(A){let r=A.workspace.getLeavesOfType(St);if(r.length>0){A.workspace.revealLeaf(r[0]);return}let e=A.workspace.getLeftLeaf(!1);if(!e){new re.Notice("Stashpad: couldn't open the panels view.");return}await e.setViewState({type:St,active:!0}),A.workspace.revealLeaf(e)}In();Tt();ce();function zr(A){return/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(A)}var En=class extends Qe.ItemView{constructor(e,t){super(e);this.plugin=t;this.displayedPath=null;this.bodyComponent=null;this.unsubscribeSelection=null;this.renderTimer=null;this.renderToken=0;this.expanded=new Set;this.composerAutocomplete=null;this.composerInputEl=null;this.composerDraft="";this.composerDraftForId=null;this.displayedId=null;this.unsubscribeContent=null}getViewType(){return Kt}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",e=>{!e||e===this.leaf||e.view?.getViewType?.()===$&&this.scheduleRender()})),this.registerEvent(this.app.vault.on("modify",e=>{this.displayedPath&&e.path===this.displayedPath&&this.scheduleRender()})),this.registerEvent(this.app.vault.on("rename",(e,t)=>{this.displayedPath&&t===this.displayedPath&&(this.displayedPath=e.path,this.scheduleRender())})),this.registerEvent(this.app.metadataCache.on("changed",e=>{this.displayedPath&&e.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 i=this.plugin.lastActiveStashpadLeaf?.view;if(i?.getViewType?.()===$&&i.tree?.get){let s=i.tree.get(this.displayedId);if(s?.file)return{folder:i.noteFolder,id:this.displayedId,file:s.file}}this.displayedId=null}let e=this.plugin.getActiveStashpadSelection();if(e)return this.displayedId=e.id,e;let t=this.plugin.lastActiveStashpadLeaf?.view;if(t?.getViewType?.()===$&&t.tree?.get&&t.focusId){let i=t.tree.get(t.focusId);if(i?.file)return{folder:t.noteFolder,id:t.focusId,file:i.file}}return null}async render(){let e=++this.renderToken,t=this.contentEl,i=!!this.composerInputEl&&document.activeElement===this.composerInputEl,s=this.composerInputEl?.selectionStart??null;this.composerAutocomplete?.detach(),this.composerAutocomplete=null,this.composerInputEl=null,t.empty(),t.addClass("stashpad-detail-root");let n=this.resolveDisplayed();if(!n){this.displayedPath=null;let g=t.createDiv({cls:"stashpad-detail-empty"});(0,Qe.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 o=n.file;this.displayedPath=o.path;let a=this.app.metadataCache.getFileCache(o)?.frontmatter??{},l=t.createDiv({cls:"stashpad-detail-scroll"}),c=l.createDiv({cls:"stashpad-detail-header"}),d=c.createDiv({cls:"stashpad-detail-titlerow"});d.createDiv({cls:"stashpad-detail-title",text:this.titleFor(o)});let h=d.createEl("button",{cls:"stashpad-detail-open-btn",attr:{"aria-label":"Open in Stashpad tab"}});(0,Qe.setIcon)(h,"arrow-up-right"),h.title="Open this note in a new Stashpad tab",h.onclick=()=>{this.openInStashpad(n.folder,n.id)};let p=c.createDiv({cls:"stashpad-detail-metarow"});if(n.folder&&p.createSpan({cls:"stashpad-detail-meta-chip",text:n.folder.split("/").pop()||n.folder}),typeof a.color=="string"&&zr(a.color)){let g=p.createSpan({cls:"stashpad-detail-meta-color"});g.style.background=a.color,g.title=a.color}if(a.completed===!0&&p.createSpan({cls:"stashpad-detail-meta-chip is-completed",text:"\u2713 completed"}),typeof a.due=="string"||typeof a.due=="number"){let g=Date.parse(String(a.due)),I=Number.isNaN(g)?String(a.due):it(g,this.plugin.settings);p.createSpan({cls:"stashpad-detail-meta-chip is-due",text:`due ${I}`})}if(Array.isArray(a.tags))for(let g of a.tags.filter(I=>typeof I=="string"))p.createSpan({cls:"stashpad-detail-meta-tag",text:`#${g.replace(/^#/,"")}`});let f=l.createDiv({cls:"stashpad-detail-body"});try{let g=await this.app.vault.cachedRead(o),I=this.stripFrontmatter(g);this.bodyComponent&&(this.removeChild(this.bodyComponent),this.bodyComponent=null);let m=new Qe.Component;this.addChild(m),this.bodyComponent=m,await Qe.MarkdownRenderer.render(this.app,I,f,o.path,m)}catch(g){f.createDiv({cls:"stashpad-detail-error",text:`Couldn't read \`${o.path}\`: ${g.message}`})}if(e!==this.renderToken)return;this.renderFooterMeta(l,o,a,n),this.renderChildren(l,n.folder,n.id),this.renderComposer(t,n);let u=this.composerInputEl;if(i&&u&&(u.focus(),s!=null)){let g=Math.min(s,u.value.length);try{u.setSelectionRange(g,g)}catch{}}}renderComposer(e,t){let i=e.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===t.id?s.value=this.composerDraft:(this.composerDraft="",this.composerDraftForId=t.id),s.addEventListener("input",()=>{this.composerDraft=s.value,this.composerDraftForId=t.id}),s.addEventListener("keydown",o=>{if(o.key==="Enter"&&!o.shiftKey&&!o.isComposing){if(this.composerAutocomplete?.isOpen?.())return;o.preventDefault(),this.submitComposer(t)}});let n=i.createEl("button",{cls:"stashpad-detail-composer-send",attr:{"aria-label":"Add child note"}});(0,Qe.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(t),this.composerAutocomplete=new Pt(this.app,s),this.composerAutocomplete.attach()}async submitComposer(e){let t=(this.composerInputEl?.value??"").trim();if(!t)return;let i=this.plugin.lastActiveStashpadLeaf?.view;if(!i||i.getViewType?.()!==$||typeof i.createNoteUnder!="function"){new Qe.Notice("Open a Stashpad view to add notes.");return}try{await i.createNoteUnder(t,e.id)}catch(s){new Qe.Notice(`Couldn't add note: ${s.message}`);return}this.composerDraft="",this.composerDraftForId=e.id,this.composerInputEl&&(this.composerInputEl.value=""),await this.render(),setTimeout(()=>this.composerInputEl?.focus(),0)}renderChildren(e,t,i){let s=this.plugin.lastActiveStashpadLeaf?.view;if(!s||s.getViewType?.()!==$)return;let n=s.tree;if(!n?.getChildren)return;let o=n.getChildren(i);if(!o||o.length===0)return;let a=e.createDiv({cls:"stashpad-detail-children"});a.createDiv({cls:"stashpad-detail-children-header",text:`Children (${o.length})`});let l=a.createDiv({cls:"stashpad-detail-children-list"});for(let c of o)c.file&&this.renderDetailChildRow(l,s,n,t,c,0)}renderDetailChildRow(e,t,i,s,n,o,a=new Set){if(!n.file||a.has(n.id))return;let l=this.app.metadataCache.getFileCache(n.file)?.frontmatter??{},c=typeof l.color=="string"&&zr(l.color)?l.color:null,d=l.completed===!0,h=i.getChildren(n.id),p=h.length>0,f=`${s}|${n.id}`,u=this.expanded.has(f),g=e.createDiv({cls:"stashpad-detail-child-row"});d&&g.addClass("is-completed"),o>0&&(g.style.paddingLeft=`${o*16}px`),g.draggable=!0,g.dataset.id=n.id,g.addEventListener("dragstart",E=>{E.dataTransfer?.setData("text/plain",n.id),E.dataTransfer&&(E.dataTransfer.effectAllowed="move"),g.addClass("is-dragging")}),g.addEventListener("dragend",()=>g.removeClass("is-dragging")),g.addEventListener("dragover",E=>{E.preventDefault(),E.dataTransfer&&(E.dataTransfer.dropEffect="move");let y=g.getBoundingClientRect(),v=E.clientY-y.top<y.height/2;g.toggleClass("drop-before",v),g.toggleClass("drop-after",!v)}),g.addEventListener("dragleave",()=>{g.removeClass("drop-before"),g.removeClass("drop-after")}),g.addEventListener("drop",E=>{E.preventDefault(),g.removeClass("drop-before"),g.removeClass("drop-after");let y=E.dataTransfer?.getData("text/plain");if(!y||y===n.id)return;let v=g.getBoundingClientRect(),Q=E.clientY-v.top<v.height/2;typeof t.reorderToTarget=="function"&&t.reorderToTarget([y],n.id,Q?"before":"after")}),g.oncontextmenu=E=>{E.preventDefault();let y=i.get(n.id);y&&typeof t.openNoteMenu=="function"&&t.openNoteMenu(E,y)};let I=g.createSpan({cls:"stashpad-detail-child-toggle"});if(p&&(Ht(I,h.length,u),I.onclick=E=>{E.stopPropagation(),this.expanded.has(f)?this.expanded.delete(f):this.expanded.add(f),this.render()}),Ai(l,"task")||l.task===!0||l.completed!==void 0){let E=g.createSpan({cls:"stashpad-detail-child-checkbox"});(0,Qe.setIcon)(E,d?"check-square":"square"),E.title=d?"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 t.toggleCompletedForNode=="function"&&t.toggleCompletedForNode(v)}}let C=g.createSpan({cls:"stashpad-detail-child-icon"});(0,Qe.setIcon)(C,p?"folder-tree":"file-text"),c&&(C.style.color=c);let B=g.createSpan({cls:"stashpad-detail-child-title",text:this.titleFor(n.file)});if(B.onclick=()=>{t?.navigateTo&&t.navigateTo(n.id)},p&&u){let E=new Set(a).add(n.id);for(let y of h)this.renderDetailChildRow(e,t,i,s,y,o+1,E)}}renderFooterMeta(e,t,i,s){let n=e.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(l=>typeof l=="string").map(l=>this.stripWikiLink(l));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:t.path}),o.push({label:"ID",value:s.id}),o.length===0){n.remove();return}for(let a of o){let l=n.createDiv({cls:"stashpad-detail-meta-line"});l.createSpan({cls:"stashpad-detail-meta-key",text:a.label}),l.createSpan({cls:"stashpad-detail-meta-val",text:a.value})}}titleFor(e){return e.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ")}stripFrontmatter(e){if(!e.startsWith("---"))return e;let t=e.indexOf(` +---`,3);return t<0?e:e.slice(t+4).replace(/^\n+/,"")}stripWikiLink(e){let t=e.match(/^\[\[(.+?)(?:\|(.+))?\]\]$/);return t?t[2]??(t[1].split("/").pop()??t[1]).replace(/\.md$/,""):e}formatTime(e){let t=Date.parse(e);return Number.isFinite(t)?it(t,this.plugin.settings):e}async openInStashpad(e,t){try{let i=await this.plugin.activateViewForFolder(e);t!==S&&this.plugin.navigateLeafTo(i,e,t)}catch(i){new Qe.Notice(`Couldn't open: ${i.message}`)}}};async function vn(A){let r=A.workspace.getLeavesOfType(Kt);if(r.length>0){A.workspace.revealLeaf(r[0]);return}let e=A.workspace.getRightLeaf(!1);if(!e){new Qe.Notice("Stashpad: couldn't open the detail panel.");return}await e.setViewState({type:Kt,active:!0}),A.workspace.revealLeaf(e)}var F=require("obsidian");ce();var Rt=require("obsidian");ce();function dd(A,r){let e=A.vault.getAbstractFileByPath(r);if(!(e instanceof Rt.TFolder))return[];let t=[],i=[e];for(;i.length;){let s=i.pop();for(let n of s.children)n instanceof Rt.TFile?n.extension==="md"&&t.push(n):n instanceof Rt.TFolder&&(Xa(n.name)||i.push(n))}return t}var Qn=class{constructor(r){this.app=r;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(S,{id:S,parent:null,children:[],file:null,created:""})}setOrderProvider(r){this.orderProvider=r}onChange(r){return this.listeners.add(r),()=>this.listeners.delete(r)}emit(){for(let r of this.listeners)r()}rebuild(r){r!==void 0&&(this.currentFolder=r);let e=this.currentFolder,t=this.byPath,i=this.nodes;this.nodes=new Map,this.byPath=new Map,this.nodes.set(S,{id:S,parent:null,children:[],file:null,created:""});let s=e?dd(this.app,e):this.app.vault.getMarkdownFiles();for(let n of s){let o=this.app.metadataCache.getFileCache(n)?.frontmatter,a=o?.id;if(!a){let c=t.get(n.path),d=c?i.get(c):void 0,h=this.synthetic.get(n.path),p=d??h;p&&(this.nodes.set(p.id,{...p,children:[],file:n}),this.byPath.set(n.path,p.id));continue}if(this.synthetic.delete(n.path),a===S){let c=this.nodes.get(S);c.file=n,c.created=o?.created??"",this.byPath.set(n.path,S);continue}let l=o?.parent??null;l===a&&(l=null),this.nodes.set(a,{id:a,parent:l??S,children:[],file:n,created:o?.created??""}),this.byPath.set(n.path,a)}for(let n of this.nodes.values()){if(n.id===S)continue;let o=new Set([n.id]),a=n.parent??S;for(;a!==S&&this.nodes.has(a);){if(o.has(a)){n.parent=S;break}o.add(a),a=this.nodes.get(a).parent??S}}for(let n of this.nodes.values()){if(n.id===S)continue;let o=n.parent??S;(this.nodes.get(o)??this.nodes.get(S)).children.push(n.id)}for(let n of this.nodes.values())if(n.children.sort((o,a)=>{let l=this.nodes.get(o),c=this.nodes.get(a);return(l.created||"").localeCompare(c.created||"")}),this.orderProvider){let o=this.orderProvider(n.id);if(o.length>0){let a=new Map;o.forEach((l,c)=>a.set(l,c)),n.children.sort((l,c)=>{let d=a.has(l)?a.get(l):1/0,h=a.has(c)?a.get(c):1/0;return d===h?0:d-h})}}this.emit()}insertSynthetic(r){if(!r.file)return;let e=r.file.path;this.synthetic.set(e,r),this.nodes.set(r.id,r),this.byPath.set(e,r.id);let t=r.parent??S,i=this.nodes.get(t);i&&!i.children.includes(r.id)&&i.children.push(r.id),this.emit()}get(r){return this.nodes.get(r)}getRoot(){return this.nodes.get(S)}getChildren(r){let e=this.nodes.get(r);return e?e.children.map(t=>this.nodes.get(t)).filter(t=>!!t):[]}fileBackedCount(){let r=0;for(let e of this.nodes.values())e.file&&r++;return r}pathTo(r){let e=[],t=new Set,i=this.nodes.get(r);for(;i&&i.id!==S&&!t.has(i.id);)t.add(i.id),e.unshift(i),i=i.parent?this.nodes.get(i.parent):void 0;return e}idForPath(r){return this.byPath.get(r)}snapshot(){let r={};for(let e of this.nodes.values())e.id===S||!e.file||(r[e.id]={parent:e.parent===S?null:e.parent,path:e.file.path});return r}hookMetadataCache(r){let e=l=>{let c=this.currentFolder;return c?typeof l!="string"?!1:l===c||l.startsWith(c+"/"):!0},t=!1,i=()=>{t=!0,this.coalesceTimer==null&&(this.coalesceTimer=window.setTimeout(()=>{this.coalesceTimer=null,t&&(t=!1,this.emit(),r())},16))},s=l=>{l instanceof Rt.TFile&&e(l.path)&&l.extension==="md"&&(this.applyChange(l),i())},n=l=>{l instanceof Rt.TFile&&e(l.path)&&l.extension==="md"&&this.applyChange(l)&&i()},o=l=>{let c=l?.path;typeof c=="string"&&e(c)&&this.applyDelete(c)&&i()},a=(l,c)=>{if(!(l instanceof Rt.TFile))return;let d=typeof c=="string"?c:null;!e(l.path)&&!e(d)||this.applyRename(l,d??"")&&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(r){if(Jt(r.path))return this.byPath.has(r.path)?this.applyDelete(r.path):!1;let e=this.app.metadataCache.getFileCache(r)?.frontmatter,t=e?.id,i=this.byPath.get(r.path);if(!t){if(i){let c=this.nodes.get(i);if(c&&c.file!==r)return c.file=r,!0}return!1}if(this.synthetic.delete(r.path),t===S){let c=this.nodes.get(S),d=e?.created??"",h=!1;return c.file!==r&&(c.file=r,h=!0),c.created!==d&&(c.created=d,h=!0),this.byPath.get(r.path)!==S&&(this.byPath.set(r.path,S),h=!0),h}let s=e?.parent??S;s===t&&(s=S);let n=e?.created??"";if(!(s===S||this.nodes.has(s)))return this.rebuild(),!0;if(i&&i!==t)return this.rebuild(),!0;let a=this.nodes.get(t);if(!a){let c={id:t,parent:s,children:[],file:r,created:n};return this.nodes.set(t,c),this.byPath.set(r.path,t),this.attachToParent(c),this.resortChildrenOf(s),!0}let l=!1;if(a.file!==r&&(a.file=r,l=!0),a.created!==n&&(a.created=n,this.resortChildrenOf(a.parent??S),l=!0),a.parent!==s){let c=a.parent??S;this.detachFromParent(a),a.parent=s,this.attachToParent(a),this.resortChildrenOf(c),this.resortChildrenOf(s),l=!0}return l}applyDelete(r){let e=this.byPath.get(r);if(!e)return!1;let t=this.nodes.get(e);if(!t)return this.byPath.delete(r),this.synthetic.delete(r),!0;this.detachFromParent(t);let i=this.nodes.get(S);for(let s of t.children){let n=this.nodes.get(s);n&&(n.parent=S,i.children.includes(s)||i.children.push(s))}return t.children.length>0&&this.resortChildrenOf(S),this.nodes.delete(e),this.byPath.delete(r),this.synthetic.delete(r),!0}applyRename(r,e){let t=this.currentFolder,i=!t||e===t||e.startsWith(t+"/"),s=!t||r.path===t||r.path.startsWith(t+"/");if(!i&&!s)return!1;if(i&&!s)return this.applyDelete(e);if(!i&&s)return this.applyChange(r);if(Jt(r.path))return this.byPath.has(e)?this.applyDelete(e):!1;let n=this.byPath.get(e);if(!n)return this.applyChange(r);this.byPath.delete(e),this.byPath.set(r.path,n);let o=this.nodes.get(n);return o&&(o.file=r),!0}detachFromParent(r){let e=this.nodes.get(r.parent??S);if(!e)return;let t=e.children.indexOf(r.id);t>=0&&e.children.splice(t,1)}attachToParent(r){let e=this.nodes.get(r.parent??S);e||(e=this.nodes.get(S)),e.children.includes(r.id)||e.children.push(r.id)}resortChildrenOf(r){let e=this.nodes.get(r);if(e&&(e.children.sort((t,i)=>{let s=this.nodes.get(t),n=this.nodes.get(i);return(s.created||"").localeCompare(n.created||"")}),this.orderProvider)){let t=this.orderProvider(r);if(t.length>0){let i=new Map;t.forEach((s,n)=>i.set(s,n)),e.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 sa=class{constructor(){this.enabled=!1;this.buckets=new Map}record(r,e){if(!this.enabled)return;let t=this.buckets.get(r);t||(t={count:0,total:0,max:0},this.buckets.set(r,t)),t.count+=1,t.total+=e,e>t.max&&(t.max=e)}time(r,e){if(!this.enabled)return e();let t=performance.now();try{return e()}finally{this.record(r,performance.now()-t)}}async timeAsync(r,e){if(!this.enabled)return e();let t=performance.now();try{return await e()}finally{this.record(r,performance.now()-t)}}reset(){this.buckets.clear()}hasData(){return this.buckets.size>0}report(){let r=[...this.buckets.entries()].map(([t,i])=>({label:t,...i,avg:i.total/i.count})).sort((t,i)=>i.total-t.total);if(r.length===0)return"Stashpad perf: no samples (enable profiling, then use the app).";let e=["**Stashpad performance profile**","","| label | count | total (ms) | avg (ms) | max (ms) |","| --- | ---: | ---: | ---: | ---: |"];for(let t of r)e.push(`| \`${t.label}\` | ${t.count} | ${t.total.toFixed(0)} | ${t.avg.toFixed(1)} | ${t.max.toFixed(0)} |`);return e.join(` +`)}},Te=new sa;Tt();var Ut={min:6e4,minute:6e4,m:6e4,h:36e5,hr:36e5,hour:36e5,d:864e5,day:864e5,w:6048e5,wk:6048e5,week:6048e5};function na(A){if(typeof A=="number")return A>0?A:null;if(!A)return null;let r=String(A).trim().toLowerCase().match(/^(\d+(?:\.\d+)?)\s*([a-z]+)?$/);if(!r)return null;let e=parseFloat(r[1]),t=(r[2]||"min").replace(/s$/,""),i=Ut[t];return i&&e>0?e*i:null}var Vr=["sunday","monday","tuesday","wednesday","thursday","friday","saturday"];function Wr(A,r){let e=new Date(A),t=e.getDate();return e.setMonth(e.getMonth()+r),e.getDate()<t&&e.setDate(0),e.getTime()}function Xr(A,r){let e=new Date(A);return e.setFullYear(e.getFullYear()+r),e.getTime()}function Ad(A,r){let e=new Date(A);do e.setDate(e.getDate()+1);while(e.getDay()!==r);return e.getTime()}function hd(A){let r=new Date(A);do r.setDate(r.getDate()+1);while(r.getDay()===0||r.getDay()===6);return r.getTime()}function kn(A){if(!A)return null;let r=String(A).trim().toLowerCase();if(!r)return null;let e="due";/\b(when done|after completion|on completion|from completion)\b/.test(r)&&(e="completion",r=r.replace(/\b(when done|after completion|on completion|from completion)\b/g,"").trim()),r=r.replace(/^every\s+/,"").replace(/\s+/g," ").trim();let t=(n,o)=>({next:n,anchor:e,label:o});if(/^(first|1st) of (the )?month$/.test(r))return t(n=>{let o=new Date(n);return o.setMonth(o.getMonth()+1,1),o.getTime()},"first of the month");let i=Vr.indexOf(r.replace(/s$/,""));if(i>=0)return t(n=>Ad(n,i),`every ${Vr[i]}`);if(r==="weekday"||r==="weekdays"||r==="business day"||r==="business days")return t(hd,"every weekday");if(r==="daily"||r==="day")return t(n=>n+Ut.day,"every day");if(r==="weekly"||r==="week")return t(n=>n+Ut.week,"every week");if(r==="monthly"||r==="month")return t(n=>Wr(n,1),"every month");if(r==="yearly"||r==="annually"||r==="year")return t(n=>Xr(n,1),"every year");if(r==="hourly"||r==="hour")return t(n=>n+Ut.h,"every hour");let s=r.match(/^(\d+)\s*([a-z]+)$/);if(s){let n=parseInt(s[1],10),o=s[2].replace(/s$/,"");if(n>0){if(o==="day")return t(a=>a+n*Ut.day,`every ${n} days`);if(o==="week"||o==="wk")return t(a=>a+n*Ut.week,`every ${n} weeks`);if(o==="month"||o==="mo")return t(a=>Wr(a,n),`every ${n} months`);if(o==="year"||o==="yr")return t(a=>Xr(a,n),`every ${n} years`);if(o==="hour"||o==="hr"||o==="h")return t(a=>a+n*Ut.h,`every ${n} hours`);if(o==="min"||o==="minute"||o==="m")return t(a=>a+n*Ut.min,`every ${n} minutes`)}}return null}function Fn(A,r,e){let t=A.anchor==="completion"?e:r??e,i=A.next(t),s=0;for(;i<=e&&s++<5e3;)i=A.next(i);if(i<=e){i=A.next(e);let n=0;for(;i<=e&&n++<5e3;)i=A.next(i)}return i}var Zr=".stashpad-order.json",Ni=class{constructor(r){this.app=r;this.cache=new Map;this.pendingTimers=new Map;this.writeInFlight=new Map}async load(r){if(this.cache.has(r))return this.cache.get(r);let e=`${r}/${Zr}`,t=this.app.vault.adapter,i={};try{if(await t.exists(e)){let s=await t.read(e),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(l=>typeof l=="string")&&(i[o]=a)}}catch(s){console.warn("Stashpad: order load failed",s)}return this.cache.set(r,i),i}async save(r){this.scheduleWrite(r)}async flush(r){let e=this.pendingTimers.get(r);e!=null&&(window.clearTimeout(e),this.pendingTimers.delete(r)),await this.writeNow(r)}scheduleWrite(r){let e=this.pendingTimers.get(r);e!=null&&window.clearTimeout(e);let t=window.setTimeout(()=>{this.pendingTimers.delete(r),this.writeNow(r)},150);this.pendingTimers.set(r,t)}async writeNow(r){let t=(this.writeInFlight.get(r)??Promise.resolve()).then(()=>this.doWrite(r));this.writeInFlight.set(r,t);try{await t}finally{this.writeInFlight.get(r)===t&&this.writeInFlight.delete(r)}}async doWrite(r){let e=this.cache.get(r)??{},t=`${r}/${Zr}`,i=this.app.vault.adapter;try{if(await i.exists(t)){let n=JSON.parse(await i.read(t));if(n&&typeof n=="object"&&!Array.isArray(n))for(let[o,a]of Object.entries(n))!(o in e)&&Array.isArray(a)&&a.every(l=>typeof l=="string")&&(e[o]=a)}}catch{}let s={};for(let[n,o]of Object.entries(e))o.length>0&&(s[n]=o);this.cache.set(r,s);try{if(Object.keys(s).length===0)try{await i.remove(t)}catch{}else await i.write(t,JSON.stringify(s,null,2))}catch(n){console.warn("Stashpad: order save failed",n)}}getOrder(r,e){return this.cache.get(r)?.[e]?.slice()??[]}setOrder(r,e,t){let i=this.cache.get(r)??{};i[e]=t.slice(),this.cache.set(r,i)}appendChild(r,e,t){let i=this.cache.get(r)??{},s=i[e]??[];s.includes(t)||s.push(t),i[e]=s,this.cache.set(r,i)}removeChild(r,e){let t=this.cache.get(r);if(t)for(let i of Object.values(t)){let s=i.indexOf(e);s>=0&&i.splice(s,1)}}invalidate(r){this.cache.delete(r)}};var Ti={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"},oa=["manual","created-asc","created-desc","modified-asc","modified-desc","title-az","title-za"],jr=new Set(oa),_r=".stashpad-sort.json",Sn=class{constructor(r){this.app=r;this.cache=new Map;this.pendingTimers=new Map;this.writeInFlight=new Map}async load(r){if(this.cache.has(r))return this.cache.get(r);let e=`${r}/${_r}`,t=this.app.vault.adapter,i={};try{if(await t.exists(e)){let s=JSON.parse(await t.read(e));if(s&&typeof s=="object"&&!Array.isArray(s))for(let[n,o]of Object.entries(s))typeof o=="string"&&jr.has(o)&&(i[n]=o)}}catch(s){console.warn("Stashpad: sort load failed",s)}return this.cache.set(r,i),i}async save(r){this.scheduleWrite(r)}async flush(r){let e=this.pendingTimers.get(r);e!=null&&(window.clearTimeout(e),this.pendingTimers.delete(r)),await this.writeNow(r)}scheduleWrite(r){let e=this.pendingTimers.get(r);e!=null&&window.clearTimeout(e);let t=window.setTimeout(()=>{this.pendingTimers.delete(r),this.writeNow(r)},150);this.pendingTimers.set(r,t)}async writeNow(r){let t=(this.writeInFlight.get(r)??Promise.resolve()).then(()=>this.doWrite(r));this.writeInFlight.set(r,t);try{await t}finally{this.writeInFlight.get(r)===t&&this.writeInFlight.delete(r)}}async doWrite(r){let e=this.cache.get(r)??{},t=`${r}/${_r}`,i=this.app.vault.adapter;try{if(await i.exists(t)){let s=JSON.parse(await i.read(t));if(s&&typeof s=="object"&&!Array.isArray(s))for(let[n,o]of Object.entries(s))!(n in e)&&typeof o=="string"&&jr.has(o)&&(e[n]=o)}}catch{}try{if(Object.keys(e).length===0)try{await i.remove(t)}catch{}else await i.write(t,JSON.stringify(e,null,2))}catch(s){console.warn("Stashpad: sort save failed",s)}}getMode(r,e){return this.cache.get(r)?.[e]??"manual"}setMode(r,e,t){let i=this.cache.get(r)??{};t==="manual"?delete i[e]:i[e]=t,this.cache.set(r,i)}removeParent(r,e){let t=this.cache.get(r);t&&delete t[e]}invalidate(r){this.cache.delete(r)}};ce();ki();var Lt="parentLink",Pi="children";var Mi=class Mi{constructor(r,e){this.app=r;this.getTree=e;this.pending=new Set;this.timer=null;this.activityListeners=new Set;this.recentSelfWrites=new Map;this.errorListeners=new Set}onActivity(r){return this.activityListeners.add(r),()=>this.activityListeners.delete(r)}emitActivity(){let r=this.pending.size;for(let e of this.activityListeners)try{e(r)}catch(t){console.warn("[Stashpad] fmSync activity listener failed",t)}}wasRecentSelfWrite(r){let e=this.recentSelfWrites.get(r);return e==null?!1:(this.recentSelfWrites.delete(r),Date.now()-e<Mi.SELF_WRITE_GRACE_MS)}schedule(r){if(!r||!X().writeRecoveryLinks)return;let e=this.pending.size;this.pending.add(r),this.pending.size!==e&&this.emitActivity(),this.kick()}scheduleParentChange(r,e,t){this.schedule(r),e&&this.schedule(e),this.schedule(t)}scheduleSubtree(r){let e=this.getTree(),t=i=>{this.schedule(i);for(let s of e.getChildren(i))t(s.id)};t(r)}scheduleParentOfDeleted(r){r&&this.schedule(r)}async flush(){for(this.timer!=null&&(window.clearTimeout(this.timer),this.timer=null);this.pending.size>0;){let r=this.pending.values().next().value;if(r===void 0)break;this.pending.delete(r),this.emitActivity(),await this.syncOne(r)}}pendingCount(){return this.pending.size}onError(r){return this.errorListeners.add(r),()=>this.errorListeners.delete(r)}emitError(r,e){for(let t of this.errorListeners)try{t(r,e)}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(),Mi.PACING_MS))}async tick(){this.timer=null;let r=this.pending.values().next().value;if(r!==void 0){this.pending.delete(r),this.emitActivity();try{await this.syncOne(r)}catch(e){console.warn("[Stashpad] frontmatter sync tick failed",e)}this.pending.size>0&&this.kick()}}wouldWrite(r){let t=this.getTree().get(r);if(!t||!t.file)return!1;let i=this.computeParentLink(t),s=this.computeChildrenLinks(t),n=this.app.metadataCache.getFileCache(t.file)?.frontmatter,o=n&&typeof n[Lt]=="string"?n[Lt]:null,a=n?.[Pi],l=Array.isArray(a)?a.filter(c=>typeof c=="string"):[];if((o??null)!==(i??null)||l.length!==s.length)return!0;for(let c=0;c<l.length;c++)if(l[c]!==s[c])return!0;return!1}async syncOne(r){let t=this.getTree().get(r);if(!t||!t.file||!this.wouldWrite(r))return;let i=this.computeParentLink(t),s=this.computeChildrenLinks(t);try{this.recentSelfWrites.set(t.file.path,Date.now()),await Te.timeAsync("write.fmSync",()=>this.app.fileManager.processFrontMatter(t.file,n=>{i?n[Lt]=i:delete n[Lt],s.length>0?n[Pi]=s:delete n[Pi]}))}catch(n){console.warn("[Stashpad] frontmatter sync failed",t.file?.path,n),this.emitError(t.file.path,n)}}computeParentLink(r){if(r.id===S)return null;let e=this.getTree();if(!r.parent||r.parent===S){let i=e.getRoot();return i&&i.id!==r.id&&i.file?bn(i.file.path):null}let t=e.get(r.parent);return t?.file?bn(t.file.path):null}computeChildrenLinks(r){return this.getTree().getChildren(r.id).filter(t=>!!t.file).map(t=>bn(t.file.path))}};Mi.PACING_MS=100,Mi.SELF_WRITE_GRACE_MS=2500;var Dn=Mi;async function Hi(A,r){let e=r.endsWith("/")?r:r+"/",t=new Map,i=new Map;for(let c of A.vault.getMarkdownFiles()){if(c.path!==r&&!c.path.startsWith(e))continue;let d=A.metadataCache.getFileCache(c)?.frontmatter,h=typeof d?.id=="string"?d.id:null;if(!h)continue;let p=typeof d?.parent=="string"?d.parent:S;t.set(h,{file:c,id:h,parent:p});let f=i.get(p)??[];f.push(h),i.set(p,f)}let s=c=>bn(c.file.path),n=c=>{if(c.id===S)return null;if(c.parent===S||!c.parent){let h=t.get(S);return h?s(h):null}let d=t.get(c.parent);return d?s(d):null},o=c=>{let d=i.get(c.id)??[],h=[];for(let p of d){let f=t.get(p);f&&h.push(s(f))}return h},a=0,l=0;for(let c of t.values()){a+=1;let d=n(c),h=o(c),p=A.metadataCache.getFileCache(c.file)?.frontmatter,f=p&&typeof p[Lt]=="string"?p[Lt]:null,u=p?.[Pi],g=Array.isArray(u)?u.filter(C=>typeof C=="string"):[],I=(f??null)===(d??null),m=g.length===h.length&&g.every((C,B)=>C===h[B]);if(!(I&&m))try{await A.fileManager.processFrontMatter(c.file,C=>{d?C[Lt]=d:delete C[Lt],h.length>0?C[Pi]=h:delete C[Pi]}),l+=1,await new Promise(C=>setTimeout(C,50))}catch(C){console.warn("[Stashpad] rebootstrap fm sync failed",c.file.path,C)}}return{checked:a,written:l}}function bn(A){return`[[${A.replace(/\.md$/i,"")}]]`}sn();ui();var xn=class{constructor(r,e){this.tree=r;this.log=e;this.sweepChain=Promise.resolve()}async sweep(r){let e=this.sweepChain.then(()=>this.doSweep(r),()=>this.doSweep(r));return this.sweepChain=e.catch(()=>{}),e}async doSweep(r){let e=await this.log.readState(),t=this.tree.snapshot(),i=n=>{if(!r)return!0;let o=r.replace(/\/+$/,"");return n===o||n.startsWith(o+"/")};for(let[n,o]of Object.entries(t)){let a=e[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(e))!t[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(e))i(o.path)||(s[n]=o);for(let[n,o]of Object.entries(t))s[n]=o;await this.log.writeState(s)}};ki();var Ie=require("obsidian");ce();Fo();var ye=Ie.moment;function aa(A){let r=A.trim().toLowerCase();if(!r)return null;let e=Date.now(),t=u=>ye(u).startOf("day").valueOf(),i=/\b(\d{1,2})(?::(\d{2}))?\s*(am|pm)?\b/gi,s=0,n=!1,o=r,a=null;for(let u=i.exec(r);u!=null;u=i.exec(r))if(u[3]||u[2]){a=u;break}if(a){let u=parseInt(a[1],10),g=a[2]?parseInt(a[2],10):0,I=a[3]?.toLowerCase();I==="pm"&&u<12&&(u+=12),I==="am"&&u===12&&(u=0),u>=0&&u<24&&g>=0&&g<60&&(s=(u*3600+g*60)*1e3,n=!0,o=r.replace(a[0]," ").replace(/\s+/g," ").trim())}let l=u=>n?u+s:u;if(o===""||o==="today")return l(t(e));if(o==="yesterday")return l(ye(e).startOf("day").subtract(1,"day").valueOf());if(o==="tomorrow")return l(ye(e).startOf("day").add(1,"day").valueOf());let c=["sunday","monday","tuesday","wednesday","thursday","friday","saturday"],d=["sun","mon","tue","wed","thu","fri","sat"],h=c.indexOf(o)>=0?c.indexOf(o):d.indexOf(o);if(h>=0){let u=ye().startOf("day"),I=(u.day()-h+7)%7;return l(u.subtract(I,"days").valueOf())}let p=/^(\d+)\s*([dwmy])$/.exec(o);if(p){let u=parseInt(p[1],10),g={d:"days",w:"weeks",m:"months",y:"years"}[p[2]];return l(ye().subtract(u,g).startOf("day").valueOf())}let f=ye(o,["YYYY-MM-DD","YYYY/MM/DD","MM-DD-YYYY","MM/DD/YYYY","M-D-YYYY","M/D/YYYY"],!0);return f.isValid()?l(f.startOf("day").valueOf()):null}function ra(A){let r={text:[],filters:{}},e=(A||"").trim();if(!e)return r;let t=/(?<![\w-])(in|before|after|on):\s*(?:\[([^\]]*)\]|([^]*?)(?=\s+(?:in|before|after|on):|$))/gi,i=e.split(""),s;for(;(s=t.exec(e))!=null;){let n=s[1].toLowerCase(),o=(s[2]!==void 0?s[2]:s[3]??"").trim();if(!o)continue;let a=!1;if(n==="in")r.filters.in=o.toLowerCase(),a=!0;else if(n==="before"){let l=aa(o);l!=null&&(r.filters.before=l,a=!0)}else if(n==="after"){let l=aa(o);l!=null&&(r.filters.after=l,a=!0)}else if(n==="on"){let l=aa(o);if(l!=null)if(a=!0,/\b\d{1,2}:\d{2}\b|\b\d{1,2}\s*(?:am|pm)\b/i.test(o))r.filters.on={start:l-6e4,end:l+6e4};else{let d=ye(l).startOf("day");r.filters.on={start:d.valueOf(),end:d.clone().add(1,"day").valueOf()}}}if(a)for(let l=s.index;l<s.index+s[0].length;l++)i[l]=" "}for(let n of i.join("").split(/\s+/))n&&r.text.push(n.toLowerCase());return r}var at=class A extends Ie.SuggestModal{constructor(e,t,i,s){super(e);this.tree=t;this.titleFn=i;this.opts=s;this.notes=[];this.includeExcluded=!1;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 e=this.pendingCleanups.pop();try{e&&e()}catch{}}try{this.opts.onClose?.()}catch{}}loadAll(){let e=this.tree.getRoot(),t=e.file?.parent?.name?.trim()??"",i=t?`Home \u2014 ${t}`:"Home",s=(n,o)=>{let a=this.tree.get(n);a?.file&&n!==S?this.notes.push({node:a,title:`${" ".repeat(o)}${this.titleFn(a)}`,body:""}):a?.file&&n===S&&this.notes.push({node:a,title:i,body:""});for(let l of this.tree.getChildren(n))s(l.id,o+1)};e.file&&this.notes.push({node:e,title:i,body:""});for(let n of this.tree.getChildren(S))s(n.id,1);if(this.opts.lockedNotes)for(let n of this.opts.lockedNotes()){let o=(this.opts.hideLockedTitles??!1)||!n.title;this.notes.push({node:null,title:o?"Locked note":n.title,body:"",locked:n})}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(a=>{o.body=this.stripFm(a)})}}createdMsFor(e){if(e.node?.created){let t=Date.parse(e.node.created);if(!Number.isNaN(t))return t}if(e.locked?.created){let t=Date.parse(e.locked.created);if(!Number.isNaN(t))return t}return e.cross?.file?.stat?.ctime!=null?e.cross.file.stat.ctime:null}stripFm(e){if(!e.startsWith("---"))return e;let t=e.indexOf(` +---`,3);return t===-1?e:e.slice(t+4).replace(/^\r?\n/,"")}getSuggestions(e){let t=e.trim().toLowerCase(),i=ra(e),s=i.text,n=y=>{if(!s.length)return!0;for(let v of s)if(!y.includes(v))return!1;return!0},o=null,a=null;if(i.filters.in){let y=i.filters.in.split(/\s+/).filter(Boolean);o=new Set,a=new Map;let v=k=>y.every(D=>k.toLowerCase().includes(D)),Q=k=>{if(!o.has(k)){o.add(k);for(let D of this.tree.getChildren(k))Q(D.id)}};for(let k of this.notes)!k.node||k.cross||v(k.title)&&Q(k.node.id);let w=new Map;for(let k of this.notes){if(!k.cross)continue;let D=w.get(k.cross.folder)??[];D.push(k),w.set(k.cross.folder,D)}for(let[k,D]of w){let H=new Map;for(let x of D){let U=x.cross?.parentId??null;if(!U)continue;let T=H.get(U)??[];T.push(x.cross.id),H.set(U,T)}let R=new Set;a.set(k,R);let L=x=>{if(!R.has(x)){R.add(x);for(let U of H.get(x)??[])L(U)}};for(let x of D)v(x.title)&&L(x.cross.id)}}let l=y=>{let v=i.filters;if(o||a)if(y.cross){let Q=a?.get(y.cross.folder);if(!Q||!Q.has(y.cross.id))return!1}else if(y.node){if(!o||!o.has(y.node.id))return!1}else return!1;if(v.before||v.after||v.on){let Q=this.createdMsFor(y);if(Q==null||v.before!=null&&Q>=v.before||v.after!=null&&Q<=v.after||v.on&&(Q<v.on.start||Q>=v.on.end))return!1}return!0},c=y=>n(y.toLowerCase()),d=this.notes.filter(y=>!y.cross),h=this.notes.filter(y=>y.cross),p=(y,v)=>({id:y.locked?`locked:${y.locked.blob}`:y.cross?`cross:${y.cross.folder}:${y.cross.id}`:y.node.id,label:y.title,node:y.node,kind:"note",bodyPreview:this.previewFromBody(y.body,v),matchLine:v,crossFolder:y.cross?.folder,crossFile:y.cross?.file,crossId:y.cross?.id,locked:y.locked}),f=y=>y.node?.file?.stat?.mtime??y.cross?.file?.stat?.mtime??0,u=y=>y.node?.id===S||y.cross?.id===S,g=this.opts.mode==="pick",I=y=>{let v;if(!t)v=0;else{let Q=y.title.toLowerCase(),w=y.body.toLowerCase();Q===t?v=6:Q.startsWith(t)?v=5:Q.includes(t)?v=4:s.every(k=>Q.includes(k))?v=3:w.includes(t)?v=2:v=1}return g&&u(y)&&(v+=.5),v},m=y=>{let v=[];for(let k of y)if(l(k))if(this.opts.mode==="search"){if(!t){v.push({n:k,matchLines:[]});continue}let D=n(k.title.toLowerCase()),H=k.body.split(/\r?\n/),R=[];for(let x=0;x<H.length;x++)c(H[x])&&R.push(x);let L=R.length>0||n(k.body.toLowerCase());if(!D&&!L)continue;v.push({n:k,matchLines:R})}else{if(t&&!n(k.title.toLowerCase())&&!n(k.body.toLowerCase()))continue;v.push({n:k,matchLines:[]})}let Q=v.map(k=>({...k,band:I(k.n),mtime:f(k.n)}));Q.sort((k,D)=>D.band-k.band||D.mtime-k.mtime);let w=[];for(let{n:k,matchLines:D}of Q)if(this.opts.mode==="search"&&t&&D.length>0){let H=[],R=-100;for(let x of D)x-R>5&&H.push(x),R=x;let L=5;for(let x of H.slice(0,L))w.push(p(k,x))}else w.push(p(k,-1));return w},C=m(d),B=[...C];if(this.opts.mode==="search"?t?!0:C.length<10:!!t){let y=m(h);this.opts.mode==="search"&&!t&&(B.length=Math.min(B.length,50)),B.push(...y)}if(this.opts.folderResults){let y=this.opts.folderResults(),v={id:"__folder_picker__",label:"Open folder in a new tab\u2026",node:null,kind:"folder-open"};y.length>0&&(t?y.some(Q=>{let w=Q.split("/").pop()??Q;return n(`${Q.toLowerCase()} ${w.toLowerCase()}`)})&&B.push(v):B.unshift(v))}if(this.opts.allowCreate&&t&&!B.some(y=>y.label.trim().toLowerCase()===t)&&B.push({id:"__create__",label:`Create new: "${e}"`,node:null,kind:"create"}),i.text.join("").length>=3){let y=Q=>Q.kind==="note"&&(Q.id===S||Q.crossId===S)&&n(Q.label.toLowerCase()),v=B.filter(y);if(v.length>0){let Q=B.filter(w=>!y(w));B.splice(0,B.length,...v,...Q)}}return this.opts.excludedFolderNotes&&!this.includeExcluded&&B.push({id:"__search_excluded__",label:"Search excluded Stashpad folders",node:null,kind:"search-excluded"}),B}loadExcludedNotes(){if(this.includeExcluded||!this.opts.excludedFolderNotes)return;this.includeExcluded=!0;for(let t of this.opts.excludedFolderNotes())this.notes.push({node:null,title:t.title,body:t.body,cross:t});this.crossFolderIndex=null;for(let t of this.notes)!t.cross||t.body||!t.cross.file||this.app.vault.cachedRead(t.cross.file).then(i=>{t.body=this.stripFm(i)});let e=this.inputEl;e&&(e.dispatchEvent(new Event("input",{bubbles:!0})),setTimeout(()=>e.dispatchEvent(new Event("input",{bubbles:!0})),250))}previewFromBody(e,t){let i=e.split(/\r?\n/);if(t<0)return i.filter(a=>a.trim().length>0).slice(0,3).join(` `);let s=Math.max(0,t-2),n=Math.min(i.length,t+3);return i.slice(s,n).filter(o=>o.trim().length>0).join(` -`)}renderSuggestion(e,t){if(t.addClass("stashpad-suggest-item"),e.kind==="create"){t.createDiv({cls:"stashpad-suggest-create",text:e.label});return}if(e.kind==="folder-open"){t.addClass("is-folder-open"),t.createDiv({cls:"stashpad-suggest-title",text:e.label}),e.folder?t.createDiv({cls:"stashpad-suggest-preview",text:e.folder}):t.createDiv({cls:"stashpad-suggest-preview",text:"Click to choose a folder\u2026"});return}if(e.kind==="search-excluded"){t.addClass("is-search-excluded");let f=t.createDiv({cls:"stashpad-suggest-title stashpad-search-excluded-row"}),u=f.createSpan({cls:"stashpad-search-excluded-icon"});(0,Ie.setIcon)(u,"folder-search"),f.createSpan({text:e.label}),t.createDiv({cls:"stashpad-suggest-preview",text:"Include folders you've excluded from search (e.g. to move a note there)."});return}if(e.locked){t.addClass("stashpad-suggest-row","is-locked");let f=t.createDiv({cls:"stashpad-suggest-body"}),u=f.createDiv({cls:"stashpad-suggest-title stashpad-suggest-locked"});(0,Ie.setIcon)(u.createSpan({cls:"stashpad-suggest-locked-icon"}),"lock");let g=na(this.inputEl?.value??"").text;this.highlightInto(u.createSpan(),e.label,g),f.createDiv({cls:"stashpad-suggest-preview",text:e.locked.count>1?`${e.locked.count} notes \xB7 locked`:"Encrypted \u2014 locked"});return}e.crossFolder&&t.addClass("is-cross-folder"),t.addClass("stashpad-suggest-row");let i=t.createDiv({cls:"stashpad-suggest-body"}),s=this.notes.find(f=>e.crossFolder?f.cross?.folder===e.crossFolder&&f.cross?.id===e.crossId:f.node?.id===e.id),n=na(this.inputEl?.value??"").text,o=this.firstLineOfBody(s?.body??"")||e.label.trim(),a=i.createDiv({cls:"stashpad-suggest-title"});this.highlightInto(a,o,n);let l=e.crossFolder??this.opts.localFolder??null;if(e.bodyPreview&&e.matchLine!=null&&e.matchLine>=0){let f=i.createDiv({cls:"stashpad-suggest-preview stashpad-suggest-snippet"});this.highlightInto(f,e.bodyPreview,n)}let c="";if(e.crossFolder?c=s?.cross?.parentBlurb??"":c=this.parentBlurbFor(e.node),c){let f=i.createDiv({cls:"stashpad-suggest-preview"});f.appendText("Parent: "),this.highlightInto(f,c,n)}let A=e.crossFolder?this.buildCrossBreadcrumb(e):this.buildLocalBreadcrumb(e.node),h=e.crossFolder??this.opts.localFolder??null;if(h||A){let f=i.createDiv({cls:"stashpad-suggest-breadcrumb"}),g=[h?h.split("/").pop()||h:"",A].filter(I=>I&&I.length>0).join(" \u203A ");g&&f.setText(g)}let p=s?this.createdMsFor(s):null;if(p!=null||l){let f=t.createDiv({cls:"stashpad-suggest-rail"});if(p!=null){let u=f.createDiv({cls:"stashpad-suggest-time"});u.setText(this.formatRelativeTime(p)),u.title=ye(p).format("YYYY-MM-DD HH:mm")}l&&f.createDiv({cls:"stashpad-suggest-folder-badge",text:l.split("/").pop()||l})}}formatRelativeTime(e){let t=ye(e),i=ye().startOf("day").diff(ye(e).startOf("day"),"days");return i===0?t.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?t.format("MMM D"):t.format("MMM D, YYYY")}highlightInto(e,t,i){if(!t)return;let s=i.filter(c=>c&&c.length>0);if(!s.length){e.appendText(t);return}let n=t.toLowerCase(),o=[];for(let c of s){let A=0;for(;(A=n.indexOf(c,A))!==-1;)o.push([A,A+c.length]),A+=1}if(!o.length){e.appendText(t);return}o.sort((c,A)=>c[0]-A[0]);let a=[];for(let c of o){let A=a[a.length-1];A&&c[0]<=A[1]?A[1]=Math.max(A[1],c[1]):a.push([c[0],c[1]])}let l=0;for(let[c,A]of a)c>l&&e.appendText(t.slice(l,c)),e.createSpan({cls:"stashpad-suggest-match",text:t.slice(c,A)}),l=A;l<t.length&&e.appendText(t.slice(l))}buildLocalBreadcrumb(e){if(!e||!e.parent||e.parent===S)return"";let t=[],i=new Set([e.id]),s=this.tree.get(e.parent);for(;s&&s.id!==S&&!i.has(s.id);)i.add(s.id),t.unshift(this.titleFn(s)),s=s.parent&&s.parent!==S?this.tree.get(s.parent):void 0;return t.join(" \u203A ")}buildCrossBreadcrumb(e){if(!e.crossFolder)return"";if(!this.crossFolderIndex){this.crossFolderIndex=new Map;for(let l of this.notes){if(!l.cross)continue;let c=this.crossFolderIndex.get(l.cross.folder);c||(c=new Map,this.crossFolderIndex.set(l.cross.folder,c)),c.set(l.cross.id,l.cross)}}let t=this.crossFolderIndex.get(e.crossFolder);if(!t)return"";let i=e.crossId??e.id.replace(/^cross:/,""),s=t.get(i);if(!s)return"";let n=[],o=new Set([s.id]),a=s.parentId?t.get(s.parentId):null;for(;a&&!o.has(a.id);)o.add(a.id),n.unshift(a.title),a=a.parentId?t.get(a.parentId):null;return n.join(" \u203A ")}firstLineOfBody(e){if(!e)return"";let t=e.split(/\r?\n/);for(let i of t){let s=i.trim();if(s)return s}return""}parentBlurbFor(e){if(!e||!e.parent||e.parent===S)return"";let t=this.tree.get(e.parent);if(!t||!t.file)return"";let i=this.notes.find(s=>s.node?.id===t.id);return i?this.firstLineOfBody(i.body):""}onOpen(){if(super.onOpen(),this.opts.showFilterChips&&!Ie.Platform.isMobile){let e=this.inputEl,t=this.resultContainerEl;if(!e||!t)return;this.mountFilterChipRow(e,t);return}if(Ie.Platform.isMobile){let e=this.inputEl;e&&e.focus()}}mountFilterChipRow(e,t){e.addEventListener("keydown",c=>{if(c.key==="["){c.preventDefault();let A=e.selectionStart??e.value.length,h=e.selectionEnd??A,p=e.value.slice(0,A),f=e.value.slice(A,h),u=e.value.slice(h);e.value=`${p}[${f}]${u}`;let g=A+1+f.length;e.setSelectionRange(g,g),e.dispatchEvent(new Event("input",{bubbles:!0}));return}if(c.key==="]"){let A=e.selectionStart??-1;A>=0&&e.value[A]==="]"&&(c.preventDefault(),e.setSelectionRange(A+1,A+1));return}if(c.key==="Backspace"&&!c.metaKey&&!c.ctrlKey&&!c.altKey&&e.selectionStart===e.selectionEnd){let A=e.selectionStart??-1;if(A>0&&e.value[A-1]==="["&&e.value[A]==="]"){c.preventDefault();let h=e.value.slice(0,A-1),p=e.value.slice(A+1);e.value=`${h}${p}`,e.setSelectionRange(A-1,A-1),e.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(e,"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(e,i)}),o.addEventListener("keydown",c=>{(c.key==="Enter"||c.key===" ")&&(c.preventDefault(),c.stopPropagation(),o.click())}),i.appendChild(o),t.parentElement?.insertBefore(i,t);let a=new Ie.Scope(this.scope),l=c=>{let A=document.activeElement;return A?.classList?.contains("stashpad-search-filter-chip")?(c.preventDefault(),A.click(),!1):c.key==="Enter"&&!c.isComposing?(c.preventDefault(),this.selectActiveSuggestion?.(c),!1):!0};a.register([],"Enter",l),a.register([]," ",l),a.register(["Mod"],"f",c=>{c.preventDefault();let A=this.inputEl;return A&&(A.focus(),A.select()),!1}),a.register([],"Tab",c=>{let A=this.modalEl,h=this.inputEl;if(!A)return!0;let p=Array.from(A.querySelectorAll('input, button, select, textarea, a[href], [tabindex]:not([tabindex="-1"])')).filter(g=>!g.hasAttribute("disabled")&&g.tabIndex!==-1&&g.offsetParent!==null);if(p.length===0)return!0;let f=document.activeElement,u=f?p.indexOf(f):-1;if(c.shiftKey){if(u<=0)return c.preventDefault(),p[p.length-1].focus(),!1}else if(u===p.length-1)return c.preventDefault(),(h??p[0]).focus(),!1;return!0}),this.app.keymap?.pushScope(a),this.pendingCleanups.push(()=>{try{this.app.keymap?.popScope(a)}catch{}})}appendFilterToInput(e,t,i){let s=e.value,o=`${s.length>0&&!/\s$/.test(s)?" ":""}${t}: [`,a="]",l=i;e.value=`${s}${o}${l}${a}`;let c=s.length+o.length+l.length;if(e.setSelectionRange(c,c+0),!l){let A=s.length+o.length;e.setSelectionRange(A,A)}e.focus(),e.dispatchEvent(new Event("input",{bubbles:!0}))}toggleWhenBuilder(e,t){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 g of o){let I=document.createElement("button");I.type="button",I.className="stashpad-when-tab",I.textContent=g.label,this.whenMode===g.id&&I.addClass("is-active"),I.addEventListener("mousedown",m=>m.preventDefault()),I.addEventListener("click",m=>{if(m.preventDefault(),this.whenMode===g.id)return;let C=this.whenMode;C!=="between"&&g.id==="between"?this.whenBetweenEndText="":C==="between"&&g.id!=="between"&&(!this.whenSingleText&&this.whenBetweenEndText&&(this.whenSingleText=this.whenBetweenEndText),this.whenBetweenEndText=""),this.whenMode=g.id;for(let B in a)a[B].toggleClass("is-active",B===g.id);u()}),a[g.id]=I,n.appendChild(I)}s.appendChild(n);let l=document.createElement("div");l.className="stashpad-when-body",s.appendChild(l);let c=(g,I,m="single")=>{let C=ye().format("YYYY-MM-DD"),B=!I||I===C;if(m==="betweenStart")return"00:00";if(m==="betweenEnd")return"23:59";switch(g){case"after":return"00:00";case"on":return B?ye().format("HH:mm"):"23:59";case"before":return B?ye().format("HH:mm"):"23:59";default:return"23:59"}},A=(g,I)=>{g.addEventListener("keydown",m=>{m.key==="Enter"?(m.preventDefault(),m.stopPropagation(),I()):m.key==="Escape"&&(m.preventDefault(),m.stopPropagation(),this.closeWhenBuilder())})},h=(g,I)=>{let m=g.selectionStart??g.value.length,C=g.selectionEnd??g.value.length,E=`${m>0&&!/\s$/.test(g.value.slice(0,m))?" ":""}${I}`,y=g.value.slice(0,m)+E+g.value.slice(C);g.value=y;let v=m+E.length;g.setSelectionRange(v,v),g.focus(),g.dispatchEvent(new Event("input",{bubbles:!0}))},p=(g,I)=>{let C=g.slice(0,I).match(/(\d{4}-\d{2}-\d{2})(?!.*\d{4}-\d{2}-\d{2})/);return C?C[1]:null},f=(g,I,m,C)=>{let B=l.createDiv({cls:"stashpad-when-input-wrap has-icons"}),E=B.createDiv({cls:"stashpad-when-icon-slot"}),y=E.createEl("button",{cls:"stashpad-when-icon stashpad-when-icon-cal"});y.type="button",y.title="Pick date",(0,Ie.setIcon)(y,"calendar-days");let v=E.createEl("input",{cls:"stashpad-when-native",attr:{type:"date"}});v.tabIndex=-1;let Q=B.createDiv({cls:"stashpad-when-icon-slot"}),w=Q.createEl("button",{cls:"stashpad-when-icon stashpad-when-icon-clock"});w.type="button",w.title="Pick time",(0,Ie.setIcon)(w,"clock");let F=B.createDiv({cls:"stashpad-when-icon-slot"}),D=F.createEl("button",{cls:"stashpad-when-icon stashpad-when-icon-day"});D.type="button",D.title="Pick day",(0,Ie.setIcon)(D,"calendar");let H=B.createDiv({cls:"stashpad-when-icon-slot"}),R=H.createEl("button",{cls:"stashpad-when-icon stashpad-when-icon-tf"});R.type="button",R.title="Pick timeframe",(0,Ie.setIcon)(R,"history");let L=B.createEl("input",{cls:"stashpad-when-input",attr:{type:"text",placeholder:g}});L.value=I(),L.addEventListener("input",()=>m(L.value));let x=B.createEl("button",{cls:"stashpad-when-clear"});x.type="button",x.textContent="\xD7",x.title="Clear";for(let O of[y,w,D,R,x])O.addEventListener("mousedown",K=>K.preventDefault());let U=null,T=(O,K)=>{U&&U();let $=O.createDiv({cls:"stashpad-when-popover"}),Z=O.ownerDocument??document,V=new Ie.Scope(this.scope),J=null,ee=te=>{J=te},ue=!1,oe=te=>{!$.contains(te.target)&&te.target!==O&&!O.contains(te.target)&&ie()},ie=()=>{if(!ue){ue=!0,$.remove(),Z.removeEventListener("mousedown",oe,!0);try{this.app.keymap?.popScope(V)}catch{}U===ie&&(U=null)}};U=ie,V.register([],"Escape",te=>(te.preventDefault(),ie(),!1)),V.register([],"Enter",te=>(te.preventDefault(),J&&J(),!1));try{K($,ie,ee)}catch(te){console.error("[stashpad] popover fill threw:",te),$.remove(),U=null;return}this.app.keymap?.pushScope(V),this.pendingCleanups.push(ie),setTimeout(()=>Z.addEventListener("mousedown",oe,!0),0)};R.addEventListener("click",O=>{O.preventDefault(),T(H,(K,$,Z)=>{let V=this.whenMode==="on",J=(se,Ae)=>{if(!V)return`${se}${Ae}`;let Xe={d:"days",w:"weeks",m:"months",y:"years"}[Ae];return ye().subtract(se,Xe).format("YYYY-MM-DD")},ee=K.createDiv({cls:"stashpad-when-pop-row"}),ue=[{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 se of ue){let Ae=ee.createEl("button",{cls:"stashpad-when-pop-chip",text:se.label});Ae.type="button",Ae.addEventListener("mousedown",Xe=>Xe.preventDefault()),Ae.addEventListener("click",Xe=>{Xe.preventDefault(),h(L,J(se.n,se.unit)),$()})}let oe=K.createDiv({cls:"stashpad-when-pop-row stashpad-when-pop-builder"});oe.createSpan({text:"Last",cls:"stashpad-when-pop-label"});let ie=oe.createEl("input",{cls:"stashpad-when-pop-number",attr:{type:"number",min:"1",max:"999",value:"7"}}),te=oe.createEl("select",{cls:"stashpad-when-pop-unit"});for(let se of[{v:"d",label:"days"},{v:"w",label:"weeks"},{v:"m",label:"months"},{v:"y",label:"years"}]){let Ae=te.createEl("option",{text:se.label});Ae.value=se.v}let fe=oe.createEl("button",{cls:"stashpad-when-pop-chip stashpad-when-pop-go",text:"Insert"});fe.type="button";let we=()=>{let se=parseInt(ie.value,10);!Number.isFinite(se)||se<1||(h(L,J(se,te.value)),$())};fe.addEventListener("mousedown",se=>se.preventDefault()),fe.addEventListener("click",se=>{se.preventDefault(),we()}),Z(we),ie.focus(),ie.select()})});let b=(O,K,$,Z,V)=>{T(K,(J,ee,ue)=>{$s(J,{seedH:$,seedM:Z,seedPeriod:V,close:ee,setOnEnter:ue,onFinalize:oe=>h(O,nr(oe))})})};D.addEventListener("click",O=>{O.preventDefault(),T(F,(K,$,Z)=>{let V=K.createDiv({cls:"stashpad-when-pop-row"});for(let ie of["Today","Yesterday"]){let te=V.createEl("button",{cls:"stashpad-when-pop-chip",text:ie});te.type="button",te.addEventListener("mousedown",fe=>fe.preventDefault()),te.addEventListener("click",fe=>{fe.preventDefault(),h(L,ie),$()})}let J=K.createDiv({cls:"stashpad-when-pop-row stashpad-when-pop-days"}),ee=["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],oe=(ye().day()+6)%7;for(let ie=0;ie<ee.length;ie++){let te=ee[ie],fe=J.createEl("button",{cls:"stashpad-when-pop-chip",text:te.slice(0,3)});fe.type="button",fe.title=te,ie===oe&&fe.addClass("is-today"),fe.addEventListener("mousedown",we=>we.preventDefault()),fe.addEventListener("click",we=>{if(we.preventDefault(),C==="betweenEnd"){let se=ie,Ae=ye().startOf("day"),Xe=(Ae.day()+6)%7,ai=(se-Xe+7)%7;ai===0&&(ai=7);let Us=Ae.clone().add(ai,"days").format("YYYY-MM-DD");h(L,Us)}else h(L,te);$()})}})});let M=(O,K)=>{O.value||(O.value=K);let $=O;if(typeof $.showPicker=="function")try{$.showPicker();return}catch{}O.focus(),O.click()};return y.addEventListener("click",O=>{O.preventDefault(),M(v,ye().format("YYYY-MM-DD"))}),v.addEventListener("change",()=>{v.value&&h(L,v.value)}),w.addEventListener("click",O=>{O.preventDefault();let K=L.selectionStart??L.value.length,$=p(L.value,K),Z=c(this.whenMode,$,C),[V,J]=Z.split(":"),ee=parseInt(V,10),ue=parseInt(J,10),oe=ee%12;oe===0&&(oe=12);let ie=ee>=12?"pm":"am";b(L,Q,oe,ue,ie)}),x.addEventListener("click",O=>{O.preventDefault(),L.value="",m(""),L.focus()}),L},u=()=>{if(l.empty(),this.whenMode==="between"){let g=f("start (date / day / timeframe)",()=>this.whenSingleText,y=>{this.whenSingleText=y},"betweenStart"),I=f("end (date / day / timeframe)",()=>this.whenBetweenEndText,y=>{this.whenBetweenEndText=y},"betweenEnd"),m=l.createDiv({cls:"stashpad-when-actions"}),C=m.createEl("button",{cls:"stashpad-when-insert",text:"Insert"});C.type="button",C.addEventListener("mousedown",y=>y.preventDefault());let B=()=>{let y=g.value.trim(),v=I.value.trim();y&&this.appendFilterToInput(e,"after",y),v&&this.appendFilterToInput(e,"before",v),this.closeWhenBuilder()};C.addEventListener("click",y=>{y.preventDefault(),B()});let E=m.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()}),A(g,B),A(I,B),g.focus(),g.setSelectionRange(g.value.length,g.value.length)}else{let g=f("date / day / timeframe",()=>this.whenSingleText,E=>{this.whenSingleText=E},"single"),I=l.createDiv({cls:"stashpad-when-actions"}),m=I.createEl("button",{cls:"stashpad-when-insert",text:"Insert"});m.type="button",m.addEventListener("mousedown",E=>E.preventDefault());let C=()=>{let E=g.value.trim();E&&this.appendFilterToInput(e,this.whenMode,E),this.closeWhenBuilder()};m.addEventListener("click",E=>{E.preventDefault(),C()});let B=I.createEl("button",{cls:"stashpad-when-cancel",text:"Cancel"});B.type="button",B.addEventListener("mousedown",E=>E.preventDefault()),B.addEventListener("click",E=>{E.preventDefault(),this.closeWhenBuilder()}),A(g,C),g.focus(),g.setSelectionRange(g.value.length,g.value.length)}};u(),t.parentElement?.insertBefore(s,t.nextSibling),this.whenBuilderEl=s}closeWhenBuilder(){if(!this.whenBuilderEl)return;this.whenBuilderEl.remove(),this.whenBuilderEl=null,this.modalEl?.removeClass("is-when-builder-open")}selectSuggestion(e,t){if(e&&e.kind==="search-excluded"){this.loadExcludedNotes();return}super.selectSuggestion(e,t)}onChooseSuggestion(e){if(e.kind==="create"&&this.opts.onCreate){let t=this.inputEl?.value??"",i=t.replace(/(?<![\w-])(in|before|after|on):\s*(?:\[[^\]]*\]|[^]*?(?=\s+(?:in|before|after|on):|$))/gi," ").replace(/\s+/g," ").trim();this.opts.onCreate(i||t);return}if(e.kind==="folder-open"&&e.id==="__folder_picker__"){let t=this.opts.folderResults?.()??[];if(!t.length)return;let i=this.inputEl?.value??"",s=!1,n=p=>{s=!0;let f=p.split("/").pop()??p;this.opts.onPick({id:`folder:${p}`,label:`Open folder \u201C${f}\u201D in a new tab`,node:null,kind:"folder-open",folder:p})},o=new oa(this.app,t,n),a=o.onClose.bind(o),l=this.tree,c=this.titleFn,A=this.opts,h=this.app;o.onClose=()=>{a(),setTimeout(()=>{if(s)return;let p=new d(h,l,c,A);p.open(),setTimeout(()=>{let f=p.inputEl;f&&(i&&(f.value=i,f.dispatchEvent(new Event("input",{bubbles:!0}))),f.focus(),f.setSelectionRange(f.value.length,f.value.length))},0)},0)},o.open();return}if(e.node?.file&&!this.app.vault.getAbstractFileByPath(e.node.file.path)){new Ie.Notice("That note no longer exists.");return}this.opts.onPick(e)}},oa=class extends Ie.FuzzySuggestModal{constructor(e,t,i){super(e);this.folders=t;this.onChosen=i;this.setPlaceholder("Open which folder?")}getItems(){return this.folders}getItemText(e){let t=e.split("/").pop()??e;return t===e?e:`${t} \u2014 ${e}`}onChooseItem(e){this.onChosen(e)}};var ys="stashpad";function Dn(d){let r=[];d.vault&&r.push(`vault=${encodeURIComponent(d.vault)}`),r.push(`folder=${encodeURIComponent(d.folder)}`),d.note&&r.push(`note=${encodeURIComponent(d.note)}`);let e=d.run&&d.run.length?d.run:["reveal"];return r.push(`run=${encodeURIComponent(e.join(","))}`),`obsidian://${ys}?${r.join("&")}`}function Zr(d){let r=(d||"").trim();if(!r)return null;let e;if(/^obsidian:\/\//i.test(r)){let c=r.match(/^obsidian:\/\/([^?]*)(?:\?(.*))?$/i);if(!c||decodeURIComponent(c[1].replace(/\/+$/,"")).toLowerCase()!==ys)return null;e=c[2]??""}else e=r.replace(/^\?/,"");let t=new URLSearchParams(e),i=t.get("folder");if(!i)return null;let s={folder:i},n=t.get("vault");n&&(s.vault=n);let o=t.get("note");o&&(s.note=o);let a=t.get("run");a&&(s.run=a);let l=t.get("action");return l&&(s.action=l),s}function jr(d){let r=d.run;!r&&d.action&&d.action!==ys&&(r=d.action);let e=(r||"reveal").split(",").map(t=>t.trim().toLowerCase()).filter(Boolean);return e.length?e:["reveal"]}var Ge=require("obsidian");ve();async function _r(d,r,e,t){let i=e.blob,s=i.replace(/\.stashenc$/,".stashmeta"),n=d.vault.adapter,o=null,a=null;try{o=await n.readBinary(i)}catch{o=null}if(!o){new Ge.Notice("Couldn't read the encrypted file to delete it.");return}try{await n.exists(s)&&(a=await n.read(s))}catch{a=null}let l=(r.settings.lockedSubtrees??[]).find(p=>p.blob===i)??null,c=async p=>{let f=d.vault.getAbstractFileByPath(p);if(f)try{await d.fileManager.trashFile(f);return}catch{}try{await n.exists(p)&&await n.remove(p)}catch{}},A=async()=>{await c(i),await c(s),r.settings.lockedSubtrees=(r.settings.lockedSubtrees??[]).filter(p=>p.blob!==i),await r.saveSettings(),t()},h=async()=>{if(await n.writeBinary(i,o),a!=null)try{await n.write(s,a)}catch{}l&&!(r.settings.lockedSubtrees??[]).some(p=>p.blob===i)&&(r.settings.lockedSubtrees=[...r.settings.lockedSubtrees??[],l],await r.saveSettings()),t()};await A(),r.getUndoStack(e.folder).push({label:e.count>1?"Delete encrypted notes":"Delete encrypted note",undo:h,redo:A}),new Ge.Notice(e.count>1?"Encrypted notes deleted \u2014 undo to restore.":"Encrypted note deleted \u2014 undo to restore.")}function xn(d,r){let{app:e,plugin:t,descriptor:i}=r,s=p=>new Ge.Notice(`Unlock this note first to ${p}.`),n=p=>{if(Ge.Platform.isMobile)return p;try{return e.vault.adapter?.getFullPath?.(p)||p}catch{return p}},o=()=>{let p=Dn({vault:e.vault.getName(),folder:i.folder,note:i.rootId,run:["reveal"]});navigator.clipboard.writeText(p).then(()=>new Ge.Notice("Stashpad link copied."),()=>new Ge.Notice("Couldn't copy the link."))},a=()=>{d.addItem(p=>{p.setTitle("Share & export").setIcon("share-2");let f=typeof p.setSubmenu=="function"?p.setSubmenu():null;f&&typeof f.addItem=="function"?(f.addItem(u=>{u.setTitle("Copy Stashpad link").setIcon("link"),i.rootId?u.onClick(()=>o()):u.setDisabled(!0)}),f.addItem(u=>u.setTitle("Export to .stash\u2026").setIcon("package").onClick(()=>{t.exportLockedSubtree(i.blob)})),t.settings.okfEnabled&&f.addItem(u=>u.setTitle("Export as OKF\u2026").setIcon("book-marked").onClick(()=>s("export it as OKF")))):i.rootId?p.onClick(()=>o()):p.setDisabled(!0)})},l=()=>{d.addItem(p=>p.setTitle(r.unlockLabel).setIcon("unlock").onClick(()=>r.onUnlock()))},c=()=>{if(Ge.Platform.isMobile)return;let p=Ge.Platform.isMacOS?"Finder":Ge.Platform.isWin?"File Explorer":"file manager";d.addItem(f=>f.setTitle(`Show in ${p}`).setIcon("folder-search").onClick(()=>{try{let u=window.require?.("electron")?.shell,g=e.vault.adapter?.getFullPath?.(i.blob);g&&u?.showItemInFolder&&u.showItemInFolder(g)}catch(u){console.warn("[Stashpad] showItemInFolder failed",u)}}))},A=()=>{d.addItem(p=>p.setTitle("Copy encrypted file path").setIcon("copy").onClick(()=>{navigator.clipboard.writeText(n(i.blob)),new Ge.Notice("Path copied.")}))},h=()=>{d.addItem(p=>{p.setTitle(i.count>1?"Delete encrypted notes\u2026":"Delete encrypted note\u2026").setIcon("trash-2"),p.setWarning?.(!0),p.onClick(()=>{r.confirmDelete?new j(e,i.count>1?`Delete ${i.count} encrypted notes?`:"Delete encrypted note?","The encrypted file moves to Obsidian's trash (recoverable there). You'll still need your password to read it if you restore it.","Delete",async f=>{f&&await _r(e,t,i,r.onChange)}).open():_r(e,t,i,r.onChange)})})};r.fullParity?(d.addItem(p=>p.setTitle("Open in new Stashpad tab").setIcon("layout-grid").onClick(()=>s("open it in a tab"))),d.addItem(p=>p.setTitle("Open in Obsidian editor").setIcon("file-text").onClick(()=>s("open it in the editor"))),d.addItem(p=>p.setTitle("Focus in Stashpad").setIcon("arrow-right").onClick(()=>s("focus it"))),d.addSeparator(),d.addItem(p=>p.setTitle("Split note\u2026").setIcon("split").onClick(()=>s("split it"))),d.addItem(p=>p.setTitle("Copy text").setIcon("copy").onClick(()=>s("copy its text"))),d.addItem(p=>p.setTitle("Clone (duplicate / copy)").setIcon("files").onClick(()=>s("clone it"))),d.addItem(p=>p.setTitle("Fork into a separate note\u2026").setIcon("git-branch").onClick(()=>s("fork it"))),a(),l(),c(),A(),d.addSeparator(),d.addItem(p=>p.setTitle("Move to\u2026").setIcon("move").onClick(()=>s("move it"))),d.addItem(p=>p.setTitle("Move to Home").setIcon("home").onClick(()=>s("move it"))),d.addItem(p=>p.setTitle("Pin to sidebar").setIcon("pin").onClick(()=>s("pin it"))),d.addItem(p=>p.setTitle("Pin to top of list").setIcon("arrow-up-to-line").onClick(()=>s("pin it"))),d.addItem(p=>p.setTitle("Set color\u2026").setIcon("palette").onClick(()=>s("set its color"))),d.addItem(p=>p.setTitle("Task").setIcon("check-circle-2").onClick(()=>s("change its task state"))),d.addSeparator(),h()):(l(),a(),d.addSeparator(),c(),A(),d.addSeparator(),h())}var el=require("obsidian");ce();var Nn=class extends el.SuggestModal{constructor(r){super(r),this.setPlaceholder("Run a Stashpad command\u2026");let e=this.app.commands?.commands??{};this.commands=Object.keys(e).filter(t=>t.startsWith("stashpad:")).filter(t=>t!=="stashpad:stashpad-command-palette").map(t=>({id:t,name:cd(e[t]?.name??t)})).sort((t,i)=>t.name.localeCompare(i.name))}getSuggestions(r){return this.commands.filter(e=>qs(r,e.name))}renderSuggestion(r,e){e.createDiv({text:r.name,cls:"stashpad-cmd-palette-name"})}onChooseSuggestion(r){this.app.commands?.executeCommandById?.(r.id)}};function cd(d){return d.replace(/^(?:\s*Stashpad:\s*)+/i,"").trim()||d}An();ve();un();var aa=require("obsidian");function tl(d){let r=d.code||"",e=/^Key([A-Z])$/.exec(r);if(e)return e[1].toLowerCase();let t=/^Digit(\d)$/.exec(r);return t?t[1]:(d.key||"").toLowerCase()}function dd(d,r){return!r||d.metaKey||d.ctrlKey||d.altKey?!1:r.length===1&&!/[a-z0-9]/i.test(r)?d.key===r:tl(d)===r.toLowerCase()}function Hi(d,r){return r?r.includes("+")?Ad(d,r):dd(d,r):!1}function q(d,r){if(!r)return!1;let{primary:e,secondary:t,preferRight:i,useBoth:s}=r;return e&&t?s?Hi(d,e)||Hi(d,t):i?Hi(d,t):Hi(d,e):Hi(d,e)||Hi(d,t)}function ws(d){if(!d)return"";let r=aa.Platform.isMacOS;return d.split("+").map(e=>{let t=e.trim();return t?t.toLowerCase()==="mod"?r?"Cmd":"Ctrl":t.toLowerCase()==="alt"?r?"Opt":"Alt":t.length===1?t.toUpperCase():t:""}).filter(Boolean).join("+")}function Ad(d,r){if(!r)return!1;let e=r.split("+").map(h=>h.trim()).filter(Boolean);if(e.length<2)return!1;let t=e[e.length-1].toLowerCase(),i=new Set(e.slice(0,-1).map(h=>h.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"),l=i.has("shift"),A=aa.Platform.isMacOS?d.metaKey:d.ctrlKey;return s&&!A||n&&!d.ctrlKey||o&&!d.metaKey||a!==d.altKey||l!==d.shiftKey||!s&&(!n&&d.ctrlKey||!o&&d.metaKey)?!1:tl(d)===t}var ae=require("obsidian");ce();var il=require("obsidian"),hd="byfolder";function Tn(d,r,e,t){let i=d.createDiv({cls:"stashpad-trash-modes"}),s=i.createEl("button",{cls:"stashpad-agg-reset",attr:{"aria-label":"Reset to default view"}});(0,il.setIcon)(s,"rotate-ccw"),s.onclick=()=>t(hd);let n=[{key:"byfolder",label:"By folder",count:e.total},{key:"separated",label:"Separated",count:e.total},{key:"mixed",label:"Mixed (by date)",count:e.total},{key:"encrypted",label:"Encrypted",count:e.enc},{key:"unencrypted",label:"Unencrypted",count:e.dec}];for(let o of n){let a=i.createEl("button",{cls:"stashpad-triage-chip"});r===o.key&&a.addClass("is-active"),a.createSpan({text:o.label}),a.createSpan({cls:"stashpad-triage-chip-count",text:String(o.count)}),a.onclick=()=>t(o.key)}}function yt(d,r,e,t){if(!e||e===r)return;let i=o=>{let a=!1;return d.iterateAllLeaves(l=>{l===o&&(a=!0)}),a},s=r,n=d.on("active-leaf-change",()=>{if(i(r)){s=d.activeLeaf??s;return}d.offref(n),s===r&&i(e)&&(d.setActiveLeaf(e,{focus:!0}),d.revealLeaf(e))});t?.(n)}var Mn=ae.moment,Pn=class extends ae.ItemView{constructor(e,t){super(e);this.plugin=t;this.mode="encrypted";this.taskState=mn();this.archiveSubMode="byfolder";this.renderPending=!1;this.watchFolderFilter="";this.watchViaFilter="";this.watchQuery=""}getViewType(){return ci}getDisplayText(){return this.mode==="archived"?"All archived":this.mode==="tasks"?"All tasks":this.mode==="watch"?"Previously encrypted":"All encrypted"}getIcon(){return this.mode==="archived"?"archive":this.mode==="tasks"?"check-square":this.mode==="watch"?"history":"lock"}getState(){return{...super.getState(),mode:this.mode}}async setState(e,t){(e?.mode==="archived"||e?.mode==="encrypted"||e?.mode==="tasks"||e?.mode==="watch")&&(this.mode=e.mode),await super.setState(e,t),await this.render()}async onOpen(){this.containerEl.addClass("stashpad-aggregate-view");let e=s=>s.endsWith(".stashenc")&&!s.startsWith("_deleted/"),t=s=>s.endsWith(".md")&&/(^|\/)archive\//.test(s),i=s=>e(s)||t(s);this.registerEvent(this.app.vault.on("create",s=>{i(s.path)&&this.scheduleRender()})),this.registerEvent(this.app.vault.on("delete",s=>{i(s.path)&&this.scheduleRender()})),this.registerEvent(this.app.vault.on("rename",(s,n)=>{(i(s.path)||i(n))&&this.scheduleRender()})),await this.render()}scheduleRender(){this.renderPending||(this.renderPending=!0,window.setTimeout(()=>{this.renderPending=!1,this.render()},150))}cleanFolder(e){return(e||"").replace(/\/+$/,"")}archiveFolders(){let e=new Set;for(let i of this.plugin.discoverStashpadFolders()){let s=Dt(i);this.plugin.app.vault.getAbstractFileByPath(s)&&e.add(s)}for(let i of this.plugin.settings.archiveFolders??[])e.add(this.cleanFolder(i));let t=this.plugin.settings.folderEncPrefs??{};for(let[i,s]of Object.entries(t))s?.archive&&e.add(this.cleanFolder(i));return[...e].sort((i,s)=>i.localeCompare(s))}async render(){let e=this.contentEl;e.empty(),e.addClass("stashpad-aggregate-body");let t=e.createDiv({cls:"stashpad-aggregate-header"});t.createEl("h3",{text:this.getDisplayText()});let i=t.createEl("button",{cls:"stashpad-trash-iconbtn"});if((0,ae.setIcon)(i,"refresh-cw"),i.setAttr("aria-label","Refresh"),i.onclick=()=>void this.render(),this.mode==="tasks"){Cs(e.createDiv(),this.app,this.plugin,this.taskState,{onOpen:(s,n)=>void this.plugin.revealNoteByRef(s,n)});return}if(this.mode==="archived"){this.renderArchived(e);return}if(this.mode==="watch"){this.renderWatch(e);return}this.renderEncrypted(e)}renderEncrypted(e){let t=this.plugin.settings.lockedSubtrees??[];if(t.length===0){e.createDiv({cls:"stashpad-trash-empty",text:"Nothing is encrypted yet. Lock a note or folder and it shows up here."});return}let i=new Map;for(let n of t){let o=this.cleanFolder(n.folder)||"(vault root)";(i.get(o)??i.set(o,[]).get(o)).push(n)}let s=[...i.keys()].sort((n,o)=>n.localeCompare(o));e.createDiv({cls:"stashpad-aggregate-sub",text:`${t.length} locked ${t.length===1?"item":"items"} in ${s.length} ${s.length===1?"folder":"folders"}.`});for(let n of s){let o=e.createDiv({cls:"stashpad-trash-group"}),a=o.createDiv({cls:"stashpad-trash-group-head"});(0,ae.setIcon)(a.createSpan({cls:"stashpad-trash-group-icon"}),"folder"),a.createSpan({text:n.split("/").pop()||n}),a.createSpan({cls:"stashpad-trash-group-count",text:String(i.get(n).length)});let l=a.createEl("button",{cls:"stashpad-trash-iconbtn",text:"Open"});l.onclick=()=>void this.plugin.activateViewForFolder(n);for(let c of i.get(n)){let A=o.createDiv({cls:"stashpad-trash-row"}),h=A.createDiv({cls:"stashpad-trash-row-main"});h.createSpan({cls:"stashpad-trash-title",text:c.title||"Locked note"});let p=c.created?`locked ${Mn(c.created).fromNow()}`:"locked",f=c.count>1?` \xB7 ${c.count} notes`:"";h.createSpan({cls:"stashpad-trash-sub",text:p+f});let u=A.createEl("button",{cls:"stashpad-trash-iconbtn",text:"Export"});u.setAttr("aria-label","Export to .stash (encrypted with a password you choose)"),u.onclick=()=>void this.plugin.exportLockedSubtree(c.blob);let g=A.createSpan({cls:"stashpad-aggregate-lockbadge"});(0,ae.setIcon)(g,"lock"),this.attachLockedRowMenu(A,c,{archived:!1})}}}renderArchived(e){let t=this.archiveFolders();if(t.length===0){e.createDiv({cls:"stashpad-trash-empty",text:"No archive folders yet. Toggle Archive on a folder to collect it here."});return}let i=new Set(t),s=this.plugin.settings.lockedSubtrees??[],n=new Map;for(let g of s){let I=this.cleanFolder(g.folder);i.has(I)&&(n.get(I)??n.set(I,[]).get(I)).push(g)}let o=new Map,a=0;for(let g of t){let I=this.plugin.archivedPlainNotesIn(g);o.set(g,I),a+=I.length}let l=[...n.values()].reduce((g,I)=>g+I.length,0),c=a+l,A=t.flatMap(g=>o.get(g)??[]),h=t.flatMap(g=>n.get(g)??[]);e.createDiv({cls:"stashpad-aggregate-sub",text:`${t.length} archive ${t.length===1?"folder":"folders"}, ${c} archived ${c===1?"item":"items"} (${a} plain \xB7 ${l} locked).`}),Tn(e,this.archiveSubMode,{total:c,enc:l,dec:a},g=>{this.archiveSubMode=g,this.render()});let p=this.archiveSubMode;if(p==="mixed"){let g=[];for(let m of A)g.push({ts:m.stat.mtime||0,kind:"plain",f:m});for(let m of h)g.push({ts:m.created&&Date.parse(m.created)||0,kind:"locked",e:m});g.sort((m,C)=>C.ts-m.ts);let I=e.createDiv({cls:"stashpad-trash-group"});for(let m of g)m.kind==="plain"&&m.f?this.archivePlainRow(I,m.f):m.e&&this.archiveLockedRow(I,m.e);return}if(p==="byfolder"){for(let g of t){let I=n.get(g)??[],m=o.get(g)??[],C=e.createDiv({cls:"stashpad-trash-group"}),B=C.createDiv({cls:"stashpad-trash-group-head"});(0,ae.setIcon)(B.createSpan({cls:"stashpad-trash-group-icon"}),"archive"),B.createSpan({text:g.split("/").pop()||g}),B.createSpan({cls:"stashpad-trash-group-count",text:String(I.length+m.length)});let E=B.createEl("button",{cls:"stashpad-trash-iconbtn",text:"Open"});if(E.onclick=()=>void this.plugin.activateViewForFolder(g),I.length===0&&m.length===0){C.createDiv({cls:"stashpad-trash-sub",text:"No archived items."});continue}for(let y of m)this.archivePlainRow(C,y);for(let y of I)this.archiveLockedRow(C,y)}return}let f=p!=="encrypted"&&A.length>0,u=p!=="unencrypted"&&h.length>0;if(!f&&!u){e.createDiv({cls:"stashpad-trash-empty",text:"Nothing in this view."});return}if(f){let g=e.createDiv({cls:"stashpad-trash-group"}),I=g.createDiv({cls:"stashpad-trash-group-head"});(0,ae.setIcon)(I.createSpan({cls:"stashpad-trash-group-icon"}),"file-text"),I.createSpan({text:"Plain notes"}),I.createSpan({cls:"stashpad-trash-group-count",text:String(A.length)});for(let m of A)this.archivePlainRow(g,m)}if(u){let g=e.createDiv({cls:"stashpad-trash-group"}),I=g.createDiv({cls:"stashpad-trash-group-head"});(0,ae.setIcon)(I.createSpan({cls:"stashpad-trash-group-icon"}),"lock"),I.createSpan({text:"Locked (encrypted)"}),I.createSpan({cls:"stashpad-trash-group-count",text:String(h.length)});for(let m of h)this.archiveLockedRow(g,m)}}archivePlainRow(e,t){let i=e.createDiv({cls:"stashpad-trash-row"}),s=i.createDiv({cls:"stashpad-trash-row-main"});s.createSpan({cls:"stashpad-trash-title",text:t.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ").trim()||t.basename}),s.createSpan({cls:"stashpad-trash-sub",text:`archived ${Mn(t.stat.mtime).fromNow()}`});let n=i.createEl("button",{cls:"stashpad-trash-restore",text:"Restore"});(0,ae.setIcon)(n.createSpan({cls:"stashpad-btn-icon"}),"rotate-ccw"),n.onclick=async()=>{n.disabled=!0,await this.plugin.unarchiveNote(t)?this.render():n.disabled=!1},this.attachPlainRowMenu(i,t,n)}attachPlainRowMenu(e,t,i){let s=()=>{let o=new ae.Menu;return o.addItem(a=>a.setTitle("Open note").setIcon("file-text").onClick(()=>void this.app.workspace.getLeaf(!1).openFile(t))),o.addItem(a=>a.setTitle("Restore (un-archive)").setIcon("rotate-ccw").onClick(()=>i.click())),o.addSeparator(),ae.Platform.isMobile||o.addItem(a=>a.setTitle("Show in Finder").setIcon("folder-open").onClick(()=>{try{let l=window.require?.("electron")?.shell,c=this.app.vault.adapter?.getFullPath?.(t.path);c&&l?.showItemInFolder&&l.showItemInFolder(c)}catch(l){console.warn("[Stashpad] showItemInFolder failed",l)}})),o.addItem(a=>a.setTitle("Copy file path").setIcon("copy").onClick(()=>{let l=t.path;if(!ae.Platform.isMobile)try{l=this.app.vault.adapter?.getFullPath?.(t.path)||t.path}catch{}navigator.clipboard.writeText(l),new ae.Notice("Path copied.")})),o};e.oncontextmenu=o=>{o.preventDefault(),s().showAtMouseEvent(o)};let n=e.createEl("button",{cls:"stashpad-trash-iconbtn stashpad-agg-more"});(0,ae.setIcon)(n,"ellipsis-vertical"),n.setAttr("aria-label","More actions"),n.onclick=o=>{o.stopPropagation(),s().showAtMouseEvent(o)}}archiveLockedRow(e,t){let i=e.createDiv({cls:"stashpad-trash-row"}),s=i.createDiv({cls:"stashpad-trash-row-main"});s.createSpan({cls:"stashpad-trash-title",text:t.title||"Locked note"});let n=t.created?`archived ${Mn(t.created).fromNow()}`:"archived",o=(t.count??0)>1?` \xB7 ${t.count} notes`:"";s.createSpan({cls:"stashpad-trash-sub",text:n+o});let a=i.createEl("button",{cls:"stashpad-trash-restore",text:"Restore"});(0,ae.setIcon)(a.createSpan({cls:"stashpad-btn-icon"}),"rotate-ccw"),a.setAttr("aria-label","Unlock and restore (needs the password)"),a.onclick=async()=>{a.disabled=!0;let A=t.blob.split("/"),h=A.lastIndexOf("archive"),p=h>0?A.slice(0,h).join("/"):void 0;await this.plugin.unlockBundleAt(t.blob,p?{destFolder:p}:{})?this.render():a.disabled=!1};let l=i.createEl("button",{cls:"stashpad-trash-iconbtn",text:"Export"});l.setAttr("aria-label","Export to .stash (encrypted with a password you choose)"),l.onclick=()=>void this.plugin.exportLockedSubtree(t.blob);let c=i.createSpan({cls:"stashpad-aggregate-lockbadge"});(0,ae.setIcon)(c,"lock"),this.attachLockedRowMenu(i,t,{archived:!0})}attachLockedRowMenu(e,t,i){let s=()=>{let o=new ae.Menu;return xn(o,{app:this.app,plugin:this.plugin,descriptor:{blob:t.blob,rootId:t.rootId,count:t.count??1,folder:this.cleanFolder(t.folder)},unlockLabel:i.archived?"Unlock & restore":"Decrypt (unlock)",onUnlock:async()=>{let a;if(i.archived){let c=t.blob.split("/"),A=c.lastIndexOf("archive");a=A>0?c.slice(0,A).join("/"):void 0}await this.plugin.unlockBundleAt(t.blob,a?{destFolder:a}:{})&&this.render()},onChange:()=>void this.render(),fullParity:!1,confirmDelete:!1}),o};e.oncontextmenu=o=>{o.preventDefault(),s().showAtMouseEvent(o)};let n=e.createEl("button",{cls:"stashpad-trash-iconbtn stashpad-agg-more"});(0,ae.setIcon)(n,"ellipsis-vertical"),n.setAttr("aria-label","More actions"),n.onclick=o=>{o.stopPropagation(),s().showAtMouseEvent(o)}}renderWatch(e){this.plugin.pruneReEncryptWatch()&&this.plugin.saveSettings();let t=this.plugin.settings.reEncryptWatch??[],i=t.filter(g=>!g.removed),s=t.filter(g=>g.removed);if(t.length===0){e.createDiv({cls:"stashpad-trash-empty",text:"Nothing here yet. When you unlock an encrypted note (or restore one from the trash), it shows up here so you can re-encrypt it later."});return}let n=e.createDiv({cls:"stashpad-trash-modes"}),o=n.createEl("select",{cls:"dropdown"});o.createEl("option",{value:"",text:"All folders"});for(let g of[...new Set(i.map(I=>I.folder))].sort())o.createEl("option",{value:g,text:g});o.value=this.watchFolderFilter,o.onchange=()=>{this.watchFolderFilter=o.value,this.render()};let a=n.createEl("select",{cls:"dropdown"});a.createEl("option",{value:"",text:"Unlocked + restored"}),a.createEl("option",{value:"unlock",text:"Unlocked"}),a.createEl("option",{value:"restore",text:"Restored from trash"}),a.value=this.watchViaFilter,a.onchange=()=>{this.watchViaFilter=a.value,this.render()};let l=n.createEl("input",{type:"text",attr:{placeholder:"Search\u2026"}});l.value=this.watchQuery,l.oninput=()=>{this.watchQuery=l.value,u()};let c=(g,I)=>g.toLowerCase().split(/\s+/).filter(Boolean).every(m=>I.toLowerCase().includes(m)),A=g=>(!this.watchFolderFilter||g.folder===this.watchFolderFilter)&&(!this.watchViaFilter||g.via===this.watchViaFilter)&&(!this.watchQuery.trim()||c(this.watchQuery,`${g.title} ${g.folder}`)),h=async()=>{await this.plugin.saveSettings(),this.render()},p=(g,I,m)=>{let C=g.createDiv({cls:"stashpad-trash-row"}),B=C.createDiv({cls:"stashpad-trash-row-main"});B.createSpan({cls:"stashpad-trash-title",text:this.plugin.reEncryptDisplayTitle(I)});let E=Mn(I.unlockedAt).fromNow(),y=I.count>1?` \xB7 ${I.count} notes`:"";if(B.createSpan({cls:"stashpad-trash-sub",text:`${I.via==="restore"?"restored":"unlocked"} ${E} \xB7 ${I.folder.split("/").pop()||I.folder}${y}`}),m){let v=C.createEl("button",{cls:"stashpad-trash-iconbtn",text:"Un-remove"});v.onclick=()=>{delete I.removed,delete I.removedAt,h()}}else{let v=C.createEl("button",{cls:"stashpad-trash-restore",text:"Re-encrypt"});(0,ae.setIcon)(v.createSpan({cls:"stashpad-btn-icon"}),"lock"),v.onclick=async()=>{v.disabled=!0,await this.plugin.lockNoteSubtree(I.folder,I.rootId,null,{})||(v.disabled=!1),this.render()};let Q=C.createEl("input",{type:"number",cls:"stashpad-watch-peek",attr:{placeholder:"auto",title:"Auto re-encrypt after N idle minutes (blank = folder/global default, 0 = off)",min:"0"}});Q.value=I.peekMin==null?"":String(I.peekMin),Q.onchange=()=>{let F=Q.value.trim(),D=Number(F);if(F==="")delete I.peekMin;else if(Number.isFinite(D)&&D>=0)I.peekMin=Math.floor(D);else{Q.value=I.peekMin==null?"":String(I.peekMin);return}this.plugin.saveSettings()};let w=C.createEl("button",{cls:"stashpad-trash-iconbtn"});(0,ae.setIcon)(w,"x"),w.setAttr("aria-label","Remove from watchlist (recoverable below)"),w.onclick=()=>{I.removed=!0,I.removedAt=new Date().toISOString(),h()}}},f=e.createDiv(),u=()=>{f.empty();let g=i.filter(A).sort((C,B)=>(B.unlockedAt||"").localeCompare(C.unlockedAt||"")),I=f.createDiv({cls:"stashpad-trash-group-head"});if((0,ae.setIcon)(I.createSpan({cls:"stashpad-trash-group-icon"}),"history"),I.createSpan({text:"Watching"}),I.createSpan({cls:"stashpad-trash-group-count",text:String(g.length)}),i.length>0){let C=I.createEl("button",{cls:"stashpad-trash-iconbtn",text:"Re-encrypt all applicable"});C.onclick=()=>void this.plugin.encryptEverythingApplicable()}g.length===0&&f.createDiv({cls:"stashpad-trash-sub",text:i.length?"No matches for the current filters.":"Nothing being watched."});let m=f.createDiv({cls:"stashpad-trash-group"});for(let C of g)p(m,C,!1);if(s.length>0){let C=f.createEl("details",{cls:"stashpad-watch-removed"});C.createEl("summary",{text:`Removed from watchlist (${s.length})`});let B=C.createDiv({cls:"stashpad-trash-group"});for(let E of s.filter(A))p(B,E,!0)}};u()}async onClose(){this.contentEl.empty()}};async function He(d,r){let{workspace:e}=d.app,t=e.getLeavesOfType(ci).find(n=>n.getViewState()?.state?.mode===r);if(t){e.revealLeaf(t);return}let i=e.getMostRecentLeaf(),s=e.getLeaf("tab");await s.setViewState({type:ci,active:!0,state:{mode:r}}),e.revealLeaf(s),yt(e,s,i,n=>d.registerEvent(n))}var ti=require("obsidian");ve();var Oe=class Oe{constructor(r){this.host=r;this.knownBodies=new Map;this.contribTimers=new Map;this.recentSelfWrites=new Map;this.lastExternalModify=new Map}dispose(){for(let r of this.contribTimers.values())clearTimeout(r);this.contribTimers.clear(),this.knownBodies.clear(),this.recentSelfWrites.clear(),this.lastExternalModify.clear()}currentAuthorLink(){let r=(this.host.plugin.settings.authorName??"").trim(),e=(this.host.plugin.settings.authorId??"").trim();if(!r||!e)return null;let t=r.replace(/[^\w\- ]+/g,"").trim().replace(/\s+/g,"-")||"author",i=`${this.host.noteFolder}/_authors/${t}-${e}.md`,s=r.replace(/[\[\]|]/g,"").trim()||t;return{link:`[[${i}|${s}]]`,path:i,name:r,id:e}}claimSelectedAsAuthor(){this.claimAuthorship({scope:"selection",contributorMode:!1})}claimFolderAsAuthor(){this.claimAuthorship({scope:"folder",contributorMode:!1})}claimSelectedWithContributor(){this.claimAuthorship({scope:"selection",contributorMode:!0})}claimFolderWithContributor(){this.claimAuthorship({scope:"folder",contributorMode:!0})}fileBackedNotesInFolder(){let r=this.host.noteFolder.replace(/\/+$/,"");return this.host.app.vault.getMarkdownFiles().filter(e=>{let t=e.parent?.path?.replace(/\/+$/,"")??"";if(t!==r&&!t.startsWith(r+"/")||e.path.includes("/_authors/"))return!1;let i=this.host.app.metadataCache.getFileCache(e)?.frontmatter;return typeof i?.id=="string"&&!!i.id})}async pacedFrontmatter(r,e){for(let s=0;s<r.length;s++){let n=this.host.app.vault.getAbstractFileByPath(r[s]);if(n instanceof ti.TFile){this.recentSelfWrites.set(n.path,Date.now());try{await this.host.app.fileManager.processFrontMatter(n,o=>e(o,r[s]))}catch(o){console.warn("[Stashpad] claim: frontmatter write failed",r[s],o)}}(s+1)%25===0&&await new Promise(o=>setTimeout(o,30))}}async claimAuthorship(r){let e=this.currentAuthorLink();if(!e){new ti.Notice("Set your author name in Stashpad settings first.");return}let t=`-${e.id}`,i=r.scope==="selection"?this.host.getActionTargets().map(p=>p.file).filter(p=>!!p):this.fileBackedNotesInFolder();if(i.length===0){new ti.Notice(r.scope==="selection"?"No notes selected.":"No notes in this folder.");return}let s=[],n=[];for(let p of i){let f=this.host.app.metadataCache.getFileCache(p)?.frontmatter,u=typeof f?.author=="string"?f.author:"";if(!u.trim()){s.push(p.path);continue}if(u.includes(t)||!r.contributorMode)continue;(Array.isArray(f?.contributors)?f.contributors.filter(I=>typeof I=="string"):[]).some(I=>I.includes(t))||n.push(p.path)}let o=s.length+n.length;if(o===0){new ti.Notice("Nothing to claim \u2014 those notes are already authored by you.");return}if(r.scope==="folder"){let p=[`Stamp yourself as author on ${s.length} unauthored note(s)`];if(n.length&&p.push(`and as a contributor on ${n.length} already-authored note(s)`),!await new Promise(u=>{new j(this.host.app,"Claim authorship",`${p.join(" ")}? -Existing authors are never overwritten. This can be undone.`,"Claim",u).open()}))return}let a=this.host.noteFolder,l=e.link,c=new Set,A=async()=>{await this.pacedFrontmatter(s,(p,f)=>{typeof p.author=="string"&&p.author.trim()||(p.author=l),Array.isArray(p.contributors)&&p.contributors.some(u=>typeof u=="string"&&u.includes(t))&&(p.contributors=p.contributors.filter(u=>!(typeof u=="string"&&u.includes(t))),c.add(f))}),await this.pacedFrontmatter(n,p=>{let f=Array.isArray(p.contributors)?p.contributors.filter(u=>typeof u=="string"):[];f.some(u=>u.includes(t))||f.push(l),p.contributors=f})};this.ensureAuthorFile(e),await A(),this.host.plugin.getUndoStack(a).push({label:`Claim authorship (${o} note${o===1?"":"s"})`,undo:async()=>{await this.pacedFrontmatter(s,(p,f)=>{if(typeof p.author=="string"&&p.author.includes(t)&&delete p.author,c.has(f)){let u=Array.isArray(p.contributors)?p.contributors.filter(g=>typeof g=="string"):[];u.some(g=>g.includes(t))||u.push(l),p.contributors=u}}),await this.pacedFrontmatter(n,p=>{Array.isArray(p.contributors)&&(p.contributors=p.contributors.filter(f=>!(typeof f=="string"&&f.includes(t))))}),this.host.debouncedRender()},redo:async()=>{c.clear(),await A(),this.host.debouncedRender()}});let h=[];s.length&&h.push(`authored ${s.length}`),n.length&&h.push(`contributing to ${n.length}`),new ti.Notice(`Claimed authorship: ${h.join(", ")}. Undo available.`),this.host.debouncedRender()}async ensureAuthorFile(r){try{r.id&&this.host.plugin.authorRegistry.record({id:r.id,name:r.name});let e=`${this.host.noteFolder}/_authors`;if(await this.host.ensureFolder(e),await this.host.app.vault.adapter.exists(r.path))return;let t=r.id===(this.host.plugin.settings.authorId??"").trim(),i=this.host.plugin.buildAuthorStub({id:r.id,name:r.name,role:t?this.host.plugin.settings.authorRole:void 0,department:t?this.host.plugin.settings.authorDepartment:void 0},new Date().toISOString());await this.host.app.vault.create(r.path,i)}catch(e){console.warn("[Stashpad] ensureAuthorFile failed",e)}}collectAuthorIds(r){let e=new Set,t=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 r){if(!i.file)continue;let s=this.host.app.metadataCache.getFileCache(i.file)?.frontmatter;if(!s)continue;let n=t(s.author);if(n&&e.add(n),Array.isArray(s.contributors))for(let o of s.contributors){let a=t(o);a&&e.add(a)}}return Array.from(e)}pruneContribMaps(){let r=Date.now(),e=Oe.EXTERNAL_WRITE_GRACE_MS*20,t=Oe.EXTERNAL_QUIESCENCE_MS*12;for(let[i,s]of this.recentSelfWrites)r-s>e&&this.recentSelfWrites.delete(i);for(let[i,s]of this.lastExternalModify)r-s>t&&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(r){let e=Date.now(),t=this.recentSelfWrites.get(r.path);t!==void 0&&e-t<Oe.EXTERNAL_WRITE_GRACE_MS||this.lastExternalModify.set(r.path,e),this.scheduleContribution(r)}scheduleContribution(r){let e=this.contribTimers.get(r.path);e&&clearTimeout(e);let t=this.isFileActivelyEdited(r),i=Oe.CONTRIB_DEBOUNCE_MS+(t?Oe.CONTRIB_ACTIVE_EDITOR_BONUS_MS:0),s=setTimeout(()=>{if(this.contribTimers.delete(r.path),this.isFileActivelyEdited(r)){this.scheduleContribution(r);return}let n=this.lastExternalModify.get(r.path);if(n!==void 0&&Date.now()-n<Oe.EXTERNAL_QUIESCENCE_MS){this.scheduleContribution(r);return}this.maybeRecordContribution(r)},i);this.contribTimers.set(r.path,s)}isFileActivelyEdited(r){try{let e=this.host.app.workspace.activeLeaf;if(!e)return!1;let t=e.view;if(!t||t.getViewType?.()!=="markdown"||t.file?.path!==r.path)return!1;let i=t.containerEl??null;return!!i&&i.contains(document.activeElement)}catch{return!1}}async maybeRecordContribution(r){let e="";try{e=await this.host.app.vault.cachedRead(r)}catch{return}let t=this.host.stripFrontmatter(e),i=this.knownBodies.get(r.path);if(this.knownBodies.set(r.path,t),i===void 0||i===t||this.host.plugin.rebootstrapInProgress)return;let s=this.currentAuthorLink();if(!s)return;this.ensureAuthorFile(s);let n=new Date().toISOString();this.recentSelfWrites.set(r.path,Date.now());try{await this.host.app.fileManager.processFrontMatter(r,o=>{o.modified=n;let a=typeof o.author=="string"?o.author:"",l=Array.isArray(o.contributors)?o.contributors.filter(p=>typeof p=="string"):[],c=`-${s.id}`,A=a.includes(c),h=l.some(p=>p.includes(c));!A&&!h&&l.push(s.link),o.contributors=l})}catch(o){console.warn("[Stashpad] maybeRecordContribution failed",o)}}};Oe.CONTRIB_DEBOUNCE_MS=4e3,Oe.CONTRIB_ACTIVE_EDITOR_BONUS_MS=2e3,Oe.EXTERNAL_WRITE_GRACE_MS=1500,Oe.EXTERNAL_QUIESCENCE_MS=5e3;var Hn=Oe;var Rn=class{constructor(r){this.host=r;this.dragSourceIds=null;this.dragPlaceholder=null;this.dragRowHeight=0}attachRowDnD(r,e,t){r.addEventListener("dragstart",i=>{let s=this.host.selection.has(e.id)&&this.host.selection.size>1?[...this.host.selection]:[e.id];if(this.dragSourceIds=s,this.dragRowHeight=r.offsetHeight,r.addClass("is-dragging"),this.host.listEl&&(this.dragPlaceholder=this.host.listEl.createDiv({cls:"stashpad-drop-placeholder"}),this.dragPlaceholder.setCssStyles({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,l=this.dragPlaceholder.previousElementSibling;this.removeDragPlaceholder();let c,A="before";a&&a.classList.contains("stashpad-note")?(c=a.dataset.id,A="before"):l&&l.classList.contains("stashpad-note")&&(c=l.dataset.id,A="after"),c&&this.host.reorderToTarget(o,c,A)}),this.dragPlaceholder.remove()),i.dataTransfer?.setData("text/plain",s.join(",")),i.dataTransfer){i.dataTransfer.effectAllowed="move";try{i.dataTransfer.setDragImage(r,12,12)}catch{}}}),r.addEventListener("dragend",()=>{r.removeClass("is-dragging"),this.clearDropIndicators(),this.removeDragPlaceholder(),this.dragSourceIds=null}),r.addEventListener("dragover",i=>{if(!this.dragSourceIds)return;i.preventDefault(),i.dataTransfer&&(i.dataTransfer.dropEffect="move");let s=this.dropZone(i,r);this.clearDropIndicators(),s==="drop-into"?(this.removeDragPlaceholder(),r.addClass("drop-into")):(r.removeClass("drop-into"),this.placePlaceholder(r,s==="drop-above"?"before":"after"))}),r.addEventListener("dragleave",i=>{let s=r.getBoundingClientRect();(i.clientX<s.left||i.clientX>s.right||i.clientY<s.top||i.clientY>s.bottom)&&r.removeClass("drop-into")}),r.addEventListener("drop",i=>{if(!this.dragSourceIds)return;i.preventDefault(),i.stopPropagation();let s=this.dragSourceIds.slice();this.dragSourceIds=null;let n=this.dropZone(i,r);this.clearDropIndicators(),this.removeDragPlaceholder(),r.removeClass("is-dragging"),n==="drop-into"?this.host.reorderToTarget(s,e.id,"into"):this.host.reorderToTarget(s,e.id,n==="drop-above"?"before":"after")})}attachListDnD(r){r.addEventListener("dragover",e=>{if(!this.dragSourceIds)return;let t=e.target;if(t&&t.closest&&t.closest(".stashpad-note"))return;e.preventDefault(),e.dataTransfer&&(e.dataTransfer.dropEffect="move");let i=Array.from(r.querySelectorAll(".stashpad-note"));if(i.length!==0){for(let s of i){let n=s.getBoundingClientRect();if(e.clientY<n.top+n.height/2){this.placePlaceholder(s,"before");return}}this.placePlaceholder(i[i.length-1],"after")}}),r.addEventListener("drop",e=>{if(!this.dragSourceIds)return;e.preventDefault();let t=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(t,n,"before")}else if(s&&s.classList.contains("stashpad-note")){let n=s.dataset.id;n&&this.host.reorderToTarget(t,n,"after")}})}placePlaceholder(r,e){if(!this.dragPlaceholder||!this.host.listEl)return;let t=e==="before"?r:r.nextSibling;if(e==="before"&&this.dragPlaceholder.nextSibling===r||e==="after"&&this.dragPlaceholder.previousSibling===r)return;let i=!!this.dragPlaceholder.parentElement;this.host.listEl.insertBefore(this.dragPlaceholder,t),this.dragPlaceholder.setCssStyles({opacity:"1"}),i?this.dragPlaceholder.setCssStyles({height:`${this.dragRowHeight}px`}):(this.dragPlaceholder.setCssStyles({height:"0px"}),this.dragPlaceholder.offsetHeight,this.dragPlaceholder.setCssStyles({height:`${this.dragRowHeight}px`}))}removeDragPlaceholder(){if(!this.dragPlaceholder?.parentElement)return;let r=this.dragPlaceholder;r.setCssStyles({height:"0px",opacity:"0"}),setTimeout(()=>{r.parentElement&&r.remove()},150)}dropZone(r,e){let t=e.getBoundingClientRect(),i=r.clientY-t.top;return i<t.height*.3?"drop-above":i>t.height*.7?"drop-below":"drop-into"}clearDropIndicators(){if(this.host.listEl)for(let r of Array.from(this.host.listEl.querySelectorAll(".drop-into")))r.removeClass("drop-into")}};var ra=require("obsidian");var Un=class{constructor(r,e,t){this.host=r;this.component=e;this.bodyObserver=null;this.lazyBodies=new WeakMap;this.renderCache=t??new Map}async getOrComputeRender(r){let e=this.renderCache.get(r.path);if(e&&e.mtime===r.stat.mtime)return Te.record("render.row.cacheHit",0),e;let t=await Te.timeAsync("render.row.read",()=>this.host.app.vault.cachedRead(r)),i=this.host.stripFrontmatter(t),{text:s,attachments:n}=this.splitAttachments(i),o=createDiv({cls:"stashpad-note-text"});await Te.timeAsync("render.row.markdown",()=>ra.MarkdownRenderer.render(this.host.app,s,o,r.path,this.component));let a=o.innerHTML,l={mtime:r.stat.mtime,text:s,attachments:n,html:a};return this.renderCache.set(r.path,l),l}async primeRender(r,e){try{let{text:t,attachments:i}=this.splitAttachments(this.host.stripFrontmatter(e)),s=createDiv({cls:"stashpad-note-text"});await ra.MarkdownRenderer.render(this.host.app,t,s,r.path,this.component);let n={mtime:r.stat.mtime,text:t,attachments:i,html:s.innerHTML};this.renderCache.set(r.path,n)}catch(t){console.warn("[Stashpad] primeRender failed",t)}}arm(){this.bodyObserver?.disconnect(),this.lazyBodies=new WeakMap,this.bodyObserver=new IntersectionObserver(r=>{for(let e of r){if(!e.isIntersecting)continue;let t=e.target,i=this.lazyBodies.get(t);this.bodyObserver?.unobserve(t),this.lazyBodies.delete(t),i&&i()}},{root:this.host.contentEl,rootMargin:"1400px 0px"})}dispose(){this.bodyObserver?.disconnect(),this.bodyObserver=null}isArmed(){return!!this.bodyObserver}hasFreshRenderCache(r){let e=this.renderCache.get(r.path);return!!e&&e.mtime===r.stat.mtime}peekCache(r){return this.renderCache.get(r.path)}evict(r){let e=this.renderCache;e.evict?e.evict(r.path):e.delete&&e.delete(r.path)}retagMtime(r,e){let t=this.renderCache.get(r);t&&t.mtime!==e&&this.renderCache.set(r,{...t,mtime:e})}defer(r,e){this.lazyBodies.set(r,e),this.bodyObserver?.observe(r)}splitAttachments(r){let e=[];return{text:r.replace(/!\[\[([^\]\|]+)(?:\|[^\]]+)?\]\]/g,(i,s)=>(e.push(s),"")).replace(/\n{3,}/g,` +`)}renderSuggestion(e,t){if(t.addClass("stashpad-suggest-item"),e.kind==="create"){t.createDiv({cls:"stashpad-suggest-create",text:e.label});return}if(e.kind==="folder-open"){t.addClass("is-folder-open"),t.createDiv({cls:"stashpad-suggest-title",text:e.label}),e.folder?t.createDiv({cls:"stashpad-suggest-preview",text:e.folder}):t.createDiv({cls:"stashpad-suggest-preview",text:"Click to choose a folder\u2026"});return}if(e.kind==="search-excluded"){t.addClass("is-search-excluded");let f=t.createDiv({cls:"stashpad-suggest-title stashpad-search-excluded-row"}),u=f.createSpan({cls:"stashpad-search-excluded-icon"});(0,Ie.setIcon)(u,"folder-search"),f.createSpan({text:e.label}),t.createDiv({cls:"stashpad-suggest-preview",text:"Include folders you've excluded from search (e.g. to move a note there)."});return}if(e.locked){t.addClass("stashpad-suggest-row","is-locked");let f=t.createDiv({cls:"stashpad-suggest-body"}),u=f.createDiv({cls:"stashpad-suggest-title stashpad-suggest-locked"});(0,Ie.setIcon)(u.createSpan({cls:"stashpad-suggest-locked-icon"}),"lock");let g=ra(this.inputEl?.value??"").text;this.highlightInto(u.createSpan(),e.label,g),f.createDiv({cls:"stashpad-suggest-preview",text:e.locked.count>1?`${e.locked.count} notes \xB7 locked`:"Encrypted \u2014 locked"});return}e.crossFolder&&t.addClass("is-cross-folder"),t.addClass("stashpad-suggest-row");let i=t.createDiv({cls:"stashpad-suggest-body"}),s=this.notes.find(f=>e.crossFolder?f.cross?.folder===e.crossFolder&&f.cross?.id===e.crossId:f.node?.id===e.id),n=ra(this.inputEl?.value??"").text,o=this.firstLineOfBody(s?.body??"")||e.label.trim(),a=i.createDiv({cls:"stashpad-suggest-title"});this.highlightInto(a,o,n);let l=e.crossFolder??this.opts.localFolder??null;if(e.bodyPreview&&e.matchLine!=null&&e.matchLine>=0){let f=i.createDiv({cls:"stashpad-suggest-preview stashpad-suggest-snippet"});this.highlightInto(f,e.bodyPreview,n)}let c="";if(e.crossFolder?c=s?.cross?.parentBlurb??"":c=this.parentBlurbFor(e.node),c){let f=i.createDiv({cls:"stashpad-suggest-preview"});f.appendText("Parent: "),this.highlightInto(f,c,n)}let d=e.crossFolder?this.buildCrossBreadcrumb(e):this.buildLocalBreadcrumb(e.node),h=e.crossFolder??this.opts.localFolder??null;if(h||d){let f=i.createDiv({cls:"stashpad-suggest-breadcrumb"}),g=[h?h.split("/").pop()||h:"",d].filter(I=>I&&I.length>0).join(" \u203A ");g&&f.setText(g)}let p=s?this.createdMsFor(s):null;if(p!=null||l){let f=t.createDiv({cls:"stashpad-suggest-rail"});if(p!=null){let u=f.createDiv({cls:"stashpad-suggest-time"});u.setText(this.formatRelativeTime(p)),u.title=ye(p).format("YYYY-MM-DD HH:mm")}l&&f.createDiv({cls:"stashpad-suggest-folder-badge",text:l.split("/").pop()||l})}}formatRelativeTime(e){let t=ye(e),i=ye().startOf("day").diff(ye(e).startOf("day"),"days");return i===0?t.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?t.format("MMM D"):t.format("MMM D, YYYY")}highlightInto(e,t,i){if(!t)return;let s=i.filter(c=>c&&c.length>0);if(!s.length){e.appendText(t);return}let n=t.toLowerCase(),o=[];for(let c of s){let d=0;for(;(d=n.indexOf(c,d))!==-1;)o.push([d,d+c.length]),d+=1}if(!o.length){e.appendText(t);return}o.sort((c,d)=>c[0]-d[0]);let a=[];for(let c of o){let d=a[a.length-1];d&&c[0]<=d[1]?d[1]=Math.max(d[1],c[1]):a.push([c[0],c[1]])}let l=0;for(let[c,d]of a)c>l&&e.appendText(t.slice(l,c)),e.createSpan({cls:"stashpad-suggest-match",text:t.slice(c,d)}),l=d;l<t.length&&e.appendText(t.slice(l))}buildLocalBreadcrumb(e){if(!e||!e.parent||e.parent===S)return"";let t=[],i=new Set([e.id]),s=this.tree.get(e.parent);for(;s&&s.id!==S&&!i.has(s.id);)i.add(s.id),t.unshift(this.titleFn(s)),s=s.parent&&s.parent!==S?this.tree.get(s.parent):void 0;return t.join(" \u203A ")}buildCrossBreadcrumb(e){if(!e.crossFolder)return"";if(!this.crossFolderIndex){this.crossFolderIndex=new Map;for(let l of this.notes){if(!l.cross)continue;let c=this.crossFolderIndex.get(l.cross.folder);c||(c=new Map,this.crossFolderIndex.set(l.cross.folder,c)),c.set(l.cross.id,l.cross)}}let t=this.crossFolderIndex.get(e.crossFolder);if(!t)return"";let i=e.crossId??e.id.replace(/^cross:/,""),s=t.get(i);if(!s)return"";let n=[],o=new Set([s.id]),a=s.parentId?t.get(s.parentId):null;for(;a&&!o.has(a.id);)o.add(a.id),n.unshift(a.title),a=a.parentId?t.get(a.parentId):null;return n.join(" \u203A ")}firstLineOfBody(e){if(!e)return"";let t=e.split(/\r?\n/);for(let i of t){let s=i.trim();if(s)return s}return""}parentBlurbFor(e){if(!e||!e.parent||e.parent===S)return"";let t=this.tree.get(e.parent);if(!t||!t.file)return"";let i=this.notes.find(s=>s.node?.id===t.id);return i?this.firstLineOfBody(i.body):""}onOpen(){if(super.onOpen(),this.opts.showFilterChips&&!Ie.Platform.isMobile){let e=this.inputEl,t=this.resultContainerEl;if(!e||!t)return;this.mountFilterChipRow(e,t);return}if(Ie.Platform.isMobile){let e=this.inputEl;e&&e.focus()}}mountFilterChipRow(e,t){e.addEventListener("keydown",c=>{if(c.key==="["){c.preventDefault();let d=e.selectionStart??e.value.length,h=e.selectionEnd??d,p=e.value.slice(0,d),f=e.value.slice(d,h),u=e.value.slice(h);e.value=`${p}[${f}]${u}`;let g=d+1+f.length;e.setSelectionRange(g,g),e.dispatchEvent(new Event("input",{bubbles:!0}));return}if(c.key==="]"){let d=e.selectionStart??-1;d>=0&&e.value[d]==="]"&&(c.preventDefault(),e.setSelectionRange(d+1,d+1));return}if(c.key==="Backspace"&&!c.metaKey&&!c.ctrlKey&&!c.altKey&&e.selectionStart===e.selectionEnd){let d=e.selectionStart??-1;if(d>0&&e.value[d-1]==="["&&e.value[d]==="]"){c.preventDefault();let h=e.value.slice(0,d-1),p=e.value.slice(d+1);e.value=`${h}${p}`,e.setSelectionRange(d-1,d-1),e.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(e,"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(e,i)}),o.addEventListener("keydown",c=>{(c.key==="Enter"||c.key===" ")&&(c.preventDefault(),c.stopPropagation(),o.click())}),i.appendChild(o),t.parentElement?.insertBefore(i,t);let a=new Ie.Scope(this.scope),l=c=>{let d=document.activeElement;return d?.classList?.contains("stashpad-search-filter-chip")?(c.preventDefault(),d.click(),!1):c.key==="Enter"&&!c.isComposing?(c.preventDefault(),this.selectActiveSuggestion?.(c),!1):!0};a.register([],"Enter",l),a.register([]," ",l),a.register(["Mod"],"f",c=>{c.preventDefault();let d=this.inputEl;return d&&(d.focus(),d.select()),!1}),a.register([],"Tab",c=>{let d=this.modalEl,h=this.inputEl;if(!d)return!0;let p=Array.from(d.querySelectorAll('input, button, select, textarea, a[href], [tabindex]:not([tabindex="-1"])')).filter(g=>!g.hasAttribute("disabled")&&g.tabIndex!==-1&&g.offsetParent!==null);if(p.length===0)return!0;let f=document.activeElement,u=f?p.indexOf(f):-1;if(c.shiftKey){if(u<=0)return c.preventDefault(),p[p.length-1].focus(),!1}else if(u===p.length-1)return c.preventDefault(),(h??p[0]).focus(),!1;return!0}),this.app.keymap?.pushScope(a),this.pendingCleanups.push(()=>{try{this.app.keymap?.popScope(a)}catch{}})}appendFilterToInput(e,t,i){let s=e.value,o=`${s.length>0&&!/\s$/.test(s)?" ":""}${t}: [`,a="]",l=i;e.value=`${s}${o}${l}${a}`;let c=s.length+o.length+l.length;if(e.setSelectionRange(c,c+0),!l){let d=s.length+o.length;e.setSelectionRange(d,d)}e.focus(),e.dispatchEvent(new Event("input",{bubbles:!0}))}toggleWhenBuilder(e,t){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 g of o){let I=document.createElement("button");I.type="button",I.className="stashpad-when-tab",I.textContent=g.label,this.whenMode===g.id&&I.addClass("is-active"),I.addEventListener("mousedown",m=>m.preventDefault()),I.addEventListener("click",m=>{if(m.preventDefault(),this.whenMode===g.id)return;let C=this.whenMode;C!=="between"&&g.id==="between"?this.whenBetweenEndText="":C==="between"&&g.id!=="between"&&(!this.whenSingleText&&this.whenBetweenEndText&&(this.whenSingleText=this.whenBetweenEndText),this.whenBetweenEndText=""),this.whenMode=g.id;for(let B in a)a[B].toggleClass("is-active",B===g.id);u()}),a[g.id]=I,n.appendChild(I)}s.appendChild(n);let l=document.createElement("div");l.className="stashpad-when-body",s.appendChild(l);let c=(g,I,m="single")=>{let C=ye().format("YYYY-MM-DD"),B=!I||I===C;if(m==="betweenStart")return"00:00";if(m==="betweenEnd")return"23:59";switch(g){case"after":return"00:00";case"on":return B?ye().format("HH:mm"):"23:59";case"before":return B?ye().format("HH:mm"):"23:59";default:return"23:59"}},d=(g,I)=>{g.addEventListener("keydown",m=>{m.key==="Enter"?(m.preventDefault(),m.stopPropagation(),I()):m.key==="Escape"&&(m.preventDefault(),m.stopPropagation(),this.closeWhenBuilder())})},h=(g,I)=>{let m=g.selectionStart??g.value.length,C=g.selectionEnd??g.value.length,E=`${m>0&&!/\s$/.test(g.value.slice(0,m))?" ":""}${I}`,y=g.value.slice(0,m)+E+g.value.slice(C);g.value=y;let v=m+E.length;g.setSelectionRange(v,v),g.focus(),g.dispatchEvent(new Event("input",{bubbles:!0}))},p=(g,I)=>{let C=g.slice(0,I).match(/(\d{4}-\d{2}-\d{2})(?!.*\d{4}-\d{2}-\d{2})/);return C?C[1]:null},f=(g,I,m,C)=>{let B=l.createDiv({cls:"stashpad-when-input-wrap has-icons"}),E=B.createDiv({cls:"stashpad-when-icon-slot"}),y=E.createEl("button",{cls:"stashpad-when-icon stashpad-when-icon-cal"});y.type="button",y.title="Pick date",(0,Ie.setIcon)(y,"calendar-days");let v=E.createEl("input",{cls:"stashpad-when-native",attr:{type:"date"}});v.tabIndex=-1;let Q=B.createDiv({cls:"stashpad-when-icon-slot"}),w=Q.createEl("button",{cls:"stashpad-when-icon stashpad-when-icon-clock"});w.type="button",w.title="Pick time",(0,Ie.setIcon)(w,"clock");let k=B.createDiv({cls:"stashpad-when-icon-slot"}),D=k.createEl("button",{cls:"stashpad-when-icon stashpad-when-icon-day"});D.type="button",D.title="Pick day",(0,Ie.setIcon)(D,"calendar");let H=B.createDiv({cls:"stashpad-when-icon-slot"}),R=H.createEl("button",{cls:"stashpad-when-icon stashpad-when-icon-tf"});R.type="button",R.title="Pick timeframe",(0,Ie.setIcon)(R,"history");let L=B.createEl("input",{cls:"stashpad-when-input",attr:{type:"text",placeholder:g}});L.value=I(),L.addEventListener("input",()=>m(L.value));let x=B.createEl("button",{cls:"stashpad-when-clear"});x.type="button",x.textContent="\xD7",x.title="Clear";for(let O of[y,w,D,R,x])O.addEventListener("mousedown",K=>K.preventDefault());let U=null,T=(O,K)=>{U&&U();let Y=O.createDiv({cls:"stashpad-when-popover"}),Z=O.ownerDocument??document,V=new Ie.Scope(this.scope),q=null,ee=te=>{q=te},ue=!1,oe=te=>{!Y.contains(te.target)&&te.target!==O&&!O.contains(te.target)&&ie()},ie=()=>{if(!ue){ue=!0,Y.remove(),Z.removeEventListener("mousedown",oe,!0);try{this.app.keymap?.popScope(V)}catch{}U===ie&&(U=null)}};U=ie,V.register([],"Escape",te=>(te.preventDefault(),ie(),!1)),V.register([],"Enter",te=>(te.preventDefault(),q&&q(),!1));try{K(Y,ie,ee)}catch(te){console.error("[stashpad] popover fill threw:",te),Y.remove(),U=null;return}this.app.keymap?.pushScope(V),this.pendingCleanups.push(ie),setTimeout(()=>Z.addEventListener("mousedown",oe,!0),0)};R.addEventListener("click",O=>{O.preventDefault(),T(H,(K,Y,Z)=>{let V=this.whenMode==="on",q=(se,Ae)=>{if(!V)return`${se}${Ae}`;let Xe={d:"days",w:"weeks",m:"months",y:"years"}[Ae];return ye().subtract(se,Xe).format("YYYY-MM-DD")},ee=K.createDiv({cls:"stashpad-when-pop-row"}),ue=[{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 se of ue){let Ae=ee.createEl("button",{cls:"stashpad-when-pop-chip",text:se.label});Ae.type="button",Ae.addEventListener("mousedown",Xe=>Xe.preventDefault()),Ae.addEventListener("click",Xe=>{Xe.preventDefault(),h(L,q(se.n,se.unit)),Y()})}let oe=K.createDiv({cls:"stashpad-when-pop-row stashpad-when-pop-builder"});oe.createSpan({text:"Last",cls:"stashpad-when-pop-label"});let ie=oe.createEl("input",{cls:"stashpad-when-pop-number",attr:{type:"number",min:"1",max:"999",value:"7"}}),te=oe.createEl("select",{cls:"stashpad-when-pop-unit"});for(let se of[{v:"d",label:"days"},{v:"w",label:"weeks"},{v:"m",label:"months"},{v:"y",label:"years"}]){let Ae=te.createEl("option",{text:se.label});Ae.value=se.v}let fe=oe.createEl("button",{cls:"stashpad-when-pop-chip stashpad-when-pop-go",text:"Insert"});fe.type="button";let we=()=>{let se=parseInt(ie.value,10);!Number.isFinite(se)||se<1||(h(L,q(se,te.value)),Y())};fe.addEventListener("mousedown",se=>se.preventDefault()),fe.addEventListener("click",se=>{se.preventDefault(),we()}),Z(we),ie.focus(),ie.select()})});let b=(O,K,Y,Z,V)=>{T(K,(q,ee,ue)=>{zs(q,{seedH:Y,seedM:Z,seedPeriod:V,close:ee,setOnEnter:ue,onFinalize:oe=>h(O,rr(oe))})})};D.addEventListener("click",O=>{O.preventDefault(),T(k,(K,Y,Z)=>{let V=K.createDiv({cls:"stashpad-when-pop-row"});for(let ie of["Today","Yesterday"]){let te=V.createEl("button",{cls:"stashpad-when-pop-chip",text:ie});te.type="button",te.addEventListener("mousedown",fe=>fe.preventDefault()),te.addEventListener("click",fe=>{fe.preventDefault(),h(L,ie),Y()})}let q=K.createDiv({cls:"stashpad-when-pop-row stashpad-when-pop-days"}),ee=["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],oe=(ye().day()+6)%7;for(let ie=0;ie<ee.length;ie++){let te=ee[ie],fe=q.createEl("button",{cls:"stashpad-when-pop-chip",text:te.slice(0,3)});fe.type="button",fe.title=te,ie===oe&&fe.addClass("is-today"),fe.addEventListener("mousedown",we=>we.preventDefault()),fe.addEventListener("click",we=>{if(we.preventDefault(),C==="betweenEnd"){let se=ie,Ae=ye().startOf("day"),Xe=(Ae.day()+6)%7,ri=(se-Xe+7)%7;ri===0&&(ri=7);let Gs=Ae.clone().add(ri,"days").format("YYYY-MM-DD");h(L,Gs)}else h(L,te);Y()})}})});let M=(O,K)=>{O.value||(O.value=K);let Y=O;if(typeof Y.showPicker=="function")try{Y.showPicker();return}catch{}O.focus(),O.click()};return y.addEventListener("click",O=>{O.preventDefault(),M(v,ye().format("YYYY-MM-DD"))}),v.addEventListener("change",()=>{v.value&&h(L,v.value)}),w.addEventListener("click",O=>{O.preventDefault();let K=L.selectionStart??L.value.length,Y=p(L.value,K),Z=c(this.whenMode,Y,C),[V,q]=Z.split(":"),ee=parseInt(V,10),ue=parseInt(q,10),oe=ee%12;oe===0&&(oe=12);let ie=ee>=12?"pm":"am";b(L,Q,oe,ue,ie)}),x.addEventListener("click",O=>{O.preventDefault(),L.value="",m(""),L.focus()}),L},u=()=>{if(l.empty(),this.whenMode==="between"){let g=f("start (date / day / timeframe)",()=>this.whenSingleText,y=>{this.whenSingleText=y},"betweenStart"),I=f("end (date / day / timeframe)",()=>this.whenBetweenEndText,y=>{this.whenBetweenEndText=y},"betweenEnd"),m=l.createDiv({cls:"stashpad-when-actions"}),C=m.createEl("button",{cls:"stashpad-when-insert",text:"Insert"});C.type="button",C.addEventListener("mousedown",y=>y.preventDefault());let B=()=>{let y=g.value.trim(),v=I.value.trim();y&&this.appendFilterToInput(e,"after",y),v&&this.appendFilterToInput(e,"before",v),this.closeWhenBuilder()};C.addEventListener("click",y=>{y.preventDefault(),B()});let E=m.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()}),d(g,B),d(I,B),g.focus(),g.setSelectionRange(g.value.length,g.value.length)}else{let g=f("date / day / timeframe",()=>this.whenSingleText,E=>{this.whenSingleText=E},"single"),I=l.createDiv({cls:"stashpad-when-actions"}),m=I.createEl("button",{cls:"stashpad-when-insert",text:"Insert"});m.type="button",m.addEventListener("mousedown",E=>E.preventDefault());let C=()=>{let E=g.value.trim();E&&this.appendFilterToInput(e,this.whenMode,E),this.closeWhenBuilder()};m.addEventListener("click",E=>{E.preventDefault(),C()});let B=I.createEl("button",{cls:"stashpad-when-cancel",text:"Cancel"});B.type="button",B.addEventListener("mousedown",E=>E.preventDefault()),B.addEventListener("click",E=>{E.preventDefault(),this.closeWhenBuilder()}),d(g,C),g.focus(),g.setSelectionRange(g.value.length,g.value.length)}};u(),t.parentElement?.insertBefore(s,t.nextSibling),this.whenBuilderEl=s}closeWhenBuilder(){if(!this.whenBuilderEl)return;this.whenBuilderEl.remove(),this.whenBuilderEl=null,this.modalEl?.removeClass("is-when-builder-open")}selectSuggestion(e,t){if(e&&e.kind==="search-excluded"){this.loadExcludedNotes();return}super.selectSuggestion(e,t)}onChooseSuggestion(e){if(e.kind==="create"&&this.opts.onCreate){let t=this.inputEl?.value??"",i=t.replace(/(?<![\w-])(in|before|after|on):\s*(?:\[[^\]]*\]|[^]*?(?=\s+(?:in|before|after|on):|$))/gi," ").replace(/\s+/g," ").trim();this.opts.onCreate(i||t);return}if(e.kind==="folder-open"&&e.id==="__folder_picker__"){let t=this.opts.folderResults?.()??[];if(!t.length)return;let i=this.inputEl?.value??"",s=!1,n=p=>{s=!0;let f=p.split("/").pop()??p;this.opts.onPick({id:`folder:${p}`,label:`Open folder \u201C${f}\u201D in a new tab`,node:null,kind:"folder-open",folder:p})},o=new la(this.app,t,n),a=o.onClose.bind(o),l=this.tree,c=this.titleFn,d=this.opts,h=this.app;o.onClose=()=>{a(),setTimeout(()=>{if(s)return;let p=new A(h,l,c,d);p.open(),setTimeout(()=>{let f=p.inputEl;f&&(i&&(f.value=i,f.dispatchEvent(new Event("input",{bubbles:!0}))),f.focus(),f.setSelectionRange(f.value.length,f.value.length))},0)},0)},o.open();return}if(e.node?.file&&!this.app.vault.getAbstractFileByPath(e.node.file.path)){new Ie.Notice("That note no longer exists.");return}this.opts.onPick(e)}},la=class extends Ie.FuzzySuggestModal{constructor(e,t,i){super(e);this.folders=t;this.onChosen=i;this.setPlaceholder("Open which folder?")}getItems(){return this.folders}getItemText(e){let t=e.split("/").pop()??e;return t===e?e:`${t} \u2014 ${e}`}onChooseItem(e){this.onChosen(e)}};var Es="stashpad";function Nn(A){let r=[];A.vault&&r.push(`vault=${encodeURIComponent(A.vault)}`),r.push(`folder=${encodeURIComponent(A.folder)}`),A.note&&r.push(`note=${encodeURIComponent(A.note)}`);let e=A.run&&A.run.length?A.run:["reveal"];return r.push(`run=${encodeURIComponent(e.join(","))}`),`obsidian://${Es}?${r.join("&")}`}function el(A){let r=(A||"").trim();if(!r)return null;let e;if(/^obsidian:\/\//i.test(r)){let c=r.match(/^obsidian:\/\/([^?]*)(?:\?(.*))?$/i);if(!c||decodeURIComponent(c[1].replace(/\/+$/,"")).toLowerCase()!==Es)return null;e=c[2]??""}else e=r.replace(/^\?/,"");let t=new URLSearchParams(e),i=t.get("folder");if(!i)return null;let s={folder:i},n=t.get("vault");n&&(s.vault=n);let o=t.get("note");o&&(s.note=o);let a=t.get("run");a&&(s.run=a);let l=t.get("action");return l&&(s.action=l),s}function tl(A){let r=A.run;!r&&A.action&&A.action!==Es&&(r=A.action);let e=(r||"reveal").split(",").map(t=>t.trim().toLowerCase()).filter(Boolean);return e.length?e:["reveal"]}var Ge=require("obsidian");ve();async function il(A,r,e,t){let i=e.blob,s=i.replace(/\.stashenc$/,".stashmeta"),n=A.vault.adapter,o=null,a=null;try{o=await n.readBinary(i)}catch{o=null}if(!o){new Ge.Notice("Couldn't read the encrypted file to delete it.");return}try{await n.exists(s)&&(a=await n.read(s))}catch{a=null}let l=(r.settings.lockedSubtrees??[]).find(p=>p.blob===i)??null,c=async p=>{let f=A.vault.getAbstractFileByPath(p);if(f)try{await A.fileManager.trashFile(f);return}catch{}try{await n.exists(p)&&await n.remove(p)}catch{}},d=async()=>{await c(i),await c(s),r.settings.lockedSubtrees=(r.settings.lockedSubtrees??[]).filter(p=>p.blob!==i),await r.saveSettings(),t()},h=async()=>{if(await n.writeBinary(i,o),a!=null)try{await n.write(s,a)}catch{}l&&!(r.settings.lockedSubtrees??[]).some(p=>p.blob===i)&&(r.settings.lockedSubtrees=[...r.settings.lockedSubtrees??[],l],await r.saveSettings()),t()};await d(),r.getUndoStack(e.folder).push({label:e.count>1?"Delete encrypted notes":"Delete encrypted note",undo:h,redo:d}),new Ge.Notice(e.count>1?"Encrypted notes deleted \u2014 undo to restore.":"Encrypted note deleted \u2014 undo to restore.")}function Tn(A,r){let{app:e,plugin:t,descriptor:i}=r,s=p=>new Ge.Notice(`Unlock this note first to ${p}.`),n=p=>{if(Ge.Platform.isMobile)return p;try{return e.vault.adapter?.getFullPath?.(p)||p}catch{return p}},o=()=>{let p=Nn({vault:e.vault.getName(),folder:i.folder,note:i.rootId,run:["reveal"]});navigator.clipboard.writeText(p).then(()=>new Ge.Notice("Stashpad link copied."),()=>new Ge.Notice("Couldn't copy the link."))},a=()=>{A.addItem(p=>{p.setTitle("Share & export").setIcon("share-2");let f=typeof p.setSubmenu=="function"?p.setSubmenu():null;f&&typeof f.addItem=="function"?(f.addItem(u=>{u.setTitle("Copy Stashpad link").setIcon("link"),i.rootId?u.onClick(()=>o()):u.setDisabled(!0)}),f.addItem(u=>u.setTitle("Export to .stash\u2026").setIcon("package").onClick(()=>{t.exportLockedSubtree(i.blob)})),t.settings.okfEnabled&&f.addItem(u=>u.setTitle("Export as OKF\u2026").setIcon("book-marked").onClick(()=>s("export it as OKF")))):i.rootId?p.onClick(()=>o()):p.setDisabled(!0)})},l=()=>{A.addItem(p=>p.setTitle(r.unlockLabel).setIcon("unlock").onClick(()=>r.onUnlock()))},c=()=>{if(Ge.Platform.isMobile)return;let p=Ge.Platform.isMacOS?"Finder":Ge.Platform.isWin?"File Explorer":"file manager";A.addItem(f=>f.setTitle(`Show in ${p}`).setIcon("folder-search").onClick(()=>{try{let u=window.require?.("electron")?.shell,g=e.vault.adapter?.getFullPath?.(i.blob);g&&u?.showItemInFolder&&u.showItemInFolder(g)}catch(u){console.warn("[Stashpad] showItemInFolder failed",u)}}))},d=()=>{A.addItem(p=>p.setTitle("Copy encrypted file path").setIcon("copy").onClick(()=>{navigator.clipboard.writeText(n(i.blob)),new Ge.Notice("Path copied.")}))},h=()=>{A.addItem(p=>{p.setTitle(i.count>1?"Delete encrypted notes\u2026":"Delete encrypted note\u2026").setIcon("trash-2"),p.setWarning?.(!0),p.onClick(()=>{r.confirmDelete?new j(e,i.count>1?`Delete ${i.count} encrypted notes?`:"Delete encrypted note?","The encrypted file moves to Obsidian's trash (recoverable there). You'll still need your password to read it if you restore it.","Delete",async f=>{f&&await il(e,t,i,r.onChange)}).open():il(e,t,i,r.onChange)})})};r.fullParity?(A.addItem(p=>p.setTitle("Open in new Stashpad tab").setIcon("layout-grid").onClick(()=>s("open it in a tab"))),A.addItem(p=>p.setTitle("Open in Obsidian editor").setIcon("file-text").onClick(()=>s("open it in the editor"))),A.addItem(p=>p.setTitle("Focus in Stashpad").setIcon("arrow-right").onClick(()=>s("focus it"))),A.addSeparator(),A.addItem(p=>p.setTitle("Split note\u2026").setIcon("split").onClick(()=>s("split it"))),A.addItem(p=>p.setTitle("Copy text").setIcon("copy").onClick(()=>s("copy its text"))),A.addItem(p=>p.setTitle("Clone (duplicate / copy)").setIcon("files").onClick(()=>s("clone it"))),A.addItem(p=>p.setTitle("Fork into a separate note\u2026").setIcon("git-branch").onClick(()=>s("fork it"))),a(),l(),c(),d(),A.addSeparator(),A.addItem(p=>p.setTitle("Move to\u2026").setIcon("move").onClick(()=>s("move it"))),A.addItem(p=>p.setTitle("Move to Home").setIcon("home").onClick(()=>s("move it"))),A.addItem(p=>p.setTitle("Pin to sidebar").setIcon("pin").onClick(()=>s("pin it"))),A.addItem(p=>p.setTitle("Pin to top of list").setIcon("arrow-up-to-line").onClick(()=>s("pin it"))),A.addItem(p=>p.setTitle("Set color\u2026").setIcon("palette").onClick(()=>s("set its color"))),A.addItem(p=>p.setTitle("Task").setIcon("check-circle-2").onClick(()=>s("change its task state"))),A.addSeparator(),h()):(l(),a(),A.addSeparator(),c(),d(),A.addSeparator(),h())}var sl=require("obsidian");ce();var Mn=class extends sl.SuggestModal{constructor(r){super(r),this.setPlaceholder("Run a Stashpad command\u2026");let e=this.app.commands?.commands??{};this.commands=Object.keys(e).filter(t=>t.startsWith("stashpad:")).filter(t=>t!=="stashpad:stashpad-command-palette").map(t=>({id:t,name:pd(e[t]?.name??t)})).sort((t,i)=>t.name.localeCompare(i.name))}getSuggestions(r){return this.commands.filter(e=>$s(r,e.name))}renderSuggestion(r,e){e.createDiv({text:r.name,cls:"stashpad-cmd-palette-name"})}onChooseSuggestion(r){this.app.commands?.executeCommandById?.(r.id)}};function pd(A){return A.replace(/^(?:\s*Stashpad:\s*)+/i,"").trim()||A}pn();ve();In();var ca=require("obsidian");function nl(A){let r=A.code||"",e=/^Key([A-Z])$/.exec(r);if(e)return e[1].toLowerCase();let t=/^Digit(\d)$/.exec(r);return t?t[1]:(A.key||"").toLowerCase()}function gd(A,r){return!r||A.metaKey||A.ctrlKey||A.altKey?!1:r.length===1&&!/[a-z0-9]/i.test(r)?A.key===r:nl(A)===r.toLowerCase()}function Ri(A,r){return r?r.includes("+")?ud(A,r):gd(A,r):!1}function J(A,r){if(!r)return!1;let{primary:e,secondary:t,preferRight:i,useBoth:s}=r;return e&&t?s?Ri(A,e)||Ri(A,t):i?Ri(A,t):Ri(A,e):Ri(A,e)||Ri(A,t)}function vs(A){if(!A)return"";let r=ca.Platform.isMacOS;return A.split("+").map(e=>{let t=e.trim();return t?t.toLowerCase()==="mod"?r?"Cmd":"Ctrl":t.toLowerCase()==="alt"?r?"Opt":"Alt":t.length===1?t.toUpperCase():t:""}).filter(Boolean).join("+")}function ud(A,r){if(!r)return!1;let e=r.split("+").map(h=>h.trim()).filter(Boolean);if(e.length<2)return!1;let t=e[e.length-1].toLowerCase(),i=new Set(e.slice(0,-1).map(h=>h.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"),l=i.has("shift"),d=ca.Platform.isMacOS?A.metaKey:A.ctrlKey;return s&&!d||n&&!A.ctrlKey||o&&!A.metaKey||a!==A.altKey||l!==A.shiftKey||!s&&(!n&&A.ctrlKey||!o&&A.metaKey)?!1:nl(A)===t}var ae=require("obsidian");ce();var ol=require("obsidian"),fd="byfolder";function Pn(A,r,e,t){let i=A.createDiv({cls:"stashpad-trash-modes"}),s=i.createEl("button",{cls:"stashpad-agg-reset",attr:{"aria-label":"Reset to default view"}});(0,ol.setIcon)(s,"rotate-ccw"),s.onclick=()=>t(fd);let n=[{key:"byfolder",label:"By folder",count:e.total},{key:"separated",label:"Separated",count:e.total},{key:"mixed",label:"Mixed (by date)",count:e.total},{key:"encrypted",label:"Encrypted",count:e.enc},{key:"unencrypted",label:"Unencrypted",count:e.dec}];for(let o of n){let a=i.createEl("button",{cls:"stashpad-triage-chip"});r===o.key&&a.addClass("is-active"),a.createSpan({text:o.label}),a.createSpan({cls:"stashpad-triage-chip-count",text:String(o.count)}),a.onclick=()=>t(o.key)}}function yt(A,r,e,t){if(!e||e===r)return;let i=o=>{let a=!1;return A.iterateAllLeaves(l=>{l===o&&(a=!0)}),a},s=r,n=A.on("active-leaf-change",()=>{if(i(r)){s=A.activeLeaf??s;return}A.offref(n),s===r&&i(e)&&(A.setActiveLeaf(e,{focus:!0}),A.revealLeaf(e))});t?.(n)}var Hn=ae.moment,Rn=class extends ae.ItemView{constructor(e,t){super(e);this.plugin=t;this.mode="encrypted";this.taskState=Bn();this.archiveSubMode="byfolder";this.renderPending=!1;this.watchFolderFilter="";this.watchViaFilter="";this.watchQuery=""}getViewType(){return di}getDisplayText(){return this.mode==="archived"?"All archived":this.mode==="tasks"?"All tasks":this.mode==="watch"?"Previously encrypted":"All encrypted"}getIcon(){return this.mode==="archived"?"archive":this.mode==="tasks"?"check-square":this.mode==="watch"?"history":"lock"}getState(){return{...super.getState(),mode:this.mode}}async setState(e,t){(e?.mode==="archived"||e?.mode==="encrypted"||e?.mode==="tasks"||e?.mode==="watch")&&(this.mode=e.mode),await super.setState(e,t),await this.render()}async onOpen(){this.containerEl.addClass("stashpad-aggregate-view");let e=s=>s.endsWith(".stashenc")&&!s.startsWith("_deleted/"),t=s=>s.endsWith(".md")&&/(^|\/)archive\//.test(s),i=s=>e(s)||t(s);this.registerEvent(this.app.vault.on("create",s=>{i(s.path)&&this.scheduleRender()})),this.registerEvent(this.app.vault.on("delete",s=>{i(s.path)&&this.scheduleRender()})),this.registerEvent(this.app.vault.on("rename",(s,n)=>{(i(s.path)||i(n))&&this.scheduleRender()})),await this.render()}scheduleRender(){this.renderPending||(this.renderPending=!0,window.setTimeout(()=>{this.renderPending=!1,this.render()},150))}cleanFolder(e){return(e||"").replace(/\/+$/,"")}archiveFolders(){let e=new Set;for(let i of this.plugin.discoverStashpadFolders()){let s=Dt(i);this.plugin.app.vault.getAbstractFileByPath(s)&&e.add(s)}for(let i of this.plugin.settings.archiveFolders??[])e.add(this.cleanFolder(i));let t=this.plugin.settings.folderEncPrefs??{};for(let[i,s]of Object.entries(t))s?.archive&&e.add(this.cleanFolder(i));return[...e].sort((i,s)=>i.localeCompare(s))}async render(){let e=this.contentEl;e.empty(),e.addClass("stashpad-aggregate-body");let t=e.createDiv({cls:"stashpad-aggregate-header"});t.createEl("h3",{text:this.getDisplayText()});let i=t.createEl("button",{cls:"stashpad-trash-iconbtn"});if((0,ae.setIcon)(i,"refresh-cw"),i.setAttr("aria-label","Refresh"),i.onclick=()=>void this.render(),this.mode==="tasks"){ys(e.createDiv(),this.app,this.plugin,this.taskState,{onOpen:(s,n)=>void this.plugin.revealNoteByRef(s,n)});return}if(this.mode==="archived"){this.renderArchived(e);return}if(this.mode==="watch"){this.renderWatch(e);return}this.renderEncrypted(e)}renderEncrypted(e){let t=this.plugin.settings.lockedSubtrees??[];if(t.length===0){e.createDiv({cls:"stashpad-trash-empty",text:"Nothing is encrypted yet. Lock a note or folder and it shows up here."});return}let i=new Map;for(let n of t){let o=this.cleanFolder(n.folder)||"(vault root)";(i.get(o)??i.set(o,[]).get(o)).push(n)}let s=[...i.keys()].sort((n,o)=>n.localeCompare(o));e.createDiv({cls:"stashpad-aggregate-sub",text:`${t.length} locked ${t.length===1?"item":"items"} in ${s.length} ${s.length===1?"folder":"folders"}.`});for(let n of s){let o=e.createDiv({cls:"stashpad-trash-group"}),a=o.createDiv({cls:"stashpad-trash-group-head"});(0,ae.setIcon)(a.createSpan({cls:"stashpad-trash-group-icon"}),"folder"),a.createSpan({text:n.split("/").pop()||n}),a.createSpan({cls:"stashpad-trash-group-count",text:String(i.get(n).length)});let l=a.createEl("button",{cls:"stashpad-trash-iconbtn",text:"Open"});l.onclick=()=>void this.plugin.activateViewForFolder(n);for(let c of i.get(n)){let d=o.createDiv({cls:"stashpad-trash-row"}),h=d.createDiv({cls:"stashpad-trash-row-main"});h.createSpan({cls:"stashpad-trash-title",text:c.title||"Locked note"});let p=c.created?`locked ${Hn(c.created).fromNow()}`:"locked",f=c.count>1?` \xB7 ${c.count} notes`:"";h.createSpan({cls:"stashpad-trash-sub",text:p+f});let u=d.createEl("button",{cls:"stashpad-trash-iconbtn",text:"Export"});u.setAttr("aria-label","Export to .stash (encrypted with a password you choose)"),u.onclick=()=>void this.plugin.exportLockedSubtree(c.blob);let g=d.createSpan({cls:"stashpad-aggregate-lockbadge"});(0,ae.setIcon)(g,"lock"),this.attachLockedRowMenu(d,c,{archived:!1})}}}renderArchived(e){let t=this.archiveFolders();if(t.length===0){e.createDiv({cls:"stashpad-trash-empty",text:"No archive folders yet. Toggle Archive on a folder to collect it here."});return}let i=new Set(t),s=this.plugin.settings.lockedSubtrees??[],n=new Map;for(let g of s){let I=this.cleanFolder(g.folder);i.has(I)&&(n.get(I)??n.set(I,[]).get(I)).push(g)}let o=new Map,a=0;for(let g of t){let I=this.plugin.archivedPlainNotesIn(g);o.set(g,I),a+=I.length}let l=[...n.values()].reduce((g,I)=>g+I.length,0),c=a+l,d=t.flatMap(g=>o.get(g)??[]),h=t.flatMap(g=>n.get(g)??[]);e.createDiv({cls:"stashpad-aggregate-sub",text:`${t.length} archive ${t.length===1?"folder":"folders"}, ${c} archived ${c===1?"item":"items"} (${a} plain \xB7 ${l} locked).`}),Pn(e,this.archiveSubMode,{total:c,enc:l,dec:a},g=>{this.archiveSubMode=g,this.render()});let p=this.archiveSubMode;if(p==="mixed"){let g=[];for(let m of d)g.push({ts:m.stat.mtime||0,kind:"plain",f:m});for(let m of h)g.push({ts:m.created&&Date.parse(m.created)||0,kind:"locked",e:m});g.sort((m,C)=>C.ts-m.ts);let I=e.createDiv({cls:"stashpad-trash-group"});for(let m of g)m.kind==="plain"&&m.f?this.archivePlainRow(I,m.f):m.e&&this.archiveLockedRow(I,m.e);return}if(p==="byfolder"){for(let g of t){let I=n.get(g)??[],m=o.get(g)??[],C=e.createDiv({cls:"stashpad-trash-group"}),B=C.createDiv({cls:"stashpad-trash-group-head"});(0,ae.setIcon)(B.createSpan({cls:"stashpad-trash-group-icon"}),"archive"),B.createSpan({text:g.split("/").pop()||g}),B.createSpan({cls:"stashpad-trash-group-count",text:String(I.length+m.length)});let E=B.createEl("button",{cls:"stashpad-trash-iconbtn",text:"Open"});if(E.onclick=()=>void this.plugin.activateViewForFolder(g),I.length===0&&m.length===0){C.createDiv({cls:"stashpad-trash-sub",text:"No archived items."});continue}for(let y of m)this.archivePlainRow(C,y);for(let y of I)this.archiveLockedRow(C,y)}return}let f=p!=="encrypted"&&d.length>0,u=p!=="unencrypted"&&h.length>0;if(!f&&!u){e.createDiv({cls:"stashpad-trash-empty",text:"Nothing in this view."});return}if(f){let g=e.createDiv({cls:"stashpad-trash-group"}),I=g.createDiv({cls:"stashpad-trash-group-head"});(0,ae.setIcon)(I.createSpan({cls:"stashpad-trash-group-icon"}),"file-text"),I.createSpan({text:"Plain notes"}),I.createSpan({cls:"stashpad-trash-group-count",text:String(d.length)});for(let m of d)this.archivePlainRow(g,m)}if(u){let g=e.createDiv({cls:"stashpad-trash-group"}),I=g.createDiv({cls:"stashpad-trash-group-head"});(0,ae.setIcon)(I.createSpan({cls:"stashpad-trash-group-icon"}),"lock"),I.createSpan({text:"Locked (encrypted)"}),I.createSpan({cls:"stashpad-trash-group-count",text:String(h.length)});for(let m of h)this.archiveLockedRow(g,m)}}archivePlainRow(e,t){let i=e.createDiv({cls:"stashpad-trash-row"}),s=i.createDiv({cls:"stashpad-trash-row-main"});s.createSpan({cls:"stashpad-trash-title",text:t.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ").trim()||t.basename}),s.createSpan({cls:"stashpad-trash-sub",text:`archived ${Hn(t.stat.mtime).fromNow()}`});let n=i.createEl("button",{cls:"stashpad-trash-restore",text:"Restore"});(0,ae.setIcon)(n.createSpan({cls:"stashpad-btn-icon"}),"rotate-ccw"),n.onclick=async()=>{n.disabled=!0,await this.plugin.unarchiveNote(t)?this.render():n.disabled=!1},this.attachPlainRowMenu(i,t,n)}attachPlainRowMenu(e,t,i){let s=()=>{let o=new ae.Menu;return o.addItem(a=>a.setTitle("Open note").setIcon("file-text").onClick(()=>void this.app.workspace.getLeaf(!1).openFile(t))),o.addItem(a=>a.setTitle("Restore (un-archive)").setIcon("rotate-ccw").onClick(()=>i.click())),o.addSeparator(),ae.Platform.isMobile||o.addItem(a=>a.setTitle("Show in Finder").setIcon("folder-open").onClick(()=>{try{let l=window.require?.("electron")?.shell,c=this.app.vault.adapter?.getFullPath?.(t.path);c&&l?.showItemInFolder&&l.showItemInFolder(c)}catch(l){console.warn("[Stashpad] showItemInFolder failed",l)}})),o.addItem(a=>a.setTitle("Copy file path").setIcon("copy").onClick(()=>{let l=t.path;if(!ae.Platform.isMobile)try{l=this.app.vault.adapter?.getFullPath?.(t.path)||t.path}catch{}navigator.clipboard.writeText(l),new ae.Notice("Path copied.")})),o};e.oncontextmenu=o=>{o.preventDefault(),s().showAtMouseEvent(o)};let n=e.createEl("button",{cls:"stashpad-trash-iconbtn stashpad-agg-more"});(0,ae.setIcon)(n,"ellipsis-vertical"),n.setAttr("aria-label","More actions"),n.onclick=o=>{o.stopPropagation(),s().showAtMouseEvent(o)}}archiveLockedRow(e,t){let i=e.createDiv({cls:"stashpad-trash-row"}),s=i.createDiv({cls:"stashpad-trash-row-main"});s.createSpan({cls:"stashpad-trash-title",text:t.title||"Locked note"});let n=t.created?`archived ${Hn(t.created).fromNow()}`:"archived",o=(t.count??0)>1?` \xB7 ${t.count} notes`:"";s.createSpan({cls:"stashpad-trash-sub",text:n+o});let a=i.createEl("button",{cls:"stashpad-trash-restore",text:"Restore"});(0,ae.setIcon)(a.createSpan({cls:"stashpad-btn-icon"}),"rotate-ccw"),a.setAttr("aria-label","Unlock and restore (needs the password)"),a.onclick=async()=>{a.disabled=!0;let d=t.blob.split("/"),h=d.lastIndexOf("archive"),p=h>0?d.slice(0,h).join("/"):void 0;await this.plugin.unlockBundleAt(t.blob,p?{destFolder:p}:{})?this.render():a.disabled=!1};let l=i.createEl("button",{cls:"stashpad-trash-iconbtn",text:"Export"});l.setAttr("aria-label","Export to .stash (encrypted with a password you choose)"),l.onclick=()=>void this.plugin.exportLockedSubtree(t.blob);let c=i.createSpan({cls:"stashpad-aggregate-lockbadge"});(0,ae.setIcon)(c,"lock"),this.attachLockedRowMenu(i,t,{archived:!0})}attachLockedRowMenu(e,t,i){let s=()=>{let o=new ae.Menu;return Tn(o,{app:this.app,plugin:this.plugin,descriptor:{blob:t.blob,rootId:t.rootId,count:t.count??1,folder:this.cleanFolder(t.folder)},unlockLabel:i.archived?"Unlock & restore":"Decrypt (unlock)",onUnlock:async()=>{let a;if(i.archived){let c=t.blob.split("/"),d=c.lastIndexOf("archive");a=d>0?c.slice(0,d).join("/"):void 0}await this.plugin.unlockBundleAt(t.blob,a?{destFolder:a}:{})&&this.render()},onChange:()=>void this.render(),fullParity:!1,confirmDelete:!1}),o};e.oncontextmenu=o=>{o.preventDefault(),s().showAtMouseEvent(o)};let n=e.createEl("button",{cls:"stashpad-trash-iconbtn stashpad-agg-more"});(0,ae.setIcon)(n,"ellipsis-vertical"),n.setAttr("aria-label","More actions"),n.onclick=o=>{o.stopPropagation(),s().showAtMouseEvent(o)}}renderWatch(e){this.plugin.pruneReEncryptWatch()&&this.plugin.saveSettings();let t=this.plugin.settings.reEncryptWatch??[],i=t.filter(g=>!g.removed),s=t.filter(g=>g.removed);if(t.length===0){e.createDiv({cls:"stashpad-trash-empty",text:"Nothing here yet. When you unlock an encrypted note (or restore one from the trash), it shows up here so you can re-encrypt it later."});return}let n=e.createDiv({cls:"stashpad-trash-modes"}),o=n.createEl("select",{cls:"dropdown"});o.createEl("option",{value:"",text:"All folders"});for(let g of[...new Set(i.map(I=>I.folder))].sort())o.createEl("option",{value:g,text:g});o.value=this.watchFolderFilter,o.onchange=()=>{this.watchFolderFilter=o.value,this.render()};let a=n.createEl("select",{cls:"dropdown"});a.createEl("option",{value:"",text:"Unlocked + restored"}),a.createEl("option",{value:"unlock",text:"Unlocked"}),a.createEl("option",{value:"restore",text:"Restored from trash"}),a.value=this.watchViaFilter,a.onchange=()=>{this.watchViaFilter=a.value,this.render()};let l=n.createEl("input",{type:"text",attr:{placeholder:"Search\u2026"}});l.value=this.watchQuery,l.oninput=()=>{this.watchQuery=l.value,u()};let c=(g,I)=>g.toLowerCase().split(/\s+/).filter(Boolean).every(m=>I.toLowerCase().includes(m)),d=g=>(!this.watchFolderFilter||g.folder===this.watchFolderFilter)&&(!this.watchViaFilter||g.via===this.watchViaFilter)&&(!this.watchQuery.trim()||c(this.watchQuery,`${g.title} ${g.folder}`)),h=async()=>{await this.plugin.saveSettings(),this.render()},p=(g,I,m)=>{let C=g.createDiv({cls:"stashpad-trash-row"}),B=C.createDiv({cls:"stashpad-trash-row-main"});B.createSpan({cls:"stashpad-trash-title",text:this.plugin.reEncryptDisplayTitle(I)});let E=Hn(I.unlockedAt).fromNow(),y=I.count>1?` \xB7 ${I.count} notes`:"";if(B.createSpan({cls:"stashpad-trash-sub",text:`${I.via==="restore"?"restored":"unlocked"} ${E} \xB7 ${I.folder.split("/").pop()||I.folder}${y}`}),m){let v=C.createEl("button",{cls:"stashpad-trash-iconbtn",text:"Un-remove"});v.onclick=()=>{delete I.removed,delete I.removedAt,h()}}else{let v=C.createEl("button",{cls:"stashpad-trash-restore",text:"Re-encrypt"});(0,ae.setIcon)(v.createSpan({cls:"stashpad-btn-icon"}),"lock"),v.onclick=async()=>{v.disabled=!0,await this.plugin.lockNoteSubtree(I.folder,I.rootId,null,{})||(v.disabled=!1),this.render()};let Q=C.createEl("input",{type:"number",cls:"stashpad-watch-peek",attr:{placeholder:"auto",title:"Auto re-encrypt after N idle minutes (blank = folder/global default, 0 = off)",min:"0"}});Q.value=I.peekMin==null?"":String(I.peekMin),Q.onchange=()=>{let k=Q.value.trim(),D=Number(k);if(k==="")delete I.peekMin;else if(Number.isFinite(D)&&D>=0)I.peekMin=Math.floor(D);else{Q.value=I.peekMin==null?"":String(I.peekMin);return}this.plugin.saveSettings()};let w=C.createEl("button",{cls:"stashpad-trash-iconbtn"});(0,ae.setIcon)(w,"x"),w.setAttr("aria-label","Remove from watchlist (recoverable below)"),w.onclick=()=>{I.removed=!0,I.removedAt=new Date().toISOString(),h()}}},f=e.createDiv(),u=()=>{f.empty();let g=i.filter(d).sort((C,B)=>(B.unlockedAt||"").localeCompare(C.unlockedAt||"")),I=f.createDiv({cls:"stashpad-trash-group-head"});if((0,ae.setIcon)(I.createSpan({cls:"stashpad-trash-group-icon"}),"history"),I.createSpan({text:"Watching"}),I.createSpan({cls:"stashpad-trash-group-count",text:String(g.length)}),i.length>0){let C=I.createEl("button",{cls:"stashpad-trash-iconbtn",text:"Re-encrypt all applicable"});C.onclick=()=>void this.plugin.encryptEverythingApplicable()}g.length===0&&f.createDiv({cls:"stashpad-trash-sub",text:i.length?"No matches for the current filters.":"Nothing being watched."});let m=f.createDiv({cls:"stashpad-trash-group"});for(let C of g)p(m,C,!1);if(s.length>0){let C=f.createEl("details",{cls:"stashpad-watch-removed"});C.createEl("summary",{text:`Removed from watchlist (${s.length})`});let B=C.createDiv({cls:"stashpad-trash-group"});for(let E of s.filter(d))p(B,E,!0)}};u()}async onClose(){this.contentEl.empty()}};async function He(A,r){let{workspace:e}=A.app,t=e.getLeavesOfType(di).find(n=>n.getViewState()?.state?.mode===r);if(t){e.revealLeaf(t);return}let i=e.getMostRecentLeaf(),s=e.getLeaf("tab");await s.setViewState({type:di,active:!0,state:{mode:r}}),e.revealLeaf(s),yt(e,s,i,n=>A.registerEvent(n))}var ti=require("obsidian");ve();var Oe=class Oe{constructor(r){this.host=r;this.knownBodies=new Map;this.contribTimers=new Map;this.recentSelfWrites=new Map;this.lastExternalModify=new Map}dispose(){for(let r of this.contribTimers.values())clearTimeout(r);this.contribTimers.clear(),this.knownBodies.clear(),this.recentSelfWrites.clear(),this.lastExternalModify.clear()}currentAuthorLink(){let r=(this.host.plugin.settings.authorName??"").trim(),e=(this.host.plugin.settings.authorId??"").trim();if(!r||!e)return null;let t=r.replace(/[^\w\- ]+/g,"").trim().replace(/\s+/g,"-")||"author",i=`${this.host.noteFolder}/_authors/${t}-${e}.md`,s=r.replace(/[\[\]|]/g,"").trim()||t;return{link:`[[${i}|${s}]]`,path:i,name:r,id:e}}claimSelectedAsAuthor(){this.claimAuthorship({scope:"selection",contributorMode:!1})}claimFolderAsAuthor(){this.claimAuthorship({scope:"folder",contributorMode:!1})}claimSelectedWithContributor(){this.claimAuthorship({scope:"selection",contributorMode:!0})}claimFolderWithContributor(){this.claimAuthorship({scope:"folder",contributorMode:!0})}fileBackedNotesInFolder(){let r=this.host.noteFolder.replace(/\/+$/,"");return this.host.app.vault.getMarkdownFiles().filter(e=>{let t=e.parent?.path?.replace(/\/+$/,"")??"";if(t!==r&&!t.startsWith(r+"/")||e.path.includes("/_authors/"))return!1;let i=this.host.app.metadataCache.getFileCache(e)?.frontmatter;return typeof i?.id=="string"&&!!i.id})}async pacedFrontmatter(r,e){for(let s=0;s<r.length;s++){let n=this.host.app.vault.getAbstractFileByPath(r[s]);if(n instanceof ti.TFile){this.recentSelfWrites.set(n.path,Date.now());try{await this.host.app.fileManager.processFrontMatter(n,o=>e(o,r[s]))}catch(o){console.warn("[Stashpad] claim: frontmatter write failed",r[s],o)}}(s+1)%25===0&&await new Promise(o=>setTimeout(o,30))}}async claimAuthorship(r){let e=this.currentAuthorLink();if(!e){new ti.Notice("Set your author name in Stashpad settings first.");return}let t=`-${e.id}`,i=r.scope==="selection"?this.host.getActionTargets().map(p=>p.file).filter(p=>!!p):this.fileBackedNotesInFolder();if(i.length===0){new ti.Notice(r.scope==="selection"?"No notes selected.":"No notes in this folder.");return}let s=[],n=[];for(let p of i){let f=this.host.app.metadataCache.getFileCache(p)?.frontmatter,u=typeof f?.author=="string"?f.author:"";if(!u.trim()){s.push(p.path);continue}if(u.includes(t)||!r.contributorMode)continue;(Array.isArray(f?.contributors)?f.contributors.filter(I=>typeof I=="string"):[]).some(I=>I.includes(t))||n.push(p.path)}let o=s.length+n.length;if(o===0){new ti.Notice("Nothing to claim \u2014 those notes are already authored by you.");return}if(r.scope==="folder"){let p=[`Stamp yourself as author on ${s.length} unauthored note(s)`];if(n.length&&p.push(`and as a contributor on ${n.length} already-authored note(s)`),!await new Promise(u=>{new j(this.host.app,"Claim authorship",`${p.join(" ")}? +Existing authors are never overwritten. This can be undone.`,"Claim",u).open()}))return}let a=this.host.noteFolder,l=e.link,c=new Set,d=async()=>{await this.pacedFrontmatter(s,(p,f)=>{typeof p.author=="string"&&p.author.trim()||(p.author=l),Array.isArray(p.contributors)&&p.contributors.some(u=>typeof u=="string"&&u.includes(t))&&(p.contributors=p.contributors.filter(u=>!(typeof u=="string"&&u.includes(t))),c.add(f))}),await this.pacedFrontmatter(n,p=>{let f=Array.isArray(p.contributors)?p.contributors.filter(u=>typeof u=="string"):[];f.some(u=>u.includes(t))||f.push(l),p.contributors=f})};this.ensureAuthorFile(e),await d(),this.host.plugin.getUndoStack(a).push({label:`Claim authorship (${o} note${o===1?"":"s"})`,undo:async()=>{await this.pacedFrontmatter(s,(p,f)=>{if(typeof p.author=="string"&&p.author.includes(t)&&delete p.author,c.has(f)){let u=Array.isArray(p.contributors)?p.contributors.filter(g=>typeof g=="string"):[];u.some(g=>g.includes(t))||u.push(l),p.contributors=u}}),await this.pacedFrontmatter(n,p=>{Array.isArray(p.contributors)&&(p.contributors=p.contributors.filter(f=>!(typeof f=="string"&&f.includes(t))))}),this.host.debouncedRender()},redo:async()=>{c.clear(),await d(),this.host.debouncedRender()}});let h=[];s.length&&h.push(`authored ${s.length}`),n.length&&h.push(`contributing to ${n.length}`),new ti.Notice(`Claimed authorship: ${h.join(", ")}. Undo available.`),this.host.debouncedRender()}async ensureAuthorFile(r){try{r.id&&this.host.plugin.authorRegistry.record({id:r.id,name:r.name});let e=`${this.host.noteFolder}/_authors`;if(await this.host.ensureFolder(e),await this.host.app.vault.adapter.exists(r.path))return;let t=r.id===(this.host.plugin.settings.authorId??"").trim(),i=this.host.plugin.buildAuthorStub({id:r.id,name:r.name,role:t?this.host.plugin.settings.authorRole:void 0,department:t?this.host.plugin.settings.authorDepartment:void 0},new Date().toISOString());await this.host.app.vault.create(r.path,i)}catch(e){console.warn("[Stashpad] ensureAuthorFile failed",e)}}collectAuthorIds(r){let e=new Set,t=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 r){if(!i.file)continue;let s=this.host.app.metadataCache.getFileCache(i.file)?.frontmatter;if(!s)continue;let n=t(s.author);if(n&&e.add(n),Array.isArray(s.contributors))for(let o of s.contributors){let a=t(o);a&&e.add(a)}}return Array.from(e)}pruneContribMaps(){let r=Date.now(),e=Oe.EXTERNAL_WRITE_GRACE_MS*20,t=Oe.EXTERNAL_QUIESCENCE_MS*12;for(let[i,s]of this.recentSelfWrites)r-s>e&&this.recentSelfWrites.delete(i);for(let[i,s]of this.lastExternalModify)r-s>t&&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(r){let e=Date.now(),t=this.recentSelfWrites.get(r.path);t!==void 0&&e-t<Oe.EXTERNAL_WRITE_GRACE_MS||this.lastExternalModify.set(r.path,e),this.scheduleContribution(r)}scheduleContribution(r){let e=this.contribTimers.get(r.path);e&&clearTimeout(e);let t=this.isFileActivelyEdited(r),i=Oe.CONTRIB_DEBOUNCE_MS+(t?Oe.CONTRIB_ACTIVE_EDITOR_BONUS_MS:0),s=setTimeout(()=>{if(this.contribTimers.delete(r.path),this.isFileActivelyEdited(r)){this.scheduleContribution(r);return}let n=this.lastExternalModify.get(r.path);if(n!==void 0&&Date.now()-n<Oe.EXTERNAL_QUIESCENCE_MS){this.scheduleContribution(r);return}this.maybeRecordContribution(r)},i);this.contribTimers.set(r.path,s)}isFileActivelyEdited(r){try{let e=this.host.app.workspace.activeLeaf;if(!e)return!1;let t=e.view;if(!t||t.getViewType?.()!=="markdown"||t.file?.path!==r.path)return!1;let i=t.containerEl??null;return!!i&&i.contains(document.activeElement)}catch{return!1}}async maybeRecordContribution(r){let e="";try{e=await this.host.app.vault.cachedRead(r)}catch{return}let t=this.host.stripFrontmatter(e),i=this.knownBodies.get(r.path);if(this.knownBodies.set(r.path,t),i===void 0||i===t||this.host.plugin.rebootstrapInProgress)return;let s=this.currentAuthorLink();if(!s)return;this.ensureAuthorFile(s);let n=new Date().toISOString();this.recentSelfWrites.set(r.path,Date.now());try{await this.host.app.fileManager.processFrontMatter(r,o=>{o.modified=n;let a=typeof o.author=="string"?o.author:"",l=Array.isArray(o.contributors)?o.contributors.filter(p=>typeof p=="string"):[],c=`-${s.id}`,d=a.includes(c),h=l.some(p=>p.includes(c));!d&&!h&&l.push(s.link),o.contributors=l})}catch(o){console.warn("[Stashpad] maybeRecordContribution failed",o)}}};Oe.CONTRIB_DEBOUNCE_MS=4e3,Oe.CONTRIB_ACTIVE_EDITOR_BONUS_MS=2e3,Oe.EXTERNAL_WRITE_GRACE_MS=1500,Oe.EXTERNAL_QUIESCENCE_MS=5e3;var Un=Oe;var Ln=class{constructor(r){this.host=r;this.dragSourceIds=null;this.dragPlaceholder=null;this.dragRowHeight=0}attachRowDnD(r,e,t){r.addEventListener("dragstart",i=>{let s=this.host.selection.has(e.id)&&this.host.selection.size>1?[...this.host.selection]:[e.id];if(this.dragSourceIds=s,this.dragRowHeight=r.offsetHeight,r.addClass("is-dragging"),this.host.listEl&&(this.dragPlaceholder=this.host.listEl.createDiv({cls:"stashpad-drop-placeholder"}),this.dragPlaceholder.setCssStyles({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,l=this.dragPlaceholder.previousElementSibling;this.removeDragPlaceholder();let c,d="before";a&&a.classList.contains("stashpad-note")?(c=a.dataset.id,d="before"):l&&l.classList.contains("stashpad-note")&&(c=l.dataset.id,d="after"),c&&this.host.reorderToTarget(o,c,d)}),this.dragPlaceholder.remove()),i.dataTransfer?.setData("text/plain",s.join(",")),i.dataTransfer){i.dataTransfer.effectAllowed="move";try{i.dataTransfer.setDragImage(r,12,12)}catch{}}}),r.addEventListener("dragend",()=>{r.removeClass("is-dragging"),this.clearDropIndicators(),this.removeDragPlaceholder(),this.dragSourceIds=null}),r.addEventListener("dragover",i=>{if(!this.dragSourceIds)return;i.preventDefault(),i.dataTransfer&&(i.dataTransfer.dropEffect="move");let s=this.dropZone(i,r);this.clearDropIndicators(),s==="drop-into"?(this.removeDragPlaceholder(),r.addClass("drop-into")):(r.removeClass("drop-into"),this.placePlaceholder(r,s==="drop-above"?"before":"after"))}),r.addEventListener("dragleave",i=>{let s=r.getBoundingClientRect();(i.clientX<s.left||i.clientX>s.right||i.clientY<s.top||i.clientY>s.bottom)&&r.removeClass("drop-into")}),r.addEventListener("drop",i=>{if(!this.dragSourceIds)return;i.preventDefault(),i.stopPropagation();let s=this.dragSourceIds.slice();this.dragSourceIds=null;let n=this.dropZone(i,r);this.clearDropIndicators(),this.removeDragPlaceholder(),r.removeClass("is-dragging"),n==="drop-into"?this.host.reorderToTarget(s,e.id,"into"):this.host.reorderToTarget(s,e.id,n==="drop-above"?"before":"after")})}attachListDnD(r){r.addEventListener("dragover",e=>{if(!this.dragSourceIds)return;let t=e.target;if(t&&t.closest&&t.closest(".stashpad-note"))return;e.preventDefault(),e.dataTransfer&&(e.dataTransfer.dropEffect="move");let i=Array.from(r.querySelectorAll(".stashpad-note"));if(i.length!==0){for(let s of i){let n=s.getBoundingClientRect();if(e.clientY<n.top+n.height/2){this.placePlaceholder(s,"before");return}}this.placePlaceholder(i[i.length-1],"after")}}),r.addEventListener("drop",e=>{if(!this.dragSourceIds)return;e.preventDefault();let t=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(t,n,"before")}else if(s&&s.classList.contains("stashpad-note")){let n=s.dataset.id;n&&this.host.reorderToTarget(t,n,"after")}})}placePlaceholder(r,e){if(!this.dragPlaceholder||!this.host.listEl)return;let t=e==="before"?r:r.nextSibling;if(e==="before"&&this.dragPlaceholder.nextSibling===r||e==="after"&&this.dragPlaceholder.previousSibling===r)return;let i=!!this.dragPlaceholder.parentElement;this.host.listEl.insertBefore(this.dragPlaceholder,t),this.dragPlaceholder.setCssStyles({opacity:"1"}),i?this.dragPlaceholder.setCssStyles({height:`${this.dragRowHeight}px`}):(this.dragPlaceholder.setCssStyles({height:"0px"}),this.dragPlaceholder.offsetHeight,this.dragPlaceholder.setCssStyles({height:`${this.dragRowHeight}px`}))}removeDragPlaceholder(){if(!this.dragPlaceholder?.parentElement)return;let r=this.dragPlaceholder;r.setCssStyles({height:"0px",opacity:"0"}),setTimeout(()=>{r.parentElement&&r.remove()},150)}dropZone(r,e){let t=e.getBoundingClientRect(),i=r.clientY-t.top;return i<t.height*.3?"drop-above":i>t.height*.7?"drop-below":"drop-into"}clearDropIndicators(){if(this.host.listEl)for(let r of Array.from(this.host.listEl.querySelectorAll(".drop-into")))r.removeClass("drop-into")}};var da=require("obsidian");var Gn=class{constructor(r,e,t){this.host=r;this.component=e;this.bodyObserver=null;this.lazyBodies=new WeakMap;this.renderCache=t??new Map}async getOrComputeRender(r){let e=this.renderCache.get(r.path);if(e&&e.mtime===r.stat.mtime)return Te.record("render.row.cacheHit",0),e;let t=await Te.timeAsync("render.row.read",()=>this.host.app.vault.cachedRead(r)),i=this.host.stripFrontmatter(t),{text:s,attachments:n}=this.splitAttachments(i),o=createDiv({cls:"stashpad-note-text"});await Te.timeAsync("render.row.markdown",()=>da.MarkdownRenderer.render(this.host.app,s,o,r.path,this.component));let a=o.innerHTML,l={mtime:r.stat.mtime,text:s,attachments:n,html:a};return this.renderCache.set(r.path,l),l}async primeRender(r,e){try{let{text:t,attachments:i}=this.splitAttachments(this.host.stripFrontmatter(e)),s=createDiv({cls:"stashpad-note-text"});await da.MarkdownRenderer.render(this.host.app,t,s,r.path,this.component);let n={mtime:r.stat.mtime,text:t,attachments:i,html:s.innerHTML};this.renderCache.set(r.path,n)}catch(t){console.warn("[Stashpad] primeRender failed",t)}}arm(){this.bodyObserver?.disconnect(),this.lazyBodies=new WeakMap,this.bodyObserver=new IntersectionObserver(r=>{for(let e of r){if(!e.isIntersecting)continue;let t=e.target,i=this.lazyBodies.get(t);this.bodyObserver?.unobserve(t),this.lazyBodies.delete(t),i&&i()}},{root:this.host.contentEl,rootMargin:"1400px 0px"})}dispose(){this.bodyObserver?.disconnect(),this.bodyObserver=null}isArmed(){return!!this.bodyObserver}hasFreshRenderCache(r){let e=this.renderCache.get(r.path);return!!e&&e.mtime===r.stat.mtime}peekCache(r){return this.renderCache.get(r.path)}evict(r){let e=this.renderCache;e.evict?e.evict(r.path):e.delete&&e.delete(r.path)}retagMtime(r,e){let t=this.renderCache.get(r);t&&t.mtime!==e&&this.renderCache.set(r,{...t,mtime:e})}defer(r,e){this.lazyBodies.set(r,e),this.bodyObserver?.observe(r)}splitAttachments(r){let e=[];return{text:r.replace(/!\[\[([^\]\|]+)(?:\|[^\]]+)?\]\]/g,(i,s)=>(e.push(s),"")).replace(/\n{3,}/g,` -`).trim(),attachments:e}}};function nl(d,r,e){return d.tree.getChildren(r).slice().sort((i,s)=>pd(d,i,s,e)).map(i=>i.id)}function pd(d,r,e,t){switch(t){case"created-asc":return(r.created||"").localeCompare(e.created||"");case"created-desc":return(e.created||"").localeCompare(r.created||"");case"modified-asc":case"modified-desc":{let i=sl(d,r)||r.created||"",s=sl(d,e)||e.created||"";return t==="modified-asc"?i.localeCompare(s):s.localeCompare(i)}case"title-az":case"title-za":{let i=d.titleForNode(r),s=d.titleForNode(e),n={numeric:!0,sensitivity:"base"};return t==="title-az"?i.localeCompare(s,void 0,n):s.localeCompare(i,void 0,n)}default:return 0}}function sl(d,r){if(!r.file)return"";let e=d.app.metadataCache.getFileCache(r.file)?.frontmatter;return(typeof e?.modified=="string"?e.modified:"")||""}var Ri=require("obsidian");Qi();Zi();async function la(d){let r=d.getActionTargets();if(!r.length)return;let e=X().prefixTimestampsOnCopy,t=[];for(let s of r){if(!s.file)continue;let n=await d.app.vault.cachedRead(s.file),o=d.stripFrontmatter(n).trim(),{needsDash:a,checkbox:l,meta:c}=d.copyMetaPrefix(s),A=`${a?"- ":""}${l}${c}`,h=e?`${d.formatTimeInline(s.created)} `:"";t.push(`${A}${h}${o}`)}let i=t[0]??"";for(let s=1;s<t.length;s++){let n=t[s-1].includes(` +`).trim(),attachments:e}}};function rl(A,r,e){return A.tree.getChildren(r).slice().sort((i,s)=>Id(A,i,s,e)).map(i=>i.id)}function Id(A,r,e,t){switch(t){case"created-asc":return(r.created||"").localeCompare(e.created||"");case"created-desc":return(e.created||"").localeCompare(r.created||"");case"modified-asc":case"modified-desc":{let i=al(A,r)||r.created||"",s=al(A,e)||e.created||"";return t==="modified-asc"?i.localeCompare(s):s.localeCompare(i)}case"title-az":case"title-za":{let i=A.titleForNode(r),s=A.titleForNode(e),n={numeric:!0,sensitivity:"base"};return t==="title-az"?i.localeCompare(s,void 0,n):s.localeCompare(i,void 0,n)}default:return 0}}function al(A,r){if(!r.file)return"";let e=A.app.metadataCache.getFileCache(r.file)?.frontmatter;return(typeof e?.modified=="string"?e.modified:"")||""}var Ui=require("obsidian");ki();_i();async function Aa(A){let r=A.getActionTargets();if(!r.length)return;let e=X().prefixTimestampsOnCopy,t=[];for(let s of r){if(!s.file)continue;let n=await A.app.vault.cachedRead(s.file),o=A.stripFrontmatter(n).trim(),{needsDash:a,checkbox:l,meta:c}=A.copyMetaPrefix(s),d=`${a?"- ":""}${l}${c}`,h=e?`${A.formatTimeInline(s.created)} `:"";t.push(`${d}${h}${o}`)}let i=t[0]??"";for(let s=1;s<t.length;s++){let n=t[s-1].includes(` `)||t[s].includes(` `)?` `:` -`;i+=n+t[s]}await navigator.clipboard.writeText(i),d.plugin.notifications.show({message:`Copied ${d.titleList(r)} to clipboard`,kind:"success",category:"system",affectedIds:r.map(s=>s.id),folder:d.noteFolder})}async function ol(d){let r=d.getActionTargets();if(!r.length||!r[0].file){new Ri.Notice("Nothing to copy from.");return}let e=r[0],t=await d.app.vault.cachedRead(e.file),i=d.stripFrontmatter(t),s=er(i);if(s.length===0){d.plugin.notifications.show({message:`No codeblock found in "${d.titleForNode(e)}".`,kind:"info",category:"system",affectedIds:[e.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(e)}".`,kind:"success",category:"system",affectedIds:[e.id],folder:d.noteFolder});return}let n=s.map((a,l)=>({kind:"one",idx:l,label:`${l+1}. ${a.lang||"(no language)"} \u2014 ${a.code.split(` +`;i+=n+t[s]}await navigator.clipboard.writeText(i),A.plugin.notifications.show({message:`Copied ${A.titleList(r)} to clipboard`,kind:"success",category:"system",affectedIds:r.map(s=>s.id),folder:A.noteFolder})}async function ll(A){let r=A.getActionTargets();if(!r.length||!r[0].file){new Ui.Notice("Nothing to copy from.");return}let e=r[0],t=await A.app.vault.cachedRead(e.file),i=A.stripFrontmatter(t),s=sr(i);if(s.length===0){A.plugin.notifications.show({message:`No codeblock found in "${A.titleForNode(e)}".`,kind:"info",category:"system",affectedIds:[e.id],folder:A.noteFolder});return}if(s.length===1){await navigator.clipboard.writeText(s[0].code),A.plugin.notifications.show({message:`Copied codeblock${s[0].lang?` (${s[0].lang})`:""} from "${A.titleForNode(e)}".`,kind:"success",category:"system",affectedIds:[e.id],folder:A.noteFolder});return}let n=s.map((a,l)=>({kind:"one",idx:l,label:`${l+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 Ri.SuggestModal{getSuggestions(a){let l=a.trim().toLowerCase();if(!l)return n;let c=l.split(/\s+/).filter(Boolean);return n.filter(A=>{let h=A.label.toLowerCase();return c.every(p=>h.includes(p))})}renderSuggestion(a,l){l.createDiv({cls:"stashpad-suggest-title",text:a.label})}async onChooseSuggestion(a){let l=a.kind==="all"?s.map(c=>c.code).join(` +`)?"\u2026":""}`}));n.push({kind:"all",idx:-1,label:`Copy all ${s.length} blocks (joined with blank lines)`});let o=new class extends Ui.SuggestModal{getSuggestions(a){let l=a.trim().toLowerCase();if(!l)return n;let c=l.split(/\s+/).filter(Boolean);return n.filter(d=>{let h=d.label.toLowerCase();return c.every(p=>h.includes(p))})}renderSuggestion(a,l){l.createDiv({cls:"stashpad-suggest-title",text:a.label})}async onChooseSuggestion(a){let l=a.kind==="all"?s.map(c=>c.code).join(` -`):s[a.idx].code;await navigator.clipboard.writeText(l),d.plugin.notifications.show({message:a.kind==="all"?`Copied all ${s.length} codeblocks from "${d.titleForNode(e)}".`:`Copied codeblock${s[a.idx].lang?` (${s[a.idx].lang})`:""} from "${d.titleForNode(e)}".`,kind:"success",category:"system",affectedIds:[e.id],folder:d.noteFolder})}}(d.app);o.setPlaceholder(`${s.length} codeblocks in "${d.titleForNode(e)}" \u2014 pick one to copy.`),o.open()}async function al(d){let r=d.getActionTargets();if(r.length===0){let n=d.tree.get(d.focusId);n?.file&&(r=[n])}if(r.length===0){new Ri.Notice("Nothing to copy.");return}let e=X().prefixTimestampsOnCopy,t=[],i=async(n,o)=>{if(n.file){let a=await d.app.vault.cachedRead(n.file),l=d.stripFrontmatter(a).trim().split(/\r?\n/).join(" "),c=e?`${d.formatTimeInline(n.created)} `:"",{checkbox:A,meta:h}=d.copyMetaPrefix(n);t.push(`${" ".repeat(o)}- ${A}${h}${c}${l}`)}for(let a of d.tree.getChildren(n.id))await i(a,o+1)};for(let n of r)await i(n,0);let s=t.join(` -`);await navigator.clipboard.writeText(s),d.plugin.clearNoteClipboard(),d.plugin.noteClipboard={mode:"copy",folder:d.noteFolder,ids:r.map(n=>n.id),text:s},d.render(),d.plugin.notifications.show({message:`Copied tree of ${d.titleList(r)} (${t.length} entries) \u2014 paste in the list to clone, in a note to drop the outline in`,kind:"success",category:"system",affectedIds:r.map(n=>n.id),folder:d.noteFolder})}async function rl(d){let r=d.getActionTargets();if(r.length===0){let i=d.tree.get(d.focusId);i?.file&&(r=[i])}if(r.length===0){new Ri.Notice("Nothing to copy.");return}let e=[],t=(i,s)=>{if(!i.file)return;let n=" ".repeat(s),{checkbox:o,meta:a}=d.copyMetaPrefix(i);e.push(`${n}- ${o}${a}![[${i.file.basename}]]`);for(let l of d.tree.getChildren(i.id))t(l,s+1)};for(let i of r)t(i,0);await navigator.clipboard.writeText(e.join(` -`)),d.plugin.notifications.show({message:`Copied outline of ${d.titleList(r)} (${e.length} entr${e.length===1?"y":"ies"})`,kind:"success",category:"system",affectedIds:r.map(i=>i.id),folder:d.noteFolder})}var Me=require("obsidian");ce();var Jn=require("obsidian");qn();pt();ce();var ct="stash",Sl=1;function wa(d){let e=(d.split(/[\\/]/).pop()??"").trim();return!e||e==="."||e===".."||e.includes("/")||e.includes("\\")||e.includes("..")?"":e}var Ea=/!\[\[([^\]\|]+)(?:\|[^\]]+)?\]\]/g;async function vt(d,r){let e=[],t=Rd([...r.rootNotes,...r.allDescendants]),i=new Map,s=[];for(let o of t){let a=await d.vault.read(o.file),l=a,c=va(a);for(let A of c){let h=d.metadataCache.getFirstLinkpathDest(A,o.file.path);if(!h){s.push(`Missing attachment "${A}" in ${o.file.path}`);continue}let p=h.name;i.has(p)||i.set(p,await d.vault.readBinary(h)),l=Dl(l,A,p)}l=xl(l,d,o.file.path),e.push({name:`notes/${o.file.name}`,data:l})}for(let[o,a]of i)e.push({name:`attachments/${o}`,data:a});let n={stashSchema:Sl,exportedAt:new Date().toISOString(),sourceFolder:r.sourceFolder,noteCount:t.length,rootIds:r.rootNotes.map(o=>o.id)};return e.push({name:"manifest.json",data:JSON.stringify(n,null,2)}),s.length&&e.push({name:"warnings.txt",data:s.join(` -`)}),Ui(e,6)}async function bl(d,r,e){let t=[],i=new Map,s=[],n=new Set;for(let o of r){let a=await d.vault.read(o.file);if(e!=="frontmatter"){for(let A of va(a)){let h=d.metadataCache.getFirstLinkpathDest(A,o.file.path);if(!h){s.push(`Missing attachment "${A}" in ${o.file.path}`);continue}let p=h.name;i.has(p)||i.set(p,await d.vault.readBinary(h)),a=Dl(a,A,p)}a=xl(a,d,o.file.path)}let l=Kd(a,e),c=o.file.name;for(;n.has(c);)c=`${o.file.basename}-${he(4)}.md`;n.add(c),t.push({name:`notes/${c}`,data:l})}for(let[o,a]of i)t.push({name:`attachments/${o}`,data:a});return s.length&&t.push({name:"warnings.txt",data:s.join(` -`)}),Ui(t,6)}async function We(d,r,e,t,i={}){let s=await Li(r),n=s["manifest.json"];if(!n)throw new Error("Not a valid .stash package: missing manifest.json");let o=JSON.parse(Kn(n));if(typeof o.stashSchema!="number"||o.stashSchema>Sl)throw new Error(`Unsupported .stash schema: v${o.stashSchema}`);await kl(d,e);let a=Object.entries(s).filter(([v])=>v.startsWith("notes/")&&v.endsWith(".md")),l=[];for(let[v,Q]of a){let w=Kn(Q),{fm:F,body:D}=ge(w),H=wa(v.slice(6))||wa(`${F.id||"imported-"+he(4)}.md`)||`imported-${he(4)}.md`;l.push({originalName:H,fm:F,body:D})}let c=new Map,A=0;for(let v of l){let Q=v.fm.id;Q&&(i.forceNewIds?c.set(Q,he(6)):t.has(Q)||c.has(Q)?(c.set(Q,`${Q}-${he(4)}-Imported`),A++):c.set(Q,Q))}let h=new Date().toISOString(),p=[],f=`${e}/_attachments`,u=0,g=Object.entries(s).filter(([v])=>v.startsWith("attachments/")),I=new Map,m=null;if(i.dedupeExisting){m=new Map;for(let v of d.vault.getFiles())m.has(v.name)||m.set(v.name,v.path)}let C=(v,Q)=>{if(v.length!==Q.length)return!1;for(let w=0;w<v.length;w++)if(v[w]!==Q[w])return!1;return!0},B=!1;for(let[v,Q]of g){let w=wa(v.slice(12));if(!w)continue;let F=Q,D=[],H=m?.get(w);H&&D.push(H);let R=`${f}/${w}`;await d.vault.adapter.exists(R)&&D.push(R);let L=null;for(let U of D)try{if(C(new Uint8Array(await d.vault.adapter.readBinary(U)),F)){L=U;break}}catch{}if(L){I.set(w,L);continue}let x=R;for(let U=1;await d.vault.adapter.exists(x);U++)x=`${f}/${Ud(w,U)}`;I.set(w,x),B||(await kl(d,f),B=!0),await d.vault.createBinary(x,F.buffer),u++}let E=0;for(let v of l){let Q=v.fm.id;if(!Q){p.push(`Skipped ${v.originalName} \u2014 no id in frontmatter`);continue}let w=c.get(Q),F=v.fm.parent??null,D=F;!F||F===S?D=i.reparentRootsTo??F??S:c.has(F)?D=c.get(F):D=t.has(F)?F:i.reparentRootsTo??S;let H=Ld(v.body,I,f),R=v.fm;if(i.stripReserved){let b={};for(let[M,O]of Object.entries(v.fm))et.includes(M)||(b[M]=O);v.fm.author!==void 0&&(b.author=v.fm.author),v.fm.contributors!==void 0&&(b.contributors=v.fm.contributors),v.fm.created!==void 0&&(b.created=v.fm.created),v.fm.modified!==void 0&&(b.modified=v.fm.modified),Array.isArray(v.fm.attachments)&&(b.attachments=v.fm.attachments),R=b}let L={...R,id:w,parent:D,import_date:h};Array.isArray(L.attachments)&&(L.attachments=L.attachments.map(b=>{let M=Nl(Jt(b));return tt(I.get(M)??`${f}/${M}`)}));let x=Ot(L,H),U=w===Q?v.originalName:Od(v.originalName,Q,w),T=`${e}/${U}`;await d.vault.adapter.exists(T)&&(U=`${U.replace(/\.md$/,"")}-${he(4)}.md`,T=`${e}/${U}`),await d.vault.create(T,x),E++}let y;if(o.colorAliases&&typeof o.colorAliases=="object"){let v={};for(let[Q,w]of Object.entries(o.colorAliases)){let F=String(Q).trim().toLowerCase(),D=String(w??"").trim();/^#([0-9a-f]{6})$/.test(F)&&D&&(v[F]=D.slice(0,60))}Object.keys(v).length&&(y=v)}return{notesWritten:E,attachmentsWritten:u,collisionsRenamed:A,warnings:p,colorAliases:y,idRemap:Object.fromEntries(c)}}function Rd(d){let r=new Set,e=[];for(let t of d)r.has(t.id)||(r.add(t.id),e.push(t));return e}function va(d){let r=new Set,e;for(Ea.lastIndex=0;(e=Ea.exec(d))!==null;)r.add(e[1]);return[...r]}async function ii(d,r){let e=await d.vault.read(r),t=[],i=new Set;for(let s of va(e)){let n=d.metadataCache.getFirstLinkpathDest(s,r.path);n&&!i.has(n.path)&&(i.add(n.path),t.push(n))}return t}function Dl(d,r,e){return d.replace(new RegExp(`!\\[\\[${Gd(r)}(\\|[^\\]]+)?\\]\\]`,"g"),(t,i)=>`![[${e}${i??""}]]`)}function Ud(d,r){let e=d.lastIndexOf(".");return e>0?`${d.slice(0,e)}-${r}${d.slice(e)}`:`${d}-${r}`}function Ld(d,r,e){return d.replace(Ea,(t,i,s)=>{if(i.includes("/"))return t;let n=r.get(i)??`${e}/${i}`;return t.replace(i,n)})}function xl(d,r,e){let t=ge(d);if(!t.fm.attachments||!Array.isArray(t.fm.attachments))return d;let i=t.fm.attachments.map(n=>{let o=r.metadataCache.getFirstLinkpathDest(n,e);return o?o.name:Nl(n)}),s={...t.fm,attachments:i};return Ot(s,t.body)}function Gd(d){return d.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Nl(d){let r=d.lastIndexOf("/");return r<0?d:d.slice(r+1)}function Od(d,r,e){return d.includes(r)?d.replace(r,e):d.replace(/\.md$/,`-${e}.md`)}function ge(d){if(!d.startsWith("---"))return{fm:{},body:d};let r=d.indexOf(` ----`,3);if(r<0)return{fm:{},body:d};let e=d.slice(3,r).replace(/^\n/,""),t=d.slice(r+4),i={};try{i=(0,Jn.parseYaml)(e)??{}}catch{i={}}let s=t.startsWith(` -`)?t.slice(1):t;return{fm:i,body:s}}function Ot(d,r){return`--- -${(0,Jn.stringifyYaml)(d).trimEnd()} +`):s[a.idx].code;await navigator.clipboard.writeText(l),A.plugin.notifications.show({message:a.kind==="all"?`Copied all ${s.length} codeblocks from "${A.titleForNode(e)}".`:`Copied codeblock${s[a.idx].lang?` (${s[a.idx].lang})`:""} from "${A.titleForNode(e)}".`,kind:"success",category:"system",affectedIds:[e.id],folder:A.noteFolder})}}(A.app);o.setPlaceholder(`${s.length} codeblocks in "${A.titleForNode(e)}" \u2014 pick one to copy.`),o.open()}async function cl(A){let r=A.getActionTargets();if(r.length===0){let n=A.tree.get(A.focusId);n?.file&&(r=[n])}if(r.length===0){new Ui.Notice("Nothing to copy.");return}let e=X().prefixTimestampsOnCopy,t=[],i=async(n,o)=>{if(n.file){let a=await A.app.vault.cachedRead(n.file),l=A.stripFrontmatter(a).trim().split(/\r?\n/).join(" "),c=e?`${A.formatTimeInline(n.created)} `:"",{checkbox:d,meta:h}=A.copyMetaPrefix(n);t.push(`${" ".repeat(o)}- ${d}${h}${c}${l}`)}for(let a of A.tree.getChildren(n.id))await i(a,o+1)};for(let n of r)await i(n,0);let s=t.join(` +`);await navigator.clipboard.writeText(s),A.plugin.clearNoteClipboard(),A.plugin.noteClipboard={mode:"copy",folder:A.noteFolder,ids:r.map(n=>n.id),text:s},A.render(),A.plugin.notifications.show({message:`Copied tree of ${A.titleList(r)} (${t.length} entries) \u2014 paste in the list to clone, in a note to drop the outline in`,kind:"success",category:"system",affectedIds:r.map(n=>n.id),folder:A.noteFolder})}async function dl(A){let r=A.getActionTargets();if(r.length===0){let i=A.tree.get(A.focusId);i?.file&&(r=[i])}if(r.length===0){new Ui.Notice("Nothing to copy.");return}let e=[],t=(i,s)=>{if(!i.file)return;let n=" ".repeat(s),{checkbox:o,meta:a}=A.copyMetaPrefix(i);e.push(`${n}- ${o}${a}![[${i.file.basename}]]`);for(let l of A.tree.getChildren(i.id))t(l,s+1)};for(let i of r)t(i,0);await navigator.clipboard.writeText(e.join(` +`)),A.plugin.notifications.show({message:`Copied outline of ${A.titleList(r)} (${e.length} entr${e.length===1?"y":"ies"})`,kind:"success",category:"system",affectedIds:r.map(i=>i.id),folder:A.noteFolder})}var Me=require("obsidian");ce();var Yn=require("obsidian");$n();pt();ce();var ct="stash",xl=1;function Qa(A){let e=(A.split(/[\\/]/).pop()??"").trim();return!e||e==="."||e===".."||e.includes("/")||e.includes("\\")||e.includes("..")?"":e}var ka=/!\[\[([^\]\|]+)(?:\|[^\]]+)?\]\]/g;async function vt(A,r){let e=[],t=Od([...r.rootNotes,...r.allDescendants]),i=new Map,s=[];for(let o of t){let a=await A.vault.read(o.file),l=a,c=Fa(a);for(let d of c){let h=A.metadataCache.getFirstLinkpathDest(d,o.file.path);if(!h){s.push(`Missing attachment "${d}" in ${o.file.path}`);continue}let p=h.name;i.has(p)||i.set(p,await A.vault.readBinary(h)),l=Tl(l,d,p)}l=Ml(l,A,o.file.path),e.push({name:`notes/${o.file.name}`,data:l})}for(let[o,a]of i)e.push({name:`attachments/${o}`,data:a});let n={stashSchema:xl,exportedAt:new Date().toISOString(),sourceFolder:r.sourceFolder,noteCount:t.length,rootIds:r.rootNotes.map(o=>o.id)};return e.push({name:"manifest.json",data:JSON.stringify(n,null,2)}),s.length&&e.push({name:"warnings.txt",data:s.join(` +`)}),Li(e,6)}async function Nl(A,r,e){let t=[],i=new Map,s=[],n=new Set;for(let o of r){let a=await A.vault.read(o.file);if(e!=="frontmatter"){for(let d of Fa(a)){let h=A.metadataCache.getFirstLinkpathDest(d,o.file.path);if(!h){s.push(`Missing attachment "${d}" in ${o.file.path}`);continue}let p=h.name;i.has(p)||i.set(p,await A.vault.readBinary(h)),a=Tl(a,d,p)}a=Ml(a,A,o.file.path)}let l=Yd(a,e),c=o.file.name;for(;n.has(c);)c=`${o.file.basename}-${he(4)}.md`;n.add(c),t.push({name:`notes/${c}`,data:l})}for(let[o,a]of i)t.push({name:`attachments/${o}`,data:a});return s.length&&t.push({name:"warnings.txt",data:s.join(` +`)}),Li(t,6)}async function We(A,r,e,t,i={}){let s=await Gi(r),n=s["manifest.json"];if(!n)throw new Error("Not a valid .stash package: missing manifest.json");let o=JSON.parse(qn(n));if(typeof o.stashSchema!="number"||o.stashSchema>xl)throw new Error(`Unsupported .stash schema: v${o.stashSchema}`);await Dl(A,e);let a=Object.entries(s).filter(([v])=>v.startsWith("notes/")&&v.endsWith(".md")),l=[];for(let[v,Q]of a){let w=qn(Q),{fm:k,body:D}=ge(w),H=Qa(v.slice(6))||Qa(`${k.id||"imported-"+he(4)}.md`)||`imported-${he(4)}.md`;l.push({originalName:H,fm:k,body:D})}let c=new Map,d=0;for(let v of l){let Q=v.fm.id;Q&&(i.forceNewIds?c.set(Q,he(6)):t.has(Q)||c.has(Q)?(c.set(Q,`${Q}-${he(4)}-Imported`),d++):c.set(Q,Q))}let h=new Date().toISOString(),p=[],f=`${e}/_attachments`,u=0,g=Object.entries(s).filter(([v])=>v.startsWith("attachments/")),I=new Map,m=null;if(i.dedupeExisting){m=new Map;for(let v of A.vault.getFiles())m.has(v.name)||m.set(v.name,v.path)}let C=(v,Q)=>{if(v.length!==Q.length)return!1;for(let w=0;w<v.length;w++)if(v[w]!==Q[w])return!1;return!0},B=!1;for(let[v,Q]of g){let w=Qa(v.slice(12));if(!w)continue;let k=Q,D=[],H=m?.get(w);H&&D.push(H);let R=`${f}/${w}`;await A.vault.adapter.exists(R)&&D.push(R);let L=null;for(let U of D)try{if(C(new Uint8Array(await A.vault.adapter.readBinary(U)),k)){L=U;break}}catch{}if(L){I.set(w,L);continue}let x=R;for(let U=1;await A.vault.adapter.exists(x);U++)x=`${f}/${Kd(w,U)}`;I.set(w,x),B||(await Dl(A,f),B=!0),await A.vault.createBinary(x,k.buffer),u++}let E=0;for(let v of l){let Q=v.fm.id;if(!Q){p.push(`Skipped ${v.originalName} \u2014 no id in frontmatter`);continue}let w=c.get(Q),k=v.fm.parent??null,D=k;!k||k===S?D=i.reparentRootsTo??k??S:c.has(k)?D=c.get(k):D=t.has(k)?k:i.reparentRootsTo??S;let H=Jd(v.body,I,f),R=v.fm;if(i.stripReserved){let b={};for(let[M,O]of Object.entries(v.fm))et.includes(M)||(b[M]=O);v.fm.author!==void 0&&(b.author=v.fm.author),v.fm.contributors!==void 0&&(b.contributors=v.fm.contributors),v.fm.created!==void 0&&(b.created=v.fm.created),v.fm.modified!==void 0&&(b.modified=v.fm.modified),Array.isArray(v.fm.attachments)&&(b.attachments=v.fm.attachments),R=b}let L={...R,id:w,parent:D,import_date:h};Array.isArray(L.attachments)&&(L.attachments=L.attachments.map(b=>{let M=Pl(qt(b));return tt(I.get(M)??`${f}/${M}`)}));let x=Ot(L,H),U=w===Q?v.originalName:$d(v.originalName,Q,w),T=`${e}/${U}`;await A.vault.adapter.exists(T)&&(U=`${U.replace(/\.md$/,"")}-${he(4)}.md`,T=`${e}/${U}`),await A.vault.create(T,x),E++}let y;if(o.colorAliases&&typeof o.colorAliases=="object"){let v={};for(let[Q,w]of Object.entries(o.colorAliases)){let k=String(Q).trim().toLowerCase(),D=String(w??"").trim();/^#([0-9a-f]{6})$/.test(k)&&D&&(v[k]=D.slice(0,60))}Object.keys(v).length&&(y=v)}return{notesWritten:E,attachmentsWritten:u,collisionsRenamed:d,warnings:p,colorAliases:y,idRemap:Object.fromEntries(c)}}function Od(A){let r=new Set,e=[];for(let t of A)r.has(t.id)||(r.add(t.id),e.push(t));return e}function Fa(A){let r=new Set,e;for(ka.lastIndex=0;(e=ka.exec(A))!==null;)r.add(e[1]);return[...r]}async function ii(A,r){let e=await A.vault.read(r),t=[],i=new Set;for(let s of Fa(e)){let n=A.metadataCache.getFirstLinkpathDest(s,r.path);n&&!i.has(n.path)&&(i.add(n.path),t.push(n))}return t}function Tl(A,r,e){return A.replace(new RegExp(`!\\[\\[${qd(r)}(\\|[^\\]]+)?\\]\\]`,"g"),(t,i)=>`![[${e}${i??""}]]`)}function Kd(A,r){let e=A.lastIndexOf(".");return e>0?`${A.slice(0,e)}-${r}${A.slice(e)}`:`${A}-${r}`}function Jd(A,r,e){return A.replace(ka,(t,i,s)=>{if(i.includes("/"))return t;let n=r.get(i)??`${e}/${i}`;return t.replace(i,n)})}function Ml(A,r,e){let t=ge(A);if(!t.fm.attachments||!Array.isArray(t.fm.attachments))return A;let i=t.fm.attachments.map(n=>{let o=r.metadataCache.getFirstLinkpathDest(n,e);return o?o.name:Pl(n)}),s={...t.fm,attachments:i};return Ot(s,t.body)}function qd(A){return A.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Pl(A){let r=A.lastIndexOf("/");return r<0?A:A.slice(r+1)}function $d(A,r,e){return A.includes(r)?A.replace(r,e):A.replace(/\.md$/,`-${e}.md`)}function ge(A){if(!A.startsWith("---"))return{fm:{},body:A};let r=A.indexOf(` +---`,3);if(r<0)return{fm:{},body:A};let e=A.slice(3,r).replace(/^\n/,""),t=A.slice(r+4),i={};try{i=(0,Yn.parseYaml)(e)??{}}catch{i={}}let s=t.startsWith(` +`)?t.slice(1):t;return{fm:i,body:s}}function Ot(A,r){return`--- +${(0,Yn.stringifyYaml)(A).trimEnd()} --- -${r}`}function Kd(d,r){if(r==="full")return d;let e=d.match(/^\uFEFF?---\r?\n[\s\S]*?\r?\n---[ \t]*(?:\r?\n|$)/);return r==="frontmatter"?e?e[0]:"":e?d.slice(e[0].length).replace(/^\s*\n/,""):d}async function kl(d,r){if(!(!r||await d.vault.adapter.exists(r)))try{await d.vault.createFolder(r)}catch(t){let i=t?.message??"";if(!/already exists/i.test(i))throw t}}Wt();Ys();ve();Wt();qn();var dt="stashenc",Tl="stashmeta",ks="stashpack";function qe(d){return d.replace(/\.(stashenc|stashpack)$/,`.${Tl}`)}async function zn(d,r){try{return JSON.parse(await d.vault.adapter.read(qe(r)))}catch{return null}}async function Qt(d,r,e){let t=r.replace(/\/+$/,""),i=[];for(let c of d.vault.getMarkdownFiles()){if((c.parent?.path?.replace(/\/+$/,"")??"")!==t)continue;let A;try{A=ge(await d.vault.read(c)).fm}catch{continue}typeof A.id=="string"&&i.push({id:A.id,file:c,parent:typeof A.parent=="string"?A.parent:null,created:typeof A.created=="string"?A.created:""})}let s=i.find(c=>c.id===e);if(!s)return null;let n=new Map;for(let c of i){if(!c.parent)continue;let A=n.get(c.parent)??[];A.push(c),n.set(c.parent,A)}let o=[],a=new Set([e]),l=[e];for(;l.length;){let c=[];for(let A of l)for(let h of n.get(A)??[])a.has(h.id)||(a.add(h.id),o.push(h),c.push(h.id));l=c}return{rootNote:s,descendants:o,parentId:s.parent}}function $n(d){if(!d)return null;let r=d.replace(/\/+$/,"");return!r||r.startsWith("/")||r.includes("\\")||/^[a-zA-Z]:/.test(r)||r.split("/").some(e=>e===".."||e===".")?null:r}async function Vn(d,r,e){await d.vault.adapter.writeBinary(r,e);let t;try{t=new Uint8Array(await d.vault.adapter.readBinary(r))}catch(s){throw new Error(`Couldn't read back the encrypted file to verify it (${s.message}). Nothing was deleted.`)}let i=t.length===e.length;if(i){for(let s=0;s<e.length;s++)if(t[s]!==e[s]){i=!1;break}}if(!i){try{await d.vault.adapter.remove(r)}catch{}throw new Error("The encrypted file on disk doesn't match what was written (bad write?). Nothing was deleted.")}}function Gi(d){return d.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ").trim()||d.basename}function Oi(d){return(d.replace(/[\\/:*?"<>|]+/g," ").replace(/\s+/g," ").trim()||"locked").slice(0,60)}async function Qa(d,r,e){let t=new Set(r.map(a=>a.file.path)),i=new Map;for(let a of r)for(let l of await ii(d,a.file))i.set(l.path,l);let s=new Set,n=d.metadataCache.resolvedLinks??{};for(let a of Object.keys(n))if(!t.has(a))for(let l of Object.keys(n[a]??{}))i.has(l)&&s.add(l);let o=[];for(let a of r){let l=e?.get(a.file.path);if(l!=null)try{let c=await d.vault.adapter.stat(a.file.path);if(c&&c.mtime!==l){console.warn("[Stashpad] note changed since it was bundled \u2014 keeping plaintext",a.file.path),o.push(a.file.path);continue}}catch{}try{await d.vault.delete(a.file)}catch(c){console.warn("[Stashpad] couldn't delete plaintext note",a.file.path,c),o.push(a.file.path)}}for(let[a,l]of i){if(s.has(a))continue;let c=e?.get(a);if(c!=null)try{let A=await d.vault.adapter.stat(a);if(A&&A.mtime!==c){console.warn("[Stashpad] attachment changed since it was bundled \u2014 keeping plaintext",a),o.push(a);continue}}catch{}try{await d.vault.delete(l)}catch(A){console.warn("[Stashpad] couldn't delete exclusive attachment",a,A),o.push(a)}}return{unpurged:o}}async function Ml(d,r,e,t,i=null,s=!1,n){let o=await Qt(d,r,e);if(!o)throw new Error("Couldn't find that note to lock.");let{rootNote:a,descendants:l,parentId:c}=o,A=[a,...l],h=new Map;for(let y of A){try{let v=await d.vault.adapter.stat(y.file.path);v&&h.set(y.file.path,v.mtime)}catch{}for(let v of await ii(d,y.file))try{let Q=await d.vault.adapter.stat(v.path);Q&&h.set(v.path,Q.mtime)}catch{}}let p=await vt(d,{rootNotes:[{id:a.id,file:a.file}],allDescendants:l.map(y=>({id:y.id,file:y.file})),sourceFolder:r}),f=await as(p,t),u=await Ye(f,t);if(u.length!==p.length)throw new Error("Encryption self-check failed (size mismatch).");for(let y=0;y<p.length;y++)if(u[y]!==p[y])throw new Error("Encryption self-check failed (content mismatch).");let g=(n??r).replace(/\/+$/,"");n&&!await d.vault.adapter.exists(g)&&await d.vault.adapter.mkdir(g);let I=Oi(s?e:Gi(a.file)),m=`${g}/${I}.${dt}`;for(let y=1;await d.vault.adapter.exists(m);y++)m=`${g}/${I} (${y}).${dt}`;await Vn(d,m,f);let C=A,B={v:1,parentId:c,title:s?"":Gi(a.file),count:C.length,created:a.created,rootId:e,prevSibling:i};try{await d.vault.adapter.write(qe(m),JSON.stringify(B))}catch(y){console.warn("[Stashpad] couldn't write lock sidecar",y)}let{unpurged:E}=await Qa(d,C,h);return{blobPath:m,noteCount:C.length,rootId:e,parentId:c,title:B.title,created:a.created,unpurged:E}}async function Pl(d,r,e,t,i){let s=new Uint8Array(await d.vault.adapter.readBinary(r));if(!Ue(s))throw new Error("Not an encrypted bundle.");let n=await Ye(s,e),o=$n(i)??r.replace(/\/[^/]*$/,""),a=await We(d,n,o,t,{dedupeExisting:!0});await d.vault.adapter.remove(r);try{await d.vault.adapter.remove(qe(r))}catch{}return{notesWritten:a.notesWritten,restoredTo:o}}var Yn="_deleted";function qd(d){let r="";for(let e=0;e<d.length;e++)r+=String.fromCharCode(d[e]);return btoa(r)}function Jd(d){let r=atob(d),e=new Uint8Array(r.length);for(let t=0;t<r.length;t++)e[t]=r.charCodeAt(t);return e}async function Ss(d,r,e,t){let i=$n(e?.originalFolder);if(!i&&e?.originalFolderEnc&&t)try{i=$n(new TextDecoder().decode(await Ye(Jd(e.originalFolderEnc),t)))}catch{i=null}let s=r.replace(/\/[^/]*$/,""),n=/(^|\/)trash$/.test(s)?s.replace(/\/?trash$/,""):"";if(i&&n&&i!==n&&!await d.vault.adapter.exists(i)&&(i=n||null),i)return await d.vault.adapter.exists(i)||await d.vault.adapter.mkdir(i),i;if(s===Yn||s.startsWith(`${Yn}/`))throw new Error("This deleted note's origin folder is unknown (missing or tampered sidecar) \u2014 can't restore it safely. The encrypted copy was kept.");if(/(^|\/)trash$/.test(s)){let o=s.replace(/\/?trash$/,"");if(o)return await d.vault.adapter.exists(o)||await d.vault.adapter.mkdir(o),o;throw new Error("This deleted note's origin folder is unknown (missing or tampered sidecar) \u2014 can't restore it safely. The encrypted copy was kept.")}return s}async function Hl(d,r,e,t,i,s=!1,n,o=Yn){let a=await Qt(d,r,e);if(!a)throw new Error("Couldn't find that note to delete.");let{rootNote:l,descendants:c,parentId:A}=a,h=[l,...c],p=new Map;for(let Q of h){try{let w=await d.vault.adapter.stat(Q.file.path);w&&p.set(Q.file.path,w.mtime)}catch{}for(let w of await ii(d,Q.file))try{let F=await d.vault.adapter.stat(w.path);F&&p.set(w.path,F.mtime)}catch{}}let f=await vt(d,{rootNotes:[{id:l.id,file:l.file}],allDescendants:c.map(Q=>({id:Q.id,file:Q.file})),sourceFolder:r}),u=await as(f,t),g=await Ye(u,t);if(g.length!==f.length)throw new Error("Encryption self-check failed (size).");for(let Q=0;Q<f.length;Q++)if(g[Q]!==f[Q])throw new Error("Encryption self-check failed (content).");{let Q=o.replace(/\/+$/,"").split("/").filter(Boolean),w="";for(let F of Q){w=w?`${w}/${F}`:F;try{await d.vault.adapter.exists(w)||await d.vault.adapter.mkdir(w)}catch{}}}let I=r.replace(/\/+$/,""),m=I.split("/").pop()||"vault",C=Oi(s?e:`${m} ${Gi(l.file)}`),B=`${o}/${C}.${dt}`;for(let Q=1;await d.vault.adapter.exists(B);Q++)B=`${o}/${C} (${Q}).${dt}`;await Vn(d,B,u);let E=h,y={v:1,kind:"deleted",originalFolder:s?"":I,...s?{originalFolderEnc:qd(await as(new TextEncoder().encode(I),t))}:{},parentId:A,title:s?"":Gi(l.file),count:E.length,created:l.created,rootId:e,deletedAt:i,...n?{keyId:n}:{}};try{await d.vault.adapter.write(qe(B),JSON.stringify(y))}catch(Q){console.warn("[Stashpad] couldn't write deleted sidecar \u2014 aborting delete, keeping plaintext",Q);try{await d.vault.adapter.remove(B)}catch{}throw new Error("Couldn't write trash metadata \u2014 the note was NOT deleted (kept intact).")}let{unpurged:v}=await Qa(d,E,p);return{blobPath:B,noteCount:E.length,rootId:e,originalFolder:I,title:y.title,unpurged:v}}async function Rl(d,r,e,t){let i=new Uint8Array(await d.vault.adapter.readBinary(r));if(!Ue(i))throw new Error("Not an encrypted bundle.");let s=await At(d,r),n=await Ss(d,r,s,e),o=await Ye(i,e),a=await We(d,o,n,t,{dedupeExisting:!0});await d.vault.adapter.remove(r);try{await d.vault.adapter.remove(qe(r))}catch{}return{notesWritten:a.notesWritten,restoredTo:n}}async function At(d,r){try{return JSON.parse(await d.vault.adapter.read(qe(r)))}catch{return null}}async function Ul(d,r,e,t,i){let s=await Qt(d,r,e);if(!s)throw new Error("Couldn't find that note to delete.");let{rootNote:n,descendants:o,parentId:a}=s,l=[n,...o],c=new Map;for(let m of l){try{let C=await d.vault.adapter.stat(m.file.path);C&&c.set(m.file.path,C.mtime)}catch{}for(let C of await ii(d,m.file))try{let B=await d.vault.adapter.stat(C.path);B&&c.set(C.path,B.mtime)}catch{}}let A=await vt(d,{rootNotes:[{id:n.id,file:n.file}],allDescendants:o.map(m=>({id:m.id,file:m.file})),sourceFolder:r});{let m=i.replace(/\/+$/,"").split("/").filter(Boolean),C="";for(let B of m){C=C?`${C}/${B}`:B;try{await d.vault.adapter.exists(C)||await d.vault.adapter.mkdir(C)}catch{}}}let h=r.replace(/\/+$/,""),p=h.split("/").pop()||"vault",f=Oi(`${p} ${Gi(n.file)}`),u=`${i}/${f}.${ks}`;for(let m=1;await d.vault.adapter.exists(u);m++)u=`${i}/${f} (${m}).${ks}`;await Vn(d,u,A);let g={v:1,kind:"deleted",originalFolder:h,parentId:a,title:Gi(n.file),count:l.length,created:n.created,rootId:e,deletedAt:t,encrypted:!1};try{await d.vault.adapter.write(qe(u),JSON.stringify(g))}catch(m){console.warn("[Stashpad] couldn't write trash sidecar \u2014 aborting delete, keeping plaintext",m);try{await d.vault.adapter.remove(u)}catch{}throw new Error("Couldn't write trash metadata \u2014 the note was NOT deleted (kept intact).")}let{unpurged:I}=await Qa(d,l,c);return{blobPath:u,noteCount:l.length,rootId:e,originalFolder:h,title:g.title,unpurged:I}}async function Ll(d,r,e){let t=new Uint8Array(await d.vault.adapter.readBinary(r)),i=await At(d,r),s=await Ss(d,r,i),n=await We(d,t,s,e,{dedupeExisting:!0});await d.vault.adapter.remove(r);try{await d.vault.adapter.remove(qe(r))}catch{}return{notesWritten:n.notesWritten,restoredTo:s}}async function Gl(d,r){let e=[];for(let t of r)try{if(!await d.vault.adapter.exists(t))continue;let i=await d.vault.adapter.list(t);e.push(...i.files.filter(s=>s.endsWith(`.${ks}`)))}catch{}return e}async function Fa(d,r){await d.vault.adapter.remove(r);try{await d.vault.adapter.remove(qe(r))}catch{}}var si=".trash";async function $d(d,r){let e=[],t=[r];for(;t.length;){let i=t.shift(),s;try{s=await d.vault.adapter.list(i)}catch{continue}e.push(...s.files),t.push(...s.folders)}return e}function Ol(d){let r=d.split("/").filter(Boolean);if(r.length===0)return null;for(let e of r)if(e===".."||e==="."||e.includes("\\")||/^[a-zA-Z]:/.test(e))return null;return r.join("/")}async function Kl(d,r,e){let t=new Uint8Array(await d.vault.adapter.readBinary(r));if(!Ue(t))throw new Error("Not an encrypted bundle.");let i=await Ye(t,e),s=await Li(i),n=0;for(let[o,a]of Object.entries(s)){if(!o.startsWith("files/"))continue;let l=Ol(o.slice(6));if(!l){console.warn("[Stashpad] skipped unsafe trash entry",o);continue}let c=`${si}/${l}`.split("/").slice(0,-1).join("/"),A="";for(let p of c.split("/"))A=A?`${A}/${p}`:p,await d.vault.adapter.exists(A)||await d.vault.adapter.mkdir(A);let h=`${si}/${l}`;for(let p=1;await d.vault.adapter.exists(h);p++)h=`${si}/${l.replace(/(\.[^./]*)?$/,` (${p})$1`)}`;await d.vault.adapter.writeBinary(h,a.buffer),n++}await d.vault.adapter.remove(r);try{await d.vault.adapter.remove(qe(r))}catch{}return{filesWritten:n}}async function ql(d,r,e,t,i){let s=r.replace(/\/+$/,""),n=(await $d(d,s)).filter(g=>!g.endsWith(`.${dt}`)&&!g.endsWith(`.${Tl}`));if(n.length===0)throw new Error("This folder has no files to encrypt.");let o=[],a=new Map;for(let g of n){o.push({name:`files/${g.slice(s.length+1)}`,data:await d.vault.adapter.readBinary(g)});try{let I=await d.vault.adapter.stat(g);I&&a.set(g,I.mtime)}catch{}}let l=await Ui(o),c=await as(l,e),A=await Ye(c,e);if(A.length!==l.length)throw new Error("Encryption self-check failed (size).");for(let g=0;g<l.length;g++)if(A[g]!==l[g])throw new Error("Encryption self-check failed (content).");let h=Oi(s.split("/").pop()||"folder"),p=`${s}/${h}.${dt}`;for(let g=1;await d.vault.adapter.exists(p);g++)p=`${s}/${h} (${g}).${dt}`;await Vn(d,p,c);let f={v:1,kind:"rawfolder",originalFolder:s,parentId:null,title:s.split("/").pop()||"",count:n.length,created:i,rootId:"",deletedAt:i,...t?{keyId:t}:{}};try{await d.vault.adapter.write(qe(p),JSON.stringify(f))}catch(g){console.warn("[Stashpad] couldn't write rawfolder sidecar",g)}let u=[];for(let g of n){let I=a.get(g);try{if(I!=null){let m=await d.vault.adapter.stat(g);if(m&&m.mtime!==I){u.push(g);continue}}await d.vault.adapter.remove(g)}catch(m){console.warn("[Stashpad] couldn't delete file",g,m),u.push(g)}}if(u.length===0){let g=[...new Set(n.map(I=>I.slice(0,I.lastIndexOf("/"))))].filter(I=>I.length>s.length).sort((I,m)=>m.length-I.length);for(let I of g)try{let m=await d.vault.adapter.list(I);!m.files.length&&!m.folders.length&&await d.vault.adapter.rmdir(I,!0)}catch{}}return{blobPath:p,fileCount:n.length,unpurged:u}}async function Jl(d,r,e){let t=new Uint8Array(await d.vault.adapter.readBinary(r));if(!Ue(t))throw new Error("Not an encrypted bundle.");let i=await At(d,r),s=$n(i?.originalFolder)??r.replace(/\/[^/]*$/,""),n=await Ye(t,e),o=await Li(n),a=0;for(let[l,c]of Object.entries(o)){if(!l.startsWith("files/"))continue;let A=Ol(l.slice(6));if(!A){console.warn("[Stashpad] skipped unsafe folder entry",l);continue}let h=`${s}/${A}`.split("/").slice(0,-1).join("/"),p="";for(let u of h.split("/"))p=p?`${p}/${u}`:u,p&&!await d.vault.adapter.exists(p)&&await d.vault.adapter.mkdir(p);let f=`${s}/${A}`;for(let u=1;await d.vault.adapter.exists(f);u++)f=`${s}/${A.replace(/(\.[^./]*)?$/,` (${u})$1`)}`;await d.vault.adapter.writeBinary(f,c.buffer),a++}await d.vault.adapter.remove(r);try{await d.vault.adapter.remove(qe(r))}catch{}return{filesWritten:a,folder:s}}async function ka(d,r){let e=r.replace(/\/+$/,"");try{let t=await d.vault.adapter.list(e);for(let i of t.files){if(!i.endsWith(`.${dt}`))continue;if((await At(d,i))?.kind==="rawfolder")return i}}catch{}return null}async function $l(d){let r=[];for(let e of d.vault.getFiles())if(e.extension===dt)try{(await At(d,e.path))?.kind==="rawfolder"&&r.push({folder:e.parent?.path?.replace(/\/+$/,"")??"",blobPath:e.path})}catch{}return r}function bs(d){return`${(d||"").replace(/\/+$/,"")}/trash`}async function Wn(d,r=[]){let e=[];for(let t of[Yn,...r])try{if(!await d.vault.adapter.exists(t))continue;let i=await d.vault.adapter.list(t);e.push(...i.files.filter(s=>s.endsWith(`.${dt}`)))}catch{}return e}function Sa(d){return d.replace(/[^\w.\-]+/g,"_").replace(/^\.+/,"").slice(0,60)||"stash-export"}async function Yl(d,r){let e=Xd(d,r);if(e.length===0){new Me.Notice("Nothing to export.");return}let t=Zd(d,e);if(t.length===0){new Me.Notice("No exportable notes (no files attached).");return}let i=(d.noteFolder.split("/").pop()||d.noteFolder).trim(),s=e.length===1?d.titleForNode(e[0]):`${i}-${e.length}notes`;new bi(d.app,s,t.length,n=>{n.format==="stash"?Vd(d,e,t,n.baseName,n.password,n.remember):n.format==="okf"?zd(d,e,t,n.baseName,n.okf):Wd(d,e,t,n.baseName,n.content)},{kdfProbe:os,okfEnabled:d.plugin.settings.okfEnabled}).open()}async function zl(d,r){let e=r.replace(/\/[^/]*$/,"").replace(/\/+$/,""),t=await d.ensureFolderUnlocked(e);if(!t)return;let i;try{let l=new Uint8Array(await d.app.vault.adapter.readBinary(r));i=await Ye(l,t)}catch(l){new Me.Notice(`Couldn't decrypt this note to export it: ${l.message}`);return}finally{t.fill(0)}let s=await zn(d.app,r),n=(d.settings.lockedSubtrees??[]).find(l=>l.blob===r),o=n?.title||s?.title||"locked-note",a=n?.count??s?.count??1;new bi(d.app,o,a,l=>{Yd(d,e,l.baseName,i,l.password,l.remember)},{kdfProbe:os,locked:!0}).open()}async function Yd(d,r,e,t,i,s=!1){try{let n=t,o="";if(i){let f=await Ct(n,i);n=f.data;let u=$o[f.kdf];o=u.strong?` (encrypted \xB7 ${u.label})`:` (encrypted \xB7 ${u.label} \u2014 Argon2id unavailable here, weaker)`}let a=(0,Me.moment)().format("YYYYMMDD-HHmmss"),c=(d.settings.exportFolder||"_exports").trim().replace(/^\/+|\/+$/g,"").split("/").filter(f=>f&&f!=="."&&f!==".."&&!/[\\:]/.test(f)).join("/")||"_exports",A=`${r}/${c}`;await d.app.vault.adapter.exists(A)||await d.app.vault.adapter.mkdir(A);let h=`${Sa(e)}-${a}`,p=`${A}/${h}.${ct}`;if(await d.app.vault.createBinary(p,n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength)),s&&i)try{d.app.secretStorage?.setSecret(pi(h),i)}catch(f){console.warn("[Stashpad] couldn't save export passphrase",f)}new Me.Notice(`Exported encrypted note${o} \u2192 ${p}`,0)}catch(n){new Me.Notice(`Export failed: ${n.message}`),console.error(n)}finally{try{t.fill(0)}catch{}}}async function zd(d,r,e,t,i){try{let s=await d.plugin.exportOkf(d.noteFolder,r.map(n=>n.id),t,{zip:i.zip,targz:i.targz});if(!s.length){new Me.Notice("Nothing exported.");return}d.plugin.notifications.show({message:`Exported OKF \u2014 ${s.length} file${s.length===1?"":"s"} \u2192 \`${d.noteFolder}/${d.plugin.settings.exportFolder||"_exports"}\``,kind:"success",category:"export",affectedPaths:s,folder:d.noteFolder,actions:s[0]?d.actionsForFile(s[0]):void 0,duration:0}),await d.log.append({type:"stash_export",id:r[0].id,payload:{okf:!0,paths:s,noteCount:e.length,rootIds:r.map(n=>n.id)}})}catch(s){new Me.Notice(`OKF export failed: ${s.message}`),console.error(s)}}async function Vd(d,r,e,t,i,s=!1){try{let n=await vt(d.app,{rootNotes:r.filter(f=>!!f.file).map(f=>({id:f.id,file:f.file})),allDescendants:e.filter(f=>!r.some(u=>u.id===f.id)).filter(f=>!!f.file).map(f=>({id:f.id,file:f.file})),sourceFolder:d.noteFolder}),o="";if(i){let f=await Ct(n,i);n=f.data;let u=$o[f.kdf];o=u.strong?` (encrypted \xB7 ${u.label})`:` (encrypted \xB7 ${u.label} \u2014 Argon2id unavailable on this device, this export is weaker)`}let a=(0,Me.moment)().format("YYYYMMDD-HHmmss"),l=Sa(t),c=(d.plugin.settings.exportFolder||"_exports").trim().replace(/^\/+|\/+$/g,""),A=`${d.noteFolder}/${c}`;await d.ensureFolder(A);let h=`${l}-${a}`,p=`${A}/${h}.${ct}`;if(await d.app.vault.createBinary(p,n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength)),s&&i){let f=d.app.secretStorage;try{f?.setSecret(pi(h),i)}catch(u){console.warn("[Stashpad] couldn't save export passphrase to secret storage",u)}}await d.log.append({type:"stash_export",id:r[0].id,payload:{path:p,noteCount:e.length,rootIds:r.map(f=>f.id)}}),d.plugin.notifications.show({message:`Exported ${e.length} note${e.length===1?"":"s"}${o} \u2192 \`${p}\``,kind:i&&o.includes("weaker")?"warning":"success",category:"export",affectedPaths:[p],folder:d.noteFolder,actions:d.actionsForFile(p),duration:0})}catch(n){d.plugin.notifications.show({message:`Stashpad: export failed +${r}`}function Yd(A,r){if(r==="full")return A;let e=A.match(/^\uFEFF?---\r?\n[\s\S]*?\r?\n---[ \t]*(?:\r?\n|$)/);return r==="frontmatter"?e?e[0]:"":e?A.slice(e[0].length).replace(/^\s*\n/,""):A}async function Dl(A,r){if(!(!r||await A.vault.adapter.exists(r)))try{await A.vault.createFolder(r)}catch(t){let i=t?.message??"";if(!/already exists/i.test(i))throw t}}Wt();Vs();ve();Wt();$n();var dt="stashenc",Hl="stashmeta",bs="stashpack";function Je(A){return A.replace(/\.(stashenc|stashpack)$/,`.${Hl}`)}async function Wn(A,r){try{return JSON.parse(await A.vault.adapter.read(Je(r)))}catch{return null}}async function Qt(A,r,e){let t=r.replace(/\/+$/,""),i=[];for(let c of A.vault.getMarkdownFiles()){if((c.parent?.path?.replace(/\/+$/,"")??"")!==t)continue;let d;try{d=ge(await A.vault.read(c)).fm}catch{continue}typeof d.id=="string"&&i.push({id:d.id,file:c,parent:typeof d.parent=="string"?d.parent:null,created:typeof d.created=="string"?d.created:""})}let s=i.find(c=>c.id===e);if(!s)return null;let n=new Map;for(let c of i){if(!c.parent)continue;let d=n.get(c.parent)??[];d.push(c),n.set(c.parent,d)}let o=[],a=new Set([e]),l=[e];for(;l.length;){let c=[];for(let d of l)for(let h of n.get(d)??[])a.has(h.id)||(a.add(h.id),o.push(h),c.push(h.id));l=c}return{rootNote:s,descendants:o,parentId:s.parent}}function zn(A){if(!A)return null;let r=A.replace(/\/+$/,"");return!r||r.startsWith("/")||r.includes("\\")||/^[a-zA-Z]:/.test(r)||r.split("/").some(e=>e===".."||e===".")?null:r}async function Xn(A,r,e){await A.vault.adapter.writeBinary(r,e);let t;try{t=new Uint8Array(await A.vault.adapter.readBinary(r))}catch(s){throw new Error(`Couldn't read back the encrypted file to verify it (${s.message}). Nothing was deleted.`)}let i=t.length===e.length;if(i){for(let s=0;s<e.length;s++)if(t[s]!==e[s]){i=!1;break}}if(!i){try{await A.vault.adapter.remove(r)}catch{}throw new Error("The encrypted file on disk doesn't match what was written (bad write?). Nothing was deleted.")}}function Oi(A){return A.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ").trim()||A.basename}function Ki(A){return(A.replace(/[\\/:*?"<>|]+/g," ").replace(/\s+/g," ").trim()||"locked").slice(0,60)}async function Sa(A,r,e){let t=new Set(r.map(a=>a.file.path)),i=new Map;for(let a of r)for(let l of await ii(A,a.file))i.set(l.path,l);let s=new Set,n=A.metadataCache.resolvedLinks??{};for(let a of Object.keys(n))if(!t.has(a))for(let l of Object.keys(n[a]??{}))i.has(l)&&s.add(l);let o=[];for(let a of r){let l=e?.get(a.file.path);if(l!=null)try{let c=await A.vault.adapter.stat(a.file.path);if(c&&c.mtime!==l){console.warn("[Stashpad] note changed since it was bundled \u2014 keeping plaintext",a.file.path),o.push(a.file.path);continue}}catch{}try{await A.vault.delete(a.file)}catch(c){console.warn("[Stashpad] couldn't delete plaintext note",a.file.path,c),o.push(a.file.path)}}for(let[a,l]of i){if(s.has(a))continue;let c=e?.get(a);if(c!=null)try{let d=await A.vault.adapter.stat(a);if(d&&d.mtime!==c){console.warn("[Stashpad] attachment changed since it was bundled \u2014 keeping plaintext",a),o.push(a);continue}}catch{}try{await A.vault.delete(l)}catch(d){console.warn("[Stashpad] couldn't delete exclusive attachment",a,d),o.push(a)}}return{unpurged:o}}async function Rl(A,r,e,t,i=null,s=!1,n){let o=await Qt(A,r,e);if(!o)throw new Error("Couldn't find that note to lock.");let{rootNote:a,descendants:l,parentId:c}=o,d=[a,...l],h=new Map;for(let y of d){try{let v=await A.vault.adapter.stat(y.file.path);v&&h.set(y.file.path,v.mtime)}catch{}for(let v of await ii(A,y.file))try{let Q=await A.vault.adapter.stat(v.path);Q&&h.set(v.path,Q.mtime)}catch{}}let p=await vt(A,{rootNotes:[{id:a.id,file:a.file}],allDescendants:l.map(y=>({id:y.id,file:y.file})),sourceFolder:r}),f=await ls(p,t),u=await Ye(f,t);if(u.length!==p.length)throw new Error("Encryption self-check failed (size mismatch).");for(let y=0;y<p.length;y++)if(u[y]!==p[y])throw new Error("Encryption self-check failed (content mismatch).");let g=(n??r).replace(/\/+$/,"");n&&!await A.vault.adapter.exists(g)&&await A.vault.adapter.mkdir(g);let I=Ki(s?e:Oi(a.file)),m=`${g}/${I}.${dt}`;for(let y=1;await A.vault.adapter.exists(m);y++)m=`${g}/${I} (${y}).${dt}`;await Xn(A,m,f);let C=d,B={v:1,parentId:c,title:s?"":Oi(a.file),count:C.length,created:a.created,rootId:e,prevSibling:i};try{await A.vault.adapter.write(Je(m),JSON.stringify(B))}catch(y){console.warn("[Stashpad] couldn't write lock sidecar",y)}let{unpurged:E}=await Sa(A,C,h);return{blobPath:m,noteCount:C.length,rootId:e,parentId:c,title:B.title,created:a.created,unpurged:E}}async function Ul(A,r,e,t,i){let s=new Uint8Array(await A.vault.adapter.readBinary(r));if(!Ue(s))throw new Error("Not an encrypted bundle.");let n=await Ye(s,e),o=zn(i)??r.replace(/\/[^/]*$/,""),a=await We(A,n,o,t,{dedupeExisting:!0});await A.vault.adapter.remove(r);try{await A.vault.adapter.remove(Je(r))}catch{}return{notesWritten:a.notesWritten,restoredTo:o}}var Vn="_deleted";function zd(A){let r="";for(let e=0;e<A.length;e++)r+=String.fromCharCode(A[e]);return btoa(r)}function Vd(A){let r=atob(A),e=new Uint8Array(r.length);for(let t=0;t<r.length;t++)e[t]=r.charCodeAt(t);return e}async function Ds(A,r,e,t){let i=zn(e?.originalFolder);if(!i&&e?.originalFolderEnc&&t)try{i=zn(new TextDecoder().decode(await Ye(Vd(e.originalFolderEnc),t)))}catch{i=null}let s=r.replace(/\/[^/]*$/,""),n=/(^|\/)trash$/.test(s)?s.replace(/\/?trash$/,""):"";if(i&&n&&i!==n&&!await A.vault.adapter.exists(i)&&(i=n||null),i)return await A.vault.adapter.exists(i)||await A.vault.adapter.mkdir(i),i;if(s===Vn||s.startsWith(`${Vn}/`))throw new Error("This deleted note's origin folder is unknown (missing or tampered sidecar) \u2014 can't restore it safely. The encrypted copy was kept.");if(/(^|\/)trash$/.test(s)){let o=s.replace(/\/?trash$/,"");if(o)return await A.vault.adapter.exists(o)||await A.vault.adapter.mkdir(o),o;throw new Error("This deleted note's origin folder is unknown (missing or tampered sidecar) \u2014 can't restore it safely. The encrypted copy was kept.")}return s}async function Ll(A,r,e,t,i,s=!1,n,o=Vn){let a=await Qt(A,r,e);if(!a)throw new Error("Couldn't find that note to delete.");let{rootNote:l,descendants:c,parentId:d}=a,h=[l,...c],p=new Map;for(let Q of h){try{let w=await A.vault.adapter.stat(Q.file.path);w&&p.set(Q.file.path,w.mtime)}catch{}for(let w of await ii(A,Q.file))try{let k=await A.vault.adapter.stat(w.path);k&&p.set(w.path,k.mtime)}catch{}}let f=await vt(A,{rootNotes:[{id:l.id,file:l.file}],allDescendants:c.map(Q=>({id:Q.id,file:Q.file})),sourceFolder:r}),u=await ls(f,t),g=await Ye(u,t);if(g.length!==f.length)throw new Error("Encryption self-check failed (size).");for(let Q=0;Q<f.length;Q++)if(g[Q]!==f[Q])throw new Error("Encryption self-check failed (content).");{let Q=o.replace(/\/+$/,"").split("/").filter(Boolean),w="";for(let k of Q){w=w?`${w}/${k}`:k;try{await A.vault.adapter.exists(w)||await A.vault.adapter.mkdir(w)}catch{}}}let I=r.replace(/\/+$/,""),m=I.split("/").pop()||"vault",C=Ki(s?e:`${m} ${Oi(l.file)}`),B=`${o}/${C}.${dt}`;for(let Q=1;await A.vault.adapter.exists(B);Q++)B=`${o}/${C} (${Q}).${dt}`;await Xn(A,B,u);let E=h,y={v:1,kind:"deleted",originalFolder:s?"":I,...s?{originalFolderEnc:zd(await ls(new TextEncoder().encode(I),t))}:{},parentId:d,title:s?"":Oi(l.file),count:E.length,created:l.created,rootId:e,deletedAt:i,...n?{keyId:n}:{}};try{await A.vault.adapter.write(Je(B),JSON.stringify(y))}catch(Q){console.warn("[Stashpad] couldn't write deleted sidecar \u2014 aborting delete, keeping plaintext",Q);try{await A.vault.adapter.remove(B)}catch{}throw new Error("Couldn't write trash metadata \u2014 the note was NOT deleted (kept intact).")}let{unpurged:v}=await Sa(A,E,p);return{blobPath:B,noteCount:E.length,rootId:e,originalFolder:I,title:y.title,unpurged:v}}async function Gl(A,r,e,t){let i=new Uint8Array(await A.vault.adapter.readBinary(r));if(!Ue(i))throw new Error("Not an encrypted bundle.");let s=await At(A,r),n=await Ds(A,r,s,e),o=await Ye(i,e),a=await We(A,o,n,t,{dedupeExisting:!0});await A.vault.adapter.remove(r);try{await A.vault.adapter.remove(Je(r))}catch{}return{notesWritten:a.notesWritten,restoredTo:n}}async function At(A,r){try{return JSON.parse(await A.vault.adapter.read(Je(r)))}catch{return null}}async function Ol(A,r,e,t,i){let s=await Qt(A,r,e);if(!s)throw new Error("Couldn't find that note to delete.");let{rootNote:n,descendants:o,parentId:a}=s,l=[n,...o],c=new Map;for(let m of l){try{let C=await A.vault.adapter.stat(m.file.path);C&&c.set(m.file.path,C.mtime)}catch{}for(let C of await ii(A,m.file))try{let B=await A.vault.adapter.stat(C.path);B&&c.set(C.path,B.mtime)}catch{}}let d=await vt(A,{rootNotes:[{id:n.id,file:n.file}],allDescendants:o.map(m=>({id:m.id,file:m.file})),sourceFolder:r});{let m=i.replace(/\/+$/,"").split("/").filter(Boolean),C="";for(let B of m){C=C?`${C}/${B}`:B;try{await A.vault.adapter.exists(C)||await A.vault.adapter.mkdir(C)}catch{}}}let h=r.replace(/\/+$/,""),p=h.split("/").pop()||"vault",f=Ki(`${p} ${Oi(n.file)}`),u=`${i}/${f}.${bs}`;for(let m=1;await A.vault.adapter.exists(u);m++)u=`${i}/${f} (${m}).${bs}`;await Xn(A,u,d);let g={v:1,kind:"deleted",originalFolder:h,parentId:a,title:Oi(n.file),count:l.length,created:n.created,rootId:e,deletedAt:t,encrypted:!1};try{await A.vault.adapter.write(Je(u),JSON.stringify(g))}catch(m){console.warn("[Stashpad] couldn't write trash sidecar \u2014 aborting delete, keeping plaintext",m);try{await A.vault.adapter.remove(u)}catch{}throw new Error("Couldn't write trash metadata \u2014 the note was NOT deleted (kept intact).")}let{unpurged:I}=await Sa(A,l,c);return{blobPath:u,noteCount:l.length,rootId:e,originalFolder:h,title:g.title,unpurged:I}}async function Kl(A,r,e){let t=new Uint8Array(await A.vault.adapter.readBinary(r)),i=await At(A,r),s=await Ds(A,r,i),n=await We(A,t,s,e,{dedupeExisting:!0});await A.vault.adapter.remove(r);try{await A.vault.adapter.remove(Je(r))}catch{}return{notesWritten:n.notesWritten,restoredTo:s}}async function Jl(A,r){let e=[];for(let t of r)try{if(!await A.vault.adapter.exists(t))continue;let i=await A.vault.adapter.list(t);e.push(...i.files.filter(s=>s.endsWith(`.${bs}`)))}catch{}return e}async function ba(A,r){await A.vault.adapter.remove(r);try{await A.vault.adapter.remove(Je(r))}catch{}}var si=".trash";async function Wd(A,r){let e=[],t=[r];for(;t.length;){let i=t.shift(),s;try{s=await A.vault.adapter.list(i)}catch{continue}e.push(...s.files),t.push(...s.folders)}return e}function ql(A){let r=A.split("/").filter(Boolean);if(r.length===0)return null;for(let e of r)if(e===".."||e==="."||e.includes("\\")||/^[a-zA-Z]:/.test(e))return null;return r.join("/")}async function $l(A,r,e){let t=new Uint8Array(await A.vault.adapter.readBinary(r));if(!Ue(t))throw new Error("Not an encrypted bundle.");let i=await Ye(t,e),s=await Gi(i),n=0;for(let[o,a]of Object.entries(s)){if(!o.startsWith("files/"))continue;let l=ql(o.slice(6));if(!l){console.warn("[Stashpad] skipped unsafe trash entry",o);continue}let c=`${si}/${l}`.split("/").slice(0,-1).join("/"),d="";for(let p of c.split("/"))d=d?`${d}/${p}`:p,await A.vault.adapter.exists(d)||await A.vault.adapter.mkdir(d);let h=`${si}/${l}`;for(let p=1;await A.vault.adapter.exists(h);p++)h=`${si}/${l.replace(/(\.[^./]*)?$/,` (${p})$1`)}`;await A.vault.adapter.writeBinary(h,a.buffer),n++}await A.vault.adapter.remove(r);try{await A.vault.adapter.remove(Je(r))}catch{}return{filesWritten:n}}async function Yl(A,r,e,t,i){let s=r.replace(/\/+$/,""),n=(await Wd(A,s)).filter(g=>!g.endsWith(`.${dt}`)&&!g.endsWith(`.${Hl}`));if(n.length===0)throw new Error("This folder has no files to encrypt.");let o=[],a=new Map;for(let g of n){o.push({name:`files/${g.slice(s.length+1)}`,data:await A.vault.adapter.readBinary(g)});try{let I=await A.vault.adapter.stat(g);I&&a.set(g,I.mtime)}catch{}}let l=await Li(o),c=await ls(l,e),d=await Ye(c,e);if(d.length!==l.length)throw new Error("Encryption self-check failed (size).");for(let g=0;g<l.length;g++)if(d[g]!==l[g])throw new Error("Encryption self-check failed (content).");let h=Ki(s.split("/").pop()||"folder"),p=`${s}/${h}.${dt}`;for(let g=1;await A.vault.adapter.exists(p);g++)p=`${s}/${h} (${g}).${dt}`;await Xn(A,p,c);let f={v:1,kind:"rawfolder",originalFolder:s,parentId:null,title:s.split("/").pop()||"",count:n.length,created:i,rootId:"",deletedAt:i,...t?{keyId:t}:{}};try{await A.vault.adapter.write(Je(p),JSON.stringify(f))}catch(g){console.warn("[Stashpad] couldn't write rawfolder sidecar",g)}let u=[];for(let g of n){let I=a.get(g);try{if(I!=null){let m=await A.vault.adapter.stat(g);if(m&&m.mtime!==I){u.push(g);continue}}await A.vault.adapter.remove(g)}catch(m){console.warn("[Stashpad] couldn't delete file",g,m),u.push(g)}}if(u.length===0){let g=[...new Set(n.map(I=>I.slice(0,I.lastIndexOf("/"))))].filter(I=>I.length>s.length).sort((I,m)=>m.length-I.length);for(let I of g)try{let m=await A.vault.adapter.list(I);!m.files.length&&!m.folders.length&&await A.vault.adapter.rmdir(I,!0)}catch{}}return{blobPath:p,fileCount:n.length,unpurged:u}}async function zl(A,r,e){let t=new Uint8Array(await A.vault.adapter.readBinary(r));if(!Ue(t))throw new Error("Not an encrypted bundle.");let i=await At(A,r),s=zn(i?.originalFolder)??r.replace(/\/[^/]*$/,""),n=await Ye(t,e),o=await Gi(n),a=0;for(let[l,c]of Object.entries(o)){if(!l.startsWith("files/"))continue;let d=ql(l.slice(6));if(!d){console.warn("[Stashpad] skipped unsafe folder entry",l);continue}let h=`${s}/${d}`.split("/").slice(0,-1).join("/"),p="";for(let u of h.split("/"))p=p?`${p}/${u}`:u,p&&!await A.vault.adapter.exists(p)&&await A.vault.adapter.mkdir(p);let f=`${s}/${d}`;for(let u=1;await A.vault.adapter.exists(f);u++)f=`${s}/${d.replace(/(\.[^./]*)?$/,` (${u})$1`)}`;await A.vault.adapter.writeBinary(f,c.buffer),a++}await A.vault.adapter.remove(r);try{await A.vault.adapter.remove(Je(r))}catch{}return{filesWritten:a,folder:s}}async function Da(A,r){let e=r.replace(/\/+$/,"");try{let t=await A.vault.adapter.list(e);for(let i of t.files){if(!i.endsWith(`.${dt}`))continue;if((await At(A,i))?.kind==="rawfolder")return i}}catch{}return null}async function Vl(A){let r=[];for(let e of A.vault.getFiles())if(e.extension===dt)try{(await At(A,e.path))?.kind==="rawfolder"&&r.push({folder:e.parent?.path?.replace(/\/+$/,"")??"",blobPath:e.path})}catch{}return r}function xs(A){return`${(A||"").replace(/\/+$/,"")}/trash`}async function Zn(A,r=[]){let e=[];for(let t of[Vn,...r])try{if(!await A.vault.adapter.exists(t))continue;let i=await A.vault.adapter.list(t);e.push(...i.files.filter(s=>s.endsWith(`.${dt}`)))}catch{}return e}function xa(A){return A.replace(/[^\w.\-]+/g,"_").replace(/^\.+/,"").slice(0,60)||"stash-export"}async function Wl(A,r){let e=eA(A,r);if(e.length===0){new Me.Notice("Nothing to export.");return}let t=tA(A,e);if(t.length===0){new Me.Notice("No exportable notes (no files attached).");return}let i=(A.noteFolder.split("/").pop()||A.noteFolder).trim(),s=e.length===1?A.titleForNode(e[0]):`${i}-${e.length}notes`;new Di(A.app,s,t.length,n=>{n.format==="stash"?jd(A,e,t,n.baseName,n.password,n.remember):n.format==="okf"?Zd(A,e,t,n.baseName,n.okf):_d(A,e,t,n.baseName,n.content)},{kdfProbe:rs,okfEnabled:A.plugin.settings.okfEnabled}).open()}async function Xl(A,r){let e=r.replace(/\/[^/]*$/,"").replace(/\/+$/,""),t=await A.ensureFolderUnlocked(e);if(!t)return;let i;try{let l=new Uint8Array(await A.app.vault.adapter.readBinary(r));i=await Ye(l,t)}catch(l){new Me.Notice(`Couldn't decrypt this note to export it: ${l.message}`);return}finally{t.fill(0)}let s=await Wn(A.app,r),n=(A.settings.lockedSubtrees??[]).find(l=>l.blob===r),o=n?.title||s?.title||"locked-note",a=n?.count??s?.count??1;new Di(A.app,o,a,l=>{Xd(A,e,l.baseName,i,l.password,l.remember)},{kdfProbe:rs,locked:!0}).open()}async function Xd(A,r,e,t,i,s=!1){try{let n=t,o="";if(i){let f=await Ct(n,i);n=f.data;let u=Vo[f.kdf];o=u.strong?` (encrypted \xB7 ${u.label})`:` (encrypted \xB7 ${u.label} \u2014 Argon2id unavailable here, weaker)`}let a=(0,Me.moment)().format("YYYYMMDD-HHmmss"),c=(A.settings.exportFolder||"_exports").trim().replace(/^\/+|\/+$/g,"").split("/").filter(f=>f&&f!=="."&&f!==".."&&!/[\\:]/.test(f)).join("/")||"_exports",d=`${r}/${c}`;await A.app.vault.adapter.exists(d)||await A.app.vault.adapter.mkdir(d);let h=`${xa(e)}-${a}`,p=`${d}/${h}.${ct}`;if(await A.app.vault.createBinary(p,n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength)),s&&i)try{A.app.secretStorage?.setSecret(gi(h),i)}catch(f){console.warn("[Stashpad] couldn't save export passphrase",f)}new Me.Notice(`Exported encrypted note${o} \u2192 ${p}`,0)}catch(n){new Me.Notice(`Export failed: ${n.message}`),console.error(n)}finally{try{t.fill(0)}catch{}}}async function Zd(A,r,e,t,i){try{let s=await A.plugin.exportOkf(A.noteFolder,r.map(n=>n.id),t,{zip:i.zip,targz:i.targz});if(!s.length){new Me.Notice("Nothing exported.");return}A.plugin.notifications.show({message:`Exported OKF \u2014 ${s.length} file${s.length===1?"":"s"} \u2192 \`${A.noteFolder}/${A.plugin.settings.exportFolder||"_exports"}\``,kind:"success",category:"export",affectedPaths:s,folder:A.noteFolder,actions:s[0]?A.actionsForFile(s[0]):void 0,duration:0}),await A.log.append({type:"stash_export",id:r[0].id,payload:{okf:!0,paths:s,noteCount:e.length,rootIds:r.map(n=>n.id)}})}catch(s){new Me.Notice(`OKF export failed: ${s.message}`),console.error(s)}}async function jd(A,r,e,t,i,s=!1){try{let n=await vt(A.app,{rootNotes:r.filter(f=>!!f.file).map(f=>({id:f.id,file:f.file})),allDescendants:e.filter(f=>!r.some(u=>u.id===f.id)).filter(f=>!!f.file).map(f=>({id:f.id,file:f.file})),sourceFolder:A.noteFolder}),o="";if(i){let f=await Ct(n,i);n=f.data;let u=Vo[f.kdf];o=u.strong?` (encrypted \xB7 ${u.label})`:` (encrypted \xB7 ${u.label} \u2014 Argon2id unavailable on this device, this export is weaker)`}let a=(0,Me.moment)().format("YYYYMMDD-HHmmss"),l=xa(t),c=(A.plugin.settings.exportFolder||"_exports").trim().replace(/^\/+|\/+$/g,""),d=`${A.noteFolder}/${c}`;await A.ensureFolder(d);let h=`${l}-${a}`,p=`${d}/${h}.${ct}`;if(await A.app.vault.createBinary(p,n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength)),s&&i){let f=A.app.secretStorage;try{f?.setSecret(gi(h),i)}catch(u){console.warn("[Stashpad] couldn't save export passphrase to secret storage",u)}}await A.log.append({type:"stash_export",id:r[0].id,payload:{path:p,noteCount:e.length,rootIds:r.map(f=>f.id)}}),A.plugin.notifications.show({message:`Exported ${e.length} note${e.length===1?"":"s"}${o} \u2192 \`${p}\``,kind:i&&o.includes("weaker")?"warning":"success",category:"export",affectedPaths:[p],folder:A.noteFolder,actions:A.actionsForFile(p),duration:0})}catch(n){A.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)}}async function Wd(d,r,e,t,i){try{let s=e.filter(p=>!!p.file).map(p=>({file:p.file})),n=await bl(d.app,s,i),o=(0,Me.moment)().format("YYYYMMDD-HHmmss"),a=Sa(t),l=(d.plugin.settings.exportFolder||"_exports").trim().replace(/^\/+|\/+$/g,""),c=`${d.noteFolder}/${l}`;await d.ensureFolder(c);let A=`${c}/${a}-${o}.zip`;await d.app.vault.createBinary(A,n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength));let h=i==="frontmatter"?"frontmatter only":i==="body"?"body only":"full notes";await d.log.append({type:"stash_export",id:r[0].id,payload:{path:A,noteCount:s.length,rootIds:r.map(p=>p.id),content:i}}),d.plugin.notifications.show({message:`Exported ${s.length} note${s.length===1?"":"s"} (${h}, plain .zip) \u2192 \`${A}\``,kind:"success",category:"export",affectedPaths:[A],folder:d.noteFolder,actions:d.actionsForFile(A),duration:0})}catch(s){d.plugin.notifications.show({message:`Stashpad: export failed +Check disk space + write permissions on the export folder.`,kind:"error",category:"export"}),console.error(n)}}async function _d(A,r,e,t,i){try{let s=e.filter(p=>!!p.file).map(p=>({file:p.file})),n=await Nl(A.app,s,i),o=(0,Me.moment)().format("YYYYMMDD-HHmmss"),a=xa(t),l=(A.plugin.settings.exportFolder||"_exports").trim().replace(/^\/+|\/+$/g,""),c=`${A.noteFolder}/${l}`;await A.ensureFolder(c);let d=`${c}/${a}-${o}.zip`;await A.app.vault.createBinary(d,n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength));let h=i==="frontmatter"?"frontmatter only":i==="body"?"body only":"full notes";await A.log.append({type:"stash_export",id:r[0].id,payload:{path:d,noteCount:s.length,rootIds:r.map(p=>p.id),content:i}}),A.plugin.notifications.show({message:`Exported ${s.length} note${s.length===1?"":"s"} (${h}, plain .zip) \u2192 \`${d}\``,kind:"success",category:"export",affectedPaths:[d],folder:A.noteFolder,actions:A.actionsForFile(d),duration:0})}catch(s){A.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 Xd(d,r){if(r?.file)return[r];if(d.selection.size>0)return[...d.selection].map(t=>d.tree.get(t)).filter(t=>!!t?.file);if(d.cursorIdx>=0&&d.currentChildren[d.cursorIdx])return[d.currentChildren[d.cursorIdx]];let e=d.tree.get(d.focusId);return e?.file?[e]:[]}function Zd(d,r){let e=new Set,t=[],i=s=>{if(!e.has(s.id)){e.add(s.id),s.file&&t.push(s);for(let n of d.tree.getChildren(s.id))i(n)}};for(let s of r)i(s);return t}async function Vl(d){let r=d.app.vault.getFiles().filter(t=>t.extension===ct);if(r.length===0){new Me.Notice("No .stash files found in this vault.");return}let e=new class extends Me.FuzzySuggestModal{getItems(){return r}getItemText(t){return t.path}onChooseItem(t){ba(d,t)}}(d.app);e.setPlaceholder("Pick a .stash file to import\u2026"),e.open()}async function ba(d,r){try{let e=new Uint8Array(await d.app.vault.readBinary(r)),t=await yi(d.app,e,{secretId:pi(r.basename)});if(!t)return;let i=await We(d.app,t,d.noteFolder,jd(d),{stripReserved:!0});d.tree.rebuild(d.noteFolder),d.render(),await d.log.append({type:"stash_import",id:S,payload:{from:r.path,into:d.noteFolder,noteCount:i.notesWritten,attachmentsWritten:i.attachmentsWritten,collisionsRenamed:i.collisionsRenamed}});try{await d.app.fileManager.trashFile(r)}catch{}d.plugin.importService.clearPendingEncrypted(r.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(e){d.plugin.notifications.show({message:`Stashpad: import failed +Check disk space + write permissions on the export folder.`,kind:"error",category:"export"}),console.error(s)}}function eA(A,r){if(r?.file)return[r];if(A.selection.size>0)return[...A.selection].map(t=>A.tree.get(t)).filter(t=>!!t?.file);if(A.cursorIdx>=0&&A.currentChildren[A.cursorIdx])return[A.currentChildren[A.cursorIdx]];let e=A.tree.get(A.focusId);return e?.file?[e]:[]}function tA(A,r){let e=new Set,t=[],i=s=>{if(!e.has(s.id)){e.add(s.id),s.file&&t.push(s);for(let n of A.tree.getChildren(s.id))i(n)}};for(let s of r)i(s);return t}async function Zl(A){let r=A.app.vault.getFiles().filter(t=>t.extension===ct);if(r.length===0){new Me.Notice("No .stash files found in this vault.");return}let e=new class extends Me.FuzzySuggestModal{getItems(){return r}getItemText(t){return t.path}onChooseItem(t){Na(A,t)}}(A.app);e.setPlaceholder("Pick a .stash file to import\u2026"),e.open()}async function Na(A,r){try{let e=new Uint8Array(await A.app.vault.readBinary(r)),t=await wi(A.app,e,{secretId:gi(r.basename)});if(!t)return;let i=await We(A.app,t,A.noteFolder,iA(A),{stripReserved:!0});A.tree.rebuild(A.noteFolder),A.render(),await A.log.append({type:"stash_import",id:S,payload:{from:r.path,into:A.noteFolder,noteCount:i.notesWritten,attachmentsWritten:i.attachmentsWritten,collisionsRenamed:i.collisionsRenamed}});try{await A.app.fileManager.trashFile(r)}catch{}A.plugin.importService.clearPendingEncrypted(r.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)`),A.plugin.notifications.show({message:s.join(" "),kind:"success",category:"import",folder:A.noteFolder})}catch(e){A.plugin.notifications.show({message:`Stashpad: import failed File: \`${r.name}\` Error: ${e.message} -Inspect with the buttons below \u2014 rename to .zip to crack it open in an archive tool.`,kind:"error",category:"import",affectedPaths:[r.path],actions:d.actionsForFile(r.path)}),console.error(e)}}function jd(d){let r=new Set,e=t=>{if(r.add(t),!!d.tree.get(t))for(let s of d.tree.getChildren(t))e(s.id)};return e(S),r}Zi();Zi();var Wl=new Set(["png","jpg","jpeg","gif","webp","svg","bmp","avif"]),Ds={nested:"Nested",flat:"Flat",everything:"Everything"},xs=[{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"}],Ns=class Ns extends k.ItemView{constructor(e,t){super(e);this.focusId=S;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.bulkRenderDepth=0;this.bulkSettleTimer=null;this.bootstrappedFolders=new Set;this.selection=new Set;this.lastSelected=null;this.cursorIdx=-1;this.pendingCursorId=null;this.currentChildren=[];this.modeSplit=null;this.modeEnterSubmits=!0;this.nextDestination=null;this.nextDestinationFolder=null;this.nextDestinationLabel=null;this.inListPicker=null;this.pickerEscapeAt=0;this.composerExitAt=0;this.listEl=null;this.composerInputEl=null;this.composerSplitBtn=null;this.composerEnterBtn=null;this.composerHelperEl=null;this.composerDestBtn=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.tapSettleUntil=0;this.aimedTapTargetId=null;this.aimedTapAt=0;this.stickyRowObserver=null;this.listResizeObserver=null;this.composerNarrowObserver=null;this.barOverflowRO=null;this.lastCursorByFocus=new Map;this.lastSelectionByFocus=new Map;this.expandedNotes=new Set;this.cursorExpandOverride=new Set;this.cursorHasMoved=!1;this.activeVersionByGroup=new Map;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.syncBurstTimes=[];this.autoSyncDeferActive=!1;this.autoSyncSettleTimer=null;this.autoSyncNotice=null;this.stampLastCursorTimer=null;this.stampSelectionTimer=null;this._renderT0=null;this.tinyOpacityPopover=null;this.tinyOpacityClose=null;this.lastListWidth=0;this.keydownWindow=window;this.onDocKeyDown=e=>{if(!this.viewRoot.isConnected||this.app.workspace.activeLeaf!==this.leaf||_a(e.target))return;let t=X().bindings;if(q(e,t.toggleSplit)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.toggleSplit();return}if(q(e,t.pickDestination)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.openDestinationPicker();return}if(q(e,t.search)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.openSearchModal();return}if(q(e,t.commandPalette)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.openStashpadCommandPalette();return}if(q(e,t.lockSelection)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdLockSelection();return}if(q(e,t.unlockAll)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdUnlockAll();return}if(q(e,t.moveToArchive)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdMoveToArchive();return}if(q(e,t.encryptDelete)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdEncryptDelete();return}if(q(e,t.searchInParent)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.openSearchInParentModal();return}if(q(e,t.exportStash)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdExportStash();return}if(q(e,t.importStash)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdImportStash();return}if(q(e,t.pickFolder)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdOpenFolderPicker();return}if(q(e,t.cloneStashpadTab)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdCloneStashpadTab();return}let i=e.target,s=!!i&&(i.tagName==="INPUT"||i.tagName==="TEXTAREA");if(e.key===" "&&!e.metaKey&&!e.ctrlKey&&!e.altKey&&!e.shiftKey&&!s){let l=this.composerInputEl;if(l){e.preventDefault(),e.stopPropagation(),l.focus();let c=l.value.length;l.setSelectionRange(c,c);return}}let n=!!i&&(i.tagName==="INPUT"||i.tagName==="TEXTAREA"||i.tagName==="BUTTON"||i.tagName==="SELECT");if(e.key==="Escape"&&i instanceof HTMLElement&&(i.tagName==="BUTTON"||i.tagName==="SELECT")&&this.viewRoot.contains(i)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.viewRoot.focus();return}if(this.inListPicker&&e.key==="Escape"){e.preventDefault(),e.stopPropagation(),this.inListPicker=null,this.pickerEscapeAt=Date.now();let l=this.listEl,c=!!l&&l.scrollTop+l.clientHeight>=l.scrollHeight-2,A=l?.scrollTop??0;if(this.render(),l){let h=c?l.scrollHeight:A;l.scrollTop=h,requestAnimationFrame(()=>{l.scrollTop=c?l.scrollHeight:A}),setTimeout(()=>{l.scrollTop=c?l.scrollHeight:A},60),this.revealCursorRow()}return}if(this.inListPicker&&!n){if(e.key==="ArrowDown"){e.preventDefault(),this.inListPicker.activeIdx=this.nextPickableIdx(this.inListPicker.activeIdx,1),this.repaintSelectionClasses(),this.revealRowAt(this.inListPicker.activeIdx);return}if(e.key==="ArrowUp"){e.preventDefault(),this.inListPicker.activeIdx=this.nextPickableIdx(this.inListPicker.activeIdx,-1),this.repaintSelectionClasses(),this.revealRowAt(this.inListPicker.activeIdx);return}if(e.key==="Enter"){e.preventDefault(),this.commitInListPicker();return}if(q(e,X().bindings.move)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.inListPicker=null,this.repaintSelectionClasses(),this.cmdMovePicker();return}return}if(n)return;if(q(e,t.delete)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdDelete();return}if(q(e,t.toggleComplete)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdToggleComplete();return}if(q(e,t.moveToTop)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdMoveToTop();return}if(q(e,t.moveToBottom)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdMoveToBottom();return}if(q(e,t.moveUp)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdMoveUp();return}if(q(e,t.moveDown)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdMoveDown();return}if(q(e,t.outdent)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdOutdent();return}if(q(e,t.setColor)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdSetColor();return}if(q(e,t.selectAll)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdSelectAll();return}if(q(e,t.swapWithParent)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdSwapWithParent();return}if(q(e,t.undo)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdUndo();return}if(q(e,t.redo)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdRedo();return}if(e.key===" "){e.preventDefault();let l=this.composerInputEl;if(l){l.focus();let c=l.value.length;l.setSelectionRange(c,c)}return}if(e.key==="ArrowDown"){e.preventDefault(),this.cursorIdx>=this.currentChildren.length-1?this.cursorIdx=0:this.cursorIdx++,this.selectCursor(e.shiftKey);return}if(e.key==="ArrowUp"){e.preventDefault(),this.cursorIdx<=0?this.cursorIdx=this.currentChildren.length-1:this.cursorIdx--,this.selectCursor(e.shiftKey);return}if(e.altKey&&e.key==="ArrowLeft"){e.preventDefault(),this.navigateBack();return}if(e.altKey&&e.key==="ArrowRight"){e.preventDefault(),this.navigateForward();return}if(e.key==="ArrowRight"){let l=this.currentChildren[this.cursorIdx];l&&(e.preventDefault(),this.navigateTo(l.id));return}if(e.key==="ArrowLeft"||e.key==="Backspace"){e.preventDefault(),this.navigateUp();return}if(e.key==="Escape"){if(e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),Date.now()-this.pickerEscapeAt<350||Date.now()-this.composerExitAt<400)return;if(this.plugin.noteClipboard&&this.plugin.noteClipboard.folder===this.noteFolder){this.plugin.clearNoteClipboard(),this.render();return}let l=this.firstSelectedId??(this.selection.size>0?this.selection.values().next().value:null);if(this.selection.clear(),this.firstSelectedId=null,l){let c=this.currentChildren.findIndex(A=>A.id===l);this.selection.add(l),this.lastSelected=l,c>=0&&(this.cursorIdx=c)}this.repaintSelectionClasses(),this.revealCursorRow();return}let o=X().bindings;if(q(e,o.pasteNotes)&&this.plugin.noteClipboard){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdPasteNotes();return}if(q(e,o.openAllTasks)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),He(this.plugin,"tasks");return}if(this.selection.size>0||this.cursorIdx>=0&&this.currentChildren[this.cursorIdx]){if(q(e,o.move)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdMovePicker();return}if(q(e,o.pickMove)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdInListPicker();return}if(q(e,o.merge)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdMerge();return}if(q(e,o.copy)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdCopy();return}if(q(e,o.copyNotes)&&!window.getSelection()?.toString()){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdCopyNotes();return}if(q(e,o.cutNotes)&&!window.getSelection()?.toString()){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdCutNotes();return}if(q(e,o.copyTree)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdCopyTree();return}if(q(e,o.copyLink)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdCopyStashpadLink();return}if(q(e,o.copyOutline)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdCopyOutline();return}if(q(e,o.copyCodeBlock)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdCopyCodeBlock();return}if(q(e,o.openEditor)){if(e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),e.shiftKey){let l=this.tree.get(this.focusId);l?.file&&this.cmdOpenInEditor(l)}else this.cmdOpenInEditor();return}if(q(e,o.openTab)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdOpenInNewStashpadTab();return}if(q(e,o.split)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdSplit();return}if(q(e,o.editParent)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdEditParent();return}if(q(e,o.edit)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdEdit();return}if(q(e,o.clone)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdClone();return}if(q(e,o.forkNote)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdForkNote();return}if(q(e,o.insertTemplate)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdInsertTemplate();return}if(q(e,o.toggleExpand)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdToggleExpand();return}if(q(e,o.expandAll)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdExpandAll();return}if(q(e,o.collapseAll)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdCollapseAll();return}if(q(e,o.togglePin)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdTogglePin();return}if(q(e,o.listPin)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdToggleListPin();return}if(q(e,o.toggleTask)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdToggleTask();return}if(q(e,o.setDue)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdSetDue();return}}if(this.currentChildren.length>0){if(q(e,o.jumpToTop)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.jumpToTop();return}if(q(e,o.jumpToBottom)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.jumpToBottom();return}}let a=this.tree.get(this.focusId);if(a?.file){if(q(e,o.openEditor)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdOpenInEditor(a);return}if(q(e,o.openTab)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdOpenInNewStashpadTab(a);return}}};this.openSearchInstance=null;this.fmSyncUnsubscribe=null;this.completedState=new Map;this.taskTaggedState=new Map;this.listPinnedState=new Map;this.pendingFocusIds=null;this.recentFmSelfWrites=new Map;this.onFileModify=e=>{if(!(!(e instanceof k.TFile)||e.extension!=="md")&&e.path.startsWith(this.noteFolder+"/")){if(this.fmSync.wasRecentSelfWrite(e.path)){this.bodyRenderer.retagMtime(e.path,e.stat.mtime);return}if(this.wasRecentFmSelfWrite(e.path)){if(this.bodyRenderer.retagMtime(e.path,e.stat.mtime),this.deferDuringSyncBurst())return;this.debouncedRender();return}this.bodyRenderer.evict(e),this.scheduleSlugRename(e),this.scheduleAttachmentSync(e),this.authorship.noteModify(e),!this.deferDuringSyncBurst()&&this.debouncedRender()}};this.onFileCreate=e=>{!(e instanceof k.TFile)||e.extension!=="md"||e.path.startsWith(this.noteFolder+"/")&&(this.deferDuringSyncBurst()||this.debouncedRender())};this.plugin=t,this.tree=new En(this.app),this.log=t.newLog(),this.integrity=new bn(this.tree,this.log),this.order=new xi(this.app),this.sortStore=new Fn(this.app),this.fmSync=new Sn(this.app,()=>this.tree),this.tree.setOrderProvider(i=>{let s=this.noteFolder,n=this.sortStore.getMode(s,i),o=n==="manual"?this.order.getOrder(s,i):nl(this,i,n);return this.hoistListPinned(i,o)}),this.debouncedRender=(0,k.debounce)(()=>{this.renderSuppressed()||this.render()},80),this.authorship=new Hn(this),this.dnd=new Rn(this),this.bodyRenderer=new Un(this,this,this.plugin.renderCacheStore)}getViewType(){return z}getDisplayText(){let e=(this.noteFolder||"").trim(),t=e.split("/").pop()||e||"Stashpad";if(this.focusId&&this.focusId!==S){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`${t} \u2014 ${n} \xB7 ${this.focusId}`}}return t}refreshHeaderTitle(){let e=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!==e&&i.setText(e)}getIcon(){return this.plugin.getFolderIcon(this.noteFolder)??"list-tree"}async onOpen(){let e=this.contentEl;e.empty(),e.addClass("stashpad-scroll-host"),this.viewRoot=e.createDiv({cls:"stashpad-view"}),this.viewRoot.setAttribute("tabindex","0"),this.viewRoot.addEventListener("focusin",()=>dn(this)),this.viewRoot.addEventListener("click",()=>dn(this)),this.viewRoot.addEventListener("mouseup",l=>{l.button===3?(l.preventDefault(),this.navigateBack()):l.button===4&&(l.preventDefault(),this.navigateForward())}),this.viewRoot.addEventListener("auxclick",l=>{l.button===3?(l.preventDefault(),this.navigateBack()):l.button===4&&(l.preventDefault(),this.navigateForward())}),dn(this),this.registerInterval(window.setInterval(()=>this.authorship.pruneContribMaps(),6e4));let t=null,i=()=>{t||(t=new k.Scope(this.app.scope),t.register([],"Escape",()=>{if(this.inListPicker)return this.inListPicker=null,this.pickerEscapeAt=Date.now(),this.repaintSelectionClasses(),!1;if(Date.now()-this.pickerEscapeAt<350||Date.now()-this.composerExitAt<400)return!1;if(this.selection.size>1){let l=this.firstSelectedId??this.selection.values().next().value??null;if(this.selection.clear(),this.firstSelectedId=null,l){let c=this.currentChildren.findIndex(A=>A.id===l);this.selection.add(l),this.lastSelected=l,c>=0&&(this.cursorIdx=c)}this.render(),this.revealCursorRow()}return!1}),this.app.keymap?.pushScope(t))},s=()=>{if(t){try{this.app.keymap?.popScope(t)}catch{}t=null}};this.viewRoot.addEventListener("focusin",i),this.viewRoot.addEventListener("focusout",l=>{let c=l.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",l=>{if(l.extension!=="md")return;let c=this.app.metadataCache.getFileCache(l)?.frontmatter;this.completedState.set(l.path,!!c?.completed),this.taskTaggedState.set(l.path,this.taggedFromFm(c))})),this.registerEvent(this.app.vault.on("rename",(l,c)=>{for(let A of[this.completedState,this.taskTaggedState])A.has(c)&&(A.set(l.path,A.get(c)),A.delete(c))})),this.registerEvent(this.app.vault.on("delete",l=>{this.completedState.delete(l.path),this.taskTaggedState.delete(l.path);let c=l.path.lastIndexOf("/"),A=(c>=0?l.path.slice(0,c):"").replace(/\/+$/,"");l.path.endsWith(".md")&&A===this.noteFolder.replace(/\/+$/,"")&&(this.tree.rebuild(this.noteFolder),this.debouncedRender())})),this.detachSettings=Rr(()=>{this.loadConfig();let l=this.plugin.settings.drafts?.[this.noteFolder]??"",c=this.composerInputEl?.value??"";l===""&&this.composerDraft!==""&&c===""?(this.composerDraft="",this.composerInputEl&&(this.composerInputEl.value="")):l===""&&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),this.keydownWindow=this.containerEl?.ownerDocument?.defaultView??window,this.keydownWindow.addEventListener("keydown",this.onDocKeyDown,!0),this.loadConfig();try{await this.bootstrapFolder()}catch(l){let c=l?.message??"";/already exists/i.test(c)||console.warn("[Stashpad] bootstrapFolder failed:",l)}this.tree.rebuild(this.noteFolder),this.installFmSyncActivityNotice(),this.backfillFrontmatterSync(),this.plugin.maybeSweepFolder(this.noteFolder),this.defaultCursorToLast(),this.refreshHeaderTitle(),await this.loadDraftsForFolder();try{let l=this.plugin.loadLastCursor(this.noteFolder);for(let[c,A]of l)this.lastCursorByFocus.set(c,A);this.lastSelectionByFocus=this.plugin.loadLastSelection(this.noteFolder),this.activeVersionByGroup=this.plugin.loadActiveVersions(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 a=this.foldRestoredSelection(n);a&&(this.pendingFocusIds=a),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)}),X().focusComposerOnOpen?this.focusComposer():this.focusView(),this.registerEvent(this.app.workspace.on("active-leaf-change",l=>{l===this.leaf?X().focusComposerOnOpen?this.focusComposer():this.focusView():this.stickToListBottom=!1}))}renderSuppressed(){return this.bulkRenderDepth>0||this.bulkSettleTimer!=null||this.autoSyncDeferActive||this.plugin.rebootstrapInProgress||this.plugin.okfRebuildingFolders.has(this.noteFolder)}beginBulkRender(){this.bulkRenderDepth++,this.bulkSettleTimer!=null&&(window.clearTimeout(this.bulkSettleTimer),this.bulkSettleTimer=null)}endBulkRender(e=500){this.bulkRenderDepth>0&&this.bulkRenderDepth--,!(this.bulkRenderDepth>0)&&(this.bulkSettleTimer!=null&&window.clearTimeout(this.bulkSettleTimer),this.bulkSettleTimer=window.setTimeout(()=>{this.bulkSettleTimer=null,this.viewRoot?.isConnected&&(this.tree.rebuild(this.noteFolder),this.render())},e))}deferDuringSyncBurst(){if(this.plugin.rebootstrapInProgress)return!1;let e=Date.now();this.syncBurstTimes.push(e);let t=e-2e3;for(;this.syncBurstTimes.length&&this.syncBurstTimes[0]<t;)this.syncBurstTimes.shift();return!this.autoSyncDeferActive&&this.syncBurstTimes.length>=6&&(this.autoSyncDeferActive=!0,this.autoSyncNotice=new k.Notice("Stashpad: syncing \u2014 list updates paused until it settles\u2026",0)),this.autoSyncDeferActive?(this.autoSyncSettleTimer!=null&&window.clearTimeout(this.autoSyncSettleTimer),this.autoSyncSettleTimer=window.setTimeout(()=>this.endAutoSyncDefer(),1500),!0):!1}endAutoSyncDefer(){this.autoSyncSettleTimer=null,this.autoSyncDeferActive=!1,this.syncBurstTimes=[],this.autoSyncNotice?.hide(),this.autoSyncNotice=null,this.forceReconcileRender()}forceReconcileRender(){this.viewRoot?.isConnected&&(this.tree.rebuild(this.noteFolder),this.render())}scheduleTreeReconcile(){this.renderSuppressed()||this.treeReconcileTimer==null&&(this.treeReconcileTimer=window.setTimeout(()=>{if(this.treeReconcileTimer=null,!this.viewRoot?.isConnected)return;let e=this.noteFolder,t=e+"/",i=0;for(let s of this.app.vault.getMarkdownFiles()){let n=s.parent?.path?.replace(/\/+$/,"")??"";if(!(n===e||e!==""&&n.startsWith(t)))continue;let o=this.app.metadataCache.getFileCache(s)?.frontmatter?.id;typeof o=="string"&&o&&i++}i!==this.tree.fileBackedCount()&&(this.tree.rebuild(e),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(!X().focusComposerOnOpen)return;let e=()=>{if(!this.viewRoot?.isConnected||Date.now()<this.suppressComposerFocusUntil||Date.now()<this.plugin.suppressComposerAutofocusUntil)return;let t=document.activeElement;t&&(t.tagName==="INPUT"||t.tagName==="TEXTAREA")&&t!==this.composerInputEl||(t&&t.tagName==="BUTTON"&&this.viewRoot.contains(t),this.composerInputEl?.focus({preventScroll:!0}))};requestAnimationFrame(e),setTimeout(e,50),setTimeout(e,200)}async onClose(){Mr(this),this.debouncedRender?.cancel?.(),this.tinyOpacityClose?.(),this.detachTreeHook?.(),this.detachSettings?.(),this.app.vault.off("modify",this.onFileModify),this.app.vault.off("create",this.onFileCreate),this.keydownWindow.removeEventListener("keydown",this.onDocKeyDown,!0),this.listResizeObserver?.disconnect(),this.listResizeObserver=null,this.stickyRowObserver?.disconnect(),this.stickyRowObserver=null,this.bodyRenderer.dispose(),this.barOverflowRO?.disconnect(),this.barOverflowRO=null,this.composerNarrowObserver?.disconnect(),this.composerNarrowObserver=null,this.focusedMiniObserver?.disconnect(),this.focusedMiniObserver=null,this.treeReconcileTimer!=null&&(window.clearTimeout(this.treeReconcileTimer),this.treeReconcileTimer=null),this.autoSyncSettleTimer!=null&&(window.clearTimeout(this.autoSyncSettleTimer),this.autoSyncSettleTimer=null),this.autoSyncNotice?.hide(),this.autoSyncNotice=null,this.composerAutocomplete?.detach(),this.composerAutocomplete=null;for(let e of this.slugDebouncers.values())e.cancel();for(let e of this.attachmentDebouncers.values())e.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(e){let t=e;t?.focusId&&(this.focusId=t.focusId),t?.timeFilter&&(this.timeFilter=t.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(e,t){let i=e??null;if(i){"folderOverride"in i&&(this.folderOverride=i.folderOverride??null),i.timeFilter&&(this.timeFilter=i.timeFilter),i.focusId&&(this.focusId=i.focusId),i.cursorId&&(this.pendingCursorId=i.cursorId),"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(e,t),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[A,h]of c)this.lastCursorByFocus.set(A,h);this.lastSelectionByFocus=this.plugin.loadLastSelection(this.noteFolder),this.activeVersionByGroup=this.plugin.loadActiveVersions(this.noteFolder)}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"};let l=this.foldRestoredSelection(o);l&&(this.pendingFocusIds=l),this.render(a),this.scheduleSelectionRestore()}}focus(){this.viewRoot?.focus({preventScroll:!0})}foldRestoredSelection(e){let t=this.lastSelectionByFocus.get(this.focusId)??null;if(!t||!t.length)return null;let i=t.filter(s=>!!this.tree.get(s));return i.length?e&&i.includes(e)?[e,...i.filter(s=>s!==e)]:i:null}stampSelection(e=!1){let t=[...this.selection],i=()=>{try{this.plugin.saveLastSelection(this.noteFolder,this.focusId,t)}catch{}};if(this.stampSelectionTimer!=null&&(window.clearTimeout(this.stampSelectionTimer),this.stampSelectionTimer=null),e){i();return}this.stampSelectionTimer=window.setTimeout(()=>{this.stampSelectionTimer=null,i()},400)}scheduleSelectionRestore(){let e=this.lastSelectionByFocus.get(this.focusId);if(!e||!e.length)return;let t=()=>{let i=e.filter(a=>this.currentChildren.some(l=>l.id===a));if(!i.length)return;let s=[...this.selection],n=new Set(i);if(s.length<i.length&&s.every(a=>n.has(a))){this.selection.clear();for(let a of i)this.selection.add(a);this.firstSelectedId=i[0],this.lastSelected=i[i.length-1],this.repaintSelectionClasses()}};for(let i of[120,400,900,1600])window.setTimeout(t,i)}loadConfig(){let e=(this.plugin?.settings?.folder??"Stashpad").trim().replace(/^\/+|\/+$/g,""),i=this.folderOverride?.trim().replace(/^\/+|\/+$/g,"")||null||e||"Stashpad";i!==this.noteFolder?(this.noteFolder=i,this.tree.rebuild(this.noteFolder)):this.noteFolder=i}captureNavSnapshot(){return{folder:this.noteFolder,focusId:this.focusId}}recordNavState(e={}){let t=this.captureNavSnapshot(),i=this.navBackStack[this.navBackStack.length-1];i&&i.folder===t.folder&&i.focusId===t.focusId||(this.navBackStack.push(t),e.keepForward||(this.navForwardSnapshots=[]))}async setFolderOverride(e,t={}){let i=e?.trim().replace(/^\/+|\/+$/g,"")||null;if(i&&this.isReservedFolder(i)){new k.Notice(`"${i}" is a reserved Stashpad subfolder (imports/exports/attachments). Pick a different folder.`);return}if((i||null)!==(this.folderOverride||null)){t.skipHistory||this.recordNavState(),this.folderOverride=i,this.focusId=S,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 e=[];for(let t of this.app.vault.getAllLoadedFiles())if(t instanceof k.TFolder){if(t.path==="/"||t.path===""||t.path.startsWith(".")||this.isReservedFolder(t.path))continue;e.push(t.path)}return e.sort((t,i)=>t.localeCompare(i))}isReservedFolder(e){let t=e.split("/").filter(Boolean).pop()??"";return t?new Set([this.plugin.settings.importDropFolder,this.plugin.settings.exportFolder,"_attachments","_processed","_authors"].map(s=>(s??"").trim().replace(/^\/+|\/+$/g,"")).filter(Boolean)).has(t):!1}persistFocus(){try{this.app.workspace.requestSaveLayout()}catch{}}cmdUndo(){let e=this.plugin.getUndoStack(this.noteFolder);if(!e.canUndo()){new k.Notice("Nothing to undo.");return}let t=e.peekUndoLabel(),i=this.plugin.notifications.recent()[0]?.category??"system";e.undo().then(()=>this.plugin.notifications.show({message:`Undid: ${t}`,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 e=this.plugin.getUndoStack(this.noteFolder);if(!e.canRedo()){new k.Notice("Nothing to redo.");return}let t=e.peekRedoLabel(),i=this.plugin.notifications.recent()[0]?.category??"system";e.redo().then(()=>this.plugin.notifications.show({message:`Redid: ${t}`,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(e,t){let i=[],s=new Set;for(let l of e)!l.file||s.has(l.file.path)||(s.add(l.file.path),i.push(l.file));let n=await Promise.all(i.map(l=>this.app.vault.read(l))),o=i.map((l,c)=>({path:l.path,content:n[c]})),a=[];if(t){let l=new Set,c=[];for(let h of n)for(let p of this.extractAttachments(this.stripFrontmatter(h))){let f=this.app.metadataCache.getFirstLinkpathDest(p,"");f&&!l.has(f.path)&&(l.add(f.path),c.push(f))}let A=await Promise.all(c.map(h=>this.app.vault.readBinary(h)));for(let h=0;h<c.length;h++)a.push({path:c[h].path,data:A[h]})}return{notes:o,attachments:a}}fileForNote(e,t){return(e?this.tree.get(e)?.file:null)??this.app.vault.getAbstractFileByPath(t)}async restoreSnapshots(e,t){for(let s of e.attachments)try{await this.app.vault.adapter.exists(s.path)||await this.app.vault.createBinary(s.path,s.data)}catch{}for(let s of e.notes)try{let n=s.content.split(` ----`)[0]??"",a=/^id:\s*["']?([^"'\s]+)/m.exec(n)?.[1];if(a&&this.tree.get(a)?.file)continue;await this.app.vault.adapter.exists(s.path)||await this.app.vault.create(s.path,s.content)}catch{}let i=()=>{t&&t.some(n=>this.tree.get(n))&&(this.pendingFocusIds=t.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 e.notes){let n=this.tree.idForPath(s.path);n&&this.fmSync.schedule(n)}},500)}async trashNotesAndAttachments(e){let t=new Set;for(let i of e.notes){let s=this.tree.idForPath(i.path);if(!s)continue;let n=this.tree.get(s);n?.parent&&t.add(n.parent)}for(let i of e.notes){let s=this.app.vault.getAbstractFileByPath(i.path);if(s)try{await this.app.fileManager.trashFile(s)}catch{}}for(let i of e.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 t)this.fmSync.scheduleParentOfDeleted(i)}async loadDraftsForFolder(){if(this.draftsLoadedFor===this.noteFolder)return;this.draftsLoadedFor=this.noteFolder;let e=this.plugin.settings.drafts??{};this.composerDraft=e[this.noteFolder]??"",console.debug("[Stashpad] loadDrafts",{folder:this.noteFolder,has:!!e[this.noteFolder],available:Object.keys(e)})}async saveDraft(e){try{let t=this.noteFolder;if((this.plugin.settings.drafts?.[t]??"")===e)return;let s={...this.plugin.settings.drafts??{}};e.length===0?delete s[t]:s[t]=e,this.plugin.settings.drafts=s,e.length===0?await this.plugin.saveSettings():await this.plugin.persistSettingsQuiet()}catch(t){console.warn("Stashpad: drafts save failed",t)}}async recordLastSubmitted(e){try{let t={...this.plugin.settings.lastSubmitted??{}};t[this.noteFolder]=e,this.plugin.settings.lastSubmitted=t,await this.plugin.persistSettingsQuiet()}catch{}}hasRestorableDraft(){let e=this.plugin.settings.drafts?.[this.noteFolder];if(!e||!e.trim())return!1;let t=this.plugin.settings.lastSubmitted?.[this.noteFolder];return!(t&&t===e)}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 t=(0,k.moment)();switch(this.timeFilter){case"day":return t.startOf("day").valueOf();case"week":return t.startOf("isoWeek").valueOf();case"month":return t.startOf("month").valueOf();case"year":return t.startOf("year").valueOf()}}let e=Date.now();switch(this.timeFilter){case"day":return e-864e5;case"week":return e-7*864e5;case"month":return e-30*864e5;case"year":return e-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(e){let t={...this.plugin.settings.includeAttachmentsInEverything??{}};e?t[this.noteFolder]=!0:delete t[this.noteFolder],this.plugin.settings.includeAttachmentsInEverything=t,await this.plugin.saveSettings()}currentEncryptionFilter(){return this.plugin.settings.encryptionFilter?.[this.noteFolder]??"all"}async setEncryptionFilter(e){let t={...this.plugin.settings.encryptionFilter??{}};e==="all"?delete t[this.noteFolder]:t[this.noteFolder]=e,this.plugin.settings.encryptionFilter=t,await this.plugin.saveSettings()}currentHideChildless(){return!!this.plugin.settings.hideChildlessNotes?.[this.noteFolder]}async setHideChildless(e){let t={...this.plugin.settings.hideChildlessNotes??{}};e?t[this.noteFolder]=!0:delete t[this.noteFolder],this.plugin.settings.hideChildlessNotes=t,await this.plugin.saveSettings()}currentHideCompleted(){return!!this.plugin.settings.hideCompletedNotes?.[this.noteFolder]}async setHideCompleted(e){let t={...this.plugin.settings.hideCompletedNotes??{}};e?t[this.noteFolder]=!0:delete t[this.noteFolder],this.plugin.settings.hideCompletedNotes=t,await this.plugin.saveSettings()}currentAttachmentsOnly(){return!!this.plugin.settings.attachmentsOnlyNotes?.[this.noteFolder]}async setAttachmentsOnly(e){let t={...this.plugin.settings.attachmentsOnlyNotes??{}};e?t[this.noteFolder]=!0:delete t[this.noteFolder],this.plugin.settings.attachmentsOnlyNotes=t,await this.plugin.saveSettings()}nodeHasAttachment(e){if(!e.file)return!1;let t=this.app.metadataCache.getFileCache(e.file)?.frontmatter?.attachments;return Array.isArray(t)&&t.length>0}hasAttachmentInSubtree(e){if(this.nodeHasAttachment(e))return!0;for(let t of this.tree.getChildren(e.id))if(this.hasAttachmentInSubtree(t))return!0;return!1}hasIncompleteDescendant(e){for(let t of e.children){let i=this.tree.get(t);if(i&&(!this.isCompleted(i)||this.hasIncompleteDescendant(i)))return!0}return!1}collectEmbeddedAttachmentPaths(){let e=new Set,t=this.noteFolder,i=this.app.vault.getAbstractFileByPath(t);if(!(i instanceof k.TFolder))return e;let s=[i];for(;s.length;){let n=s.pop();for(let o of n.children){if(o instanceof k.TFolder){s.push(o);continue}if(!(o instanceof k.TFile)||o.extension!=="md")continue;let a=this.app.metadataCache.getFileCache(o)?.frontmatter;if(!(!a||!Array.isArray(a.attachments)))for(let l of a.attachments){if(typeof l!="string")continue;let c=Jt(l),A=this.app.metadataCache.getFirstLinkpathDest(c,o.path);A?e.add(A.path):e.add(c)}}}return e}collectFileItems(e){let t=this.noteFolder,i=this.app.vault.getAbstractFileByPath(t);if(!(i instanceof k.TFolder))return[];let s=this.currentIncludeAttachments(),n=s?new Set:this.collectEmbeddedAttachmentPaths(),o=new Set(["_authors","_imports","_exports","_processed","_attachments","_archive",".archive"]),a=[],l=[i];for(;l.length;){let c=l.pop();for(let A of c.children){if(A instanceof k.TFolder){let h=A.name;if(c===i&&o.has(h)||c===i&&h==="_attachments"&&!s)continue;l.push(A);continue}A instanceof k.TFile&&A.extension!=="md"&&(A.name===".stashpad-order.json"||A.name===".stashpad-sort.json"||!s&&n.has(A.path)||a.push(A))}}return a}populateListBody(e,t){if(this.lastListWidth=e.clientWidth||this.lastListWidth,this.bodyRenderer.arm(),this.pendingCursorId){let A=this.currentChildren.findIndex(h=>h.id===this.pendingCursorId);A>=0&&(this.cursorIdx=A,this.selection.clear(),this.selection.add(this.pendingCursorId),this.lastSelected=this.pendingCursorId,this.pendingCursorId=null)}t.file&&k.Platform.isMobile&&!this.compactMode&&(this.renderFocusedHeaderMini(e,t),this.renderFocusedHeader(e,t));let i=this.currentViewMode(),s=i==="everything"?this.collectFileItems(t.id):[],n=A=>A.created&&Number.isFinite(Date.parse(A.created))?Date.parse(A.created):Number.POSITIVE_INFINITY,o=this.currentEncryptionFilter(),a;if(o==="unlocked")a=[];else if(i==="nested")a=this.plugin.lockedSubtreesFor(this.noteFolder,t.id);else{let A=new Set([t.id,...this.currentChildren.map(p=>p.id)]),h=new Set;a=[];for(let p of A)for(let f of this.plugin.lockedSubtreesFor(this.noteFolder,p))h.has(f.blob)||(h.add(f.blob),a.push(f))}let l=a.map(A=>({lk:A,ts:n(A)})).sort((A,h)=>A.ts-h.ts),c=i==="nested"&&this.sortStore.getMode(this.noteFolder,t.id)==="manual";if(this.currentChildren.length===0&&s.length===0&&l.length===0)e.createDiv({cls:"stashpad-empty",text:"No notes here yet. Type below to add one."});else if(c&&l.length>0){let A=new Map(this.currentChildren.map((g,I)=>[g.id,I])),h=new Map;for(let{lk:g}of l)g.rootId&&h.set(g.rootId,g);let p=this.currentChildren.map(g=>g.id),f=l.map(({lk:g})=>g).filter(g=>g.rootId).sort((g,I)=>n(I)-n(g)),u=!0;for(;f.length&&u;){u=!1;for(let g=0;g<f.length;g++){let I=f[g],m=I.prevSibling??null,C;if(m==null)C=0;else{let B=p.indexOf(m);if(B<0)continue;C=B+1}p.splice(C,0,I.rootId),f.splice(g,1),g--,u=!0}}for(let g of f)p.push(g.rootId);for(let g of p){let I=A.get(g);if(I!==void 0)this.renderNote(e,this.currentChildren[I],I);else{let m=h.get(g);m&&this.renderLockedPlaceholder(e,m)}}for(let g of s.slice().sort((I,m)=>I.stat.ctime-m.stat.ctime))this.renderFileRow(e,g)}else if(s.length===0){let A=0;for(let h=0;h<this.currentChildren.length;h++){let p=Number.isFinite(Date.parse(this.currentChildren[h].created))?Date.parse(this.currentChildren[h].created):0;for(;A<l.length&&l[A].ts<=p;)this.renderLockedPlaceholder(e,l[A].lk),A++;this.renderNote(e,this.currentChildren[h],h)}for(;A<l.length;)this.renderLockedPlaceholder(e,l[A].lk),A++}else{let A=[...this.currentChildren.map((h,p)=>({kind:"note",ts:Number.isFinite(Date.parse(h.created))?Date.parse(h.created):0,idx:p})),...s.map(h=>({kind:"file",ts:h.stat.ctime,file:h})),...l.map(h=>({kind:"lock",ts:h.ts,lk:h.lk}))];A.sort((h,p)=>h.ts-p.ts);for(let h of A)h.kind==="note"?this.renderNote(e,this.currentChildren[h.idx],h.idx):h.kind==="file"?this.renderFileRow(e,h.file):this.renderLockedPlaceholder(e,h.lk)}t.file&&k.Platform.isMobile&&!this.compactMode&&this.installFocusedMiniObserver(e)}renderLockedPlaceholder(e,t){let i=e.createDiv({cls:"stashpad-locked-row"});t.created&&i.createSpan({cls:"stashpad-note-time stashpad-locked-time",text:this.formatTime(t.created)});let s=i.createSpan({cls:"stashpad-locked-icon"});(0,k.setIcon)(s,"lock");let n=!t.title;i.createSpan({cls:"stashpad-locked-title",text:n?"Locked note":t.title}),i.createSpan({cls:"stashpad-locked-count",text:t.count>1?`${t.count} notes \xB7 locked`:"locked"});let o=i.createEl("button",{cls:"stashpad-locked-unlock",text:"Unlock"});(0,k.setIcon)(o.createSpan({cls:"stashpad-btn-icon"}),"unlock");let a=async A=>{A.preventDefault(),A.stopPropagation();let h=(this.plugin.settings.lockedSubtrees??[]).find(I=>I.blob===t.blob),p=t.rootId??h?.rootId??null,f=t.parentId??h?.parentId??S,u=t.prevSibling??h?.prevSibling??null;if(await this.plugin.unlockBundleAt(t.blob)){if(this.selection.clear(),this.lastSelected=null,p){let I=this.order.getOrder(this.noteFolder,f),m=this.sortStore.getMode(this.noteFolder,f)==="manual";if(I.length===0&&m&&(I=this.tree.getChildren(f).map(C=>C.id)),I.length>0){let C=I.filter(E=>E!==p),B=u&&C.includes(u)?C.indexOf(u)+1:0;C.splice(Math.max(0,B),0,p),this.order.setOrder(this.noteFolder,f,C),this.order.flush(this.noteFolder)}this.pendingCursorId=p}if(this.render(),p){let I=this.noteFolder,m=t.blob;this.plugin.getUndoStack(I).push({label:"Unlock note",undo:async()=>{let C=await this.plugin.lockNoteSubtree(I,p,u,{silent:!0});C&&(m=C.blobPath),this.render()},redo:async()=>{try{await this.plugin.unlockBundleAt(m,{silent:!0})}catch{}this.render()}})}}};o.onclick=a;let l=A=>{A.preventDefault(),A.stopPropagation();let h=new k.Menu;xn(h,{app:this.app,plugin:this.plugin,descriptor:{blob:t.blob,rootId:t.rootId,count:t.count,folder:this.noteFolder},unlockLabel:"Decrypt (unlock)",onUnlock:()=>void a(A),onChange:()=>this.render(),fullParity:!0,confirmDelete:!0}),h.showAtMouseEvent(A)};i.oncontextmenu=l;let c=i.createEl("button",{cls:"stashpad-pencil stashpad-locked-menu"});(0,k.setIcon)(c,"more-vertical"),c.setAttr("aria-label","Locked note menu"),c.onclick=A=>l(A),i.setAttr("aria-label",`${n?"Locked note":`Locked: ${t.title}`}. Use the Unlock button to decrypt.`)}refreshList(){if(!this.listEl){this.render();return}let e=this.tree.get(this.focusId)??this.tree.getRoot();this.currentChildren=this.filterChildren(this.collectViewItems(e.id)),this.cursorIdx>=this.currentChildren.length&&(this.cursorIdx=this.currentChildren.length-1);let t=this.listEl.scrollTop+this.listEl.clientHeight>=this.listEl.scrollHeight-2,i=this.listEl.scrollTop;this.listEl.empty(),this.populateListBody(this.listEl,e),t?this.listEl.scrollTop=this.listEl.scrollHeight:this.listEl.scrollTop=i}renderFileRow(e,t){if(this.currentEncryptionFilter()==="locked")return;let i=e.createDiv({cls:"stashpad-file-row"});i.dataset.path=t.path,i.createDiv({cls:"stashpad-file-meta"}).createSpan({cls:"stashpad-file-time",text:this.formatTime(new Date(t.stat.ctime).toISOString())});let n=i.createDiv({cls:"stashpad-file-body"});n.createSpan({cls:"stashpad-file-name",text:t.name}),n.createSpan({cls:"stashpad-file-ext",text:t.extension.toUpperCase()}),i.title=`${t.path} \u2014 click to open`,i.onclick=o=>{o.preventDefault(),this.app.workspace.openLinkText(t.path,"",!1)}}async setViewMode(e){let t={...this.plugin.settings.viewModes??{}};e==="nested"?delete t[this.noteFolder]:t[this.noteFolder]=e,this.plugin.settings.viewModes=t,await this.plugin.saveSettings()}collectViewItems(e){let t=this.currentViewMode(),i=this.currentHideChildless(),s=this.tree.getChildren(e),n=i?s.filter(l=>l.children.length>0):s;if(t==="nested")return n;let o=[],a=l=>{o.push(l);for(let c of this.tree.getChildren(l.id))a(c)};for(let l of n)a(l);return o}filterChildren(e){e=this.collapseVersions(e);let t=this.timeFilterCutoff(),i=this.tagFilter?.toLowerCase(),s=this.colorFilter?.toLowerCase()??null,n=this.currentHideCompleted(),o=this.currentAttachmentsOnly(),a=this.importedOnly,l=this.authorFilter;return!t&&!i&&!s&&!n&&!o&&!a&&!l?e:e.filter(c=>{if(a&&(!c.file||this.app.metadataCache.getFileCache(c.file)?.frontmatter?.imported!==!0))return!1;if(l){if(!c.file)return!1;let A=gt(this.app.metadataCache.getFileCache(c.file)?.frontmatter?.author);if(!A||A.id!==l)return!1}if(t&&c.created){let A=Date.parse(c.created);if(!Number.isNaN(A)&&A<t)return!1}if(i){if(!c.file)return!1;if(this.tagFilter===Yt){if(!this.nodeHasAnyTag(c))return!1}else if(this.tagFilter===zt){if(this.nodeHasAnyTag(c))return!1}else if(!this.nodeHasTag(c,i))return!1}return!(s&&(this.colorForNode(c)?.toLowerCase()??null)!==s||n&&this.isCompleted(c)&&!this.hasIncompleteDescendant(c)||o&&!this.hasAttachmentInSubtree(c))})}collapseVersions(e){if(!this.plugin.settings.enableSheetVersions)return e;let t=new Map,i=!1;for(let n of e){let o=ke(this.app,n);if(!Vi(o))continue;i=!0;let a=_e(o),l=t.get(a);l?l.push(n):t.set(a,[n])}if(!i)return e;let s=new Set;for(let[n,o]of t){let a=this.activeVersionNode(n,o);a&&s.add(a.id)}return e.filter(n=>Vi(ke(this.app,n))?s.has(n.id):!0)}activeVersionNode(e,t){let i=this.activeVersionByGroup.get(e);if(i){let s=t.find(n=>n.id===i);if(s)return s}return qa(this.app,t)}setActiveVersion(e,t){this.activeVersionByGroup.set(e,t),this.plugin.saveActiveVersion(this.noteFolder,e,t),this.render()}nodeHasAnyTag(e){if(!e.file)return!1;let t=this.app.metadataCache.getFileCache(e.file);if(!t)return!1;if(t.tags&&t.tags.length>0)return!0;let i=t.frontmatter?.tags;return!!(i&&(Array.isArray(i)?i:[i]).some(n=>typeof n=="string"&&n.trim().length>0))}nodeHasTag(e,t){if(!e.file)return!1;let i=this.app.metadataCache.getFileCache(e.file);if(!i)return!1;if(i.tags){for(let n of i.tags)if((n.tag||"").replace(/^#/,"").toLowerCase()===t)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()===t)return!0}return!1}collectFolderTags(){let e=new Map,t=this.tree.getChildren(this.focusId);for(let s of t){if(!s.file)continue;let n=this.app.metadataCache.getFileCache(s.file);if(n?.tags)for(let a of n.tags){let l=(a.tag||"").replace(/^#/,"");l&&e.set(l,(e.get(l)??0)+1)}let o=n?.frontmatter?.tags;if(o){let a=Array.isArray(o)?o:[o];for(let l of a){if(typeof l!="string")continue;let c=l.replace(/^#/,"");c&&e.set(c,(e.get(c)??0)+1)}}}let i=[...e.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(e){return e&&e.split("/").map(t=>t.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 e=new Map,t=this.tree.getChildren(this.focusId);for(let s of t){let n=this.colorForNode(s);if(!n)continue;let o=n.toLowerCase();e.set(o,(e.get(o)??0)+1)}let i=[...e.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 e=this.tree.get(this.focusId)??this.tree.getRoot(),t=this.filterChildren(this.collectViewItems(e.id));this.cursorIdx=t.length-1,this.selection.clear(),t.length>0&&(this.selection.add(t[t.length-1].id),this.lastSelected=t[t.length-1].id)}stampSelectedCursor(e=!1){this.stampSelection(e);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(e){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 e=this.listEl;if(!e)return null;let t=e.getBoundingClientRect().top,i=Array.from(e.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-t;if(a>=0){s={id:o,offsetFromListTop:a};break}s={id:o,offsetFromListTop:a}}return s}restoreScrollAnchor(e,t){let i=this.listEl;if(i){if(e){let s=i.querySelector(`[data-id="${e.id}"]`);if(s){let n=i.getBoundingClientRect().top,o=s.getBoundingClientRect().top-n;i.scrollTop+=o-e.offsetFromListTop;return}}t>0&&(i.scrollTop=t)}}render(e){if(Te.enabled&&(this._renderT0=performance.now()),!this.viewRoot?.isConnected)return;this.pendingRenderPolicy=e??{kind:"preserve"},this.loadConfig();let t=this.viewRoot,i=this.listEl?.scrollTop??0,n=(e??{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);t.empty(),t.toggleClass("is-mobile",k.Platform.isMobile),t.toggleClass("is-tiny",this.tinyMode),t.toggleClass("is-compact",this.compactMode);let l=this.containerEl.closest(".workspace-leaf");l&&(l.classList.toggle("stashpad-is-tiny",this.tinyMode),l.classList.toggle("stashpad-is-compact",this.compactMode));let c=this.containerEl.closest(".workspace-tabs");if(c&&c.classList.toggle("stashpad-has-tiny",this.tinyMode),this.tinyMode)this.renderTinyHeader(t);else{let u=this.compactMode&&k.Platform.isMobile;(!this.compactMode||k.Platform.isMobile)&&this.renderTimeFilterBar(t),u||this.renderBreadcrumb(t)}let A=this.tree.get(this.focusId)??this.tree.getRoot();A.file&&!k.Platform.isMobile&&!this.tinyMode&&!this.compactMode&&this.renderFocusedHeader(t,A),this.currentChildren=this.filterChildren(this.collectViewItems(A.id));let h=!1;if(this.autoSelectNewest&&this.currentChildren.length>0){let u=this.currentChildren[this.currentChildren.length-1];this.cursorIdx=this.currentChildren.length-1,this.selection.clear(),this.selection.add(u.id),this.lastSelected=u.id,this.autoSelectNewest=!1,h=!0}else if(this.pendingFocusIds){let u=this.pendingFocusIds;this.pendingFocusIds=null,this.selection.clear();let g=-1;for(let I of u){let m=this.currentChildren.findIndex(C=>C.id===I);m>=0&&(this.selection.add(I),g<0&&(g=m))}this.cursorIdx=g,g>=0&&(this.lastSelected=u.find(I=>this.currentChildren.some(m=>m.id===I))??null)}else this.cursorIdx>=this.currentChildren.length&&(this.cursorIdx=this.currentChildren.length-1);let p=t.createDiv({cls:"stashpad-list"});if(this.listEl=p,this.dnd.attachListDnD(p),this.populateListBody(p,A),this.renderComposer(t),k.Platform.isMobile&&this.renderMobileNav(t),this._renderT0!=null&&(Te.record("render.total",performance.now()-this._renderT0),this._renderT0=null),this.plugin.notifyStashpadContentChanged(),h&&this.plugin.notifyStashpadSelectionChanged(),this.focusComposerOnNextRender){this.focusComposerOnNextRender=!1;let u=this.pendingComposerCaret;this.pendingComposerCaret=null;let g=this.composerInputEl;if(g&&g.isConnected){if(g.focus({preventScroll:!0}),u!=null){let I=Math.min(u,g.value.length);try{g.setSelectionRange(I,I)}catch{}}}else requestAnimationFrame(()=>{let I=this.composerInputEl;if(I&&(I.focus({preventScroll:!0}),u!=null)){let m=Math.min(u,I.value.length);try{I.setSelectionRange(m,m)}catch{}}})}let f=this.pendingRenderPolicy;if(this.pendingRenderPolicy=null,f&&this.listEl){let u=this.scrollToBottomOnNextRender;switch(this.scrollToBottomOnNextRender=!1,f.kind){case"preserve":u?this.scrollListToBottom():a?this.scrollListToBottom():this.restoreScrollAnchor(n,i);break;case"pin-bottom":this.scrollListToBottom();break;case"restore":{let g=f.scrollTop,I=this.listEl,m=()=>{this.suppressScrollSave=!0;let C=Math.max(0,I.scrollHeight-I.clientHeight);I.scrollTop=Math.min(g,C),Promise.resolve().then(()=>{this.suppressScrollSave=!1})};m(),requestAnimationFrame(m),setTimeout(m,60),setTimeout(m,200),setTimeout(m,600);break}case"follow-cursor":i>0&&(this.listEl.scrollTop=i),this.revealCursorRow();break;case"scroll-to-id":{let g=f.id,I=f.align,m=this.listEl,C=()=>{this.suppressScrollSave=!0;let B=m.querySelector(`[data-id="${g}"]`);B&&B.scrollIntoView({block:I,behavior:"auto"}),Promise.resolve().then(()=>{this.suppressScrollSave=!1})};C(),requestAnimationFrame(C),setTimeout(C,60),setTimeout(C,200),setTimeout(C,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 u=this.listEl,g=u.scrollTop,I=new ResizeObserver(()=>{if(Date.now()<this.keyboardTransitionUntil)return;if(this.stickToListBottom){u.scrollTop=u.scrollHeight,g=u.scrollTop;return}let C=Math.max(0,u.scrollHeight-u.clientHeight);u.scrollTop<g&&g<=C?u.scrollTop=g:g=u.scrollTop});I.observe(u),this.listResizeObserver=I,u.addEventListener("wheel",C=>{C.deltaY<0&&(this.stickToListBottom=!1)},{passive:!0});let m=0;u.addEventListener("touchstart",C=>{m=C.touches[0]?.clientY??0},{passive:!0}),u.addEventListener("touchmove",C=>{let B=C.touches[0]?.clientY??m;B>m&&(this.stickToListBottom=!1),m=B},{passive:!0}),u.addEventListener("mousedown",()=>{this.stickToListBottom=!1}),u.addEventListener("keydown",()=>{this.stickToListBottom=!1})}}refreshFolderSwitcherIcon(){let e=this.containerEl.querySelector(".stashpad-folder-btn .stashpad-btn-icon");e&&(e.empty(),(0,k.setIcon)(e,this.plugin.getFolderIcon(this.noteFolder)??"folder"))}renderTimeFilterBar(e){let t=e.createDiv({cls:"stashpad-time-filter-bar"});if(!k.Platform.isMobile){let c=t.createEl("button",{cls:"stashpad-folder-btn"}),A=!!this.folderOverride,h=this.noteFolder.split("/").pop()||this.noteFolder||"Stashpad";(0,k.setIcon)(c.createSpan({cls:"stashpad-btn-icon"}),this.plugin.getFolderIcon(this.noteFolder)??"folder"),c.createSpan({text:h,cls:"stashpad-btn-text"}),c.title=A?`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:[r.path],actions:A.actionsForFile(r.path)}),console.error(e)}}function iA(A){let r=new Set,e=t=>{if(r.add(t),!!A.tree.get(t))for(let s of A.tree.getChildren(t))e(s.id)};return e(S),r}_i();_i();var jl=new Set(["png","jpg","jpeg","gif","webp","svg","bmp","avif"]),nA=900,oA=5,aA=700,Ns={nested:"Nested",flat:"Flat",everything:"Everything"},Ts=[{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"}],Ms=class Ms extends F.ItemView{constructor(e,t){super(e);this.focusId=S;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.renderBurstCount=0;this.renderBurstWindowAt=0;this.renderTimer=null;this.renderStorm=!1;this.bulkRenderDepth=0;this.bulkSettleTimer=null;this.bootstrappedFolders=new Set;this.selection=new Set;this.lastSelected=null;this.cursorIdx=-1;this.pendingCursorId=null;this.currentChildren=[];this.modeSplit=null;this.modeEnterSubmits=!0;this.nextDestination=null;this.nextDestinationFolder=null;this.nextDestinationLabel=null;this.inListPicker=null;this.pickerEscapeAt=0;this.composerExitAt=0;this.listEl=null;this.composerInputEl=null;this.composerSplitBtn=null;this.composerEnterBtn=null;this.composerHelperEl=null;this.composerDestBtn=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.tapSettleUntil=0;this.aimedTapTargetId=null;this.aimedTapAt=0;this.stickyRowObserver=null;this.listResizeObserver=null;this.composerNarrowObserver=null;this.barOverflowRO=null;this.lastCursorByFocus=new Map;this.lastSelectionByFocus=new Map;this.expandedNotes=new Set;this.cursorExpandOverride=new Set;this.cursorHasMoved=!1;this.activeVersionByGroup=new Map;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.syncBurstTimes=[];this.autoSyncDeferActive=!1;this.autoSyncSettleTimer=null;this.autoSyncNotice=null;this.stampLastCursorTimer=null;this.stampSelectionTimer=null;this._renderT0=null;this.tinyOpacityPopover=null;this.tinyOpacityClose=null;this.lastListWidth=0;this.keydownWindow=window;this.onDocKeyDown=e=>{if(!this.viewRoot.isConnected||this.app.workspace.activeLeaf!==this.leaf||ir(e.target))return;let t=X().bindings;if(J(e,t.toggleSplit)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.toggleSplit();return}if(J(e,t.pickDestination)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.openDestinationPicker();return}if(J(e,t.search)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.openSearchModal();return}if(J(e,t.commandPalette)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.openStashpadCommandPalette();return}if(J(e,t.lockSelection)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdLockSelection();return}if(J(e,t.unlockAll)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdUnlockAll();return}if(J(e,t.moveToArchive)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdMoveToArchive();return}if(J(e,t.encryptDelete)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdEncryptDelete();return}if(J(e,t.searchInParent)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.openSearchInParentModal();return}if(J(e,t.exportStash)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdExportStash();return}if(J(e,t.importStash)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdImportStash();return}if(J(e,t.pickFolder)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdOpenFolderPicker();return}if(J(e,t.cloneStashpadTab)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdCloneStashpadTab();return}let i=e.target,s=!!i&&(i.tagName==="INPUT"||i.tagName==="TEXTAREA");if(e.key===" "&&!e.metaKey&&!e.ctrlKey&&!e.altKey&&!e.shiftKey&&!s){let l=this.composerInputEl;if(l){e.preventDefault(),e.stopPropagation(),l.focus();let c=l.value.length;l.setSelectionRange(c,c);return}}let n=!!i&&(i.tagName==="INPUT"||i.tagName==="TEXTAREA"||i.tagName==="BUTTON"||i.tagName==="SELECT");if(e.key==="Escape"&&i instanceof HTMLElement&&(i.tagName==="BUTTON"||i.tagName==="SELECT")&&this.viewRoot.contains(i)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.viewRoot.focus();return}if(this.inListPicker&&e.key==="Escape"){e.preventDefault(),e.stopPropagation(),this.inListPicker=null,this.pickerEscapeAt=Date.now();let l=this.listEl,c=!!l&&l.scrollTop+l.clientHeight>=l.scrollHeight-2,d=l?.scrollTop??0;if(this.render(),l){let h=c?l.scrollHeight:d;l.scrollTop=h,requestAnimationFrame(()=>{l.scrollTop=c?l.scrollHeight:d}),setTimeout(()=>{l.scrollTop=c?l.scrollHeight:d},60),this.revealCursorRow()}return}if(this.inListPicker&&!n){if(e.key==="ArrowDown"){e.preventDefault(),this.inListPicker.activeIdx=this.nextPickableIdx(this.inListPicker.activeIdx,1),this.repaintSelectionClasses(),this.revealRowAt(this.inListPicker.activeIdx);return}if(e.key==="ArrowUp"){e.preventDefault(),this.inListPicker.activeIdx=this.nextPickableIdx(this.inListPicker.activeIdx,-1),this.repaintSelectionClasses(),this.revealRowAt(this.inListPicker.activeIdx);return}if(e.key==="Enter"){e.preventDefault(),this.commitInListPicker();return}if(J(e,X().bindings.move)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.inListPicker=null,this.repaintSelectionClasses(),this.cmdMovePicker();return}return}if(n)return;if(J(e,t.delete)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdDelete();return}if(J(e,t.toggleComplete)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdToggleComplete();return}if(J(e,t.moveToTop)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdMoveToTop();return}if(J(e,t.moveToBottom)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdMoveToBottom();return}if(J(e,t.moveUp)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdMoveUp();return}if(J(e,t.moveDown)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdMoveDown();return}if(J(e,t.outdent)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdOutdent();return}if(J(e,t.setColor)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdSetColor();return}if(J(e,t.selectAll)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdSelectAll();return}if(J(e,t.swapWithParent)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdSwapWithParent();return}if(J(e,t.undo)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdUndo();return}if(J(e,t.redo)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdRedo();return}if(e.key===" "){e.preventDefault();let l=this.composerInputEl;if(l){l.focus();let c=l.value.length;l.setSelectionRange(c,c)}return}if(e.key==="ArrowDown"){e.preventDefault(),this.cursorIdx>=this.currentChildren.length-1?this.cursorIdx=0:this.cursorIdx++,this.selectCursor(e.shiftKey);return}if(e.key==="ArrowUp"){e.preventDefault(),this.cursorIdx<=0?this.cursorIdx=this.currentChildren.length-1:this.cursorIdx--,this.selectCursor(e.shiftKey);return}if(e.altKey&&e.key==="ArrowLeft"){e.preventDefault(),this.navigateBack();return}if(e.altKey&&e.key==="ArrowRight"){e.preventDefault(),this.navigateForward();return}if(e.key==="ArrowRight"){let l=this.currentChildren[this.cursorIdx];l&&(e.preventDefault(),this.navigateTo(l.id));return}if(e.key==="ArrowLeft"||e.key==="Backspace"){e.preventDefault(),this.navigateUp();return}if(e.key==="Escape"){if(e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),Date.now()-this.pickerEscapeAt<350||Date.now()-this.composerExitAt<400)return;if(this.plugin.noteClipboard&&this.plugin.noteClipboard.folder===this.noteFolder){this.plugin.clearNoteClipboard(),this.render();return}let l=this.firstSelectedId??(this.selection.size>0?this.selection.values().next().value:null);if(this.selection.clear(),this.firstSelectedId=null,l){let c=this.currentChildren.findIndex(d=>d.id===l);this.selection.add(l),this.lastSelected=l,c>=0&&(this.cursorIdx=c)}this.repaintSelectionClasses(),this.revealCursorRow();return}let o=X().bindings;if(J(e,o.pasteNotes)&&this.plugin.noteClipboard){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdPasteNotes();return}if(J(e,o.openAllTasks)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),He(this.plugin,"tasks");return}if(this.selection.size>0||this.cursorIdx>=0&&this.currentChildren[this.cursorIdx]){if(J(e,o.move)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdMovePicker();return}if(J(e,o.pickMove)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdInListPicker();return}if(J(e,o.merge)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdMerge();return}if(J(e,o.copy)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdCopy();return}if(J(e,o.copyNotes)&&!window.getSelection()?.toString()){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdCopyNotes();return}if(J(e,o.cutNotes)&&!window.getSelection()?.toString()){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdCutNotes();return}if(J(e,o.copyTree)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdCopyTree();return}if(J(e,o.copyLink)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdCopyStashpadLink();return}if(J(e,o.copyOutline)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdCopyOutline();return}if(J(e,o.copyCodeBlock)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdCopyCodeBlock();return}if(J(e,o.openEditor)){if(e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),e.shiftKey){let l=this.tree.get(this.focusId);l?.file&&this.cmdOpenInEditor(l)}else this.cmdOpenInEditor();return}if(J(e,o.openTab)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdOpenInNewStashpadTab();return}if(J(e,o.split)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdSplit();return}if(J(e,o.editParent)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdEditParent();return}if(J(e,o.edit)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdEdit();return}if(J(e,o.clone)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdClone();return}if(J(e,o.forkNote)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdForkNote();return}if(J(e,o.insertTemplate)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdInsertTemplate();return}if(J(e,o.toggleExpand)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdToggleExpand();return}if(J(e,o.expandAll)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdExpandAll();return}if(J(e,o.collapseAll)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdCollapseAll();return}if(J(e,o.togglePin)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdTogglePin();return}if(J(e,o.listPin)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdToggleListPin();return}if(J(e,o.toggleTask)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdToggleTask();return}if(J(e,o.setDue)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdSetDue();return}}if(this.currentChildren.length>0){if(J(e,o.jumpToTop)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.jumpToTop();return}if(J(e,o.jumpToBottom)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.jumpToBottom();return}}let a=this.tree.get(this.focusId);if(a?.file){if(J(e,o.openEditor)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdOpenInEditor(a);return}if(J(e,o.openTab)){e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.cmdOpenInNewStashpadTab(a);return}}};this.openSearchInstance=null;this.fmSyncUnsubscribe=null;this.completedState=new Map;this.taskTaggedState=new Map;this.listPinnedState=new Map;this.pendingFocusIds=null;this.recentFmSelfWrites=new Map;this.onFileModify=e=>{if(!(!(e instanceof F.TFile)||e.extension!=="md")&&e.path.startsWith(this.noteFolder+"/")){if(this.fmSync.wasRecentSelfWrite(e.path)){this.bodyRenderer.retagMtime(e.path,e.stat.mtime);return}if(this.wasRecentFmSelfWrite(e.path)){if(this.bodyRenderer.retagMtime(e.path,e.stat.mtime),this.deferDuringSyncBurst())return;this.debouncedRender();return}this.bodyRenderer.evict(e),this.scheduleSlugRename(e),this.scheduleAttachmentSync(e),this.authorship.noteModify(e),!this.deferDuringSyncBurst()&&this.debouncedRender()}};this.onFileCreate=e=>{!(e instanceof F.TFile)||e.extension!=="md"||e.path.startsWith(this.noteFolder+"/")&&(this.deferDuringSyncBurst()||this.debouncedRender())};this.plugin=t,this.tree=new Qn(this.app),this.log=t.newLog(),this.integrity=new xn(this.tree,this.log),this.order=new Ni(this.app),this.sortStore=new Sn(this.app),this.fmSync=new Dn(this.app,()=>this.tree),this.tree.setOrderProvider(s=>{let n=this.noteFolder,o=this.sortStore.getMode(n,s),a=o==="manual"?this.order.getOrder(n,s):rl(this,s,o);return this.hoistListPinned(s,a)});let i=()=>{let s=Date.now();s-this.renderBurstWindowAt>nA&&(this.renderBurstCount=0,this.renderStorm=!1),this.renderBurstWindowAt=s,this.renderBurstCount++,this.renderBurstCount>oA&&(this.renderStorm=!0);let n=this.renderStorm?aA:80;this.renderTimer!=null&&window.clearTimeout(this.renderTimer),this.renderTimer=window.setTimeout(()=>{this.renderTimer=null,!this.renderSuppressed()&&this.render()},n)};this.debouncedRender=Object.assign(i,{cancel:()=>{this.renderTimer!=null&&(window.clearTimeout(this.renderTimer),this.renderTimer=null)}}),this.authorship=new Un(this),this.dnd=new Ln(this),this.bodyRenderer=new Gn(this,this,this.plugin.renderCacheStore)}getViewType(){return $}getDisplayText(){let e=(this.noteFolder||"").trim(),t=e.split("/").pop()||e||"Stashpad";if(this.focusId&&this.focusId!==S){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`${t} \u2014 ${n} \xB7 ${this.focusId}`}}return t}refreshHeaderTitle(){let e=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!==e&&i.setText(e)}getIcon(){return this.plugin.getFolderIcon(this.noteFolder)??"list-tree"}async onOpen(){let e=this.contentEl;e.empty(),e.addClass("stashpad-scroll-host"),this.viewRoot=e.createDiv({cls:"stashpad-view"}),this.viewRoot.setAttribute("tabindex","0"),this.viewRoot.addEventListener("focusin",()=>hn(this)),this.viewRoot.addEventListener("click",()=>hn(this)),this.viewRoot.addEventListener("mouseup",l=>{l.button===3?(l.preventDefault(),this.navigateBack()):l.button===4&&(l.preventDefault(),this.navigateForward())}),this.viewRoot.addEventListener("auxclick",l=>{l.button===3?(l.preventDefault(),this.navigateBack()):l.button===4&&(l.preventDefault(),this.navigateForward())}),hn(this),this.registerInterval(window.setInterval(()=>this.authorship.pruneContribMaps(),6e4));let t=null,i=()=>{t||(t=new F.Scope(this.app.scope),t.register([],"Escape",()=>{if(this.inListPicker)return this.inListPicker=null,this.pickerEscapeAt=Date.now(),this.repaintSelectionClasses(),!1;if(Date.now()-this.pickerEscapeAt<350||Date.now()-this.composerExitAt<400)return!1;if(this.selection.size>1){let l=this.firstSelectedId??this.selection.values().next().value??null;if(this.selection.clear(),this.firstSelectedId=null,l){let c=this.currentChildren.findIndex(d=>d.id===l);this.selection.add(l),this.lastSelected=l,c>=0&&(this.cursorIdx=c)}this.render(),this.revealCursorRow()}return!1}),this.app.keymap?.pushScope(t))},s=()=>{if(t){try{this.app.keymap?.popScope(t)}catch{}t=null}};this.viewRoot.addEventListener("focusin",i),this.viewRoot.addEventListener("focusout",l=>{let c=l.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",l=>{if(l.extension!=="md")return;let c=this.app.metadataCache.getFileCache(l)?.frontmatter;this.completedState.set(l.path,!!c?.completed),this.taskTaggedState.set(l.path,this.taggedFromFm(c))})),this.registerEvent(this.app.vault.on("rename",(l,c)=>{for(let d of[this.completedState,this.taskTaggedState])d.has(c)&&(d.set(l.path,d.get(c)),d.delete(c))})),this.registerEvent(this.app.vault.on("delete",l=>{this.completedState.delete(l.path),this.taskTaggedState.delete(l.path);let c=l.path.lastIndexOf("/"),d=(c>=0?l.path.slice(0,c):"").replace(/\/+$/,"");l.path.endsWith(".md")&&d===this.noteFolder.replace(/\/+$/,"")&&(this.tree.rebuild(this.noteFolder),this.debouncedRender())})),this.detachSettings=Gr(()=>{this.loadConfig();let l=this.plugin.settings.drafts?.[this.noteFolder]??"",c=this.composerInputEl?.value??"";l===""&&this.composerDraft!==""&&c===""?(this.composerDraft="",this.composerInputEl&&(this.composerInputEl.value="")):l===""&&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),this.keydownWindow=this.containerEl?.ownerDocument?.defaultView??window,this.keydownWindow.addEventListener("keydown",this.onDocKeyDown,!0),this.loadConfig();try{await this.bootstrapFolder()}catch(l){let c=l?.message??"";/already exists/i.test(c)||console.warn("[Stashpad] bootstrapFolder failed:",l)}this.tree.rebuild(this.noteFolder),this.installFmSyncActivityNotice(),this.backfillFrontmatterSync(),this.plugin.maybeSweepFolder(this.noteFolder),this.defaultCursorToLast(),this.refreshHeaderTitle(),await this.loadDraftsForFolder();try{let l=this.plugin.loadLastCursor(this.noteFolder);for(let[c,d]of l)this.lastCursorByFocus.set(c,d);this.lastSelectionByFocus=this.plugin.loadLastSelection(this.noteFolder),this.activeVersionByGroup=this.plugin.loadActiveVersions(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 a=this.foldRestoredSelection(n);a&&(this.pendingFocusIds=a),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)}),X().focusComposerOnOpen?this.focusComposer():this.focusView(),this.registerEvent(this.app.workspace.on("active-leaf-change",l=>{l===this.leaf?X().focusComposerOnOpen?this.focusComposer():this.focusView():this.stickToListBottom=!1}))}renderSuppressed(){return this.bulkRenderDepth>0||this.bulkSettleTimer!=null||this.autoSyncDeferActive||this.plugin.rebootstrapInProgress||this.plugin.okfRebuildingFolders.has(this.noteFolder)}beginBulkRender(){this.bulkRenderDepth++,this.bulkSettleTimer!=null&&(window.clearTimeout(this.bulkSettleTimer),this.bulkSettleTimer=null)}endBulkRender(e=500){this.bulkRenderDepth>0&&this.bulkRenderDepth--,!(this.bulkRenderDepth>0)&&(this.bulkSettleTimer!=null&&window.clearTimeout(this.bulkSettleTimer),this.bulkSettleTimer=window.setTimeout(()=>{this.bulkSettleTimer=null,this.viewRoot?.isConnected&&(this.tree.rebuild(this.noteFolder),this.render())},e))}deferDuringSyncBurst(){if(this.plugin.rebootstrapInProgress)return!1;let e=Date.now();this.syncBurstTimes.push(e);let t=e-2e3;for(;this.syncBurstTimes.length&&this.syncBurstTimes[0]<t;)this.syncBurstTimes.shift();return!this.autoSyncDeferActive&&this.syncBurstTimes.length>=6&&(this.autoSyncDeferActive=!0,this.autoSyncNotice=new F.Notice("Stashpad: syncing \u2014 list updates paused until it settles\u2026",0)),this.autoSyncDeferActive?(this.autoSyncSettleTimer!=null&&window.clearTimeout(this.autoSyncSettleTimer),this.autoSyncSettleTimer=window.setTimeout(()=>this.endAutoSyncDefer(),1500),!0):!1}endAutoSyncDefer(){this.autoSyncSettleTimer=null,this.autoSyncDeferActive=!1,this.syncBurstTimes=[],this.autoSyncNotice?.hide(),this.autoSyncNotice=null,this.forceReconcileRender()}forceReconcileRender(){this.viewRoot?.isConnected&&(this.tree.rebuild(this.noteFolder),this.render())}scheduleTreeReconcile(){this.renderSuppressed()||this.treeReconcileTimer==null&&(this.treeReconcileTimer=window.setTimeout(()=>{if(this.treeReconcileTimer=null,!this.viewRoot?.isConnected)return;let e=this.noteFolder,t=e+"/",i=0;for(let s of this.app.vault.getMarkdownFiles()){let n=s.parent?.path?.replace(/\/+$/,"")??"";if(!(n===e||e!==""&&n.startsWith(t)))continue;let o=this.app.metadataCache.getFileCache(s)?.frontmatter?.id;typeof o=="string"&&o&&i++}i!==this.tree.fileBackedCount()&&(this.tree.rebuild(e),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(!X().focusComposerOnOpen)return;let e=()=>{if(!this.viewRoot?.isConnected||Date.now()<this.suppressComposerFocusUntil||Date.now()<this.plugin.suppressComposerAutofocusUntil)return;let t=document.activeElement;t&&(t.tagName==="INPUT"||t.tagName==="TEXTAREA")&&t!==this.composerInputEl||(t&&t.tagName==="BUTTON"&&this.viewRoot.contains(t),this.composerInputEl?.focus({preventScroll:!0}))};requestAnimationFrame(e),setTimeout(e,50),setTimeout(e,200)}async onClose(){Rr(this),this.debouncedRender?.cancel?.(),this.tinyOpacityClose?.(),this.detachTreeHook?.(),this.detachSettings?.(),this.app.vault.off("modify",this.onFileModify),this.app.vault.off("create",this.onFileCreate),this.keydownWindow.removeEventListener("keydown",this.onDocKeyDown,!0),this.listResizeObserver?.disconnect(),this.listResizeObserver=null,this.stickyRowObserver?.disconnect(),this.stickyRowObserver=null,this.bodyRenderer.dispose(),this.barOverflowRO?.disconnect(),this.barOverflowRO=null,this.composerNarrowObserver?.disconnect(),this.composerNarrowObserver=null,this.focusedMiniObserver?.disconnect(),this.focusedMiniObserver=null,this.treeReconcileTimer!=null&&(window.clearTimeout(this.treeReconcileTimer),this.treeReconcileTimer=null),this.autoSyncSettleTimer!=null&&(window.clearTimeout(this.autoSyncSettleTimer),this.autoSyncSettleTimer=null),this.autoSyncNotice?.hide(),this.autoSyncNotice=null,this.composerAutocomplete?.detach(),this.composerAutocomplete=null;for(let e of this.slugDebouncers.values())e.cancel();for(let e of this.attachmentDebouncers.values())e.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(e){let t=e;t?.focusId&&(this.focusId=t.focusId),t?.timeFilter&&(this.timeFilter=t.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(e,t){let i=e??null;if(i){"folderOverride"in i&&(this.folderOverride=i.folderOverride??null),i.timeFilter&&(this.timeFilter=i.timeFilter),i.focusId&&(this.focusId=i.focusId),i.cursorId&&(this.pendingCursorId=i.cursorId),"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(e,t),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[d,h]of c)this.lastCursorByFocus.set(d,h);this.lastSelectionByFocus=this.plugin.loadLastSelection(this.noteFolder),this.activeVersionByGroup=this.plugin.loadActiveVersions(this.noteFolder)}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"};let l=this.foldRestoredSelection(o);l&&(this.pendingFocusIds=l),this.render(a),this.scheduleSelectionRestore()}}focus(){this.viewRoot?.focus({preventScroll:!0})}foldRestoredSelection(e){let t=this.lastSelectionByFocus.get(this.focusId)??null;if(!t||!t.length)return null;let i=t.filter(s=>!!this.tree.get(s));return i.length?e&&i.includes(e)?[e,...i.filter(s=>s!==e)]:i:null}stampSelection(e=!1){let t=[...this.selection],i=()=>{try{this.plugin.saveLastSelection(this.noteFolder,this.focusId,t)}catch{}};if(this.stampSelectionTimer!=null&&(window.clearTimeout(this.stampSelectionTimer),this.stampSelectionTimer=null),e){i();return}this.stampSelectionTimer=window.setTimeout(()=>{this.stampSelectionTimer=null,i()},400)}scheduleSelectionRestore(){let e=this.lastSelectionByFocus.get(this.focusId);if(!e||!e.length)return;let t=()=>{let i=e.filter(a=>this.currentChildren.some(l=>l.id===a));if(!i.length)return;let s=[...this.selection],n=new Set(i);if(s.length<i.length&&s.every(a=>n.has(a))){this.selection.clear();for(let a of i)this.selection.add(a);this.firstSelectedId=i[0],this.lastSelected=i[i.length-1],this.repaintSelectionClasses()}};for(let i of[120,400,900,1600])window.setTimeout(t,i)}loadConfig(){let e=(this.plugin?.settings?.folder??"Stashpad").trim().replace(/^\/+|\/+$/g,""),i=this.folderOverride?.trim().replace(/^\/+|\/+$/g,"")||null||e||"Stashpad";i!==this.noteFolder?(this.noteFolder=i,this.tree.rebuild(this.noteFolder)):this.noteFolder=i}captureNavSnapshot(){return{folder:this.noteFolder,focusId:this.focusId}}recordNavState(e={}){let t=this.captureNavSnapshot(),i=this.navBackStack[this.navBackStack.length-1];i&&i.folder===t.folder&&i.focusId===t.focusId||(this.navBackStack.push(t),e.keepForward||(this.navForwardSnapshots=[]))}async setFolderOverride(e,t={}){let i=e?.trim().replace(/^\/+|\/+$/g,"")||null;if(i&&this.isReservedFolder(i)){new F.Notice(`"${i}" is a reserved Stashpad subfolder (imports/exports/attachments). Pick a different folder.`);return}if((i||null)!==(this.folderOverride||null)){t.skipHistory||this.recordNavState(),this.folderOverride=i,this.focusId=S,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 e=[];for(let t of this.app.vault.getAllLoadedFiles())if(t instanceof F.TFolder){if(t.path==="/"||t.path===""||t.path.startsWith(".")||this.isReservedFolder(t.path))continue;e.push(t.path)}return e.sort((t,i)=>t.localeCompare(i))}isReservedFolder(e){let t=e.split("/").filter(Boolean).pop()??"";return t?new Set([this.plugin.settings.importDropFolder,this.plugin.settings.exportFolder,"_attachments","_processed","_authors"].map(s=>(s??"").trim().replace(/^\/+|\/+$/g,"")).filter(Boolean)).has(t):!1}persistFocus(){try{this.app.workspace.requestSaveLayout()}catch{}}cmdUndo(){let e=this.plugin.getUndoStack(this.noteFolder);if(!e.canUndo()){new F.Notice("Nothing to undo.");return}let t=e.peekUndoLabel(),i=this.plugin.notifications.recent()[0]?.category??"system";e.undo().then(()=>this.plugin.notifications.show({message:`Undid: ${t}`,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 e=this.plugin.getUndoStack(this.noteFolder);if(!e.canRedo()){new F.Notice("Nothing to redo.");return}let t=e.peekRedoLabel(),i=this.plugin.notifications.recent()[0]?.category??"system";e.redo().then(()=>this.plugin.notifications.show({message:`Redid: ${t}`,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(e,t){let i=[],s=new Set;for(let l of e)!l.file||s.has(l.file.path)||(s.add(l.file.path),i.push(l.file));let n=await Promise.all(i.map(l=>this.app.vault.read(l))),o=i.map((l,c)=>({path:l.path,content:n[c]})),a=[];if(t){let l=new Set,c=[];for(let h of n)for(let p of this.extractAttachments(this.stripFrontmatter(h))){let f=this.app.metadataCache.getFirstLinkpathDest(p,"");f&&!l.has(f.path)&&(l.add(f.path),c.push(f))}let d=await Promise.all(c.map(h=>this.app.vault.readBinary(h)));for(let h=0;h<c.length;h++)a.push({path:c[h].path,data:d[h]})}return{notes:o,attachments:a}}fileForNote(e,t){return(e?this.tree.get(e)?.file:null)??this.app.vault.getAbstractFileByPath(t)}async restoreSnapshots(e,t){for(let s of e.attachments)try{await this.app.vault.adapter.exists(s.path)||await this.app.vault.createBinary(s.path,s.data)}catch{}for(let s of e.notes)try{let n=s.content.split(` +---`)[0]??"",a=/^id:\s*["']?([^"'\s]+)/m.exec(n)?.[1];if(a&&this.tree.get(a)?.file)continue;await this.app.vault.adapter.exists(s.path)||await this.app.vault.create(s.path,s.content)}catch{}let i=()=>{t&&t.some(n=>this.tree.get(n))&&(this.pendingFocusIds=t.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 e.notes){let n=this.tree.idForPath(s.path);n&&this.fmSync.schedule(n)}},500)}async trashNotesAndAttachments(e){let t=new Set;for(let i of e.notes){let s=this.tree.idForPath(i.path);if(!s)continue;let n=this.tree.get(s);n?.parent&&t.add(n.parent)}for(let i of e.notes){let s=this.app.vault.getAbstractFileByPath(i.path);if(s)try{await this.app.fileManager.trashFile(s)}catch{}}for(let i of e.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 t)this.fmSync.scheduleParentOfDeleted(i)}async loadDraftsForFolder(){if(this.draftsLoadedFor===this.noteFolder)return;this.draftsLoadedFor=this.noteFolder;let e=this.plugin.settings.drafts??{};this.composerDraft=e[this.noteFolder]??"",console.debug("[Stashpad] loadDrafts",{folder:this.noteFolder,has:!!e[this.noteFolder],available:Object.keys(e)})}async saveDraft(e){try{let t=this.noteFolder;if((this.plugin.settings.drafts?.[t]??"")===e)return;let s={...this.plugin.settings.drafts??{}};e.length===0?delete s[t]:s[t]=e,this.plugin.settings.drafts=s,e.length===0?await this.plugin.saveSettings():await this.plugin.persistSettingsQuiet()}catch(t){console.warn("Stashpad: drafts save failed",t)}}async recordLastSubmitted(e){try{let t={...this.plugin.settings.lastSubmitted??{}};t[this.noteFolder]=e,this.plugin.settings.lastSubmitted=t,await this.plugin.persistSettingsQuiet()}catch{}}hasRestorableDraft(){let e=this.plugin.settings.drafts?.[this.noteFolder];if(!e||!e.trim())return!1;let t=this.plugin.settings.lastSubmitted?.[this.noteFolder];return!(t&&t===e)}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 t=(0,F.moment)();switch(this.timeFilter){case"day":return t.startOf("day").valueOf();case"week":return t.startOf("isoWeek").valueOf();case"month":return t.startOf("month").valueOf();case"year":return t.startOf("year").valueOf()}}let e=Date.now();switch(this.timeFilter){case"day":return e-864e5;case"week":return e-7*864e5;case"month":return e-30*864e5;case"year":return e-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(e){let t={...this.plugin.settings.includeAttachmentsInEverything??{}};e?t[this.noteFolder]=!0:delete t[this.noteFolder],this.plugin.settings.includeAttachmentsInEverything=t,await this.plugin.saveSettings()}currentEncryptionFilter(){return this.plugin.settings.encryptionFilter?.[this.noteFolder]??"all"}async setEncryptionFilter(e){let t={...this.plugin.settings.encryptionFilter??{}};e==="all"?delete t[this.noteFolder]:t[this.noteFolder]=e,this.plugin.settings.encryptionFilter=t,await this.plugin.saveSettings()}currentHideChildless(){return!!this.plugin.settings.hideChildlessNotes?.[this.noteFolder]}async setHideChildless(e){let t={...this.plugin.settings.hideChildlessNotes??{}};e?t[this.noteFolder]=!0:delete t[this.noteFolder],this.plugin.settings.hideChildlessNotes=t,await this.plugin.saveSettings()}currentHideCompleted(){return!!this.plugin.settings.hideCompletedNotes?.[this.noteFolder]}async setHideCompleted(e){let t={...this.plugin.settings.hideCompletedNotes??{}};e?t[this.noteFolder]=!0:delete t[this.noteFolder],this.plugin.settings.hideCompletedNotes=t,await this.plugin.saveSettings()}currentAttachmentsOnly(){return!!this.plugin.settings.attachmentsOnlyNotes?.[this.noteFolder]}async setAttachmentsOnly(e){let t={...this.plugin.settings.attachmentsOnlyNotes??{}};e?t[this.noteFolder]=!0:delete t[this.noteFolder],this.plugin.settings.attachmentsOnlyNotes=t,await this.plugin.saveSettings()}nodeHasAttachment(e){if(!e.file)return!1;let t=this.app.metadataCache.getFileCache(e.file)?.frontmatter?.attachments;return Array.isArray(t)&&t.length>0}hasAttachmentInSubtree(e){if(this.nodeHasAttachment(e))return!0;for(let t of this.tree.getChildren(e.id))if(this.hasAttachmentInSubtree(t))return!0;return!1}hasIncompleteDescendant(e){for(let t of e.children){let i=this.tree.get(t);if(i&&(!this.isCompleted(i)||this.hasIncompleteDescendant(i)))return!0}return!1}collectEmbeddedAttachmentPaths(){let e=new Set,t=this.noteFolder,i=this.app.vault.getAbstractFileByPath(t);if(!(i instanceof F.TFolder))return e;let s=[i];for(;s.length;){let n=s.pop();for(let o of n.children){if(o instanceof F.TFolder){s.push(o);continue}if(!(o instanceof F.TFile)||o.extension!=="md")continue;let a=this.app.metadataCache.getFileCache(o)?.frontmatter;if(!(!a||!Array.isArray(a.attachments)))for(let l of a.attachments){if(typeof l!="string")continue;let c=qt(l),d=this.app.metadataCache.getFirstLinkpathDest(c,o.path);d?e.add(d.path):e.add(c)}}}return e}collectFileItems(e){let t=this.noteFolder,i=this.app.vault.getAbstractFileByPath(t);if(!(i instanceof F.TFolder))return[];let s=this.currentIncludeAttachments(),n=s?new Set:this.collectEmbeddedAttachmentPaths(),o=new Set(["_authors","_imports","_exports","_processed","_attachments","_archive",".archive"]),a=[],l=[i];for(;l.length;){let c=l.pop();for(let d of c.children){if(d instanceof F.TFolder){let h=d.name;if(c===i&&o.has(h)||c===i&&h==="_attachments"&&!s)continue;l.push(d);continue}d instanceof F.TFile&&d.extension!=="md"&&(d.name===".stashpad-order.json"||d.name===".stashpad-sort.json"||!s&&n.has(d.path)||a.push(d))}}return a}populateListBody(e,t){if(this.lastListWidth=e.clientWidth||this.lastListWidth,this.bodyRenderer.arm(),this.pendingCursorId){let d=this.currentChildren.findIndex(h=>h.id===this.pendingCursorId);d>=0&&(this.cursorIdx=d,this.selection.clear(),this.selection.add(this.pendingCursorId),this.lastSelected=this.pendingCursorId,this.pendingCursorId=null)}t.file&&F.Platform.isMobile&&!this.compactMode&&(this.renderFocusedHeaderMini(e,t),this.renderFocusedHeader(e,t));let i=this.currentViewMode(),s=i==="everything"?this.collectFileItems(t.id):[],n=d=>d.created&&Number.isFinite(Date.parse(d.created))?Date.parse(d.created):Number.POSITIVE_INFINITY,o=this.currentEncryptionFilter(),a;if(o==="unlocked")a=[];else if(i==="nested")a=this.plugin.lockedSubtreesFor(this.noteFolder,t.id);else{let d=new Set([t.id,...this.currentChildren.map(p=>p.id)]),h=new Set;a=[];for(let p of d)for(let f of this.plugin.lockedSubtreesFor(this.noteFolder,p))h.has(f.blob)||(h.add(f.blob),a.push(f))}let l=a.map(d=>({lk:d,ts:n(d)})).sort((d,h)=>d.ts-h.ts),c=i==="nested"&&this.sortStore.getMode(this.noteFolder,t.id)==="manual";if(this.currentChildren.length===0&&s.length===0&&l.length===0)e.createDiv({cls:"stashpad-empty",text:"No notes here yet. Type below to add one."});else if(c&&l.length>0){let d=new Map(this.currentChildren.map((g,I)=>[g.id,I])),h=new Map;for(let{lk:g}of l)g.rootId&&h.set(g.rootId,g);let p=this.currentChildren.map(g=>g.id),f=l.map(({lk:g})=>g).filter(g=>g.rootId).sort((g,I)=>n(I)-n(g)),u=!0;for(;f.length&&u;){u=!1;for(let g=0;g<f.length;g++){let I=f[g],m=I.prevSibling??null,C;if(m==null)C=0;else{let B=p.indexOf(m);if(B<0)continue;C=B+1}p.splice(C,0,I.rootId),f.splice(g,1),g--,u=!0}}for(let g of f)p.push(g.rootId);for(let g of p){let I=d.get(g);if(I!==void 0)this.renderNote(e,this.currentChildren[I],I);else{let m=h.get(g);m&&this.renderLockedPlaceholder(e,m)}}for(let g of s.slice().sort((I,m)=>I.stat.ctime-m.stat.ctime))this.renderFileRow(e,g)}else if(s.length===0){let d=0;for(let h=0;h<this.currentChildren.length;h++){let p=Number.isFinite(Date.parse(this.currentChildren[h].created))?Date.parse(this.currentChildren[h].created):0;for(;d<l.length&&l[d].ts<=p;)this.renderLockedPlaceholder(e,l[d].lk),d++;this.renderNote(e,this.currentChildren[h],h)}for(;d<l.length;)this.renderLockedPlaceholder(e,l[d].lk),d++}else{let d=[...this.currentChildren.map((h,p)=>({kind:"note",ts:Number.isFinite(Date.parse(h.created))?Date.parse(h.created):0,idx:p})),...s.map(h=>({kind:"file",ts:h.stat.ctime,file:h})),...l.map(h=>({kind:"lock",ts:h.ts,lk:h.lk}))];d.sort((h,p)=>h.ts-p.ts);for(let h of d)h.kind==="note"?this.renderNote(e,this.currentChildren[h.idx],h.idx):h.kind==="file"?this.renderFileRow(e,h.file):this.renderLockedPlaceholder(e,h.lk)}t.file&&F.Platform.isMobile&&!this.compactMode&&this.installFocusedMiniObserver(e)}renderLockedPlaceholder(e,t){let i=e.createDiv({cls:"stashpad-locked-row"});t.created&&i.createSpan({cls:"stashpad-note-time stashpad-locked-time",text:this.formatTime(t.created)});let s=i.createSpan({cls:"stashpad-locked-icon"});(0,F.setIcon)(s,"lock");let n=!t.title;i.createSpan({cls:"stashpad-locked-title",text:n?"Locked note":t.title}),i.createSpan({cls:"stashpad-locked-count",text:t.count>1?`${t.count} notes \xB7 locked`:"locked"});let o=i.createEl("button",{cls:"stashpad-locked-unlock",text:"Unlock"});(0,F.setIcon)(o.createSpan({cls:"stashpad-btn-icon"}),"unlock");let a=async d=>{d.preventDefault(),d.stopPropagation();let h=(this.plugin.settings.lockedSubtrees??[]).find(I=>I.blob===t.blob),p=t.rootId??h?.rootId??null,f=t.parentId??h?.parentId??S,u=t.prevSibling??h?.prevSibling??null;if(await this.plugin.unlockBundleAt(t.blob)){if(this.selection.clear(),this.lastSelected=null,p){let I=this.order.getOrder(this.noteFolder,f),m=this.sortStore.getMode(this.noteFolder,f)==="manual";if(I.length===0&&m&&(I=this.tree.getChildren(f).map(C=>C.id)),I.length>0){let C=I.filter(E=>E!==p),B=u&&C.includes(u)?C.indexOf(u)+1:0;C.splice(Math.max(0,B),0,p),this.order.setOrder(this.noteFolder,f,C),this.order.flush(this.noteFolder)}this.pendingCursorId=p}if(this.render(),p){let I=this.noteFolder,m=t.blob;this.plugin.getUndoStack(I).push({label:"Unlock note",undo:async()=>{let C=await this.plugin.lockNoteSubtree(I,p,u,{silent:!0});C&&(m=C.blobPath),this.render()},redo:async()=>{try{await this.plugin.unlockBundleAt(m,{silent:!0})}catch{}this.render()}})}}};o.onclick=a;let l=d=>{d.preventDefault(),d.stopPropagation();let h=new F.Menu;Tn(h,{app:this.app,plugin:this.plugin,descriptor:{blob:t.blob,rootId:t.rootId,count:t.count,folder:this.noteFolder},unlockLabel:"Decrypt (unlock)",onUnlock:()=>void a(d),onChange:()=>this.render(),fullParity:!0,confirmDelete:!0}),h.showAtMouseEvent(d)};i.oncontextmenu=l;let c=i.createEl("button",{cls:"stashpad-pencil stashpad-locked-menu"});(0,F.setIcon)(c,"more-vertical"),c.setAttr("aria-label","Locked note menu"),c.onclick=d=>l(d),i.setAttr("aria-label",`${n?"Locked note":`Locked: ${t.title}`}. Use the Unlock button to decrypt.`)}refreshList(){if(!this.listEl){this.render();return}let e=this.tree.get(this.focusId)??this.tree.getRoot();this.currentChildren=this.filterChildren(this.collectViewItems(e.id)),this.cursorIdx>=this.currentChildren.length&&(this.cursorIdx=this.currentChildren.length-1);let t=this.listEl.scrollTop+this.listEl.clientHeight>=this.listEl.scrollHeight-2,i=this.listEl.scrollTop;this.listEl.empty(),this.populateListBody(this.listEl,e),t?this.listEl.scrollTop=this.listEl.scrollHeight:this.listEl.scrollTop=i}renderFileRow(e,t){if(this.currentEncryptionFilter()==="locked")return;let i=e.createDiv({cls:"stashpad-file-row"});i.dataset.path=t.path,i.createDiv({cls:"stashpad-file-meta"}).createSpan({cls:"stashpad-file-time",text:this.formatTime(new Date(t.stat.ctime).toISOString())});let n=i.createDiv({cls:"stashpad-file-body"});n.createSpan({cls:"stashpad-file-name",text:t.name}),n.createSpan({cls:"stashpad-file-ext",text:t.extension.toUpperCase()}),i.title=`${t.path} \u2014 click to open`,i.onclick=o=>{o.preventDefault(),this.app.workspace.openLinkText(t.path,"",!1)}}async setViewMode(e){let t={...this.plugin.settings.viewModes??{}};e==="nested"?delete t[this.noteFolder]:t[this.noteFolder]=e,this.plugin.settings.viewModes=t,await this.plugin.saveSettings()}collectViewItems(e){let t=this.currentViewMode(),i=this.currentHideChildless(),s=this.tree.getChildren(e),n=i?s.filter(l=>l.children.length>0):s;if(t==="nested")return n;let o=[],a=l=>{o.push(l);for(let c of this.tree.getChildren(l.id))a(c)};for(let l of n)a(l);return o}filterChildren(e){e=this.collapseVersions(e);let t=this.timeFilterCutoff(),i=this.tagFilter?.toLowerCase(),s=this.colorFilter?.toLowerCase()??null,n=this.currentHideCompleted(),o=this.currentAttachmentsOnly(),a=this.importedOnly,l=this.authorFilter;return!t&&!i&&!s&&!n&&!o&&!a&&!l?e:e.filter(c=>{if(a&&(!c.file||this.app.metadataCache.getFileCache(c.file)?.frontmatter?.imported!==!0))return!1;if(l){if(!c.file)return!1;let d=gt(this.app.metadataCache.getFileCache(c.file)?.frontmatter?.author);if(!d||d.id!==l)return!1}if(t&&c.created){let d=Date.parse(c.created);if(!Number.isNaN(d)&&d<t)return!1}if(i){if(!c.file)return!1;if(this.tagFilter===Yt){if(!this.nodeHasAnyTag(c))return!1}else if(this.tagFilter===zt){if(this.nodeHasAnyTag(c))return!1}else if(!this.nodeHasTag(c,i))return!1}return!(s&&(this.colorForNode(c)?.toLowerCase()??null)!==s||n&&this.isCompleted(c)&&!this.hasIncompleteDescendant(c)||o&&!this.hasAttachmentInSubtree(c))})}collapseVersions(e){if(!this.plugin.settings.enableSheetVersions)return e;let t=new Map,i=!1;for(let n of e){let o=Fe(this.app,n);if(!Xi(o))continue;i=!0;let a=_e(o),l=t.get(a);l?l.push(n):t.set(a,[n])}if(!i)return e;let s=new Set;for(let[n,o]of t){let a=this.activeVersionNode(n,o);a&&s.add(a.id)}return e.filter(n=>Xi(Fe(this.app,n))?s.has(n.id):!0)}activeVersionNode(e,t){let i=this.activeVersionByGroup.get(e);if(i){let s=t.find(n=>n.id===i);if(s)return s}return Ya(this.app,t)}setActiveVersion(e,t){this.activeVersionByGroup.set(e,t),this.plugin.saveActiveVersion(this.noteFolder,e,t),this.render()}nodeHasAnyTag(e){if(!e.file)return!1;let t=this.app.metadataCache.getFileCache(e.file);if(!t)return!1;if(t.tags&&t.tags.length>0)return!0;let i=t.frontmatter?.tags;return!!(i&&(Array.isArray(i)?i:[i]).some(n=>typeof n=="string"&&n.trim().length>0))}nodeHasTag(e,t){if(!e.file)return!1;let i=this.app.metadataCache.getFileCache(e.file);if(!i)return!1;if(i.tags){for(let n of i.tags)if((n.tag||"").replace(/^#/,"").toLowerCase()===t)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()===t)return!0}return!1}collectFolderTags(){let e=new Map,t=this.tree.getChildren(this.focusId);for(let s of t){if(!s.file)continue;let n=this.app.metadataCache.getFileCache(s.file);if(n?.tags)for(let a of n.tags){let l=(a.tag||"").replace(/^#/,"");l&&e.set(l,(e.get(l)??0)+1)}let o=n?.frontmatter?.tags;if(o){let a=Array.isArray(o)?o:[o];for(let l of a){if(typeof l!="string")continue;let c=l.replace(/^#/,"");c&&e.set(c,(e.get(c)??0)+1)}}}let i=[...e.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(e){return e&&e.split("/").map(t=>t.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 e=new Map,t=this.tree.getChildren(this.focusId);for(let s of t){let n=this.colorForNode(s);if(!n)continue;let o=n.toLowerCase();e.set(o,(e.get(o)??0)+1)}let i=[...e.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 e=this.tree.get(this.focusId)??this.tree.getRoot(),t=this.filterChildren(this.collectViewItems(e.id));this.cursorIdx=t.length-1,this.selection.clear(),t.length>0&&(this.selection.add(t[t.length-1].id),this.lastSelected=t[t.length-1].id)}stampSelectedCursor(e=!1){this.stampSelection(e);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(e){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 e=this.listEl;if(!e)return null;let t=e.getBoundingClientRect().top,i=Array.from(e.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-t;if(a>=0){s={id:o,offsetFromListTop:a};break}s={id:o,offsetFromListTop:a}}return s}restoreScrollAnchor(e,t){let i=this.listEl;if(i){if(e){let s=i.querySelector(`[data-id="${e.id}"]`);if(s){let n=i.getBoundingClientRect().top,o=s.getBoundingClientRect().top-n;i.scrollTop+=o-e.offsetFromListTop;return}}t>0&&(i.scrollTop=t)}}render(e){if(Te.enabled&&(this._renderT0=performance.now()),!this.viewRoot?.isConnected)return;this.pendingRenderPolicy=e??{kind:"preserve"},this.loadConfig();let t=this.viewRoot,i=this.listEl?.scrollTop??0,n=(e??{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);t.empty(),t.toggleClass("is-mobile",F.Platform.isMobile),t.toggleClass("is-tiny",this.tinyMode),t.toggleClass("is-compact",this.compactMode);let l=this.containerEl.closest(".workspace-leaf");l&&(l.classList.toggle("stashpad-is-tiny",this.tinyMode),l.classList.toggle("stashpad-is-compact",this.compactMode));let c=this.containerEl.closest(".workspace-tabs");if(c&&c.classList.toggle("stashpad-has-tiny",this.tinyMode),this.tinyMode)this.renderTinyHeader(t);else{let u=this.compactMode&&F.Platform.isMobile;(!this.compactMode||F.Platform.isMobile)&&this.renderTimeFilterBar(t),u||this.renderBreadcrumb(t)}let d=this.tree.get(this.focusId)??this.tree.getRoot();d.file&&!F.Platform.isMobile&&!this.tinyMode&&!this.compactMode&&this.renderFocusedHeader(t,d),this.currentChildren=this.filterChildren(this.collectViewItems(d.id));let h=!1;if(this.autoSelectNewest&&this.currentChildren.length>0){let u=this.currentChildren[this.currentChildren.length-1];this.cursorIdx=this.currentChildren.length-1,this.selection.clear(),this.selection.add(u.id),this.lastSelected=u.id,this.autoSelectNewest=!1,h=!0}else if(this.pendingFocusIds){let u=this.pendingFocusIds;this.pendingFocusIds=null,this.selection.clear();let g=-1;for(let I of u){let m=this.currentChildren.findIndex(C=>C.id===I);m>=0&&(this.selection.add(I),g<0&&(g=m))}this.cursorIdx=g,g>=0&&(this.lastSelected=u.find(I=>this.currentChildren.some(m=>m.id===I))??null)}else this.cursorIdx>=this.currentChildren.length&&(this.cursorIdx=this.currentChildren.length-1);let p=t.createDiv({cls:"stashpad-list"});if(this.listEl=p,this.dnd.attachListDnD(p),this.populateListBody(p,d),this.renderComposer(t),F.Platform.isMobile&&this.renderMobileNav(t),this._renderT0!=null&&(Te.record("render.total",performance.now()-this._renderT0),this._renderT0=null),this.plugin.notifyStashpadContentChanged(),h&&this.plugin.notifyStashpadSelectionChanged(),this.focusComposerOnNextRender){this.focusComposerOnNextRender=!1;let u=this.pendingComposerCaret;this.pendingComposerCaret=null;let g=this.composerInputEl;if(g&&g.isConnected){if(g.focus({preventScroll:!0}),u!=null){let I=Math.min(u,g.value.length);try{g.setSelectionRange(I,I)}catch{}}}else requestAnimationFrame(()=>{let I=this.composerInputEl;if(I&&(I.focus({preventScroll:!0}),u!=null)){let m=Math.min(u,I.value.length);try{I.setSelectionRange(m,m)}catch{}}})}let f=this.pendingRenderPolicy;if(this.pendingRenderPolicy=null,f&&this.listEl){let u=this.scrollToBottomOnNextRender;switch(this.scrollToBottomOnNextRender=!1,f.kind){case"preserve":u?this.scrollListToBottom():a?this.scrollListToBottom():this.restoreScrollAnchor(n,i);break;case"pin-bottom":this.scrollListToBottom();break;case"restore":{let g=f.scrollTop,I=this.listEl,m=()=>{this.suppressScrollSave=!0;let C=Math.max(0,I.scrollHeight-I.clientHeight);I.scrollTop=Math.min(g,C),Promise.resolve().then(()=>{this.suppressScrollSave=!1})};m(),requestAnimationFrame(m),setTimeout(m,60),setTimeout(m,200),setTimeout(m,600);break}case"follow-cursor":i>0&&(this.listEl.scrollTop=i),this.revealCursorRow();break;case"scroll-to-id":{let g=f.id,I=f.align,m=this.listEl,C=()=>{this.suppressScrollSave=!0;let B=m.querySelector(`[data-id="${g}"]`);B&&B.scrollIntoView({block:I,behavior:"auto"}),Promise.resolve().then(()=>{this.suppressScrollSave=!1})};C(),requestAnimationFrame(C),setTimeout(C,60),setTimeout(C,200),setTimeout(C,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 u=this.listEl,g=u.scrollTop,I=new ResizeObserver(()=>{if(Date.now()<this.keyboardTransitionUntil)return;if(this.stickToListBottom){u.scrollTop=u.scrollHeight,g=u.scrollTop;return}let C=Math.max(0,u.scrollHeight-u.clientHeight);u.scrollTop<g&&g<=C?u.scrollTop=g:g=u.scrollTop});I.observe(u),this.listResizeObserver=I,u.addEventListener("wheel",C=>{C.deltaY<0&&(this.stickToListBottom=!1)},{passive:!0});let m=0;u.addEventListener("touchstart",C=>{m=C.touches[0]?.clientY??0},{passive:!0}),u.addEventListener("touchmove",C=>{let B=C.touches[0]?.clientY??m;B>m&&(this.stickToListBottom=!1),m=B},{passive:!0}),u.addEventListener("mousedown",()=>{this.stickToListBottom=!1}),u.addEventListener("keydown",()=>{this.stickToListBottom=!1})}}refreshFolderSwitcherIcon(){let e=this.containerEl.querySelector(".stashpad-folder-btn .stashpad-btn-icon");e&&(e.empty(),(0,F.setIcon)(e,this.plugin.getFolderIcon(this.noteFolder)??"folder"))}renderTimeFilterBar(e){let t=e.createDiv({cls:"stashpad-time-filter-bar"});if(!F.Platform.isMobile){let c=t.createEl("button",{cls:"stashpad-folder-btn"}),d=!!this.folderOverride,h=this.noteFolder.split("/").pop()||this.noteFolder||"Stashpad";(0,F.setIcon)(c.createSpan({cls:"stashpad-btn-icon"}),this.plugin.getFolderIcon(this.noteFolder)??"folder"),c.createSpan({text:h,cls:"stashpad-btn-text"}),c.title=d?`Folder (override): ${this.noteFolder} Click to change or revert to default.`:`Folder: ${this.noteFolder} -Click to override for this tab.`,A&&c.addClass("is-override"),c.onclick=f=>{f.preventDefault(),this.openFolderPicker()};let p=t.createEl("button",{cls:"stashpad-search-btn"});De(p,"search","\u{1F50D}"),p.title="Search notes (Mod+F)",p.onclick=f=>{f.preventDefault(),this.openSearchModal()}}k.Platform.isMobile?(this.renderActionsCluster(t),this.renderMobileFiltersButton(t)):(this.renderTagFilterDropdown(t),this.renderColorFilterDropdown(t),this.renderSortDropdown(t),this.renderViewDropdown(t));let i=t.createDiv({cls:"stashpad-time-filter-btns"}),s=i.createEl("button",{cls:"stashpad-time-filter-btn stashpad-time-filter-cal"});(0,k.setIcon)(s,this.timeFilterCalendar?"calendar":"history"),s.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&&s.addClass("is-active"),s.onclick=c=>{c.preventDefault(),this.timeFilterCalendar=!this.timeFilterCalendar,this.persistFocus(),this.render()};for(let c of xs){let A=this.timeFilterCalendar?c.calShort:c.rollShort,h=this.timeFilterCalendar?c.calLong:c.rollLong,p=i.createEl("button",{cls:"stashpad-time-filter-btn",text:A});p.title=h,this.timeFilter===c.key&&p.addClass("is-active"),p.onclick=f=>{f.preventDefault(),this.setTimeFilter(c.key)}}let n=t.createEl("select",{cls:"stashpad-time-filter-select"});for(let c of xs){let A=this.timeFilterCalendar?c.calLong:c.rollLong,h=n.createEl("option",{text:A});h.value=c.key,this.timeFilter===c.key&&(h.selected=!0)}n.onchange=()=>this.setTimeFilter(n.value);let o=t.createDiv({cls:"stashpad-view-mode-btns"});if(!k.Platform.isMobile){let c=o.createEl("button",{cls:"stashpad-view-mode-btn"});(0,k.setIcon)(c,"minimize-2"),c.title="Tiny mode \u2014 open this tab in a small always-on-top-capable popout window.",c.onclick=A=>{A.preventDefault(),this.plugin.openTinyWindow()}}let a=o.createEl("button",{cls:"stashpad-view-mode-btn"});if((0,k.setIcon)(a,this.compactMode?"panel-top":"rows-2"),a.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&&a.addClass("is-active"),a.onclick=c=>{c.preventDefault(),this.toggleCompactMode()},k.Platform.isMobile)return;let l=o.createEl("button",{cls:"stashpad-view-mode-btn"});(0,k.setIcon)(l,"external-link"),l.title=X().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.)",l.onclick=c=>{c.preventDefault();let A=X().popoutDuplicates;try{let h=this.app.workspace;if(A){let p=this.leaf.getViewState(),f=h.openPopoutLeaf?.();f?f.setViewState({...p,active:!0}):new k.Notice("Stashpad: this Obsidian build doesn't expose openPopoutLeaf.")}else h.moveLeafToPopout?.(this.leaf)}catch(h){new k.Notice(`Stashpad: open-in-new-window failed (${h.message})`)}},this.setupBarOverflow(t)}setupBarOverflow(e){let t=[{key:"nav",icon:"folder-search",title:"Folder & search",memberSel:[".stashpad-folder-btn",".stashpad-search-btn"],memberKeys:["folder","search"],collapsePrio:5,displayIdx:0},{key:"filter",icon:"filter",title:"Tag & color",memberSel:[".stashpad-tag-filter-btn",".stashpad-color-filter-btn"],memberKeys:["tag","color"],collapsePrio:3,displayIdx:1},{key:"arrange",icon:"sliders-horizontal",title:"Sort & view",memberSel:[".stashpad-sort-btn",".stashpad-view-btn"],memberKeys:["sort","view"],collapsePrio:4,displayIdx:2},{key:"time",icon:"clock",title:"Time",memberSel:[".stashpad-time-filter-btns",".stashpad-time-filter-select"],memberKeys:["time"],collapsePrio:2,displayIdx:3},{key:"window",icon:"app-window",title:"Window & layout",memberSel:[".stashpad-view-mode-btns"],memberKeys:["mode"],collapsePrio:1,displayIdx:4}];e.addClass("stashpad-overflow-managed");let i=[];for(let f of[...t].sort((u,g)=>u.displayIdx-g.displayIdx)){let u=f.memberSel.map(B=>e.querySelector(B)).filter(B=>!!B);if(u.length===0)continue;let g=createDiv({cls:"stashpad-bar-group"});e.insertBefore(g,u[0]);let I=g.createDiv({cls:"stashpad-bar-group-expanded"});for(let B of u)I.appendChild(B);let m=g.createDiv({cls:"stashpad-bar-overflow-btn stashpad-bar-group-icon stashpad-overflow-hidden"});m.setAttribute("role","button"),m.setAttribute("tabindex","0"),(0,k.setIcon)(m.createSpan({cls:"stashpad-bar-group-icon-glyph"}),f.icon),m.title=`${f.title} \u2014 combined menu`;let C=B=>{B.preventDefault(),this.openBarOverflowMenu(m,f.memberKeys)};m.onclick=C,m.onkeydown=B=>{(B.key==="Enter"||B.key===" ")&&C(B)},i.push({...f,wrapper:g,expanded:I,iconBtn:m})}let s=e.createDiv({cls:"stashpad-bar-overflow-btn stashpad-bar-kebab stashpad-overflow-hidden"});s.setAttribute("role","button"),s.setAttribute("tabindex","0"),(0,k.setIcon)(s.createSpan({cls:"stashpad-bar-overflow-icon"}),"more-horizontal"),s.title="More filters / view options";let n=[...i].sort((f,u)=>f.collapsePrio-u.collapsePrio),o=[...i].sort((f,u)=>u.displayIdx-f.displayIdx),a=[],l=()=>e.scrollWidth<=e.clientWidth+1,c=()=>{if(!e.isConnected||e.clientWidth===0)return;for(let u of i)u.wrapper.removeClass("stashpad-overflow-hidden"),u.expanded.removeClass("stashpad-overflow-hidden"),u.iconBtn.addClass("stashpad-overflow-hidden"),u.iconBtn.toggleClass("is-active",u.memberKeys.some(g=>this.barUnitActive(g)));if(s.addClass("stashpad-overflow-hidden"),a=[],l())return;for(let u of n){if(l())break;u.expanded.addClass("stashpad-overflow-hidden"),u.iconBtn.removeClass("stashpad-overflow-hidden")}if(l())return;s.removeClass("stashpad-overflow-hidden");let f=[];for(let u of o){if(l())break;u.wrapper.addClass("stashpad-overflow-hidden"),f.push(u)}a=[...f].sort((u,g)=>u.displayIdx-g.displayIdx).flatMap(u=>u.memberKeys),s.toggleClass("is-active",a.some(u=>this.barUnitActive(u)))},A=f=>{f.preventDefault(),this.openBarOverflowMenu(s,a)};s.onclick=A,s.onkeydown=f=>{(f.key==="Enter"||f.key===" ")&&A(f)};try{this.barOverflowRO?.disconnect()}catch{}let h=(e.ownerDocument?.defaultView??window).ResizeObserver,p=-1;this.barOverflowRO=new h(f=>{let u=Math.round(f[f.length-1].contentRect.width);u!==p&&(p=u,c())}),this.barOverflowRO.observe(e),requestAnimationFrame(()=>c())}barUnitActive(e){switch(e){case"folder":return!!this.folderOverride;case"tag":return!!this.tagFilter;case"color":return!!this.colorFilter;case"time":return this.timeFilter!=="all";case"sort":return this.currentViewMode()==="nested"&&this.sortStore.getMode(this.noteFolder,this.focusId)!=="manual";case"view":return this.currentViewMode()!=="nested"||this.currentEncryptionFilter()!=="all"||this.currentHideChildless()||this.currentHideCompleted()||this.currentAttachmentsOnly()||this.currentIncludeAttachments();case"mode":return this.compactMode;default:return!1}}openBarOverflowMenu(e,t){let i=e.ownerDocument??document;i.querySelectorAll(".stashpad-mobile-filters-popover").forEach(u=>u.remove());let s=i.body.createDiv({cls:"stashpad-mobile-filters-popover"}),n=e.getBoundingClientRect(),o=i.defaultView??window;s.setCssStyles({right:`${Math.max(8,o.innerWidth-n.right)}px`,left:"auto",top:`${n.bottom+4}px`,maxWidth:"min(360px, calc(100vw - 16px))",width:"max-content",minWidth:"260px"});let a=new k.Scope(this.app.scope),l=()=>{s.remove(),i.removeEventListener("mousedown",c,!0);try{this.app.keymap?.popScope(a)}catch{}},c=u=>{!s.contains(u.target)&&u.target!==e&&!e.contains(u.target)&&l()},h=[{key:"folder",title:"Folder",summary:()=>this.noteFolder.split("/").pop()||this.noteFolder||"Stashpad",populate:u=>this.populateFolderMenuBody(u,l)},{key:"search",title:"Search",summary:()=>"Search notes (Mod+F)",populate:u=>this.populateSearchMenuBody(u,l)},{key:"tag",title:"Tag filter",summary:()=>this.tagFilter?`#${this.tagFilter}`:"All tags",populate:u=>this.populateTagMenuBody(u,l)},{key:"color",title:"Color filter",summary:()=>this.colorFilter?this.plugin.getColorAlias(this.noteFolder,this.colorFilter)??this.colorFilter:"All colors",populate:u=>this.populateColorMenuBody(u,this.collectFolderColors(),l)},{key:"sort",title:"Sort",summary:()=>this.currentViewMode()!=="nested"?"\u2014 (Nested only)":Ni[this.sortStore.getMode(this.noteFolder,this.focusId)],populate:u=>{if(this.currentViewMode()!=="nested"){u.createDiv({cls:"stashpad-mobile-filters-note",text:"Sort applies only in Nested view."});return}this.populateSortMenuBody(u,l)}},{key:"view",title:"View",summary:()=>Ds[this.currentViewMode()],populate:u=>this.populateViewMenuBody(u,l)},{key:"time",title:"Time filter",summary:()=>{let u=xs.find(g=>g.key===this.timeFilter);return u?this.timeFilterCalendar?u.calShort:u.rollShort:"All"},populate:u=>this.populateTimeMenuBody(u,l)},{key:"mode",title:"View mode",summary:()=>this.compactMode?"Compact on":"Tiny \xB7 Compact \xB7 Window",populate:u=>this.populateModeMenuBody(u,l)}].filter(u=>t.includes(u.key)),p="",f=()=>{s.empty();for(let u of h){let g=s.createDiv({cls:"stashpad-mobile-filters-section"}),I=g.createDiv({cls:"stashpad-mobile-filters-header"}),m=I.createSpan({cls:"stashpad-mobile-filters-chev"});(0,k.setIcon)(m,p===u.key?"chevron-down":"chevron-right"),I.createSpan({cls:"stashpad-mobile-filters-title",text:u.title}),I.createSpan({cls:"stashpad-mobile-filters-summary",text:u.summary()}),I.onclick=C=>{C.preventDefault(),C.stopPropagation(),p=p===u.key?"":u.key,f()},p===u.key&&u.populate(g.createDiv({cls:"stashpad-mobile-filters-body"}))}};f(),a.register([],"Escape",u=>(u.preventDefault(),l(),!1)),this.app.keymap?.pushScope(a),setTimeout(()=>{i.addEventListener("mousedown",c,!0)},0)}populateFolderMenuBody(e,t){let i=e.createDiv({cls:"stashpad-sort-popover-row"});i.createSpan({cls:"stashpad-sort-popover-label",text:this.folderOverride?"Change folder (override active)\u2026":"Change folder for this tab\u2026"}),i.onclick=s=>{s.preventDefault(),s.stopPropagation(),t(),this.openFolderPicker()}}populateSearchMenuBody(e,t){let i=e.createDiv({cls:"stashpad-sort-popover-row"});i.createSpan({cls:"stashpad-sort-popover-label",text:"Search notes\u2026"}),i.onclick=s=>{s.preventDefault(),s.stopPropagation(),t(),this.openSearchModal()}}populateModeMenuBody(e,t){let i=(n,o)=>{let a=e.createDiv({cls:"stashpad-sort-popover-row"});a.createSpan({cls:"stashpad-sort-popover-label",text:n}),a.onclick=l=>{l.preventDefault(),l.stopPropagation(),t(),o()}};i("Tiny mode (popout window)",()=>void this.plugin.openTinyWindow());let s=e.createDiv({cls:"stashpad-sort-popover-row"});this.compactMode&&s.addClass("is-active"),s.createSpan({cls:"stashpad-sort-popover-label",text:this.compactMode?"Compact mode (on)":"Compact mode"}),s.onclick=n=>{n.preventDefault(),n.stopPropagation(),t(),this.toggleCompactMode()},i(X().popoutDuplicates?"Duplicate to new window":"Move to new window",()=>{try{let n=this.app.workspace;if(X().popoutDuplicates){let o=n.openPopoutLeaf?.();o?o.setViewState({...this.leaf.getViewState(),active:!0}):new k.Notice("Stashpad: this Obsidian build doesn't expose openPopoutLeaf.")}else n.moveLeafToPopout?.(this.leaf)}catch(n){new k.Notice(`Stashpad: open-in-new-window failed (${n.message})`)}})}toggleCompactMode(){this.compactMode=!this.compactMode,this.render();try{this.app.workspace.requestSaveLayout?.()}catch{}}renderActionsCluster(e){let t=e.createDiv({cls:"stashpad-mobile-actions"}),i=t.createEl("button",{cls:"stashpad-mobile-action-btn"});De(i,"arrow-left","\u2039");let s=this.navBackStack.length>0||this.focusId!==S;i.title=this.navBackStack.length>0?"Back":this.focusId!==S?"Back (up to parent)":"No back history",s||i.addClass("is-disabled"),i.onclick=h=>{h.preventDefault(),this.navigateBack()};let n=t.createEl("button",{cls:"stashpad-mobile-action-btn"});De(n,"arrow-right","\u203A");let o=this.navForwardSnapshots.length>0;if(n.title=o?"Forward":"No forward history",o||n.addClass("is-disabled"),n.onclick=h=>{h.preventDefault(),this.navigateForward()},k.Platform.isMobile){let h=t.createEl("button",{cls:"stashpad-mobile-action-btn"});De(h,"route","\u22D4"),h.title="Jump to a level in the path",h.onclick=p=>{p.preventDefault(),this.openBreadcrumbLevelsModal()}}let a=t.createEl("button",{cls:"stashpad-mobile-action-btn"}),l=this.mobileSelectMode;De(a,l?"check-square":"square",l?"\u2611":"\u2610"),a.title=l?`${this.selection.size} selected \u2014 tap to exit (keeps the first selection)`:"Enter select mode (tap notes to add)",l&&a.addClass("is-active"),a.onclick=h=>{if(h.preventDefault(),this.mobileSelectMode){let p=this.firstSelectedId??this.selection.values().next().value;if(this.selection.clear(),p){let f=this.currentChildren.findIndex(u=>u.id===p);this.selection.add(p),this.lastSelected=p,f>=0&&(this.cursorIdx=f)}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 k.Notice("Select mode: tap notes to add, press \u26A1 for actions")}};let c=t.createEl("button",{cls:"stashpad-mobile-action-btn"});De(c,"zap","\u26A1"),c.title="Actions (move, delete, undo, \u2026)",c.onclick=h=>{h.preventDefault(),this.openMobileActionsMenu(c)};let A=t.createEl("button",{cls:"stashpad-mobile-action-btn stashpad-open-link-btn"});De(A,"link","\u{1F517}"),A.title="Open a Stashpad link (paste a deep link / URL)",A.onclick=h=>{h.preventDefault(),this.plugin.openDeepLinkModal()}}openMobileActionsMenu(e){let t=new k.Menu,i=this.selection.size>0||this.cursorIdx>=0&&!!this.currentChildren[this.cursorIdx],s=this.selection.size<=1;t.addItem(o=>o.setTitle("Undo").setIcon("undo").onClick(()=>this.cmdUndo())),t.addItem(o=>o.setTitle("Redo").setIcon("redo").onClick(()=>this.cmdRedo())),t.addSeparator(),t.addItem(o=>o.setTitle("Notification history\u2026").setIcon("bell").onClick(()=>{this.app.commands?.executeCommandById?.("stashpad:stashpad-open-notification-history")})),t.addItem(o=>o.setTitle("Reload without saving").setIcon("rotate-ccw").onClick(()=>this.plugin.reloadAppForUpdate())),t.addItem(o=>o.setTitle("Open Stashpad link\u2026").setIcon("link").onClick(()=>this.plugin.openDeepLinkModal())),t.addSeparator(),t.addItem(o=>o.setTitle("Expand all").setIcon("unfold-vertical").onClick(()=>this.cmdExpandAll())),t.addItem(o=>o.setTitle("Collapse all").setIcon("fold-vertical").onClick(()=>this.cmdCollapseAll())),t.addSeparator(),t.addItem(o=>o.setTitle("Open in new Stashpad tab").setIcon("list-tree").setDisabled(!i).onClick(()=>this.cmdOpenInNewStashpadTab())),t.addItem(o=>o.setTitle("Edit in Stashpad").setIcon("pencil-line").setDisabled(!i).onClick(()=>void this.cmdEdit())),t.addItem(o=>o.setTitle("Open in Obsidian editor").setIcon("pencil").setDisabled(!i).onClick(()=>this.cmdOpenInEditor())),t.addSeparator(),t.addItem(o=>o.setTitle("Move\u2026").setIcon("arrow-right-circle").setDisabled(!i).onClick(()=>this.cmdMovePicker())),t.addItem(o=>o.setTitle("Nest under\u2026 (in-list)").setIcon("indent").setDisabled(!i).onClick(()=>this.cmdInListPicker())),t.addItem(o=>o.setTitle("Outdent").setIcon("outdent").setDisabled(!i).onClick(()=>void this.cmdOutdent())),t.addItem(o=>o.setTitle("Set color\u2026").setIcon("palette").setDisabled(!i).onClick(()=>this.cmdSetColor())),t.addItem(o=>o.setTitle("Toggle complete").setIcon("check-circle").setDisabled(!i).onClick(()=>void this.cmdToggleComplete())),t.addItem(o=>o.setTitle("Toggle task (todo)").setIcon("check-square").setDisabled(!i).onClick(()=>void this.cmdToggleTask())),t.addItem(o=>o.setTitle("Set due date\u2026").setIcon("calendar-clock").setDisabled(!i).onClick(()=>this.cmdSetDue())),t.addItem(o=>o.setTitle("Assign to\u2026").setIcon("user-plus").setDisabled(!i).onClick(()=>this.cmdAssign())),t.addSeparator(),t.addItem(o=>o.setTitle("Copy").setIcon("copy").setDisabled(!i).onClick(()=>void this.cmdCopy())),t.addItem(o=>o.setTitle("Copy tree").setIcon("copy-plus").setDisabled(!i).onClick(()=>void this.cmdCopyTree())),t.addItem(o=>o.setTitle("Clone (duplicate / copy)").setIcon("files").setDisabled(!i).onClick(()=>void this.cmdClone())),this.addShareExportSubmenu(t,this.getActionTargets()[0]??null,{normalizeToNode:!1}),this.plugin.settings.enableSheetVersions&&(t.addItem(o=>o.setTitle("Fork as a version (draft)").setIcon("git-fork").setDisabled(!i||!s).onClick(()=>void this.cmdForkVersion())),t.addItem(o=>o.setTitle("Mark version as final").setIcon("star").setDisabled(!i||!s).onClick(()=>void this.cmdMarkVersionFinal()))),t.addItem(o=>o.setTitle("Insert template\u2026").setIcon("file-plus-2").onClick(()=>this.cmdInsertTemplate())),t.addItem(o=>o.setTitle("Merge").setIcon("merge").setDisabled(this.selection.size<2).onClick(()=>void this.cmdMerge())),t.addItem(o=>o.setTitle("Split note\u2026").setIcon("scissors").setDisabled(!i||!s).onClick(()=>void this.cmdSplit())),t.addSeparator(),t.addItem(o=>o.setTitle("Delete").setIcon("trash-2").setDisabled(!i).onClick(()=>void this.cmdDelete())),t.addSeparator(),t.addItem(o=>o.setTitle("More commands\u2026").setIcon("terminal").onClick(()=>this.openCommandPalette()));let n=e.getBoundingClientRect();t.showAtPosition({x:n.left,y:n.bottom+4})}openCommandPalette(){this.app.commands?.executeCommandById?.("command-palette:open")}openStashpadCommandPalette(){new Nn(this.app).open()}tagFilterLabel(){return this.tagFilter===Yt?"Tagged":this.tagFilter===zt?"Untagged":this.tagFilter?`#${this.formatTagLabel(this.tagFilter)}`:this.collectFolderTags().length===0?"No tags":"All tags"}renderTagFilterDropdown(e){let t=this.collectFolderTags(),i=e.createDiv({cls:"stashpad-tag-filter-btn"});i.setAttribute("role","button"),i.setAttribute("tabindex","0");let s=i.createSpan({cls:"stashpad-tag-filter-btn-icon"});De(s,"tag","#"),i.createSpan({cls:"stashpad-tag-filter-label",text:this.tagFilterLabel()}),t.length===0&&!this.tagFilter&&i.addClass("is-disabled");let n=o=>{o.preventDefault(),!(t.length===0&&!this.tagFilter)&&this.openTagFilterMenu(i)};i.onclick=n,i.onkeydown=o=>{(o.key==="Enter"||o.key===" ")&&n(o)}}openTagFilterMenu(e){let t=e.ownerDocument??document;t.querySelectorAll(".stashpad-tag-filter-popover").forEach(E=>E.remove());let i=t.body.createDiv({cls:"stashpad-tag-filter-popover"}),s=e.getBoundingClientRect();i.setCssStyles({left:`${Math.max(8,s.left)}px`,top:`${s.bottom+4}px`,minWidth:`${Math.max(s.width,200)}px`,maxWidth:"min(320px, calc(100vw - 16px))",width:"max-content"});let n=new k.Scope(this.app.scope),o=()=>{i.remove(),t.removeEventListener("mousedown",a,!0);try{this.app.keymap?.popScope(n)}catch{}},a=E=>{!i.contains(E.target)&&E.target!==e&&!e.contains(E.target)&&o()},l=i.createDiv({cls:"stashpad-tag-filter-search"}),c=l.createSpan({cls:"stashpad-tag-filter-search-icon"});De(c,"search","\u2315");let A=l.createEl("input",{type:"text",cls:"stashpad-tag-filter-input",attr:{placeholder:"Filter tags\u2026"}}),h=l.createSpan({cls:"stashpad-tag-filter-clear",attr:{"aria-label":"Clear"}});De(h,"x","\xD7"),h.setCssStyles({display:"none"});let p=i.createDiv({cls:"stashpad-tag-filter-list"}),f=this.collectFolderTags(),u=[],g=0,I=E=>{this.setTagFilter(E),o()},m=E=>{if(u.length===0){g=0;return}g=(E+u.length)%u.length,u.forEach((y,v)=>y.el.toggleClass("is-highlighted",v===g)),u[g].el.scrollIntoView({block:"nearest"})},C=(E,y,v,Q)=>{let w=p.createDiv({cls:"stashpad-tag-filter-row"});Q&&w.addClass("is-active"),w.createSpan({cls:"stashpad-tag-filter-row-label",text:E}),typeof v=="number"&&w.createSpan({cls:"stashpad-tag-filter-row-count",text:String(v)});let F=u.length;u.push({value:y,el:w}),w.onmousedown=D=>{D.preventDefault(),I(y)},w.onmouseenter=()=>m(F)},B=()=>{let E=A.value;h.setCssStyles({display:E?"":"none"}),p.empty(),u=[];let y=this.tagFilter?.toLowerCase();if(E.trim()){let v=ir(E,f);if(v.length===0)p.createDiv({cls:"stashpad-tag-filter-empty",text:"No matching tags"});else for(let Q of v)C(`#${Q.label}`,Q.raw,Q.count,y===Q.raw.toLowerCase())}else{C("All tags",null,void 0,!this.tagFilter),C("Tagged",Yt,void 0,this.tagFilter===Yt),C("Untagged",zt,void 0,this.tagFilter===zt);for(let v of f)C(`#${v.label}`,v.raw,v.count,y===v.raw.toLowerCase())}m(0)};h.onclick=()=>{A.value="",B(),A.focus()},A.addEventListener("input",B),A.addEventListener("keydown",E=>{E.key==="ArrowDown"?(E.preventDefault(),m(g+1)):E.key==="ArrowUp"?(E.preventDefault(),m(g-1)):E.key==="Enter"&&(E.preventDefault(),u[g]&&I(u[g].value))}),n.register([],"Escape",E=>(E.preventDefault(),o(),!1)),this.app.keymap?.pushScope(n),B(),setTimeout(()=>{t.addEventListener("mousedown",a,!0),A.focus()},0)}renderColorFilterDropdown(e){let t=this.collectFolderColors(),i=e.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 l=this.colorFilter.toLowerCase();o.setCssStyles({background:l});let c=this.plugin.getColorAlias(this.noteFolder,l);a.setText(c??l)}else t.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(),!(t.length===0&&!this.colorFilter)&&this.openColorFilterMenu(i,t)};i.onclick=n,i.onkeydown=o=>{(o.key==="Enter"||o.key===" ")&&n(o)}}openColorFilterMenu(e,t){let i=e.ownerDocument??document;i.querySelectorAll(".stashpad-color-filter-popover").forEach(c=>c.remove());let s=i.body.createDiv({cls:"stashpad-color-filter-popover"}),n=e.getBoundingClientRect();s.setCssStyles({left:`${Math.max(8,n.left)}px`,top:`${n.bottom+4}px`,minWidth:`${n.width}px`,maxWidth:"min(280px, calc(100vw - 16px))",width:"max-content"});let o=new k.Scope(this.app.scope),a=()=>{s.remove(),i.removeEventListener("mousedown",l,!0);try{this.app.keymap?.popScope(o)}catch{}},l=c=>{!s.contains(c.target)&&c.target!==e&&!e.contains(c.target)&&a()};o.register([],"Escape",c=>(c.preventDefault(),a(),!1)),this.app.keymap?.pushScope(o),this.populateColorMenuBody(s,t,a),setTimeout(()=>{i.addEventListener("mousedown",l,!0)},0)}renderSortDropdown(e){let t=this.noteFolder,i=this.focusId,s=this.sortStore.getMode(t,i),n=this.currentViewMode(),o=n!=="nested",a=e.createDiv({cls:"stashpad-sort-btn"});a.setAttribute("role","button"),a.setAttribute("tabindex",o?"-1":"0"),o&&a.addClass("is-disabled");let l=a.createSpan({cls:"stashpad-sort-icon"});(0,k.setIcon)(l,"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 (${Ds[n]}) shows a synthesized flat list sorted by created time \u2014 switch back to Nested to change sort.`):(c.setText(Ni[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: ${Ni[s]}. Drag-reorder will revert this parent to Manual.`);let A=h=>{o||(h.preventDefault(),this.openSortMenu(a))};a.onclick=A,a.onkeydown=h=>{o||(h.key==="Enter"||h.key===" ")&&A(h)}}openSortMenu(e){let t=e.ownerDocument??document;t.querySelectorAll(".stashpad-sort-popover").forEach(l=>l.remove());let i=t.body.createDiv({cls:"stashpad-sort-popover"}),s=e.getBoundingClientRect();i.setCssStyles({left:`${Math.max(8,s.left)}px`,top:`${s.bottom+4}px`,minWidth:`${s.width}px`,maxWidth:"min(280px, calc(100vw - 16px))",width:"max-content"});let n=()=>{i.remove(),t.removeEventListener("mousedown",o,!0);try{this.app.keymap?.popScope(a)}catch{}},o=l=>{!i.contains(l.target)&&l.target!==e&&!e.contains(l.target)&&n()};this.populateSortMenuBody(i,n);let a=new k.Scope(this.app.scope);a.register([],"Escape",l=>(l.preventDefault(),n(),!1)),this.app.keymap?.pushScope(a),setTimeout(()=>{t.addEventListener("mousedown",o,!0)},0)}renderMobileFiltersButton(e){let t=e.createDiv({cls:"stashpad-mobile-filters-btn"});t.setAttribute("role","button"),t.setAttribute("tabindex","0");let i=t.createSpan({cls:"stashpad-mobile-filters-icon"});(0,k.setIcon)(i,"sliders-horizontal"),t.title="Filters / view options";let s=!!this.tagFilter,n=!!this.colorFilter,o=this.timeFilter!=="all",a=this.sortStore.getMode(this.noteFolder,this.focusId)!=="manual",l=this.currentViewMode()!=="nested"||this.currentHideChildless()||this.currentHideCompleted()||this.currentAttachmentsOnly()||this.currentIncludeAttachments();(s||n||o||a||l)&&t.addClass("is-active");let c=A=>{A.preventDefault(),this.openMobileFiltersMenu(t)};t.onclick=c,t.onkeydown=A=>{(A.key==="Enter"||A.key===" ")&&c(A)}}openMobileFiltersMenu(e){let t=e.ownerDocument??document;t.querySelectorAll(".stashpad-mobile-filters-popover").forEach(f=>f.remove());let i=t.body.createDiv({cls:"stashpad-mobile-filters-popover"}),s=e.getBoundingClientRect(),n=t.defaultView??window,o=s.bottom+280>n.innerHeight;i.setCssStyles({right:`${Math.max(8,n.innerWidth-s.right)}px`,left:"auto",...o?{bottom:`${Math.max(8,n.innerHeight-s.top+4)}px`,top:"auto"}:{top:`${s.bottom+4}px`,bottom:"auto"},maxWidth:"min(360px, calc(100vw - 16px))",maxHeight:"min(60vh, 420px)",overflowY:"auto",width:"max-content",minWidth:"260px"});let a=()=>{i.remove(),t.removeEventListener("mousedown",l,!0);try{this.app.keymap?.popScope(p)}catch{}},l=f=>{!i.contains(f.target)&&f.target!==e&&!e.contains(f.target)&&a()},c=[{key:"tag",title:"Tag filter",summary:()=>this.tagFilter?`#${this.tagFilter}`:"All tags",populate:f=>this.populateTagMenuBody(f,a)},{key:"color",title:"Color filter",summary:()=>this.colorFilter?this.plugin.getColorAlias(this.noteFolder,this.colorFilter)??this.colorFilter:"All colors",populate:f=>this.populateColorMenuBody(f,this.collectFolderColors(),a)},{key:"time",title:"Time filter",summary:()=>{let f=xs.find(u=>u.key===this.timeFilter);return f?this.timeFilterCalendar?f.calShort:f.rollShort:"All"},populate:f=>this.populateTimeMenuBody(f,a)},{key:"sort",title:"Sort",summary:()=>this.currentViewMode()!=="nested"?"\u2014 (Nested only)":Ni[this.sortStore.getMode(this.noteFolder,this.focusId)],populate:f=>{if(this.currentViewMode()!=="nested"){f.createDiv({cls:"stashpad-mobile-filters-note",text:"Sort applies only in Nested view."});return}this.populateSortMenuBody(f,a)}},{key:"view",title:"View",summary:()=>Ds[this.currentViewMode()],populate:f=>this.populateViewMenuBody(f,a)}],A="",h=()=>{i.empty();for(let f of c){let u=i.createDiv({cls:"stashpad-mobile-filters-section"}),g=u.createDiv({cls:"stashpad-mobile-filters-header"}),I=g.createSpan({cls:"stashpad-mobile-filters-chev"});if((0,k.setIcon)(I,A===f.key?"chevron-down":"chevron-right"),g.createSpan({cls:"stashpad-mobile-filters-title",text:f.title}),g.createSpan({cls:"stashpad-mobile-filters-summary",text:f.summary()}),g.onclick=m=>{m.preventDefault(),m.stopPropagation(),A=A===f.key?"":f.key,h()},A===f.key){let m=u.createDiv({cls:"stashpad-mobile-filters-body"});f.populate(m)}}};h();let p=new k.Scope(this.app.scope);p.register([],"Escape",f=>(f.preventDefault(),a(),!1)),this.app.keymap?.pushScope(p),setTimeout(()=>{t.addEventListener("mousedown",l,!0)},0)}renderViewDropdown(e){let t=this.currentViewMode(),i=e.createDiv({cls:"stashpad-view-btn"});i.setAttribute("role","button"),i.setAttribute("tabindex","0");let s=i.createSpan({cls:"stashpad-view-icon"});(0,k.setIcon)(s,t==="flat"?"list":t==="everything"?"layout-grid":"list-tree"),i.createSpan({cls:"stashpad-view-label"}).setText(Ds[t]),(t!=="nested"||this.currentEncryptionFilter()!=="all")&&i.addClass("is-active"),i.title=t==="nested"?"View: Nested (the default). Click to switch to Flat or Everything.":t==="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(e){let t=e.ownerDocument??document;t.querySelectorAll(".stashpad-view-popover").forEach(l=>l.remove());let i=t.body.createDiv({cls:"stashpad-view-popover"});k.Platform.isMobile&&i.addClass("is-mobile");let s=e.getBoundingClientRect();i.setCssStyles({left:`${Math.max(8,s.left)}px`,top:`${s.bottom+4}px`,minWidth:`${s.width}px`,maxWidth:"min(320px, calc(100vw - 16px))",width:"max-content"});let n=()=>{i.remove(),t.removeEventListener("mousedown",o,!0);try{this.app.keymap?.popScope(a)}catch{}},o=l=>{!i.contains(l.target)&&l.target!==e&&!e.contains(l.target)&&n()};this.populateViewMenuBody(i,n);let a=new k.Scope(this.app.scope);a.register([],"Escape",l=>(l.preventDefault(),n(),!1)),this.app.keymap?.pushScope(a),setTimeout(()=>{t.addEventListener("mousedown",o,!0)},0)}populateViewMenuBody(e,t){let i=this.currentViewMode(),s=(y,v,Q)=>{let w=e.createDiv({cls:"stashpad-view-popover-row"});y===i&&w.addClass("is-active");let F=w.createDiv({cls:"stashpad-view-popover-main"});(0,k.setIcon)(F.createSpan({cls:"stashpad-view-popover-icon"}),Q),F.createSpan({cls:"stashpad-view-popover-label",text:Ds[y]}),w.createDiv({cls:"stashpad-view-popover-desc",text:v}),w.onclick=async D=>{D.preventDefault(),D.stopPropagation(),t(),y!==i&&(await this.setViewMode(y),this.render())}};if(s("nested","Tree of immediate children (default).","list-tree"),e.createDiv({cls:"stashpad-view-popover-divider"}),s("flat","All descendants of the current focus, flat by sort.","list"),e.createDiv({cls:"stashpad-view-popover-divider"}),s("everything","All descendants PLUS non-Stashpad files in the folder.","layout-grid"),e.createDiv({cls:"stashpad-view-popover-divider"}),this.plugin.encryption?.isConfigured?.()){let y=this.currentEncryptionFilter(),v=(Q,w,F)=>{let D=e.createDiv({cls:"stashpad-view-popover-row"});Q===y&&D.addClass("is-active"),D.createDiv({cls:"stashpad-view-popover-main"}).createSpan({cls:"stashpad-view-popover-label",text:w}),D.createDiv({cls:"stashpad-view-popover-desc",text:F}),D.onclick=async H=>{H.preventDefault(),H.stopPropagation(),Q!==y&&(await this.setEncryptionFilter(Q),this.refreshList()),t()}};v("all","Encryption: show all","Both locked \u{1F512} and decrypted notes."),v("locked","Encryption: locked only","Show only locked \u{1F512} stubs."),v("unlocked","Encryption: decrypted only","Hide locked \u{1F512} stubs."),e.createDiv({cls:"stashpad-view-popover-divider"})}let n=e.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 y=>{y.target!==o&&(y.preventDefault(),o.checked=!o.checked),await this.setHideChildless(o.checked),this.refreshList()};let a=e.createDiv({cls:"stashpad-view-popover-row stashpad-view-popover-toggle"}),l=a.createEl("input",{type:"checkbox"});l.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 y=>{y.target!==l&&(y.preventDefault(),l.checked=!l.checked),await this.setHideCompleted(l.checked),this.refreshList()};let c=e.createDiv({cls:"stashpad-view-popover-row stashpad-view-popover-toggle"}),A=c.createEl("input",{type:"checkbox"});A.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 y=>{y.target!==A&&(y.preventDefault(),A.checked=!A.checked),await this.setAttachmentsOnly(A.checked),this.refreshList()},e.createDiv({cls:"stashpad-view-popover-divider"});let h=e.createDiv({cls:"stashpad-view-popover-row stashpad-view-popover-toggle"});i!=="everything"&&h.addClass("is-disabled");let p=h.createEl("input",{type:"checkbox"});p.checked=this.currentIncludeAttachments(),p.disabled=i!=="everything",h.createDiv({cls:"stashpad-view-popover-main"}).createSpan({cls:"stashpad-view-popover-label",text:"Include attachments"}),h.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."}),h.onclick=async y=>{i==="everything"&&(y.target!==p&&(y.preventDefault(),p.checked=!p.checked),await this.setIncludeAttachments(p.checked),this.refreshList())},e.createDiv({cls:"stashpad-view-popover-divider"});let f=e.createDiv({cls:"stashpad-view-popover-row stashpad-view-popover-toggle"}),u=f.createEl("input",{type:"checkbox"});u.checked=this.importedOnly,f.createDiv({cls:"stashpad-view-popover-main"}).createSpan({cls:"stashpad-view-popover-label",text:"Imported notes only"}),f.createDiv({cls:"stashpad-view-popover-desc",text:"Show only notes that came in via import."}),f.onclick=y=>{y.target!==u&&(y.preventDefault(),u.checked=!u.checked),this.importedOnly=u.checked,this.reconcileSelectionAfterFilter(),this.refreshList()};let g=new Map,I=this.noteFolder.replace(/\/+$/,"");for(let y of this.app.vault.getMarkdownFiles()){if((y.parent?.path?.replace(/\/+$/,"")??"")!==I)continue;let v=gt(this.app.metadataCache.getFileCache(y)?.frontmatter?.author);v&&g.set(v.id,v.name)}e.createDiv({cls:"stashpad-view-popover-divider"});let m=e.createDiv({cls:"stashpad-view-popover-row"}),C=m.createDiv({cls:"stashpad-view-popover-main"});(0,k.setIcon)(C.createSpan({cls:"stashpad-view-popover-icon"}),"user"),C.createSpan({cls:"stashpad-view-popover-label",text:"By author"});let B=C.createEl("select",{cls:"stashpad-view-author-select"}),E=B.createEl("option",{text:"All authors",value:""});this.authorFilter||(E.selected=!0);for(let[y,v]of[...g.entries()].sort((Q,w)=>Q[1].localeCompare(w[1]))){let Q=B.createEl("option",{text:v,value:y});this.authorFilter===y&&(Q.selected=!0)}B.onclick=y=>y.stopPropagation(),B.onchange=()=>{this.authorFilter=B.value||null,this.reconcileSelectionAfterFilter(),this.refreshList()},m.createDiv({cls:"stashpad-view-popover-desc",text:g.size?"Show only notes by the chosen author.":"No authored notes in this folder yet."})}setTagFilter(e){(this.tagFilter??null)!==(e??null)&&(this.tagFilter=e,this.reconcileSelectionAfterFilter(),this.persistFocus(),this.render())}populateSortMenuBody(e,t){let i=this.noteFolder,s=this.focusId,n=this.sortStore.getMode(i,s);for(let o of ia){let a=e.createDiv({cls:"stashpad-sort-popover-row"});o===n&&a.addClass("is-active"),a.createSpan({cls:"stashpad-sort-popover-label",text:Ni[o]}),a.onclick=async l=>{l.preventDefault(),l.stopPropagation(),t(),o!==n&&(this.sortStore.setMode(i,s,o),await this.sortStore.save(i),this.tree.rebuild(i),this.render())}}}populateTimeMenuBody(e,t){let i=e.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 xs){let o=e.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=l=>{l.preventDefault(),l.stopPropagation(),t(),this.timeFilter!==n.key&&this.setTimeFilter(n.key)}}}populateColorMenuBody(e,t,i){let s=(n,o,a)=>{let l=e.createDiv({cls:"stashpad-color-filter-popover-row"}),c=l.createSpan({cls:"stashpad-color-filter-swatch"});o?c.setCssStyles({background:o}):c.addClass("is-empty");let A=l.createSpan({cls:"stashpad-color-filter-popover-label"});A.setText(n),o&&(A.style.color=o),l.onclick=h=>{h.preventDefault(),h.stopPropagation(),a(),i()}};s("All colors",null,()=>this.setColorFilter(null));for(let n of t){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(e,t){let i=this.collectFolderTags(),s=(n,o)=>{let a=e.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=A=>{A.preventDefault(),A.stopPropagation(),this.setTagFilter(o),t()}};s(i.length===0?"No tags":"All tags",null),s("Tagged",Yt),s("Untagged",zt);for(let n of i)s(`${n.label} (${n.count})`,n.raw)}setColorFilter(e){let t=e?e.toLowerCase():null;(this.colorFilter??null)!==t&&(this.colorFilter=t,this.reconcileSelectionAfterFilter(),this.persistFocus(),this.render())}setTimeFilter(e){this.timeFilter!==e&&(this.timeFilter=e,this.reconcileSelectionAfterFilter(),this.persistFocus(),this.render())}reconcileSelectionAfterFilter(){let e=this.filterChildren(this.collectViewItems(this.focusId)),t=new Set(e.map(i=>i.id));for(let i of[...this.selection])t.has(i)||this.selection.delete(i);if(this.firstSelectedId&&!t.has(this.firstSelectedId)&&(this.firstSelectedId=null),this.lastSelected&&!t.has(this.lastSelected)&&(this.lastSelected=null),this.selection.size>0){let i=e.findIndex(s=>this.selection.has(s.id));this.cursorIdx=i>=0?i:Math.min(this.cursorIdx,e.length-1)}else this.cursorIdx>=e.length&&(this.cursorIdx=e.length-1)}renderTinyHeader(e){let t=e.createDiv({cls:"stashpad-tiny-header"}),i=t.createEl("button",{cls:"stashpad-tiny-nav-btn"});De(i,"arrow-left","\u2039"),i.title="Back (up to parent)",this.navBackStack.length>0||this.focusId!==S||i.addClass("is-disabled"),i.title=this.navBackStack.length>0?"Back":this.focusId!==S?"Back (up to parent)":"No back history",i.onclick=()=>this.navigateBack();let n=t.createEl("button",{cls:"stashpad-tiny-nav-btn"});De(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(),l=this.focusId===S?a:`${a} / ${this.titleForNode(o).trim()}`,c=t.createEl("button",{cls:"stashpad-tiny-title stashpad-folder-btn"}),A=c.createSpan({cls:"stashpad-tiny-title-icon stashpad-btn-icon"});(0,k.setIcon)(A,"folder"),c.createSpan({cls:"stashpad-tiny-title-text stashpad-btn-text",text:l}),c.title=`${this.noteFolder}${this.focusId!==S?` / ${this.titleForNode(o).trim()}`:""} -Click to switch / create folder.`,c.onclick=g=>{g.preventDefault(),this.plugin.openFolderPicker()};let h=t.createDiv({cls:"stashpad-tiny-sticky"}),p=h.createEl("input",{type:"checkbox"});if(p.checked=this.tinyAlwaysOnTop,h.createSpan({text:"Sticky"}),p.onchange=()=>{this.tinyAlwaysOnTop=p.checked,this.applyTinyAlwaysOnTop()},!k.Platform.isMobile){let g=t.createEl("button",{cls:"stashpad-tiny-nav-btn stashpad-tiny-opacity-btn"});(0,k.setIcon)(g,"contrast"),g.title="Window transparency",this.tinyOpacity<1&&g.addClass("is-active"),g.onclick=I=>{I.stopPropagation(),this.toggleTinyOpacityPopover(g)}}let f=t.createEl("button",{cls:"stashpad-tiny-expand stashpad-tiny-exit-compact"});(0,k.setIcon)(f,this.compactMode?"panel-top":"rows-2"),f.title=this.compactMode?"Compact mode is ON \u2014 click to turn off.":"Compact mode \u2014 click to turn on (strips row metadata).",this.compactMode&&f.addClass("is-active"),f.onclick=()=>{this.toggleCompactMode()};let u=t.createEl("button",{cls:"stashpad-tiny-expand"});(0,k.setIcon)(u,"maximize-2"),u.title="Exit tiny mode",u.onclick=()=>{this.exitTinyMode()}}toggleTinyOpacityPopover(e){if(this.tinyOpacityPopover){this.tinyOpacityPopover.remove(),this.tinyOpacityPopover=null;return}let t=document.createElement("div");t.className="stashpad-tiny-opacity-popover",t.createSpan({cls:"stashpad-tiny-opacity-label",text:"Transparency"});let i=t.createEl("input",{type:"range"});i.min="30",i.max="100",i.step="1",i.value=String(Math.round(this.tinyOpacity*100));let s=t.createSpan({cls:"stashpad-tiny-opacity-pct",text:`${i.value}%`});i.addEventListener("input",()=>{let A=Math.min(100,Math.max(30,parseInt(i.value,10)||100));this.tinyOpacity=A/100,s.setText(`${A}%`),this.applyTinyOpacity(),e.toggleClass("is-active",this.tinyOpacity<1)}),i.addEventListener("change",()=>{this.app.workspace.requestSaveLayout()}),this.viewRoot.appendChild(t);let n=e.getBoundingClientRect(),o=this.viewRoot.getBoundingClientRect();t.setCssStyles({top:`${n.bottom-o.top+4}px`,left:`${Math.max(4,Math.min(n.left-o.left,o.width-180))}px`});let a=A=>{t.contains(A.target)||A.target===e||e.contains(A.target)||c()},l=A=>{A.key==="Escape"&&c()},c=()=>{t.remove(),this.tinyOpacityPopover=null,this.tinyOpacityClose=null,document.removeEventListener("mousedown",a,!0),document.removeEventListener("keydown",l,!0)};setTimeout(()=>{document.addEventListener("mousedown",a,!0),document.addEventListener("keydown",l,!0)},0),this.tinyOpacityPopover=t,this.tinyOpacityClose=c,i.focus()}getOwnElectronWindow(){try{let e=this.containerEl?.ownerDocument?.defaultView??window,s=((e?.require?.("electron")??window.require?.("electron"))?.remote??e?.electron?.remote??e?.["@electron/remote"])?.getCurrentWindow?.()??e?.electronWindow??null;if(!s)try{let n=window.require?.("electron"),o=n?.remote??n?.["@electron/remote"],l=(o?.BrowserWindow??n?.BrowserWindow)?.getAllWindows?.()??[];l.length===1?s=l[0]:l.length>1&&(s=o?.getFocusedWindow?.()??null??l[l.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(e){return console.debug("[Stashpad] resolve own electron window failed",e),null}}applyTinyAlwaysOnTop(){let e=this.getOwnElectronWindow();if(e)try{e.setAlwaysOnTop?.(!!this.tinyAlwaysOnTop)}catch(t){console.debug("[Stashpad] setAlwaysOnTop failed",t)}}applyTinyOpacity(){let e=this.getOwnElectronWindow();if(!e)return;let t=Math.min(1,Math.max(.3,this.tinyOpacity));try{e.setOpacity?.(t)}catch(i){console.debug("[Stashpad] setOpacity failed",i)}}applyTinyWindow(){let e=this.getOwnElectronWindow();if(e)try{if(this.tinyMode){e.setMinimumSize?.(220,260);let s=100,n=100;try{let o=e.getBounds?.();o&&typeof o.x=="number"&&(s=o.x,n=o.y)}catch{}try{e.setBounds?.({x:s,y:n,width:280,height:360})}catch{}try{e.setSize?.(280,360)}catch{}e.setAlwaysOnTop?.(!!this.tinyAlwaysOnTop);try{e.setOpacity?.(Math.min(1,Math.max(.3,this.tinyOpacity)))}catch{}}else e.setAlwaysOnTop?.(!1)}catch(t){console.debug("[Stashpad] tiny window apply failed",t)}}async exitTinyMode(){this.tinyMode=!1,this.tinyAlwaysOnTop=!1,this.tinyOpacity=1;try{this.getOwnElectronWindow()?.setOpacity?.(1)}catch{}this.compactMode=!1,this.applyTinyWindow();let e=this.getOwnElectronWindow();try{if(e?.setMinimumSize?.(400,300),k.Platform.isMacOS??!1){let i=this.containerEl?.ownerDocument?.defaultView?.require?.("electron")??window.require?.("electron"),n=(i?.remote?.screen??i?.screen)?.getPrimaryDisplay?.().workArea;n?e?.setBounds?.({x:n.x,y:n.y,width:n.width,height:n.height}):e?.maximize?.()}else e?.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(e){let t=e.createDiv({cls:"stashpad-breadcrumb"});k.Platform.isMobile||this.renderActionsCluster(t);let i=t.createSpan({cls:"stashpad-crumb stashpad-crumb-home"});if(k.Platform.isMobile?((0,k.setIcon)(i,"home"),i.title="Home"):i.setText("Home"),i.onclick=()=>this.navigateTo(S),this.focusId===S){let c=this.tree.getChildren(this.focusId).length;if(c>0&&(t.createSpan({cls:"stashpad-crumb-count",text:`\xB7 ${c}`}).title=`${c} direct child${c===1?"":"ren"}`),this.compactMode){let A=t.createEl("button",{cls:"stashpad-compact-exit-btn"});(0,k.setIcon)(A,"panel-top"),A.title="Exit compact mode",A.onclick=h=>{h.preventDefault(),this.toggleCompactMode()}}return}let s=28,n=this.tree.pathTo(this.focusId);this.warmCrumbTitles(n);let o=n.map(c=>{let A=this.titleForNode(c),h=A.length>s?A.slice(0,s-1)+"\u2026":A;return{id:c.id,label:h}}),a=k.Platform.isMobile?"/":" / ";for(let c of o)if(t.createSpan({cls:"stashpad-crumb-sep",text:a}),c.isEllipsis)t.createSpan({cls:"stashpad-crumb stashpad-crumb-ellipsis",text:c.label}).title=n.map(A=>this.titleForNode(A)).join(" / ");else{let A=c.id,h=t.createSpan({cls:"stashpad-crumb",text:c.label});h.title=c.label,h.onclick=()=>this.navigateTo(A),h.oncontextmenu=p=>{p.preventDefault(),this.openCrumbMenu(p,A)},k.Platform.isMobile&&this.attachLongPress(h,()=>this.openCrumbMenu(null,A))}if(t.querySelector(".stashpad-crumb-home")?.addEventListener("contextmenu",c=>{c.preventDefault(),this.openCrumbMenu(c,S)}),k.Platform.isMobile){let c=t.querySelector(".stashpad-crumb-home");c&&this.attachLongPress(c,()=>this.openCrumbMenu(null,S))}let l=this.tree.getChildren(this.focusId).length;if(l>0&&(t.createSpan({cls:"stashpad-crumb-count",text:`\xB7 ${l}`}).title=`${l} direct child${l===1?"":"ren"}`),this.compactMode){let c=t.createEl("button",{cls:"stashpad-compact-exit-btn"});(0,k.setIcon)(c,"panel-top"),c.title="Exit compact mode",c.onclick=A=>{A.preventDefault(),this.toggleCompactMode()}}k.Platform.isMobile||this.renderBreadcrumbLevelsButton(t)}renderBreadcrumbLevelsButton(e){let t=e.createEl("button",{cls:"stashpad-mobile-action-btn stashpad-crumb-levels-btn"});De(t,"route","\u22D4"),t.title="Show all levels \u2014 jump to any level in the path",t.onclick=i=>{i.preventDefault(),this.openBreadcrumbLevelsModal()}}openBreadcrumbLevelsModal(){let e=this.tree.pathTo(this.focusId),t=[{id:S,label:"Home",level:0,isCurrent:this.focusId===S,isHome:!0}];e.forEach((i,s)=>{t.push({id:i.id,label:this.titleForNode(i),level:s+1,isCurrent:i.id===this.focusId})}),new gs(this.app,t,i=>this.navigateTo(i),{onContext:(i,s,n,o)=>this.openCrumbMenu(s,i,n,o),attachLongPress:(i,s)=>this.attachLongPress(i,s)}).open()}attachLongPress(e,t){let i=null,s=0,n=0,o=()=>{i!=null&&(window.clearTimeout(i),i=null)};e.addEventListener("touchstart",a=>{let l=a.touches[0];s=l?.clientX??0,n=l?.clientY??0,o(),i=window.setTimeout(()=>{i=null,t()},500)},{passive:!0}),e.addEventListener("touchmove",a=>{let l=a.touches[0];l&&(Math.abs(l.clientX-s)>10||Math.abs(l.clientY-n)>10)&&o()},{passive:!0}),e.addEventListener("touchend",o),e.addEventListener("touchcancel",o)}openCrumbMenu(e,t,i,s){let n=this.tree.get(t);if(!n)return;let o=new k.Menu;if(o.addItem(a=>a.setTitle("Open in new Stashpad tab").setIcon("list-tree").onClick(()=>{s?.(),this.cmdOpenInNewStashpadTab(n)})),o.addItem(a=>a.setTitle("Navigate here").setIcon("arrow-right-circle").onClick(()=>{s?.(),this.navigateTo(t)})),n.file&&(o.addItem(a=>a.setTitle("Edit in Stashpad").setIcon("pencil-line").onClick(()=>{s?.(),this.cmdEdit(n)})),o.addItem(a=>a.setTitle("Open in Obsidian editor (new tab)").setIcon("pencil").onClick(()=>{s?.(),this.cmdOpenInEditor(n)}))),e&&(e.clientX>0||e.clientY>0))o.showAtMouseEvent(e);else{let l=(i??e?.target??null)?.getBoundingClientRect();o.showAtPosition({x:l?.left??8,y:(l?.bottom??60)+4})}}renderFocusedHeaderMini(e,t){if(!t.file)return;let i=e.createDiv({cls:"stashpad-focused-mini"});i.dataset.id=t.id,i.createDiv({cls:"stashpad-focused-mini-text"}).setText(this.titleForNode(t).trim());let n=i.createEl("button",{cls:"stashpad-pencil stashpad-note-more stashpad-focused-mini-more"});(0,k.setIcon)(n,"ellipsis-vertical"),n.title="Actions",n.onclick=o=>{o.stopPropagation(),this.openNoteMenu(o,t)}}installFocusedMiniObserver(e){let t=e.querySelector(".stashpad-focused"),i=e.querySelector(".stashpad-focused-mini");!t||!i||(this.focusedMiniObserver&&this.focusedMiniObserver.disconnect(),this.focusedMiniObserver=new IntersectionObserver(s=>{for(let n of s)i.toggleClass("is-visible",!n.isIntersecting)},{root:e,threshold:.05}),this.focusedMiniObserver.observe(t))}renderFocusedHeader(e,t){if(!t.file)return;let i=t.file,s=e.createDiv({cls:"stashpad-focused"});s.oncontextmenu=A=>{A.preventDefault(),this.openNoteMenu(A,t)};let 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(t.created)}),o.createDiv({cls:"stashpad-focused-grip-spacer"});let a=s.createDiv({cls:"stashpad-focused-body"});a.addEventListener("click",A=>this.handleRenderedClick(A,t));let l=s.createDiv({cls:"stashpad-focused-actions"}),c;if(k.Platform.isMobile){let A=l.createEl("button",{cls:"stashpad-pencil stashpad-note-more stashpad-focused-more"});(0,k.setIcon)(A,"ellipsis-vertical"),A.title="Actions",A.onclick=h=>{h.stopPropagation(),this.openNoteMenu(h,t)},c=A}else{let A=l.createEl("button",{cls:"stashpad-pencil stashpad-focused-pencil"});(0,k.setIcon)(A,"pencil"),A.title="Edit in Stashpad",A.onclick=()=>void this.cmdEdit(t);let h=l.createEl("button",{cls:"stashpad-pencil stashpad-focused-dup"});(0,k.setIcon)(h,"copy"),h.title="Open this Stashpad in a new tab (clone)",h.onclick=()=>this.cmdOpenInNewStashpadTab(t),c=A}this.renderNoteBody(a,t,{clamp:!0,immediate:!0,toggleHost:l,toggleAnchor:c})}renderRowBreadcrumb(e,t){let i=this.tree.pathTo(t.id),s=i.findIndex(a=>a.id===this.focusId),n=i.slice(s+1,i.length-1);if(n.length===0)return;let o=e.createDiv({cls:"stashpad-row-breadcrumb"});n.forEach((a,l)=>{let c=o.createSpan({cls:"stashpad-row-breadcrumb-seg",text:this.titleForNode(a)});c.title=`Focus into "${this.titleForNode(a)}"`,c.onclick=A=>{A.stopPropagation(),this.navigateTo(a.id)},l<n.length-1&&o.createSpan({cls:"stashpad-row-breadcrumb-sep",text:" / "})})}actionsForFile(e){return ts(this.app,e,k.Platform.isMobile)}bulkActionMessage(e){let t=e.nodes.map(a=>`"${this.titleForNode(a).trim()||"(untitled)"}"`),i=e.suffix?` ${e.suffix}`:"",s=e.destination?` ${e.destination}`:"";if(t.length===0)return`${e.verb}${i}${s}`;if(t.length===1)return`${e.verb} ${t[0]}${i}${s}`;let n=e.bulletMax??10,o=t.length<=n?t.map(a=>`\u2022 ${a}`).join(` +Click to override for this tab.`,d&&c.addClass("is-override"),c.onclick=f=>{f.preventDefault(),this.openFolderPicker()};let p=t.createEl("button",{cls:"stashpad-search-btn"});De(p,"search","\u{1F50D}"),p.title="Search notes (Mod+F)",p.onclick=f=>{f.preventDefault(),this.openSearchModal()}}F.Platform.isMobile?(this.renderActionsCluster(t),this.renderMobileFiltersButton(t)):(this.renderTagFilterDropdown(t),this.renderColorFilterDropdown(t),this.renderSortDropdown(t),this.renderViewDropdown(t));let i=t.createDiv({cls:"stashpad-time-filter-btns"}),s=i.createEl("button",{cls:"stashpad-time-filter-btn stashpad-time-filter-cal"});(0,F.setIcon)(s,this.timeFilterCalendar?"calendar":"history"),s.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&&s.addClass("is-active"),s.onclick=c=>{c.preventDefault(),this.timeFilterCalendar=!this.timeFilterCalendar,this.persistFocus(),this.render()};for(let c of Ts){let d=this.timeFilterCalendar?c.calShort:c.rollShort,h=this.timeFilterCalendar?c.calLong:c.rollLong,p=i.createEl("button",{cls:"stashpad-time-filter-btn",text:d});p.title=h,this.timeFilter===c.key&&p.addClass("is-active"),p.onclick=f=>{f.preventDefault(),this.setTimeFilter(c.key)}}let n=t.createEl("select",{cls:"stashpad-time-filter-select"});for(let c of Ts){let d=this.timeFilterCalendar?c.calLong:c.rollLong,h=n.createEl("option",{text:d});h.value=c.key,this.timeFilter===c.key&&(h.selected=!0)}n.onchange=()=>this.setTimeFilter(n.value);let o=t.createDiv({cls:"stashpad-view-mode-btns"});if(!F.Platform.isMobile){let c=o.createEl("button",{cls:"stashpad-view-mode-btn"});(0,F.setIcon)(c,"minimize-2"),c.title="Tiny mode \u2014 open this tab in a small always-on-top-capable popout window.",c.onclick=d=>{d.preventDefault(),this.plugin.openTinyWindow()}}let a=o.createEl("button",{cls:"stashpad-view-mode-btn"});if((0,F.setIcon)(a,this.compactMode?"panel-top":"rows-2"),a.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&&a.addClass("is-active"),a.onclick=c=>{c.preventDefault(),this.toggleCompactMode()},F.Platform.isMobile)return;let l=o.createEl("button",{cls:"stashpad-view-mode-btn"});(0,F.setIcon)(l,"external-link"),l.title=X().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.)",l.onclick=c=>{c.preventDefault();let d=X().popoutDuplicates;try{let h=this.app.workspace;if(d){let p=this.leaf.getViewState(),f=h.openPopoutLeaf?.();f?f.setViewState({...p,active:!0}):new F.Notice("Stashpad: this Obsidian build doesn't expose openPopoutLeaf.")}else h.moveLeafToPopout?.(this.leaf)}catch(h){new F.Notice(`Stashpad: open-in-new-window failed (${h.message})`)}},this.setupBarOverflow(t)}setupBarOverflow(e){let t=[{key:"nav",icon:"folder-search",title:"Folder & search",memberSel:[".stashpad-folder-btn",".stashpad-search-btn"],memberKeys:["folder","search"],collapsePrio:5,displayIdx:0},{key:"filter",icon:"filter",title:"Tag & color",memberSel:[".stashpad-tag-filter-btn",".stashpad-color-filter-btn"],memberKeys:["tag","color"],collapsePrio:3,displayIdx:1},{key:"arrange",icon:"sliders-horizontal",title:"Sort & view",memberSel:[".stashpad-sort-btn",".stashpad-view-btn"],memberKeys:["sort","view"],collapsePrio:4,displayIdx:2},{key:"time",icon:"clock",title:"Time",memberSel:[".stashpad-time-filter-btns",".stashpad-time-filter-select"],memberKeys:["time"],collapsePrio:2,displayIdx:3},{key:"window",icon:"app-window",title:"Window & layout",memberSel:[".stashpad-view-mode-btns"],memberKeys:["mode"],collapsePrio:1,displayIdx:4}];e.addClass("stashpad-overflow-managed");let i=[];for(let f of[...t].sort((u,g)=>u.displayIdx-g.displayIdx)){let u=f.memberSel.map(B=>e.querySelector(B)).filter(B=>!!B);if(u.length===0)continue;let g=createDiv({cls:"stashpad-bar-group"});e.insertBefore(g,u[0]);let I=g.createDiv({cls:"stashpad-bar-group-expanded"});for(let B of u)I.appendChild(B);let m=g.createDiv({cls:"stashpad-bar-overflow-btn stashpad-bar-group-icon stashpad-overflow-hidden"});m.setAttribute("role","button"),m.setAttribute("tabindex","0"),(0,F.setIcon)(m.createSpan({cls:"stashpad-bar-group-icon-glyph"}),f.icon),m.title=`${f.title} \u2014 combined menu`;let C=B=>{B.preventDefault(),this.openBarOverflowMenu(m,f.memberKeys)};m.onclick=C,m.onkeydown=B=>{(B.key==="Enter"||B.key===" ")&&C(B)},i.push({...f,wrapper:g,expanded:I,iconBtn:m})}let s=e.createDiv({cls:"stashpad-bar-overflow-btn stashpad-bar-kebab stashpad-overflow-hidden"});s.setAttribute("role","button"),s.setAttribute("tabindex","0"),(0,F.setIcon)(s.createSpan({cls:"stashpad-bar-overflow-icon"}),"more-horizontal"),s.title="More filters / view options";let n=[...i].sort((f,u)=>f.collapsePrio-u.collapsePrio),o=[...i].sort((f,u)=>u.displayIdx-f.displayIdx),a=[],l=()=>e.scrollWidth<=e.clientWidth+1,c=()=>{if(!e.isConnected||e.clientWidth===0)return;for(let u of i)u.wrapper.removeClass("stashpad-overflow-hidden"),u.expanded.removeClass("stashpad-overflow-hidden"),u.iconBtn.addClass("stashpad-overflow-hidden"),u.iconBtn.toggleClass("is-active",u.memberKeys.some(g=>this.barUnitActive(g)));if(s.addClass("stashpad-overflow-hidden"),a=[],l())return;for(let u of n){if(l())break;u.expanded.addClass("stashpad-overflow-hidden"),u.iconBtn.removeClass("stashpad-overflow-hidden")}if(l())return;s.removeClass("stashpad-overflow-hidden");let f=[];for(let u of o){if(l())break;u.wrapper.addClass("stashpad-overflow-hidden"),f.push(u)}a=[...f].sort((u,g)=>u.displayIdx-g.displayIdx).flatMap(u=>u.memberKeys),s.toggleClass("is-active",a.some(u=>this.barUnitActive(u)))},d=f=>{f.preventDefault(),this.openBarOverflowMenu(s,a)};s.onclick=d,s.onkeydown=f=>{(f.key==="Enter"||f.key===" ")&&d(f)};try{this.barOverflowRO?.disconnect()}catch{}let h=(e.ownerDocument?.defaultView??window).ResizeObserver,p=-1;this.barOverflowRO=new h(f=>{let u=Math.round(f[f.length-1].contentRect.width);u!==p&&(p=u,c())}),this.barOverflowRO.observe(e),requestAnimationFrame(()=>c())}barUnitActive(e){switch(e){case"folder":return!!this.folderOverride;case"tag":return!!this.tagFilter;case"color":return!!this.colorFilter;case"time":return this.timeFilter!=="all";case"sort":return this.currentViewMode()==="nested"&&this.sortStore.getMode(this.noteFolder,this.focusId)!=="manual";case"view":return this.currentViewMode()!=="nested"||this.currentEncryptionFilter()!=="all"||this.currentHideChildless()||this.currentHideCompleted()||this.currentAttachmentsOnly()||this.currentIncludeAttachments();case"mode":return this.compactMode;default:return!1}}openBarOverflowMenu(e,t){let i=e.ownerDocument??document;i.querySelectorAll(".stashpad-mobile-filters-popover").forEach(u=>u.remove());let s=i.body.createDiv({cls:"stashpad-mobile-filters-popover"}),n=e.getBoundingClientRect(),o=i.defaultView??window;s.setCssStyles({right:`${Math.max(8,o.innerWidth-n.right)}px`,left:"auto",top:`${n.bottom+4}px`,maxWidth:"min(360px, calc(100vw - 16px))",width:"max-content",minWidth:"260px"});let a=new F.Scope(this.app.scope),l=()=>{s.remove(),i.removeEventListener("mousedown",c,!0);try{this.app.keymap?.popScope(a)}catch{}},c=u=>{!s.contains(u.target)&&u.target!==e&&!e.contains(u.target)&&l()},h=[{key:"folder",title:"Folder",summary:()=>this.noteFolder.split("/").pop()||this.noteFolder||"Stashpad",populate:u=>this.populateFolderMenuBody(u,l)},{key:"search",title:"Search",summary:()=>"Search notes (Mod+F)",populate:u=>this.populateSearchMenuBody(u,l)},{key:"tag",title:"Tag filter",summary:()=>this.tagFilter?`#${this.tagFilter}`:"All tags",populate:u=>this.populateTagMenuBody(u,l)},{key:"color",title:"Color filter",summary:()=>this.colorFilter?this.plugin.getColorAlias(this.noteFolder,this.colorFilter)??this.colorFilter:"All colors",populate:u=>this.populateColorMenuBody(u,this.collectFolderColors(),l)},{key:"sort",title:"Sort",summary:()=>this.currentViewMode()!=="nested"?"\u2014 (Nested only)":Ti[this.sortStore.getMode(this.noteFolder,this.focusId)],populate:u=>{if(this.currentViewMode()!=="nested"){u.createDiv({cls:"stashpad-mobile-filters-note",text:"Sort applies only in Nested view."});return}this.populateSortMenuBody(u,l)}},{key:"view",title:"View",summary:()=>Ns[this.currentViewMode()],populate:u=>this.populateViewMenuBody(u,l)},{key:"time",title:"Time filter",summary:()=>{let u=Ts.find(g=>g.key===this.timeFilter);return u?this.timeFilterCalendar?u.calShort:u.rollShort:"All"},populate:u=>this.populateTimeMenuBody(u,l)},{key:"mode",title:"View mode",summary:()=>this.compactMode?"Compact on":"Tiny \xB7 Compact \xB7 Window",populate:u=>this.populateModeMenuBody(u,l)}].filter(u=>t.includes(u.key)),p="",f=()=>{s.empty();for(let u of h){let g=s.createDiv({cls:"stashpad-mobile-filters-section"}),I=g.createDiv({cls:"stashpad-mobile-filters-header"}),m=I.createSpan({cls:"stashpad-mobile-filters-chev"});(0,F.setIcon)(m,p===u.key?"chevron-down":"chevron-right"),I.createSpan({cls:"stashpad-mobile-filters-title",text:u.title}),I.createSpan({cls:"stashpad-mobile-filters-summary",text:u.summary()}),I.onclick=C=>{C.preventDefault(),C.stopPropagation(),p=p===u.key?"":u.key,f()},p===u.key&&u.populate(g.createDiv({cls:"stashpad-mobile-filters-body"}))}};f(),a.register([],"Escape",u=>(u.preventDefault(),l(),!1)),this.app.keymap?.pushScope(a),setTimeout(()=>{i.addEventListener("mousedown",c,!0)},0)}populateFolderMenuBody(e,t){let i=e.createDiv({cls:"stashpad-sort-popover-row"});i.createSpan({cls:"stashpad-sort-popover-label",text:this.folderOverride?"Change folder (override active)\u2026":"Change folder for this tab\u2026"}),i.onclick=s=>{s.preventDefault(),s.stopPropagation(),t(),this.openFolderPicker()}}populateSearchMenuBody(e,t){let i=e.createDiv({cls:"stashpad-sort-popover-row"});i.createSpan({cls:"stashpad-sort-popover-label",text:"Search notes\u2026"}),i.onclick=s=>{s.preventDefault(),s.stopPropagation(),t(),this.openSearchModal()}}populateModeMenuBody(e,t){let i=(n,o)=>{let a=e.createDiv({cls:"stashpad-sort-popover-row"});a.createSpan({cls:"stashpad-sort-popover-label",text:n}),a.onclick=l=>{l.preventDefault(),l.stopPropagation(),t(),o()}};i("Tiny mode (popout window)",()=>void this.plugin.openTinyWindow());let s=e.createDiv({cls:"stashpad-sort-popover-row"});this.compactMode&&s.addClass("is-active"),s.createSpan({cls:"stashpad-sort-popover-label",text:this.compactMode?"Compact mode (on)":"Compact mode"}),s.onclick=n=>{n.preventDefault(),n.stopPropagation(),t(),this.toggleCompactMode()},i(X().popoutDuplicates?"Duplicate to new window":"Move to new window",()=>{try{let n=this.app.workspace;if(X().popoutDuplicates){let o=n.openPopoutLeaf?.();o?o.setViewState({...this.leaf.getViewState(),active:!0}):new F.Notice("Stashpad: this Obsidian build doesn't expose openPopoutLeaf.")}else n.moveLeafToPopout?.(this.leaf)}catch(n){new F.Notice(`Stashpad: open-in-new-window failed (${n.message})`)}})}toggleCompactMode(){this.compactMode=!this.compactMode,this.render();try{this.app.workspace.requestSaveLayout?.()}catch{}}renderActionsCluster(e){let t=e.createDiv({cls:"stashpad-mobile-actions"}),i=t.createEl("button",{cls:"stashpad-mobile-action-btn"});De(i,"arrow-left","\u2039");let s=this.navBackStack.length>0||this.focusId!==S;i.title=this.navBackStack.length>0?"Back":this.focusId!==S?"Back (up to parent)":"No back history",s||i.addClass("is-disabled"),i.onclick=h=>{h.preventDefault(),this.navigateBack()};let n=t.createEl("button",{cls:"stashpad-mobile-action-btn"});De(n,"arrow-right","\u203A");let o=this.navForwardSnapshots.length>0;if(n.title=o?"Forward":"No forward history",o||n.addClass("is-disabled"),n.onclick=h=>{h.preventDefault(),this.navigateForward()},F.Platform.isMobile){let h=t.createEl("button",{cls:"stashpad-mobile-action-btn"});De(h,"route","\u22D4"),h.title="Jump to a level in the path",h.onclick=p=>{p.preventDefault(),this.openBreadcrumbLevelsModal()}}let a=t.createEl("button",{cls:"stashpad-mobile-action-btn"}),l=this.mobileSelectMode;De(a,l?"check-square":"square",l?"\u2611":"\u2610"),a.title=l?`${this.selection.size} selected \u2014 tap to exit (keeps the first selection)`:"Enter select mode (tap notes to add)",l&&a.addClass("is-active"),a.onclick=h=>{if(h.preventDefault(),this.mobileSelectMode){let p=this.firstSelectedId??this.selection.values().next().value;if(this.selection.clear(),p){let f=this.currentChildren.findIndex(u=>u.id===p);this.selection.add(p),this.lastSelected=p,f>=0&&(this.cursorIdx=f)}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 F.Notice("Select mode: tap notes to add, press \u26A1 for actions")}};let c=t.createEl("button",{cls:"stashpad-mobile-action-btn"});De(c,"zap","\u26A1"),c.title="Actions (move, delete, undo, \u2026)",c.onclick=h=>{h.preventDefault(),this.openMobileActionsMenu(c)};let d=t.createEl("button",{cls:"stashpad-mobile-action-btn stashpad-open-link-btn"});De(d,"link","\u{1F517}"),d.title="Open a Stashpad link (paste a deep link / URL)",d.onclick=h=>{h.preventDefault(),this.plugin.openDeepLinkModal()}}openMobileActionsMenu(e){let t=new F.Menu,i=this.selection.size>0||this.cursorIdx>=0&&!!this.currentChildren[this.cursorIdx],s=this.selection.size<=1;t.addItem(o=>o.setTitle("Undo").setIcon("undo").onClick(()=>this.cmdUndo())),t.addItem(o=>o.setTitle("Redo").setIcon("redo").onClick(()=>this.cmdRedo())),t.addSeparator(),t.addItem(o=>o.setTitle("Notification history\u2026").setIcon("bell").onClick(()=>{this.app.commands?.executeCommandById?.("stashpad:stashpad-open-notification-history")})),t.addItem(o=>o.setTitle("Reload without saving").setIcon("rotate-ccw").onClick(()=>this.plugin.reloadAppForUpdate())),t.addItem(o=>o.setTitle("Open Stashpad link\u2026").setIcon("link").onClick(()=>this.plugin.openDeepLinkModal())),t.addSeparator(),t.addItem(o=>o.setTitle("Expand all").setIcon("unfold-vertical").onClick(()=>this.cmdExpandAll())),t.addItem(o=>o.setTitle("Collapse all").setIcon("fold-vertical").onClick(()=>this.cmdCollapseAll())),t.addSeparator(),t.addItem(o=>o.setTitle("Open in new Stashpad tab").setIcon("list-tree").setDisabled(!i).onClick(()=>this.cmdOpenInNewStashpadTab())),t.addItem(o=>o.setTitle("Edit in Stashpad").setIcon("pencil-line").setDisabled(!i).onClick(()=>void this.cmdEdit())),t.addItem(o=>o.setTitle("Open in Obsidian editor").setIcon("pencil").setDisabled(!i).onClick(()=>this.cmdOpenInEditor())),t.addSeparator(),t.addItem(o=>o.setTitle("Move\u2026").setIcon("arrow-right-circle").setDisabled(!i).onClick(()=>this.cmdMovePicker())),t.addItem(o=>o.setTitle("Nest under\u2026 (in-list)").setIcon("indent").setDisabled(!i).onClick(()=>this.cmdInListPicker())),t.addItem(o=>o.setTitle("Outdent").setIcon("outdent").setDisabled(!i).onClick(()=>void this.cmdOutdent())),t.addItem(o=>o.setTitle("Set color\u2026").setIcon("palette").setDisabled(!i).onClick(()=>this.cmdSetColor())),t.addItem(o=>o.setTitle("Toggle complete").setIcon("check-circle").setDisabled(!i).onClick(()=>void this.cmdToggleComplete())),t.addItem(o=>o.setTitle("Toggle task (todo)").setIcon("check-square").setDisabled(!i).onClick(()=>void this.cmdToggleTask())),t.addItem(o=>o.setTitle("Set due date\u2026").setIcon("calendar-clock").setDisabled(!i).onClick(()=>this.cmdSetDue())),t.addItem(o=>o.setTitle("Assign to\u2026").setIcon("user-plus").setDisabled(!i).onClick(()=>this.cmdAssign())),t.addSeparator(),t.addItem(o=>o.setTitle("Copy").setIcon("copy").setDisabled(!i).onClick(()=>void this.cmdCopy())),t.addItem(o=>o.setTitle("Copy tree").setIcon("copy-plus").setDisabled(!i).onClick(()=>void this.cmdCopyTree())),t.addItem(o=>o.setTitle("Clone (duplicate / copy)").setIcon("files").setDisabled(!i).onClick(()=>void this.cmdClone())),this.addShareExportSubmenu(t,this.getActionTargets()[0]??null,{normalizeToNode:!1}),this.plugin.settings.enableSheetVersions&&(t.addItem(o=>o.setTitle("Fork as a version (draft)").setIcon("git-fork").setDisabled(!i||!s).onClick(()=>void this.cmdForkVersion())),t.addItem(o=>o.setTitle("Mark version as final").setIcon("star").setDisabled(!i||!s).onClick(()=>void this.cmdMarkVersionFinal()))),t.addItem(o=>o.setTitle("Insert template\u2026").setIcon("file-plus-2").onClick(()=>this.cmdInsertTemplate())),t.addItem(o=>o.setTitle("Merge").setIcon("merge").setDisabled(this.selection.size<2).onClick(()=>void this.cmdMerge())),t.addItem(o=>o.setTitle("Split note\u2026").setIcon("scissors").setDisabled(!i||!s).onClick(()=>void this.cmdSplit())),t.addSeparator(),t.addItem(o=>o.setTitle("Delete").setIcon("trash-2").setDisabled(!i).onClick(()=>void this.cmdDelete())),t.addSeparator(),t.addItem(o=>o.setTitle("More commands\u2026").setIcon("terminal").onClick(()=>this.openCommandPalette()));let n=e.getBoundingClientRect();t.showAtPosition({x:n.left,y:n.bottom+4})}openCommandPalette(){this.app.commands?.executeCommandById?.("command-palette:open")}openStashpadCommandPalette(){new Mn(this.app).open()}tagFilterLabel(){return this.tagFilter===Yt?"Tagged":this.tagFilter===zt?"Untagged":this.tagFilter?`#${this.formatTagLabel(this.tagFilter)}`:this.collectFolderTags().length===0?"No tags":"All tags"}renderTagFilterDropdown(e){let t=this.collectFolderTags(),i=e.createDiv({cls:"stashpad-tag-filter-btn"});i.setAttribute("role","button"),i.setAttribute("tabindex","0");let s=i.createSpan({cls:"stashpad-tag-filter-btn-icon"});De(s,"tag","#"),i.createSpan({cls:"stashpad-tag-filter-label",text:this.tagFilterLabel()}),t.length===0&&!this.tagFilter&&i.addClass("is-disabled");let n=o=>{o.preventDefault(),!(t.length===0&&!this.tagFilter)&&this.openTagFilterMenu(i)};i.onclick=n,i.onkeydown=o=>{(o.key==="Enter"||o.key===" ")&&n(o)}}openTagFilterMenu(e){let t=e.ownerDocument??document;t.querySelectorAll(".stashpad-tag-filter-popover").forEach(E=>E.remove());let i=t.body.createDiv({cls:"stashpad-tag-filter-popover"}),s=e.getBoundingClientRect();i.setCssStyles({left:`${Math.max(8,s.left)}px`,top:`${s.bottom+4}px`,minWidth:`${Math.max(s.width,200)}px`,maxWidth:"min(320px, calc(100vw - 16px))",width:"max-content"});let n=new F.Scope(this.app.scope),o=()=>{i.remove(),t.removeEventListener("mousedown",a,!0);try{this.app.keymap?.popScope(n)}catch{}},a=E=>{!i.contains(E.target)&&E.target!==e&&!e.contains(E.target)&&o()},l=i.createDiv({cls:"stashpad-tag-filter-search"}),c=l.createSpan({cls:"stashpad-tag-filter-search-icon"});De(c,"search","\u2315");let d=l.createEl("input",{type:"text",cls:"stashpad-tag-filter-input",attr:{placeholder:"Filter tags\u2026"}}),h=l.createSpan({cls:"stashpad-tag-filter-clear",attr:{"aria-label":"Clear"}});De(h,"x","\xD7"),h.setCssStyles({display:"none"});let p=i.createDiv({cls:"stashpad-tag-filter-list"}),f=this.collectFolderTags(),u=[],g=0,I=E=>{this.setTagFilter(E),o()},m=E=>{if(u.length===0){g=0;return}g=(E+u.length)%u.length,u.forEach((y,v)=>y.el.toggleClass("is-highlighted",v===g)),u[g].el.scrollIntoView({block:"nearest"})},C=(E,y,v,Q)=>{let w=p.createDiv({cls:"stashpad-tag-filter-row"});Q&&w.addClass("is-active"),w.createSpan({cls:"stashpad-tag-filter-row-label",text:E}),typeof v=="number"&&w.createSpan({cls:"stashpad-tag-filter-row-count",text:String(v)});let k=u.length;u.push({value:y,el:w}),w.onmousedown=D=>{D.preventDefault(),I(y)},w.onmouseenter=()=>m(k)},B=()=>{let E=d.value;h.setCssStyles({display:E?"":"none"}),p.empty(),u=[];let y=this.tagFilter?.toLowerCase();if(E.trim()){let v=or(E,f);if(v.length===0)p.createDiv({cls:"stashpad-tag-filter-empty",text:"No matching tags"});else for(let Q of v)C(`#${Q.label}`,Q.raw,Q.count,y===Q.raw.toLowerCase())}else{C("All tags",null,void 0,!this.tagFilter),C("Tagged",Yt,void 0,this.tagFilter===Yt),C("Untagged",zt,void 0,this.tagFilter===zt);for(let v of f)C(`#${v.label}`,v.raw,v.count,y===v.raw.toLowerCase())}m(0)};h.onclick=()=>{d.value="",B(),d.focus()},d.addEventListener("input",B),d.addEventListener("keydown",E=>{E.key==="ArrowDown"?(E.preventDefault(),m(g+1)):E.key==="ArrowUp"?(E.preventDefault(),m(g-1)):E.key==="Enter"&&(E.preventDefault(),u[g]&&I(u[g].value))}),n.register([],"Escape",E=>(E.preventDefault(),o(),!1)),this.app.keymap?.pushScope(n),B(),setTimeout(()=>{t.addEventListener("mousedown",a,!0),d.focus()},0)}renderColorFilterDropdown(e){let t=this.collectFolderColors(),i=e.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 l=this.colorFilter.toLowerCase();o.setCssStyles({background:l});let c=this.plugin.getColorAlias(this.noteFolder,l);a.setText(c??l)}else t.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(),!(t.length===0&&!this.colorFilter)&&this.openColorFilterMenu(i,t)};i.onclick=n,i.onkeydown=o=>{(o.key==="Enter"||o.key===" ")&&n(o)}}openColorFilterMenu(e,t){let i=e.ownerDocument??document;i.querySelectorAll(".stashpad-color-filter-popover").forEach(c=>c.remove());let s=i.body.createDiv({cls:"stashpad-color-filter-popover"}),n=e.getBoundingClientRect();s.setCssStyles({left:`${Math.max(8,n.left)}px`,top:`${n.bottom+4}px`,minWidth:`${n.width}px`,maxWidth:"min(280px, calc(100vw - 16px))",width:"max-content"});let o=new F.Scope(this.app.scope),a=()=>{s.remove(),i.removeEventListener("mousedown",l,!0);try{this.app.keymap?.popScope(o)}catch{}},l=c=>{!s.contains(c.target)&&c.target!==e&&!e.contains(c.target)&&a()};o.register([],"Escape",c=>(c.preventDefault(),a(),!1)),this.app.keymap?.pushScope(o),this.populateColorMenuBody(s,t,a),setTimeout(()=>{i.addEventListener("mousedown",l,!0)},0)}renderSortDropdown(e){let t=this.noteFolder,i=this.focusId,s=this.sortStore.getMode(t,i),n=this.currentViewMode(),o=n!=="nested",a=e.createDiv({cls:"stashpad-sort-btn"});a.setAttribute("role","button"),a.setAttribute("tabindex",o?"-1":"0"),o&&a.addClass("is-disabled");let l=a.createSpan({cls:"stashpad-sort-icon"});(0,F.setIcon)(l,"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 (${Ns[n]}) shows a synthesized flat list sorted by created time \u2014 switch back to Nested to change sort.`):(c.setText(Ti[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: ${Ti[s]}. Drag-reorder will revert this parent to Manual.`);let d=h=>{o||(h.preventDefault(),this.openSortMenu(a))};a.onclick=d,a.onkeydown=h=>{o||(h.key==="Enter"||h.key===" ")&&d(h)}}openSortMenu(e){let t=e.ownerDocument??document;t.querySelectorAll(".stashpad-sort-popover").forEach(l=>l.remove());let i=t.body.createDiv({cls:"stashpad-sort-popover"}),s=e.getBoundingClientRect();i.setCssStyles({left:`${Math.max(8,s.left)}px`,top:`${s.bottom+4}px`,minWidth:`${s.width}px`,maxWidth:"min(280px, calc(100vw - 16px))",width:"max-content"});let n=()=>{i.remove(),t.removeEventListener("mousedown",o,!0);try{this.app.keymap?.popScope(a)}catch{}},o=l=>{!i.contains(l.target)&&l.target!==e&&!e.contains(l.target)&&n()};this.populateSortMenuBody(i,n);let a=new F.Scope(this.app.scope);a.register([],"Escape",l=>(l.preventDefault(),n(),!1)),this.app.keymap?.pushScope(a),setTimeout(()=>{t.addEventListener("mousedown",o,!0)},0)}renderMobileFiltersButton(e){let t=e.createDiv({cls:"stashpad-mobile-filters-btn"});t.setAttribute("role","button"),t.setAttribute("tabindex","0");let i=t.createSpan({cls:"stashpad-mobile-filters-icon"});(0,F.setIcon)(i,"sliders-horizontal"),t.title="Filters / view options";let s=!!this.tagFilter,n=!!this.colorFilter,o=this.timeFilter!=="all",a=this.sortStore.getMode(this.noteFolder,this.focusId)!=="manual",l=this.currentViewMode()!=="nested"||this.currentHideChildless()||this.currentHideCompleted()||this.currentAttachmentsOnly()||this.currentIncludeAttachments();(s||n||o||a||l)&&t.addClass("is-active");let c=d=>{d.preventDefault(),this.openMobileFiltersMenu(t)};t.onclick=c,t.onkeydown=d=>{(d.key==="Enter"||d.key===" ")&&c(d)}}openMobileFiltersMenu(e){let t=e.ownerDocument??document;t.querySelectorAll(".stashpad-mobile-filters-popover").forEach(f=>f.remove());let i=t.body.createDiv({cls:"stashpad-mobile-filters-popover"}),s=e.getBoundingClientRect(),n=t.defaultView??window,o=s.bottom+280>n.innerHeight;i.setCssStyles({right:`${Math.max(8,n.innerWidth-s.right)}px`,left:"auto",...o?{bottom:`${Math.max(8,n.innerHeight-s.top+4)}px`,top:"auto"}:{top:`${s.bottom+4}px`,bottom:"auto"},maxWidth:"min(360px, calc(100vw - 16px))",maxHeight:"min(60vh, 420px)",overflowY:"auto",width:"max-content",minWidth:"260px"});let a=()=>{i.remove(),t.removeEventListener("mousedown",l,!0);try{this.app.keymap?.popScope(p)}catch{}},l=f=>{!i.contains(f.target)&&f.target!==e&&!e.contains(f.target)&&a()},c=[{key:"tag",title:"Tag filter",summary:()=>this.tagFilter?`#${this.tagFilter}`:"All tags",populate:f=>this.populateTagMenuBody(f,a)},{key:"color",title:"Color filter",summary:()=>this.colorFilter?this.plugin.getColorAlias(this.noteFolder,this.colorFilter)??this.colorFilter:"All colors",populate:f=>this.populateColorMenuBody(f,this.collectFolderColors(),a)},{key:"time",title:"Time filter",summary:()=>{let f=Ts.find(u=>u.key===this.timeFilter);return f?this.timeFilterCalendar?f.calShort:f.rollShort:"All"},populate:f=>this.populateTimeMenuBody(f,a)},{key:"sort",title:"Sort",summary:()=>this.currentViewMode()!=="nested"?"\u2014 (Nested only)":Ti[this.sortStore.getMode(this.noteFolder,this.focusId)],populate:f=>{if(this.currentViewMode()!=="nested"){f.createDiv({cls:"stashpad-mobile-filters-note",text:"Sort applies only in Nested view."});return}this.populateSortMenuBody(f,a)}},{key:"view",title:"View",summary:()=>Ns[this.currentViewMode()],populate:f=>this.populateViewMenuBody(f,a)}],d="",h=()=>{i.empty();for(let f of c){let u=i.createDiv({cls:"stashpad-mobile-filters-section"}),g=u.createDiv({cls:"stashpad-mobile-filters-header"}),I=g.createSpan({cls:"stashpad-mobile-filters-chev"});if((0,F.setIcon)(I,d===f.key?"chevron-down":"chevron-right"),g.createSpan({cls:"stashpad-mobile-filters-title",text:f.title}),g.createSpan({cls:"stashpad-mobile-filters-summary",text:f.summary()}),g.onclick=m=>{m.preventDefault(),m.stopPropagation(),d=d===f.key?"":f.key,h()},d===f.key){let m=u.createDiv({cls:"stashpad-mobile-filters-body"});f.populate(m)}}};h();let p=new F.Scope(this.app.scope);p.register([],"Escape",f=>(f.preventDefault(),a(),!1)),this.app.keymap?.pushScope(p),setTimeout(()=>{t.addEventListener("mousedown",l,!0)},0)}renderViewDropdown(e){let t=this.currentViewMode(),i=e.createDiv({cls:"stashpad-view-btn"});i.setAttribute("role","button"),i.setAttribute("tabindex","0");let s=i.createSpan({cls:"stashpad-view-icon"});(0,F.setIcon)(s,t==="flat"?"list":t==="everything"?"layout-grid":"list-tree"),i.createSpan({cls:"stashpad-view-label"}).setText(Ns[t]),(t!=="nested"||this.currentEncryptionFilter()!=="all")&&i.addClass("is-active"),i.title=t==="nested"?"View: Nested (the default). Click to switch to Flat or Everything.":t==="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(e){let t=e.ownerDocument??document;t.querySelectorAll(".stashpad-view-popover").forEach(l=>l.remove());let i=t.body.createDiv({cls:"stashpad-view-popover"});F.Platform.isMobile&&i.addClass("is-mobile");let s=e.getBoundingClientRect();i.setCssStyles({left:`${Math.max(8,s.left)}px`,top:`${s.bottom+4}px`,minWidth:`${s.width}px`,maxWidth:"min(320px, calc(100vw - 16px))",width:"max-content"});let n=()=>{i.remove(),t.removeEventListener("mousedown",o,!0);try{this.app.keymap?.popScope(a)}catch{}},o=l=>{!i.contains(l.target)&&l.target!==e&&!e.contains(l.target)&&n()};this.populateViewMenuBody(i,n);let a=new F.Scope(this.app.scope);a.register([],"Escape",l=>(l.preventDefault(),n(),!1)),this.app.keymap?.pushScope(a),setTimeout(()=>{t.addEventListener("mousedown",o,!0)},0)}populateViewMenuBody(e,t){let i=this.currentViewMode(),s=(y,v,Q)=>{let w=e.createDiv({cls:"stashpad-view-popover-row"});y===i&&w.addClass("is-active");let k=w.createDiv({cls:"stashpad-view-popover-main"});(0,F.setIcon)(k.createSpan({cls:"stashpad-view-popover-icon"}),Q),k.createSpan({cls:"stashpad-view-popover-label",text:Ns[y]}),w.createDiv({cls:"stashpad-view-popover-desc",text:v}),w.onclick=async D=>{D.preventDefault(),D.stopPropagation(),t(),y!==i&&(await this.setViewMode(y),this.render())}};if(s("nested","Tree of immediate children (default).","list-tree"),e.createDiv({cls:"stashpad-view-popover-divider"}),s("flat","All descendants of the current focus, flat by sort.","list"),e.createDiv({cls:"stashpad-view-popover-divider"}),s("everything","All descendants PLUS non-Stashpad files in the folder.","layout-grid"),e.createDiv({cls:"stashpad-view-popover-divider"}),this.plugin.encryption?.isConfigured?.()){let y=this.currentEncryptionFilter(),v=(Q,w,k)=>{let D=e.createDiv({cls:"stashpad-view-popover-row"});Q===y&&D.addClass("is-active"),D.createDiv({cls:"stashpad-view-popover-main"}).createSpan({cls:"stashpad-view-popover-label",text:w}),D.createDiv({cls:"stashpad-view-popover-desc",text:k}),D.onclick=async H=>{H.preventDefault(),H.stopPropagation(),Q!==y&&(await this.setEncryptionFilter(Q),this.refreshList()),t()}};v("all","Encryption: show all","Both locked \u{1F512} and decrypted notes."),v("locked","Encryption: locked only","Show only locked \u{1F512} stubs."),v("unlocked","Encryption: decrypted only","Hide locked \u{1F512} stubs."),e.createDiv({cls:"stashpad-view-popover-divider"})}let n=e.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 y=>{y.target!==o&&(y.preventDefault(),o.checked=!o.checked),await this.setHideChildless(o.checked),this.refreshList()};let a=e.createDiv({cls:"stashpad-view-popover-row stashpad-view-popover-toggle"}),l=a.createEl("input",{type:"checkbox"});l.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 y=>{y.target!==l&&(y.preventDefault(),l.checked=!l.checked),await this.setHideCompleted(l.checked),this.refreshList()};let c=e.createDiv({cls:"stashpad-view-popover-row stashpad-view-popover-toggle"}),d=c.createEl("input",{type:"checkbox"});d.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 y=>{y.target!==d&&(y.preventDefault(),d.checked=!d.checked),await this.setAttachmentsOnly(d.checked),this.refreshList()},e.createDiv({cls:"stashpad-view-popover-divider"});let h=e.createDiv({cls:"stashpad-view-popover-row stashpad-view-popover-toggle"});i!=="everything"&&h.addClass("is-disabled");let p=h.createEl("input",{type:"checkbox"});p.checked=this.currentIncludeAttachments(),p.disabled=i!=="everything",h.createDiv({cls:"stashpad-view-popover-main"}).createSpan({cls:"stashpad-view-popover-label",text:"Include attachments"}),h.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."}),h.onclick=async y=>{i==="everything"&&(y.target!==p&&(y.preventDefault(),p.checked=!p.checked),await this.setIncludeAttachments(p.checked),this.refreshList())},e.createDiv({cls:"stashpad-view-popover-divider"});let f=e.createDiv({cls:"stashpad-view-popover-row stashpad-view-popover-toggle"}),u=f.createEl("input",{type:"checkbox"});u.checked=this.importedOnly,f.createDiv({cls:"stashpad-view-popover-main"}).createSpan({cls:"stashpad-view-popover-label",text:"Imported notes only"}),f.createDiv({cls:"stashpad-view-popover-desc",text:"Show only notes that came in via import."}),f.onclick=y=>{y.target!==u&&(y.preventDefault(),u.checked=!u.checked),this.importedOnly=u.checked,this.reconcileSelectionAfterFilter(),this.refreshList()};let g=new Map,I=this.noteFolder.replace(/\/+$/,"");for(let y of this.app.vault.getMarkdownFiles()){if((y.parent?.path?.replace(/\/+$/,"")??"")!==I)continue;let v=gt(this.app.metadataCache.getFileCache(y)?.frontmatter?.author);v&&g.set(v.id,v.name)}e.createDiv({cls:"stashpad-view-popover-divider"});let m=e.createDiv({cls:"stashpad-view-popover-row"}),C=m.createDiv({cls:"stashpad-view-popover-main"});(0,F.setIcon)(C.createSpan({cls:"stashpad-view-popover-icon"}),"user"),C.createSpan({cls:"stashpad-view-popover-label",text:"By author"});let B=C.createEl("select",{cls:"stashpad-view-author-select"}),E=B.createEl("option",{text:"All authors",value:""});this.authorFilter||(E.selected=!0);for(let[y,v]of[...g.entries()].sort((Q,w)=>Q[1].localeCompare(w[1]))){let Q=B.createEl("option",{text:v,value:y});this.authorFilter===y&&(Q.selected=!0)}B.onclick=y=>y.stopPropagation(),B.onchange=()=>{this.authorFilter=B.value||null,this.reconcileSelectionAfterFilter(),this.refreshList()},m.createDiv({cls:"stashpad-view-popover-desc",text:g.size?"Show only notes by the chosen author.":"No authored notes in this folder yet."})}setTagFilter(e){(this.tagFilter??null)!==(e??null)&&(this.tagFilter=e,this.reconcileSelectionAfterFilter(),this.persistFocus(),this.render())}populateSortMenuBody(e,t){let i=this.noteFolder,s=this.focusId,n=this.sortStore.getMode(i,s);for(let o of oa){let a=e.createDiv({cls:"stashpad-sort-popover-row"});o===n&&a.addClass("is-active"),a.createSpan({cls:"stashpad-sort-popover-label",text:Ti[o]}),a.onclick=async l=>{l.preventDefault(),l.stopPropagation(),t(),o!==n&&(this.sortStore.setMode(i,s,o),await this.sortStore.save(i),this.tree.rebuild(i),this.render())}}}populateTimeMenuBody(e,t){let i=e.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 Ts){let o=e.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=l=>{l.preventDefault(),l.stopPropagation(),t(),this.timeFilter!==n.key&&this.setTimeFilter(n.key)}}}populateColorMenuBody(e,t,i){let s=(n,o,a)=>{let l=e.createDiv({cls:"stashpad-color-filter-popover-row"}),c=l.createSpan({cls:"stashpad-color-filter-swatch"});o?c.setCssStyles({background:o}):c.addClass("is-empty");let d=l.createSpan({cls:"stashpad-color-filter-popover-label"});d.setText(n),o&&(d.style.color=o),l.onclick=h=>{h.preventDefault(),h.stopPropagation(),a(),i()}};s("All colors",null,()=>this.setColorFilter(null));for(let n of t){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(e,t){let i=this.collectFolderTags(),s=(n,o)=>{let a=e.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=d=>{d.preventDefault(),d.stopPropagation(),this.setTagFilter(o),t()}};s(i.length===0?"No tags":"All tags",null),s("Tagged",Yt),s("Untagged",zt);for(let n of i)s(`${n.label} (${n.count})`,n.raw)}setColorFilter(e){let t=e?e.toLowerCase():null;(this.colorFilter??null)!==t&&(this.colorFilter=t,this.reconcileSelectionAfterFilter(),this.persistFocus(),this.render())}setTimeFilter(e){this.timeFilter!==e&&(this.timeFilter=e,this.reconcileSelectionAfterFilter(),this.persistFocus(),this.render())}reconcileSelectionAfterFilter(){let e=this.filterChildren(this.collectViewItems(this.focusId)),t=new Set(e.map(i=>i.id));for(let i of[...this.selection])t.has(i)||this.selection.delete(i);if(this.firstSelectedId&&!t.has(this.firstSelectedId)&&(this.firstSelectedId=null),this.lastSelected&&!t.has(this.lastSelected)&&(this.lastSelected=null),this.selection.size>0){let i=e.findIndex(s=>this.selection.has(s.id));this.cursorIdx=i>=0?i:Math.min(this.cursorIdx,e.length-1)}else this.cursorIdx>=e.length&&(this.cursorIdx=e.length-1)}renderTinyHeader(e){let t=e.createDiv({cls:"stashpad-tiny-header"}),i=t.createEl("button",{cls:"stashpad-tiny-nav-btn"});De(i,"arrow-left","\u2039"),i.title="Back (up to parent)",this.navBackStack.length>0||this.focusId!==S||i.addClass("is-disabled"),i.title=this.navBackStack.length>0?"Back":this.focusId!==S?"Back (up to parent)":"No back history",i.onclick=()=>this.navigateBack();let n=t.createEl("button",{cls:"stashpad-tiny-nav-btn"});De(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(),l=this.focusId===S?a:`${a} / ${this.titleForNode(o).trim()}`,c=t.createEl("button",{cls:"stashpad-tiny-title stashpad-folder-btn"}),d=c.createSpan({cls:"stashpad-tiny-title-icon stashpad-btn-icon"});(0,F.setIcon)(d,"folder"),c.createSpan({cls:"stashpad-tiny-title-text stashpad-btn-text",text:l}),c.title=`${this.noteFolder}${this.focusId!==S?` / ${this.titleForNode(o).trim()}`:""} +Click to switch / create folder.`,c.onclick=g=>{g.preventDefault(),this.plugin.openFolderPicker()};let h=t.createDiv({cls:"stashpad-tiny-sticky"}),p=h.createEl("input",{type:"checkbox"});if(p.checked=this.tinyAlwaysOnTop,h.createSpan({text:"Sticky"}),p.onchange=()=>{this.tinyAlwaysOnTop=p.checked,this.applyTinyAlwaysOnTop()},!F.Platform.isMobile){let g=t.createEl("button",{cls:"stashpad-tiny-nav-btn stashpad-tiny-opacity-btn"});(0,F.setIcon)(g,"contrast"),g.title="Window transparency",this.tinyOpacity<1&&g.addClass("is-active"),g.onclick=I=>{I.stopPropagation(),this.toggleTinyOpacityPopover(g)}}let f=t.createEl("button",{cls:"stashpad-tiny-expand stashpad-tiny-exit-compact"});(0,F.setIcon)(f,this.compactMode?"panel-top":"rows-2"),f.title=this.compactMode?"Compact mode is ON \u2014 click to turn off.":"Compact mode \u2014 click to turn on (strips row metadata).",this.compactMode&&f.addClass("is-active"),f.onclick=()=>{this.toggleCompactMode()};let u=t.createEl("button",{cls:"stashpad-tiny-expand"});(0,F.setIcon)(u,"maximize-2"),u.title="Exit tiny mode",u.onclick=()=>{this.exitTinyMode()}}toggleTinyOpacityPopover(e){if(this.tinyOpacityPopover){this.tinyOpacityPopover.remove(),this.tinyOpacityPopover=null;return}let t=document.createElement("div");t.className="stashpad-tiny-opacity-popover",t.createSpan({cls:"stashpad-tiny-opacity-label",text:"Transparency"});let i=t.createEl("input",{type:"range"});i.min="30",i.max="100",i.step="1",i.value=String(Math.round(this.tinyOpacity*100));let s=t.createSpan({cls:"stashpad-tiny-opacity-pct",text:`${i.value}%`});i.addEventListener("input",()=>{let d=Math.min(100,Math.max(30,parseInt(i.value,10)||100));this.tinyOpacity=d/100,s.setText(`${d}%`),this.applyTinyOpacity(),e.toggleClass("is-active",this.tinyOpacity<1)}),i.addEventListener("change",()=>{this.app.workspace.requestSaveLayout()}),this.viewRoot.appendChild(t);let n=e.getBoundingClientRect(),o=this.viewRoot.getBoundingClientRect();t.setCssStyles({top:`${n.bottom-o.top+4}px`,left:`${Math.max(4,Math.min(n.left-o.left,o.width-180))}px`});let a=d=>{t.contains(d.target)||d.target===e||e.contains(d.target)||c()},l=d=>{d.key==="Escape"&&c()},c=()=>{t.remove(),this.tinyOpacityPopover=null,this.tinyOpacityClose=null,document.removeEventListener("mousedown",a,!0),document.removeEventListener("keydown",l,!0)};setTimeout(()=>{document.addEventListener("mousedown",a,!0),document.addEventListener("keydown",l,!0)},0),this.tinyOpacityPopover=t,this.tinyOpacityClose=c,i.focus()}getOwnElectronWindow(){try{let e=this.containerEl?.ownerDocument?.defaultView??window,s=((e?.require?.("electron")??window.require?.("electron"))?.remote??e?.electron?.remote??e?.["@electron/remote"])?.getCurrentWindow?.()??e?.electronWindow??null;if(!s)try{let n=window.require?.("electron"),o=n?.remote??n?.["@electron/remote"],l=(o?.BrowserWindow??n?.BrowserWindow)?.getAllWindows?.()??[];l.length===1?s=l[0]:l.length>1&&(s=o?.getFocusedWindow?.()??null??l[l.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(e){return console.debug("[Stashpad] resolve own electron window failed",e),null}}applyTinyAlwaysOnTop(){let e=this.getOwnElectronWindow();if(e)try{e.setAlwaysOnTop?.(!!this.tinyAlwaysOnTop)}catch(t){console.debug("[Stashpad] setAlwaysOnTop failed",t)}}applyTinyOpacity(){let e=this.getOwnElectronWindow();if(!e)return;let t=Math.min(1,Math.max(.3,this.tinyOpacity));try{e.setOpacity?.(t)}catch(i){console.debug("[Stashpad] setOpacity failed",i)}}applyTinyWindow(){let e=this.getOwnElectronWindow();if(e)try{if(this.tinyMode){e.setMinimumSize?.(220,260);let s=100,n=100;try{let o=e.getBounds?.();o&&typeof o.x=="number"&&(s=o.x,n=o.y)}catch{}try{e.setBounds?.({x:s,y:n,width:280,height:360})}catch{}try{e.setSize?.(280,360)}catch{}e.setAlwaysOnTop?.(!!this.tinyAlwaysOnTop);try{e.setOpacity?.(Math.min(1,Math.max(.3,this.tinyOpacity)))}catch{}}else e.setAlwaysOnTop?.(!1)}catch(t){console.debug("[Stashpad] tiny window apply failed",t)}}async exitTinyMode(){this.tinyMode=!1,this.tinyAlwaysOnTop=!1,this.tinyOpacity=1;try{this.getOwnElectronWindow()?.setOpacity?.(1)}catch{}this.compactMode=!1,this.applyTinyWindow();let e=this.getOwnElectronWindow();try{if(e?.setMinimumSize?.(400,300),F.Platform.isMacOS??!1){let i=this.containerEl?.ownerDocument?.defaultView?.require?.("electron")??window.require?.("electron"),n=(i?.remote?.screen??i?.screen)?.getPrimaryDisplay?.().workArea;n?e?.setBounds?.({x:n.x,y:n.y,width:n.width,height:n.height}):e?.maximize?.()}else e?.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(e){let t=e.createDiv({cls:"stashpad-breadcrumb"});F.Platform.isMobile||this.renderActionsCluster(t);let i=t.createSpan({cls:"stashpad-crumb stashpad-crumb-home"});if(F.Platform.isMobile?((0,F.setIcon)(i,"home"),i.title="Home"):i.setText("Home"),i.onclick=()=>this.navigateTo(S),this.focusId===S){let c=this.tree.getChildren(this.focusId).length;if(c>0&&(t.createSpan({cls:"stashpad-crumb-count",text:`\xB7 ${c}`}).title=`${c} direct child${c===1?"":"ren"}`),this.compactMode){let d=t.createEl("button",{cls:"stashpad-compact-exit-btn"});(0,F.setIcon)(d,"panel-top"),d.title="Exit compact mode",d.onclick=h=>{h.preventDefault(),this.toggleCompactMode()}}return}let s=28,n=this.tree.pathTo(this.focusId);this.warmCrumbTitles(n);let o=n.map(c=>{let d=this.titleForNode(c),h=d.length>s?d.slice(0,s-1)+"\u2026":d;return{id:c.id,label:h}}),a=F.Platform.isMobile?"/":" / ";for(let c of o)if(t.createSpan({cls:"stashpad-crumb-sep",text:a}),c.isEllipsis)t.createSpan({cls:"stashpad-crumb stashpad-crumb-ellipsis",text:c.label}).title=n.map(d=>this.titleForNode(d)).join(" / ");else{let d=c.id,h=t.createSpan({cls:"stashpad-crumb",text:c.label});h.title=c.label,h.onclick=()=>this.navigateTo(d),h.oncontextmenu=p=>{p.preventDefault(),this.openCrumbMenu(p,d)},F.Platform.isMobile&&this.attachLongPress(h,()=>this.openCrumbMenu(null,d))}if(t.querySelector(".stashpad-crumb-home")?.addEventListener("contextmenu",c=>{c.preventDefault(),this.openCrumbMenu(c,S)}),F.Platform.isMobile){let c=t.querySelector(".stashpad-crumb-home");c&&this.attachLongPress(c,()=>this.openCrumbMenu(null,S))}let l=this.tree.getChildren(this.focusId).length;if(l>0&&(t.createSpan({cls:"stashpad-crumb-count",text:`\xB7 ${l}`}).title=`${l} direct child${l===1?"":"ren"}`),this.compactMode){let c=t.createEl("button",{cls:"stashpad-compact-exit-btn"});(0,F.setIcon)(c,"panel-top"),c.title="Exit compact mode",c.onclick=d=>{d.preventDefault(),this.toggleCompactMode()}}F.Platform.isMobile||this.renderBreadcrumbLevelsButton(t)}renderBreadcrumbLevelsButton(e){let t=e.createEl("button",{cls:"stashpad-mobile-action-btn stashpad-crumb-levels-btn"});De(t,"route","\u22D4"),t.title="Show all levels \u2014 jump to any level in the path",t.onclick=i=>{i.preventDefault(),this.openBreadcrumbLevelsModal()}}openBreadcrumbLevelsModal(){let e=this.tree.pathTo(this.focusId),t=[{id:S,label:"Home",level:0,isCurrent:this.focusId===S,isHome:!0}];e.forEach((i,s)=>{t.push({id:i.id,label:this.titleForNode(i),level:s+1,isCurrent:i.id===this.focusId})}),new fs(this.app,t,i=>this.navigateTo(i),{onContext:(i,s,n,o)=>this.openCrumbMenu(s,i,n,o),attachLongPress:(i,s)=>this.attachLongPress(i,s)}).open()}attachLongPress(e,t){let i=null,s=0,n=0,o=()=>{i!=null&&(window.clearTimeout(i),i=null)};e.addEventListener("touchstart",a=>{let l=a.touches[0];s=l?.clientX??0,n=l?.clientY??0,o(),i=window.setTimeout(()=>{i=null,t()},500)},{passive:!0}),e.addEventListener("touchmove",a=>{let l=a.touches[0];l&&(Math.abs(l.clientX-s)>10||Math.abs(l.clientY-n)>10)&&o()},{passive:!0}),e.addEventListener("touchend",o),e.addEventListener("touchcancel",o)}openCrumbMenu(e,t,i,s){let n=this.tree.get(t);if(!n)return;let o=new F.Menu;if(o.addItem(a=>a.setTitle("Open in new Stashpad tab").setIcon("list-tree").onClick(()=>{s?.(),this.cmdOpenInNewStashpadTab(n)})),o.addItem(a=>a.setTitle("Navigate here").setIcon("arrow-right-circle").onClick(()=>{s?.(),this.navigateTo(t)})),n.file&&(o.addItem(a=>a.setTitle("Edit in Stashpad").setIcon("pencil-line").onClick(()=>{s?.(),this.cmdEdit(n)})),o.addItem(a=>a.setTitle("Open in Obsidian editor (new tab)").setIcon("pencil").onClick(()=>{s?.(),this.cmdOpenInEditor(n)}))),e&&(e.clientX>0||e.clientY>0))o.showAtMouseEvent(e);else{let l=(i??e?.target??null)?.getBoundingClientRect();o.showAtPosition({x:l?.left??8,y:(l?.bottom??60)+4})}}renderFocusedHeaderMini(e,t){if(!t.file)return;let i=e.createDiv({cls:"stashpad-focused-mini"});i.dataset.id=t.id,i.createDiv({cls:"stashpad-focused-mini-text"}).setText(this.titleForNode(t).trim());let n=i.createEl("button",{cls:"stashpad-pencil stashpad-note-more stashpad-focused-mini-more"});(0,F.setIcon)(n,"ellipsis-vertical"),n.title="Actions",n.onclick=o=>{o.stopPropagation(),this.openNoteMenu(o,t)}}installFocusedMiniObserver(e){let t=e.querySelector(".stashpad-focused"),i=e.querySelector(".stashpad-focused-mini");!t||!i||(this.focusedMiniObserver&&this.focusedMiniObserver.disconnect(),this.focusedMiniObserver=new IntersectionObserver(s=>{for(let n of s)i.toggleClass("is-visible",!n.isIntersecting)},{root:e,threshold:.05}),this.focusedMiniObserver.observe(t))}renderFocusedHeader(e,t){if(!t.file)return;let i=t.file,s=e.createDiv({cls:"stashpad-focused"});s.oncontextmenu=d=>{d.preventDefault(),this.openNoteMenu(d,t)};let 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(t.created)}),o.createDiv({cls:"stashpad-focused-grip-spacer"});let a=s.createDiv({cls:"stashpad-focused-body"});a.addEventListener("click",d=>this.handleRenderedClick(d,t));let l=s.createDiv({cls:"stashpad-focused-actions"}),c;if(F.Platform.isMobile){let d=l.createEl("button",{cls:"stashpad-pencil stashpad-note-more stashpad-focused-more"});(0,F.setIcon)(d,"ellipsis-vertical"),d.title="Actions",d.onclick=h=>{h.stopPropagation(),this.openNoteMenu(h,t)},c=d}else{let d=l.createEl("button",{cls:"stashpad-pencil stashpad-focused-pencil"});(0,F.setIcon)(d,"pencil"),d.title="Edit in Stashpad",d.onclick=()=>void this.cmdEdit(t);let h=l.createEl("button",{cls:"stashpad-pencil stashpad-focused-dup"});(0,F.setIcon)(h,"copy"),h.title="Open this Stashpad in a new tab (clone)",h.onclick=()=>this.cmdOpenInNewStashpadTab(t),c=d}this.renderNoteBody(a,t,{clamp:!0,immediate:!0,toggleHost:l,toggleAnchor:c})}renderRowBreadcrumb(e,t){let i=this.tree.pathTo(t.id),s=i.findIndex(a=>a.id===this.focusId),n=i.slice(s+1,i.length-1);if(n.length===0)return;let o=e.createDiv({cls:"stashpad-row-breadcrumb"});n.forEach((a,l)=>{let c=o.createSpan({cls:"stashpad-row-breadcrumb-seg",text:this.titleForNode(a)});c.title=`Focus into "${this.titleForNode(a)}"`,c.onclick=d=>{d.stopPropagation(),this.navigateTo(a.id)},l<n.length-1&&o.createSpan({cls:"stashpad-row-breadcrumb-sep",text:" / "})})}actionsForFile(e){return ss(this.app,e,F.Platform.isMobile)}bulkActionMessage(e){let t=e.nodes.map(a=>`"${this.titleForNode(a).trim()||"(untitled)"}"`),i=e.suffix?` ${e.suffix}`:"",s=e.destination?` ${e.destination}`:"";if(t.length===0)return`${e.verb}${i}${s}`;if(t.length===1)return`${e.verb} ${t[0]}${i}${s}`;let n=e.bulletMax??10,o=t.length<=n?t.map(a=>`\u2022 ${a}`).join(` `):t.slice(0,n).map(a=>`\u2022 ${a}`).join(` `)+` \u2026+ ${t.length-n} more`;return`${e.verb} ${t.length} notes${i}${s}: -${o}`}titleList(e,t=3){if(!e.length)return"";let i=e.map(n=>this.titleForNode(n).trim()||"(untitled)");return i.length<=t?i.map(n=>`"${n}"`).join(", "):`${i.slice(0,t).map(n=>`"${n}"`).join(", ")}, +${i.length-t} more`}titleForNode(e){if(!e.file)return"Untitled";let i=this.app.metadataCache.getFileCache(e.file)?.headings?.[0]?.heading;if(i)return i.trim();let n=this.plugin.renderCacheStore.get(e.file.path)?.text?.slice(0,200).split(/\r?\n/).map(o=>o.trim()).find(Boolean);return n||e.file.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ")||"Untitled"}warmCrumbTitles(e){let t=e.filter(i=>!i.file||this.app.metadataCache.getFileCache(i.file)?.headings?.[0]?.heading?!1:!this.plugin.renderCacheStore.get(i.file.path));t.length&&Promise.all(t.map(i=>this.bodyRenderer.getOrComputeRender(i.file).catch(()=>null))).then(i=>{i.some(s=>s&&s.text&&s.text.trim())&&this.debouncedRender()})}async forceManualMode(e){let t=this.noteFolder;this.sortStore.getMode(t,e)!=="manual"&&(this.sortStore.setMode(t,e,"manual"),await this.sortStore.save(t))}renderNote(e,t,i){if(!t.file||this.currentEncryptionFilter()==="locked")return;let s=t.file,n=this.tree.getChildren(t.id).length,o=this.selection.has(t.id),a=i===this.cursorIdx,l=this.inListPicker?.activeIdx===i,c=e.createDiv({cls:"stashpad-note"});o&&c.addClass("is-selected"),a&&c.addClass("is-cursor"),a&&this.cursorHasMoved&&this.plugin.settings.autoExpandCursorRow&&!this.cursorExpandOverride.has(t.id)&&c.addClass("is-cursor-expanded"),l&&c.addClass("is-pick-target"),this.isCompleted(t)&&c.addClass("is-completed"),this.isListPinned(t.id)&&c.addClass("is-list-pinned"),this.isCutPending(t.id)?c.addClass("is-cut-pending"):this.isCopyPending(t.id)&&c.addClass("is-copy-pending"),c.dataset.idx=String(i),c.dataset.id=t.id;let A=this.currentViewMode()==="nested";c.draggable=A,A&&this.dnd.attachRowDnD(c,t,i),c.addEventListener("click",v=>this.handleRowClick(v,i,t)),c.addEventListener("dblclick",v=>{if(!this.plugin.settings.doubleClickToFocus)return;let Q=this.shouldAbsorbDismissTap();if(Q&&this.aimedTapTargetId&&Date.now()-this.aimedTapAt<=Ns.AIMED_TAP_WINDOW_MS){let F=this.aimedTapTargetId;this.aimedTapTargetId=null,this.traceTap("dblclick",v,i,!1),v.preventDefault(),window.getSelection()?.removeAllRanges(),this.navigateTo(F);return}if(this.traceTap("dblclick",v,i,Q),Q){v.preventDefault();return}v.target?.closest?.(".internal-link, .tag, a, .stashpad-note-task-checkbox")||(v.preventDefault(),window.getSelection()?.removeAllRanges(),this.navigateTo(t.id))});let h=this.isTask(t)||this.compactMode;h&&(c.addClass("is-task"),k.Platform.isMobile||this.addTaskCheckbox(c,t));let p=c.createDiv({cls:"stashpad-note-meta"}),f=p.createDiv({cls:"stashpad-note-meta-top"});f.createSpan({cls:"stashpad-note-time",text:this.formatTime(t.created)});let u=this.colorForNode(t),g=f.createDiv({cls:"stashpad-note-grip"});u&&g.addClass("has-color"),(0,k.setIcon)(g,"grip-vertical"),g.title=u?"Drag to reorder \xB7 right-click to change color":"Drag to reorder",g.draggable=A,A||(g.title=u?"Right-click to change color \xB7 drag disabled in this view mode":"Drag disabled in this view mode"),u&&g.style.setProperty("--stashpad-note-color",u);let I=h&&k.Platform.isMobile,m=this.isListPinned(t.id);if(n>0||I||m){let v=p.createDiv({cls:"stashpad-note-meta-bottom"});if(m){let Q=v.createSpan({cls:"stashpad-note-listpin"});(0,k.setIcon)(Q,"pin"),Q.setAttr("aria-label","Pinned to top of list")}if(I&&this.addTaskCheckbox(v,t),n>0){let Q=v.createSpan({cls:"stashpad-note-enter"});u&&(Q.style.color=u),(0,k.setIcon)(Q.createSpan({cls:"stashpad-btn-icon"}),"corner-down-right"),Q.createSpan({text:` ${n}`}),Q.onclick=w=>{w.stopPropagation(),this.navigateTo(t.id)}}}if(u)c.addClass("has-color"),c.style.setProperty("--stashpad-note-color",u);else{let v=this.inheritedColorForNode(t);v&&v.depth>0&&(c.addClass("has-inherited-color"),c.style.setProperty("--stashpad-inherited-color",v.hex),c.style.setProperty("--stashpad-inherited-depth",String(v.depth)))}let C=c.createDiv({cls:"stashpad-note-body"});this.currentViewMode()!=="nested"&&this.renderRowBreadcrumb(C,t);let B=C.createDiv({cls:"stashpad-note-body-content"}),E=c.createDiv({cls:"stashpad-note-actions"}),y;if(k.Platform.isMobile){let v=E.createEl("button",{cls:"stashpad-pencil stashpad-note-more"});(0,k.setIcon)(v,"ellipsis-vertical"),v.title="Actions",v.onclick=Q=>{Q.stopPropagation(),this.openNoteMenu(Q,t)},y=v}else{let v=E.createEl("button",{cls:"stashpad-pencil"});(0,k.setIcon)(v,"pencil"),v.title="Edit in Stashpad",v.onclick=F=>{F.stopPropagation(),this.cmdEdit(t)};let Q=E.createEl("button",{cls:"stashpad-pencil stashpad-enter-btn"});(0,k.setIcon)(Q,"arrow-right"),Q.title="Open in Stashpad view",Q.onclick=F=>{F.stopPropagation(),this.navigateTo(t.id)};let w=E.createEl("button",{cls:"stashpad-pencil stashpad-note-more"});(0,k.setIcon)(w,"ellipsis-vertical"),w.title="More actions",w.onclick=F=>{F.stopPropagation(),this.openNoteMenu(F,t)},y=v}this.renderNoteBody(B,t,{clamp:!0,toggleHost:E,toggleAnchor:y}),this.renderVersionTabs(C,t),c.oncontextmenu=v=>{v.preventDefault(),this.openNoteMenu(v,t)}}renderVersionTabs(e,t){if(!this.plugin.settings.enableSheetVersions||!Vi(ke(this.app,t)))return;let i=_e(ke(this.app,t)),s=t.parent??this.focusId,n=this.tree.getChildren(s),o=Io(this.app,n.filter(c=>{let A=ke(this.app,c);return Vi(A)&&_e(A)===i}));if(o.length<2)return;let a=e.createDiv({cls:"stashpad-version-tabs"});for(let c of o){let A=c.id===t.id,h=ke(this.app,c),p=Wi(h),f=Ga(h),u=a.createDiv({cls:"stashpad-version-tab"+(A?" is-active":"")+(p?" is-final":"")+(f?" is-original":"")});p&&u.createSpan({cls:"stashpad-version-star",text:"\u2605"}),u.createSpan({cls:"stashpad-version-tab-label",text:Ja(this.app,c,this.titleForNode(c).trim()||"Untitled")});let g=this.titleForNode(c).trim();u.title=f?`${g} (original)`:`${g} (forked)`,A||(u.onclick=I=>{I.stopPropagation(),this.setActiveVersion(i,c.id)})}let l=a.createEl("button",{cls:"stashpad-version-add stashpad-version-fork"});(0,k.setIcon)(l,"git-fork"),l.title="Fork this version (copy)",l.onclick=c=>{c.stopPropagation(),this.cmdForkVersion(t)}}addTaskCheckbox(e,t){let i=e.createSpan({cls:"stashpad-note-task-checkbox"}),s=this.isCompleted(t);(0,k.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(t)}}renderNoteBody(e,t,i={clamp:!0}){if(!t.file)return;if(i.immediate||this.bodyRenderer.hasFreshRenderCache(t.file)||!this.bodyRenderer.isArmed()){this.renderNoteBodyNow(e,t,i);return}let s=this.bodyRenderer.peekCache(t.file);if(s){this.prepaintCachedBody(e,t,s,i),this.renderNoteBodyNow(e,t,i);return}e.empty();let n=e.createDiv({cls:"stashpad-note-text is-plain is-lazy-placeholder"});n.textContent=this.titleForNode(t),this.bodyRenderer.defer(e,()=>this.renderNoteBodyNow(e,t,i))}prepaintCachedBody(e,t,i,s){e.empty();let n=e.createDiv({cls:"stashpad-note-text"}),o=this.isNoteExpanded(t.id);s.clamp&&!o&&n.addClass("is-clamped"),e.toggleClass("is-body-expanded",s.clamp===!0&&o),this.compactMode||this.tinyMode?(n.addClass("is-plain"),n.textContent=i.text):n.append((0,k.sanitizeHTMLToDom)(i.html))}renderNoteBodyNow(e,t,i={clamp:!0}){if(!t.file)return;let s=t.file,n=(e.__stashpadRenderToken??0)+1;e.__stashpadRenderToken=n,this.bodyRenderer.getOrComputeRender(s).then(o=>{if(e.__stashpadRenderToken!==n)return;let{text:a,attachments:l,html:c}=o;e.empty();let A=e.createDiv({cls:"stashpad-note-text"}),h=this.isNoteExpanded(t.id);if(i.clamp&&!h&&A.addClass("is-clamped"),e.toggleClass("is-body-expanded",i.clamp===!0&&h),this.compactMode||this.tinyMode?(A.addClass("is-plain"),A.textContent=a):A.append((0,k.sanitizeHTMLToDom)(c)),l.length>0&&this.renderAttachmentRail(e,l),this.renderAuthorshipFooter(e,t),!i.clamp)return;let p=this.lastListWidth;if(o.ovW===p&&o.ovV!==void 0&&!h){o.ovV?this.attachExpandToggle(i,e,t,h):A.removeClass("is-clamped");return}requestAnimationFrame(()=>{if(h){this.attachExpandToggle(i,e,t,h);return}let f=e.closest?.(".stashpad-note.is-cursor-expanded");f&&f.removeClass("is-cursor-expanded");let u=A.scrollHeight>A.clientHeight+4;if(f&&f.addClass("is-cursor-expanded"),o.ovW=p,o.ovV=u,!u){A.removeClass("is-clamped");return}this.attachExpandToggle(i,e,t,h)})})}attachExpandToggle(e,t,i,s){let n=!!e.toggleHost,o=e.toggleHost??t;o.querySelector(".stashpad-expand-toggle")?.remove();let a=!!t.closest?.(".stashpad-note.is-cursor-expanded"),l=s||a,c=o.createEl("button",{cls:"stashpad-expand-toggle"});c.title=l?"Show less":"Show more",n||k.Platform.isMobile?((0,k.setIcon)(c,l?"chevron-up":"chevron-down"),c.addClass("is-icon"),n&&c.addClass("is-inline")):c.setText(l?"Show less":"Show more"),e.toggleAnchor&&e.toggleAnchor.parentElement===o&&o.insertBefore(c,e.toggleAnchor),c.addEventListener("dblclick",A=>{A.preventDefault(),A.stopPropagation()}),c.addEventListener("mousedown",A=>{A.stopPropagation()}),c.onclick=A=>{A.stopPropagation();let h=t.closest?.(".stashpad-note"),p=!!h?.classList.contains("is-cursor-expanded"),u=!(this.isNoteExpanded(i.id)||p);p&&!u?(h?.removeClass("is-cursor-expanded"),this.cursorExpandOverride.add(i.id)):u&&this.cursorExpandOverride.delete(i.id),this.setNoteExpanded(i.id,u),t.empty(),this.renderNoteBody(t,i,e)}}renderAttachmentRail(e,t){let i=e.createDiv({cls:"stashpad-rail"});for(let s of t){let n=this.app.metadataCache.getFirstLinkpathDest(s,""),o=(s.split(".").pop()??"").toLowerCase(),a=i.createDiv({cls:"stashpad-att"});if(a.title=s,n&&Wl.has(o)){let l=a.createEl("img",{cls:"stashpad-att-img"});l.src=this.app.vault.getResourcePath(n),l.alt=s}else{a.createDiv({cls:"stashpad-att-ext",text:o.toUpperCase()||"?"});let l=(s.split("/").pop()??s).replace(/\.[^.]+$/,"");a.createDiv({cls:"stashpad-att-name",text:l})}a.onclick=l=>{l.stopPropagation(),n&&this.app.workspace.getLeaf("tab").openFile(n)},a.oncontextmenu=l=>{l.preventDefault(),l.stopPropagation(),this.openAttachmentMenu(l,s,n,o)}}}openAttachmentMenu(e,t,i,s){let n=new k.Menu;if(i&&Wl.has(s)&&n.addItem(o=>o.setTitle("Copy image").setIcon("copy").onClick(()=>void this.copyAttachmentImage(i))),i){n.addItem(o=>o.setTitle("Open in new tab").setIcon("external-link").onClick(()=>void this.app.workspace.getLeaf("tab").openFile(i)));for(let o of ts(this.app,i.path,k.Platform.isMobile))n.addItem(a=>a.setTitle(o.label).setIcon(o.label.startsWith("Reveal")?"folder-open":"arrow-up-right").onClick(()=>void o.onClick()))}n.addItem(o=>o.setTitle("Copy path").setIcon("link").onClick(()=>void navigator.clipboard?.writeText(t).then(()=>new k.Notice("Path copied."),()=>{}))),n.showAtMouseEvent(e)}async copyAttachmentImage(e){try{let t=window.require?.("electron");if(!t?.clipboard?.writeImage||!t?.nativeImage){new k.Notice("Copying an image to the clipboard needs the desktop app.");return}let i=await this.app.vault.readBinary(e),s=t.nativeImage.createFromBuffer(Buffer.from(new Uint8Array(i)));if(s.isEmpty()){new k.Notice("Couldn't read that image.");return}t.clipboard.writeImage(s),new k.Notice("Image copied to the clipboard.")}catch(t){console.warn("[Stashpad] copy image failed",t),new k.Notice("Couldn't copy the image.")}}renderComposerNavCluster(e){let t=e.createDiv({cls:"stashpad-composer-nav"}),i=t.createEl("button",{cls:"stashpad-composer-btn stashpad-composer-nav-folder"});(0,k.setIcon)(i,this.plugin.getFolderIcon(this.noteFolder)??"folder");let s=this.noteFolder.split("/").pop()||this.noteFolder||"Stashpad";i.createSpan({cls:"stashpad-btn-text",text:s}),i.title=`Folder: ${this.noteFolder} -Tap to switch / create.`,this.folderOverride&&i.addClass("is-active"),i.onmousedown=o=>o.preventDefault(),i.onclick=o=>{o.preventDefault(),this.openFolderPicker()};let n=t.createEl("button",{cls:"stashpad-composer-btn"});De(n,"search","\u{1F50D}"),n.title="Search notes (Mod+F)",n.onmousedown=o=>o.preventDefault(),n.onclick=o=>{o.preventDefault(),this.openSearchModal()}}renderComposer(e){let t=X(),i=this.modeEnterSubmits,s=this.modeSplit??t.splitOnLines,n=e.createDiv({cls:"stashpad-composer"}),o=n.createDiv({cls:"stashpad-composer-input-wrap"}),a=o.createEl("textarea",{cls:"stashpad-composer-input",attr:{rows:"2",placeholder:this.composerPlaceholder(i,s)}});a.value=this.composerDraft;let l=o.createEl("button",{cls:"stashpad-composer-fullscreen"});(0,k.setIcon)(l,"maximize"),l.title="Open in the full editor",l.setAttr("aria-label","Open in the full editor"),l.onmousedown=x=>x.preventDefault(),l.onclick=x=>{x.preventDefault(),this.cmdComposerFullscreen()},this.debouncedSaveDraft||(this.debouncedSaveDraft=(0,k.debounce)(x=>{this.saveDraft(x)},250)),a.addEventListener("input",()=>{this.composerDraft=a.value,this.debouncedSaveDraft(a.value)}),a.addEventListener("blur",()=>{this.saveDraft(a.value)});let c=null,A=()=>{c||(c=new k.Scope(this.app.scope),c.register([],"Escape",()=>(this.composerExitAt=Date.now(),a.blur(),this.viewRoot?.focus({preventScroll:!0}),!1)),c.register(["Mod"],"z",()=>!0),c.register(["Mod","Shift"],"z",()=>!0),this.app.keymap?.pushScope(c))},h=()=>{if(c){try{this.app.keymap?.popScope(c)}catch{}c=null}};if(a.addEventListener("focus",A),a.addEventListener("blur",h),document.activeElement===a&&A(),k.Platform.isMobile){let x=()=>{this.keyboardTransitionUntil=Date.now()+600};a.addEventListener("focus",()=>{document.body.classList.add("stashpad-keyboard-open"),x()}),a.addEventListener("blur",()=>{document.body.classList.remove("stashpad-keyboard-open"),x(),this.tapSettleUntil=Date.now()+300,k.Platform.isMobile&&this.cursorIdx>=0&&setTimeout(()=>this.revealCursorRow(),350)})}this.composerInputEl=a,this.composerAutocomplete&&this.composerAutocomplete.detach(),this.composerAutocomplete=new Pt(this.app,a),this.composerAutocomplete.attach();let p=async x=>{let U="";for(let T of x){let b=await this.importAttachment(T);if(!b)continue;let M=a.value+U,O=M&&!M.endsWith(` +${o}`}titleList(e,t=3){if(!e.length)return"";let i=e.map(n=>this.titleForNode(n).trim()||"(untitled)");return i.length<=t?i.map(n=>`"${n}"`).join(", "):`${i.slice(0,t).map(n=>`"${n}"`).join(", ")}, +${i.length-t} more`}titleForNode(e){if(!e.file)return"Untitled";let i=this.app.metadataCache.getFileCache(e.file)?.headings?.[0]?.heading;if(i)return i.trim();let n=this.plugin.renderCacheStore.get(e.file.path)?.text?.slice(0,200).split(/\r?\n/).map(o=>o.trim()).find(Boolean);return n||e.file.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ")||"Untitled"}warmCrumbTitles(e){let t=e.filter(i=>!i.file||this.app.metadataCache.getFileCache(i.file)?.headings?.[0]?.heading?!1:!this.plugin.renderCacheStore.get(i.file.path));t.length&&Promise.all(t.map(i=>this.bodyRenderer.getOrComputeRender(i.file).catch(()=>null))).then(i=>{i.some(s=>s&&s.text&&s.text.trim())&&this.debouncedRender()})}async forceManualMode(e){let t=this.noteFolder;this.sortStore.getMode(t,e)!=="manual"&&(this.sortStore.setMode(t,e,"manual"),await this.sortStore.save(t))}renderNote(e,t,i){if(!t.file||this.currentEncryptionFilter()==="locked")return;let s=t.file,n=this.tree.getChildren(t.id).length,o=this.selection.has(t.id),a=i===this.cursorIdx,l=this.inListPicker?.activeIdx===i,c=e.createDiv({cls:"stashpad-note"});o&&c.addClass("is-selected"),a&&c.addClass("is-cursor"),a&&this.cursorHasMoved&&this.plugin.settings.autoExpandCursorRow&&!this.cursorExpandOverride.has(t.id)&&c.addClass("is-cursor-expanded"),l&&c.addClass("is-pick-target"),this.isCompleted(t)&&c.addClass("is-completed"),this.isListPinned(t.id)&&c.addClass("is-list-pinned"),this.isCutPending(t.id)?c.addClass("is-cut-pending"):this.isCopyPending(t.id)&&c.addClass("is-copy-pending"),c.dataset.idx=String(i),c.dataset.id=t.id;let d=this.currentViewMode()==="nested";c.draggable=d,d&&this.dnd.attachRowDnD(c,t,i),c.addEventListener("click",v=>this.handleRowClick(v,i,t)),c.addEventListener("dblclick",v=>{if(!this.plugin.settings.doubleClickToFocus)return;let Q=this.shouldAbsorbDismissTap();if(Q&&this.aimedTapTargetId&&Date.now()-this.aimedTapAt<=Ms.AIMED_TAP_WINDOW_MS){let k=this.aimedTapTargetId;this.aimedTapTargetId=null,this.traceTap("dblclick",v,i,!1),v.preventDefault(),window.getSelection()?.removeAllRanges(),this.navigateTo(k);return}if(this.traceTap("dblclick",v,i,Q),Q){v.preventDefault();return}v.target?.closest?.(".internal-link, .tag, a, .stashpad-note-task-checkbox")||(v.preventDefault(),window.getSelection()?.removeAllRanges(),this.navigateTo(t.id))});let h=this.isTask(t)||this.compactMode;h&&(c.addClass("is-task"),F.Platform.isMobile||this.addTaskCheckbox(c,t));let p=c.createDiv({cls:"stashpad-note-meta"}),f=p.createDiv({cls:"stashpad-note-meta-top"});f.createSpan({cls:"stashpad-note-time",text:this.formatTime(t.created)});let u=this.colorForNode(t),g=f.createDiv({cls:"stashpad-note-grip"});u&&g.addClass("has-color"),(0,F.setIcon)(g,"grip-vertical"),g.title=u?"Drag to reorder \xB7 right-click to change color":"Drag to reorder",g.draggable=d,d||(g.title=u?"Right-click to change color \xB7 drag disabled in this view mode":"Drag disabled in this view mode"),u&&g.style.setProperty("--stashpad-note-color",u);let I=h&&F.Platform.isMobile,m=this.isListPinned(t.id);if(n>0||I||m){let v=p.createDiv({cls:"stashpad-note-meta-bottom"});if(m){let Q=v.createSpan({cls:"stashpad-note-listpin"});(0,F.setIcon)(Q,"pin"),Q.setAttr("aria-label","Pinned to top of list")}if(I&&this.addTaskCheckbox(v,t),n>0){let Q=v.createSpan({cls:"stashpad-note-enter"});u&&(Q.style.color=u),(0,F.setIcon)(Q.createSpan({cls:"stashpad-btn-icon"}),"corner-down-right"),Q.createSpan({text:` ${n}`}),Q.onclick=w=>{w.stopPropagation(),this.navigateTo(t.id)}}}if(u)c.addClass("has-color"),c.style.setProperty("--stashpad-note-color",u);else{let v=this.inheritedColorForNode(t);v&&v.depth>0&&(c.addClass("has-inherited-color"),c.style.setProperty("--stashpad-inherited-color",v.hex),c.style.setProperty("--stashpad-inherited-depth",String(v.depth)))}let C=c.createDiv({cls:"stashpad-note-body"});this.currentViewMode()!=="nested"&&this.renderRowBreadcrumb(C,t);let B=C.createDiv({cls:"stashpad-note-body-content"}),E=c.createDiv({cls:"stashpad-note-actions"}),y;if(F.Platform.isMobile){let v=E.createEl("button",{cls:"stashpad-pencil stashpad-note-more"});(0,F.setIcon)(v,"ellipsis-vertical"),v.title="Actions",v.onclick=Q=>{Q.stopPropagation(),this.openNoteMenu(Q,t)},y=v}else{let v=E.createEl("button",{cls:"stashpad-pencil"});(0,F.setIcon)(v,"pencil"),v.title="Edit in Stashpad",v.onclick=k=>{k.stopPropagation(),this.cmdEdit(t)};let Q=E.createEl("button",{cls:"stashpad-pencil stashpad-enter-btn"});(0,F.setIcon)(Q,"arrow-right"),Q.title="Open in Stashpad view",Q.onclick=k=>{k.stopPropagation(),this.navigateTo(t.id)};let w=E.createEl("button",{cls:"stashpad-pencil stashpad-note-more"});(0,F.setIcon)(w,"ellipsis-vertical"),w.title="More actions",w.onclick=k=>{k.stopPropagation(),this.openNoteMenu(k,t)},y=v}this.renderNoteBody(B,t,{clamp:!0,toggleHost:E,toggleAnchor:y}),this.renderVersionTabs(C,t),c.oncontextmenu=v=>{v.preventDefault(),this.openNoteMenu(v,t)}}renderVersionTabs(e,t){if(!this.plugin.settings.enableSheetVersions||!Xi(Fe(this.app,t)))return;let i=_e(Fe(this.app,t)),s=t.parent??this.focusId,n=this.tree.getChildren(s),o=Bo(this.app,n.filter(c=>{let d=Fe(this.app,c);return Xi(d)&&_e(d)===i}));if(o.length<2)return;let a=e.createDiv({cls:"stashpad-version-tabs"});for(let c of o){let d=c.id===t.id,h=Fe(this.app,c),p=Zi(h),f=Ja(h),u=a.createDiv({cls:"stashpad-version-tab"+(d?" is-active":"")+(p?" is-final":"")+(f?" is-original":"")});p&&u.createSpan({cls:"stashpad-version-star",text:"\u2605"}),u.createSpan({cls:"stashpad-version-tab-label",text:za(this.app,c,this.titleForNode(c).trim()||"Untitled")});let g=this.titleForNode(c).trim();u.title=f?`${g} (original)`:`${g} (forked)`,d||(u.onclick=I=>{I.stopPropagation(),this.setActiveVersion(i,c.id)})}let l=a.createEl("button",{cls:"stashpad-version-add stashpad-version-fork"});(0,F.setIcon)(l,"git-fork"),l.title="Fork this version (copy)",l.onclick=c=>{c.stopPropagation(),this.cmdForkVersion(t)}}addTaskCheckbox(e,t){let i=e.createSpan({cls:"stashpad-note-task-checkbox"}),s=this.isCompleted(t);(0,F.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(t)}}renderNoteBody(e,t,i={clamp:!0}){if(!t.file)return;if(i.immediate||this.bodyRenderer.hasFreshRenderCache(t.file)||!this.bodyRenderer.isArmed()){this.renderNoteBodyNow(e,t,i);return}let s=this.bodyRenderer.peekCache(t.file);if(s){this.prepaintCachedBody(e,t,s,i),this.renderNoteBodyNow(e,t,i);return}e.empty();let n=e.createDiv({cls:"stashpad-note-text is-plain is-lazy-placeholder"});n.textContent=this.titleForNode(t),this.bodyRenderer.defer(e,()=>this.renderNoteBodyNow(e,t,i))}prepaintCachedBody(e,t,i,s){e.empty();let n=e.createDiv({cls:"stashpad-note-text"}),o=this.isNoteExpanded(t.id);s.clamp&&!o&&n.addClass("is-clamped"),e.toggleClass("is-body-expanded",s.clamp===!0&&o),this.compactMode||this.tinyMode?(n.addClass("is-plain"),n.textContent=i.text):n.append((0,F.sanitizeHTMLToDom)(i.html))}renderNoteBodyNow(e,t,i={clamp:!0}){if(!t.file)return;let s=t.file,n=(e.__stashpadRenderToken??0)+1;e.__stashpadRenderToken=n,this.bodyRenderer.getOrComputeRender(s).then(o=>{if(e.__stashpadRenderToken!==n)return;let{text:a,attachments:l,html:c}=o;e.empty();let d=e.createDiv({cls:"stashpad-note-text"}),h=this.isNoteExpanded(t.id);if(i.clamp&&!h&&d.addClass("is-clamped"),e.toggleClass("is-body-expanded",i.clamp===!0&&h),this.compactMode||this.tinyMode?(d.addClass("is-plain"),d.textContent=a):d.append((0,F.sanitizeHTMLToDom)(c)),l.length>0&&this.renderAttachmentRail(e,l),this.renderAuthorshipFooter(e,t),!i.clamp)return;let p=this.lastListWidth;if(o.ovW===p&&o.ovV!==void 0&&!h){o.ovV?this.attachExpandToggle(i,e,t,h):d.removeClass("is-clamped");return}requestAnimationFrame(()=>{if(h){this.attachExpandToggle(i,e,t,h);return}let f=e.closest?.(".stashpad-note.is-cursor-expanded");f&&f.removeClass("is-cursor-expanded");let u=d.scrollHeight>d.clientHeight+4;if(f&&f.addClass("is-cursor-expanded"),o.ovW=p,o.ovV=u,!u){d.removeClass("is-clamped");return}this.attachExpandToggle(i,e,t,h)})})}attachExpandToggle(e,t,i,s){let n=!!e.toggleHost,o=e.toggleHost??t;o.querySelector(".stashpad-expand-toggle")?.remove();let a=!!t.closest?.(".stashpad-note.is-cursor-expanded"),l=s||a,c=o.createEl("button",{cls:"stashpad-expand-toggle"});c.title=l?"Show less":"Show more",n||F.Platform.isMobile?((0,F.setIcon)(c,l?"chevron-up":"chevron-down"),c.addClass("is-icon"),n&&c.addClass("is-inline")):c.setText(l?"Show less":"Show more"),e.toggleAnchor&&e.toggleAnchor.parentElement===o&&o.insertBefore(c,e.toggleAnchor),c.addEventListener("dblclick",d=>{d.preventDefault(),d.stopPropagation()}),c.addEventListener("mousedown",d=>{d.stopPropagation()}),c.onclick=d=>{d.stopPropagation();let h=t.closest?.(".stashpad-note"),p=!!h?.classList.contains("is-cursor-expanded"),u=!(this.isNoteExpanded(i.id)||p);p&&!u?(h?.removeClass("is-cursor-expanded"),this.cursorExpandOverride.add(i.id)):u&&this.cursorExpandOverride.delete(i.id),this.setNoteExpanded(i.id,u),t.empty(),this.renderNoteBody(t,i,e)}}renderAttachmentRail(e,t){let i=e.createDiv({cls:"stashpad-rail"});for(let s of t){let n=this.app.metadataCache.getFirstLinkpathDest(s,""),o=(s.split(".").pop()??"").toLowerCase(),a=i.createDiv({cls:"stashpad-att"});if(a.title=s,n&&jl.has(o)){let l=a.createEl("img",{cls:"stashpad-att-img"});l.src=this.app.vault.getResourcePath(n),l.alt=s}else{a.createDiv({cls:"stashpad-att-ext",text:o.toUpperCase()||"?"});let l=(s.split("/").pop()??s).replace(/\.[^.]+$/,"");a.createDiv({cls:"stashpad-att-name",text:l})}a.onclick=l=>{l.stopPropagation(),n&&this.app.workspace.getLeaf("tab").openFile(n)},a.oncontextmenu=l=>{l.preventDefault(),l.stopPropagation(),this.openAttachmentMenu(l,s,n,o)}}}openAttachmentMenu(e,t,i,s){let n=new F.Menu;if(i&&jl.has(s)&&n.addItem(o=>o.setTitle("Copy image").setIcon("copy").onClick(()=>void this.copyAttachmentImage(i))),i){n.addItem(o=>o.setTitle("Open in new tab").setIcon("external-link").onClick(()=>void this.app.workspace.getLeaf("tab").openFile(i)));for(let o of ss(this.app,i.path,F.Platform.isMobile))n.addItem(a=>a.setTitle(o.label).setIcon(o.label.startsWith("Reveal")?"folder-open":"arrow-up-right").onClick(()=>void o.onClick()))}n.addItem(o=>o.setTitle("Copy path").setIcon("link").onClick(()=>void navigator.clipboard?.writeText(t).then(()=>new F.Notice("Path copied."),()=>{}))),n.showAtMouseEvent(e)}async copyAttachmentImage(e){try{let t=window.require?.("electron");if(!t?.clipboard?.writeImage||!t?.nativeImage){new F.Notice("Copying an image to the clipboard needs the desktop app.");return}let i=await this.app.vault.readBinary(e),s=t.nativeImage.createFromBuffer(Buffer.from(new Uint8Array(i)));if(s.isEmpty()){new F.Notice("Couldn't read that image.");return}t.clipboard.writeImage(s),new F.Notice("Image copied to the clipboard.")}catch(t){console.warn("[Stashpad] copy image failed",t),new F.Notice("Couldn't copy the image.")}}renderComposerNavCluster(e){let t=e.createDiv({cls:"stashpad-composer-nav"}),i=t.createEl("button",{cls:"stashpad-composer-btn stashpad-composer-nav-folder"});(0,F.setIcon)(i,this.plugin.getFolderIcon(this.noteFolder)??"folder");let s=this.noteFolder.split("/").pop()||this.noteFolder||"Stashpad";i.createSpan({cls:"stashpad-btn-text",text:s}),i.title=`Folder: ${this.noteFolder} +Tap to switch / create.`,this.folderOverride&&i.addClass("is-active"),i.onmousedown=o=>o.preventDefault(),i.onclick=o=>{o.preventDefault(),this.openFolderPicker()};let n=t.createEl("button",{cls:"stashpad-composer-btn"});De(n,"search","\u{1F50D}"),n.title="Search notes (Mod+F)",n.onmousedown=o=>o.preventDefault(),n.onclick=o=>{o.preventDefault(),this.openSearchModal()}}renderComposer(e){let t=X(),i=this.modeEnterSubmits,s=this.modeSplit??t.splitOnLines,n=e.createDiv({cls:"stashpad-composer"}),o=n.createDiv({cls:"stashpad-composer-input-wrap"}),a=o.createEl("textarea",{cls:"stashpad-composer-input",attr:{rows:"2",placeholder:this.composerPlaceholder(i,s)}});a.value=this.composerDraft;let l=o.createEl("button",{cls:"stashpad-composer-fullscreen"});(0,F.setIcon)(l,"maximize"),l.title="Open in the full editor",l.setAttr("aria-label","Open in the full editor"),l.onmousedown=x=>x.preventDefault(),l.onclick=x=>{x.preventDefault(),this.cmdComposerFullscreen()},this.debouncedSaveDraft||(this.debouncedSaveDraft=(0,F.debounce)(x=>{this.saveDraft(x)},250)),a.addEventListener("input",()=>{this.composerDraft=a.value,this.debouncedSaveDraft(a.value)}),a.addEventListener("blur",()=>{this.saveDraft(a.value)});let c=null,d=()=>{c||(c=new F.Scope(this.app.scope),c.register([],"Escape",()=>(this.composerExitAt=Date.now(),a.blur(),this.viewRoot?.focus({preventScroll:!0}),!1)),c.register(["Mod"],"z",()=>!0),c.register(["Mod","Shift"],"z",()=>!0),this.app.keymap?.pushScope(c))},h=()=>{if(c){try{this.app.keymap?.popScope(c)}catch{}c=null}};if(a.addEventListener("focus",d),a.addEventListener("blur",h),document.activeElement===a&&d(),F.Platform.isMobile){let x=()=>{this.keyboardTransitionUntil=Date.now()+600};a.addEventListener("focus",()=>{document.body.classList.add("stashpad-keyboard-open"),x()}),a.addEventListener("blur",()=>{document.body.classList.remove("stashpad-keyboard-open"),x(),this.tapSettleUntil=Date.now()+300,F.Platform.isMobile&&this.cursorIdx>=0&&setTimeout(()=>this.revealCursorRow(),350)})}this.composerInputEl=a,this.composerAutocomplete&&this.composerAutocomplete.detach(),this.composerAutocomplete=new Pt(this.app,a),this.composerAutocomplete.attach();let p=async x=>{let U="";for(let T of x){let b=await this.importAttachment(T);if(!b)continue;let M=a.value+U,O=M&&!M.endsWith(` `)?` `:"";U+=`${O}${b} -`}U&&(a.value=a.value+U,this.composerDraft=a.value,this.saveDraft(a.value),a.focus(),a.setSelectionRange(a.value.length,a.value.length))};a.addEventListener("dragover",x=>{if(!(!x.dataTransfer||!Array.from(x.dataTransfer.types).includes("Files"))){x.preventDefault(),x.stopPropagation();try{x.dataTransfer.dropEffect="copy"}catch{}}}),a.addEventListener("drop",x=>{let U=Array.from(x.dataTransfer?.files??[]);U.length!==0&&(x.preventDefault(),x.stopPropagation(),p(U))}),a.addEventListener("paste",x=>{let U=this.plugin.noteClipboard;if(U?.mode==="cut"&&U.text&&x.clipboardData?.getData("text/plain")===U.text){if(this.focusedInsideCut(U.ids)){x.preventDefault(),new k.Notice("Can't paste a cut note into the note you're cutting.");return}x.preventDefault(),this.completeCutIntoComposer();return}let T=[],b=x.clipboardData;if(b){for(let M of Array.from(b.files??[]))T.push(M);if(T.length===0){for(let M of Array.from(b.items??[]))if(M.kind==="file"){let O=M.getAsFile();O&&T.push(O)}}T.length!==0&&(x.preventDefault(),x.stopPropagation(),p(T))}});let f=n.createEl("input",{cls:"stashpad-composer-file-input",type:"file",attr:{multiple:"true"}});f.setCssStyles({display:"none"});let u=n.createDiv({cls:"stashpad-composer-btn-rail"});k.Platform.isMobile&&this.renderComposerNavCluster(u);let g=u.createDiv({cls:"stashpad-composer-btn-group"}),I=g.createEl("button",{cls:"stashpad-composer-btn"});(0,k.setIcon)(I,"list-end"),this.composerSplitBtn=I;let m=hi[X().splitMode].toLowerCase();I.title=s?`Split: ON \u2014 ${m} (Mod+/ to toggle, right-click to change)`:`Split into notes (Mod+/) \u2014 right-click to choose: ${m}`,s&&I.addClass("is-active"),I.onmousedown=x=>x.preventDefault(),I.onclick=x=>{x.preventDefault(),this.toggleSplit()},I.oncontextmenu=x=>{x.preventDefault();let U=new k.Menu,T=X().splitMode;["lines","paragraphs","headings"].forEach(b=>{U.addItem(M=>M.setTitle(hi[b]).setChecked(b===T).onClick(async()=>{this.plugin.settings.splitMode=b,await this.plugin.saveSettings(),this.syncComposerModeUI()}))}),U.showAtMouseEvent(x)};let C=g.createEl("button",{cls:"stashpad-composer-btn stashpad-composer-dest"});this.composerDestBtn=C,(0,k.setIcon)(C,"map-pin"),this.nextDestination&&C.createSpan({text:` ${this.destinationLabel()}`,cls:"stashpad-btn-text"}),C.title="Set destination (Mod+D)",this.nextDestination&&C.addClass("is-active"),C.onmousedown=x=>x.preventDefault(),C.onclick=x=>{x.preventDefault();let U=document.activeElement===a;this.openDestinationPicker(U)};let B=g.createEl("button",{cls:"stashpad-composer-btn"});this.composerEnterBtn=B,(0,k.setIcon)(B,i?"corner-down-left":"arrow-big-down-dash"),B.title=i?"Enter sends (click to switch to Shift+Enter)":"Shift+Enter sends (click to switch to Enter)",B.onmousedown=x=>x.preventDefault(),B.onclick=x=>{x.preventDefault(),this.modeEnterSubmits=!this.modeEnterSubmits,this.syncComposerModeUI(),a.focus()};let E=x=>{let U=a.value&&!a.value.endsWith(` +`}U&&(a.value=a.value+U,this.composerDraft=a.value,this.saveDraft(a.value),a.focus(),a.setSelectionRange(a.value.length,a.value.length))};a.addEventListener("dragover",x=>{if(!(!x.dataTransfer||!Array.from(x.dataTransfer.types).includes("Files"))){x.preventDefault(),x.stopPropagation();try{x.dataTransfer.dropEffect="copy"}catch{}}}),a.addEventListener("drop",x=>{let U=Array.from(x.dataTransfer?.files??[]);U.length!==0&&(x.preventDefault(),x.stopPropagation(),p(U))}),a.addEventListener("paste",x=>{let U=this.plugin.noteClipboard;if(U?.mode==="cut"&&U.text&&x.clipboardData?.getData("text/plain")===U.text){if(this.focusedInsideCut(U.ids)){x.preventDefault(),new F.Notice("Can't paste a cut note into the note you're cutting.");return}x.preventDefault(),this.completeCutIntoComposer();return}let T=[],b=x.clipboardData;if(b){for(let M of Array.from(b.files??[]))T.push(M);if(T.length===0){for(let M of Array.from(b.items??[]))if(M.kind==="file"){let O=M.getAsFile();O&&T.push(O)}}T.length!==0&&(x.preventDefault(),x.stopPropagation(),p(T))}});let f=n.createEl("input",{cls:"stashpad-composer-file-input",type:"file",attr:{multiple:"true"}});f.setCssStyles({display:"none"});let u=n.createDiv({cls:"stashpad-composer-btn-rail"});F.Platform.isMobile&&this.renderComposerNavCluster(u);let g=u.createDiv({cls:"stashpad-composer-btn-group"}),I=g.createEl("button",{cls:"stashpad-composer-btn"});(0,F.setIcon)(I,"list-end"),this.composerSplitBtn=I;let m=pi[X().splitMode].toLowerCase();I.title=s?`Split: ON \u2014 ${m} (Mod+/ to toggle, right-click to change)`:`Split into notes (Mod+/) \u2014 right-click to choose: ${m}`,s&&I.addClass("is-active"),I.onmousedown=x=>x.preventDefault(),I.onclick=x=>{x.preventDefault(),this.toggleSplit()},I.oncontextmenu=x=>{x.preventDefault();let U=new F.Menu,T=X().splitMode;["lines","paragraphs","headings"].forEach(b=>{U.addItem(M=>M.setTitle(pi[b]).setChecked(b===T).onClick(async()=>{this.plugin.settings.splitMode=b,await this.plugin.saveSettings(),this.syncComposerModeUI()}))}),U.showAtMouseEvent(x)};let C=g.createEl("button",{cls:"stashpad-composer-btn stashpad-composer-dest"});this.composerDestBtn=C,(0,F.setIcon)(C,"map-pin"),this.nextDestination&&C.createSpan({text:` ${this.destinationLabel()}`,cls:"stashpad-btn-text"}),C.title="Set destination (Mod+D)",this.nextDestination&&C.addClass("is-active"),C.onmousedown=x=>x.preventDefault(),C.onclick=x=>{x.preventDefault();let U=document.activeElement===a;this.openDestinationPicker(U)};let B=g.createEl("button",{cls:"stashpad-composer-btn"});this.composerEnterBtn=B,(0,F.setIcon)(B,i?"corner-down-left":"arrow-big-down-dash"),B.title=i?"Enter sends (click to switch to Shift+Enter)":"Shift+Enter sends (click to switch to Enter)",B.onmousedown=x=>x.preventDefault(),B.onclick=x=>{x.preventDefault(),this.modeEnterSubmits=!this.modeEnterSubmits,this.syncComposerModeUI(),a.focus()};let E=x=>{let U=a.value&&!a.value.endsWith(` `)?` `:"";a.value+=`${U}${x} -`,this.composerDraft=a.value},y=g.createEl("button",{cls:"stashpad-composer-btn"});(0,k.setIcon)(y,"paperclip"),y.title="Attach files",y.onmousedown=x=>x.preventDefault(),y.onclick=x=>{x.preventDefault();let U=document.activeElement===a;if(f.click(),U){let T=()=>{a.focus()};setTimeout(T,100),setTimeout(T,500)}},f.addEventListener("change",async()=>{let x=Array.from(f.files??[]);f.value="";for(let U of x){let T=await this.importAttachment(U);T&&E(T)}a.focus()}),g.append(C,y,B,I);let v=u.createEl("button",{cls:"stashpad-composer-btn stashpad-composer-rail-toggle"});(0,k.setIcon)(v,"chevron-left"),v.title="Show more composer options",u.insertBefore(v,g);let Q=x=>{u.toggleClass("is-expanded",x),v.title=x?"Hide options":"Show more composer options",(0,k.setIcon)(v,x?"chevron-right":"chevron-left")};v.onmousedown=x=>x.preventDefault(),v.onclick=x=>{x.preventDefault(),Q(!u.hasClass("is-expanded"))},Q(!1);let w=()=>n.clientWidth<(k.Platform.isMobile?360:700),F=()=>{let x=w();n.toggleClass("is-narrow",x),Q(!x)};F(),requestAnimationFrame(F);let D=new ResizeObserver(F);D.observe(n),this.composerNarrowObserver?.disconnect(),this.composerNarrowObserver=D;let H=u.createEl("button",{cls:"stashpad-composer-btn stashpad-composer-send"});H.title="Send (Enter)",(0,k.setIcon)(H,"arrow-up");let R=async()=>{let x=a.value.trim();if(!x)return;a.value="",this.composerDraft="";try{await this.saveDraft("")}catch{}try{await this.recordLastSubmitted(x)}catch{}let U=this.modeSplit??X().splitOnLines,T=this.nextDestination,b=this.nextDestinationFolder,M=!!b&&b!==this.noteFolder;this.nextDestination=null,this.nextDestinationFolder=null,this.nextDestinationLabel=null,this.autoSelectNewest=!M,this.scrollToBottomOnNextRender=!M;let O=M?{targetFolder:b}:void 0,K=T??this.focusId;if(U){let $=$t(x,X().splitMode);$.length===1?await this.createNoteUnder($[0],K,O):$.length>1&&await this.createNotesBatch($,K,O,x,M?b:this.noteFolder)}else await this.createNoteUnder(x,K,O);X().autofocusComposerAfterSend&&(this.focusComposerOnNextRender=!0,M&&this.composerInputEl?.focus())};H.onclick=()=>void R(),a.addEventListener("keydown",x=>{let U=this.modeEnterSubmits;if(x.key==="Escape"){x.preventDefault(),x.stopPropagation(),a.blur(),this.viewRoot.focus({preventScroll:!0});return}if(x.key==="ArrowUp"&&a.selectionStart===0&&a.selectionEnd===0){if(x.preventDefault(),a.blur(),this.viewRoot.focus({preventScroll:!0}),this.currentChildren.length>0){let T=this.lastCursorByFocus.get(this.focusId)??this.lastSelected,b=T?this.currentChildren.findIndex(M=>M.id===T):-1;this.cursorIdx=b>=0?b:this.currentChildren.length-1,this.selectCursor(!1)}return}x.key==="Enter"&&!x.isComposing&&(U?!x.shiftKey:x.shiftKey)&&(x.preventDefault(),x.stopPropagation(),x.stopImmediatePropagation(),R())});let L=e.createDiv({cls:"stashpad-composer-help"});this.composerHelperEl=L,L.setText(this.composerHelperText(i,s))}composerPlaceholder(e,t){return k.Platform.isMobile?t?"New notes (split on newlines)":"New note":`Type a note. ${e?"Enter":"Shift+Enter"} = send, ${e?"Shift+Enter":"Enter"} = newline${t?" (each line \u2192 a note)":""}\u2026`}composerHelperText(e,t){let i=e?"Enter":"Shift+Enter",s=e?"Shift+Enter":"Enter",n=X().bindings,o=h=>{let p=n[h];return p.primary&&p.secondary?p.preferRight?p.secondary:p.primary:p.primary||p.secondary},a=ws(o("toggleSplit")),l=ws(o("pickDestination")),c=ws(o("search")),A=this.nextDestination?` \u2022 destination: ${this.destinationLabel()}`:"";return`${i} sends \xB7 ${s} newline \xB7 ${a} split: ${t?"ON":"off"} \xB7 ${l} destination \xB7 ${c} search${A}`}destinationLabel(){if(!this.nextDestination)return"current";if(this.nextDestinationFolder)return this.nextDestinationLabel??this.nextDestinationFolder;if(this.nextDestination===S)return"Home";let e=this.tree.get(this.nextDestination);return e?this.titleForNode(e).trim():"?"}renderMobileNav(e){let t=e.createDiv({cls:"stashpad-mobile-nav"});t.createEl("button",{text:"Home"}).onclick=()=>this.navigateTo(S),t.createEl("button",{text:"Back"}).onclick=()=>this.navigateUp(),t.createEl("button",{text:"Bookmarks"}).onclick=()=>this.openBookmarks()}handleRenderedClick(e,t){let i=e.target,s=i?.closest?.(".tag");if(s){e.preventDefault(),e.stopPropagation();let a=(s.getAttribute("href")||s.textContent||"").replace(/^#/,"").trim();if(a){let l=this.app.internalPlugins?.plugins?.["global-search"],c=l?.instance?.openGlobalSearch?.bind(l.instance);c&&c(`tag:#${a}`)}return}let n=i?.closest?.(".internal-link");if(n){e.preventDefault(),e.stopPropagation();let o=n.getAttribute("data-href")||n.getAttribute("href");if(o){let a=t.file?.path||"";this.app.workspace.openLinkText(o,a,!0)}}}handleRowClick(e,t,i){let s=this.shouldAbsorbDismissTap();if(this.traceTap("click",e,t,s),s){(!this.aimedTapTargetId||Date.now()-this.aimedTapAt>Ns.AIMED_TAP_WINDOW_MS)&&(this.aimedTapTargetId=i.id,this.aimedTapAt=Date.now()),e.stopPropagation();return}this.aimedTapTargetId=null,this.cursorHasMoved=!0;let n=e.target,o=n?.closest?.(".tag");if(o){e.preventDefault(),e.stopPropagation();let A=(o.getAttribute("href")||o.textContent||"").replace(/^#/,"").trim();if(A){let h=this.app.internalPlugins?.plugins?.["global-search"],p=h?.instance?.openGlobalSearch?.bind(h.instance);p&&p(`tag:#${A}`)}return}let a=n?.closest?.(".internal-link");if(a){e.preventDefault(),e.stopPropagation();let c=a.getAttribute("data-href")||a.getAttribute("href");if(c){let A=i.file?.path||"";this.app.workspace.openLinkText(c,A,!0)}return}if(n?.tagName==="A"&&n.href)return;if(e.stopPropagation(),this.inListPicker){this.inListPicker.activeIdx=t,this.commitInListPicker();return}let l=this.selection.size===0;if(e.shiftKey&&this.lastSelected){this.cursorIdx=t;let c=this.currentChildren.findIndex(A=>A.id===this.lastSelected);if(l&&(this.firstSelectedId=this.lastSelected),c!==-1){let[A,h]=c<t?[c,t]:[t,c];for(let p=A;p<=h;p++)this.selection.add(this.currentChildren[p].id)}else this.selection.add(i.id)}else if(e.metaKey||e.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 c=this.lastSelected??[...this.selection][this.selection.size-1],A=c?this.currentChildren.findIndex(h=>h.id===c):-1;A>=0&&(this.cursorIdx=A)}else this.cursorIdx=t,l&&(this.firstSelectedId=i.id),this.selection.add(i.id);else this.mobileSelectMode?(this.cursorIdx=t,this.selection.has(i.id)?(this.selection.delete(i.id),this.firstSelectedId===i.id&&(this.firstSelectedId=null)):this.selection.add(i.id)):(this.cursorIdx=t,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 e=()=>{if(this.cursorIdx<0)return;let t=this.listEl?.querySelector(`[data-idx="${this.cursorIdx}"]`);if(!t||!this.listEl)return;let i=this.listEl,s=i.getBoundingClientRect(),n=t.getBoundingClientRect(),o=4,a=s.top+o,l=s.bottom-o;if(k.Platform.isMobile&&document.body.classList.contains("stashpad-keyboard-open")){let c=this.viewRoot?.querySelector(".stashpad-composer");c&&(l=Math.min(l,c.getBoundingClientRect().top-o))}n.top<a?i.scrollTop+=n.top-a:n.bottom>l&&(i.scrollTop+=n.bottom-l)};e(),requestAnimationFrame(e),setTimeout(e,60),setTimeout(e,200)}shouldAbsorbDismissTap(){return k.Platform.isMobile&&Date.now()<this.tapSettleUntil}traceTap(e,t,i,s){if(!this.plugin.settings.debugTrace||!this.listEl)return;let n=this.listEl,o=window.visualViewport,a=n.querySelector(`.stashpad-note[data-idx="${i}"]`)?.getBoundingClientRect();this.plugin.trace(`tap:${e}`,{absorbed:s,clientY:Math.round(t.clientY),clientX:Math.round(t.clientX),idx:i,rowTop:a?Math.round(a.top):null,listTop:Math.round(n.getBoundingClientRect().top),listScrollTop:Math.round(n.scrollTop),listScrollH:Math.round(n.scrollHeight),listClientH:Math.round(n.clientHeight),innerH:window.innerHeight,vvHeight:o?Math.round(o.height):null,vvOffsetTop:o?Math.round(o.offsetTop):null,tapSettleInMs:Math.max(0,this.tapSettleUntil-Date.now()),kbOpen:document.body.classList.contains("stashpad-keyboard-open")})}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(e){let t=this.currentChildren[this.cursorIdx];if(t){if(this.cursorHasMoved=!0,!e)this.selection.clear(),this.selection.add(t.id),this.firstSelectedId=t.id,this.lastSelected=t.id;else{let i=this.firstSelectedId??t.id,s=this.currentChildren.findIndex(n=>n.id===i);if(s===-1)this.selection.add(t.id),this.firstSelectedId=t.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=t.id}this.repaintSelectionClasses(),this.revealCursorRow(),this.stampSelectedCursor(),this.plugin.notifyStashpadSelectionChanged()}}repaintSelectionClasses(){if(!this.listEl)return;let e=!!this.plugin.settings.autoExpandCursorRow,t=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)),a||this.cursorExpandOverride.delete(o),s.classList.toggle("is-cursor-expanded",e&&a&&this.cursorHasMoved&&!this.cursorExpandOverride.has(o)),s.classList.toggle("is-pick-target",n===t)})}revealRowAt(e){if(!this.listEl)return;let t=this.listEl.querySelector(`.stashpad-note[data-idx="${e}"]`);if(!t)return;let i=t.getBoundingClientRect(),s=this.listEl.getBoundingClientRect();(i.top<s.top||i.bottom>s.bottom)&&t.scrollIntoView({block:"nearest",behavior:"auto"})}getActionTargets(){if(this.selection.size>0)return[...this.selection].map(t=>this.tree.get(t)).filter(t=>!!t&&!!t.file);let e=this.currentChildren[this.cursorIdx];return e?[e]:[]}cmdLockSelectionHideName(){return this.cmdLockSelection({hideName:!0})}async cmdLockSelection(e={}){if(!this.plugin.encryption?.isConfigured?.()){new k.Notice("Set up encryption first (Settings \u2192 Stashpad \u2192 Encryption).");return}let t=this.getActionTargets();if(t.length===0)return;let i=new Set(t.map(l=>l.id)),s=new Set((this.plugin.settings.lockedSubtrees??[]).map(l=>l.rootId).filter(l=>!!l)),n=t.filter(l=>{if(s.has(l.id))return!1;let c=l.parent;for(;c;){if(i.has(c))return!1;c=this.tree.get(c)?.parent??null}return!0});if(n.length===0){new k.Notice("Nothing to lock (already locked).");return}let o=0,a=[];for(let l of n){let c=this.order.getOrder(this.noteFolder,l.parent??S),A=c.indexOf(l.id),h=A>0?c[A-1]:null,p=await this.plugin.lockNoteSubtree(this.noteFolder,l.id,h,{silent:!0,hideTitle:e.hideName});p&&(o++,a.push({rootId:l.id,prevSibling:h,blob:p.blobPath}),await this.log.append({type:"lock",id:l.id}))}if(o>0){this.selection.clear(),this.lastSelected=null,this.render();let l=this.noteFolder;this.plugin.getUndoStack(l).push({label:`Lock ${o} stash${o===1?"":"es"}`,undo:async()=>{for(let c of a)try{await this.plugin.unlockBundleAt(c.blob,{silent:!0})}catch{}this.render()},redo:async()=>{for(let c of a){let A=await this.plugin.lockNoteSubtree(l,c.rootId,c.prevSibling,{silent:!0,hideTitle:e.hideName});A&&(c.blob=A.blobPath)}this.render()}}),this.plugin.notifications.show({message:`Locked ${o} stash${o===1?"":"es"} \u2014 undo to unlock.`,kind:"success",category:"system",folder:this.noteFolder,actions:[{label:"All encrypted",onClick:()=>void He(this.plugin,"encrypted")}]})}}async cmdMoveToArchive(){let e=this.getActionTargets();if(e.length===0)return;let t=(this.noteFolder??"").replace(/\/+$/,"");if(Ks(t)){new k.Notice("These notes are already in an archive.",6e3);return}this.archiveSources(e,Dt(t))}async archiveSources(e,t){let i=this.noteFolder,s=t.replace(/\/+$/,""),n=s.replace(/\/archive$/,""),o=this.plugin.archiveEncryptFor(n);try{await this.app.vault.adapter.exists(s)||await this.app.vault.createFolder(s)}catch{}if(!o){let p=new Set(e.map(B=>B.id)),f=e.filter(B=>{let E=B.parent;for(;E;){if(p.has(E))return!1;E=this.tree.get(E)?.parent??null}return!0});if(f.length===0)return;let u=[],g=new Set,I=B=>{if(!g.has(B.id)){g.add(B.id),B.file&&u.push(B.file);for(let E of this.tree.getChildren(B.id))I(E)}};for(let B of f)I(B);let m=[];for(let B of u){let E=B.path,y=B.name,v=y.lastIndexOf("."),Q=v>0?y.slice(0,v):y,w=v>0?y.slice(v):"",F=`${s}/${y}`;for(let D=1;await this.app.vault.adapter.exists(F);D++)F=`${s}/${Q}-${D}${w}`;try{await this.app.fileManager.renameFile(B,F),m.push({from:E,to:F})}catch(D){console.warn("[Stashpad] plaintext archive move failed",E,D)}}if(this.selection.clear(),this.lastSelected=null,this.tree.rebuild(i),this.render(),m.length>0)for(let B of f)await this.log.append({type:"archive",id:B.id,payload:{to:s,encrypted:!1}});let C=s.split("/").pop()||s;this.plugin.notifications.show({message:`Moved ${m.length} note${m.length===1?"":"s"} \u2192 plaintext archive \u201C${C}\u201D (de-indexed, not encrypted). Undo to bring ${m.length===1?"it":"them"} back.`,kind:"success",category:"system",folder:i,actions:[{label:"All archived",onClick:()=>void He(this.plugin,"archived")}]}),this.plugin.getUndoStack(i).push({label:`Archive (plaintext, ${f.length})`,undo:async()=>{for(let B of m){let E=this.app.vault.getAbstractFileByPath(B.to);if(E instanceof k.TFile)try{await this.app.fileManager.renameFile(E,B.from)}catch(y){console.warn("[Stashpad] plaintext archive undo failed",B.to,y)}}this.tree.rebuild(i),this.render()},redo:async()=>{for(let B of m){let E=this.app.vault.getAbstractFileByPath(B.from);if(E instanceof k.TFile)try{await this.app.fileManager.renameFile(E,B.to)}catch(y){console.warn("[Stashpad] plaintext archive redo failed",B.from,y)}}this.tree.rebuild(i),this.render()}});return}if(!this.plugin.encryption?.isConfigured?.()){new k.Notice(`Archiving here encrypts the notes ("Encrypt archived notes" is on for \u201C${n.split("/").pop()}\u201D), but encryption isn't set up yet (Settings \u2192 Stashpad \u2192 Encryption). Set it up \u2014 or turn that toggle off for a plaintext archive.`,9e3);return}let a=new Set(e.map(p=>p.id)),l=e.filter(p=>{let f=p.parent;for(;f;){if(a.has(f))return!1;f=this.tree.get(f)?.parent??null}return!0});if(l.length===0)return;let c=l.map(p=>p.id),A=[];for(let p of l){let f=this.order.getOrder(i,p.parent??S),u=f.indexOf(p.id),g=u>0?f[u-1]:null,I=await this.plugin.lockNoteSubtree(i,p.id,g,{silent:!0,blobFolder:t});I&&(A.push(I.blobPath),await this.log.append({type:"archive",id:p.id,payload:{to:t,encrypted:!0}}))}if(A.length===0)return;this.selection.clear(),this.lastSelected=null,this.tree.rebuild(i),this.render();let h=t.split("/").pop()||t;this.plugin.notifications.show({message:`Archived ${A.length} note${A.length===1?"":"s"} \u2192 \u201C${h}\u201D. Undo to bring ${A.length===1?"it":"them"} back.`,kind:"success",category:"system",folder:i,actions:[{label:"All archived",onClick:()=>void He(this.plugin,"archived")}]}),this.plugin.getUndoStack(i).push({label:`Archive (${A.length})`,undo:async()=>{let p=[];for(let f of A)try{await this.plugin.unlockBundleAt(f,{silent:!0,destFolder:i})||p.push(f)}catch(u){p.push(f),console.warn("[Stashpad] archive undo failed",f,u)}A=p,p.length&&new k.Notice(`Undo incomplete: ${p.length} archived item${p.length===1?"":"s"} couldn't be restored (they're still in the archive). Try again, or restore from the Archived view.`,8e3),this.tree.rebuild(i),this.render()},redo:async()=>{A=[];for(let p of c){let f=await this.plugin.lockNoteSubtree(i,p,null,{silent:!0,blobFolder:t});f&&A.push(f.blobPath)}this.tree.rebuild(i),this.render()}})}async cmdEncryptDelete(){if(!this.plugin.encryption?.isConfigured?.()){new k.Notice("Set up encryption first (Settings \u2192 Stashpad \u2192 Encryption).");return}let e=this.getActionTargets();if(e.length===0)return;let t=new Set(e.map(n=>n.id)),i=e.filter(n=>{let o=n.parent;for(;o;){if(t.has(o))return!1;o=this.tree.get(o)?.parent??null}return!0});if(i.length===0)return;let s=i.length;new j(this.app,`Encrypt & delete ${s} note${s===1?"":"s"}?`,[`The selected note${s===1?"":"s"} (and any children) will be encrypted and moved to Stashpad's encrypted trash.`,"","\u2022 The readable copy is permanently removed from the folder.",`\u2022 You can restore ${s===1?"it":"them"} later from the encrypted trash \u2014 you'll need your encryption password.`,`\u2022 If you lose your password, ${s===1?"it's":"they're"} gone for good.`].join(` -`),"Encrypt & delete",async n=>{n&&await this.secureDeleteSources(i)}).open()}async secureDeleteSources(e){if(!this.plugin.encryption?.isConfigured?.()){new k.Notice("Set up encryption first (Settings \u2192 Stashpad \u2192 Encryption).");return}let t=new Set(e.map(a=>a.id)),i=e.filter(a=>{let l=a.parent;for(;l;){if(t.has(l))return!1;l=this.tree.get(l)?.parent??null}return!0});if(i.length===0)return;let s=this.noteFolder,n=i.map(a=>a.id),o=[];for(let a of n){let l=await this.plugin.encryptDeleteSubtree(s,a);l&&o.push(l)}o.length!==0&&(this.selection.clear(),this.lastSelected=null,this.tree.rebuild(s),this.render(),this.plugin.notifications.show({message:`Securely deleted ${o.length} note${o.length===1?"":"s"} \u2192 encrypted trash. Undo to bring ${o.length===1?"it":"them"} back.`,kind:"success",category:"system",folder:s,actions:[{label:"Open Trash",onClick:()=>this.plugin.openEncryptedTrash()}]}),this.plugin.getUndoStack(s).push({label:`Secure delete (${o.length})`,undo:async()=>{let a=[];for(let l of o)try{await this.plugin.restoreDeletedAt(l,{silent:!0})||a.push(l)}catch(c){a.push(l),console.warn("[Stashpad] secure-delete undo failed",l,c)}o=a,a.length&&new k.Notice(`Undo incomplete: ${a.length} deleted item${a.length===1?"":"s"} couldn't be restored (still in Trash). Try again, or restore from the Trash view.`,8e3),this.tree.rebuild(s),this.render()},redo:async()=>{o=[];for(let a of n){let l=await this.plugin.encryptDeleteSubtree(s,a);l&&o.push(l)}this.tree.rebuild(s),this.render()}}))}async plaintextDeleteToStashpadTrash(e){let t=new Set(e.map(a=>a.id)),i=e.filter(a=>{let l=a.parent;for(;l;){if(t.has(l))return!1;l=this.tree.get(l)?.parent??null}return!0});if(i.length===0)return;let s=this.noteFolder,n=i.map(a=>a.id),o=[];for(let a of n){let l=await this.plugin.plaintextDeleteSubtree(s,a);l&&(o.push(l),await this.log.append({type:"delete",id:a,payload:{to:"trash",bundle:l}}))}o.length!==0&&(this.selection.clear(),this.lastSelected=null,this.tree.rebuild(s),this.render(),this.plugin.notifications.show({message:`Deleted ${o.length} note${o.length===1?"":"s"} \u2192 Trash. Undo to bring ${o.length===1?"it":"them"} back.`,kind:"success",category:"system",folder:s,actions:[{label:"Open Trash",onClick:()=>this.plugin.openEncryptedTrash()}]}),this.plugin.getUndoStack(s).push({label:`Delete (${o.length})`,undo:async()=>{let a=[];for(let l of o)try{await this.plugin.restoreDeletedAt(l,{silent:!0})||a.push(l)}catch(c){a.push(l),console.warn("[Stashpad] plaintext-trash undo failed",l,c)}o=a,a.length&&new k.Notice(`Undo incomplete: ${a.length} deleted item${a.length===1?"":"s"} couldn't be restored (still in Trash). Try again, or restore from the Trash view.`,8e3),this.tree.rebuild(s),this.render()},redo:async()=>{o=[];for(let a of n){let l=await this.plugin.plaintextDeleteSubtree(s,a);l&&o.push(l)}this.tree.rebuild(s),this.render()}}))}async cmdUnlockAll(){if(!this.plugin.encryption?.isConfigured?.()){new k.Notice("Set up encryption first (Settings \u2192 Stashpad \u2192 Encryption).");return}let e=new Set,t=new Set,i=this.getActionTargets().map(n=>n.id);for(;i.length;){let n=i.pop();if(!t.has(n)){t.add(n);for(let o of this.tree.getChildren(n))i.push(o.id)}}for(let n of t)for(let o of this.plugin.lockedSubtreesFor(this.noteFolder,n))e.add(o.blob);if(e.size===0){let n=(this.tree.get(this.focusId)??this.tree.getRoot()).id;for(let o of this.plugin.lockedSubtreesFor(this.noteFolder,n))e.add(o.blob)}if(e.size===0){new k.Notice("No locked notes to unlock here.");return}if(!await this.plugin.ensureFolderUnlocked(this.noteFolder))return;let s=0;for(let n of e)try{await this.plugin.unlockBundleAt(n,{silent:!0})&&s++}catch(o){console.warn("[Stashpad] batch unlock skipped",n,o)}s>0&&(this.selection.clear(),this.lastSelected=null,this.render(),this.plugin.notifications.show({message:`Unlocked ${s} stash${s===1?"":"es"}.`,kind:"success",category:"system",folder:this.noteFolder}))}syncComposerModeUI(){let e=this.modeSplit??X().splitOnLines,t=this.modeEnterSubmits;if(this.composerSplitBtn){this.composerSplitBtn.toggleClass("is-active",e);let i=hi[X().splitMode].toLowerCase();this.composerSplitBtn.title=e?`Split: ON \u2014 ${i} (Mod+/ to toggle, right-click to change)`:`Split into notes (Mod+/) \u2014 right-click to choose: ${i}`}this.composerEnterBtn&&((0,k.setIcon)(this.composerEnterBtn,t?"corner-down-left":"arrow-big-down-dash"),this.composerEnterBtn.title=t?"Enter sends (click to switch to Shift+Enter)":"Shift+Enter sends (click to switch to Enter)"),this.composerInputEl&&(this.composerInputEl.placeholder=this.composerPlaceholder(t,e)),this.composerHelperEl&&this.composerHelperEl.setText(this.composerHelperText(t,e))}refreshDestButton(){let e=this.composerDestBtn;e&&(e.empty(),(0,k.setIcon)(e,"map-pin"),this.nextDestination&&e.createSpan({text:` ${this.destinationLabel()}`,cls:"stashpad-btn-text"}),e.toggleClass("is-active",!!this.nextDestination)),this.syncComposerModeUI()}toggleSplit(){let e=this.modeSplit??X().splitOnLines;this.modeSplit=!e,this.syncComposerModeUI(),this.composerInputEl?.focus()}openDestinationPicker(e=!1){let t=!1;new at(this.app,this.tree,i=>this.titleForNode(i),{mode:"pick",placeholder:"Send next note(s) under which note?",allowCreate:!0,onPick:async i=>{if(t=!0,i.crossFolder){let s=i.crossId??i.id.replace(/^cross:/,"");this.nextDestination=s,this.nextDestinationFolder=i.crossFolder;let n=i.crossFolder.split("/").pop()||i.crossFolder,o=s===S?"Home":(i.crossFile?.basename??"note").replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ");this.nextDestinationLabel=`${n} \u25B8 ${o}`,this.refreshDestButton(),this.composerInputEl?.focus();return}this.nextDestination=i.id,this.nextDestinationFolder=null,this.nextDestinationLabel=null,this.refreshDestButton(),this.composerInputEl?.focus()},onCreate:async i=>{t=!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(),excludedFolderNotes:this.excludedSearchFolders().length>0?()=>this.collectExcludedFolderNotes():void 0,onClose:()=>{e&&!t&&this.composerInputEl?.focus()}}).open()}collectCrossFolderDestinations(){let e=this.collectCrossFolderNotes(),t=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(!t.includes(o))continue;this.app.metadataCache.getFileCache(n)?.frontmatter?.id===S&&i.set(o,n)}return[...t.map(n=>({file:i.get(n),folder:n,id:S,title:`Home \u2014 ${n.split("/").pop()||n}`,body:""})),...e]}openSearchInParentModal(){let e=this.focusId,t=s=>{if(s===e)return!0;let n=new Set,o=this.tree.get(s);for(;o&&o.id!==S&&!n.has(o.id);){if(n.add(o.id),o.parent===e||o.id===e)return!0;if(!o.parent)return!1;o=this.tree.get(o.parent)}return e===S},i=new Proxy(this.tree,{get:(s,n)=>n==="getRoot"?()=>s.get(e)??s.getRoot():n==="getChildren"?o=>s.getChildren(o):s[n]});new at(this.app,i,s=>this.titleForNode(s),{mode:"search",placeholder:`Search in "${this.titleForNode(this.tree.get(e)??this.tree.getRoot()).trim()}"\u2026`,allowCreate:!1,onPick:s=>{s.node&&t(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 e=new at(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 at(this.app,this.tree,n=>this.titleForNode(n),{mode:"pick",placeholder:`Create "${s}" under which note?`,allowCreate:!1,crossFolderNotes:()=>this.collectCrossFolderDestinations(),excludedFolderNotes:this.excludedSearchFolders().length>0?()=>this.collectExcludedFolderNotes():void 0,folderResults:()=>this.plugin.discoverStashpadFolders().filter(n=>n!==this.noteFolder),localFolder:this.noteFolder,onPick:async n=>{let o=n.crossFolder?n.crossId??n.id.replace(/^cross:/,""):n.node?.id,a=n.crossFolder??this.noteFolder;if(!o)return;let l=(this.plugin.settings.folder||"Stashpad").trim().replace(/^\/+|\/+$/g,"")||"Stashpad",c=this.app.workspace,A=c.getLeaf("tab");await A.setViewState({type:z,active:!0,state:{focusId:o,folderOverride:a===l?null:a}}),c.revealLeaf(A);let h=A.view;if(h&&typeof h.createNoteUnder=="function"){let p=await h.createNoteUnder(s,o);p&&typeof h.navigateTo=="function"&&h.navigateTo(p)}}}).open()},onPick:i=>{if(i.kind==="folder-open"&&i.folder){this.openFolderInNewTab(i.folder);return}let s=this.plugin.settings.searchOpensInNewTab!==!1;if(i.locked){let n=i.locked.parentId??S;s?this.openNoteInNewTab(this.noteFolder,n):this.navigateTo(n);return}if(i.crossFolder&&i.crossFile){let n=i.crossId??i.id.replace(/^cross:/,"");s?this.openNoteInNewTab(i.crossFolder,n):this.switchToFolderAndFocus(i.crossFolder,n);return}if(i.node){let n=this.plugin.settings.searchOpensInContext!==!1,o=n?i.node.parent??S:i.node.id,a=n?i.node.id:void 0;s?this.openNoteInNewTab(this.noteFolder,o,a):(a&&(this.pendingCursorId=a),this.navigateTo(o))}},crossFolderNotes:()=>this.collectCrossFolderDestinations(),excludedFolderNotes:this.excludedSearchFolders().length>0?()=>this.collectExcludedFolderNotes():void 0,folderResults:()=>this.plugin.discoverStashpadFolders().filter(i=>i!==this.noteFolder),showFilterChips:!0,localFolder:this.noteFolder,lockedNotes:()=>this.plugin.lockedSubtreesInFolder(this.noteFolder),hideLockedTitles:!1});this.openSearchInstance=e;let t=e.onClose.bind(e);e.onClose=()=>{t(),this.openSearchInstance===e&&(this.openSearchInstance=null)},e.open()}excludedSearchFolders(){let e=new Set(this.plugin.searchableFolders(this.noteFolder));return this.plugin.discoverStashpadFolders().filter(t=>t!==this.noteFolder&&!e.has(t))}collectExcludedFolderNotes(){let e=this.excludedSearchFolders();if(!e.length)return[];let t=this.collectCrossFolderNotes(e),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===S&&i.set(o,n)}return[...e.map(n=>({file:i.get(n),folder:n,id:S,title:`Home \u2014 ${n.split("/").pop()||n}`,body:""})),...t]}collectCrossFolderNotes(e){let t=[],i=(e??this.plugin.searchableFolders(this.noteFolder)).filter(o=>o!==this.noteFolder);if(!i.length)return t;let s=new Set(i),n=new Map;for(let o of this.app.vault.getMarkdownFiles()){let a=o.parent?.path?.replace(/\/+$/,"")??"";if(!s.has(a))continue;let l=n.get(a);l||(l=[],n.set(a,l)),l.push(o)}for(let o of i){let a=n.get(o)??[],l=new Map;for(let c of a){let A=this.app.metadataCache.getFileCache(c)?.frontmatter;typeof A?.id=="string"&&l.set(A.id,c)}for(let c of a){let A=this.app.metadataCache.getFileCache(c)?.frontmatter,h=typeof A?.id=="string"?A.id:"";if(!h||h===S)continue;let p=c.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," "),f,u=A?.parent??null;if(u&&u!==S){let g=l.get(u);g&&(f=g.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," "))}t.push({file:c,folder:o,id:h,title:p,body:"",parentBlurb:f,parentId:u??null})}}return t}async switchToFolderAndFocus(e,t){await this.setFolderOverride(e),this.tree.get(t)&&this.navigateTo(t)}async cmdOutdent(){let e=this.getActionTargets();if(!e.length)return;let t=[],i=[],s=[];for(let o of e){let a=o.parent?this.tree.get(o.parent):null;if(!a||a.id===S){i.push(o.id);continue}let l=a.parent??S;s.push({id:o.id,path:o.file?.path??"",oldParent:o.parent??null,newParent:l}),await this.changeParent(o,l,{record:!1,silentSuccess:!0}),t.push(o)}if(t.length===0){new k.Notice(i.length?"Already at the top level.":"Nothing to outdent.");return}let n=this.noteFolder;if(this.plugin.getUndoStack(n).push({label:`Outdent (${t.length})`,undo:async()=>{for(let o of s){let a=this.fileForNote(o.id,o.path);a&&await this.app.fileManager.processFrontMatter(a,l=>{l.parent=o.oldParent??S})}this.tree.rebuild(n),this.render()},redo:async()=>{for(let o of s){let a=this.fileForNote(o.id,o.path);a&&await this.app.fileManager.processFrontMatter(a,l=>{l.parent=o.newParent})}this.tree.rebuild(n),this.render()}}),this.render(),this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Outdented",nodes:t,suffix:i.length?`(${i.length} already at root)`:void 0}),kind:"success",category:"move",affectedIds:t.map(o=>o.id),folder:this.noteFolder}),this.plugin.settings.autoNavOnMoveOut&&t.length>0){let o=t[0].parent;o!=null&&t.every(l=>l.parent===o)&&o!==this.focusId&&this.navigateTo(o)}}cmdSetColor(){let e=this.getActionTargets();if(!e.length)return;let t=new Set(e.map(n=>this.colorForNode(n)??"")),i=t.size===1&&Array.from(t)[0]||null,s=this.plugin.settings.customPalette??[];new jt(this.app,i,s,async(n,o)=>{let a=[];for(let h of e)if(h.file){a.push({id:h.id,path:h.file.path,was:this.colorForNode(h)??null});try{await this.app.fileManager.processFrontMatter(h.file,p=>{n?p.color=n:delete p.color})}catch(p){new k.Notice(`Couldn't set color for ${h.id}: ${p.message}`)}}if(o.addToPalette&&typeof n=="string"){let h=[...this.plugin.settings.customPalette??[]],p=n.toLowerCase();h.some(f=>f.toLowerCase()===p)||(h.push(n),this.plugin.settings.customPalette=h,await this.plugin.persistSettingsQuiet(),await this.log.append({type:"palette_color_add",id:S,payload:{color:n}}))}this.render();let l=this.noteFolder,c=n,A=async h=>{for(let p of h){let f=this.fileForNote(p.id,p.path);if(f)try{this.markFmSelfWrite(f.path),await this.app.fileManager.processFrontMatter(f,u=>{p.col?u.color=p.col:delete u.color})}catch{}}this.tree.rebuild(l),this.render()};this.plugin.getUndoStack(l).push({label:a.length===1?"Color change":`Color change (${a.length})`,undo:()=>A(a.map(h=>({id:h.id,path:h.path,col:h.was}))),redo:()=>A(a.map(h=>({id:h.id,path:h.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:S,payload:{color:n}}),o}).open()}cmdMovePicker(){let e=this.getActionTargets();e.length&&new at(this.app,this.tree,t=>this.titleForNode(t),{mode:"pick",placeholder:"Move to which note?",allowCreate:!0,onPick:async t=>{if(t.crossFolder){let o=t.crossId??t.id.replace(/^cross:/,"");await this.moveAcrossFolders(e,t.crossFolder,o),this.selection.clear(),this.render();return}let i=t.id,s=new Map(e.map(o=>[o.id,this.tree.getChildren(o.id).length])),n=[];for(let o of e)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 t=>{let i=await this.createNoteUnder(t,this.focusId);if(!i)return;let s=new Map(e.map(o=>[o.id,this.tree.getChildren(o.id).length])),n=[];for(let o of e)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(),excludedFolderNotes:this.excludedSearchFolders().length>0?()=>this.collectExcludedFolderNotes():void 0,showFilterChips:!0}).open()}async moveAcrossFolders(e,t,i){if(!e.length)return;let s=(t||"").replace(/\/+$/,"");if(!s){new k.Notice("Target folder is empty");return}let n=[],o=new Set;for(let p of this.app.vault.getMarkdownFiles())(p.parent?.path?.replace(/\/+$/,"")??"")===s&&o.add(p.path);let a=(p,f)=>{if(!p.file)return;let u=p.file,g=`${s}/${u.name}`;if(o.has(g)){let I=u.basename.match(/^(.*)(-[a-z0-9]{4,12})$/),m=I?I[1]:u.basename,C=I?I[2]:"";for(let B=1;B<1e3;B++){let E=`${m}-${B}${C}.md`,y=`${s}/${E}`;if(!o.has(y)){g=y;break}}}o.add(g),n.push({id:p.id,file:u,oldPath:u.path,newPath:g,oldParent:p.parent,isRoot:f});for(let I of this.tree.getChildren(p.id))a(I,!1)};for(let p of e)a(p,!0);if(!n.length)return;await this.ensureFolder(s);for(let p of n)try{await this.app.fileManager.renameFile(p.file,p.newPath),p.isRoot&&await this.app.fileManager.processFrontMatter(p.file,f=>{f.parent=i}),await this.log.append({type:"parent_change",id:p.id,payload:{from:p.oldParent,to:p.isRoot?i:p.oldParent,crossFolder:{from:this.noteFolder,to:s}}})}catch(f){new k.Notice(`Move failed for ${p.id}: ${f.message}`)}if(X().writeRecoveryLinks){let p=this.noteFolder;window.setTimeout(()=>{Pi(this.app,p),Pi(this.app,s)},350)}let l=this.titleList(e);this.tree.rebuild(this.noteFolder);let c=i===S?"Open home":"Open parent",A=Math.max(0,n.length-e.length),h=e.length===1?`Moved ${l}${A>0?` and its ${A} nested note${A===1?"":"s"}`:""} \u2192 \`${s}\``:`Moved ${l}${A>0?` (${A} nested)`:""} \u2192 \`${s}\``;this.plugin.notifications.show({message:h,kind:"success",category:"move",duration:0,affectedIds:e.map(p=>p.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 p of n){let f=this.app.vault.getAbstractFileByPath(p.newPath);if(f)try{await this.app.fileManager.renameFile(f,p.oldPath),p.isRoot&&await this.app.fileManager.processFrontMatter(f,u=>{u.parent=p.oldParent})}catch{}}this.tree.rebuild(this.noteFolder),this.render()},redo:async()=>{for(let p of n){let f=this.app.vault.getAbstractFileByPath(p.oldPath);if(f)try{await this.app.fileManager.renameFile(f,p.newPath),p.isRoot&&await this.app.fileManager.processFrontMatter(f,u=>{u.parent=i})}catch{}}this.tree.rebuild(this.noteFolder),this.render()}})}nextPickableIdx(e,t){for(let i=e+t;i>=0&&i<this.currentChildren.length;i+=t){let s=this.currentChildren[i];if(s&&!this.selection.has(s.id))return i}return e}cmdInListPicker(){if(this.currentChildren.length===0)return;let e=this.cursorIdx>0?this.cursorIdx-1:0;if(this.currentChildren[e]&&this.selection.has(this.currentChildren[e].id)){let n=this.nextPickableIdx(e,-1);e=n!==e?n:this.nextPickableIdx(e,1)}this.inListPicker={activeIdx:e};let t=X().bindings.move,i=ws(t.primary||t.secondary||"M");new k.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 e=this.currentChildren[this.inListPicker.activeIdx];if(this.inListPicker=null,!e){this.render();return}let t=this.getActionTargets().filter(a=>a.id!==e.id),i=new Map(t.map(a=>[a.id,this.tree.getChildren(a.id).length])),s=[];for(let a of t)await this.changeParent(a,e.id,{silentSuccess:!0})&&s.push(a);if(this.notifyBatchMove(s,e.id,i),this.plugin.settings.autoNavOnMoveIn){this.navigateTo(e.id);return}this.selection.clear(),this.cursorIdx=-1,this.pendingFocusIds=[e.id],this.render({kind:"follow-cursor"});let n=this.selectionGuardKey,o=()=>{if(this.selectionGuardKey!==n)return;let a=this.currentChildren.findIndex(l=>l.id===e.id);a<0||this.selection.size===1&&this.selection.has(e.id)&&this.cursorIdx===a||(this.selection.clear(),this.selection.add(e.id),this.cursorIdx=a,this.render({kind:"follow-cursor"}))};setTimeout(o,120),setTimeout(o,400)}async cmdMerge(){let e=this.getActionTargets();if(e.length<2){new k.Notice("Select 2+ notes to merge.");return}e.sort((I,m)=>(I.created||"").localeCompare(m.created||""));let t=e[0];if(!t.file)return;let i=t.file.path,s=await this.app.vault.read(t.file),n=await this.snapshotNotes(e.slice(1),!1),o=[],a=[];for(let I of e){if(!I.file)continue;let m=await this.app.vault.cachedRead(I.file);a.push(this.stripFrontmatter(m).trim())}let l=a.map(I=>I.trim()).filter(Boolean).join(` -`),c=await this.app.vault.read(t.file),A=c.startsWith("---")?c.indexOf(` ----`,3):-1;if(c.startsWith("---")&&A<0){this.plugin.notifications.show({message:"Can't merge \u2014 the kept note's frontmatter is malformed (no closing ---).",kind:"warning",category:"merge",folder:this.noteFolder});return}let h=c.startsWith("---")?A+4:0,f=`${c.slice(0,h)} +`,this.composerDraft=a.value},y=g.createEl("button",{cls:"stashpad-composer-btn"});(0,F.setIcon)(y,"paperclip"),y.title="Attach files",y.onmousedown=x=>x.preventDefault(),y.onclick=x=>{x.preventDefault();let U=document.activeElement===a;if(f.click(),U){let T=()=>{a.focus()};setTimeout(T,100),setTimeout(T,500)}},f.addEventListener("change",async()=>{let x=Array.from(f.files??[]);f.value="";for(let U of x){let T=await this.importAttachment(U);T&&E(T)}a.focus()}),g.append(C,y,B,I);let v=u.createEl("button",{cls:"stashpad-composer-btn stashpad-composer-rail-toggle"});(0,F.setIcon)(v,"chevron-left"),v.title="Show more composer options",u.insertBefore(v,g);let Q=x=>{u.toggleClass("is-expanded",x),v.title=x?"Hide options":"Show more composer options",(0,F.setIcon)(v,x?"chevron-right":"chevron-left")};v.onmousedown=x=>x.preventDefault(),v.onclick=x=>{x.preventDefault(),Q(!u.hasClass("is-expanded"))},Q(!1);let w=()=>n.clientWidth<(F.Platform.isMobile?360:700),k=()=>{let x=w();n.toggleClass("is-narrow",x),Q(!x)};k(),requestAnimationFrame(k);let D=new ResizeObserver(k);D.observe(n),this.composerNarrowObserver?.disconnect(),this.composerNarrowObserver=D;let H=u.createEl("button",{cls:"stashpad-composer-btn stashpad-composer-send"});H.title="Send (Enter)",(0,F.setIcon)(H,"arrow-up");let R=async()=>{let x=a.value.trim();if(!x)return;a.value="",this.composerDraft="";try{await this.saveDraft("")}catch{}try{await this.recordLastSubmitted(x)}catch{}let U=this.modeSplit??X().splitOnLines,T=this.nextDestination,b=this.nextDestinationFolder,M=!!b&&b!==this.noteFolder;this.nextDestination=null,this.nextDestinationFolder=null,this.nextDestinationLabel=null,this.autoSelectNewest=!M,this.scrollToBottomOnNextRender=!M;let O=M?{targetFolder:b}:void 0,K=T??this.focusId;if(U){let Y=$t(x,X().splitMode);Y.length===1?await this.createNoteUnder(Y[0],K,O):Y.length>1&&await this.createNotesBatch(Y,K,O,x,M?b:this.noteFolder)}else await this.createNoteUnder(x,K,O);X().autofocusComposerAfterSend&&(this.focusComposerOnNextRender=!0,M&&this.composerInputEl?.focus())};H.onclick=()=>void R(),a.addEventListener("keydown",x=>{let U=this.modeEnterSubmits;if(x.key==="Escape"){x.preventDefault(),x.stopPropagation(),a.blur(),this.viewRoot.focus({preventScroll:!0});return}if(x.key==="ArrowUp"&&a.selectionStart===0&&a.selectionEnd===0){if(x.preventDefault(),a.blur(),this.viewRoot.focus({preventScroll:!0}),this.currentChildren.length>0){let T=this.lastCursorByFocus.get(this.focusId)??this.lastSelected,b=T?this.currentChildren.findIndex(M=>M.id===T):-1;this.cursorIdx=b>=0?b:this.currentChildren.length-1,this.selectCursor(!1)}return}x.key==="Enter"&&!x.isComposing&&(U?!x.shiftKey:x.shiftKey)&&(x.preventDefault(),x.stopPropagation(),x.stopImmediatePropagation(),R())});let L=e.createDiv({cls:"stashpad-composer-help"});this.composerHelperEl=L,L.setText(this.composerHelperText(i,s))}composerPlaceholder(e,t){return F.Platform.isMobile?t?"New notes (split on newlines)":"New note":`Type a note. ${e?"Enter":"Shift+Enter"} = send, ${e?"Shift+Enter":"Enter"} = newline${t?" (each line \u2192 a note)":""}\u2026`}composerHelperText(e,t){let i=e?"Enter":"Shift+Enter",s=e?"Shift+Enter":"Enter",n=X().bindings,o=h=>{let p=n[h];return p.primary&&p.secondary?p.preferRight?p.secondary:p.primary:p.primary||p.secondary},a=vs(o("toggleSplit")),l=vs(o("pickDestination")),c=vs(o("search")),d=this.nextDestination?` \u2022 destination: ${this.destinationLabel()}`:"";return`${i} sends \xB7 ${s} newline \xB7 ${a} split: ${t?"ON":"off"} \xB7 ${l} destination \xB7 ${c} search${d}`}destinationLabel(){if(!this.nextDestination)return"current";if(this.nextDestinationFolder)return this.nextDestinationLabel??this.nextDestinationFolder;if(this.nextDestination===S)return"Home";let e=this.tree.get(this.nextDestination);return e?this.titleForNode(e).trim():"?"}renderMobileNav(e){let t=e.createDiv({cls:"stashpad-mobile-nav"});t.createEl("button",{text:"Home"}).onclick=()=>this.navigateTo(S),t.createEl("button",{text:"Back"}).onclick=()=>this.navigateUp(),t.createEl("button",{text:"Bookmarks"}).onclick=()=>this.openBookmarks()}handleRenderedClick(e,t){let i=e.target,s=i?.closest?.(".tag");if(s){e.preventDefault(),e.stopPropagation();let a=(s.getAttribute("href")||s.textContent||"").replace(/^#/,"").trim();if(a){let l=this.app.internalPlugins?.plugins?.["global-search"],c=l?.instance?.openGlobalSearch?.bind(l.instance);c&&c(`tag:#${a}`)}return}let n=i?.closest?.(".internal-link");if(n){e.preventDefault(),e.stopPropagation();let o=n.getAttribute("data-href")||n.getAttribute("href");if(o){let a=t.file?.path||"";this.app.workspace.openLinkText(o,a,!0)}}}handleRowClick(e,t,i){let s=this.shouldAbsorbDismissTap();if(this.traceTap("click",e,t,s),s){(!this.aimedTapTargetId||Date.now()-this.aimedTapAt>Ms.AIMED_TAP_WINDOW_MS)&&(this.aimedTapTargetId=i.id,this.aimedTapAt=Date.now()),e.stopPropagation();return}this.aimedTapTargetId=null,this.cursorHasMoved=!0;let n=e.target,o=n?.closest?.(".tag");if(o){e.preventDefault(),e.stopPropagation();let d=(o.getAttribute("href")||o.textContent||"").replace(/^#/,"").trim();if(d){let h=this.app.internalPlugins?.plugins?.["global-search"],p=h?.instance?.openGlobalSearch?.bind(h.instance);p&&p(`tag:#${d}`)}return}let a=n?.closest?.(".internal-link");if(a){e.preventDefault(),e.stopPropagation();let c=a.getAttribute("data-href")||a.getAttribute("href");if(c){let d=i.file?.path||"";this.app.workspace.openLinkText(c,d,!0)}return}if(n?.tagName==="A"&&n.href)return;if(e.stopPropagation(),this.inListPicker){this.inListPicker.activeIdx=t,this.commitInListPicker();return}let l=this.selection.size===0;if(e.shiftKey&&this.lastSelected){this.cursorIdx=t;let c=this.currentChildren.findIndex(d=>d.id===this.lastSelected);if(l&&(this.firstSelectedId=this.lastSelected),c!==-1){let[d,h]=c<t?[c,t]:[t,c];for(let p=d;p<=h;p++)this.selection.add(this.currentChildren[p].id)}else this.selection.add(i.id)}else if(e.metaKey||e.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 c=this.lastSelected??[...this.selection][this.selection.size-1],d=c?this.currentChildren.findIndex(h=>h.id===c):-1;d>=0&&(this.cursorIdx=d)}else this.cursorIdx=t,l&&(this.firstSelectedId=i.id),this.selection.add(i.id);else this.mobileSelectMode?(this.cursorIdx=t,this.selection.has(i.id)?(this.selection.delete(i.id),this.firstSelectedId===i.id&&(this.firstSelectedId=null)):this.selection.add(i.id)):(this.cursorIdx=t,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 e=()=>{if(this.cursorIdx<0)return;let t=this.listEl?.querySelector(`[data-idx="${this.cursorIdx}"]`);if(!t||!this.listEl)return;let i=this.listEl,s=i.getBoundingClientRect(),n=t.getBoundingClientRect(),o=4,a=s.top+o,l=s.bottom-o;if(F.Platform.isMobile&&document.body.classList.contains("stashpad-keyboard-open")){let c=this.viewRoot?.querySelector(".stashpad-composer");c&&(l=Math.min(l,c.getBoundingClientRect().top-o))}n.top<a?i.scrollTop+=n.top-a:n.bottom>l&&(i.scrollTop+=n.bottom-l)};e(),requestAnimationFrame(e),setTimeout(e,60),setTimeout(e,200)}shouldAbsorbDismissTap(){return F.Platform.isMobile&&Date.now()<this.tapSettleUntil}traceTap(e,t,i,s){if(!this.plugin.settings.debugTrace||!this.listEl)return;let n=this.listEl,o=window.visualViewport,a=n.querySelector(`.stashpad-note[data-idx="${i}"]`)?.getBoundingClientRect();this.plugin.trace(`tap:${e}`,{absorbed:s,clientY:Math.round(t.clientY),clientX:Math.round(t.clientX),idx:i,rowTop:a?Math.round(a.top):null,listTop:Math.round(n.getBoundingClientRect().top),listScrollTop:Math.round(n.scrollTop),listScrollH:Math.round(n.scrollHeight),listClientH:Math.round(n.clientHeight),innerH:window.innerHeight,vvHeight:o?Math.round(o.height):null,vvOffsetTop:o?Math.round(o.offsetTop):null,tapSettleInMs:Math.max(0,this.tapSettleUntil-Date.now()),kbOpen:document.body.classList.contains("stashpad-keyboard-open")})}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(e){let t=this.currentChildren[this.cursorIdx];if(t){if(this.cursorHasMoved=!0,!e)this.selection.clear(),this.selection.add(t.id),this.firstSelectedId=t.id,this.lastSelected=t.id;else{let i=this.firstSelectedId??t.id,s=this.currentChildren.findIndex(n=>n.id===i);if(s===-1)this.selection.add(t.id),this.firstSelectedId=t.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=t.id}this.repaintSelectionClasses(),this.revealCursorRow(),this.stampSelectedCursor(),this.plugin.notifyStashpadSelectionChanged()}}repaintSelectionClasses(){if(!this.listEl)return;let e=!!this.plugin.settings.autoExpandCursorRow,t=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)),a||this.cursorExpandOverride.delete(o),s.classList.toggle("is-cursor-expanded",e&&a&&this.cursorHasMoved&&!this.cursorExpandOverride.has(o)),s.classList.toggle("is-pick-target",n===t)})}revealRowAt(e){if(!this.listEl)return;let t=this.listEl.querySelector(`.stashpad-note[data-idx="${e}"]`);if(!t)return;let i=t.getBoundingClientRect(),s=this.listEl.getBoundingClientRect();(i.top<s.top||i.bottom>s.bottom)&&t.scrollIntoView({block:"nearest",behavior:"auto"})}getActionTargets(){if(this.selection.size>0)return[...this.selection].map(t=>this.tree.get(t)).filter(t=>!!t&&!!t.file);let e=this.currentChildren[this.cursorIdx];return e?[e]:[]}cmdLockSelectionHideName(){return this.cmdLockSelection({hideName:!0})}async cmdLockSelection(e={}){if(!this.plugin.encryption?.isConfigured?.()){new F.Notice("Set up encryption first (Settings \u2192 Stashpad \u2192 Encryption).");return}let t=this.getActionTargets();if(t.length===0)return;let i=new Set(t.map(l=>l.id)),s=new Set((this.plugin.settings.lockedSubtrees??[]).map(l=>l.rootId).filter(l=>!!l)),n=t.filter(l=>{if(s.has(l.id))return!1;let c=l.parent;for(;c;){if(i.has(c))return!1;c=this.tree.get(c)?.parent??null}return!0});if(n.length===0){new F.Notice("Nothing to lock (already locked).");return}let o=0,a=[];for(let l of n){let c=this.order.getOrder(this.noteFolder,l.parent??S),d=c.indexOf(l.id),h=d>0?c[d-1]:null,p=await this.plugin.lockNoteSubtree(this.noteFolder,l.id,h,{silent:!0,hideTitle:e.hideName});p&&(o++,a.push({rootId:l.id,prevSibling:h,blob:p.blobPath}),await this.log.append({type:"lock",id:l.id}))}if(o>0){this.selection.clear(),this.lastSelected=null,this.render();let l=this.noteFolder;this.plugin.getUndoStack(l).push({label:`Lock ${o} stash${o===1?"":"es"}`,undo:async()=>{for(let c of a)try{await this.plugin.unlockBundleAt(c.blob,{silent:!0})}catch{}this.render()},redo:async()=>{for(let c of a){let d=await this.plugin.lockNoteSubtree(l,c.rootId,c.prevSibling,{silent:!0,hideTitle:e.hideName});d&&(c.blob=d.blobPath)}this.render()}}),this.plugin.notifications.show({message:`Locked ${o} stash${o===1?"":"es"} \u2014 undo to unlock.`,kind:"success",category:"system",folder:this.noteFolder,actions:[{label:"All encrypted",onClick:()=>void He(this.plugin,"encrypted")}]})}}async cmdMoveToArchive(){let e=this.getActionTargets();if(e.length===0)return;let t=(this.noteFolder??"").replace(/\/+$/,"");if(qs(t)){new F.Notice("These notes are already in an archive.",6e3);return}this.archiveSources(e,Dt(t))}async archiveSources(e,t){let i=this.noteFolder,s=t.replace(/\/+$/,""),n=s.replace(/\/archive$/,""),o=this.plugin.archiveEncryptFor(n);try{await this.app.vault.adapter.exists(s)||await this.app.vault.createFolder(s)}catch{}if(!o){let p=new Set(e.map(B=>B.id)),f=e.filter(B=>{let E=B.parent;for(;E;){if(p.has(E))return!1;E=this.tree.get(E)?.parent??null}return!0});if(f.length===0)return;let u=[],g=new Set,I=B=>{if(!g.has(B.id)){g.add(B.id),B.file&&u.push(B.file);for(let E of this.tree.getChildren(B.id))I(E)}};for(let B of f)I(B);let m=[];for(let B of u){let E=B.path,y=B.name,v=y.lastIndexOf("."),Q=v>0?y.slice(0,v):y,w=v>0?y.slice(v):"",k=`${s}/${y}`;for(let D=1;await this.app.vault.adapter.exists(k);D++)k=`${s}/${Q}-${D}${w}`;try{await this.app.fileManager.renameFile(B,k),m.push({from:E,to:k})}catch(D){console.warn("[Stashpad] plaintext archive move failed",E,D)}}if(this.selection.clear(),this.lastSelected=null,this.tree.rebuild(i),this.render(),m.length>0)for(let B of f)await this.log.append({type:"archive",id:B.id,payload:{to:s,encrypted:!1}});let C=s.split("/").pop()||s;this.plugin.notifications.show({message:`Moved ${m.length} note${m.length===1?"":"s"} \u2192 plaintext archive \u201C${C}\u201D (de-indexed, not encrypted). Undo to bring ${m.length===1?"it":"them"} back.`,kind:"success",category:"system",folder:i,actions:[{label:"All archived",onClick:()=>void He(this.plugin,"archived")}]}),this.plugin.getUndoStack(i).push({label:`Archive (plaintext, ${f.length})`,undo:async()=>{for(let B of m){let E=this.app.vault.getAbstractFileByPath(B.to);if(E instanceof F.TFile)try{await this.app.fileManager.renameFile(E,B.from)}catch(y){console.warn("[Stashpad] plaintext archive undo failed",B.to,y)}}this.tree.rebuild(i),this.render()},redo:async()=>{for(let B of m){let E=this.app.vault.getAbstractFileByPath(B.from);if(E instanceof F.TFile)try{await this.app.fileManager.renameFile(E,B.to)}catch(y){console.warn("[Stashpad] plaintext archive redo failed",B.from,y)}}this.tree.rebuild(i),this.render()}});return}if(!this.plugin.encryption?.isConfigured?.()){new F.Notice(`Archiving here encrypts the notes ("Encrypt archived notes" is on for \u201C${n.split("/").pop()}\u201D), but encryption isn't set up yet (Settings \u2192 Stashpad \u2192 Encryption). Set it up \u2014 or turn that toggle off for a plaintext archive.`,9e3);return}let a=new Set(e.map(p=>p.id)),l=e.filter(p=>{let f=p.parent;for(;f;){if(a.has(f))return!1;f=this.tree.get(f)?.parent??null}return!0});if(l.length===0)return;let c=l.map(p=>p.id),d=[];for(let p of l){let f=this.order.getOrder(i,p.parent??S),u=f.indexOf(p.id),g=u>0?f[u-1]:null,I=await this.plugin.lockNoteSubtree(i,p.id,g,{silent:!0,blobFolder:t});I&&(d.push(I.blobPath),await this.log.append({type:"archive",id:p.id,payload:{to:t,encrypted:!0}}))}if(d.length===0)return;this.selection.clear(),this.lastSelected=null,this.tree.rebuild(i),this.render();let h=t.split("/").pop()||t;this.plugin.notifications.show({message:`Archived ${d.length} note${d.length===1?"":"s"} \u2192 \u201C${h}\u201D. Undo to bring ${d.length===1?"it":"them"} back.`,kind:"success",category:"system",folder:i,actions:[{label:"All archived",onClick:()=>void He(this.plugin,"archived")}]}),this.plugin.getUndoStack(i).push({label:`Archive (${d.length})`,undo:async()=>{let p=[];for(let f of d)try{await this.plugin.unlockBundleAt(f,{silent:!0,destFolder:i})||p.push(f)}catch(u){p.push(f),console.warn("[Stashpad] archive undo failed",f,u)}d=p,p.length&&new F.Notice(`Undo incomplete: ${p.length} archived item${p.length===1?"":"s"} couldn't be restored (they're still in the archive). Try again, or restore from the Archived view.`,8e3),this.tree.rebuild(i),this.render()},redo:async()=>{d=[];for(let p of c){let f=await this.plugin.lockNoteSubtree(i,p,null,{silent:!0,blobFolder:t});f&&d.push(f.blobPath)}this.tree.rebuild(i),this.render()}})}async cmdEncryptDelete(){if(!this.plugin.encryption?.isConfigured?.()){new F.Notice("Set up encryption first (Settings \u2192 Stashpad \u2192 Encryption).");return}let e=this.getActionTargets();if(e.length===0)return;let t=new Set(e.map(n=>n.id)),i=e.filter(n=>{let o=n.parent;for(;o;){if(t.has(o))return!1;o=this.tree.get(o)?.parent??null}return!0});if(i.length===0)return;let s=i.length;new j(this.app,`Encrypt & delete ${s} note${s===1?"":"s"}?`,[`The selected note${s===1?"":"s"} (and any children) will be encrypted and moved to Stashpad's encrypted trash.`,"","\u2022 The readable copy is permanently removed from the folder.",`\u2022 You can restore ${s===1?"it":"them"} later from the encrypted trash \u2014 you'll need your encryption password.`,`\u2022 If you lose your password, ${s===1?"it's":"they're"} gone for good.`].join(` +`),"Encrypt & delete",async n=>{n&&await this.secureDeleteSources(i)}).open()}async secureDeleteSources(e){if(!this.plugin.encryption?.isConfigured?.()){new F.Notice("Set up encryption first (Settings \u2192 Stashpad \u2192 Encryption).");return}let t=new Set(e.map(a=>a.id)),i=e.filter(a=>{let l=a.parent;for(;l;){if(t.has(l))return!1;l=this.tree.get(l)?.parent??null}return!0});if(i.length===0)return;let s=this.noteFolder,n=i.map(a=>a.id),o=[];for(let a of n){let l=await this.plugin.encryptDeleteSubtree(s,a);l&&o.push(l)}o.length!==0&&(this.selection.clear(),this.lastSelected=null,this.tree.rebuild(s),this.render(),this.plugin.notifications.show({message:`Securely deleted ${o.length} note${o.length===1?"":"s"} \u2192 encrypted trash. Undo to bring ${o.length===1?"it":"them"} back.`,kind:"success",category:"system",folder:s,actions:[{label:"Open Trash",onClick:()=>this.plugin.openEncryptedTrash()}]}),this.plugin.getUndoStack(s).push({label:`Secure delete (${o.length})`,undo:async()=>{let a=[];for(let l of o)try{await this.plugin.restoreDeletedAt(l,{silent:!0})||a.push(l)}catch(c){a.push(l),console.warn("[Stashpad] secure-delete undo failed",l,c)}o=a,a.length&&new F.Notice(`Undo incomplete: ${a.length} deleted item${a.length===1?"":"s"} couldn't be restored (still in Trash). Try again, or restore from the Trash view.`,8e3),this.tree.rebuild(s),this.render()},redo:async()=>{o=[];for(let a of n){let l=await this.plugin.encryptDeleteSubtree(s,a);l&&o.push(l)}this.tree.rebuild(s),this.render()}}))}async plaintextDeleteToStashpadTrash(e){let t=new Set(e.map(a=>a.id)),i=e.filter(a=>{let l=a.parent;for(;l;){if(t.has(l))return!1;l=this.tree.get(l)?.parent??null}return!0});if(i.length===0)return;let s=this.noteFolder,n=i.map(a=>a.id),o=[];for(let a of n){let l=await this.plugin.plaintextDeleteSubtree(s,a);l&&(o.push(l),await this.log.append({type:"delete",id:a,payload:{to:"trash",bundle:l}}))}o.length!==0&&(this.selection.clear(),this.lastSelected=null,this.tree.rebuild(s),this.render(),this.plugin.notifications.show({message:`Deleted ${o.length} note${o.length===1?"":"s"} \u2192 Trash. Undo to bring ${o.length===1?"it":"them"} back.`,kind:"success",category:"system",folder:s,actions:[{label:"Open Trash",onClick:()=>this.plugin.openEncryptedTrash()}]}),this.plugin.getUndoStack(s).push({label:`Delete (${o.length})`,undo:async()=>{let a=[];for(let l of o)try{await this.plugin.restoreDeletedAt(l,{silent:!0})||a.push(l)}catch(c){a.push(l),console.warn("[Stashpad] plaintext-trash undo failed",l,c)}o=a,a.length&&new F.Notice(`Undo incomplete: ${a.length} deleted item${a.length===1?"":"s"} couldn't be restored (still in Trash). Try again, or restore from the Trash view.`,8e3),this.tree.rebuild(s),this.render()},redo:async()=>{o=[];for(let a of n){let l=await this.plugin.plaintextDeleteSubtree(s,a);l&&o.push(l)}this.tree.rebuild(s),this.render()}}))}async cmdUnlockAll(){if(!this.plugin.encryption?.isConfigured?.()){new F.Notice("Set up encryption first (Settings \u2192 Stashpad \u2192 Encryption).");return}let e=new Set,t=new Set,i=this.getActionTargets().map(n=>n.id);for(;i.length;){let n=i.pop();if(!t.has(n)){t.add(n);for(let o of this.tree.getChildren(n))i.push(o.id)}}for(let n of t)for(let o of this.plugin.lockedSubtreesFor(this.noteFolder,n))e.add(o.blob);if(e.size===0){let n=(this.tree.get(this.focusId)??this.tree.getRoot()).id;for(let o of this.plugin.lockedSubtreesFor(this.noteFolder,n))e.add(o.blob)}if(e.size===0){new F.Notice("No locked notes to unlock here.");return}if(!await this.plugin.ensureFolderUnlocked(this.noteFolder))return;let s=0;for(let n of e)try{await this.plugin.unlockBundleAt(n,{silent:!0})&&s++}catch(o){console.warn("[Stashpad] batch unlock skipped",n,o)}s>0&&(this.selection.clear(),this.lastSelected=null,this.render(),this.plugin.notifications.show({message:`Unlocked ${s} stash${s===1?"":"es"}.`,kind:"success",category:"system",folder:this.noteFolder}))}syncComposerModeUI(){let e=this.modeSplit??X().splitOnLines,t=this.modeEnterSubmits;if(this.composerSplitBtn){this.composerSplitBtn.toggleClass("is-active",e);let i=pi[X().splitMode].toLowerCase();this.composerSplitBtn.title=e?`Split: ON \u2014 ${i} (Mod+/ to toggle, right-click to change)`:`Split into notes (Mod+/) \u2014 right-click to choose: ${i}`}this.composerEnterBtn&&((0,F.setIcon)(this.composerEnterBtn,t?"corner-down-left":"arrow-big-down-dash"),this.composerEnterBtn.title=t?"Enter sends (click to switch to Shift+Enter)":"Shift+Enter sends (click to switch to Enter)"),this.composerInputEl&&(this.composerInputEl.placeholder=this.composerPlaceholder(t,e)),this.composerHelperEl&&this.composerHelperEl.setText(this.composerHelperText(t,e))}refreshDestButton(){let e=this.composerDestBtn;e&&(e.empty(),(0,F.setIcon)(e,"map-pin"),this.nextDestination&&e.createSpan({text:` ${this.destinationLabel()}`,cls:"stashpad-btn-text"}),e.toggleClass("is-active",!!this.nextDestination)),this.syncComposerModeUI()}toggleSplit(){let e=this.modeSplit??X().splitOnLines;this.modeSplit=!e,this.syncComposerModeUI(),this.composerInputEl?.focus()}openDestinationPicker(e=!1){let t=!1;new at(this.app,this.tree,i=>this.titleForNode(i),{mode:"pick",placeholder:"Send next note(s) under which note?",allowCreate:!0,onPick:async i=>{if(t=!0,i.crossFolder){let s=i.crossId??i.id.replace(/^cross:/,"");this.nextDestination=s,this.nextDestinationFolder=i.crossFolder;let n=i.crossFolder.split("/").pop()||i.crossFolder,o=s===S?"Home":(i.crossFile?.basename??"note").replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ");this.nextDestinationLabel=`${n} \u25B8 ${o}`,this.refreshDestButton(),this.composerInputEl?.focus();return}this.nextDestination=i.id,this.nextDestinationFolder=null,this.nextDestinationLabel=null,this.refreshDestButton(),this.composerInputEl?.focus()},onCreate:async i=>{t=!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(),excludedFolderNotes:this.excludedSearchFolders().length>0?()=>this.collectExcludedFolderNotes():void 0,onClose:()=>{e&&!t&&this.composerInputEl?.focus()}}).open()}collectCrossFolderDestinations(){let e=this.collectCrossFolderNotes(),t=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(!t.includes(o))continue;this.app.metadataCache.getFileCache(n)?.frontmatter?.id===S&&i.set(o,n)}return[...t.map(n=>({file:i.get(n),folder:n,id:S,title:`Home \u2014 ${n.split("/").pop()||n}`,body:""})),...e]}openSearchInParentModal(){let e=this.focusId,t=s=>{if(s===e)return!0;let n=new Set,o=this.tree.get(s);for(;o&&o.id!==S&&!n.has(o.id);){if(n.add(o.id),o.parent===e||o.id===e)return!0;if(!o.parent)return!1;o=this.tree.get(o.parent)}return e===S},i=new Proxy(this.tree,{get:(s,n)=>n==="getRoot"?()=>s.get(e)??s.getRoot():n==="getChildren"?o=>s.getChildren(o):s[n]});new at(this.app,i,s=>this.titleForNode(s),{mode:"search",placeholder:`Search in "${this.titleForNode(this.tree.get(e)??this.tree.getRoot()).trim()}"\u2026`,allowCreate:!1,onPick:s=>{s.node&&t(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 e=new at(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 at(this.app,this.tree,n=>this.titleForNode(n),{mode:"pick",placeholder:`Create "${s}" under which note?`,allowCreate:!1,crossFolderNotes:()=>this.collectCrossFolderDestinations(),excludedFolderNotes:this.excludedSearchFolders().length>0?()=>this.collectExcludedFolderNotes():void 0,folderResults:()=>this.plugin.discoverStashpadFolders().filter(n=>n!==this.noteFolder),localFolder:this.noteFolder,onPick:async n=>{let o=n.crossFolder?n.crossId??n.id.replace(/^cross:/,""):n.node?.id,a=n.crossFolder??this.noteFolder;if(!o)return;let l=(this.plugin.settings.folder||"Stashpad").trim().replace(/^\/+|\/+$/g,"")||"Stashpad",c=this.app.workspace,d=c.getLeaf("tab");await d.setViewState({type:$,active:!0,state:{focusId:o,folderOverride:a===l?null:a}}),c.revealLeaf(d);let h=d.view;if(h&&typeof h.createNoteUnder=="function"){let p=await h.createNoteUnder(s,o);p&&typeof h.navigateTo=="function"&&h.navigateTo(p)}}}).open()},onPick:i=>{if(i.kind==="folder-open"&&i.folder){this.openFolderInNewTab(i.folder);return}let s=this.plugin.settings.searchOpensInNewTab!==!1;if(i.locked){let n=i.locked.parentId??S;s?this.openNoteInNewTab(this.noteFolder,n):this.navigateTo(n);return}if(i.crossFolder&&i.crossFile){let n=i.crossId??i.id.replace(/^cross:/,"");s?this.openNoteInNewTab(i.crossFolder,n):this.switchToFolderAndFocus(i.crossFolder,n);return}if(i.node){let n=this.plugin.settings.searchOpensInContext!==!1,o=n?i.node.parent??S:i.node.id,a=n?i.node.id:void 0;s?this.openNoteInNewTab(this.noteFolder,o,a):(a&&(this.pendingCursorId=a),this.navigateTo(o))}},crossFolderNotes:()=>this.collectCrossFolderDestinations(),excludedFolderNotes:this.excludedSearchFolders().length>0?()=>this.collectExcludedFolderNotes():void 0,folderResults:()=>this.plugin.discoverStashpadFolders().filter(i=>i!==this.noteFolder),showFilterChips:!0,localFolder:this.noteFolder,lockedNotes:()=>this.plugin.lockedSubtreesInFolder(this.noteFolder),hideLockedTitles:!1});this.openSearchInstance=e;let t=e.onClose.bind(e);e.onClose=()=>{t(),this.openSearchInstance===e&&(this.openSearchInstance=null)},e.open()}excludedSearchFolders(){let e=new Set(this.plugin.searchableFolders(this.noteFolder));return this.plugin.discoverStashpadFolders().filter(t=>t!==this.noteFolder&&!e.has(t))}collectExcludedFolderNotes(){let e=this.excludedSearchFolders();if(!e.length)return[];let t=this.collectCrossFolderNotes(e),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===S&&i.set(o,n)}return[...e.map(n=>({file:i.get(n),folder:n,id:S,title:`Home \u2014 ${n.split("/").pop()||n}`,body:""})),...t]}collectCrossFolderNotes(e){let t=[],i=(e??this.plugin.searchableFolders(this.noteFolder)).filter(o=>o!==this.noteFolder);if(!i.length)return t;let s=new Set(i),n=new Map;for(let o of this.app.vault.getMarkdownFiles()){let a=o.parent?.path?.replace(/\/+$/,"")??"";if(!s.has(a))continue;let l=n.get(a);l||(l=[],n.set(a,l)),l.push(o)}for(let o of i){let a=n.get(o)??[],l=new Map;for(let c of a){let d=this.app.metadataCache.getFileCache(c)?.frontmatter;typeof d?.id=="string"&&l.set(d.id,c)}for(let c of a){let d=this.app.metadataCache.getFileCache(c)?.frontmatter,h=typeof d?.id=="string"?d.id:"";if(!h||h===S)continue;let p=c.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," "),f,u=d?.parent??null;if(u&&u!==S){let g=l.get(u);g&&(f=g.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," "))}t.push({file:c,folder:o,id:h,title:p,body:"",parentBlurb:f,parentId:u??null})}}return t}async switchToFolderAndFocus(e,t){await this.setFolderOverride(e),this.tree.get(t)&&this.navigateTo(t)}async cmdOutdent(){let e=this.getActionTargets();if(!e.length)return;let t=[],i=[],s=[];for(let o of e){let a=o.parent?this.tree.get(o.parent):null;if(!a||a.id===S){i.push(o.id);continue}let l=a.parent??S;s.push({id:o.id,path:o.file?.path??"",oldParent:o.parent??null,newParent:l}),await this.changeParent(o,l,{record:!1,silentSuccess:!0}),t.push(o)}if(t.length===0){new F.Notice(i.length?"Already at the top level.":"Nothing to outdent.");return}let n=this.noteFolder;if(this.plugin.getUndoStack(n).push({label:`Outdent (${t.length})`,undo:async()=>{for(let o of s){let a=this.fileForNote(o.id,o.path);a&&await this.app.fileManager.processFrontMatter(a,l=>{l.parent=o.oldParent??S})}this.tree.rebuild(n),this.render()},redo:async()=>{for(let o of s){let a=this.fileForNote(o.id,o.path);a&&await this.app.fileManager.processFrontMatter(a,l=>{l.parent=o.newParent})}this.tree.rebuild(n),this.render()}}),this.render(),this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Outdented",nodes:t,suffix:i.length?`(${i.length} already at root)`:void 0}),kind:"success",category:"move",affectedIds:t.map(o=>o.id),folder:this.noteFolder}),this.plugin.settings.autoNavOnMoveOut&&t.length>0){let o=t[0].parent;o!=null&&t.every(l=>l.parent===o)&&o!==this.focusId&&this.navigateTo(o)}}cmdSetColor(){let e=this.getActionTargets();if(!e.length)return;let t=new Set(e.map(n=>this.colorForNode(n)??"")),i=t.size===1&&Array.from(t)[0]||null,s=this.plugin.settings.customPalette??[];new jt(this.app,i,s,async(n,o)=>{let a=[];for(let h of e)if(h.file){a.push({id:h.id,path:h.file.path,was:this.colorForNode(h)??null});try{await this.app.fileManager.processFrontMatter(h.file,p=>{n?p.color=n:delete p.color})}catch(p){new F.Notice(`Couldn't set color for ${h.id}: ${p.message}`)}}if(o.addToPalette&&typeof n=="string"){let h=[...this.plugin.settings.customPalette??[]],p=n.toLowerCase();h.some(f=>f.toLowerCase()===p)||(h.push(n),this.plugin.settings.customPalette=h,await this.plugin.persistSettingsQuiet(),await this.log.append({type:"palette_color_add",id:S,payload:{color:n}}))}this.render();let l=this.noteFolder,c=n,d=async h=>{for(let p of h){let f=this.fileForNote(p.id,p.path);if(f)try{this.markFmSelfWrite(f.path),await this.app.fileManager.processFrontMatter(f,u=>{p.col?u.color=p.col:delete u.color})}catch{}}this.tree.rebuild(l),this.render()};this.plugin.getUndoStack(l).push({label:a.length===1?"Color change":`Color change (${a.length})`,undo:()=>d(a.map(h=>({id:h.id,path:h.path,col:h.was}))),redo:()=>d(a.map(h=>({id:h.id,path:h.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:S,payload:{color:n}}),o}).open()}cmdMovePicker(){let e=this.getActionTargets();e.length&&new at(this.app,this.tree,t=>this.titleForNode(t),{mode:"pick",placeholder:"Move to which note?",allowCreate:!0,onPick:async t=>{if(t.crossFolder){let o=t.crossId??t.id.replace(/^cross:/,"");await this.moveAcrossFolders(e,t.crossFolder,o),this.selection.clear(),this.render();return}let i=t.id,s=new Map(e.map(o=>[o.id,this.tree.getChildren(o.id).length])),n=[];for(let o of e)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 t=>{let i=await this.createNoteUnder(t,this.focusId);if(!i)return;let s=new Map(e.map(o=>[o.id,this.tree.getChildren(o.id).length])),n=[];for(let o of e)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(),excludedFolderNotes:this.excludedSearchFolders().length>0?()=>this.collectExcludedFolderNotes():void 0,showFilterChips:!0}).open()}async moveAcrossFolders(e,t,i){if(!e.length)return;let s=(t||"").replace(/\/+$/,"");if(!s){new F.Notice("Target folder is empty");return}let n=[],o=new Set;for(let p of this.app.vault.getMarkdownFiles())(p.parent?.path?.replace(/\/+$/,"")??"")===s&&o.add(p.path);let a=(p,f)=>{if(!p.file)return;let u=p.file,g=`${s}/${u.name}`;if(o.has(g)){let I=u.basename.match(/^(.*)(-[a-z0-9]{4,12})$/),m=I?I[1]:u.basename,C=I?I[2]:"";for(let B=1;B<1e3;B++){let E=`${m}-${B}${C}.md`,y=`${s}/${E}`;if(!o.has(y)){g=y;break}}}o.add(g),n.push({id:p.id,file:u,oldPath:u.path,newPath:g,oldParent:p.parent,isRoot:f});for(let I of this.tree.getChildren(p.id))a(I,!1)};for(let p of e)a(p,!0);if(!n.length)return;await this.ensureFolder(s);for(let p of n)try{await this.app.fileManager.renameFile(p.file,p.newPath),p.isRoot&&await this.app.fileManager.processFrontMatter(p.file,f=>{f.parent=i}),await this.log.append({type:"parent_change",id:p.id,payload:{from:p.oldParent,to:p.isRoot?i:p.oldParent,crossFolder:{from:this.noteFolder,to:s}}})}catch(f){new F.Notice(`Move failed for ${p.id}: ${f.message}`)}if(X().writeRecoveryLinks){let p=this.noteFolder;window.setTimeout(()=>{Hi(this.app,p),Hi(this.app,s)},350)}let l=this.titleList(e);this.tree.rebuild(this.noteFolder);let c=i===S?"Open home":"Open parent",d=Math.max(0,n.length-e.length),h=e.length===1?`Moved ${l}${d>0?` and its ${d} nested note${d===1?"":"s"}`:""} \u2192 \`${s}\``:`Moved ${l}${d>0?` (${d} nested)`:""} \u2192 \`${s}\``;this.plugin.notifications.show({message:h,kind:"success",category:"move",duration:0,affectedIds:e.map(p=>p.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 p of n){let f=this.app.vault.getAbstractFileByPath(p.newPath);if(f)try{await this.app.fileManager.renameFile(f,p.oldPath),p.isRoot&&await this.app.fileManager.processFrontMatter(f,u=>{u.parent=p.oldParent})}catch{}}this.tree.rebuild(this.noteFolder),this.render()},redo:async()=>{for(let p of n){let f=this.app.vault.getAbstractFileByPath(p.oldPath);if(f)try{await this.app.fileManager.renameFile(f,p.newPath),p.isRoot&&await this.app.fileManager.processFrontMatter(f,u=>{u.parent=i})}catch{}}this.tree.rebuild(this.noteFolder),this.render()}})}nextPickableIdx(e,t){for(let i=e+t;i>=0&&i<this.currentChildren.length;i+=t){let s=this.currentChildren[i];if(s&&!this.selection.has(s.id))return i}return e}cmdInListPicker(){if(this.currentChildren.length===0)return;let e=this.cursorIdx>0?this.cursorIdx-1:0;if(this.currentChildren[e]&&this.selection.has(this.currentChildren[e].id)){let n=this.nextPickableIdx(e,-1);e=n!==e?n:this.nextPickableIdx(e,1)}this.inListPicker={activeIdx:e};let t=X().bindings.move,i=vs(t.primary||t.secondary||"M");new F.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 e=this.currentChildren[this.inListPicker.activeIdx];if(this.inListPicker=null,!e){this.render();return}let t=this.getActionTargets().filter(a=>a.id!==e.id),i=new Map(t.map(a=>[a.id,this.tree.getChildren(a.id).length])),s=[];for(let a of t)await this.changeParent(a,e.id,{silentSuccess:!0})&&s.push(a);if(this.notifyBatchMove(s,e.id,i),this.plugin.settings.autoNavOnMoveIn||this.openParentInBackgroundTab(e.id),this.plugin.settings.autoNavOnMoveIn){this.navigateTo(e.id);return}this.selection.clear(),this.cursorIdx=-1,this.pendingFocusIds=[e.id],this.render({kind:"follow-cursor"});let n=this.selectionGuardKey,o=()=>{if(this.selectionGuardKey!==n)return;let a=this.currentChildren.findIndex(l=>l.id===e.id);a<0||this.selection.size===1&&this.selection.has(e.id)&&this.cursorIdx===a||(this.selection.clear(),this.selection.add(e.id),this.cursorIdx=a,this.render({kind:"follow-cursor"}))};setTimeout(o,120),setTimeout(o,400)}async cmdMerge(){let e=this.getActionTargets();if(e.length<2){new F.Notice("Select 2+ notes to merge.");return}e.sort((I,m)=>(I.created||"").localeCompare(m.created||""));let t=e[0];if(!t.file)return;let i=t.file.path,s=await this.app.vault.read(t.file),n=await this.snapshotNotes(e.slice(1),!1),o=[],a=[];for(let I of e){if(!I.file)continue;let m=await this.app.vault.cachedRead(I.file);a.push(this.stripFrontmatter(m).trim())}let l=a.map(I=>I.trim()).filter(Boolean).join(` +`),c=await this.app.vault.read(t.file),d=c.startsWith("---")?c.indexOf(` +---`,3):-1;if(c.startsWith("---")&&d<0){this.plugin.notifications.show({message:"Can't merge \u2014 the kept note's frontmatter is malformed (no closing ---).",kind:"warning",category:"merge",folder:this.noteFolder});return}let h=c.startsWith("---")?d+4:0,f=`${c.slice(0,h)} ${l} -`;await this.app.vault.modify(t.file,f);for(let I=1;I<e.length;I++){let m=e[I];if(m.file){for(let C of this.tree.getChildren(m.id)){let B=C.parent,E=C.id===t.id?m.parent??S:t.id;await this.changeParent(C,E,{record:!1})&&C.file&&o.push({childId:C.id,childPath:C.file.path,oldParent:B,newParent:E})}await this.app.fileManager.trashFile(m.file),await this.log.append({type:"delete",id:m.id,payload:{mergedInto:t.id}})}}this.selection.clear(),this.cursorIdx=-1,this.pendingFocusIds=[t.id];let u=this.titleForNode(t);this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Merged",nodes:e,destination:`\u2192 kept "${u}"`}),kind:"success",category:"merge",affectedIds:e.map(I=>I.id),folder:this.noteFolder}),this.tree.rebuild(this.noteFolder),this.render({kind:"follow-cursor"});{let I=t.id,m=this.selectionGuardKey,C=()=>{if(this.selectionGuardKey!==m||this.selection.has(I))return;let B=this.currentChildren.findIndex(E=>E.id===I);B<0||(this.selection.add(I),this.cursorIdx=B,this.render({kind:"follow-cursor"}))};setTimeout(C,120),setTimeout(C,400)}let g=this.noteFolder;this.plugin.getUndoStack(g).push({label:`Merge ${e.length} notes`,undo:async()=>{await this.restoreSnapshots(n,e.map(m=>m.id));let I=this.fileForNote(t.id,i);I&&await this.app.vault.modify(I,s);for(let m of o){let C=this.fileForNote(m.childId,m.childPath);C&&await this.app.fileManager.processFrontMatter(C,B=>{B.parent=m.oldParent})}this.pendingFocusIds=e.map(m=>m.id),this.tree.rebuild(g),this.render({kind:"follow-cursor"})},redo:async()=>{await this.trashNotesAndAttachments(n);let I=this.fileForNote(t.id,i);I&&await this.app.vault.modify(I,f);for(let m of o){let C=this.fileForNote(m.childId,m.childPath);C&&await this.app.fileManager.processFrontMatter(C,B=>{B.parent=m.newParent})}this.tree.rebuild(g),this.render()}})}cmdCopy(){return la(this)}cmdCopyCodeBlock(){return ol(this)}cmdCopyTree(){return al(this)}cmdCopyOutline(){return rl(this)}copyMetaPrefix(e){let t=this.isTask(e),i=t?this.isCompleted(e)?"[x] ":"[ ] ":"",s=this.colorForNode(e),n="";if(s){let o=this.plugin.getColorAlias(this.noteFolder,s);n=o?`[color: ${s} | alias: ${o}] `:`[color: ${s}] `}return{needsDash:t,checkbox:i,meta:n}}cmdToggleExpand(){let e=this.getActionTargets();if(!e.length)return;let t=e.some(i=>!this.isNoteExpanded(i.id));for(let i of e)this.setNoteExpanded(i.id,t);this.render()}isNoteExpanded(e){let t=this.expandedNotes.has(e);return this.plugin.settings.expandBodiesByDefault?!t:t}setNoteExpanded(e,t){let i=this.plugin.settings.expandBodiesByDefault;t===i?this.expandedNotes.delete(e):this.expandedNotes.add(e)}cmdExpandAll(){for(let e of this.currentChildren)this.setNoteExpanded(e.id,!0);this.render()}cmdCollapseAll(){for(let e of this.currentChildren)this.setNoteExpanded(e.id,!1);this.render()}async cloneSubtree(e,t,i,s={}){if(!e.file)return null;if(e.id===t||this.isDescendant(t,e.id))return new k.Notice(`Can't insert "${this.titleForNode(e)}" into itself or a descendant \u2014 that would loop forever.`),null;let n=this.tree.getChildren(e.id).slice(),o=e.file,a=await this.app.vault.read(o),l=this.stripFrontmatter(a),c=this.app.metadataCache.getFileCache(o)?.frontmatter??{},A=this.plugin.mintNoteId(),h=xe(l,this.activeStopwords()),p=Ne(h,A),f=`${this.noteFolder}/${p}`,u=new Date().toISOString(),g=s.preserveCreated&&e.created?e.created:u,I=this.extractAttachments(l),m=["---",`id: ${A}`,`parent: ${t}`,`created: ${g}`];if(I.length>0){m.push("attachments:");for(let B of I)m.push(` - "${B.replace(/"/g,'\\"')}"`)}else m.push("attachments: []");m.push("---",l),await this.ensureFolder(this.noteFolder),await this.app.vault.create(f,m.join(` -`)),i.push(f);let C=this.app.vault.getAbstractFileByPath(f);if(C){try{await this.app.fileManager.processFrontMatter(C,B=>{for(let[E,y]of Object.entries(c))et.includes(E)||fo.includes(E)||(B[E]=y);s.preserveCreated&&(B.modified=u),s.copyKind==="fork"&&(B[uo]=u)})}catch(B){console.warn("[Stashpad] cloneSubtree: processFrontMatter failed",B)}try{this.tree.insertSynthetic({id:A,parent:t,children:[],file:C,created:g})}catch{}this.fmSync.scheduleParentChange(A,null,t)}for(let B of n)await this.cloneSubtree(B,A,i,s);return A}async cmdClone(){let e=this.getActionTargets();if(!e.length){new k.Notice("Nothing to clone.");return}let t=new Set(e.map(A=>A.id)),i=e.filter(A=>{let h=A.parent;for(;h;){if(t.has(h))return!1;h=this.tree.get(h)?.parent??null}return!0}),s=this.noteFolder,n=[],o=[];try{for(let A of i){if(!A.file)continue;let h=A.parent??this.focusId,p=await this.cloneSubtree(A,h,n);p&&o.push(p)}}catch(A){console.warn("[Stashpad] clone failed partway",A),new k.Notice(`Clone stopped early: ${A.message}`)}if(!o.length)return;this.tree.rebuild(s),this.pendingFocusIds=o.slice(),this.render();let a=n.map(A=>this.app.vault.getAbstractFileByPath(A)).filter(A=>!!A&&A.extension==="md").map(A=>({id:nt(A.basename)??A.basename,parent:null,children:[],file:A,created:new Date().toISOString()})),l=await this.snapshotNotes(a,!1);this.plugin.getUndoStack(s).push({label:`Clone ${o.length} note${o.length===1?"":"s"}`,undo:async()=>{for(let A of[...n].reverse()){let h=this.app.vault.getAbstractFileByPath(A);if(h)try{await this.app.fileManager.trashFile(h)}catch{}}this.tree.rebuild(s),this.render()},redo:async()=>{await this.restoreSnapshots(l,o)}});let c=o.map(A=>this.tree.get(A)).filter(A=>!!A);this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Cloned",nodes:c,suffix:`(${n.length} file${n.length===1?"":"s"} total)`}),kind:"success",category:"clone",affectedIds:o,folder:this.noteFolder})}cmdForkNote(){let e=this.getActionTargets()[0];if(!e?.file){new k.Notice("Nothing to fork.");return}let t=e.parent??S,i=t===S?null:this.tree.get(t),s=i?this.titleForNode(i):"Home";new at(this.app,this.tree,n=>this.titleForNode(n),{mode:"pick",allowCreate:!0,placeholder:`Fork "${this.titleForNode(e)}" under\u2026 (default: ${s})`,onPick:n=>{if(n.crossFolder){new k.Notice("Fork stays in this folder for now.");return}this.forkNoteUnder(e,n.id)},onCreate:n=>{(async()=>{let o=await this.createNoteUnder(n,this.focusId);o&&await this.forkNoteUnder(e,o)})()}}).open()}async forkNoteUnder(e,t){if(!e.file)return;let i=this.noteFolder,s=[],n=await this.cloneSubtree(e,t,s,{preserveCreated:!0,copyKind:"fork"});if(!n)return;let o=s[0]?this.app.vault.getAbstractFileByPath(s[0]):null;if(o)try{await this.app.fileManager.processFrontMatter(o,A=>{A[zi]=`[[${e.file.basename}]]`})}catch{}this.tree.rebuild(i),this.pendingFocusIds=[n],this.render(),await this.syncForkSiblings(this.forkFamilyFiles({originName:e.file.basename,include:[e.file,o]}));let a=s.map(A=>this.app.vault.getAbstractFileByPath(A)).filter(A=>!!A&&A.extension==="md").map(A=>({id:nt(A.basename)??A.basename,parent:null,children:[],file:A,created:new Date().toISOString()})),l=await this.snapshotNotes(a,!1);this.plugin.getUndoStack(i).push({label:"Fork note",undo:async()=>{for(let A of[...s].reverse()){let h=this.app.vault.getAbstractFileByPath(A);if(h)try{await this.app.fileManager.trashFile(h)}catch{}}this.tree.rebuild(i),this.render()},redo:async()=>{await this.restoreSnapshots(l,[n])}});let c=this.tree.get(n);this.plugin.notifications.show({message:c?`Forked "${this.titleForNode(e)}" \u2192 "${this.titleForNode(c)}" (${s.length} file${s.length===1?"":"s"})`:"Forked note",kind:"success",category:"clone",affectedIds:[n],folder:i})}async ensureSheetGroup(e){let t=_e(this.app.metadataCache.getFileCache(e)?.frontmatter);if(t)return t;let i=Ka();return await this.app.fileManager.processFrontMatter(e,s=>{s[$i]=i,typeof s[ht]!="number"&&(s[ht]=0),s[Yi]=!0}),i}forkFamilyFiles(e){let t=new Map,i=s=>{s&&t.set(s.path,s)};for(let s of this.app.vault.getMarkdownFiles()){let n=this.app.metadataCache.getFileCache(s)?.frontmatter;e.gid&&_e(n)===e.gid&&i(s),e.originName&&(s.basename===e.originName||Oa(n)===e.originName)&&i(s)}for(let s of e.include??[])i(s);return[...t.values()]}async syncForkSiblings(e){for(let t of e){let i=e.filter(s=>s.path!==t.path).map(s=>`[[${s.basename}]]`);await this.app.fileManager.processFrontMatter(t,s=>{i.length?s[je]=i:delete s[je]})}}async cmdForkVersion(e){this.plugin.settings.enableSheetVersions||(this.plugin.settings.enableSheetVersions=!0,await this.plugin.saveSettings(),new k.Notice("Sheet versions enabled."));let t=e??this.getActionTargets()[0];if(!t?.file){new k.Notice("Select a note to version.");return}let i=this.noteFolder,s={...this.app.metadataCache.getFileCache(t.file)?.frontmatter??{}},n=await this.ensureSheetGroup(t.file),o=t.parent??this.focusId,a=typeof s[ht]=="number"?s[ht]:0;for(let u of this.tree.getChildren(o)){if(u.id===t.id)continue;let g=ke(this.app,u);if(_e(g)!==n)continue;let I=g?.[ht];typeof I=="number"&&I>a&&(a=I)}let l=a+1,c=[],A=await this.cloneSubtree(t,o,c,{preserveCreated:!0,copyKind:"fork"});if(!A||!c.length){new k.Notice("Sheets: could not create version.");return}let h=this.app.vault.getAbstractFileByPath(c[0]);h&&await this.app.fileManager.processFrontMatter(h,u=>{u[$i]=n,u[ht]=l,delete u[ri],delete u[Yi],u[zi]=`[[${t.file.basename}]]`}),this.tree.rebuild(i),this.activeVersionByGroup.set(n,A),this.plugin.saveActiveVersion(i,n,A),this.render();let p=this.app.vault.getAbstractFileByPath(c[0]);await this.syncForkSiblings(this.forkFamilyFiles({gid:n,include:[t.file,p]})),this.plugin.getUndoStack(i).push({label:"Fork version",undo:async()=>{for(let u of[...c].reverse()){let g=this.app.vault.getAbstractFileByPath(u);if(g)try{await this.app.fileManager.trashFile(g)}catch{}}this.activeVersionByGroup.delete(n),this.tree.rebuild(i),this.render()},redo:async()=>{}});let f=c.length;new k.Notice(`Forked a new version${f>1?` (${f} notes)`:""}`)}async cmdMarkVersionFinal(e){this.plugin.settings.enableSheetVersions||(this.plugin.settings.enableSheetVersions=!0,await this.plugin.saveSettings());let t=e??this.getActionTargets()[0];if(!t?.file)return;let i=_e(ke(this.app,t));if(!i){new k.Notice("Not a versioned note.");return}let s=!Wi(ke(this.app,t)),n=t.parent??this.focusId,o=this.tree.getChildren(n).filter(a=>_e(ke(this.app,a))===i);for(let a of o){if(!a.file)continue;let l=Wi(ke(this.app,a)),c=s&&a.id===t.id;l!==c&&await this.app.fileManager.processFrontMatter(a.file,A=>{c?A[ri]=!0:delete A[ri]})}this.render()}async cmdCopyNotes(){let e=this.getActionTargets();if(!e.length){new k.Notice("Nothing to copy.");return}await la(this),this.plugin.clearNoteClipboard(),this.plugin.noteClipboard={mode:"copy",folder:this.noteFolder,ids:e.map(t=>t.id)},this.render()}isCutPending(e){let t=this.plugin.noteClipboard;return!!t&&t.mode==="cut"&&t.folder===this.noteFolder&&t.ids.includes(e)}isCopyPending(e){let t=this.plugin.noteClipboard;return!!t&&t.mode==="copy"&&t.folder===this.noteFolder&&t.ids.includes(e)}insertIntoComposer(e){let t=this.composerInputEl;if(!t){this.composerDraft=this.composerDraft?`${this.composerDraft} +`;await this.app.vault.modify(t.file,f);for(let I=1;I<e.length;I++){let m=e[I];if(m.file){for(let C of this.tree.getChildren(m.id)){let B=C.parent,E=C.id===t.id?m.parent??S:t.id;await this.changeParent(C,E,{record:!1})&&C.file&&o.push({childId:C.id,childPath:C.file.path,oldParent:B,newParent:E})}await this.app.fileManager.trashFile(m.file),await this.log.append({type:"delete",id:m.id,payload:{mergedInto:t.id}})}}this.selection.clear(),this.cursorIdx=-1,this.pendingFocusIds=[t.id];let u=this.titleForNode(t);this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Merged",nodes:e,destination:`\u2192 kept "${u}"`}),kind:"success",category:"merge",affectedIds:e.map(I=>I.id),folder:this.noteFolder}),this.tree.rebuild(this.noteFolder),this.render({kind:"follow-cursor"});{let I=t.id,m=this.selectionGuardKey,C=()=>{if(this.selectionGuardKey!==m||this.selection.has(I))return;let B=this.currentChildren.findIndex(E=>E.id===I);B<0||(this.selection.add(I),this.cursorIdx=B,this.render({kind:"follow-cursor"}))};setTimeout(C,120),setTimeout(C,400)}let g=this.noteFolder;this.plugin.getUndoStack(g).push({label:`Merge ${e.length} notes`,undo:async()=>{await this.restoreSnapshots(n,e.map(m=>m.id));let I=this.fileForNote(t.id,i);I&&await this.app.vault.modify(I,s);for(let m of o){let C=this.fileForNote(m.childId,m.childPath);C&&await this.app.fileManager.processFrontMatter(C,B=>{B.parent=m.oldParent})}this.pendingFocusIds=e.map(m=>m.id),this.tree.rebuild(g),this.render({kind:"follow-cursor"})},redo:async()=>{await this.trashNotesAndAttachments(n);let I=this.fileForNote(t.id,i);I&&await this.app.vault.modify(I,f);for(let m of o){let C=this.fileForNote(m.childId,m.childPath);C&&await this.app.fileManager.processFrontMatter(C,B=>{B.parent=m.newParent})}this.tree.rebuild(g),this.render()}})}cmdCopy(){return Aa(this)}cmdCopyCodeBlock(){return ll(this)}cmdCopyTree(){return cl(this)}cmdCopyOutline(){return dl(this)}copyMetaPrefix(e){let t=this.isTask(e),i=t?this.isCompleted(e)?"[x] ":"[ ] ":"",s=this.colorForNode(e),n="";if(s){let o=this.plugin.getColorAlias(this.noteFolder,s);n=o?`[color: ${s} | alias: ${o}] `:`[color: ${s}] `}return{needsDash:t,checkbox:i,meta:n}}cmdToggleExpand(){let e=this.getActionTargets();if(!e.length)return;let t=e.some(i=>!this.isNoteExpanded(i.id));for(let i of e)this.setNoteExpanded(i.id,t);this.render()}isNoteExpanded(e){let t=this.expandedNotes.has(e);return this.plugin.settings.expandBodiesByDefault?!t:t}setNoteExpanded(e,t){let i=this.plugin.settings.expandBodiesByDefault;t===i?this.expandedNotes.delete(e):this.expandedNotes.add(e)}cmdExpandAll(){for(let e of this.currentChildren)this.setNoteExpanded(e.id,!0);this.render()}cmdCollapseAll(){for(let e of this.currentChildren)this.setNoteExpanded(e.id,!1);this.render()}async cloneSubtree(e,t,i,s={}){if(!e.file)return null;if(e.id===t||this.isDescendant(t,e.id))return new F.Notice(`Can't insert "${this.titleForNode(e)}" into itself or a descendant \u2014 that would loop forever.`),null;let n=this.tree.getChildren(e.id).slice(),o=e.file,a=await this.app.vault.read(o),l=this.stripFrontmatter(a),c=this.app.metadataCache.getFileCache(o)?.frontmatter??{},d=this.plugin.mintNoteId(),h=xe(l,this.activeStopwords()),p=Ne(h,d),f=`${this.noteFolder}/${p}`,u=new Date().toISOString(),g=s.preserveCreated&&e.created?e.created:u,I=this.extractAttachments(l),m=["---",`id: ${d}`,`parent: ${t}`,`created: ${g}`];if(I.length>0){m.push("attachments:");for(let B of I)m.push(` - "${B.replace(/"/g,'\\"')}"`)}else m.push("attachments: []");m.push("---",l),await this.ensureFolder(this.noteFolder),await this.app.vault.create(f,m.join(` +`)),i.push(f);let C=this.app.vault.getAbstractFileByPath(f);if(C){try{await this.app.fileManager.processFrontMatter(C,B=>{for(let[E,y]of Object.entries(c))et.includes(E)||Co.includes(E)||(B[E]=y);s.preserveCreated&&(B.modified=u),s.copyKind==="fork"&&(B[mo]=u)})}catch(B){console.warn("[Stashpad] cloneSubtree: processFrontMatter failed",B)}try{this.tree.insertSynthetic({id:d,parent:t,children:[],file:C,created:g})}catch{}this.fmSync.scheduleParentChange(d,null,t)}for(let B of n)await this.cloneSubtree(B,d,i,s);return d}async cmdClone(){let e=this.getActionTargets();if(!e.length){new F.Notice("Nothing to clone.");return}let t=new Set(e.map(d=>d.id)),i=e.filter(d=>{let h=d.parent;for(;h;){if(t.has(h))return!1;h=this.tree.get(h)?.parent??null}return!0}),s=this.noteFolder,n=[],o=[];try{for(let d of i){if(!d.file)continue;let h=d.parent??this.focusId,p=await this.cloneSubtree(d,h,n);p&&o.push(p)}}catch(d){console.warn("[Stashpad] clone failed partway",d),new F.Notice(`Clone stopped early: ${d.message}`)}if(!o.length)return;this.tree.rebuild(s),this.pendingFocusIds=o.slice(),this.render();let a=n.map(d=>this.app.vault.getAbstractFileByPath(d)).filter(d=>!!d&&d.extension==="md").map(d=>({id:nt(d.basename)??d.basename,parent:null,children:[],file:d,created:new Date().toISOString()})),l=await this.snapshotNotes(a,!1);this.plugin.getUndoStack(s).push({label:`Clone ${o.length} note${o.length===1?"":"s"}`,undo:async()=>{for(let d of[...n].reverse()){let h=this.app.vault.getAbstractFileByPath(d);if(h)try{await this.app.fileManager.trashFile(h)}catch{}}this.tree.rebuild(s),this.render()},redo:async()=>{await this.restoreSnapshots(l,o)}});let c=o.map(d=>this.tree.get(d)).filter(d=>!!d);this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Cloned",nodes:c,suffix:`(${n.length} file${n.length===1?"":"s"} total)`}),kind:"success",category:"clone",affectedIds:o,folder:this.noteFolder})}cmdForkNote(){let e=this.getActionTargets()[0];if(!e?.file){new F.Notice("Nothing to fork.");return}let t=e.parent??S,i=t===S?null:this.tree.get(t),s=i?this.titleForNode(i):"Home";new at(this.app,this.tree,n=>this.titleForNode(n),{mode:"pick",allowCreate:!0,placeholder:`Fork "${this.titleForNode(e)}" under\u2026 (default: ${s})`,onPick:n=>{if(n.crossFolder){new F.Notice("Fork stays in this folder for now.");return}this.forkNoteUnder(e,n.id)},onCreate:n=>{(async()=>{let o=await this.createNoteUnder(n,this.focusId);o&&await this.forkNoteUnder(e,o)})()}}).open()}async forkNoteUnder(e,t){if(!e.file)return;let i=this.noteFolder,s=[],n=await this.cloneSubtree(e,t,s,{preserveCreated:!0,copyKind:"fork"});if(!n)return;let o=s[0]?this.app.vault.getAbstractFileByPath(s[0]):null;if(o)try{await this.app.fileManager.processFrontMatter(o,d=>{d[Wi]=`[[${e.file.basename}]]`})}catch{}this.tree.rebuild(i),this.pendingFocusIds=[n],this.render(),await this.syncForkSiblings(this.forkFamilyFiles({originName:e.file.basename,include:[e.file,o]}));let a=s.map(d=>this.app.vault.getAbstractFileByPath(d)).filter(d=>!!d&&d.extension==="md").map(d=>({id:nt(d.basename)??d.basename,parent:null,children:[],file:d,created:new Date().toISOString()})),l=await this.snapshotNotes(a,!1);this.plugin.getUndoStack(i).push({label:"Fork note",undo:async()=>{for(let d of[...s].reverse()){let h=this.app.vault.getAbstractFileByPath(d);if(h)try{await this.app.fileManager.trashFile(h)}catch{}}this.tree.rebuild(i),this.render()},redo:async()=>{await this.restoreSnapshots(l,[n])}});let c=this.tree.get(n);this.plugin.notifications.show({message:c?`Forked "${this.titleForNode(e)}" \u2192 "${this.titleForNode(c)}" (${s.length} file${s.length===1?"":"s"})`:"Forked note",kind:"success",category:"clone",affectedIds:[n],folder:i})}async ensureSheetGroup(e){let t=_e(this.app.metadataCache.getFileCache(e)?.frontmatter);if(t)return t;let i=$a();return await this.app.fileManager.processFrontMatter(e,s=>{s[zi]=i,typeof s[ht]!="number"&&(s[ht]=0),s[Vi]=!0}),i}forkFamilyFiles(e){let t=new Map,i=s=>{s&&t.set(s.path,s)};for(let s of this.app.vault.getMarkdownFiles()){let n=this.app.metadataCache.getFileCache(s)?.frontmatter;e.gid&&_e(n)===e.gid&&i(s),e.originName&&(s.basename===e.originName||qa(n)===e.originName)&&i(s)}for(let s of e.include??[])i(s);return[...t.values()]}async syncForkSiblings(e){for(let t of e){let i=e.filter(s=>s.path!==t.path).map(s=>`[[${s.basename}]]`);await this.app.fileManager.processFrontMatter(t,s=>{i.length?s[je]=i:delete s[je]})}}async cmdForkVersion(e){this.plugin.settings.enableSheetVersions||(this.plugin.settings.enableSheetVersions=!0,await this.plugin.saveSettings(),new F.Notice("Sheet versions enabled."));let t=e??this.getActionTargets()[0];if(!t?.file){new F.Notice("Select a note to version.");return}let i=this.noteFolder,s={...this.app.metadataCache.getFileCache(t.file)?.frontmatter??{}},n=await this.ensureSheetGroup(t.file),o=t.parent??this.focusId,a=typeof s[ht]=="number"?s[ht]:0;for(let u of this.tree.getChildren(o)){if(u.id===t.id)continue;let g=Fe(this.app,u);if(_e(g)!==n)continue;let I=g?.[ht];typeof I=="number"&&I>a&&(a=I)}let l=a+1,c=[],d=await this.cloneSubtree(t,o,c,{preserveCreated:!0,copyKind:"fork"});if(!d||!c.length){new F.Notice("Sheets: could not create version.");return}let h=this.app.vault.getAbstractFileByPath(c[0]);h&&await this.app.fileManager.processFrontMatter(h,u=>{u[zi]=n,u[ht]=l,delete u[li],delete u[Vi],u[Wi]=`[[${t.file.basename}]]`}),this.tree.rebuild(i),this.activeVersionByGroup.set(n,d),this.plugin.saveActiveVersion(i,n,d),this.render();let p=this.app.vault.getAbstractFileByPath(c[0]);await this.syncForkSiblings(this.forkFamilyFiles({gid:n,include:[t.file,p]})),this.plugin.getUndoStack(i).push({label:"Fork version",undo:async()=>{for(let u of[...c].reverse()){let g=this.app.vault.getAbstractFileByPath(u);if(g)try{await this.app.fileManager.trashFile(g)}catch{}}this.activeVersionByGroup.delete(n),this.tree.rebuild(i),this.render()},redo:async()=>{}});let f=c.length;new F.Notice(`Forked a new version${f>1?` (${f} notes)`:""}`)}async cmdMarkVersionFinal(e){this.plugin.settings.enableSheetVersions||(this.plugin.settings.enableSheetVersions=!0,await this.plugin.saveSettings());let t=e??this.getActionTargets()[0];if(!t?.file)return;let i=_e(Fe(this.app,t));if(!i){new F.Notice("Not a versioned note.");return}let s=!Zi(Fe(this.app,t)),n=t.parent??this.focusId,o=this.tree.getChildren(n).filter(a=>_e(Fe(this.app,a))===i);for(let a of o){if(!a.file)continue;let l=Zi(Fe(this.app,a)),c=s&&a.id===t.id;l!==c&&await this.app.fileManager.processFrontMatter(a.file,d=>{c?d[li]=!0:delete d[li]})}this.render()}async cmdCopyNotes(){let e=this.getActionTargets();if(!e.length){new F.Notice("Nothing to copy.");return}await Aa(this),this.plugin.clearNoteClipboard(),this.plugin.noteClipboard={mode:"copy",folder:this.noteFolder,ids:e.map(t=>t.id)},this.render()}isCutPending(e){let t=this.plugin.noteClipboard;return!!t&&t.mode==="cut"&&t.folder===this.noteFolder&&t.ids.includes(e)}isCopyPending(e){let t=this.plugin.noteClipboard;return!!t&&t.mode==="copy"&&t.folder===this.noteFolder&&t.ids.includes(e)}insertIntoComposer(e){let t=this.composerInputEl;if(!t){this.composerDraft=this.composerDraft?`${this.composerDraft} -${e}`:e;return}let i=t.selectionStart??t.value.length,s=t.selectionEnd??t.value.length;t.value=t.value.slice(0,i)+e+t.value.slice(s);let n=i+e.length;try{t.setSelectionRange(n,n)}catch{}this.composerDraft=t.value}focusedInsideCut(e){let t=new Set(e),i=this.focusId,s=0;for(;i&&i!==S&&s++<1e3;){if(t.has(i))return!0;i=this.tree.get(i)?.parent??null}return!1}async cmdCutNotes(){let e=this.getActionTargets();if(!e.length){new k.Notice("Nothing to cut.");return}let t=[];for(let s of e)s.file&&t.push(this.stripFrontmatter(await this.app.vault.cachedRead(s.file)).trim());let i=t.join(` +${e}`:e;return}let i=t.selectionStart??t.value.length,s=t.selectionEnd??t.value.length;t.value=t.value.slice(0,i)+e+t.value.slice(s);let n=i+e.length;try{t.setSelectionRange(n,n)}catch{}this.composerDraft=t.value}focusedInsideCut(e){let t=new Set(e),i=this.focusId,s=0;for(;i&&i!==S&&s++<1e3;){if(t.has(i))return!0;i=this.tree.get(i)?.parent??null}return!1}async cmdCutNotes(){let e=this.getActionTargets();if(!e.length){new F.Notice("Nothing to cut.");return}let t=[];for(let s of e)s.file&&t.push(this.stripFrontmatter(await this.app.vault.cachedRead(s.file)).trim());let i=t.join(` -`);await navigator.clipboard.writeText(i),this.plugin.clearNoteClipboard(),this.plugin.noteClipboard={mode:"cut",folder:this.noteFolder,ids:e.map(s=>s.id),text:i},this.render(),this.plugin.noteClipboardNotice=this.plugin.notifications.show({message:`Cut ${this.titleList(e)} \u2014 paste in the LIST to move it there as a note; paste in a note's COMPOSER to drop its text in and delete the original (undoable). Esc cancels. Nothing happens until you paste.`,kind:"info",category:"system",affectedIds:e.map(s=>s.id),folder:this.noteFolder,duration:0})}async cmdPasteNotes(){let e=this.plugin.noteClipboard;if(!e){new k.Notice("The note clipboard is empty \u2014 copy or cut notes first.");return}if(e.folder!==this.noteFolder){let p=(this.currentChildren[this.cursorIdx]??null)?.parent??this.focusId??S,f=e.mode,u=e.folder,g=await this.plugin.crossFolderPaste(u,e.ids,this.noteFolder,p,f);if(!g||!g.rootIds.length)return;f==="cut"&&this.plugin.clearNoteClipboard();let I=this.noteFolder;this.tree.rebuild(I),this.pendingFocusIds=g.rootIds.slice(),this.render(),f==="cut"&&this.plugin.refreshOpenViewsForFolder(u);let m=u.split("/").pop(),C=g.rootIds.length,B=()=>{this.tree.rebuild(I),this.render(),this.plugin.refreshOpenViewsForFolder(u)};this.plugin.getUndoStack(I).push({label:`${f==="cut"?"Move":"Paste"} ${C} note${C===1?"":"s"} from ${m}`,undo:async()=>{await g.undo(),B()},redo:async()=>{await g.redo(),B()}});let E=f==="cut"?"Moved":"Pasted (copied)";this.plugin.notifications.show({message:`${E} ${C} note${C===1?"":"s"} (${g.noteCount} total) from "${m}" into this folder. Undo (in the list) reverses it.`,kind:"success",category:f==="cut"?"move":"clone",affectedIds:g.rootIds,folder:I,duration:0});return}let t=e.ids.map(h=>this.tree.get(h)).filter(h=>!!h&&!!h.file);if(!t.length){this.plugin.clearNoteClipboard(),this.render(),new k.Notice("Those notes no longer exist.");return}let i=this.currentChildren[this.cursorIdx]??null,s=i?.parent??this.focusId??S;if(e.mode==="cut"){let h=new Set(e.ids);for(let f=s;f&&f!==S;f=this.tree.get(f)?.parent??null)if(h.has(f)){new k.Notice("Can't paste cut notes under themselves.");return}let p=i&&!h.has(i.id)?i.id:"";this.plugin.clearNoteClipboard(),await this.moveAcrossThenReorder(t.map(f=>f.id),s,p,"after","Moved");return}let n=this.noteFolder,o=[],a=[];for(let h of t){let p=await this.cloneSubtree(h,s,o);p&&a.push(p)}if(!a.length)return;this.tree.rebuild(n),this.pendingFocusIds=a.slice(),this.render();let l=o.map(h=>this.app.vault.getAbstractFileByPath(h)).filter(h=>!!h&&h.extension==="md").map(h=>({id:nt(h.basename)??h.basename,parent:null,children:[],file:h,created:new Date().toISOString()})),c=await this.snapshotNotes(l,!1);this.plugin.getUndoStack(n).push({label:`Paste ${a.length} note${a.length===1?"":"s"}`,undo:async()=>{for(let h of[...o].reverse()){let p=this.app.vault.getAbstractFileByPath(h);if(p)try{await this.app.fileManager.trashFile(p)}catch{}}this.tree.rebuild(n),this.render()},redo:async()=>{await this.restoreSnapshots(c,a)}});let A=a.map(h=>this.tree.get(h)).filter(h=>!!h);this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Pasted (duplicated)",nodes:A,suffix:`(${o.length} file${o.length===1?"":"s"} total)`}),kind:"success",category:"clone",affectedIds:a,folder:n,duration:0})}async completeCutIntoComposer(){let e=this.plugin.noteClipboard;if(!e||e.mode!=="cut")return;if(e.folder!==this.noteFolder){let p=e.folder,f=e.ids.slice();this.plugin.clearNoteClipboard();let u=await this.plugin.orderedSubtreeNodes(p,f),g=X().prefixTimestampsOnCopy,I=[];for(let{file:y,created:v,depth:Q}of u)try{let w=this.stripFrontmatter(await this.app.vault.cachedRead(y)).trim().split(/\r?\n/).join(" "),F=g?`${this.formatTimeInline(v)} `:"";I.push(`${" ".repeat(Q)}- ${F}${w}`)}catch{}this.insertIntoComposer(I.length?I.join(` +`);await navigator.clipboard.writeText(i),this.plugin.clearNoteClipboard(),this.plugin.noteClipboard={mode:"cut",folder:this.noteFolder,ids:e.map(s=>s.id),text:i},this.render(),this.plugin.noteClipboardNotice=this.plugin.notifications.show({message:`Cut ${this.titleList(e)} \u2014 paste in the LIST to move it there as a note; paste in a note's COMPOSER to drop its text in and delete the original (undoable). Esc cancels. Nothing happens until you paste.`,kind:"info",category:"system",affectedIds:e.map(s=>s.id),folder:this.noteFolder,duration:0})}async cmdPasteNotes(){let e=this.plugin.noteClipboard;if(!e){new F.Notice("The note clipboard is empty \u2014 copy or cut notes first.");return}if(e.folder!==this.noteFolder){let p=(this.currentChildren[this.cursorIdx]??null)?.parent??this.focusId??S,f=e.mode,u=e.folder,g=await this.plugin.crossFolderPaste(u,e.ids,this.noteFolder,p,f);if(!g||!g.rootIds.length)return;f==="cut"&&this.plugin.clearNoteClipboard();let I=this.noteFolder;this.tree.rebuild(I),this.pendingFocusIds=g.rootIds.slice(),this.render(),f==="cut"&&this.plugin.refreshOpenViewsForFolder(u);let m=u.split("/").pop(),C=g.rootIds.length,B=()=>{this.tree.rebuild(I),this.render(),this.plugin.refreshOpenViewsForFolder(u)};this.plugin.getUndoStack(I).push({label:`${f==="cut"?"Move":"Paste"} ${C} note${C===1?"":"s"} from ${m}`,undo:async()=>{await g.undo(),B()},redo:async()=>{await g.redo(),B()}});let E=f==="cut"?"Moved":"Pasted (copied)";this.plugin.notifications.show({message:`${E} ${C} note${C===1?"":"s"} (${g.noteCount} total) from "${m}" into this folder. Undo (in the list) reverses it.`,kind:"success",category:f==="cut"?"move":"clone",affectedIds:g.rootIds,folder:I,duration:0});return}let t=e.ids.map(h=>this.tree.get(h)).filter(h=>!!h&&!!h.file);if(!t.length){this.plugin.clearNoteClipboard(),this.render(),new F.Notice("Those notes no longer exist.");return}let i=this.currentChildren[this.cursorIdx]??null,s=i?.parent??this.focusId??S;if(e.mode==="cut"){let h=new Set(e.ids);for(let f=s;f&&f!==S;f=this.tree.get(f)?.parent??null)if(h.has(f)){new F.Notice("Can't paste cut notes under themselves.");return}let p=i&&!h.has(i.id)?i.id:"";this.plugin.clearNoteClipboard(),await this.moveAcrossThenReorder(t.map(f=>f.id),s,p,"after","Moved");return}let n=this.noteFolder,o=[],a=[];for(let h of t){let p=await this.cloneSubtree(h,s,o);p&&a.push(p)}if(!a.length)return;this.tree.rebuild(n),this.pendingFocusIds=a.slice(),this.render();let l=o.map(h=>this.app.vault.getAbstractFileByPath(h)).filter(h=>!!h&&h.extension==="md").map(h=>({id:nt(h.basename)??h.basename,parent:null,children:[],file:h,created:new Date().toISOString()})),c=await this.snapshotNotes(l,!1);this.plugin.getUndoStack(n).push({label:`Paste ${a.length} note${a.length===1?"":"s"}`,undo:async()=>{for(let h of[...o].reverse()){let p=this.app.vault.getAbstractFileByPath(h);if(p)try{await this.app.fileManager.trashFile(p)}catch{}}this.tree.rebuild(n),this.render()},redo:async()=>{await this.restoreSnapshots(c,a)}});let d=a.map(h=>this.tree.get(h)).filter(h=>!!h);this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Pasted (duplicated)",nodes:d,suffix:`(${o.length} file${o.length===1?"":"s"} total)`}),kind:"success",category:"clone",affectedIds:a,folder:n,duration:0})}async completeCutIntoComposer(){let e=this.plugin.noteClipboard;if(!e||e.mode!=="cut")return;if(e.folder!==this.noteFolder){let p=e.folder,f=e.ids.slice();this.plugin.clearNoteClipboard();let u=await this.plugin.orderedSubtreeNodes(p,f),g=X().prefixTimestampsOnCopy,I=[];for(let{file:y,created:v,depth:Q}of u)try{let w=this.stripFrontmatter(await this.app.vault.cachedRead(y)).trim().split(/\r?\n/).join(" "),k=g?`${this.formatTimeInline(v)} `:"";I.push(`${" ".repeat(Q)}- ${k}${w}`)}catch{}this.insertIntoComposer(I.length?I.join(` `):e.text??"");let m=await this.plugin.subtreeFilePaths(p,f),C=await this.plugin.snapshotPaths(m),B=await this.plugin.trashSubtrees(p,f);this.plugin.refreshOpenViewsForFolder(p);let E=B.filter(y=>y.extension==="md").length;this.plugin.getUndoStack(p).push({label:`Cut ${f.length} note${f.length===1?"":"s"} into composer (from ${p.split("/").pop()})`,undo:async()=>{await this.plugin.restoreSnapshot(C),this.plugin.refreshOpenViewsForFolder(p)},redo:async()=>{await this.plugin.trashSubtrees(p,f),this.plugin.refreshOpenViewsForFolder(p)}}),this.plugin.notifications.show({message:`Pasted the text of ${f.length} cut note${f.length===1?"":"s"} from "${p.split("/").pop()}" into the composer and removed the original${E===1?"":"s"} (${E} note${E===1?"":"s"}). Undo restores them.`,kind:"warning",category:"delete",affectedIds:f,folder:p,duration:0});return}this.plugin.clearNoteClipboard();let t=e.ids.map(p=>this.tree.get(p)).filter(p=>!!p&&!!p.file);if(!t.length)return;let i=[],s=new Set,n=(p,f)=>{if(!s.has(p.id)){s.add(p.id),i.push({node:p,depth:f});for(let u of this.tree.getChildren(p.id))n(u,f+1)}};for(let p of t)n(p,0);let o=this.noteFolder,a=X().prefixTimestampsOnCopy,l=[];for(let{node:p,depth:f}of i)if(p.file)try{let u=this.stripFrontmatter(await this.app.vault.cachedRead(p.file)).trim().split(/\r?\n/).join(" "),g=a?`${this.formatTimeInline(p.created)} `:"";l.push(`${" ".repeat(f)}- ${g}${u}`)}catch{}this.insertIntoComposer(l.join(` -`));let c=i.map(p=>p.node),A=await this.snapshotNotes(c,!1);for(let p of[...c].reverse())if(p.file)try{await this.app.fileManager.trashFile(p.file)}catch(f){console.warn("[Stashpad] cut-paste delete failed",p.file.path,f)}this.selection.clear(),this.tree.rebuild(o),this.render();let h=t.map(p=>p.id);this.plugin.getUndoStack(o).push({label:`Cut ${t.length} note${t.length===1?"":"s"} into composer`,undo:async()=>{await this.restoreSnapshots(A,h)},redo:async()=>{for(let p of[...A.notes]){let f=this.app.vault.getAbstractFileByPath(p.path);if(f)try{await this.app.fileManager.trashFile(f)}catch{}}this.tree.rebuild(o),this.render()}}),this.plugin.notifications.show({message:`Pasted the text of ${this.titleList(t)} into the composer and deleted the original${t.length===1?"":"s"} (${c.length} note${c.length===1?"":"s"}). Undo (in the list) restores them.`,kind:"warning",category:"delete",affectedIds:h,folder:o,duration:0})}cmdInsertTemplate(){new at(this.app,this.tree,e=>this.titleForNode(e),{mode:"pick",placeholder:"Insert which note as a template?",allowCreate:!1,onPick:async e=>{if(e.crossFolder){new k.Notice("Cross-Stashpad templates aren't supported yet \u2014 pick a note from this Stashpad.");return}let t=this.tree.get(e.id);if(!t?.file)return;let i=this.noteFolder,s=[],n=await this.cloneSubtree(t,this.focusId,s);if(!n)return;this.tree.rebuild(i),this.pendingFocusIds=[n],this.render();let o=s.map(l=>this.app.vault.getAbstractFileByPath(l)).filter(l=>!!l&&l.extension==="md").map(l=>({id:nt(l.basename)??l.basename,parent:null,children:[],file:l,created:new Date().toISOString()})),a=await this.snapshotNotes(o,!1);this.plugin.getUndoStack(i).push({label:"Insert template",undo:async()=>{for(let l of[...s].reverse()){let c=this.app.vault.getAbstractFileByPath(l);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(e,t={}){if(t.keepForwardStack||this.recordNavState(),this.selectionGuardKey++,this.listEl&&this.stampSelectedCursor(!0),this.focusId=e,this.persistFocus(),this.defaultCursorToLast(),this.syncComposerDraftForFocus(),this.tagFilter&&this.tagFilter!==Yt&&this.tagFilter!==zt){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(e),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 e=this.navBackStack.pop();if(!e){this.focusId!==S&&this.navigateUp();return}this.navForwardSnapshots.push(this.captureNavSnapshot()),this.applyNavSnapshot(e)}navigateForward(){let e=this.navForwardSnapshots.pop();e&&(this.navBackStack.push(this.captureNavSnapshot()),this.applyNavSnapshot(e))}async applyNavSnapshot(e){if(this.tagFilter=null,this.colorFilter=null,e.folder!==this.noteFolder){await this.setFolderOverride(e.folder,{skipHistory:!0}),e.focusId!==this.focusId&&this.tree.get(e.focusId)&&(this.focusId=e.focusId,this.render({kind:"preserve"}));return}if(!this.tree.get(e.focusId))return;this.selectionGuardKey++,this.listEl&&this.stampSelectedCursor(!0),this.focusId=e.focusId,this.persistFocus(),this.defaultCursorToLast(),this.syncComposerDraftForFocus();let t=this.lastCursorByFocus.get(e.focusId),i;t&&this.tree.get(t)?(this.pendingFocusIds=[t],i={kind:"scroll-to-id",id:t,align:"start"}):i={kind:"preserve"},this.render(i),this.refreshHeaderTitle(),this.viewRoot.focus({preventScroll:!0}),this.plugin.notifyStashpadSelectionChanged()}navigateUp(){this.selectionGuardKey++,this.tagFilter=null,this.colorFilter=null;let e=this.tree.get(this.focusId);if(!e||e.parent==null){if(this.navBackStack.length>0){this.navigateBack();return}return this.navigateTo(S)}let t=this.focusId;if(this.recordNavState(),this.listEl){let o=this.currentChildren[this.cursorIdx]?.id??this.lastSelected;o&&this.plugin.saveLastCursor(this.noteFolder,t,o)}this.focusId=e.parent,this.persistFocus(),this.syncComposerDraftForFocus();let i=this.filterChildren(this.tree.getChildren(this.focusId)),s=i.findIndex(n=>n.id===t);this.selection.clear(),s>=0?(this.cursorIdx=s,this.selection.add(t),this.lastSelected=t):(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:t,align:"start"}):this.render({kind:"follow-cursor"}),this.refreshHeaderTitle(),s<0&&this.revealCursorRow(),this.plugin.notifyStashpadSelectionChanged()}openBookmarks(){let e=this.app.internalPlugins?.plugins?.bookmarks?.instance?.items??[],t=this.allowedByBases(),i=new k.Menu,s=0;for(let n of e){if(n.type!=="file"||t&&!t.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 e=(this.plugin.settings.importDropFolder||"").trim().replace(/^\/+|\/+$/g,""),t=(this.plugin.settings.exportFolder||"").trim().replace(/^\/+|\/+$/g,"");e&&await this.ensureFolder(`${this.noteFolder}/${e}`),t&&await this.ensureFolder(`${this.noteFolder}/${t}`),await this.order.load(this.noteFolder),await this.sortStore.load(this.noteFolder),this.bootstrappedFolders.add(this.noteFolder)}backfillFrontmatterSync(){let e=[S],t=this.tree.getRoot(),i=s=>{for(let n of this.tree.getChildren(s))e.push(n.id),i(n.id)};for(let s of t.children)i(s);for(let s of e)this.fmSync.wouldWrite(s)&&this.fmSync.schedule(s)}installFmSyncActivityNotice(){this.fmSyncUnsubscribe||(this.fmSyncUnsubscribe=this.fmSync.onError((e,t)=>{this.plugin.notifications.show({message:`Stashpad: couldn't update recovery metadata +`));let c=i.map(p=>p.node),d=await this.snapshotNotes(c,!1);for(let p of[...c].reverse())if(p.file)try{await this.app.fileManager.trashFile(p.file)}catch(f){console.warn("[Stashpad] cut-paste delete failed",p.file.path,f)}this.selection.clear(),this.tree.rebuild(o),this.render();let h=t.map(p=>p.id);this.plugin.getUndoStack(o).push({label:`Cut ${t.length} note${t.length===1?"":"s"} into composer`,undo:async()=>{await this.restoreSnapshots(d,h)},redo:async()=>{for(let p of[...d.notes]){let f=this.app.vault.getAbstractFileByPath(p.path);if(f)try{await this.app.fileManager.trashFile(f)}catch{}}this.tree.rebuild(o),this.render()}}),this.plugin.notifications.show({message:`Pasted the text of ${this.titleList(t)} into the composer and deleted the original${t.length===1?"":"s"} (${c.length} note${c.length===1?"":"s"}). Undo (in the list) restores them.`,kind:"warning",category:"delete",affectedIds:h,folder:o,duration:0})}cmdInsertTemplate(){new at(this.app,this.tree,e=>this.titleForNode(e),{mode:"pick",placeholder:"Insert which note as a template?",allowCreate:!1,onPick:async e=>{if(e.crossFolder){new F.Notice("Cross-Stashpad templates aren't supported yet \u2014 pick a note from this Stashpad.");return}let t=this.tree.get(e.id);if(!t?.file)return;let i=this.noteFolder,s=[],n=await this.cloneSubtree(t,this.focusId,s);if(!n)return;this.tree.rebuild(i),this.pendingFocusIds=[n],this.render();let o=s.map(l=>this.app.vault.getAbstractFileByPath(l)).filter(l=>!!l&&l.extension==="md").map(l=>({id:nt(l.basename)??l.basename,parent:null,children:[],file:l,created:new Date().toISOString()})),a=await this.snapshotNotes(o,!1);this.plugin.getUndoStack(i).push({label:"Insert template",undo:async()=>{for(let l of[...s].reverse()){let c=this.app.vault.getAbstractFileByPath(l);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(e,t={}){if(t.keepForwardStack||this.recordNavState(),this.selectionGuardKey++,this.listEl&&this.stampSelectedCursor(!0),this.focusId=e,this.persistFocus(),this.defaultCursorToLast(),this.syncComposerDraftForFocus(),this.tagFilter&&this.tagFilter!==Yt&&this.tagFilter!==zt){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(e),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 e=this.navBackStack.pop();if(!e){this.focusId!==S&&this.navigateUp();return}this.navForwardSnapshots.push(this.captureNavSnapshot()),this.applyNavSnapshot(e)}navigateForward(){let e=this.navForwardSnapshots.pop();e&&(this.navBackStack.push(this.captureNavSnapshot()),this.applyNavSnapshot(e))}async applyNavSnapshot(e){if(this.tagFilter=null,this.colorFilter=null,e.folder!==this.noteFolder){await this.setFolderOverride(e.folder,{skipHistory:!0}),e.focusId!==this.focusId&&this.tree.get(e.focusId)&&(this.focusId=e.focusId,this.render({kind:"preserve"}));return}if(!this.tree.get(e.focusId))return;this.selectionGuardKey++,this.listEl&&this.stampSelectedCursor(!0),this.focusId=e.focusId,this.persistFocus(),this.defaultCursorToLast(),this.syncComposerDraftForFocus();let t=this.lastCursorByFocus.get(e.focusId),i;t&&this.tree.get(t)?(this.pendingFocusIds=[t],i={kind:"scroll-to-id",id:t,align:"start"}):i={kind:"preserve"},this.render(i),this.refreshHeaderTitle(),this.viewRoot.focus({preventScroll:!0}),this.plugin.notifyStashpadSelectionChanged()}navigateUp(){this.selectionGuardKey++,this.tagFilter=null,this.colorFilter=null;let e=this.tree.get(this.focusId);if(!e||e.parent==null){if(this.navBackStack.length>0){this.navigateBack();return}return this.navigateTo(S)}let t=this.focusId;if(this.recordNavState(),this.listEl){let o=this.currentChildren[this.cursorIdx]?.id??this.lastSelected;o&&this.plugin.saveLastCursor(this.noteFolder,t,o)}this.focusId=e.parent,this.persistFocus(),this.syncComposerDraftForFocus();let i=this.filterChildren(this.tree.getChildren(this.focusId)),s=i.findIndex(n=>n.id===t);this.selection.clear(),s>=0?(this.cursorIdx=s,this.selection.add(t),this.lastSelected=t):(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:t,align:"start"}):this.render({kind:"follow-cursor"}),this.refreshHeaderTitle(),s<0&&this.revealCursorRow(),this.plugin.notifyStashpadSelectionChanged()}openBookmarks(){let e=this.app.internalPlugins?.plugins?.bookmarks?.instance?.items??[],t=this.allowedByBases(),i=new F.Menu,s=0;for(let n of e){if(n.type!=="file"||t&&!t.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 e=(this.plugin.settings.importDropFolder||"").trim().replace(/^\/+|\/+$/g,""),t=(this.plugin.settings.exportFolder||"").trim().replace(/^\/+|\/+$/g,"");e&&await this.ensureFolder(`${this.noteFolder}/${e}`),t&&await this.ensureFolder(`${this.noteFolder}/${t}`),await this.order.load(this.noteFolder),await this.sortStore.load(this.noteFolder),this.bootstrappedFolders.add(this.noteFolder)}backfillFrontmatterSync(){let e=[S],t=this.tree.getRoot(),i=s=>{for(let n of this.tree.getChildren(s))e.push(n.id),i(n.id)};for(let s of t.children)i(s);for(let s of e)this.fmSync.wouldWrite(s)&&this.fmSync.schedule(s)}installFmSyncActivityNotice(){this.fmSyncUnsubscribe||(this.fmSyncUnsubscribe=this.fmSync.onError((e,t)=>{this.plugin.notifications.show({message:`Stashpad: couldn't update recovery metadata File: \`${e}\` -Error: ${t.message}`,kind:"error",category:"system",duration:0,affectedPaths:[e],folder:this.noteFolder})}))}async ensureHomeNote(){let e=this.noteFolder,t=`${e}/${this.buildHomeFilename(e)}`,i=this.app.vault.getMarkdownFiles().filter(o=>o.path.startsWith(e+"/"));for(let o of i){if(this.app.metadataCache.getFileCache(o)?.frontmatter?.id!==S)continue;if(o.path===t||this.app.vault.getAbstractFileByPath(t))return o;try{await this.app.fileManager.renameFile(o,t);let c=this.app.vault.getAbstractFileByPath(t);if(c instanceof k.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: ${S}`,"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(t,n)}buildHomeFilename(e){return`Home-${(e.split("/").filter(Boolean).pop()??"Stashpad").replace(/[^A-Za-z0-9_-]+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"")||"Stashpad"}.md`}async migrateNullParents(){let e=this.noteFolder,t=this.app.vault.getMarkdownFiles().filter(i=>i.path.startsWith(e+"/"));for(let i of t){let s=this.app.metadataCache.getFileCache(i)?.frontmatter,n=s?.id;if(!n||n===S)continue;let o=s?.parent;(o==null||o===""||o==="null")&&(await this.app.fileManager.processFrontMatter(i,a=>{a.parent=S}),await this.log.append({type:"parent_change",id:n,payload:{from:null,to:S,reason:"migration"}}))}}async openInNewStashpadTab(e){let t=this.app.workspace,i=this.leaf,s=t.getLeaf("tab");await s.setViewState({type:z,active:!0,state:{focusId:e,timeFilter:this.timeFilter,folderOverride:this.folderOverride}}),t.setActiveLeaf(s,{focus:!0}),t.revealLeaf(s),yt(t,s,i,n=>this.plugin.registerEvent(n))}async openNoteInNewTab(e,t,i){let s=(e||"").trim().replace(/^\/+|\/+$/g,"");if(!s||!t)return;let n=(this.plugin.settings.folder||"Stashpad").trim().replace(/^\/+|\/+$/g,"")||"Stashpad",o=this.app.workspace,a=this.leaf,l=o.getLeaf("tab");await l.setViewState({type:z,active:!0,state:{focusId:t,folderOverride:s===n?null:s,...i?{cursorId:i}:{}}}),o.setActiveLeaf(l,{focus:!0}),o.revealLeaf(l),yt(o,l,a,c=>this.plugin.registerEvent(c))}async openFolderInNewTab(e){let t=(e||"").trim().replace(/^\/+|\/+$/g,"");if(!t)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:z,active:!0,state:{focusId:S,folderOverride:t===i?null:t}}),s.setActiveLeaf(o,{focus:!0}),s.revealLeaf(o),yt(s,o,n,a=>this.plugin.registerEvent(a))}cmdOpenInEditor(e){if(e){this.openFileAtEnd(e.file);return}let t=this.getActionTargets();if(t.length)for(let i of t)i.file&&this.openFileAtEnd(i.file)}async cmdCopyStashpadLink(e){let i=(e?[e]:this.getActionTargets()).filter(n=>!!n?.id);if(i.length===0){new k.Notice("No note selected to link to.");return}let s=i.map(n=>Dn({vault:this.app.vault.getName(),folder:this.noteFolder,note:n.id,run:["reveal"]}));try{await navigator.clipboard.writeText(s.join(` -`)),new k.Notice(s.length>1?`${s.length} Stashpad links copied.`:"Stashpad link copied.")}catch{new k.Notice("Couldn't copy the link to the clipboard.")}}cmdOpenParentInEditor(){let e=this.tree.get(this.focusId);if(!e?.file){new k.Notice("No focused parent to open.");return}this.openFileAtEnd(e.file)}async openFileAtEnd(e){let t=this.app.workspace,i=this.leaf,s=t.getLeaf("tab");await s.openFile(e,{active:!0}),t.setActiveLeaf(s,{focus:!0}),t.revealLeaf(s),yt(t,s,i,a=>this.plugin.registerEvent(a));let o=s.view?.editor;o&&requestAnimationFrame(()=>{try{let a=o.lastLine(),l=o.getLine(a)?.length??0;o.setCursor({line:a,ch:l}),o.scrollIntoView({from:{line:a,ch:l},to:{line:a,ch:l}},!0),o.focus()}catch{}})}cmdSelectAll(){if(this.currentChildren.length!==0){this.selection.clear();for(let e of this.currentChildren)this.selection.add(e.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 e=this.getActionTargets();if(e.length===0){let n=this.tree.get(this.focusId);n?.file&&(e=[n])}if(e.length===0){new k.Notice("Nothing to pin.");return}let t=e.some(n=>!this.plugin.isPinned({folder:this.noteFolder,id:n.id})),i=0,s=0;for(let n of e){let o={folder:this.noteFolder,id:n.id};t?this.plugin.isPinned(o)||(await this.plugin.pinNote(o),i++):this.plugin.isPinned(o)&&(await this.plugin.unpinNote(o),s++)}i>0?new k.Notice(`Pinned ${i} note${i===1?"":"s"} to sidebar.`):s>0&&new k.Notice(`Unpinned ${s} note${s===1?"":"s"} from sidebar.`)}isListPinned(e){let t=this.tree.get(e);if(!t?.file)return!1;let i=this.listPinnedState.get(t.file.path);return i?i.pinned:this.app.metadataCache.getFileCache(t.file)?.frontmatter?.listPinned===!0}listPinnedAt(e){let t=this.tree.get(e);if(!t?.file)return 0;let i=this.listPinnedState.get(t.file.path);if(i)return i.at;let s=this.app.metadataCache.getFileCache(t.file)?.frontmatter?.listPinnedAt,n=typeof s=="string"?Date.parse(s):NaN;return Number.isNaN(n)?0:n}hoistListPinned(e,t){let i=this.tree.getChildren(e).map(l=>l.id);if(!i.some(l=>this.isListPinned(l)))return t;let s=new Set(t),n=[...t,...i.filter(l=>!s.has(l))],o=n.filter(l=>this.isListPinned(l)).sort((l,c)=>this.listPinnedAt(l)-this.listPinnedAt(c)),a=n.filter(l=>!this.isListPinned(l));return[...o,...a]}async cmdToggleListPin(){let e=this.getActionTargets();if(e.length===0){let a=this.tree.get(this.focusId);a?.file&&(e=[a])}if(e.length===0){new k.Notice("Nothing to pin.");return}let t=e.some(a=>!this.isListPinned(a.id)),i=[],s=new Date().toISOString(),n=[];for(let a of e){if(!a.file)continue;let l=this.app.metadataCache.getFileCache(a.file)?.frontmatter;i.push({path:a.file.path,listPinned:l?.listPinned,listPinnedAt:l?.listPinnedAt});let c=t?typeof l?.listPinnedAt=="string"&&Date.parse(l.listPinnedAt)||Date.parse(s):0;this.listPinnedState.set(a.file.path,{pinned:t,at:c}),await this.app.fileManager.processFrontMatter(a.file,A=>{t?(A.listPinned=!0,A.listPinnedAt||(A.listPinnedAt=s)):(delete A.listPinned,delete A.listPinnedAt)}),n.push(a.id)}let o=this.noteFolder;this.tree.rebuild(o),this.render(),this.plugin.notifications.show({message:t?`Pinned ${n.length} to top of list`:`Unpinned ${n.length} from list`,kind:"success",category:"edit",affectedIds:n,folder:o}),this.plugin.getUndoStack(o).push({label:t?`Pin to top (${n.length})`:`Unpin from top (${n.length})`,undo:async()=>{for(let a of i){let l=this.app.vault.getAbstractFileByPath(a.path);if(!l)continue;await this.app.fileManager.processFrontMatter(l,h=>{a.listPinned===void 0?delete h.listPinned:h.listPinned=a.listPinned,a.listPinnedAt===void 0?delete h.listPinnedAt:h.listPinnedAt=a.listPinnedAt});let c=a.listPinned===!0,A=typeof a.listPinnedAt=="string"&&Date.parse(a.listPinnedAt)||0;this.listPinnedState.set(a.path,{pinned:c,at:A})}this.tree.rebuild(o),this.render()}})}async cmdToggleComplete(){let e=this.getActionTargets();if(e.length===0){let l=this.tree.get(this.focusId);l?.file&&(e=[l])}if(e.length===0){new k.Notice("Nothing to toggle.");return}let i=e.some(l=>!this.isCompleted(l)),s=[],n=[],o=[];for(let l of e){if(!l.file)continue;let c=this.isCompleted(l),A=this.app.metadataCache.getFileCache(l.file)?.frontmatter,h=A?.due!=null?String(A.due):null,p={id:l.id,path:l.file.path,was:c,dueBefore:h,rolledTo:null};if(s.push(p),c===i)continue;let f=!1;this.markFmSelfWrite(l.file.path),await this.app.fileManager.processFrontMatter(l.file,u=>{let g=i?vn(u.repeat):null;if(g){let I=u.due!=null?Date.parse(String(u.due)):NaN,m=Qn(g,Number.isFinite(I)?I:null,Date.now());u.due=new Date(m).toISOString(),delete u.completed,p.rolledTo=u.due,o.push({title:l.file.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ").trim()||"task",when:m}),f=!0}else i?u.completed=!0:delete u.completed}),this.completedState.set(l.file.path,f?!1:i),n.push(l.id)}this.render();for(let l of o)this.plugin.notifications.show({message:`\u{1F501} Rescheduled \u201C${l.title}\u201D \u2192 ${it(l.when,this.plugin.settings)}.`,kind:"success",category:"system",folder:this.noteFolder});if(n.length>0){await this.log.append({type:i?"complete":"uncomplete",id:n[0],payload:{ids:n,count:n.length}});let l=n.map(c=>this.tree.get(c)).filter(c=>!!c);this.plugin.notifications.show({message:this.bulkActionMessage({verb:i?"Marked complete":"Unmarked",nodes:l}),kind:"success",category:i?"complete":"uncomplete",affectedIds:n,folder:this.noteFolder})}let a=this.noteFolder;this.plugin.getUndoStack(a).push({label:`${i?"Mark complete":"Unmark complete"} (${e.length})`,undo:async()=>{let l=[];for(let c of s){let A=this.app.vault.getAbstractFileByPath(c.path);A&&(await this.app.fileManager.processFrontMatter(A,h=>{c.rolledTo!=null?(c.dueBefore!=null?h.due=c.dueBefore:delete h.due,delete h.completed):c.was?h.completed=!0:delete h.completed}),n.includes(c.id)&&l.push(c.id))}l.length>0&&await this.log.append({type:i?"uncomplete":"complete",id:l[0],payload:{ids:l,count:l.length,undo:!0}}),this.tree.rebuild(a),this.render()},redo:async()=>{for(let l of s){let c=this.app.vault.getAbstractFileByPath(l.path);c&&await this.app.fileManager.processFrontMatter(c,A=>{l.rolledTo!=null?(A.due=l.rolledTo,delete A.completed):i?A.completed=!0:delete A.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(a),this.render()}})}isCompleted(e){if(!e.file)return!1;let t=this.completedState.get(e.file.path);return t!==void 0?t:!!this.app.metadataCache.getFileCache(e.file)?.frontmatter?.completed}taggedFromFm(e){return e?di(e,"task")||e.task===!0:!1}cmdSetDue(e){let t;if(e)t=[e];else if(t=this.getActionTargets(),t.length===0){let l=this.tree.get(this.focusId);l?.file&&(t=[l])}if(t.length===0){new k.Notice("Nothing to schedule.");return}let i=t[0],s=i.file?this.app.metadataCache.getFileCache(i.file)?.frontmatter:null,n=s&&(typeof s.due=="string"||typeof s.due=="number")?String(s.due):null,o=this.plugin.collectKnownAuthors(),a=xt(s??{});new ze(this.app,n,l=>{this.applyDue(t,l.iso,l.assignees,!1,{repeat:l.repeat,autoDoneAfter:l.autoDoneAfter,remindEvery:l.remindEvery})},{knownAuthors:o,currentAssignees:a,quickAdjusts:this.plugin.settings.dueQuickAdjusts,showRecurrence:t.length===1,currentRepeat:typeof s?.repeat=="string"?s.repeat:"",currentAutoDoneAfter:typeof s?.autoDoneAfter=="string"?s.autoDoneAfter:"",currentRemindEvery:typeof s?.remindEvery=="string"?s.remindEvery:""}).open()}cmdSnooze(e){let t;if(e)t=[e];else if(t=this.getActionTargets(),t.length===0){let o=this.tree.get(this.focusId);o?.file&&(t=[o])}if(t.length===0){new k.Notice("Nothing to snooze.");return}let i=t[0],s=i.file?this.app.metadataCache.getFileCache(i.file)?.frontmatter:null,n=s&&(typeof s.due=="string"||typeof s.due=="number")?String(s.due):null;new ze(this.app,n,o=>{this.applyDue(t,o.iso,[],!0)},{title:"Snooze \u2014 reschedule",hideAssignees:!0,quickAdjusts:this.plugin.settings.dueQuickAdjusts}).open()}async applyDue(e,t,i=[],s=!1,n){let o=[],a=[],l=this.authorship.currentAuthorLink();for(let h of i)await this.plugin.ensureAuthorStubFor(this.noteFolder,h.id,h.name);let c=i.map(h=>this.plugin.authorRefFor(this.noteFolder,h.id,h.name));for(let h of e){if(!h.file)continue;let p=this.app.metadataCache.getFileCache(h.file)?.frontmatter,f=this.isTaskTagged(h);o.push({id:h.id,path:h.file.path,due:p?.due,task:p?.task,assignedTo:p?.assignedTo,assignedBy:p?.assignedBy,wasTagged:f,repeat:p?.repeat,autoDoneAfter:p?.autoDoneAfter,remindEvery:p?.remindEvery}),this.markFmSelfWrite(h.file.path),await this.app.fileManager.processFrontMatter(h.file,g=>{if(t===null?delete g.due:(g.due=t,g.task=!0),n){let I=(m,C)=>{let B=(C??"").trim();B?(g[m]=B,g.task=!0):delete g[m]};I("repeat",n.repeat),I("autoDoneAfter",n.autoDoneAfter),I("remindEvery",n.remindEvery)}s||(c.length>0?(g.assignedTo=c,l&&(g.assignedBy=l.link),g.task=!0):(delete g.assignedTo,delete g.assignedBy))});let u=t!==null||c.length>0;this.taskTaggedState.set(h.file.path,u||f),a.push(h.id)}if(this.render(),a.length>0){let h=a.map(p=>this.tree.get(p)).filter(p=>!!p);this.plugin.notifications.show({message:this.bulkActionMessage({verb:t===null?"Cleared due date":`Due ${it(Date.parse(t),this.plugin.settings)}`,nodes:h}),kind:"success",category:"edit",affectedIds:a,folder:this.noteFolder})}let A=this.noteFolder;this.plugin.getUndoStack(A).push({label:t===null?`Clear due date (${e.length})`:`Set due date (${e.length})`,undo:async()=>{for(let h of o){let p=this.app.vault.getAbstractFileByPath(h.path);p&&(await this.app.fileManager.processFrontMatter(p,f=>{h.due===void 0?delete f.due:f.due=h.due,h.task===void 0?delete f.task:f.task=h.task,h.assignedTo===void 0?delete f.assignedTo:f.assignedTo=h.assignedTo,h.assignedBy===void 0?delete f.assignedBy:f.assignedBy=h.assignedBy,h.repeat===void 0?delete f.repeat:f.repeat=h.repeat,h.autoDoneAfter===void 0?delete f.autoDoneAfter:f.autoDoneAfter=h.autoDoneAfter,h.remindEvery===void 0?delete f.remindEvery:f.remindEvery=h.remindEvery}),this.taskTaggedState.set(h.path,h.wasTagged))}this.tree.rebuild(A),this.render()}})}cmdAssign(){let e=this.getActionTargets();if(e.length===0){let a=this.tree.get(this.focusId);a?.file&&(e=[a])}if(e.length===0){new k.Notice("Nothing to assign.");return}let t=e[0],i=t.file?this.app.metadataCache.getFileCache(t.file)?.frontmatter:null,s=i&&(typeof i.due=="string"||typeof i.due=="number")?String(i.due):null,n=this.plugin.collectKnownAuthors(),o=xt(i??{});new ze(this.app,s,a=>{this.applyDue(e,a.iso,a.assignees,!1,{repeat:a.repeat,autoDoneAfter:a.autoDoneAfter,remindEvery:a.remindEvery})},{knownAuthors:n,currentAssignees:o,title:"Assign / schedule task",quickAdjusts:this.plugin.settings.dueQuickAdjusts,showRecurrence:e.length===1,currentRepeat:typeof i?.repeat=="string"?i.repeat:"",currentAutoDoneAfter:typeof i?.autoDoneAfter=="string"?i.autoDoneAfter:"",currentRemindEvery:typeof i?.remindEvery=="string"?i.remindEvery:""}).open()}isTask(e){return e.file?this.isTaskTagged(e)?!0:this.app.metadataCache.getFileCache(e.file)?.frontmatter?.completed!==void 0:!1}async cmdToggleTask(){let e=this.getActionTargets();if(e.length===0){let a=this.tree.get(this.focusId);a?.file&&(e=[a])}if(e.length===0){new k.Notice("Nothing to toggle.");return}let t=e.some(a=>!this.isTaskTagged(a)),i=[],s=[];for(let a of e){if(!a.file)continue;let l=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,wasTagged:l}),l===t)continue;let A=!1;this.markFmSelfWrite(a.file.path),await this.app.fileManager.processFrontMatter(a.file,h=>{t?(yo(h,"task"),h.completed===void 0&&(h.completed=!1),A=h.completed===!0,delete h.task):(wo(h,"task"),delete h.completed,delete h.task,A=!1)}),this.completedState.set(a.file.path,A),this.taskTaggedState.set(a.file.path,t),s.push(a.id)}if(this.render(),s.length>0){let a=t?"marked as task":"unmarked as task",l;if(s.length===1){let c=this.tree.get(s[0]);l=`"${c&&this.titleForNode(c).trim()||"(untitled)"}" ${a}`}else l=`${s.length} notes ${a}`;this.plugin.notifications.show({message:l,kind:"success",category:"edit",affectedIds:s,folder:this.noteFolder})}let n=this.noteFolder,o=async()=>{for(let a of i){let l=this.app.vault.getAbstractFileByPath(a.path);l&&(await this.app.fileManager.processFrontMatter(l,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.completedState.set(a.path,!!a.completed),this.taskTaggedState.set(a.path,a.wasTagged))}this.tree.rebuild(n),this.render()};this.plugin.getUndoStack(n).push({label:`${t?"Mark task":"Unmark task"} (${e.length})`,undo:o,redo:async()=>{for(let a of i){let l=this.app.vault.getAbstractFileByPath(a.path);if(!l)continue;let c=!1;await this.app.fileManager.processFrontMatter(l,A=>{t?(yo(A,"task"),A.completed===void 0&&(A.completed=!1),c=A.completed===!0,delete A.task):(wo(A,"task"),delete A.completed,delete A.task,c=!1)}),this.completedState.set(a.path,c),this.taskTaggedState.set(a.path,t)}this.tree.rebuild(n),this.render()}})}async toggleCompletedForNode(e){if(!e.file)return;let t=e.file.path,i=this.isCompleted(e);await this.app.fileManager.processFrontMatter(e.file,n=>{n.completed=!i}),this.completedState.set(t,!i),await this.log.append({type:i?"uncomplete":"complete",id:e.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(t);n&&(await this.app.fileManager.processFrontMatter(n,o=>{o.completed=i}),this.tree.rebuild(s),this.render())}})}isTaskTagged(e){if(!e.file)return!1;let t=this.taskTaggedState.get(e.file.path);if(t!==void 0)return t;let i=this.app.metadataCache.getFileCache(e.file)?.frontmatter;return this.taggedFromFm(i)}colorForNode(e){if(!e.file)return null;let t=this.app.metadataCache.getFileCache(e.file)?.frontmatter?.color;if(typeof t!="string")return null;let i=t.trim();return/^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(i)?i:null}inheritedColorForNode(e){let t=e,i=0,s=new Set;for(;t&&t.id!==S&&!s.has(t.id);){s.add(t.id);let n=this.colorForNode(t);if(n)return{hex:n,depth:i};t=t.parent?this.tree.get(t.parent):void 0,i+=1}return null}isDescendant(e,t){let i=this.tree.get(e),s=new Set;for(;i&&i.parent&&!s.has(i.id);){if(i.parent===t)return!0;s.add(i.id),i=this.tree.get(i.parent)}return!1}async moveAcrossThenReorder(e,t,i,s,n="Reparented"){let o=[],a=new Set;for(let w of e){let F=this.tree.get(w);F?.file&&(o.push({id:w,path:F.file.path,oldParent:F.parent}),a.add(F.parent??S))}a.add(t);let l=this.authorship.collectAuthorIds(e.map(w=>this.tree.get(w)).filter(w=>!!w)),c=this.noteFolder,A={};for(let w of a)A[w]=this.order.getOrder(c,w).slice();for(let w of o){let F=this.app.vault.getAbstractFileByPath(w.path);F&&(await this.app.fileManager.processFrontMatter(F,D=>{D.parent=t}),this.fmSync.scheduleParentChange(w.id,w.oldParent,t),await this.log.append({type:"parent_change",id:w.id,payload:{from:w.oldParent,to:t,reason:"drag"}}),this.order.removeChild(c,w.id))}this.tree.rebuild(c);let h=this.tree.getChildren(t).map(w=>w.id),p=new Set(e),f=h.filter(w=>!p.has(w)),u=f.indexOf(i);u<0&&(u=f.length),s==="after"&&(u+=1);let g=[...f.slice(0,u),...e.filter(w=>!!this.tree.get(w)),...f.slice(u)];this.order.setOrder(c,t,g),await this.order.save(c),await this.forceManualMode(t),await this.log.append({type:"reorder",id:t,payload:{dir:"drag-cross",parent:t,ids:e,count:e.length}});let I=this.focusId===t,m=I?e[0]:t,C=I?e.slice():[t];I?this.pendingFocusIds=C:(this.selection.clear(),this.cursorIdx=-1,this.pendingFocusIds=C),this.tree.rebuild(c),this.render({kind:"follow-cursor"});let B=this.selectionGuardKey,E=()=>{if(this.selectionGuardKey!==B||this.selection.has(m))return;let w=this.currentChildren.findIndex(F=>F.id===m);w<0||(this.selection.add(m),this.cursorIdx=w,this.render({kind:"follow-cursor"}))};setTimeout(E,120),setTimeout(E,400);let y=e.map(w=>this.tree.get(w)).filter(w=>!!w),v=this.tree.get(t),Q=v?this.titleForNode(v):"(root)";this.plugin.notifications.show({message:this.bulkActionMessage({verb:n,nodes:y,destination:`\u2192 "${Q}"`}),kind:"success",category:"move",affectedIds:e,affectedAuthorIds:l,folder:c,actions:t===S?[]:[{label:"Jump to parent",onClick:()=>this.navigateTo(t)}]}),this.plugin.getUndoStack(c).push({label:`Move + reorder (${e.length})`,undo:async()=>{for(let w of o){let F=this.fileForNote(w.id,w.path);F&&(await this.app.fileManager.processFrontMatter(F,D=>{w.oldParent===null||w.oldParent===void 0?D.parent=S:D.parent=w.oldParent}),await this.log.append({type:"parent_change",id:w.id,payload:{from:t,to:w.oldParent,reason:"drag-undo"}}))}for(let[w,F]of Object.entries(A))if(F.length===0){let D=this.order.cache.get(c)??{};delete D[w],this.order.cache.set(c,D)}else this.order.setOrder(c,w,F);await this.order.save(c),this.pendingFocusIds=e.slice(),this.selection.clear(),this.cursorIdx=-1,this.tree.rebuild(c),this.render()},redo:async()=>{for(let w of o){let F=this.fileForNote(w.id,w.path);F&&(await this.app.fileManager.processFrontMatter(F,D=>{D.parent=t}),this.order.removeChild(c,w.id))}this.order.setOrder(c,t,g),await this.order.save(c),this.pendingFocusIds=e.slice(),this.focusId!==t&&(this.selection.clear(),this.cursorIdx=-1),this.tree.rebuild(c),this.render()}})}async reorderToTarget(e,t,i){let s=this.tree.get(t);if(!s)return;let n=e.map(C=>this.tree.get(C)).filter(C=>!!C&&!!C.file);if(n.length===0)return;if(n.some(C=>C.id===t)){this.plugin.notifications.show({message:"Can't move a note into itself.",kind:"warning",category:"move",folder:this.noteFolder});return}let o=i==="into"?t:s.parent??S;for(let C of n)if(o===C.id||this.isDescendant(o,C.id)){this.plugin.notifications.show({message:`Can't move "${this.titleForNode(C)}" under itself or one of its own descendants \u2014 that would create a cycle.`,kind:"warning",category:"move",folder:this.noteFolder});return}if(n.some(C=>(C.parent??S)!==o)){let C=X(),B=async()=>{i==="into"?await this.moveAcrossThenReorder(n.map(E=>E.id),o,"","after","Nested"):await this.moveAcrossThenReorder(n.map(E=>E.id),o,t,i,"Moved")};if(C.confirmCrossParentDrag){let E=this.titleForNode(s),y=E.length>120?E.slice(0,120).trimEnd()+"\u2026":E,v=n.length,Q=i==="into"?"Nest":"Move",w=i==="into"?"as children of":"under";new j(this.app,i==="into"?"Nest under target?":"Move under different parent?",`${Q} ${v} note${v===1?"":"s"} ${w}: +Error: ${t.message}`,kind:"error",category:"system",duration:0,affectedPaths:[e],folder:this.noteFolder})}))}async ensureHomeNote(){let e=this.noteFolder,t=`${e}/${this.buildHomeFilename(e)}`,i=this.app.vault.getMarkdownFiles().filter(o=>o.path.startsWith(e+"/"));for(let o of i){if(this.app.metadataCache.getFileCache(o)?.frontmatter?.id!==S)continue;if(o.path===t||this.app.vault.getAbstractFileByPath(t))return o;try{await this.app.fileManager.renameFile(o,t);let c=this.app.vault.getAbstractFileByPath(t);if(c instanceof F.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: ${S}`,"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(t,n)}buildHomeFilename(e){return`Home-${(e.split("/").filter(Boolean).pop()??"Stashpad").replace(/[^A-Za-z0-9_-]+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"")||"Stashpad"}.md`}async migrateNullParents(){let e=this.noteFolder,t=this.app.vault.getMarkdownFiles().filter(i=>i.path.startsWith(e+"/"));for(let i of t){let s=this.app.metadataCache.getFileCache(i)?.frontmatter,n=s?.id;if(!n||n===S)continue;let o=s?.parent;(o==null||o===""||o==="null")&&(await this.app.fileManager.processFrontMatter(i,a=>{a.parent=S}),await this.log.append({type:"parent_change",id:n,payload:{from:null,to:S,reason:"migration"}}))}}async openParentInBackgroundTab(e){if(!this.plugin.settings.openParentTabOnMoveIn||!e||e===S)return;let t=this.app.workspace,i=!1;if(t.iterateAllLeaves(n=>{let o=n.view;o?.getViewType?.()===$&&o?.focusId===e&&o?.noteFolder===this.noteFolder&&(i=!0)}),i)return;let s=t.activeLeaf;try{await t.getLeaf("tab").setViewState({type:$,active:!1,state:{focusId:e,timeFilter:this.timeFilter,folderOverride:this.folderOverride}}),s&&t.setActiveLeaf(s,{focus:!0})}catch(n){console.warn("[Stashpad] background parent tab failed",n)}}async openInNewStashpadTab(e){let t=this.app.workspace,i=this.leaf,s=t.getLeaf("tab");await s.setViewState({type:$,active:!0,state:{focusId:e,timeFilter:this.timeFilter,folderOverride:this.folderOverride}}),t.setActiveLeaf(s,{focus:!0}),t.revealLeaf(s),yt(t,s,i,n=>this.plugin.registerEvent(n))}async openNoteInNewTab(e,t,i){let s=(e||"").trim().replace(/^\/+|\/+$/g,"");if(!s||!t)return;let n=(this.plugin.settings.folder||"Stashpad").trim().replace(/^\/+|\/+$/g,"")||"Stashpad",o=this.app.workspace,a=this.leaf,l=o.getLeaf("tab");await l.setViewState({type:$,active:!0,state:{focusId:t,folderOverride:s===n?null:s,...i?{cursorId:i}:{}}}),o.setActiveLeaf(l,{focus:!0}),o.revealLeaf(l),yt(o,l,a,c=>this.plugin.registerEvent(c))}async openFolderInNewTab(e){let t=(e||"").trim().replace(/^\/+|\/+$/g,"");if(!t)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:$,active:!0,state:{focusId:S,folderOverride:t===i?null:t}}),s.setActiveLeaf(o,{focus:!0}),s.revealLeaf(o),yt(s,o,n,a=>this.plugin.registerEvent(a))}cmdOpenInEditor(e){if(e){this.openFileAtEnd(e.file);return}let t=this.getActionTargets();if(t.length)for(let i of t)i.file&&this.openFileAtEnd(i.file)}async cmdCopyStashpadLink(e){let i=(e?[e]:this.getActionTargets()).filter(n=>!!n?.id);if(i.length===0){new F.Notice("No note selected to link to.");return}let s=i.map(n=>Nn({vault:this.app.vault.getName(),folder:this.noteFolder,note:n.id,run:["reveal"]}));try{await navigator.clipboard.writeText(s.join(` +`)),new F.Notice(s.length>1?`${s.length} Stashpad links copied.`:"Stashpad link copied.")}catch{new F.Notice("Couldn't copy the link to the clipboard.")}}cmdOpenParentInEditor(){let e=this.tree.get(this.focusId);if(!e?.file){new F.Notice("No focused parent to open.");return}this.openFileAtEnd(e.file)}async openFileAtEnd(e){let t=this.app.workspace,i=this.leaf,s=t.getLeaf("tab");await s.openFile(e,{active:!0}),t.setActiveLeaf(s,{focus:!0}),t.revealLeaf(s),yt(t,s,i,a=>this.plugin.registerEvent(a));let o=s.view?.editor;o&&requestAnimationFrame(()=>{try{let a=o.lastLine(),l=o.getLine(a)?.length??0;o.setCursor({line:a,ch:l}),o.scrollIntoView({from:{line:a,ch:l},to:{line:a,ch:l}},!0),o.focus()}catch{}})}cmdSelectAll(){if(this.currentChildren.length!==0){this.selection.clear();for(let e of this.currentChildren)this.selection.add(e.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 e=this.getActionTargets();if(e.length===0){let n=this.tree.get(this.focusId);n?.file&&(e=[n])}if(e.length===0){new F.Notice("Nothing to pin.");return}let t=e.some(n=>!this.plugin.isPinned({folder:this.noteFolder,id:n.id})),i=0,s=0;for(let n of e){let o={folder:this.noteFolder,id:n.id};t?this.plugin.isPinned(o)||(await this.plugin.pinNote(o),i++):this.plugin.isPinned(o)&&(await this.plugin.unpinNote(o),s++)}i>0?new F.Notice(`Pinned ${i} note${i===1?"":"s"} to sidebar.`):s>0&&new F.Notice(`Unpinned ${s} note${s===1?"":"s"} from sidebar.`)}isListPinned(e){let t=this.tree.get(e);if(!t?.file)return!1;let i=this.listPinnedState.get(t.file.path);return i?i.pinned:this.app.metadataCache.getFileCache(t.file)?.frontmatter?.listPinned===!0}listPinnedAt(e){let t=this.tree.get(e);if(!t?.file)return 0;let i=this.listPinnedState.get(t.file.path);if(i)return i.at;let s=this.app.metadataCache.getFileCache(t.file)?.frontmatter?.listPinnedAt,n=typeof s=="string"?Date.parse(s):NaN;return Number.isNaN(n)?0:n}hoistListPinned(e,t){let i=this.tree.getChildren(e).map(l=>l.id);if(!i.some(l=>this.isListPinned(l)))return t;let s=new Set(t),n=[...t,...i.filter(l=>!s.has(l))],o=n.filter(l=>this.isListPinned(l)).sort((l,c)=>this.listPinnedAt(l)-this.listPinnedAt(c)),a=n.filter(l=>!this.isListPinned(l));return[...o,...a]}async cmdToggleListPin(){let e=this.getActionTargets();if(e.length===0){let a=this.tree.get(this.focusId);a?.file&&(e=[a])}if(e.length===0){new F.Notice("Nothing to pin.");return}let t=e.some(a=>!this.isListPinned(a.id)),i=[],s=new Date().toISOString(),n=[];for(let a of e){if(!a.file)continue;let l=this.app.metadataCache.getFileCache(a.file)?.frontmatter;i.push({path:a.file.path,listPinned:l?.listPinned,listPinnedAt:l?.listPinnedAt});let c=t?typeof l?.listPinnedAt=="string"&&Date.parse(l.listPinnedAt)||Date.parse(s):0;this.listPinnedState.set(a.file.path,{pinned:t,at:c}),await this.app.fileManager.processFrontMatter(a.file,d=>{t?(d.listPinned=!0,d.listPinnedAt||(d.listPinnedAt=s)):(delete d.listPinned,delete d.listPinnedAt)}),n.push(a.id)}let o=this.noteFolder;this.tree.rebuild(o),this.render(),this.plugin.notifications.show({message:t?`Pinned ${n.length} to top of list`:`Unpinned ${n.length} from list`,kind:"success",category:"edit",affectedIds:n,folder:o}),this.plugin.getUndoStack(o).push({label:t?`Pin to top (${n.length})`:`Unpin from top (${n.length})`,undo:async()=>{for(let a of i){let l=this.app.vault.getAbstractFileByPath(a.path);if(!l)continue;await this.app.fileManager.processFrontMatter(l,h=>{a.listPinned===void 0?delete h.listPinned:h.listPinned=a.listPinned,a.listPinnedAt===void 0?delete h.listPinnedAt:h.listPinnedAt=a.listPinnedAt});let c=a.listPinned===!0,d=typeof a.listPinnedAt=="string"&&Date.parse(a.listPinnedAt)||0;this.listPinnedState.set(a.path,{pinned:c,at:d})}this.tree.rebuild(o),this.render()}})}async cmdToggleComplete(){let e=this.getActionTargets();if(e.length===0){let l=this.tree.get(this.focusId);l?.file&&(e=[l])}if(e.length===0){new F.Notice("Nothing to toggle.");return}let i=e.some(l=>!this.isCompleted(l)),s=[],n=[],o=[];for(let l of e){if(!l.file)continue;let c=this.isCompleted(l),d=this.app.metadataCache.getFileCache(l.file)?.frontmatter,h=d?.due!=null?String(d.due):null,p={id:l.id,path:l.file.path,was:c,dueBefore:h,rolledTo:null};if(s.push(p),c===i)continue;let f=!1;this.markFmSelfWrite(l.file.path),await this.app.fileManager.processFrontMatter(l.file,u=>{let g=i?kn(u.repeat):null;if(g){let I=u.due!=null?Date.parse(String(u.due)):NaN,m=Fn(g,Number.isFinite(I)?I:null,Date.now());u.due=new Date(m).toISOString(),delete u.completed,p.rolledTo=u.due,o.push({title:l.file.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ").trim()||"task",when:m}),f=!0}else i?u.completed=!0:delete u.completed}),this.completedState.set(l.file.path,f?!1:i),n.push(l.id)}this.render();for(let l of o)this.plugin.notifications.show({message:`\u{1F501} Rescheduled \u201C${l.title}\u201D \u2192 ${it(l.when,this.plugin.settings)}.`,kind:"success",category:"system",folder:this.noteFolder});if(n.length>0){await this.log.append({type:i?"complete":"uncomplete",id:n[0],payload:{ids:n,count:n.length}});let l=n.map(c=>this.tree.get(c)).filter(c=>!!c);this.plugin.notifications.show({message:this.bulkActionMessage({verb:i?"Marked complete":"Unmarked",nodes:l}),kind:"success",category:i?"complete":"uncomplete",affectedIds:n,folder:this.noteFolder})}let a=this.noteFolder;this.plugin.getUndoStack(a).push({label:`${i?"Mark complete":"Unmark complete"} (${e.length})`,undo:async()=>{let l=[];for(let c of s){let d=this.app.vault.getAbstractFileByPath(c.path);d&&(await this.app.fileManager.processFrontMatter(d,h=>{c.rolledTo!=null?(c.dueBefore!=null?h.due=c.dueBefore:delete h.due,delete h.completed):c.was?h.completed=!0:delete h.completed}),n.includes(c.id)&&l.push(c.id))}l.length>0&&await this.log.append({type:i?"uncomplete":"complete",id:l[0],payload:{ids:l,count:l.length,undo:!0}}),this.tree.rebuild(a),this.render()},redo:async()=>{for(let l of s){let c=this.app.vault.getAbstractFileByPath(l.path);c&&await this.app.fileManager.processFrontMatter(c,d=>{l.rolledTo!=null?(d.due=l.rolledTo,delete d.completed):i?d.completed=!0:delete d.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(a),this.render()}})}isCompleted(e){if(!e.file)return!1;let t=this.completedState.get(e.file.path);return t!==void 0?t:!!this.app.metadataCache.getFileCache(e.file)?.frontmatter?.completed}taggedFromFm(e){return e?Ai(e,"task")||e.task===!0:!1}cmdSetDue(e){let t;if(e)t=[e];else if(t=this.getActionTargets(),t.length===0){let l=this.tree.get(this.focusId);l?.file&&(t=[l])}if(t.length===0){new F.Notice("Nothing to schedule.");return}let i=t[0],s=i.file?this.app.metadataCache.getFileCache(i.file)?.frontmatter:null,n=s&&(typeof s.due=="string"||typeof s.due=="number")?String(s.due):null,o=this.plugin.collectKnownAuthors(),a=xt(s??{});new ze(this.app,n,l=>{this.applyDue(t,l.iso,l.assignees,!1,{repeat:l.repeat,autoDoneAfter:l.autoDoneAfter,remindEvery:l.remindEvery})},{knownAuthors:o,currentAssignees:a,quickAdjusts:this.plugin.settings.dueQuickAdjusts,showRecurrence:t.length===1,currentRepeat:typeof s?.repeat=="string"?s.repeat:"",currentAutoDoneAfter:typeof s?.autoDoneAfter=="string"?s.autoDoneAfter:"",currentRemindEvery:typeof s?.remindEvery=="string"?s.remindEvery:""}).open()}cmdSnooze(e){let t;if(e)t=[e];else if(t=this.getActionTargets(),t.length===0){let o=this.tree.get(this.focusId);o?.file&&(t=[o])}if(t.length===0){new F.Notice("Nothing to snooze.");return}let i=t[0],s=i.file?this.app.metadataCache.getFileCache(i.file)?.frontmatter:null,n=s&&(typeof s.due=="string"||typeof s.due=="number")?String(s.due):null;new ze(this.app,n,o=>{this.applyDue(t,o.iso,[],!0)},{title:"Snooze \u2014 reschedule",hideAssignees:!0,quickAdjusts:this.plugin.settings.dueQuickAdjusts}).open()}async applyDue(e,t,i=[],s=!1,n){let o=[],a=[],l=this.authorship.currentAuthorLink();for(let h of i)await this.plugin.ensureAuthorStubFor(this.noteFolder,h.id,h.name);let c=i.map(h=>this.plugin.authorRefFor(this.noteFolder,h.id,h.name));for(let h of e){if(!h.file)continue;let p=this.app.metadataCache.getFileCache(h.file)?.frontmatter,f=this.isTaskTagged(h);o.push({id:h.id,path:h.file.path,due:p?.due,task:p?.task,assignedTo:p?.assignedTo,assignedBy:p?.assignedBy,wasTagged:f,repeat:p?.repeat,autoDoneAfter:p?.autoDoneAfter,remindEvery:p?.remindEvery}),this.markFmSelfWrite(h.file.path),await this.app.fileManager.processFrontMatter(h.file,g=>{if(t===null?delete g.due:(g.due=t,g.task=!0),n){let I=(m,C)=>{let B=(C??"").trim();B?(g[m]=B,g.task=!0):delete g[m]};I("repeat",n.repeat),I("autoDoneAfter",n.autoDoneAfter),I("remindEvery",n.remindEvery)}s||(c.length>0?(g.assignedTo=c,l&&(g.assignedBy=l.link),g.task=!0):(delete g.assignedTo,delete g.assignedBy))});let u=t!==null||c.length>0;this.taskTaggedState.set(h.file.path,u||f),a.push(h.id)}if(this.render(),a.length>0){let h=a.map(p=>this.tree.get(p)).filter(p=>!!p);this.plugin.notifications.show({message:this.bulkActionMessage({verb:t===null?"Cleared due date":`Due ${it(Date.parse(t),this.plugin.settings)}`,nodes:h}),kind:"success",category:"edit",affectedIds:a,folder:this.noteFolder})}let d=this.noteFolder;this.plugin.getUndoStack(d).push({label:t===null?`Clear due date (${e.length})`:`Set due date (${e.length})`,undo:async()=>{for(let h of o){let p=this.app.vault.getAbstractFileByPath(h.path);p&&(await this.app.fileManager.processFrontMatter(p,f=>{h.due===void 0?delete f.due:f.due=h.due,h.task===void 0?delete f.task:f.task=h.task,h.assignedTo===void 0?delete f.assignedTo:f.assignedTo=h.assignedTo,h.assignedBy===void 0?delete f.assignedBy:f.assignedBy=h.assignedBy,h.repeat===void 0?delete f.repeat:f.repeat=h.repeat,h.autoDoneAfter===void 0?delete f.autoDoneAfter:f.autoDoneAfter=h.autoDoneAfter,h.remindEvery===void 0?delete f.remindEvery:f.remindEvery=h.remindEvery}),this.taskTaggedState.set(h.path,h.wasTagged))}this.tree.rebuild(d),this.render()}})}cmdAssign(){let e=this.getActionTargets();if(e.length===0){let a=this.tree.get(this.focusId);a?.file&&(e=[a])}if(e.length===0){new F.Notice("Nothing to assign.");return}let t=e[0],i=t.file?this.app.metadataCache.getFileCache(t.file)?.frontmatter:null,s=i&&(typeof i.due=="string"||typeof i.due=="number")?String(i.due):null,n=this.plugin.collectKnownAuthors(),o=xt(i??{});new ze(this.app,s,a=>{this.applyDue(e,a.iso,a.assignees,!1,{repeat:a.repeat,autoDoneAfter:a.autoDoneAfter,remindEvery:a.remindEvery})},{knownAuthors:n,currentAssignees:o,title:"Assign / schedule task",quickAdjusts:this.plugin.settings.dueQuickAdjusts,showRecurrence:e.length===1,currentRepeat:typeof i?.repeat=="string"?i.repeat:"",currentAutoDoneAfter:typeof i?.autoDoneAfter=="string"?i.autoDoneAfter:"",currentRemindEvery:typeof i?.remindEvery=="string"?i.remindEvery:""}).open()}isTask(e){return e.file?this.isTaskTagged(e)?!0:this.app.metadataCache.getFileCache(e.file)?.frontmatter?.completed!==void 0:!1}async cmdToggleTask(){let e=this.getActionTargets();if(e.length===0){let a=this.tree.get(this.focusId);a?.file&&(e=[a])}if(e.length===0){new F.Notice("Nothing to toggle.");return}let t=e.some(a=>!this.isTaskTagged(a)),i=[],s=[];for(let a of e){if(!a.file)continue;let l=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,wasTagged:l}),l===t)continue;let d=!1;this.markFmSelfWrite(a.file.path),await this.app.fileManager.processFrontMatter(a.file,h=>{t?(vo(h,"task"),h.completed===void 0&&(h.completed=!1),d=h.completed===!0,delete h.task):(Qo(h,"task"),delete h.completed,delete h.task,d=!1)}),this.completedState.set(a.file.path,d),this.taskTaggedState.set(a.file.path,t),s.push(a.id)}if(this.render(),s.length>0){let a=t?"marked as task":"unmarked as task",l;if(s.length===1){let c=this.tree.get(s[0]);l=`"${c&&this.titleForNode(c).trim()||"(untitled)"}" ${a}`}else l=`${s.length} notes ${a}`;this.plugin.notifications.show({message:l,kind:"success",category:"edit",affectedIds:s,folder:this.noteFolder})}let n=this.noteFolder,o=async()=>{for(let a of i){let l=this.app.vault.getAbstractFileByPath(a.path);l&&(await this.app.fileManager.processFrontMatter(l,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.completedState.set(a.path,!!a.completed),this.taskTaggedState.set(a.path,a.wasTagged))}this.tree.rebuild(n),this.render()};this.plugin.getUndoStack(n).push({label:`${t?"Mark task":"Unmark task"} (${e.length})`,undo:o,redo:async()=>{for(let a of i){let l=this.app.vault.getAbstractFileByPath(a.path);if(!l)continue;let c=!1;await this.app.fileManager.processFrontMatter(l,d=>{t?(vo(d,"task"),d.completed===void 0&&(d.completed=!1),c=d.completed===!0,delete d.task):(Qo(d,"task"),delete d.completed,delete d.task,c=!1)}),this.completedState.set(a.path,c),this.taskTaggedState.set(a.path,t)}this.tree.rebuild(n),this.render()}})}async toggleCompletedForNode(e){if(!e.file)return;let t=e.file.path,i=this.isCompleted(e);await this.app.fileManager.processFrontMatter(e.file,n=>{n.completed=!i}),this.completedState.set(t,!i),await this.log.append({type:i?"uncomplete":"complete",id:e.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(t);n&&(await this.app.fileManager.processFrontMatter(n,o=>{o.completed=i}),this.tree.rebuild(s),this.render())}})}isTaskTagged(e){if(!e.file)return!1;let t=this.taskTaggedState.get(e.file.path);if(t!==void 0)return t;let i=this.app.metadataCache.getFileCache(e.file)?.frontmatter;return this.taggedFromFm(i)}colorForNode(e){if(!e.file)return null;let t=this.app.metadataCache.getFileCache(e.file)?.frontmatter?.color;if(typeof t!="string")return null;let i=t.trim();return/^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(i)?i:null}inheritedColorForNode(e){let t=e,i=0,s=new Set;for(;t&&t.id!==S&&!s.has(t.id);){s.add(t.id);let n=this.colorForNode(t);if(n)return{hex:n,depth:i};t=t.parent?this.tree.get(t.parent):void 0,i+=1}return null}isDescendant(e,t){let i=this.tree.get(e),s=new Set;for(;i&&i.parent&&!s.has(i.id);){if(i.parent===t)return!0;s.add(i.id),i=this.tree.get(i.parent)}return!1}async moveAcrossThenReorder(e,t,i,s,n="Reparented"){let o=[],a=new Set;for(let w of e){let k=this.tree.get(w);k?.file&&(o.push({id:w,path:k.file.path,oldParent:k.parent}),a.add(k.parent??S))}a.add(t);let l=this.authorship.collectAuthorIds(e.map(w=>this.tree.get(w)).filter(w=>!!w)),c=this.noteFolder,d={};for(let w of a)d[w]=this.order.getOrder(c,w).slice();for(let w of o){let k=this.app.vault.getAbstractFileByPath(w.path);k&&(await this.app.fileManager.processFrontMatter(k,D=>{D.parent=t}),this.fmSync.scheduleParentChange(w.id,w.oldParent,t),await this.log.append({type:"parent_change",id:w.id,payload:{from:w.oldParent,to:t,reason:"drag"}}),this.order.removeChild(c,w.id))}this.tree.rebuild(c);let h=this.tree.getChildren(t).map(w=>w.id),p=new Set(e),f=h.filter(w=>!p.has(w)),u=f.indexOf(i);u<0&&(u=f.length),s==="after"&&(u+=1);let g=[...f.slice(0,u),...e.filter(w=>!!this.tree.get(w)),...f.slice(u)];this.order.setOrder(c,t,g),await this.order.save(c),await this.forceManualMode(t),await this.log.append({type:"reorder",id:t,payload:{dir:"drag-cross",parent:t,ids:e,count:e.length}});let I=this.focusId===t,m=I?e[0]:t,C=I?e.slice():[t];I?this.pendingFocusIds=C:(this.selection.clear(),this.cursorIdx=-1,this.pendingFocusIds=C),this.tree.rebuild(c),this.render({kind:"follow-cursor"});let B=this.selectionGuardKey,E=()=>{if(this.selectionGuardKey!==B||this.selection.has(m))return;let w=this.currentChildren.findIndex(k=>k.id===m);w<0||(this.selection.add(m),this.cursorIdx=w,this.render({kind:"follow-cursor"}))};setTimeout(E,120),setTimeout(E,400);let y=e.map(w=>this.tree.get(w)).filter(w=>!!w),v=this.tree.get(t),Q=v?this.titleForNode(v):"(root)";this.plugin.notifications.show({message:this.bulkActionMessage({verb:n,nodes:y,destination:`\u2192 "${Q}"`}),kind:"success",category:"move",affectedIds:e,affectedAuthorIds:l,folder:c,actions:t===S?[]:[{label:"Jump to parent",onClick:()=>this.navigateTo(t)}]}),this.openParentInBackgroundTab(t),this.plugin.getUndoStack(c).push({label:`Move + reorder (${e.length})`,undo:async()=>{for(let w of o){let k=this.fileForNote(w.id,w.path);k&&(await this.app.fileManager.processFrontMatter(k,D=>{w.oldParent===null||w.oldParent===void 0?D.parent=S:D.parent=w.oldParent}),await this.log.append({type:"parent_change",id:w.id,payload:{from:t,to:w.oldParent,reason:"drag-undo"}}))}for(let[w,k]of Object.entries(d))if(k.length===0){let D=this.order.cache.get(c)??{};delete D[w],this.order.cache.set(c,D)}else this.order.setOrder(c,w,k);await this.order.save(c),this.pendingFocusIds=e.slice(),this.selection.clear(),this.cursorIdx=-1,this.tree.rebuild(c),this.render()},redo:async()=>{for(let w of o){let k=this.fileForNote(w.id,w.path);k&&(await this.app.fileManager.processFrontMatter(k,D=>{D.parent=t}),this.order.removeChild(c,w.id))}this.order.setOrder(c,t,g),await this.order.save(c),this.pendingFocusIds=e.slice(),this.focusId!==t&&(this.selection.clear(),this.cursorIdx=-1),this.tree.rebuild(c),this.render()}})}async reorderToTarget(e,t,i){let s=this.tree.get(t);if(!s)return;let n=e.map(C=>this.tree.get(C)).filter(C=>!!C&&!!C.file);if(n.length===0)return;if(n.some(C=>C.id===t)){this.plugin.notifications.show({message:"Can't move a note into itself.",kind:"warning",category:"move",folder:this.noteFolder});return}let o=i==="into"?t:s.parent??S;for(let C of n)if(o===C.id||this.isDescendant(o,C.id)){this.plugin.notifications.show({message:`Can't move "${this.titleForNode(C)}" under itself or one of its own descendants \u2014 that would create a cycle.`,kind:"warning",category:"move",folder:this.noteFolder});return}if(n.some(C=>(C.parent??S)!==o)){let C=X(),B=async()=>{i==="into"?await this.moveAcrossThenReorder(n.map(E=>E.id),o,"","after","Nested"):await this.moveAcrossThenReorder(n.map(E=>E.id),o,t,i,"Moved")};if(C.confirmCrossParentDrag){let E=this.titleForNode(s),y=E.length>120?E.slice(0,120).trimEnd()+"\u2026":E,v=n.length,Q=i==="into"?"Nest":"Move",w=i==="into"?"as children of":"under";new j(this.app,i==="into"?"Nest under target?":"Move under different parent?",`${Q} ${v} note${v===1?"":"s"} ${w}: "${y}" -Their parent will change.`,Q,F=>{F&&B()}).open()}else await B();return}let l=o,c=n.map(C=>C.id),A=this.tree.getChildren(l).map(C=>C.id),h=new Set(c),p=A.filter(C=>!h.has(C)),f=p.indexOf(t);if(f<0)return;i==="after"&&(f+=1);let u=[...p.slice(0,f),...c,...p.slice(f)];if(Eo(u,A))return;let g=this.noteFolder,I=this.order.getOrder(g,l).slice();this.order.setOrder(g,l,u),await this.order.save(g),await this.forceManualMode(l),await this.log.append({type:"reorder",id:l,payload:{dir:"drag",parent:l,ids:c,count:c.length}}),this.pendingFocusIds=c.slice(),this.tree.rebuild(g),this.render();let m=c.map(C=>this.tree.get(C)).filter(C=>!!C);this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Reordered",nodes:m}),kind:"success",category:"reorder",affectedIds:c,folder:g}),this.plugin.getUndoStack(g).push({label:`Reorder (drag, ${c.length})`,undo:async()=>{if(I.length===0){let C=this.order.cache.get(g)??{};delete C[l],this.order.cache.set(g,C)}else this.order.setOrder(g,l,I);await this.order.save(g),await this.log.append({type:"reorder",id:l,payload:{dir:"undo",parent:l,ids:c,count:c.length}}),this.pendingFocusIds=c.slice(),this.tree.rebuild(g),this.render()},redo:async()=>{this.order.setOrder(g,l,u),await this.order.save(g),await this.log.append({type:"reorder",id:l,payload:{dir:"redo:drag",parent:l,ids:c,count:c.length}}),this.pendingFocusIds=c.slice(),this.tree.rebuild(g),this.render()}})}cmdMoveUp(){this.reorderSelection("up")}cmdMoveDown(){this.reorderSelection("down")}cmdMoveToTop(){this.reorderSelection("top")}cmdMoveToBottom(){this.reorderSelection("bottom")}async reorderSelection(e){let t=[];if(this.selection.size>0){let h=[...this.selection].map(f=>this.tree.get(f)).filter(f=>!!f&&!!f.file);if(h.length===0)return;if(new Set(h.map(f=>f.parent)).size>1){new k.Notice("Reorder requires a single-parent selection.");return}t=h}else this.cursorIdx>=0&&this.currentChildren[this.cursorIdx]&&(t=[this.currentChildren[this.cursorIdx]]);if(t.length===0){new k.Notice("Nothing to reorder.");return}let i=t[0].parent??S,s=this.tree.getChildren(i).map(h=>h.id);if(s.length===0)return;let n=new Set(t.map(h=>h.id)),o=s.filter(h=>n.has(h));if(o.length===0)return;let a=tr(s,o,e);if(Eo(a,s))return;let l=this.noteFolder,c=this.order.getOrder(l,i).slice();this.order.setOrder(l,i,a),await this.order.save(l),await this.forceManualMode(i),await this.log.append({type:"reorder",id:i,payload:{dir:e,parent:i,ids:o,count:o.length}}),this.pendingFocusIds=o.slice(),this.tree.rebuild(l),this.render({kind:"follow-cursor"});let A=o.map(h=>this.tree.get(h)).filter(h=>!!h);this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Moved",nodes:A,destination:e}),kind:"success",category:"reorder",affectedIds:o,folder:l}),this.plugin.getUndoStack(l).push({label:`Reorder (${e})`,undo:async()=>{if(c.length===0){let h=this.order.cache.get(l)??{};delete h[i],this.order.cache.set(l,h)}else this.order.setOrder(l,i,c);await this.order.save(l),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(l),this.render()},redo:async()=>{this.order.setOrder(l,i,a),await this.order.save(l),await this.log.append({type:"reorder",id:i,payload:{dir:`redo:${e}`,parent:i,ids:o,count:o.length}}),this.pendingFocusIds=o.slice(),this.tree.rebuild(l),this.render()}})}async cmdDeleteUnencrypted(){await this.cmdDelete({forcePlaintext:!0})}async cmdDelete(e={}){let t=this.getActionTargets();if(t.length===0){let B=this.tree.get(this.focusId);B?.file&&(t=[B])}if(t.length===0){new k.Notice("Nothing selected to delete.");return}let i=(this.noteFolder??"").replace(/\/+$/,""),s=(this.plugin.settings.folderEncPrefs??{})[i]??{},n=s.trashEncryptContent??!1,o=s.trashHandling==="obsidian";if(n&&!o&&!e.forcePlaintext){if(!this.plugin.encryption?.isConfigured?.()){new k.Notice("\u201CEncrypt items sent to trash\u201D is ON but encryption isn't set up (Settings \u2192 Stashpad \u2192 Encryption). Nothing was deleted.");return}await this.secureDeleteSources(t);return}if(!e.forcePlaintext&&!o){await this.plaintextDeleteToStashpadTrash(t);return}if(t.length===1){await this.deleteNote(t[0]);return}let a=[],l=new Set,c=B=>{if(!l.has(B.id)){l.add(B.id);for(let E of this.tree.getChildren(B.id))c(E);a.push(B)}};for(let B of t)c(B);let A=a.filter(B=>!!B.file),h=await Promise.all(A.map(B=>this.app.vault.read(B.file))),p=[];for(let B=0;B<A.length;B++){let E=A[B];p.push(...this.extractAttachments(this.stripFrontmatter(h[B])));let y=this.app.metadataCache.getFileCache(E.file)?.frontmatter;if(Array.isArray(y?.attachments))for(let v of y.attachments)typeof v=="string"&&v.trim()&&p.push(Jt(v))}let f=[...new Set(p)],u=a.length-t.length,g=async B=>{let E=await this.snapshotNotes(a,B),y=0;if(B)for(let b of f){let M=this.app.metadataCache.getFirstLinkpathDest(b,"");if(M)try{await this.app.fileManager.trashFile(M),await this.log.append({type:"attachment_remove",id:S,payload:{path:M.path}}),this.plugin.notifications.show({message:`Deleted attachment "${M.name}"`,kind:"warning",category:"attachment",affectedPaths:[M.path],folder:this.noteFolder}),y+=1}catch{}}let v=new Set;for(let b of a)b.parent&&v.add(b.parent);let Q=this.authorship.collectAuthorIds(a),w=new Set(t.map(b=>b.id)),F=this.currentChildren.map((b,M)=>w.has(b.id)?M:-1).filter(b=>b>=0),D=F.length>0?F[0]:-1,H=null;if(D>=0){for(let b=D+1;b<this.currentChildren.length;b++)if(!w.has(this.currentChildren[b].id)){H=this.currentChildren[b].id;break}if(!H){for(let b=D-1;b>=0;b--)if(!w.has(this.currentChildren[b].id)){H=this.currentChildren[b].id;break}}}for(let b of a)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:B?f:[]}})}this.selection.clear(),this.cursorIdx=-1,H&&(this.pendingFocusIds=[H]),this.tree.rebuild(this.noteFolder);for(let b of v)a.some(M=>M.id===b)||this.fmSync.scheduleParentOfDeleted(b);this.render({kind:"follow-cursor"});let R=y>0?` with ${y} attachment${y===1?"":"s"}`:"",L=this.noteFolder,x=t.map(b=>b.id),U=!1,T=async()=>{U||(U=!0,this.selection.clear(),this.cursorIdx=-1,await this.restoreSnapshots(E,x.slice()))};this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Deleted",nodes:t,suffix:R.trim()||void 0}),kind:"warning",category:"delete",duration:0,affectedIds:t.map(b=>b.id),affectedAuthorIds:Q,folder:this.noteFolder,actions:[{label:"Undo delete",onClick:()=>void T()}]}),this.plugin.getUndoStack(L).push({label:`Delete ${t.length} note${t.length===1?"":"s"}`,undo:async()=>{await T()},redo:async()=>{this.selection.clear(),this.cursorIdx=-1,U=!1,await this.trashNotesAndAttachments(E)}}),this.focusView()},I=X(),m=I.confirmBulkDelete,C=f.length>0&&I.confirmAttachmentDelete;if(!m&&!C){await g(!1);return}new Fi(this.app,`${t.length} selected note${t.length===1?"":"s"}`,u,f.length,C,g).open()}cmdEdit(e){return this.cmdSplit(e,"edit")}cmdComposerFullscreen(){let e=this.composerInputEl?.value??this.composerDraft??"",t=async()=>{this.composerInputEl&&(this.composerInputEl.value=""),this.composerDraft="";try{await this.saveDraft("")}catch{}},i=async n=>{let o=n.map(l=>l.trim()).filter(l=>l.length>0);if(o.length===0){new k.Notice("Nothing to save.");return}let a=this.focusId;this.autoSelectNewest=!0,this.scrollToBottomOnNextRender=!0,o.length===1?await this.createNoteUnder(o[0],a):await this.createNotesBatch(o,a,void 0,o.join(` +Their parent will change.`,Q,k=>{k&&B()}).open()}else await B();return}let l=o,c=n.map(C=>C.id),d=this.tree.getChildren(l).map(C=>C.id),h=new Set(c),p=d.filter(C=>!h.has(C)),f=p.indexOf(t);if(f<0)return;i==="after"&&(f+=1);let u=[...p.slice(0,f),...c,...p.slice(f)];if(ko(u,d))return;let g=this.noteFolder,I=this.order.getOrder(g,l).slice();this.order.setOrder(g,l,u),await this.order.save(g),await this.forceManualMode(l),await this.log.append({type:"reorder",id:l,payload:{dir:"drag",parent:l,ids:c,count:c.length}}),this.pendingFocusIds=c.slice(),this.tree.rebuild(g),this.render();let m=c.map(C=>this.tree.get(C)).filter(C=>!!C);this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Reordered",nodes:m}),kind:"success",category:"reorder",affectedIds:c,folder:g}),this.plugin.getUndoStack(g).push({label:`Reorder (drag, ${c.length})`,undo:async()=>{if(I.length===0){let C=this.order.cache.get(g)??{};delete C[l],this.order.cache.set(g,C)}else this.order.setOrder(g,l,I);await this.order.save(g),await this.log.append({type:"reorder",id:l,payload:{dir:"undo",parent:l,ids:c,count:c.length}}),this.pendingFocusIds=c.slice(),this.tree.rebuild(g),this.render()},redo:async()=>{this.order.setOrder(g,l,u),await this.order.save(g),await this.log.append({type:"reorder",id:l,payload:{dir:"redo:drag",parent:l,ids:c,count:c.length}}),this.pendingFocusIds=c.slice(),this.tree.rebuild(g),this.render()}})}cmdMoveUp(){this.reorderSelection("up")}cmdMoveDown(){this.reorderSelection("down")}cmdMoveToTop(){this.reorderSelection("top")}cmdMoveToBottom(){this.reorderSelection("bottom")}async reorderSelection(e){let t=[];if(this.selection.size>0){let h=[...this.selection].map(f=>this.tree.get(f)).filter(f=>!!f&&!!f.file);if(h.length===0)return;if(new Set(h.map(f=>f.parent)).size>1){new F.Notice("Reorder requires a single-parent selection.");return}t=h}else this.cursorIdx>=0&&this.currentChildren[this.cursorIdx]&&(t=[this.currentChildren[this.cursorIdx]]);if(t.length===0){new F.Notice("Nothing to reorder.");return}let i=t[0].parent??S,s=this.tree.getChildren(i).map(h=>h.id);if(s.length===0)return;let n=new Set(t.map(h=>h.id)),o=s.filter(h=>n.has(h));if(o.length===0)return;let a=nr(s,o,e);if(ko(a,s))return;let l=this.noteFolder,c=this.order.getOrder(l,i).slice();this.order.setOrder(l,i,a),await this.order.save(l),await this.forceManualMode(i),await this.log.append({type:"reorder",id:i,payload:{dir:e,parent:i,ids:o,count:o.length}}),this.pendingFocusIds=o.slice(),this.tree.rebuild(l),this.render({kind:"follow-cursor"});let d=o.map(h=>this.tree.get(h)).filter(h=>!!h);this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Moved",nodes:d,destination:e}),kind:"success",category:"reorder",affectedIds:o,folder:l}),this.plugin.getUndoStack(l).push({label:`Reorder (${e})`,undo:async()=>{if(c.length===0){let h=this.order.cache.get(l)??{};delete h[i],this.order.cache.set(l,h)}else this.order.setOrder(l,i,c);await this.order.save(l),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(l),this.render()},redo:async()=>{this.order.setOrder(l,i,a),await this.order.save(l),await this.log.append({type:"reorder",id:i,payload:{dir:`redo:${e}`,parent:i,ids:o,count:o.length}}),this.pendingFocusIds=o.slice(),this.tree.rebuild(l),this.render()}})}async cmdDeleteUnencrypted(){await this.cmdDelete({forcePlaintext:!0})}async cmdDelete(e={}){let t=this.getActionTargets();if(t.length===0){let B=this.tree.get(this.focusId);B?.file&&(t=[B])}if(t.length===0){new F.Notice("Nothing selected to delete.");return}let i=(this.noteFolder??"").replace(/\/+$/,""),s=(this.plugin.settings.folderEncPrefs??{})[i]??{},n=s.trashEncryptContent??!1,o=s.trashHandling==="obsidian";if(n&&!o&&!e.forcePlaintext){if(!this.plugin.encryption?.isConfigured?.()){new F.Notice("\u201CEncrypt items sent to trash\u201D is ON but encryption isn't set up (Settings \u2192 Stashpad \u2192 Encryption). Nothing was deleted.");return}await this.secureDeleteSources(t);return}if(!e.forcePlaintext&&!o){await this.plaintextDeleteToStashpadTrash(t);return}if(t.length===1){await this.deleteNote(t[0]);return}let a=[],l=new Set,c=B=>{if(!l.has(B.id)){l.add(B.id);for(let E of this.tree.getChildren(B.id))c(E);a.push(B)}};for(let B of t)c(B);let d=a.filter(B=>!!B.file),h=await Promise.all(d.map(B=>this.app.vault.read(B.file))),p=[];for(let B=0;B<d.length;B++){let E=d[B];p.push(...this.extractAttachments(this.stripFrontmatter(h[B])));let y=this.app.metadataCache.getFileCache(E.file)?.frontmatter;if(Array.isArray(y?.attachments))for(let v of y.attachments)typeof v=="string"&&v.trim()&&p.push(qt(v))}let f=[...new Set(p)],u=a.length-t.length,g=async B=>{let E=await this.snapshotNotes(a,B),y=0;if(B)for(let b of f){let M=this.app.metadataCache.getFirstLinkpathDest(b,"");if(M)try{await this.app.fileManager.trashFile(M),await this.log.append({type:"attachment_remove",id:S,payload:{path:M.path}}),this.plugin.notifications.show({message:`Deleted attachment "${M.name}"`,kind:"warning",category:"attachment",affectedPaths:[M.path],folder:this.noteFolder}),y+=1}catch{}}let v=new Set;for(let b of a)b.parent&&v.add(b.parent);let Q=this.authorship.collectAuthorIds(a),w=new Set(t.map(b=>b.id)),k=this.currentChildren.map((b,M)=>w.has(b.id)?M:-1).filter(b=>b>=0),D=k.length>0?k[0]:-1,H=null;if(D>=0){for(let b=D+1;b<this.currentChildren.length;b++)if(!w.has(this.currentChildren[b].id)){H=this.currentChildren[b].id;break}if(!H){for(let b=D-1;b>=0;b--)if(!w.has(this.currentChildren[b].id)){H=this.currentChildren[b].id;break}}}for(let b of a)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:B?f:[]}})}this.selection.clear(),this.cursorIdx=-1,H&&(this.pendingFocusIds=[H]),this.tree.rebuild(this.noteFolder);for(let b of v)a.some(M=>M.id===b)||this.fmSync.scheduleParentOfDeleted(b);this.render({kind:"follow-cursor"});let R=y>0?` with ${y} attachment${y===1?"":"s"}`:"",L=this.noteFolder,x=t.map(b=>b.id),U=!1,T=async()=>{U||(U=!0,this.selection.clear(),this.cursorIdx=-1,await this.restoreSnapshots(E,x.slice()))};this.plugin.notifications.show({message:this.bulkActionMessage({verb:"Deleted",nodes:t,suffix:R.trim()||void 0}),kind:"warning",category:"delete",duration:0,affectedIds:t.map(b=>b.id),affectedAuthorIds:Q,folder:this.noteFolder,actions:[{label:"Undo delete",onClick:()=>void T()}]}),this.plugin.getUndoStack(L).push({label:`Delete ${t.length} note${t.length===1?"":"s"}`,undo:async()=>{await T()},redo:async()=>{this.selection.clear(),this.cursorIdx=-1,U=!1,await this.trashNotesAndAttachments(E)}}),this.focusView()},I=X(),m=I.confirmBulkDelete,C=f.length>0&&I.confirmAttachmentDelete;if(!m&&!C){await g(!1);return}new Fi(this.app,`${t.length} selected note${t.length===1?"":"s"}`,u,f.length,C,g).open()}cmdEdit(e){return this.cmdSplit(e,"edit")}cmdComposerFullscreen(){let e=this.composerInputEl?.value??this.composerDraft??"",t=async()=>{this.composerInputEl&&(this.composerInputEl.value=""),this.composerDraft="";try{await this.saveDraft("")}catch{}},i=async n=>{let o=n.map(l=>l.trim()).filter(l=>l.length>0);if(o.length===0){new F.Notice("Nothing to save.");return}let a=this.focusId;this.autoSelectNewest=!0,this.scrollToBottomOnNextRender=!0,o.length===1?await this.createNoteUnder(o[0],a):await this.createNotesBatch(o,a,void 0,o.join(` `),this.noteFolder),await t(),this.render()},s={onSplitAtLine:async n=>{let o=e.replace(/\r\n/g,` `).split(` `);await i([o.slice(0,n).join(` `),o.slice(n).join(` -`)])},onSplitAtChar:async(n,o)=>{await i([n.slice(0,o),n.slice(o)])},onSplitMany:async n=>{await i(n)},onSave:async n=>{await i([n])},onOpenExternal:void 0,onImportFile:n=>this.importAttachment(n)};new ki(this.app,e,{...s,popOut:n=>void this.plugin.openWorkbench(e,s,n)},{surface:"edit"}).open()}cmdEditParent(){let e=this.tree.get(this.focusId);return e?.file?this.cmdEdit(e):(new k.Notice("No focused parent to edit."),Promise.resolve())}async cmdSplit(e,t="split"){let i=e??this.resolveActionTarget();if(!i?.file){new k.Notice(t==="edit"?"Pick a note to edit.":"Pick a note to split.");return}let s=i.file,n=await this.app.vault.read(s),o=this.stripFrontmatter(n).replace(/\s+$/,""),a=o.split(/\r?\n/);if(t==="split"&&o.trim().length<2){new k.Notice("Note is too short to split.");return}let l=n,c=s.path,A=async u=>{let g=u.replace(/\s+$/,"");if(!g.trim()){new k.Notice("Can't save an empty note.");return}let I=n.startsWith("---")?n.slice(0,n.indexOf(` +`)])},onSplitAtChar:async(n,o)=>{await i([n.slice(0,o),n.slice(o)])},onSplitMany:async n=>{await i(n)},onSave:async n=>{await i([n])},onOpenExternal:void 0,onImportFile:n=>this.importAttachment(n)};new Si(this.app,e,{...s,popOut:n=>void this.plugin.openWorkbench(e,s,n)},{surface:"edit"}).open()}cmdEditParent(){let e=this.tree.get(this.focusId);return e?.file?this.cmdEdit(e):(new F.Notice("No focused parent to edit."),Promise.resolve())}async cmdSplit(e,t="split"){let i=e??this.resolveActionTarget();if(!i?.file){new F.Notice(t==="edit"?"Pick a note to edit.":"Pick a note to split.");return}let s=i.file,n=await this.app.vault.read(s),o=this.stripFrontmatter(n).replace(/\s+$/,""),a=o.split(/\r?\n/);if(t==="split"&&o.trim().length<2){new F.Notice("Note is too short to split.");return}let l=n,c=s.path,d=async u=>{let g=u.replace(/\s+$/,"");if(!g.trim()){new F.Notice("Can't save an empty note.");return}let I=n.startsWith("---")?n.slice(0,n.indexOf(` ---`,3)+4):"",m=I+(I?` `:"")+g+` -`;if(m===l)return;await this.app.vault.modify(s,m);let B=await this.reslugFile(s,g)??c;this.tree.rebuild(this.noteFolder),this.render(),this.plugin.notifications.show({message:`Saved "${this.titleForNode(i)}"`,kind:"success",category:"split",affectedIds:[i.id],folder:this.noteFolder});let E=this.noteFolder;this.plugin.getUndoStack(E).push({label:"Edit note",undo:async()=>{let y=this.app.vault.getAbstractFileByPath(B);if(y&&B!==c)try{await this.app.fileManager.renameFile(y,c)}catch{}y=this.app.vault.getAbstractFileByPath(c),y&&await this.app.vault.modify(y,l),this.tree.rebuild(E),this.render()},redo:async()=>{let y=this.app.vault.getAbstractFileByPath(c);if(y&&(await this.app.vault.modify(y,m),B!==c))try{await this.app.fileManager.renameFile(y,B)}catch{}this.tree.rebuild(E),this.render()}})},h=async(u,g,I,m=!1)=>{if(!u.trim()||!g.trim()){new k.Notice("Split would leave one part empty.");return}try{let C=n.startsWith("---")?n.slice(0,n.indexOf(` +`;if(m===l)return;await this.app.vault.modify(s,m);let B=await this.reslugFile(s,g)??c;this.tree.rebuild(this.noteFolder),this.render(),this.plugin.notifications.show({message:`Saved "${this.titleForNode(i)}"`,kind:"success",category:"split",affectedIds:[i.id],folder:this.noteFolder});let E=this.noteFolder;this.plugin.getUndoStack(E).push({label:"Edit note",undo:async()=>{let y=this.app.vault.getAbstractFileByPath(B);if(y&&B!==c)try{await this.app.fileManager.renameFile(y,c)}catch{}y=this.app.vault.getAbstractFileByPath(c),y&&await this.app.vault.modify(y,l),this.tree.rebuild(E),this.render()},redo:async()=>{let y=this.app.vault.getAbstractFileByPath(c);if(y&&(await this.app.vault.modify(y,m),B!==c))try{await this.app.fileManager.renameFile(y,B)}catch{}this.tree.rebuild(E),this.render()}})},h=async(u,g,I,m=!1)=>{if(!u.trim()||!g.trim()){new F.Notice("Split would leave one part empty.");return}try{let C=n.startsWith("---")?n.slice(0,n.indexOf(` ---`,3)+4):"",B=C+(C?` `:"")+u+` -`;await this.app.vault.modify(s,B);let E=m?i.id:i.parent??S,y=Date.parse(i.created||""),v=Number.isFinite(y)?new Date(y+1).toISOString():new Date().toISOString(),Q=await this.createNoteUnder(g,E,{record:!1,createdOverride:v});await this.log.append({type:"rename",id:i.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(i)}" into two`,kind:"success",category:"split",affectedIds:[i.id],folder:this.noteFolder});let w=Q?this.tree.get(Q):void 0,F=w?.file?.path,D=F?await this.app.vault.read(w.file):null,H=this.noteFolder;this.plugin.getUndoStack(H).push({label:"Split note",undo:async()=>{if(F){let L=this.app.vault.getAbstractFileByPath(F);if(L)try{await this.app.fileManager.trashFile(L)}catch{}}let R=this.app.vault.getAbstractFileByPath(c);R&&await this.app.vault.modify(R,l),this.tree.rebuild(H),this.render()},redo:async()=>{let R=this.app.vault.getAbstractFileByPath(c);R&&await this.app.vault.modify(R,B),F&&D&&!await this.app.vault.adapter.exists(F)&&await this.app.vault.create(F,D),this.tree.rebuild(H),this.render()}})}catch(C){new k.Notice(`Stashpad: split failed (${C.message})`),console.error(C)}},p=async(u,g=!1)=>{if(!(u.length<2))try{let I=n.startsWith("---")?n.slice(0,n.indexOf(` ----`,3)+4):"",m=u[0].replace(/\s+$/,"");if(!m.trim()){new k.Notice("Split would leave the first part empty.");return}let C=I+(I?` +`;await this.app.vault.modify(s,B);let E=m?i.id:i.parent??S,y=Date.parse(i.created||""),v=Number.isFinite(y)?new Date(y+1).toISOString():new Date().toISOString(),Q=await this.createNoteUnder(g,E,{record:!1,createdOverride:v});await this.log.append({type:"rename",id:i.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(i)}" into two`,kind:"success",category:"split",affectedIds:[i.id],folder:this.noteFolder});let w=Q?this.tree.get(Q):void 0,k=w?.file?.path,D=k?await this.app.vault.read(w.file):null,H=this.noteFolder;this.plugin.getUndoStack(H).push({label:"Split note",undo:async()=>{if(k){let L=this.app.vault.getAbstractFileByPath(k);if(L)try{await this.app.fileManager.trashFile(L)}catch{}}let R=this.app.vault.getAbstractFileByPath(c);R&&await this.app.vault.modify(R,l),this.tree.rebuild(H),this.render()},redo:async()=>{let R=this.app.vault.getAbstractFileByPath(c);R&&await this.app.vault.modify(R,B),k&&D&&!await this.app.vault.adapter.exists(k)&&await this.app.vault.create(k,D),this.tree.rebuild(H),this.render()}})}catch(C){new F.Notice(`Stashpad: split failed (${C.message})`),console.error(C)}},p=async(u,g=!1)=>{if(!(u.length<2))try{let I=n.startsWith("---")?n.slice(0,n.indexOf(` +---`,3)+4):"",m=u[0].replace(/\s+$/,"");if(!m.trim()){new F.Notice("Split would leave the first part empty.");return}let C=I+(I?` `:"")+m+` -`;await this.app.vault.modify(s,C);let B=g?i.id:i.parent??S,E=Date.parse(i.created||""),y=Number.isFinite(E)?E:Date.now(),v=[];this.beginBulkRender();try{for(let F=1;F<u.length;F++)await this.createNoteUnder(u[F],B,{record:!1,createdOverride:new Date(y+F).toISOString(),deferRender:!0,collectInto:v})}finally{try{await this.fmSync.flush()}catch{}this.endBulkRender()}await this.log.append({type:"rename",id:i.id,payload:{action:"split-many",parts:u.length}}),this.suppressComposerFocusUntil=Date.now()+500,this.viewRoot?.focus({preventScroll:!0}),this.plugin.notifications.show({message:`Split "${this.titleForNode(i)}" into ${u.length}`,kind:"success",category:"split",affectedIds:[i.id],folder:this.noteFolder});let Q=v.slice(),w=this.noteFolder;this.plugin.getUndoStack(w).push({label:`Split note into ${u.length}`,undo:async()=>{for(let{path:D}of Q){let H=this.app.vault.getAbstractFileByPath(D);if(H)try{await this.app.fileManager.trashFile(H)}catch{}}let F=this.app.vault.getAbstractFileByPath(c);F&&await this.app.vault.modify(F,l),this.tree.rebuild(w),this.render()},redo:async()=>{let F=this.app.vault.getAbstractFileByPath(c);F&&await this.app.vault.modify(F,C);for(let{path:D,content:H}of Q)await this.app.vault.adapter.exists(D)||await this.app.vault.create(D,H);this.tree.rebuild(w),this.render()}})}catch(I){new k.Notice(`Stashpad: split failed (${I.message})`),console.error(I)}},f={onSplitAtLine:async(u,g)=>{let I=a.slice(0,u).join(` +`;await this.app.vault.modify(s,C);let B=g?i.id:i.parent??S,E=Date.parse(i.created||""),y=Number.isFinite(E)?E:Date.now(),v=[];this.beginBulkRender();try{for(let k=1;k<u.length;k++)await this.createNoteUnder(u[k],B,{record:!1,createdOverride:new Date(y+k).toISOString(),deferRender:!0,collectInto:v})}finally{try{await this.fmSync.flush()}catch{}this.endBulkRender()}await this.log.append({type:"rename",id:i.id,payload:{action:"split-many",parts:u.length}}),this.suppressComposerFocusUntil=Date.now()+500,this.viewRoot?.focus({preventScroll:!0}),this.plugin.notifications.show({message:`Split "${this.titleForNode(i)}" into ${u.length}`,kind:"success",category:"split",affectedIds:[i.id],folder:this.noteFolder});let Q=v.slice(),w=this.noteFolder;this.plugin.getUndoStack(w).push({label:`Split note into ${u.length}`,undo:async()=>{for(let{path:D}of Q){let H=this.app.vault.getAbstractFileByPath(D);if(H)try{await this.app.fileManager.trashFile(H)}catch{}}let k=this.app.vault.getAbstractFileByPath(c);k&&await this.app.vault.modify(k,l),this.tree.rebuild(w),this.render()},redo:async()=>{let k=this.app.vault.getAbstractFileByPath(c);k&&await this.app.vault.modify(k,C);for(let{path:D,content:H}of Q)await this.app.vault.adapter.exists(D)||await this.app.vault.create(D,H);this.tree.rebuild(w),this.render()}})}catch(I){new F.Notice(`Stashpad: split failed (${I.message})`),console.error(I)}},f={onSplitAtLine:async(u,g)=>{let I=a.slice(0,u).join(` `).replace(/\s+$/,""),m=a.slice(u).join(` -`).replace(/^\s+|\s+$/g,"");await h(I,m,{mode:"line",splitAtLine:u,nest:g},g)},onSplitAtChar:async(u,g,I)=>{let m=u.slice(0,g).replace(/\s+$/,""),C=u.slice(g).replace(/^\s+|\s+$/g,"");await h(m,C,{mode:"cursor",splitAtChar:g,edited:u!==o,nest:I},I)},onSplitMany:async(u,g)=>{await p(u,g)},onSave:A,onOpenExternal:()=>{this.openFileAtEnd(s)},onImportFile:u=>this.importAttachment(u)};new ki(this.app,o,{...f,popOut:u=>{this.plugin.openWorkbench(o,f,u)}},{surface:t}).open()}cmdOpenInNewStashpadTab(e){let t=e??this.resolveActionTarget();t?.file&&this.openInNewStashpadTab(t.id)}cmdCloneStashpadTab(){let e=this.tree.get(this.focusId);e?.file?this.cmdOpenInNewStashpadTab(e):this.openInNewStashpadTab(this.focusId)}resolveActionTarget(){if(this.cursorIdx>=0&&this.currentChildren[this.cursorIdx])return this.currentChildren[this.cursorIdx];let e=this.tree.get(this.focusId);return e?.file?e:void 0}cmdExportStash(e){return Yl(this,e)}cmdImportStash(){return Vl(this)}processStashFile(e){return ba(this,e)}async createNoteUnder(e,t,i={record:!0}){let s=(i.targetFolder??this.noteFolder).replace(/\/+$/,""),n=s!==this.noteFolder;await this.ensureFolder(s);let o=this.plugin.mintNoteId(),a=null;{let m=(this.plugin.settings.noteTemplates??{})[s];if(m){let C=this.app.vault.getAbstractFileByPath(m);if(C&&C.extension==="md")try{let B=await this.app.vault.cachedRead(C),E=this.stripFrontmatter(B);a=this.app.metadataCache.getFileCache(C)?.frontmatter??{},E.includes("{{body}}")?e=E.replace(/\{\{body\}\}/g,e):e.trim()?E.trim()&&(e=`${e} +`).replace(/^\s+|\s+$/g,"");await h(I,m,{mode:"line",splitAtLine:u,nest:g},g)},onSplitAtChar:async(u,g,I)=>{let m=u.slice(0,g).replace(/\s+$/,""),C=u.slice(g).replace(/^\s+|\s+$/g,"");await h(m,C,{mode:"cursor",splitAtChar:g,edited:u!==o,nest:I},I)},onSplitMany:async(u,g)=>{await p(u,g)},onSave:d,onOpenExternal:()=>{this.openFileAtEnd(s)},onImportFile:u=>this.importAttachment(u)};new Si(this.app,o,{...f,popOut:u=>{this.plugin.openWorkbench(o,f,u)}},{surface:t}).open()}cmdOpenInNewStashpadTab(e){let t=e??this.resolveActionTarget();t?.file&&this.openInNewStashpadTab(t.id)}cmdCloneStashpadTab(){let e=this.tree.get(this.focusId);e?.file?this.cmdOpenInNewStashpadTab(e):this.openInNewStashpadTab(this.focusId)}resolveActionTarget(){if(this.cursorIdx>=0&&this.currentChildren[this.cursorIdx])return this.currentChildren[this.cursorIdx];let e=this.tree.get(this.focusId);return e?.file?e:void 0}cmdExportStash(e){return Wl(this,e)}cmdImportStash(){return Zl(this)}processStashFile(e){return Na(this,e)}async createNoteUnder(e,t,i={record:!0}){let s=(i.targetFolder??this.noteFolder).replace(/\/+$/,""),n=s!==this.noteFolder;await this.ensureFolder(s);let o=this.plugin.mintNoteId(),a=null;{let m=(this.plugin.settings.noteTemplates??{})[s];if(m){let C=this.app.vault.getAbstractFileByPath(m);if(C&&C.extension==="md")try{let B=await this.app.vault.cachedRead(C),E=this.stripFrontmatter(B);a=this.app.metadataCache.getFileCache(C)?.frontmatter??{},E.includes("{{body}}")?e=E.replace(/\{\{body\}\}/g,e):e.trim()?E.trim()&&(e=`${e} -${E}`):e=E}catch(B){console.warn("[Stashpad] template read failed",B)}}}let l=null;{let m=e.match(/^\s*\[([ xX]?)\]\s*(?=\S)/);m&&(l={completed:/[xX]/.test(m[1])},e=e.slice(m[0].length))}let c=xe(e,this.activeStopwords()),A=Ne(c,o),h=`${s}/${A}`,p=t??this.focusId,f=i.createdOverride??new Date().toISOString(),u=this.extractAttachments(e),g=this.authorship.currentAuthorLink();g&&this.authorship.ensureAuthorFile(g);let I=["---",`id: ${o}`,`parent: ${p}`,`created: ${f}`,`modified: ${f}`];if(g&&I.push(`author: "${g.link.replace(/"/g,'\\"')}"`),u.length>0){I.push("attachments:");for(let m of u)I.push(` - "${m.replace(/"/g,'\\"')}"`)}else I.push("attachments: []");l&&I.push("task: true",`completed: ${l.completed}`),I.push("---",e);try{let m=I.join(` +${E}`):e=E}catch(B){console.warn("[Stashpad] template read failed",B)}}}let l=null;{let m=e.match(/^\s*\[([ xX]?)\]\s*(?=\S)/);m&&(l={completed:/[xX]/.test(m[1])},e=e.slice(m[0].length))}let c=xe(e,this.activeStopwords()),d=Ne(c,o),h=`${s}/${d}`,p=t??this.focusId,f=i.createdOverride??new Date().toISOString(),u=this.extractAttachments(e),g=this.authorship.currentAuthorLink();g&&this.authorship.ensureAuthorFile(g);let I=["---",`id: ${o}`,`parent: ${p}`,`created: ${f}`,`modified: ${f}`];if(g&&I.push(`author: "${g.link.replace(/"/g,'\\"')}"`),u.length>0){I.push("attachments:");for(let m of u)I.push(` - "${m.replace(/"/g,'\\"')}"`)}else I.push("attachments: []");l&&I.push("task: true",`completed: ${l.completed}`),I.push("---",e);try{let m=I.join(` `);this.plugin.importService.suppress(h,6e4),await Te.timeAsync("write.createNote.file",()=>this.app.vault.create(h,m)),i.collectInto?.push({path:h,content:m});try{let C=this.app.vault.getAbstractFileByPath(h);if(C&&C.extension==="md"){if(!n)this.tree.insertSynthetic({id:o,parent:p,children:[],file:C,created:f}),await this.bodyRenderer.primeRender(C,e),i.deferRender||this.render(),this.fmSync.scheduleParentChange(o,null,p);else{i.deferRender||this.render();let B=s.split("/").pop()||s,E=(e.split(` -`).find(y=>y.trim())??"note").trim().slice(0,60);i.deferUndo||this.plugin.notifications.show({message:`"${E}" landed in \`${B}\``,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(C,B=>{for(let[E,y]of Object.entries(a))et.includes(E)||fo.includes(E)||B[E]===void 0&&(B[E]=y)})}catch(B){console.warn("[Stashpad] template fm overlay failed",B)}}}catch{}if(await this.log.append({type:"create",id:o,payload:{path:h,parent:p}}),i.record!==!1&&!i.deferUndo){let C=e;this.plugin.getUndoStack(s).push({label:n?"Send note":"Create note",undo:async()=>{let B=this.fileForNote(o,h);if(B)try{await this.app.fileManager.trashFile(B)}catch{}if(!(this.composerInputEl?.value??this.composerDraft).trim()&&(this.composerDraft=C,this.saveDraft(C),this.recordLastSubmitted(""),this.composerInputEl)){this.composerInputEl.value=C;let y=C.length;this.composerInputEl.setSelectionRange(y,y),this.composerInputEl.focus()}n||this.tree.rebuild(this.noteFolder),this.render()},redo:async()=>{await this.app.vault.adapter.exists(h)||await this.app.vault.create(h,m),this.composerDraft="",this.saveDraft(""),this.recordLastSubmitted(C),this.composerInputEl&&(this.composerInputEl.value=""),n||this.tree.rebuild(this.noteFolder),this.render()}})}return o}catch(m){return new k.Notice(`Stashpad: failed to create note (${m.message})`),null}}async createNotesBatch(e,t,i,s,n){let o=e.length,a=[],l=!!i?.targetFolder&&i.targetFolder!==this.noteFolder,c=8,A=null;if(o>=c){let h=new k.Notice("",0),p=h.messageEl;p.empty(),p.createDiv({cls:"stashpad-split-progress-title",text:`Splitting into ${o} notes\u2026`});let u=p.createDiv({cls:"stashpad-split-progress-bar"}).createDiv({cls:"stashpad-split-progress-fill"}),g=p.createDiv({cls:"stashpad-split-progress-label",text:`0 / ${o}`});A={notice:h,fill:u,label:g}}this.beginBulkRender();try{for(let h=0;h<o;h++)if(await this.createNoteUnder(e[h],t,{...i??{},deferRender:!0,deferUndo:!0,collectInto:a}),A){let p=h+1;A.label.setText(`${p} / ${o}`),A.fill.setCssStyles({width:`${Math.round(p/o*100)}%`}),p%5===0&&await new Promise(f=>window.setTimeout(f,0))}}finally{A?.notice.hide();try{await this.fmSync.flush()}catch{}this.endBulkRender()}if(a.length){let h=a.slice();this.plugin.getUndoStack(n).push({label:`Create ${h.length} notes`,undo:async()=>{for(let{path:p}of h){let f=this.app.vault.getAbstractFileByPath(p);if(f)try{await this.app.fileManager.trashFile(f)}catch{}}if(this.composerDraft=s,this.saveDraft(s),this.recordLastSubmitted(""),this.composerInputEl){this.composerInputEl.value=s;let p=s.length;this.composerInputEl.setSelectionRange(p,p),this.composerInputEl.focus()}l||this.tree.rebuild(this.noteFolder),this.render()},redo:async()=>{for(let{path:p,content:f}of h)await this.app.vault.adapter.exists(p)||await this.app.vault.create(p,f);this.composerDraft="",this.saveDraft(""),this.composerInputEl&&(this.composerInputEl.value=""),l||this.tree.rebuild(this.noteFolder),this.render()}})}o>=c&&this.plugin.notifications.show({message:`Created ${a.length} notes${l?` in \`${n.split("/").pop()}\``:""}.`,kind:"success",category:"create"})}extractAttachments(e){let t=[],i=/!\[\[([^\]\|]+)(?:\|[^\]]+)?\]\]/g,s;for(;(s=i.exec(e))!==null;)t.push(s[1]);return t}async ensureFolder(e){if(await this.app.vault.adapter.exists(e)){let t=this.app.vault.getAbstractFileByPath(e);if(t&&!(t instanceof k.TFolder))throw new Error(`${e} exists and is not a folder`);return}try{await this.app.vault.createFolder(e)}catch(t){let i=t?.message??"";if(!/already exists/i.test(i))throw t}}async importAttachment(e){try{let t=await e.arrayBuffer(),i=`${this.noteFolder}/_attachments`;await this.ensureFolder(i);let s=e.name.replace(/[^\w.\-]+/g,"_"),n=Date.now().toString(36),o=`${i}/${zs(s,n)}`;return await this.app.vault.createBinary(o,t),await this.log.append({type:"attachment_add",id:S,payload:{path:o,name:e.name,size:e.size}}),this.plugin.notifications.show({message:`Attached ${e.name}`,kind:"success",category:"attachment",affectedPaths:[o],folder:this.noteFolder}),`![[${o}]]`}catch(t){return new k.Notice(`Stashpad: attachment failed (${t.message})`),null}}claimSelectedAsAuthor(){this.authorship.claimSelectedAsAuthor()}claimFolderAsAuthor(){this.authorship.claimFolderAsAuthor()}claimSelectedWithContributor(){this.authorship.claimSelectedWithContributor()}claimFolderWithContributor(){this.authorship.claimFolderWithContributor()}renderAuthorshipFooter(e,t){if(!t.file)return;let i=this.plugin.settings;if(!i.showAuthor&&!i.showContributors&&!i.showLastEdit)return;let s=this.app.metadataCache.getFileCache(t.file)?.frontmatter??{},n=typeof s.author=="string"?s.author:"",o=Array.isArray(s.contributors)?s.contributors.filter(u=>typeof u=="string"&&u.trim()!==""):[],a=typeof s.modified=="string"?s.modified:typeof s.created=="string"?s.created:"",l=i.showAuthor&&!!n,c=i.showContributors&&o.length>0,A=i.showLastEdit&&!!a;if(!l&&!c&&!A)return;let h=e.createDiv({cls:"stashpad-note-authorship"}),p=(u,g)=>{let I=g.replace(/^\[\[/,"").replace(/\]\]$/,""),m=I.indexOf("|"),C=m>=0?I.slice(0,m):I,B=m>=0?I.slice(m+1):I.split("/").pop()??I,E=u.createEl("a",{cls:"internal-link",text:B});E.setAttribute("data-href",C),E.setAttribute("href",C)},f=[];l&&f.push(u=>{u.createSpan({cls:"stashpad-authorship-label",text:"by "}),p(u,n)}),c&&f.push(u=>{u.createSpan({cls:"stashpad-authorship-label",text:"with "}),o.forEach((g,I)=>{I>0&&u.createSpan({text:", "}),p(u,g)})}),A&&f.push(u=>{u.createSpan({cls:"stashpad-authorship-label",text:"edited "}),u.createSpan({text:this.formatTimeInline(a)})}),f.forEach((u,g)=>{g>0&&h.createSpan({cls:"stashpad-authorship-sep",text:"\xB7"});let I=h.createSpan({cls:"stashpad-authorship-piece"});u(I)}),h.addEventListener("click",u=>this.handleRenderedClick(u,t))}markFmSelfWrite(e){this.recentFmSelfWrites.set(e,Date.now())}wasRecentFmSelfWrite(e){let t=this.recentFmSelfWrites.get(e);return t==null?!1:(this.recentFmSelfWrites.delete(e),Date.now()-t<2500)}activeStopwords(){return this.plugin.settings.slugStopWords??st}scheduleSlugRename(e){let t=this.slugDebouncers.get(e.path);t&&t.cancel(),t=(0,k.debounce)(()=>void this.maybeRenameForSlug(e),3e4),this.slugDebouncers.set(e.path,t),t()}async reslugFile(e,t){let i=this.app.metadataCache.getFileCache(e)?.frontmatter?.id,s=typeof i=="string"?i:null,o=nt(e.basename)??(ji(s??"")?s:null);if(!o||o===S||s!==o)return null;let a=Ne(xe(t,this.activeStopwords()),o);if(e.name===a)return null;let l=e.parent?`${e.parent.path}/${a}`:a;if(this.app.vault.getAbstractFileByPath(l))return null;let c=e.path;try{return await this.app.fileManager.renameFile(e,l),await this.log.append({type:"rename",id:o,payload:{from:c,to:l}}),l}catch{return null}}async maybeRenameForSlug(e){let t=this.app.metadataCache.getFileCache(e)?.frontmatter?.id,i=typeof t=="string"?t:null,n=nt(e.basename)??(ji(i)?i:null);if(!n||n===S||i!==n)return;let o=await this.app.vault.cachedRead(e),a=this.stripFrontmatter(o),l=xe(a,this.activeStopwords()),c=Ne(l,n);if(e.name===c)return;let A=e.parent?`${e.parent.path}/${c}`:c;if(this.app.vault.getAbstractFileByPath(A))return;let h=e.path;try{await this.app.fileManager.renameFile(e,A),await this.log.append({type:"rename",id:n,payload:{from:h,to:A}})}catch{}}scheduleAttachmentSync(e){let t=this.attachmentDebouncers.get(e.path);t&&t.cancel(),t=(0,k.debounce)(()=>void this.syncAttachmentsFrontmatter(e),1500),this.attachmentDebouncers.set(e.path,t),t()}async syncAttachmentsFrontmatter(e){let t=await this.app.vault.cachedRead(e),i=this.stripFrontmatter(t),s=this.extractAttachments(i),n=this.app.metadataCache.getFileCache(e)?.frontmatter,a=(Array.isArray(n?.attachments)?n.attachments:[]).filter(A=>typeof A=="string").map(A=>Jt(A));if(a.length===s.length&&a.every((A,h)=>A===s[h]))return;let c=s.map(A=>tt(A));await this.app.fileManager.processFrontMatter(e,A=>{A.attachments=c})}stripFrontmatter(e){let t=e.replace(/^\uFEFF/,""),i=t.match(/^\s*---\s*\r?\n[\s\S]*?\r?\n---\s*(?:\r?\n|$)/);return i?t.slice(i[0].length):t}formatTime(e){if(!e)return"";let t=(0,k.moment)(e);if(!t.isValid())return"";let i=X();if(i.useTemplatesFormat){let n=gn(this.app);if(n)return`${t.format(n.dateFormat)} +`).find(y=>y.trim())??"note").trim().slice(0,60);i.deferUndo||this.plugin.notifications.show({message:`"${E}" landed in \`${B}\``,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(C,B=>{for(let[E,y]of Object.entries(a))et.includes(E)||Co.includes(E)||B[E]===void 0&&(B[E]=y)})}catch(B){console.warn("[Stashpad] template fm overlay failed",B)}}}catch{}if(await this.log.append({type:"create",id:o,payload:{path:h,parent:p}}),i.record!==!1&&!i.deferUndo){let C=e;this.plugin.getUndoStack(s).push({label:n?"Send note":"Create note",undo:async()=>{let B=this.fileForNote(o,h);if(B)try{await this.app.fileManager.trashFile(B)}catch{}if(!(this.composerInputEl?.value??this.composerDraft).trim()&&(this.composerDraft=C,this.saveDraft(C),this.recordLastSubmitted(""),this.composerInputEl)){this.composerInputEl.value=C;let y=C.length;this.composerInputEl.setSelectionRange(y,y),this.composerInputEl.focus()}n||this.tree.rebuild(this.noteFolder),this.render()},redo:async()=>{await this.app.vault.adapter.exists(h)||await this.app.vault.create(h,m),this.composerDraft="",this.saveDraft(""),this.recordLastSubmitted(C),this.composerInputEl&&(this.composerInputEl.value=""),n||this.tree.rebuild(this.noteFolder),this.render()}})}return o}catch(m){return new F.Notice(`Stashpad: failed to create note (${m.message})`),null}}async createNotesBatch(e,t,i,s,n){let o=e.length,a=[],l=!!i?.targetFolder&&i.targetFolder!==this.noteFolder,c=8,d=null;if(o>=c){let h=new F.Notice("",0),p=h.messageEl;p.empty(),p.createDiv({cls:"stashpad-split-progress-title",text:`Splitting into ${o} notes\u2026`});let u=p.createDiv({cls:"stashpad-split-progress-bar"}).createDiv({cls:"stashpad-split-progress-fill"}),g=p.createDiv({cls:"stashpad-split-progress-label",text:`0 / ${o}`});d={notice:h,fill:u,label:g}}this.beginBulkRender();try{for(let h=0;h<o;h++)if(await this.createNoteUnder(e[h],t,{...i??{},deferRender:!0,deferUndo:!0,collectInto:a}),d){let p=h+1;d.label.setText(`${p} / ${o}`),d.fill.setCssStyles({width:`${Math.round(p/o*100)}%`}),p%5===0&&await new Promise(f=>window.setTimeout(f,0))}}finally{d?.notice.hide();try{await this.fmSync.flush()}catch{}this.endBulkRender()}if(a.length){let h=a.slice();this.plugin.getUndoStack(n).push({label:`Create ${h.length} notes`,undo:async()=>{for(let{path:p}of h){let f=this.app.vault.getAbstractFileByPath(p);if(f)try{await this.app.fileManager.trashFile(f)}catch{}}if(this.composerDraft=s,this.saveDraft(s),this.recordLastSubmitted(""),this.composerInputEl){this.composerInputEl.value=s;let p=s.length;this.composerInputEl.setSelectionRange(p,p),this.composerInputEl.focus()}l||this.tree.rebuild(this.noteFolder),this.render()},redo:async()=>{for(let{path:p,content:f}of h)await this.app.vault.adapter.exists(p)||await this.app.vault.create(p,f);this.composerDraft="",this.saveDraft(""),this.composerInputEl&&(this.composerInputEl.value=""),l||this.tree.rebuild(this.noteFolder),this.render()}})}o>=c&&this.plugin.notifications.show({message:`Created ${a.length} notes${l?` in \`${n.split("/").pop()}\``:""}.`,kind:"success",category:"create"})}extractAttachments(e){let t=[],i=/!\[\[([^\]\|]+)(?:\|[^\]]+)?\]\]/g,s;for(;(s=i.exec(e))!==null;)t.push(s[1]);return t}async ensureFolder(e){if(await this.app.vault.adapter.exists(e)){let t=this.app.vault.getAbstractFileByPath(e);if(t&&!(t instanceof F.TFolder))throw new Error(`${e} exists and is not a folder`);return}try{await this.app.vault.createFolder(e)}catch(t){let i=t?.message??"";if(!/already exists/i.test(i))throw t}}async importAttachment(e){try{let t=await e.arrayBuffer(),i=`${this.noteFolder}/_attachments`;await this.ensureFolder(i);let s=e.name.replace(/[^\w.\-]+/g,"_"),n=Date.now().toString(36),o=`${i}/${Ws(s,n)}`;return await this.app.vault.createBinary(o,t),await this.log.append({type:"attachment_add",id:S,payload:{path:o,name:e.name,size:e.size}}),this.plugin.notifications.show({message:`Attached ${e.name}`,kind:"success",category:"attachment",affectedPaths:[o],folder:this.noteFolder}),`![[${o}]]`}catch(t){return new F.Notice(`Stashpad: attachment failed (${t.message})`),null}}claimSelectedAsAuthor(){this.authorship.claimSelectedAsAuthor()}claimFolderAsAuthor(){this.authorship.claimFolderAsAuthor()}claimSelectedWithContributor(){this.authorship.claimSelectedWithContributor()}claimFolderWithContributor(){this.authorship.claimFolderWithContributor()}renderAuthorshipFooter(e,t){if(!t.file)return;let i=this.plugin.settings;if(!i.showAuthor&&!i.showContributors&&!i.showLastEdit)return;let s=this.app.metadataCache.getFileCache(t.file)?.frontmatter??{},n=typeof s.author=="string"?s.author:"",o=Array.isArray(s.contributors)?s.contributors.filter(u=>typeof u=="string"&&u.trim()!==""):[],a=typeof s.modified=="string"?s.modified:typeof s.created=="string"?s.created:"",l=i.showAuthor&&!!n,c=i.showContributors&&o.length>0,d=i.showLastEdit&&!!a;if(!l&&!c&&!d)return;let h=e.createDiv({cls:"stashpad-note-authorship"}),p=(u,g)=>{let I=g.replace(/^\[\[/,"").replace(/\]\]$/,""),m=I.indexOf("|"),C=m>=0?I.slice(0,m):I,B=m>=0?I.slice(m+1):I.split("/").pop()??I,E=u.createEl("a",{cls:"internal-link",text:B});E.setAttribute("data-href",C),E.setAttribute("href",C)},f=[];l&&f.push(u=>{u.createSpan({cls:"stashpad-authorship-label",text:"by "}),p(u,n)}),c&&f.push(u=>{u.createSpan({cls:"stashpad-authorship-label",text:"with "}),o.forEach((g,I)=>{I>0&&u.createSpan({text:", "}),p(u,g)})}),d&&f.push(u=>{u.createSpan({cls:"stashpad-authorship-label",text:"edited "}),u.createSpan({text:this.formatTimeInline(a)})}),f.forEach((u,g)=>{g>0&&h.createSpan({cls:"stashpad-authorship-sep",text:"\xB7"});let I=h.createSpan({cls:"stashpad-authorship-piece"});u(I)}),h.addEventListener("click",u=>this.handleRenderedClick(u,t))}markFmSelfWrite(e){this.recentFmSelfWrites.set(e,Date.now())}wasRecentFmSelfWrite(e){let t=this.recentFmSelfWrites.get(e);return t==null?!1:(this.recentFmSelfWrites.delete(e),Date.now()-t<2500)}activeStopwords(){return this.plugin.settings.slugStopWords??st}scheduleSlugRename(e){let t=this.slugDebouncers.get(e.path);t&&t.cancel(),t=(0,F.debounce)(()=>void this.maybeRenameForSlug(e),3e4),this.slugDebouncers.set(e.path,t),t()}async reslugFile(e,t){let i=this.app.metadataCache.getFileCache(e)?.frontmatter?.id,s=typeof i=="string"?i:null,o=nt(e.basename)??(es(s??"")?s:null);if(!o||o===S||s!==o)return null;let a=Ne(xe(t,this.activeStopwords()),o);if(e.name===a)return null;let l=e.parent?`${e.parent.path}/${a}`:a;if(this.app.vault.getAbstractFileByPath(l))return null;let c=e.path;try{return await this.app.fileManager.renameFile(e,l),await this.log.append({type:"rename",id:o,payload:{from:c,to:l}}),l}catch{return null}}async maybeRenameForSlug(e){let t=this.app.metadataCache.getFileCache(e)?.frontmatter?.id,i=typeof t=="string"?t:null,n=nt(e.basename)??(es(i)?i:null);if(!n||n===S||i!==n)return;let o=await this.app.vault.cachedRead(e),a=this.stripFrontmatter(o),l=xe(a,this.activeStopwords()),c=Ne(l,n);if(e.name===c)return;let d=e.parent?`${e.parent.path}/${c}`:c;if(this.app.vault.getAbstractFileByPath(d))return;let h=e.path;try{await this.app.fileManager.renameFile(e,d),await this.log.append({type:"rename",id:n,payload:{from:h,to:d}})}catch{}}scheduleAttachmentSync(e){let t=this.attachmentDebouncers.get(e.path);t&&t.cancel(),t=(0,F.debounce)(()=>void this.syncAttachmentsFrontmatter(e),1500),this.attachmentDebouncers.set(e.path,t),t()}async syncAttachmentsFrontmatter(e){let t=await this.app.vault.cachedRead(e),i=this.stripFrontmatter(t),s=this.extractAttachments(i),n=this.app.metadataCache.getFileCache(e)?.frontmatter,a=(Array.isArray(n?.attachments)?n.attachments:[]).filter(d=>typeof d=="string").map(d=>qt(d));if(a.length===s.length&&a.every((d,h)=>d===s[h]))return;let c=s.map(d=>tt(d));await this.app.fileManager.processFrontMatter(e,d=>{d.attachments=c})}stripFrontmatter(e){let t=e.replace(/^\uFEFF/,""),i=t.match(/^\s*---\s*\r?\n[\s\S]*?\r?\n---\s*(?:\r?\n|$)/);return i?t.slice(i[0].length):t}formatTime(e){if(!e)return"";let t=(0,F.moment)(e);if(!t.isValid())return"";let i=X();if(i.useTemplatesFormat){let n=fn(this.app);if(n)return`${t.format(n.dateFormat)} ${t.format(n.timeFormat)}`}let s=t.valueOf();return`${Nt(s,i)} -${Ai(s,i)}`}formatTimeInline(e){if(!e)return"";let t=(0,k.moment)(e);if(!t.isValid())return"";if(X().useTemplatesFormat){let s=gn(this.app);if(s){let n=/:ss/.test(s.timeFormat)?s.timeFormat:s.timeFormat.replace(/(:mm)/,"$1:ss");return`${t.format(s.dateFormat)} ${t.format(n)}`}}return`${t.format("YYYY.MM.DD")} ${t.format("HH:mm:ss A")}`}scrollListToBottom(){let e=this.listEl;if(!e)return;if(this.stickToListBottom=!0,e.scrollTop=e.scrollHeight,k.Platform.isMobile){let a=0,l=()=>{!this.stickToListBottom||a>=8||(a++,Date.now()>=this.keyboardTransitionUntil&&(e.scrollTop=e.scrollHeight),window.setTimeout(l,120))};window.setTimeout(l,60);return}this.stickyRowObserver?.disconnect();let t=()=>{if(!this.stickToListBottom){this.stickyRowObserver?.disconnect(),this.stickyRowObserver=null;return}e.scrollTop=e.scrollHeight},i=new ResizeObserver(t);for(let a of Array.from(e.children))a instanceof HTMLElement&&i.observe(a);this.stickyRowObserver=i;let s=performance.now(),n=e.scrollHeight,o=()=>{if(!this.stickToListBottom)return;let a=e.scrollHeight;a!==n&&(e.scrollTop=a,n=a),performance.now()-s<3e4?requestAnimationFrame(o):(this.stickToListBottom=!1,this.stickyRowObserver?.disconnect(),this.stickyRowObserver=null)};requestAnimationFrame(o)}addShareExportSubmenu(e,t,i){let s=()=>{i.normalizeToNode&&t&&!this.selection.has(t.id)&&(this.selection.clear(),this.selection.add(t.id),this.lastSelected=t.id)},n=o=>{o.addItem(a=>{a.setTitle("Copy Stashpad link").setIcon("link"),t?a.onClick(()=>void this.cmdCopyStashpadLink(i.normalizeToNode?t:void 0)):a.setDisabled(!0)}),o.addItem(a=>a.setTitle("Export\u2026").setIcon("package").onClick(()=>{s(),this.cmdExportStash()}))};e.addItem(o=>{o.setTitle("Share & export").setIcon("share-2");let a=typeof o.setSubmenu=="function"?o.setSubmenu():null;a&&typeof a.addItem=="function"?n(a):o.onClick(()=>this.openCommandPalette())})}openNoteMenu(e,t){if(!t.file)return;let i=t.file,s=new k.Menu;s.addItem(A=>A.setTitle("Open in new Stashpad tab").setIcon("layout-grid").onClick(()=>{this.openInNewStashpadTab(t.id)})),s.addItem(A=>A.setTitle("Open in Obsidian editor").setIcon("file-text").onClick(()=>{this.openFileAtEnd(i)})),s.addItem(A=>A.setTitle("Focus in Stashpad").setIcon("arrow-right").onClick(()=>this.navigateTo(t.id))),s.addSeparator(),s.addItem(A=>A.setTitle("Edit in Stashpad").setIcon("pencil-line").onClick(()=>void this.cmdEdit(t))),s.addItem(A=>A.setTitle("Split note\u2026").setIcon("split").onClick(()=>void this.cmdSplit(t))),s.addItem(A=>A.setTitle("Copy text").setIcon("copy").onClick(()=>{l(),this.cmdCopy()})),s.addItem(A=>A.setTitle("Clone (duplicate / copy)").setIcon("files").onClick(()=>{this.selection.has(t.id)||(this.selection.clear(),this.selection.add(t.id),this.lastSelected=t.id),this.cmdClone()})),s.addItem(A=>A.setTitle("Fork into a separate note\u2026").setIcon("git-branch").onClick(()=>{this.selection.has(t.id)||(this.selection.clear(),this.selection.add(t.id),this.lastSelected=t.id),this.cmdForkNote()})),this.addShareExportSubmenu(s,t,{normalizeToNode:!0}),this.plugin.encryption?.isConfigured?.()&&s.addItem(A=>A.setTitle("Encrypt (lock) note + children").setIcon("lock").onClick(async()=>{let h=this.order.getOrder(this.noteFolder,t.parent??S),p=h.indexOf(t.id),f=p>0?h[p-1]:null;await this.plugin.lockNoteSubtree(this.noteFolder,t.id,f)&&this.render()})),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(t,S),this.plugin.settings.autoNavOnMoveOut&&this.focusId!==S&&this.navigateTo(S)}));let n={folder:this.noteFolder,id:t.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)}));let a=this.isListPinned(t.id);s.addItem(A=>A.setTitle(a?"Unpin from top of list":"Pin to top of list").setIcon(a?"pin-off":"arrow-up-to-line").onClick(()=>{this.selection.has(t.id)||(this.selection.clear(),this.selection.add(t.id),this.lastSelected=t.id),this.cmdToggleListPin()})),s.addItem(A=>A.setTitle("Set color\u2026").setIcon("palette").onClick(()=>{this.selection.has(t.id)||(this.selection.clear(),this.selection.add(t.id),this.lastSelected=t.id),this.cmdSetColor()}));let l=()=>{this.selection.has(t.id)||(this.selection.clear(),this.selection.add(t.id),this.lastSelected=t.id)},c=A=>{let h=this.isTask(t);if(h){let p=this.isCompleted(t);A.addItem(f=>f.setTitle(p?"Mark incomplete":"Mark complete").setIcon(p?"circle":"check-circle").onClick(()=>{l(),this.cmdToggleComplete()}))}else A.addItem(p=>p.setTitle("Mark complete").setIcon("check-circle").onClick(()=>{l(),this.toggleCompletedForNode(t)})),A.addItem(p=>p.setTitle("Turn into task").setIcon("check-square").onClick(()=>{l(),this.cmdToggleTask()}));A.addItem(p=>p.setTitle("Assign / schedule\u2026").setIcon("user-plus").onClick(()=>{l(),this.cmdAssign()})),h&&(A.addItem(p=>p.setTitle("Snooze (reschedule)\u2026").setIcon("alarm-clock").onClick(()=>{l(),this.cmdSnooze(t)})),A.addItem(p=>p.setTitle("Remove from tasks").setIcon("square").onClick(()=>{l(),this.cmdToggleTask()})))};s.addItem(A=>{A.setTitle("Task").setIcon("check-square");let h=typeof A.setSubmenu=="function"?A.setSubmenu():null;h&&typeof h.addItem=="function"?c(h):A.onClick(()=>this.openCommandPalette())}),s.addSeparator(),s.addItem(A=>A.setTitle("Delete").setIcon("trash").onClick(async()=>{this.selection.has(t.id)||(this.selection.clear(),this.selection.add(t.id),this.lastSelected=t.id),await this.cmdDelete()})),s.addSeparator(),s.addItem(A=>A.setTitle("More commands\u2026").setIcon("terminal").onClick(()=>this.openCommandPalette())),s.showAtMouseEvent(e)}async deleteNote(e){if(!e.file)return;let t=[],i=u=>{for(let g of this.tree.getChildren(u.id))i(g),t.push(g)};i(e);let s=[...t,e],n=s.filter(u=>!!u.file),o=await Promise.all(n.map(u=>this.app.vault.cachedRead(u.file))),a=[];for(let u=0;u<n.length;u++){let g=n[u];a.push(...this.extractAttachments(this.stripFrontmatter(o[u])));let I=this.app.metadataCache.getFileCache(g.file)?.frontmatter;if(Array.isArray(I?.attachments))for(let m of I.attachments)typeof m=="string"&&m.trim()&&a.push(Jt(m))}let l=[...new Set(a)],c=this.authorship.collectAuthorIds(s),A=async u=>{let g=await this.snapshotNotes(s,u),I=0;if(u)for(let D of l){let H=this.app.metadataCache.getFirstLinkpathDest(D,"");if(H)try{await this.app.fileManager.trashFile(H),await this.log.append({type:"attachment_remove",id:S,payload:{path:H.path}}),this.plugin.notifications.show({message:`Deleted attachment "${H.name}"`,kind:"warning",category:"attachment",affectedPaths:[H.path],folder:this.noteFolder}),I+=1}catch{}}let m=new Set;for(let D of s)D.parent&&m.add(D.parent);let C=this.currentChildren.findIndex(D=>D.id===e.id),B=null;if(C>=0){for(let D=C+1;D<this.currentChildren.length;D++)if(this.currentChildren[D].id!==e.id){B=this.currentChildren[D].id;break}if(!B){for(let D=C-1;D>=0;D--)if(this.currentChildren[D].id!==e.id){B=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:u?l:[]}})}this.selection.clear(),this.cursorIdx=-1,B&&(this.pendingFocusIds=[B]),this.tree.rebuild(this.noteFolder),this.render({kind:"follow-cursor"});for(let D of m)s.some(H=>H.id===D)||this.fmSync.scheduleParentOfDeleted(D);let E=this.noteFolder,y=`Delete "${this.titleForNode(e)}"`,v=e.id,Q=I>0?` with ${I} attachment${I===1?"":"s"}`:"",w=!1,F=async()=>{w||(w=!0,this.selection.clear(),this.cursorIdx=-1,await this.restoreSnapshots(g,[v]))};this.plugin.notifications.show({message:`Deleted "${this.titleForNode(e)}"${Q}`,kind:"warning",category:"delete",duration:0,affectedIds:[e.id],affectedAuthorIds:c,folder:this.noteFolder,actions:[{label:"Undo delete",onClick:()=>void F()}]}),this.plugin.getUndoStack(E).push({label:y,undo:async()=>{await F()},redo:async()=>{this.selection.clear(),this.cursorIdx=-1,w=!1,await this.trashNotesAndAttachments(g)}})},h=X(),p=t.length>0&&h.confirmBulkDelete,f=l.length>0&&h.confirmAttachmentDelete;if(!p&&!f){await A(!1),this.focusView();return}new Fi(this.app,this.titleForNode(e),t.length,l.length,f,async u=>{await A(u),this.focusView()}).open()}async cmdSwapWithParent(){let e=this.cursorIdx>=0?this.currentChildren[this.cursorIdx]:null;if(!e?.file){new k.Notice("Pick a note first (move the cursor onto it).");return}if(!e.parent||e.parent===S){new k.Notice("Already at Home \u2014 no parent to swap with.");return}let t=this.tree.get(e.parent);if(!t?.file){new k.Notice("Couldn't find the parent note.");return}let i=t.parent??S,s=this.titleForNode(e),n=this.titleForNode(t),o=this.tree.getChildren(t.id).filter(l=>l.id!==e.id).length,a=[`"${n}" becomes a child of "${s}".`];o>0&&a.push(`${o} sibling${o===1?"":"s"} move with it.`),new j(this.app,"Swap notes?",a.join(` +${hi(s,i)}`}formatTimeInline(e){if(!e)return"";let t=(0,F.moment)(e);if(!t.isValid())return"";if(X().useTemplatesFormat){let s=fn(this.app);if(s){let n=/:ss/.test(s.timeFormat)?s.timeFormat:s.timeFormat.replace(/(:mm)/,"$1:ss");return`${t.format(s.dateFormat)} ${t.format(n)}`}}return`${t.format("YYYY.MM.DD")} ${t.format("HH:mm:ss A")}`}scrollListToBottom(){let e=this.listEl;if(!e)return;if(this.stickToListBottom=!0,e.scrollTop=e.scrollHeight,F.Platform.isMobile){let a=0,l=()=>{!this.stickToListBottom||a>=8||(a++,Date.now()>=this.keyboardTransitionUntil&&(e.scrollTop=e.scrollHeight),window.setTimeout(l,120))};window.setTimeout(l,60);return}this.stickyRowObserver?.disconnect();let t=()=>{if(!this.stickToListBottom){this.stickyRowObserver?.disconnect(),this.stickyRowObserver=null;return}e.scrollTop=e.scrollHeight},i=new ResizeObserver(t);for(let a of Array.from(e.children))a instanceof HTMLElement&&i.observe(a);this.stickyRowObserver=i;let s=performance.now(),n=e.scrollHeight,o=()=>{if(!this.stickToListBottom)return;let a=e.scrollHeight;a!==n&&(e.scrollTop=a,n=a),performance.now()-s<3e4?requestAnimationFrame(o):(this.stickToListBottom=!1,this.stickyRowObserver?.disconnect(),this.stickyRowObserver=null)};requestAnimationFrame(o)}addShareExportSubmenu(e,t,i){let s=()=>{i.normalizeToNode&&t&&!this.selection.has(t.id)&&(this.selection.clear(),this.selection.add(t.id),this.lastSelected=t.id)},n=o=>{o.addItem(a=>{a.setTitle("Copy Stashpad link").setIcon("link"),t?a.onClick(()=>void this.cmdCopyStashpadLink(i.normalizeToNode?t:void 0)):a.setDisabled(!0)}),o.addItem(a=>a.setTitle("Export\u2026").setIcon("package").onClick(()=>{s(),this.cmdExportStash()}))};e.addItem(o=>{o.setTitle("Share & export").setIcon("share-2");let a=typeof o.setSubmenu=="function"?o.setSubmenu():null;a&&typeof a.addItem=="function"?n(a):o.onClick(()=>this.openCommandPalette())})}openNoteMenu(e,t){if(!t.file)return;let i=t.file,s=new F.Menu;s.addItem(d=>d.setTitle("Open in new Stashpad tab").setIcon("layout-grid").onClick(()=>{this.openInNewStashpadTab(t.id)})),s.addItem(d=>d.setTitle("Open in Obsidian editor").setIcon("file-text").onClick(()=>{this.openFileAtEnd(i)})),s.addItem(d=>d.setTitle("Focus in Stashpad").setIcon("arrow-right").onClick(()=>this.navigateTo(t.id))),s.addSeparator(),s.addItem(d=>d.setTitle("Edit in Stashpad").setIcon("pencil-line").onClick(()=>void this.cmdEdit(t))),s.addItem(d=>d.setTitle("Split note\u2026").setIcon("split").onClick(()=>void this.cmdSplit(t))),s.addItem(d=>d.setTitle("Copy text").setIcon("copy").onClick(()=>{l(),this.cmdCopy()})),s.addItem(d=>d.setTitle("Clone (duplicate / copy)").setIcon("files").onClick(()=>{this.selection.has(t.id)||(this.selection.clear(),this.selection.add(t.id),this.lastSelected=t.id),this.cmdClone()})),s.addItem(d=>d.setTitle("Fork into a separate note\u2026").setIcon("git-branch").onClick(()=>{this.selection.has(t.id)||(this.selection.clear(),this.selection.add(t.id),this.lastSelected=t.id),this.cmdForkNote()})),this.addShareExportSubmenu(s,t,{normalizeToNode:!0}),this.plugin.encryption?.isConfigured?.()&&s.addItem(d=>d.setTitle("Encrypt (lock) note + children").setIcon("lock").onClick(async()=>{let h=this.order.getOrder(this.noteFolder,t.parent??S),p=h.indexOf(t.id),f=p>0?h[p-1]:null;await this.plugin.lockNoteSubtree(this.noteFolder,t.id,f)&&this.render()})),s.addSeparator(),s.addItem(d=>d.setTitle("Move to\u2026").setIcon("move").onClick(()=>this.cmdMovePicker())),s.addItem(d=>d.setTitle("Move to Home").setIcon("home").onClick(async()=>{await this.changeParent(t,S),this.plugin.settings.autoNavOnMoveOut&&this.focusId!==S&&this.navigateTo(S)}));let n={folder:this.noteFolder,id:t.id},o=this.plugin.isPinned(n);s.addItem(d=>d.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)}));let a=this.isListPinned(t.id);s.addItem(d=>d.setTitle(a?"Unpin from top of list":"Pin to top of list").setIcon(a?"pin-off":"arrow-up-to-line").onClick(()=>{this.selection.has(t.id)||(this.selection.clear(),this.selection.add(t.id),this.lastSelected=t.id),this.cmdToggleListPin()})),s.addItem(d=>d.setTitle("Set color\u2026").setIcon("palette").onClick(()=>{this.selection.has(t.id)||(this.selection.clear(),this.selection.add(t.id),this.lastSelected=t.id),this.cmdSetColor()}));let l=()=>{this.selection.has(t.id)||(this.selection.clear(),this.selection.add(t.id),this.lastSelected=t.id)},c=d=>{let h=this.isTask(t);if(h){let p=this.isCompleted(t);d.addItem(f=>f.setTitle(p?"Mark incomplete":"Mark complete").setIcon(p?"circle":"check-circle").onClick(()=>{l(),this.cmdToggleComplete()}))}else d.addItem(p=>p.setTitle("Mark complete").setIcon("check-circle").onClick(()=>{l(),this.toggleCompletedForNode(t)})),d.addItem(p=>p.setTitle("Turn into task").setIcon("check-square").onClick(()=>{l(),this.cmdToggleTask()}));d.addItem(p=>p.setTitle("Assign / schedule\u2026").setIcon("user-plus").onClick(()=>{l(),this.cmdAssign()})),h&&(d.addItem(p=>p.setTitle("Snooze (reschedule)\u2026").setIcon("alarm-clock").onClick(()=>{l(),this.cmdSnooze(t)})),d.addItem(p=>p.setTitle("Remove from tasks").setIcon("square").onClick(()=>{l(),this.cmdToggleTask()})))};s.addItem(d=>{d.setTitle("Task").setIcon("check-square");let h=typeof d.setSubmenu=="function"?d.setSubmenu():null;h&&typeof h.addItem=="function"?c(h):d.onClick(()=>this.openCommandPalette())}),s.addSeparator(),s.addItem(d=>d.setTitle("Delete").setIcon("trash").onClick(async()=>{this.selection.has(t.id)||(this.selection.clear(),this.selection.add(t.id),this.lastSelected=t.id),await this.cmdDelete()})),s.addSeparator(),s.addItem(d=>d.setTitle("More commands\u2026").setIcon("terminal").onClick(()=>this.openCommandPalette())),s.showAtMouseEvent(e)}async deleteNote(e){if(!e.file)return;let t=[],i=u=>{for(let g of this.tree.getChildren(u.id))i(g),t.push(g)};i(e);let s=[...t,e],n=s.filter(u=>!!u.file),o=await Promise.all(n.map(u=>this.app.vault.cachedRead(u.file))),a=[];for(let u=0;u<n.length;u++){let g=n[u];a.push(...this.extractAttachments(this.stripFrontmatter(o[u])));let I=this.app.metadataCache.getFileCache(g.file)?.frontmatter;if(Array.isArray(I?.attachments))for(let m of I.attachments)typeof m=="string"&&m.trim()&&a.push(qt(m))}let l=[...new Set(a)],c=this.authorship.collectAuthorIds(s),d=async u=>{let g=await this.snapshotNotes(s,u),I=0;if(u)for(let D of l){let H=this.app.metadataCache.getFirstLinkpathDest(D,"");if(H)try{await this.app.fileManager.trashFile(H),await this.log.append({type:"attachment_remove",id:S,payload:{path:H.path}}),this.plugin.notifications.show({message:`Deleted attachment "${H.name}"`,kind:"warning",category:"attachment",affectedPaths:[H.path],folder:this.noteFolder}),I+=1}catch{}}let m=new Set;for(let D of s)D.parent&&m.add(D.parent);let C=this.currentChildren.findIndex(D=>D.id===e.id),B=null;if(C>=0){for(let D=C+1;D<this.currentChildren.length;D++)if(this.currentChildren[D].id!==e.id){B=this.currentChildren[D].id;break}if(!B){for(let D=C-1;D>=0;D--)if(this.currentChildren[D].id!==e.id){B=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:u?l:[]}})}this.selection.clear(),this.cursorIdx=-1,B&&(this.pendingFocusIds=[B]),this.tree.rebuild(this.noteFolder),this.render({kind:"follow-cursor"});for(let D of m)s.some(H=>H.id===D)||this.fmSync.scheduleParentOfDeleted(D);let E=this.noteFolder,y=`Delete "${this.titleForNode(e)}"`,v=e.id,Q=I>0?` with ${I} attachment${I===1?"":"s"}`:"",w=!1,k=async()=>{w||(w=!0,this.selection.clear(),this.cursorIdx=-1,await this.restoreSnapshots(g,[v]))};this.plugin.notifications.show({message:`Deleted "${this.titleForNode(e)}"${Q}`,kind:"warning",category:"delete",duration:0,affectedIds:[e.id],affectedAuthorIds:c,folder:this.noteFolder,actions:[{label:"Undo delete",onClick:()=>void k()}]}),this.plugin.getUndoStack(E).push({label:y,undo:async()=>{await k()},redo:async()=>{this.selection.clear(),this.cursorIdx=-1,w=!1,await this.trashNotesAndAttachments(g)}})},h=X(),p=t.length>0&&h.confirmBulkDelete,f=l.length>0&&h.confirmAttachmentDelete;if(!p&&!f){await d(!1),this.focusView();return}new Fi(this.app,this.titleForNode(e),t.length,l.length,f,async u=>{await d(u),this.focusView()}).open()}async cmdSwapWithParent(){let e=this.cursorIdx>=0?this.currentChildren[this.cursorIdx]:null;if(!e?.file){new F.Notice("Pick a note first (move the cursor onto it).");return}if(!e.parent||e.parent===S){new F.Notice("Already at Home \u2014 no parent to swap with.");return}let t=this.tree.get(e.parent);if(!t?.file){new F.Notice("Couldn't find the parent note.");return}let i=t.parent??S,s=this.titleForNode(e),n=this.titleForNode(t),o=this.tree.getChildren(t.id).filter(l=>l.id!==e.id).length,a=[`"${n}" becomes a child of "${s}".`];o>0&&a.push(`${o} sibling${o===1?"":"s"} move with it.`),new j(this.app,"Swap notes?",a.join(` `),"Swap",async l=>{l&&await this.swapParentChild(t,e,i)}).open()}offerSwapForDescendantMove(e,t){let i=this.tree.get(t);if(!i?.file){this.plugin.notifications.show({message:`Can't nest "${this.titleForNode(e)}" under one of its own descendants \u2014 that would create a cycle.`,kind:"warning",category:"move",affectedIds:[e.id],folder:this.noteFolder});return}if(i.parent!==e.id){this.plugin.notifications.show({message:`Can't nest "${this.titleForNode(e)}" 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:[e.id,i.id],folder:this.noteFolder});return}let s=this.titleForNode(e),n=this.titleForNode(i),o=this.tree.getChildren(e.id).filter(l=>l.id!==i.id).length,a=[`"${s}" becomes a child of "${n}".`];o>0&&a.push(`${o} sibling${o===1?"":"s"} move with it.`),new j(this.app,"Confirm Note Swap",a.join(` -`),"Swap",async l=>{if(!l)return;let c=e.parent??S;await this.swapParentChild(e,i,c)}).open()}async swapParentChild(e,t,i){if(!e.file||!t.file)return;if(t.parent!==e.id){new k.Notice("Swap aborted: parent/child relationship changed.");return}let s=this.noteFolder,n=e.parent,o=this.tree.getChildren(e.id).filter(f=>f.id!==t.id).filter(f=>!!f.file),a=o.map(f=>({id:f.id,path:f.file.path,was:f.parent})),l=this.order.getOrder(s,i).slice(),c=this.order.getOrder(s,t.id).slice(),A=this.order.getOrder(s,e.id).slice();await this.app.fileManager.processFrontMatter(t.file,f=>{f.parent=i}),this.fmSync.scheduleParentChange(t.id,e.id,i),await this.app.fileManager.processFrontMatter(e.file,f=>{f.parent=t.id}),this.fmSync.scheduleParentChange(e.id,n,t.id);for(let f of o)await this.app.fileManager.processFrontMatter(f.file,u=>{u.parent=t.id}),this.fmSync.scheduleParentChange(f.id,e.id,t.id);if(l.length>0){let f=l.includes(e.id)?l.map(u=>u===e.id?t.id:u):[...l.filter(u=>u!==t.id),t.id];this.order.setOrder(s,i,f)}let h=o.map(f=>f.id),p=[e.id,...c.filter(f=>f!==e.id&&!h.includes(f)),...h];this.order.setOrder(s,t.id,p),this.order.setOrder(s,e.id,[]),await this.order.save(s),await this.log.append({type:"parent_change",id:t.id,payload:{from:e.id,to:i,reason:"swap"}}),await this.log.append({type:"parent_change",id:e.id,payload:{from:n,to:t.id,reason:"swap"}});for(let f of a)await this.log.append({type:"parent_change",id:f.id,payload:{from:f.was,to:t.id,reason:"swap"}});this.tree.rebuild(s),this.pendingFocusIds=[t.id],this.render({kind:"follow-cursor"}),this.plugin.notifications.show({message:`Swapped "${this.titleForNode(t)}" \u2194 "${this.titleForNode(e)}".`,kind:"success",category:"move",affectedIds:[t.id,e.id,...h],folder:s}),this.plugin.getUndoStack(s).push({label:`Swap "${this.titleForNode(t)}" \u2194 parent`,undo:async()=>{let f=this.tree.get(e.id),u=this.tree.get(t.id);f?.file&&await this.app.fileManager.processFrontMatter(f.file,g=>{n==null||n===S?(delete g.parent,g.parent=S):g.parent=n}),u?.file&&await this.app.fileManager.processFrontMatter(u.file,g=>{g.parent=e.id});for(let g of a){let I=this.app.vault.getAbstractFileByPath(g.path);I&&await this.app.fileManager.processFrontMatter(I,m=>{g.was==null?m.parent=S:m.parent=g.was})}this.order.setOrder(s,i,l),this.order.setOrder(s,t.id,c),this.order.setOrder(s,e.id,A),await this.order.save(s),this.tree.rebuild(s),this.pendingFocusIds=[e.id],this.render({kind:"follow-cursor"})},redo:async()=>{await this.swapParentChild(e,t,i)}})}async changeParent(e,t,i={record:!0}){if(!e.file)return!1;let s=e.file,n=e.parent,o=l=>l??S;if(o(n)===o(t)){if(!i.quiet){let l=this.titleForNode(e),c=t===S?"Home":`"${this.titleForNode(this.tree.get(t)??e)}"`;this.plugin.notifications.show({message:`"${l}" is already under ${c}.`,kind:"info",category:"move",affectedIds:[e.id],folder:this.noteFolder})}return!1}if(t===e.id)return i.quiet||this.plugin.notifications.show({message:`Can't move "${this.titleForNode(e)}" into itself.`,kind:"warning",category:"move",affectedIds:[e.id],folder:this.noteFolder}),!1;if(t!==S&&this.isDescendant(t,e.id))return i.quiet||this.offerSwapForDescendantMove(e,t),!1;let a=this.authorship.collectAuthorIds([e]);if(await this.app.fileManager.processFrontMatter(s,l=>{l.parent=t}),this.fmSync.scheduleParentChange(e.id,n,t),await this.log.append({type:"parent_change",id:e.id,payload:{from:n,to:t}}),this.pendingFocusIds=[e.id],this.focusId!==t&&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 l=this.tree.get(t),c=l?this.titleForNode(l):"(root)";this.plugin.notifications.show({message:`Reparented "${this.titleForNode(e)}" \u2192 "${c}"`,kind:"success",category:"move",affectedIds:[e.id],affectedAuthorIds:a,folder:this.noteFolder,actions:t===S?[]:[{label:"Jump to parent",onClick:()=>this.navigateTo(t)}]})}if(i.record!==!1){let l=this.noteFolder,c=s.path,A=e.id;this.plugin.getUndoStack(l).push({label:"Move note",undo:async()=>{let h=this.fileForNote(A,c);if(h){await this.app.fileManager.processFrontMatter(h,p=>{p.parent=n}),this.pendingFocusIds=[A],this.focusId!==n&&this.focusId!==t?(this.selection.clear(),this.cursorIdx=-1):this.focusId===t&&(this.selection.clear(),this.cursorIdx=-1,this.pendingFocusIds=null),this.tree.rebuild(l),this.render({kind:"follow-cursor"});{let p=this.selectionGuardKey,f=()=>{if(this.selectionGuardKey!==p||this.selection.has(A))return;let u=this.currentChildren.findIndex(g=>g.id===A);u<0||(this.selection.add(A),this.cursorIdx=u,this.render({kind:"follow-cursor"}))};setTimeout(f,120),setTimeout(f,400)}}},redo:async()=>{let h=this.fileForNote(A,c);if(h){await this.app.fileManager.processFrontMatter(h,p=>{p.parent=t}),this.pendingFocusIds=[A],this.focusId!==t&&this.focusId!==n?(this.selection.clear(),this.cursorIdx=-1):this.focusId===n&&(this.selection.clear(),this.cursorIdx=-1,this.pendingFocusIds=null),this.tree.rebuild(l),this.render({kind:"follow-cursor"});{let p=this.selectionGuardKey,f=()=>{if(this.selectionGuardKey!==p||this.selection.has(A))return;let u=this.currentChildren.findIndex(g=>g.id===A);u<0||(this.selection.add(A),this.cursorIdx=u,this.render({kind:"follow-cursor"}))};setTimeout(f,120),setTimeout(f,400)}}}})}return!0}notifyBatchMove(e,t,i){if(!e.length)return;let s=this.tree.get(t),n=t===S?"Home":`"${s?this.titleForNode(s):"the destination"}"`,o=l=>i.get(l.id)??0,a;if(e.length===1){let l=this.titleForNode(e[0]),c=o(e[0]);a=c>0?`Moved "${l}" and its ${c} ${c===1?"child":"children"} \u2192 ${n}`:`Moved "${l}" \u2192 ${n}`}else{let l=e.reduce((c,A)=>c+o(A),0);a=l>0?`Moved ${e.length} notes (${l} nested) \u2192 ${n}`:`Moved ${e.length} notes \u2192 ${n}`}this.plugin.notifications.show({message:a,kind:"success",category:"move",duration:t===S?void 0:0,affectedIds:e.map(l=>l.id),affectedAuthorIds:this.authorship.collectAuthorIds(e),folder:this.noteFolder,actions:t===S?[]:[{label:"Jump to destination",onClick:()=>this.navigateTo(t)}]})}};Ns.AIMED_TAP_WINDOW_MS=600;var Ts=Ns,Xn=class extends k.SuggestModal{constructor(e,t,i){super(e);this.entries=t;this.onPick=i;this.setPlaceholder("Restore which deleted note?")}getSuggestions(e){let t=e.toLowerCase();return this.entries.filter(i=>`${i.label} ${i.folder}`.toLowerCase().includes(t))}renderSuggestion(e,t){t.createDiv({text:e.label}),t.createEl("small",{text:`from ${e.folder}`,cls:"stashpad-suggest-path"})}onChooseSuggestion(e){this.onPick(e.blob)}};var Ce=require("obsidian");ce();ve();var Zn=Ce.moment,jn=class extends Ce.ItemView{constructor(e,t){super(e);this.plugin=t;this.renderPending=!1;this.renderGen=0;this.selected=new Set;this.order=[];this.anchorBlob=null;this.trashMode="byfolder"}getViewType(){return li}getDisplayText(){return"Trash"}getIcon(){return"trash-2"}async onOpen(){this.containerEl.addClass("stashpad-trash-view"),this.registerEvent(this.app.vault.on("create",e=>{e.path.startsWith("_deleted/")&&this.scheduleRender()})),this.registerEvent(this.app.vault.on("delete",e=>{e.path.startsWith("_deleted/")&&this.scheduleRender()})),this.registerDomEvent(document,"keydown",e=>{if(this.app.workspace.activeLeaf!==this.leaf)return;let t=e.target;if(!(t&&(t.tagName==="INPUT"||t.tagName==="TEXTAREA"||t.isContentEditable))&&(e.metaKey||e.ctrlKey)&&!e.altKey&&(e.key==="a"||e.key==="A")){if(this.order.length===0)return;e.preventDefault(),this.selectAll()}}),await this.render()}scheduleRender(){this.renderPending||(this.renderPending=!0,window.setTimeout(()=>{this.renderPending=!1,this.render()},150))}async render(){let e=++this.renderGen,t=this.contentEl;t.empty(),t.addClass("stashpad-trash-view-body"),this.order=[];let i=t.createDiv({cls:"stashpad-trash-view-header"});i.createEl("h3",{text:"Trash"});let s=i.createEl("button",{cls:"stashpad-trash-iconbtn"});(0,Ce.setIcon)(s,"refresh-cw"),s.setAttr("aria-label","Refresh"),s.onclick=()=>void this.render();let n=this.plugin.encryption?.isConfigured?.()?await this.plugin.listDeletedTrash():[];if(e!==this.renderGen)return;let o=await this.plugin.listPlaintextTrash();if(e!==this.renderGen)return;let a=[...n,...o],l=await this.plugin.listRawTrashStashpadNotes();if(e!==this.renderGen)return;if(a.length===0&&l.length===0){t.createDiv({cls:"stashpad-trash-empty",text:"Trash is empty. Securely-deleted notes land in the encrypted trash; plain deletes go to Obsidian's trash \u2014 both show here."});return}if(Tn(t,this.trashMode,{total:a.length+l.length,enc:a.length,dec:l.length},h=>{this.trashMode=h,this.clearSelection(),this.render()}),this.trashMode==="mixed"){this.renderMixed(t,a,l);return}let c=this.trashMode!=="unencrypted"&&a.length>0,A=this.trashMode!=="encrypted"&&l.length>0;if(!c&&!A){t.createDiv({cls:"stashpad-trash-empty",text:"Nothing in this view."});return}if(c){let h=i.createEl("button",{cls:"stashpad-trash-restore",text:"Restore all"});(0,Ce.setIcon)(h.createSpan({cls:"stashpad-btn-icon"}),"rotate-ccw"),h.onclick=async()=>{h.disabled=!0,await this.plugin.restoreAllTrash(),this.clearSelection(),await this.render()};let p=new Set(a.map(f=>f.blob));for(let f of[...this.selected])p.has(f)||this.selected.delete(f);if(this.selected.size>0){let f=t.createDiv({cls:"stashpad-trash-selbar"});f.createSpan({cls:"stashpad-trash-selcount",text:`${this.selected.size} selected`});let u=f.createEl("button",{cls:"stashpad-trash-restore",text:"Restore selected"});u.onclick=async()=>{u.disabled=!0;let m=0;for(let C of[...this.selected])await this.plugin.restoreDeletedAt(C,{silent:!0})||m++;m>0&&new Ce.Notice(`${m} item${m===1?"":"s"} couldn't be restored (locked key?) \u2014 still in trash.`),this.clearSelection(),await this.render()};let g=f.createEl("button",{cls:"stashpad-trash-delete mod-warning",text:"Delete selected"});g.onclick=()=>this.confirmPurge([...this.selected]);let I=f.createEl("button",{cls:"stashpad-trash-iconbtn",text:"Clear"});I.onclick=()=>{this.clearSelection(),this.render()}}}if(this.order=[],c)if(this.trashMode==="byfolder"){let h=new Map;for(let f of a){let u=f.meta?.title?f.meta.originalFolder||"(unknown folder)":" hidden";(h.get(u)??h.set(u,[]).get(u)).push(f)}let p=[...h.keys()].sort((f,u)=>f===" hidden"?1:u===" hidden"?-1:f.localeCompare(u));for(let f of p){let u=f===" hidden",g=t.createDiv({cls:"stashpad-trash-group"}),I=g.createDiv({cls:"stashpad-trash-group-head"});(0,Ce.setIcon)(I.createSpan({cls:"stashpad-trash-group-icon"}),u?"lock":"folder"),I.createSpan({text:u?"Hidden (title obscured)":f.split("/").pop()||f}),I.createSpan({cls:"stashpad-trash-group-count",text:String(h.get(f).length)});for(let m of h.get(f))this.encRow(g,m,u)}}else{let h=t.createDiv({cls:"stashpad-trash-group"}),p=h.createDiv({cls:"stashpad-trash-group-head"});(0,Ce.setIcon)(p.createSpan({cls:"stashpad-trash-group-icon"}),"trash-2"),p.createSpan({text:"Stashpad trash"}),p.createSpan({cls:"stashpad-trash-group-count",text:String(a.length)});for(let f of a)this.encRow(h,f,!f.meta?.title)}A&&this.renderRawSection(t,l)}encRow(e,t,i){let s=this.order.length;this.order.push(t.blob);let n=e.createDiv({cls:"stashpad-trash-row"});this.selected.has(t.blob)&&n.addClass("is-selected"),n.addEventListener("click",h=>{h.target.closest("button")||this.onRowClick(s,t.blob,h)});let o=n.createDiv({cls:"stashpad-trash-row-main"});o.createSpan({cls:"stashpad-trash-title",text:i?"Locked note":t.meta?.title||"Locked note"});let a=t.meta?.deletedAt?`deleted ${Zn(t.meta.deletedAt).fromNow()}`:"deleted",l=t.meta&&t.meta.count>1?` \xB7 ${t.meta.count} ${t.meta.kind==="rawtrash"?"files":"notes"}`:"";o.createSpan({cls:"stashpad-trash-sub",text:a+l});let c=n.createEl("button",{cls:"stashpad-trash-restore",text:"Restore"});(0,Ce.setIcon)(c.createSpan({cls:"stashpad-btn-icon"}),"rotate-ccw"),c.onclick=async()=>{c.disabled=!0,await this.plugin.restoreDeletedAt(t.blob)?await this.render():c.disabled=!1};let A=n.createEl("button",{cls:"stashpad-trash-delete",attr:{"aria-label":"Delete permanently"}});(0,Ce.setIcon)(A,"trash-2"),A.onclick=()=>this.confirmPurge([t.blob])}renderMixed(e,t,i){let s=[];for(let o of t)s.push({ts:o.meta?.deletedAt&&Date.parse(String(o.meta.deletedAt))||0,kind:"enc",enc:o});for(let o of i)s.push({ts:o.mtime||0,kind:"raw",raw:o});s.sort((o,a)=>a.ts-o.ts);let n=e.createDiv({cls:"stashpad-trash-group"});for(let o of s){let a=n.createDiv({cls:"stashpad-trash-row"}),l=a.createDiv({cls:"stashpad-trash-row-main"}),c=o.kind==="enc"&&o.enc?.meta?.encrypted===!1,A=l.createSpan({cls:`stashpad-trash-kind is-${o.kind}`});if((0,Ce.setIcon)(A,o.kind==="enc"&&!c?"lock":"trash"),o.kind==="enc"&&o.enc){let h=o.enc,p=!h.meta?.title&&!c;l.createSpan({cls:"stashpad-trash-title",text:h.meta?.title||(c?"Deleted note":"Locked note")});let f=h.meta?.deletedAt?`deleted ${Zn(h.meta.deletedAt).fromNow()}`:"deleted";l.createSpan({cls:"stashpad-trash-sub",text:`${f} \xB7 ${c?"unencrypted":"encrypted"}`});let u=a.createEl("button",{cls:"stashpad-trash-restore",text:"Restore"});(0,Ce.setIcon)(u.createSpan({cls:"stashpad-btn-icon"}),"rotate-ccw"),u.onclick=async()=>{u.disabled=!0,await this.plugin.restoreDeletedAt(h.blob)?await this.render():u.disabled=!1};let g=a.createEl("button",{cls:"stashpad-trash-delete",attr:{"aria-label":"Delete permanently"}});(0,Ce.setIcon)(g,"trash-2"),g.onclick=()=>this.confirmPurge([h.blob])}else if(o.raw){let h=o.raw;l.createSpan({cls:"stashpad-trash-title",text:h.title});let p=h.mtime?`deleted ${Zn(h.mtime).fromNow()}`:"in Obsidian trash";l.createSpan({cls:"stashpad-trash-sub",text:`${p} \xB7 unencrypted`});let f=a.createEl("button",{cls:"stashpad-trash-restore",text:"Restore"});(0,Ce.setIcon)(f.createSpan({cls:"stashpad-btn-icon"}),"rotate-ccw"),f.onclick=async()=>{f.disabled=!0,await this.plugin.restoreRawTrashNote(h.path)?await this.render():f.disabled=!1}}}}renderRawSection(e,t){if(t.length===0)return;let i=e.createDiv({cls:"stashpad-trash-group"}),s=i.createDiv({cls:"stashpad-trash-group-head"});(0,Ce.setIcon)(s.createSpan({cls:"stashpad-trash-group-icon"}),"trash"),s.createSpan({text:"Obsidian trash (unencrypted)"}),s.createSpan({cls:"stashpad-trash-group-count",text:String(t.length)});for(let n of t){let o=i.createDiv({cls:"stashpad-trash-row"}),a=o.createDiv({cls:"stashpad-trash-row-main"});a.createSpan({cls:"stashpad-trash-title",text:n.title});let l=n.mtime?`deleted ${Zn(n.mtime).fromNow()}`:"in Obsidian trash";a.createSpan({cls:"stashpad-trash-sub",text:l});let c=o.createEl("button",{cls:"stashpad-trash-restore",text:"Restore"});(0,Ce.setIcon)(c.createSpan({cls:"stashpad-btn-icon"}),"rotate-ccw"),c.onclick=async()=>{c.disabled=!0,await this.plugin.restoreRawTrashNote(n.path)?await this.render():c.disabled=!1}}}clearSelection(){this.selected.clear(),this.anchorBlob=null}selectAll(){if(this.order.length!==0){for(let e of this.order)this.selected.add(e);this.anchorBlob=this.order[this.order.length-1]??null,this.render()}}onRowClick(e,t,i){let s=this.anchorBlob!==null?this.order.indexOf(this.anchorBlob):-1;if(i.shiftKey&&s>=0){let[n,o]=s<e?[s,e]:[e,s];this.selected.clear();for(let a=n;a<=o;a++)this.selected.add(this.order[a])}else i.metaKey||i.ctrlKey?(this.selected.has(t)?this.selected.delete(t):this.selected.add(t),this.anchorBlob=t):(this.selected.size===1&&this.selected.has(t)?this.selected.clear():(this.selected.clear(),this.selected.add(t)),this.anchorBlob=t);this.render()}confirmPurge(e){if(e.length===0)return;let t=e.length;new j(this.app,t===1?"Delete permanently?":`Delete ${t} items permanently?`,`${t===1?"This encrypted item":`These ${t} encrypted items`} will be PERMANENTLY deleted and CANNOT be restored \u2014 there is no decrypted copy. Continue?`,"Delete forever",async i=>{if(i){for(let s of e)await this.plugin.purgeDeletedAt(s);this.clearSelection(),await this.render()}},"Cancel",!0).open()}async onClose(){this.contentEl.empty()}};async function Xl(d){let{workspace:r}=d.app,e=r.getLeavesOfType(li);if(e.length>0){r.revealLeaf(e[0]);return}let t=r.getMostRecentLeaf(),i=r.getLeaf("tab");await i.setViewState({type:li,active:!0}),r.revealLeaf(i),yt(r,i,t,s=>d.registerEvent(s))}var ni=require("obsidian"),Ms=class Ms{constructor(r){this.plugin=r;this.tick=null;this.lastTouch=new Map;this.counting=new Set;this.countdownTimers=new Set}key(r,e){return`${r} ${e}`}delayMin(r){let e=r.peekMin;if(e!=null)return e;let i=(this.plugin.settings.folderEncPrefs??{})[r.folder.replace(/\/+$/,"")]?.reEncryptAfterMin;return i??this.plugin.settings.reEncryptAfterMin??0}anyArmed(){if((this.plugin.settings.reEncryptAfterMin??0)>0)return!0;for(let r of Object.values(this.plugin.settings.folderEncPrefs??{}))if((r?.reEncryptAfterMin??0)>0)return!0;return this.plugin.reEncryptWatching().some(r=>(r.peekMin??0)>0)}start(){let r=e=>{e&&this.lastTouch.set(e.replace(/\/+$/,""),Date.now())};this.plugin.registerEvent(this.plugin.app.vault.on("modify",e=>{e instanceof ni.TFile&&r(e.parent?.path??"")})),this.plugin.registerEvent(this.plugin.app.workspace.on("file-open",e=>{e&&r(e.parent?.path??"")})),this.tick=window.setInterval(()=>void this.poll(),3e4),this.plugin.registerInterval(this.tick)}folderHasOpenEditor(r){let e=r.replace(/\/+$/,""),t=!1;return this.plugin.app.workspace.iterateAllLeaves(i=>{let s=i.view;s instanceof ni.MarkdownView&&s.file&&(s.file.parent?.path?.replace(/\/+$/,"")??"")===e&&(t=!0)}),t}keyReady(r){let e=this.plugin.encryption;return e?.isConfigured?.()?e.hasFolderKey(r)&&e.isFolderUnlocked(r):!1}async poll(){if(!this.anyArmed())return;let r=Date.now();for(let e of this.plugin.reEncryptWatching()){let t=this.delayMin(e);if(t<=0)continue;let i=e.folder.replace(/\/+$/,""),s=this.key(i,e.rootId);if(this.counting.has(s))continue;let n=Math.max(Date.parse(e.unlockedAt)||0,this.lastTouch.get(i)??0);if(!(r<n+t*6e4)&&this.keyReady(i)){if(this.folderHasOpenEditor(i)){eA(this.lastTouch,i,r);continue}this.countdownThenLock(e,s)}}}countdownThenLock(r,e){this.counting.add(e);let t=r.folder.replace(/\/+$/,""),i=r.title||"a note",s=Date.now(),n=Ms.COUNTDOWN_SECS,o=!1,a=new ni.Notice("",0),l=()=>{window.clearInterval(h),this.countdownTimers.delete(h),a.hide(),this.counting.delete(e)},c=()=>{this.lastTouch.set(t,Date.now()),l()},A=()=>{a.noticeEl.empty(),a.noticeEl.createSpan({text:`\u{1F512} Re-encrypting \u201C${i}\u201D in ${n}s\u2026 `}),a.noticeEl.createEl("button",{text:"Keep unlocked"}).onclick=()=>{o=!0,c()}};A();let h=window.setInterval(async()=>{if(o)return;if((this.lastTouch.get(t)??0)>s){c();return}if(n-=1,n>0){A();return}if(l(),!this.plugin.reEncryptWatching().some(f=>f.folder===r.folder&&f.rootId===r.rootId))return;if(this.folderHasOpenEditor(t)){this.lastTouch.set(t,Date.now());return}if(!this.keyReady(t)){this.lastTouch.set(t,Date.now());return}await this.plugin.lockNoteSubtree(r.folder,r.rootId,null,{silent:!0})&&new ni.Notice(`Re-encrypted \u201C${i}\u201D.`)},1e3);this.countdownTimers.add(h),this.plugin.registerInterval(h)}dispose(){for(let r of this.countdownTimers)window.clearInterval(r);this.countdownTimers.clear(),this.counting.clear()}};Ms.COUNTDOWN_SECS=10,Ms.RECENT_EDIT_MS=2e4;var _n=Ms;function eA(d,r,e){d.set(r.replace(/\/+$/,""),e)}ce();var W=require("obsidian");ce();ve();function oi(d){return d.kind==="folder"?`f:${d.folder}`:`n:${d.folder}:${d.id}`}var eo=class d extends W.ItemView{constructor(e,t){super(e);this.plugin=t;this.renderTimer=null;this.dividerCleanup=null;this.pinExpanded=new Set;this.folderPinExpanded=new Set;this.homeColorByFolder=new Map}getViewType(){return bt}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()))}refresh(){this.scheduleRender()}scheduleRender(){this.renderTimer==null&&(this.renderTimer=window.setTimeout(()=>{this.renderTimer=null,this.containerEl.isConnected&&this.render()},100))}render(){let e=this.contentEl;e.empty(),e.addClass("stashpad-folderpanel-root");let t=this.clampFrac(this.plugin.settings.folderPanelPinnedFraction??.5),i=e.createDiv({cls:"stashpad-folderpanel-section stashpad-folderpanel-pinned"});i.style.flex=`0 0 ${(t*100).toFixed(2)}%`;let s=i.createDiv({cls:"stashpad-folderpanel-heading stashpad-folderpanel-heading-row"});s.createSpan({cls:"stashpad-folderpanel-heading-title",text:"Pinned"});let n=s.createEl("button",{cls:"stashpad-folderpanel-iconbtn"});(0,W.setIcon)(n,"list"),n.setAttr("aria-label","Pinned view options"),n.onclick=h=>{h.stopPropagation(),this.openPinnedOptionsMenu(h)},this.renderPinned(i.createDiv({cls:"stashpad-folderpanel-list stashpad-folderpanel-pins"}));let o=e.createDiv({cls:"stashpad-folderpanel-divider"});o.createDiv({cls:"stashpad-folderpanel-divider-grip"}),this.attachDividerDrag(e,i,o);let a=e.createDiv({cls:"stashpad-folderpanel-section stashpad-folderpanel-folders"});a.setCssStyles({flex:"1 1 0"});let l=a.createDiv({cls:"stashpad-folderpanel-heading stashpad-folderpanel-heading-row"}),c=l.createSpan({cls:"stashpad-folderpanel-heading-title stashpad-folderpanel-heading-switch",text:"Folders"});c.setAttr("aria-label","Open folder switcher"),c.onmousedown=h=>{h.button===0&&(h.preventDefault(),this.plugin.openFolderPicker())};let A=l.createEl("button",{cls:"stashpad-folderpanel-iconbtn stashpad-folderpanel-heading-newfolder"});if((0,W.setIcon)(A,"folder-plus"),A.setAttr("aria-label","New Stashpad folder (folder switcher)"),A.onmousedown=h=>{h.button===0&&(h.preventDefault(),h.stopPropagation(),this.plugin.openFolderPicker())},this.plugin.encryption?.isConfigured?.()){let h=l.createEl("button",{cls:"stashpad-folderpanel-iconbtn stashpad-folderpanel-heading-trash"});(0,W.setIcon)(h,"trash-2"),h.setAttr("aria-label","Open encrypted trash"),h.onmousedown=p=>{p.button===0&&(p.preventDefault(),p.stopPropagation(),this.plugin.openEncryptedTrash())}}this.renderFolders(a.createDiv({cls:"stashpad-folderpanel-list"}))}clampFrac(e){return Number.isFinite(e)?Math.max(.15,Math.min(.85,e)):.5}attachDividerDrag(e,t,i){let s=null,n=l=>{let c=e.getBoundingClientRect();if(c.height<=0)return;let A=this.clampFrac((l.clientY-c.top)/c.height);s=A,t.style.flex=`0 0 ${(A*100).toFixed(2)}%`},o=()=>{document.removeEventListener("pointermove",n),document.removeEventListener("pointerup",a),document.removeEventListener("pointercancel",a),document.body.removeClass("stashpad-folderpanel-resizing"),this.dividerCleanup=null},a=l=>{try{i.releasePointerCapture(l.pointerId)}catch{}l.type==="pointerup"&&s!=null&&(this.plugin.settings.folderPanelPinnedFraction=s,this.plugin.saveSettings()),o()};this.registerDomEvent(i,"pointerdown",l=>{l.preventDefault(),document.body.addClass("stashpad-folderpanel-resizing");try{i.setPointerCapture(l.pointerId)}catch{}document.addEventListener("pointermove",n),document.addEventListener("pointerup",a),document.addEventListener("pointercancel",a),this.dividerCleanup=o})}openPinnedOptionsMenu(e){let t=this.plugin.settings.folderPanelPinnedGrouping??"pin-order",i=new W.Menu;i.addItem(s=>s.setTitle("Sort by pin order").setChecked(t==="pin-order").onClick(()=>void this.setPinnedGrouping("pin-order"))),i.addItem(s=>s.setTitle("Group by folder").setChecked(t==="folder").onClick(()=>void this.setPinnedGrouping("folder"))),i.showAtMouseEvent(e)}async setPinnedGrouping(e){(this.plugin.settings.folderPanelPinnedGrouping??"pin-order")!==e&&(this.plugin.settings.folderPanelPinnedGrouping=e,await this.plugin.saveSettings(),this.render())}unifiedPinnedItems(){let e=[];for(let t of this.plugin.discoverStashpadFolders())this.folderState(t)==="pinned"&&e.push({kind:"folder",folder:d.clean(t),at:this.folderPinnedAt(t)});for(let t of this.plugin.listPinnedNotes())e.push({kind:"note",folder:t.folder,id:t.id,file:t.file,at:t.pinnedAt});return e.sort((t,i)=>t.at-i.at||oi(t).localeCompare(oi(i))),e}folderPinnedAt(e){let t=d.clean(e),i=(this.plugin.settings.folderPanelPinnedAt??{})[t];if(typeof i=="number")return i;let s=(this.plugin.settings.folderPanelPinned??[]).indexOf(t);return s>=0?s:0}ensureFolderPinOrder(){let e=this.plugin.settings;e.folderPanelPinnedAt=e.folderPanelPinnedAt??{};let t=!1;(e.folderPanelPinned??[]).forEach((i,s)=>{let n=d.clean(i);typeof e.folderPanelPinnedAt[n]!="number"&&(e.folderPanelPinnedAt[n]=s,t=!0)});for(let i of Object.keys(e.folderPanelPinnedAt))(e.folderPanelPinned??[]).includes(i)||(delete e.folderPanelPinnedAt[i],t=!0);t&&this.plugin.saveSettings()}renderPinned(e){this.ensureFolderPinOrder();let t=this.unifiedPinnedItems();if(t.length===0){e.createDiv({cls:"stashpad-folderpanel-empty",text:"Nothing pinned yet \u2014 pin a note or folder from its right-click menu."});return}let i=this.openFolders(),s=this.plugin.settings.folderPanelPinnedGrouping??"pin-order",n=new Map;if(t.forEach((p,f)=>n.set(p,f)),s!=="folder"){for(let p of t)this.renderPinnedItem(e,p,n.get(p),i,!0);return}let o=t.filter(p=>p.kind==="note"),a=t.filter(p=>p.kind==="folder"),l=new Map;for(let p of o){let f=l.get(p.folder);f||(f=[],l.set(p.folder,f)),f.push(p)}for(let p of a.filter(f=>!l.has(f.folder)).sort((f,u)=>f.at-u.at))this.renderPinnedItem(e,p,n.get(p),i,!1);let c=p=>{let f=1/0,u=a.find(g=>g.folder===p);u&&(f=Math.min(f,u.at));for(let g of l.get(p)??[])f=Math.min(f,g.at);return f},A=[...l.keys()].sort((p,f)=>c(p)-c(f)||p.localeCompare(f)),h=this.plugin.lastActiveStashpadLeaf?.view?.noteFolder;for(let p of A){let f=e.createDiv({cls:"stashpad-pinned-group-header"});p===h&&f.addClass("is-active-folder"),f.createSpan({cls:"stashpad-pinned-group-name",text:p.split("/").pop()||p});let u=[],g=a.find(C=>C.folder===p);g&&u.push(g),u.push(...l.get(p)??[]);let I=this.orderedGroupItems(p,u),m=I.map(oi);I.forEach((C,B)=>{let E=C.kind==="folder"?this.renderFolderRow(e,C.folder,i):this.renderPinNote(e,C.folder,C.id,C.file,B,!1);this.attachGroupItemDrag(E,p,B,m)})}}orderedGroupItems(e,t){let i=(this.plugin.settings.folderPanelGroupItemOrder??{})[d.clean(e)]??[],s=new Map(i.map((n,o)=>[n,o]));return t.slice().sort((n,o)=>{let a=s.has(oi(n))?s.get(oi(n)):1/0,l=s.has(oi(o))?s.get(oi(o)):1/0;return a-l||n.at-o.at})}async reorderGroupItem(e,t,i,s){if(i<0||i>=t.length)return;let n=t.slice(),[o]=n.splice(i,1),a=s>i?s-1:s;n.splice(Math.max(0,Math.min(a,n.length)),0,o),this.plugin.settings.folderPanelGroupItemOrder=this.plugin.settings.folderPanelGroupItemOrder??{},this.plugin.settings.folderPanelGroupItemOrder[d.clean(e)]=n,await this.plugin.saveSettings(),this.render()}attachGroupItemDrag(e,t,i,s){let n="application/x-stashpad-groupitem";e.draggable=!0,e.addEventListener("dragstart",o=>{o.dataTransfer?.setData(n,JSON.stringify({folder:t,idx:i})),o.dataTransfer&&(o.dataTransfer.effectAllowed="move"),e.addClass("is-dragging")}),e.addEventListener("dragend",()=>e.removeClass("is-dragging")),e.addEventListener("dragover",o=>{if(!o.dataTransfer?.types?.includes(n))return;o.preventDefault(),o.dataTransfer.dropEffect="move";let a=e.getBoundingClientRect(),l=o.clientY-a.top<a.height/2;e.toggleClass("drop-before",l),e.toggleClass("drop-after",!l)}),e.addEventListener("dragleave",()=>{e.removeClass("drop-before"),e.removeClass("drop-after")}),e.addEventListener("drop",o=>{if(!o.dataTransfer?.types?.includes(n))return;o.preventDefault(),e.removeClass("drop-before"),e.removeClass("drop-after");let a=null;try{a=JSON.parse(o.dataTransfer.getData(n)||"null")}catch{a=null}if(!a||a.folder!==t||a.idx===i)return;let l=e.getBoundingClientRect(),c=o.clientY-l.top<l.height/2;this.reorderGroupItem(t,s,a.idx,c?i:i+1)})}renderPinnedItem(e,t,i,s,n){if(t.kind==="folder"){let o=this.renderFolderRow(e,t.folder,s);n&&this.attachPinDrag(o,i)}else this.renderPinNote(e,t.folder,t.id,t.file,i,n)}attachPinDrag(e,t){e.draggable=!0,e.dataset.pinIdx=String(t),e.addEventListener("dragstart",i=>{i.dataTransfer?.setData("text/plain",String(t)),i.dataTransfer&&(i.dataTransfer.effectAllowed="move"),e.addClass("is-dragging")}),e.addEventListener("dragend",()=>e.removeClass("is-dragging")),e.addEventListener("dragover",i=>{i.preventDefault(),i.dataTransfer&&(i.dataTransfer.dropEffect="move");let s=e.getBoundingClientRect(),n=i.clientY-s.top<s.height/2;e.toggleClass("drop-before",n),e.toggleClass("drop-after",!n)}),e.addEventListener("dragleave",()=>{e.removeClass("drop-before"),e.removeClass("drop-after")}),e.addEventListener("drop",i=>{i.preventDefault(),e.removeClass("drop-before"),e.removeClass("drop-after");let s=parseInt(i.dataTransfer?.getData("text/plain")??"",10);if(!Number.isFinite(s)||s===t)return;let n=e.getBoundingClientRect(),o=i.clientY-n.top<n.height/2;this.reorderPinnedItem(s,o?t:t+1)})}async reorderPinnedItem(e,t){let i=this.unifiedPinnedItems();if(e<0||e>=i.length)return;let s=i[e],n=i.filter((A,h)=>h!==e),o=Math.max(0,Math.min(t>e?t-1:t,n.length)),a=n[o-1],l=n[o],c;if(!a&&!l?c=Date.now():a?l?c=(a.at+l.at)/2:c=a.at+1e3:c=l.at-1e3,s.kind==="folder")this.plugin.settings.folderPanelPinnedAt=this.plugin.settings.folderPanelPinnedAt??{},this.plugin.settings.folderPanelPinnedAt[s.folder]=c,await this.plugin.saveSettings();else try{await this.app.fileManager.processFrontMatter(s.file,A=>{A.pinnedAt=c})}catch(A){console.warn("[Stashpad] pin reorder failed",A)}this.render()}renderPinNote(e,t,i,s,n,o){let a=this.app.metadataCache.getFileCache(s)?.frontmatter??{},l=typeof a.color=="string"?a.color:null,c=a.completed===!0,A=this.childrenOf(t,i),h=A.length>0,p=`${t}|${i}`,f=this.pinExpanded.has(p),u=e.createDiv({cls:"stashpad-pinned-row"});l&&(u.addClass("has-color"),u.style.setProperty("--stashpad-note-color",l)),c&&u.addClass("is-completed"),o&&this.attachPinDrag(u,n);let g=u.createSpan({cls:"stashpad-pinned-toggle"});h&&(Ht(g,A.length,f),g.onclick=C=>{C.stopPropagation(),this.pinExpanded.has(p)?this.pinExpanded.delete(p):this.pinExpanded.add(p),this.render()});let I=u.createSpan({cls:"stashpad-pinned-icon"});(0,W.setIcon)(I,h?"folder-tree":"file-text"),l&&(I.style.color=l);let m=u.createSpan({cls:"stashpad-pinned-label",text:this.titleFromFile(s)});if(m.onclick=()=>{this.onNavigateAway(),this.plugin.revealNoteInStashpad(s)},u.createSpan({cls:"stashpad-pinned-folder",text:t.split("/").pop()||t}),u.oncontextmenu=C=>{C.preventDefault();let B=new W.Menu;B.addItem(E=>E.setTitle("Unpin from sidebar").setIcon("pin-off").onClick(()=>void this.plugin.unpinNote({folder:t,id:i}))),B.showAtMouseEvent(C)},h&&f){let C=e.createDiv({cls:"stashpad-pinned-children"});this.renderPinSubtree(C,t,i,1)}return u}renderPinSubtree(e,t,i,s){for(let n of this.childrenOf(t,i)){let o=this.app.metadataCache.getFileCache(n)?.frontmatter??{},a=typeof o.id=="string"?o.id:null;if(!a)continue;let l=typeof o.color=="string"?o.color:null,c=o.completed===!0,A=this.childrenOf(t,a),h=A.length>0,p=`${t}|${a}`,f=this.pinExpanded.has(p),u=e.createDiv({cls:"stashpad-pinned-subrow"});c&&u.addClass("is-completed"),u.style.paddingLeft=`${s*16}px`;let g=u.createSpan({cls:"stashpad-pinned-toggle"});h&&(Ht(g,A.length,f),g.onclick=C=>{C.stopPropagation(),this.pinExpanded.has(p)?this.pinExpanded.delete(p):this.pinExpanded.add(p),this.render()});let I=u.createSpan({cls:"stashpad-pinned-icon"});(0,W.setIcon)(I,"file-text"),l&&(I.style.color=l);let m=u.createSpan({cls:"stashpad-pinned-label",text:this.titleFromFile(n)});m.onclick=()=>{this.onNavigateAway(),this.plugin.revealNoteInStashpad(n)},h&&f&&this.renderPinSubtree(e,t,a,s+1)}}childrenOf(e,t){let i=[];for(let s of this.app.vault.getMarkdownFiles()){if((s.parent?.path?.replace(/\/+$/,"")??"")!==e)continue;let o=this.app.metadataCache.getFileCache(s)?.frontmatter;if(!o||typeof o.id!="string")continue;let a=o.parent;if(a===t||t===S&&(a==null||a===S)){if(o.id===S)continue;i.push(s)}}return i.sort((s,n)=>{let o=this.app.metadataCache.getFileCache(s)?.frontmatter?.created??"",a=this.app.metadataCache.getFileCache(n)?.frontmatter?.created??"";return String(o).localeCompare(String(a))}),i}onNavigateAway(){W.Platform.isMobile&&(this.plugin.suppressComposerAutofocusUntil=Date.now()+1500,this.app.workspace.leftSplit?.collapse?.())}titleFromFile(e){return e.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ").trim()||e.basename}openFolders(){let e=new Set,t=(this.plugin.settings.folder||"Stashpad").replace(/\/+$/,"");for(let i of this.app.workspace.getLeavesOfType(z)){let s=(i.view?.noteFolder??"").replace(/\/+$/,"");s||(s=(((i.getViewState?.()?.state??{}).folderOverride??"")||t).replace(/\/+$/,"")),s&&e.add(s)}return e}static clean(e){return e.replace(/\/+$/,"")}folderState(e){let t=d.clean(e),i=this.plugin.settings;return(i.folderPanelPinned??[]).includes(t)?"pinned":(i.folderPanelDownranked??[]).includes(t)?"downranked":(i.folderPanelHidden??[]).includes(t)?"hidden":"normal"}async setFolderState(e,t){let i=d.clean(e),s=this.plugin.settings;s.folderPanelPinned=(s.folderPanelPinned??[]).filter(n=>n!==i),s.folderPanelDownranked=(s.folderPanelDownranked??[]).filter(n=>n!==i),s.folderPanelHidden=(s.folderPanelHidden??[]).filter(n=>n!==i),s.folderPanelPinnedAt=s.folderPanelPinnedAt??{},t==="pinned"?(s.folderPanelPinned.push(i),s.folderPanelPinnedAt[i]=Date.now()):(delete s.folderPanelPinnedAt[i],t==="downranked"?s.folderPanelDownranked.push(i):t==="hidden"&&s.folderPanelHidden.push(i)),await this.plugin.saveSettings(),this.render()}folderHomeColor(e){return this.homeColorByFolder.get(d.clean(e))??null}rebuildHomeColors(){this.homeColorByFolder.clear();for(let e of this.app.vault.getMarkdownFiles()){let t=this.app.metadataCache.getFileCache(e)?.frontmatter;if(!t||t.id!==S||typeof t.color!="string"||!t.color.trim())continue;let i=(e.parent?.path??"").replace(/\/+$/,"");i&&this.homeColorByFolder.set(i,t.color)}}renderFolders(e){let t=this.plugin.discoverStashpadFolders();if(t.length===0){e.createDiv({cls:"stashpad-folderpanel-empty",text:"No Stashpad folders yet."});return}this.rebuildHomeColors(),this.ensureFolderPinOrder();let i=this.openFolders(),s=[],n=[],o=[],a=[];for(let A of t)switch(this.folderState(A)){case"pinned":s.push(A);break;case"downranked":o.push(A);break;case"hidden":a.push(A);break;default:n.push(A)}s.sort((A,h)=>this.folderPinnedAt(A)-this.folderPinnedAt(h)||d.clean(A).localeCompare(d.clean(h)));let l=A=>(A.split("/").pop()||A).toLowerCase();n.sort((A,h)=>l(A).localeCompare(l(h))),o.sort((A,h)=>l(A).localeCompare(l(h)));let c=[...s,...n,...o];if(c.length===0&&a.length===0){e.createDiv({cls:"stashpad-folderpanel-empty",text:"No Stashpad folders yet."});return}for(let A of c){let h=this.renderFolderRow(e,A,i);this.folderState(A)==="pinned"&&this.attachFolderSectionDrag(h,s.indexOf(A),s)}a.length>0&&this.renderHiddenSection(e,a)}attachFolderSectionDrag(e,t,i){let s="application/x-stashpad-folder";e.draggable=!0,e.addEventListener("dragstart",n=>{n.dataTransfer?.setData(s,String(t)),n.dataTransfer&&(n.dataTransfer.effectAllowed="move"),e.addClass("is-dragging")}),e.addEventListener("dragend",()=>e.removeClass("is-dragging")),e.addEventListener("dragover",n=>{if(!n.dataTransfer?.types?.includes(s))return;n.preventDefault(),n.dataTransfer.dropEffect="move";let o=e.getBoundingClientRect(),a=n.clientY-o.top<o.height/2;e.toggleClass("drop-before",a),e.toggleClass("drop-after",!a)}),e.addEventListener("dragleave",()=>{e.removeClass("drop-before"),e.removeClass("drop-after")}),e.addEventListener("drop",n=>{if(!n.dataTransfer?.types?.includes(s))return;n.preventDefault(),e.removeClass("drop-before"),e.removeClass("drop-after");let o=parseInt(n.dataTransfer.getData(s)??"",10);if(!Number.isFinite(o)||o===t)return;let a=e.getBoundingClientRect(),l=n.clientY-a.top<a.height/2;this.reorderPinnedFolders(i,o,l?t:t+1)})}async reorderPinnedFolders(e,t,i){if(t<0||t>=e.length)return;let s=e[t],n=e.filter((A,h)=>h!==t),o=Math.max(0,Math.min(i>t?i-1:i,n.length)),a=n[o-1],l=n[o],c;!a&&!l?c=Date.now():a?l?c=(this.folderPinnedAt(a)+this.folderPinnedAt(l))/2:c=this.folderPinnedAt(a)+1e3:c=this.folderPinnedAt(l)-1e3,this.plugin.settings.folderPanelPinnedAt=this.plugin.settings.folderPanelPinnedAt??{},this.plugin.settings.folderPanelPinnedAt[d.clean(s)]=c,await this.plugin.saveSettings(),this.render()}renderFolderRow(e,t,i){let s=this.folderState(t),n=i.has(d.clean(t)),o=e.createDiv({cls:"stashpad-folderpanel-row stashpad-folderpanel-folder-row"});n&&o.addClass("is-open"),s==="downranked"&&o.addClass("is-downranked"),s==="pinned"&&o.addClass("is-pinned");let a=o.createSpan({cls:"stashpad-folderpanel-dot"});if(a.setAttr("aria-label",n?"Open in a tab":"Not open"),n&&a.setAttr("title","Open in a tab"),s==="pinned"){let m=o.createSpan({cls:"stashpad-folderpanel-pinmark"});(0,W.setIcon)(m,"pin"),m.setAttr("aria-label","Pinned")}let l=this.folderHomePinnedNotes(t),c=d.clean(t),A=this.folderPinExpanded.has(c);if(l.length>0){let m=o.createSpan({cls:"stashpad-folderpanel-pinreveal"});Ht(m,l.length,A),m.setAttr("aria-label",A?"Hide pinned notes":`${l.length} pinned note${l.length===1?"":"s"}`),m.addEventListener("mousedown",C=>{C.stopPropagation(),C.preventDefault()}),m.onclick=C=>{C.stopPropagation(),this.folderPinExpanded.has(c)?this.folderPinExpanded.delete(c):this.folderPinExpanded.add(c),this.render()}}let h=this.plugin.isArchiveFolder(t),p=o.createSpan({cls:"stashpad-folderpanel-folder-icon"});(0,W.setIcon)(p,this.plugin.getFolderIcon(t)??(h?"archive":"folder")),h&&p.setAttr("aria-label","Archive folder \u2014 de-indexed from search");let f=this.folderHomeColor(t);f&&(p.style.color=f);let u=t.split("/").pop()||t;o.createSpan({cls:"stashpad-folderpanel-row-label",text:u});let I=o.createDiv({cls:"stashpad-folderpanel-actions"}).createEl("button",{cls:"stashpad-folderpanel-iconbtn"});if((0,W.setIcon)(I,"plus-square"),I.setAttr("aria-label","Open in new tab"),I.onmousedown=m=>{m.button===0&&(m.preventDefault(),m.stopPropagation(),this.onNavigateAway(),this.plugin.activateViewForFolder(t))},o.addEventListener("mousedown",m=>{m.button===0&&(m.target?.closest?.(".stashpad-folderpanel-actions")||(this.onNavigateAway(),this.jumpToFolder(t)))}),o.oncontextmenu=m=>{m.preventDefault(),this.openFolderMenu(m,t)},l.length>0&&A){let m=e.createDiv({cls:"stashpad-folderpanel-pinlist"});for(let C of l){let B=m.createDiv({cls:"stashpad-folderpanel-pinrow"}),E=this.app.metadataCache.getFileCache(C)?.frontmatter??{},y=B.createSpan({cls:"stashpad-folderpanel-pinrow-icon"});(0,W.setIcon)(y,"arrow-up-to-line"),typeof E.color=="string"&&(y.style.color=E.color),B.createSpan({cls:"stashpad-folderpanel-pinrow-label",text:this.titleFromFile(C)}),B.onclick=()=>{this.onNavigateAway(),this.plugin.revealNoteInStashpad(C)}}}return o}folderHomePinnedNotes(e){return this.childrenOf(e,S).filter(t=>this.app.metadataCache.getFileCache(t)?.frontmatter?.listPinned===!0)}renderHiddenSection(e,t){let i=e.createDiv({cls:"stashpad-folderpanel-hidden"}),s=i.createDiv({cls:"stashpad-folderpanel-hidden-header"}),n=s.createSpan({cls:"stashpad-folderpanel-hidden-caret"});(0,W.setIcon)(n,"chevron-right"),s.createSpan({cls:"stashpad-folderpanel-hidden-title",text:`Hidden (${t.length})`});let o=i.createDiv({cls:"stashpad-folderpanel-hidden-body"});o.setCssStyles({display:"none"}),s.onclick=()=>{let a=o.style.display!=="none";o.setCssStyles({display:a?"none":""}),(0,W.setIcon)(n,a?"chevron-right":"chevron-down")};for(let a of t){let l=o.createDiv({cls:"stashpad-folderpanel-row stashpad-folderpanel-hidden-row"}),c=a.split("/").pop()||a;l.createSpan({cls:"stashpad-folderpanel-row-label",text:c});let A=l.createEl("button",{cls:"stashpad-folderpanel-iconbtn"});(0,W.setIcon)(A,"eye"),A.setAttr("aria-label","Unhide"),A.onclick=h=>{h.stopPropagation(),this.setFolderState(a,"normal")}}}jumpToFolder(e){this.plugin.openFolderInStashpad(e)}revealFolder(e){let t=this.app.vault.getAbstractFileByPath(e.replace(/\/+$/,""));if(!(t instanceof W.TFolder)){new W.Notice("Couldn't find that folder.");return}let i=this.app.workspace.getLeavesOfType("file-explorer")[0];if(!i){new W.Notice("File explorer isn't available.");return}this.app.workspace.revealLeaf(i),i.view?.revealInFolder?.(t)}openFolderMenu(e,t){let i=new W.Menu;i.addItem(n=>n.setTitle("Open in new tab").setIcon("plus-square").onClick(()=>void this.plugin.activateViewForFolder(t))),i.addItem(n=>n.setTitle("Reveal in file explorer").setIcon("folder-search").onClick(()=>this.revealFolder(t))),i.addSeparator();let s=this.folderState(t);i.addItem(n=>n.setTitle(s==="pinned"?"Unpin":"Pin to top").setIcon("pin").onClick(()=>void this.setFolderState(t,s==="pinned"?"normal":"pinned"))),i.addItem(n=>n.setTitle(s==="downranked"?"Remove downrank":"Downrank").setIcon("arrow-down").onClick(()=>void this.setFolderState(t,s==="downranked"?"normal":"downranked"))),i.addItem(n=>n.setTitle("Hide from list").setIcon("eye-off").onClick(()=>void this.setFolderState(t,"hidden"))),i.addSeparator(),i.addItem(n=>n.setTitle("Rename\u2026").setIcon("pencil").onClick(()=>this.renameFolder(t))),this.plugin.encryption?.isConfigured?.()&&(i.addSeparator(),i.addItem(n=>n.setTitle("Encrypt (lock) all notes in folder").setIcon("lock").onClick(()=>void this.plugin.lockFolder(t))),this.app.vault.getFiles().some(n=>n.extension==="stashenc"&&(n.parent?.path?.replace(/\/+$/,"")??"")===t.replace(/\/+$/,""))&&i.addItem(n=>n.setTitle("Decrypt (unlock) all notes in folder").setIcon("unlock").onClick(()=>void this.plugin.unlockFolder(t))),i.addItem(n=>n.setTitle("Open encrypted trash").setIcon("rotate-ccw").onClick(()=>this.plugin.openEncryptedTrash()))),i.addSeparator(),i.addItem(n=>{n.setTitle("Delete folder\u2026").setIcon("trash").onClick(()=>this.deleteFolder(t)),n.setWarning?.(!0)}),i.showAtMouseEvent(e)}renameFolder(e){let t=e.replace(/\/+$/,""),i=this.app.vault.getAbstractFileByPath(t);if(!(i instanceof W.TFolder)){new W.Notice("Couldn't find that folder.");return}let s=i.name;new Da(this.app,s,async n=>{let o=n.trim().replace(/[\\/:]+/g,"").trim();if(!o||o===s)return;let l=`${i.parent?.path&&i.parent.path!=="/"?`${i.parent.path}/`:""}${o}`;if(this.app.vault.getAbstractFileByPath(l)){new W.Notice(`"${o}" already exists.`);return}if(!(this.app.vault.getAbstractFileByPath(t)instanceof W.TFolder)){new W.Notice("That folder no longer exists.");return}try{await this.app.fileManager.renameFile(i,l),await this.plugin.remapFolderPathInSettings(t,l),new W.Notice(`Renamed to "${o}".`)}catch(c){console.warn("[Stashpad] folder rename failed",c),new W.Notice("Rename failed (see console).")}}).open()}deleteFolder(e){let t=e.replace(/\/+$/,""),i=this.app.vault.getAbstractFileByPath(t);if(!(i instanceof W.TFolder)){new W.Notice("Couldn't find that folder.");return}let s=this.app.vault.getMarkdownFiles().filter(o=>(o.parent?.path?.replace(/\/+$/,"")??"")===t||o.path.startsWith(t+"/")).length,n=i.name;new j(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=>{o&&await this.plugin.deleteStashpadFolderWithUndo(i)}).open()}async onClose(){this.dividerCleanup?.(),this.contentEl.empty()}},Da=class extends W.Modal{constructor(e,t,i){super(e);this.current=t;this.onSubmit=i;this.delivered=!1}onOpen(){this.modalEl.addClass("stashpad-compact-modal"),this.contentEl.empty(),this.titleEl.setText("Rename folder");let e=this.contentEl.createEl("input",{type:"text"});e.addClass("stashpad-folderpanel-rename-input"),e.value=this.current;let t=this.contentEl.createDiv({cls:"stashpad-folderpanel-rename-footer"});t.createEl("button",{text:"Cancel"}).onclick=()=>this.close();let i=t.createEl("button",{cls:"mod-cta",text:"Rename"}),s=()=>{this.delivered=!0;let n=e.value;this.close(),this.onSubmit(n)};i.onclick=s,this.scope.register([],"Enter",n=>{n.preventDefault(),e.value.trim()&&s()}),requestAnimationFrame(()=>{e.focus(),e.select()})}onClose(){this.contentEl.empty()}};async function to(d){let r=d.workspace.getLeavesOfType(bt);if(r.length>0){d.workspace.revealLeaf(r[0]);return}let e=d.workspace.getLeftLeaf(!1);if(!e){new W.Notice("Stashpad: couldn't open the folder panel.");return}await e.setViewState({type:bt,active:!0}),d.workspace.revealLeaf(e)}zo();ve();Qi();gi();An();ce();var xa="OKF Template.md",tA=`--- +`),"Swap",async l=>{if(!l)return;let c=e.parent??S;await this.swapParentChild(e,i,c)}).open()}async swapParentChild(e,t,i){if(!e.file||!t.file)return;if(t.parent!==e.id){new F.Notice("Swap aborted: parent/child relationship changed.");return}let s=this.noteFolder,n=e.parent,o=this.tree.getChildren(e.id).filter(f=>f.id!==t.id).filter(f=>!!f.file),a=o.map(f=>({id:f.id,path:f.file.path,was:f.parent})),l=this.order.getOrder(s,i).slice(),c=this.order.getOrder(s,t.id).slice(),d=this.order.getOrder(s,e.id).slice();await this.app.fileManager.processFrontMatter(t.file,f=>{f.parent=i}),this.fmSync.scheduleParentChange(t.id,e.id,i),await this.app.fileManager.processFrontMatter(e.file,f=>{f.parent=t.id}),this.fmSync.scheduleParentChange(e.id,n,t.id);for(let f of o)await this.app.fileManager.processFrontMatter(f.file,u=>{u.parent=t.id}),this.fmSync.scheduleParentChange(f.id,e.id,t.id);if(l.length>0){let f=l.includes(e.id)?l.map(u=>u===e.id?t.id:u):[...l.filter(u=>u!==t.id),t.id];this.order.setOrder(s,i,f)}let h=o.map(f=>f.id),p=[e.id,...c.filter(f=>f!==e.id&&!h.includes(f)),...h];this.order.setOrder(s,t.id,p),this.order.setOrder(s,e.id,[]),await this.order.save(s),await this.log.append({type:"parent_change",id:t.id,payload:{from:e.id,to:i,reason:"swap"}}),await this.log.append({type:"parent_change",id:e.id,payload:{from:n,to:t.id,reason:"swap"}});for(let f of a)await this.log.append({type:"parent_change",id:f.id,payload:{from:f.was,to:t.id,reason:"swap"}});this.tree.rebuild(s),this.pendingFocusIds=[t.id],this.render({kind:"follow-cursor"}),this.plugin.notifications.show({message:`Swapped "${this.titleForNode(t)}" \u2194 "${this.titleForNode(e)}".`,kind:"success",category:"move",affectedIds:[t.id,e.id,...h],folder:s}),this.plugin.getUndoStack(s).push({label:`Swap "${this.titleForNode(t)}" \u2194 parent`,undo:async()=>{let f=this.tree.get(e.id),u=this.tree.get(t.id);f?.file&&await this.app.fileManager.processFrontMatter(f.file,g=>{n==null||n===S?(delete g.parent,g.parent=S):g.parent=n}),u?.file&&await this.app.fileManager.processFrontMatter(u.file,g=>{g.parent=e.id});for(let g of a){let I=this.app.vault.getAbstractFileByPath(g.path);I&&await this.app.fileManager.processFrontMatter(I,m=>{g.was==null?m.parent=S:m.parent=g.was})}this.order.setOrder(s,i,l),this.order.setOrder(s,t.id,c),this.order.setOrder(s,e.id,d),await this.order.save(s),this.tree.rebuild(s),this.pendingFocusIds=[e.id],this.render({kind:"follow-cursor"})},redo:async()=>{await this.swapParentChild(e,t,i)}})}async changeParent(e,t,i={record:!0}){if(!e.file)return!1;let s=e.file,n=e.parent,o=l=>l??S;if(o(n)===o(t)){if(!i.quiet){let l=this.titleForNode(e),c=t===S?"Home":`"${this.titleForNode(this.tree.get(t)??e)}"`;this.plugin.notifications.show({message:`"${l}" is already under ${c}.`,kind:"info",category:"move",affectedIds:[e.id],folder:this.noteFolder})}return!1}if(t===e.id)return i.quiet||this.plugin.notifications.show({message:`Can't move "${this.titleForNode(e)}" into itself.`,kind:"warning",category:"move",affectedIds:[e.id],folder:this.noteFolder}),!1;if(t!==S&&this.isDescendant(t,e.id))return i.quiet||this.offerSwapForDescendantMove(e,t),!1;let a=this.authorship.collectAuthorIds([e]);if(await this.app.fileManager.processFrontMatter(s,l=>{l.parent=t}),this.fmSync.scheduleParentChange(e.id,n,t),await this.log.append({type:"parent_change",id:e.id,payload:{from:n,to:t}}),this.pendingFocusIds=[e.id],this.focusId!==t&&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 l=this.tree.get(t),c=l?this.titleForNode(l):"(root)";this.plugin.notifications.show({message:`Reparented "${this.titleForNode(e)}" \u2192 "${c}"`,kind:"success",category:"move",affectedIds:[e.id],affectedAuthorIds:a,folder:this.noteFolder,actions:t===S?[]:[{label:"Jump to parent",onClick:()=>this.navigateTo(t)}]})}if(i.record!==!1){let l=this.noteFolder,c=s.path,d=e.id;this.plugin.getUndoStack(l).push({label:"Move note",undo:async()=>{let h=this.fileForNote(d,c);if(h){await this.app.fileManager.processFrontMatter(h,p=>{p.parent=n}),this.pendingFocusIds=[d],this.focusId!==n&&this.focusId!==t?(this.selection.clear(),this.cursorIdx=-1):this.focusId===t&&(this.selection.clear(),this.cursorIdx=-1,this.pendingFocusIds=null),this.tree.rebuild(l),this.render({kind:"follow-cursor"});{let p=this.selectionGuardKey,f=()=>{if(this.selectionGuardKey!==p||this.selection.has(d))return;let u=this.currentChildren.findIndex(g=>g.id===d);u<0||(this.selection.add(d),this.cursorIdx=u,this.render({kind:"follow-cursor"}))};setTimeout(f,120),setTimeout(f,400)}}},redo:async()=>{let h=this.fileForNote(d,c);if(h){await this.app.fileManager.processFrontMatter(h,p=>{p.parent=t}),this.pendingFocusIds=[d],this.focusId!==t&&this.focusId!==n?(this.selection.clear(),this.cursorIdx=-1):this.focusId===n&&(this.selection.clear(),this.cursorIdx=-1,this.pendingFocusIds=null),this.tree.rebuild(l),this.render({kind:"follow-cursor"});{let p=this.selectionGuardKey,f=()=>{if(this.selectionGuardKey!==p||this.selection.has(d))return;let u=this.currentChildren.findIndex(g=>g.id===d);u<0||(this.selection.add(d),this.cursorIdx=u,this.render({kind:"follow-cursor"}))};setTimeout(f,120),setTimeout(f,400)}}}})}return!0}notifyBatchMove(e,t,i){if(!e.length)return;let s=this.tree.get(t),n=t===S?"Home":`"${s?this.titleForNode(s):"the destination"}"`,o=l=>i.get(l.id)??0,a;if(e.length===1){let l=this.titleForNode(e[0]),c=o(e[0]);a=c>0?`Moved "${l}" and its ${c} ${c===1?"child":"children"} \u2192 ${n}`:`Moved "${l}" \u2192 ${n}`}else{let l=e.reduce((c,d)=>c+o(d),0);a=l>0?`Moved ${e.length} notes (${l} nested) \u2192 ${n}`:`Moved ${e.length} notes \u2192 ${n}`}this.plugin.notifications.show({message:a,kind:"success",category:"move",duration:t===S?void 0:0,affectedIds:e.map(l=>l.id),affectedAuthorIds:this.authorship.collectAuthorIds(e),folder:this.noteFolder,actions:t===S?[]:[{label:"Jump to destination",onClick:()=>this.navigateTo(t)}]})}};Ms.AIMED_TAP_WINDOW_MS=600;var Ps=Ms,jn=class extends F.SuggestModal{constructor(e,t,i){super(e);this.entries=t;this.onPick=i;this.setPlaceholder("Restore which deleted note?")}getSuggestions(e){let t=e.toLowerCase();return this.entries.filter(i=>`${i.label} ${i.folder}`.toLowerCase().includes(t))}renderSuggestion(e,t){t.createDiv({text:e.label}),t.createEl("small",{text:`from ${e.folder}`,cls:"stashpad-suggest-path"})}onChooseSuggestion(e){this.onPick(e.blob)}};var Ce=require("obsidian");ce();ve();var _n=Ce.moment,eo=class extends Ce.ItemView{constructor(e,t){super(e);this.plugin=t;this.renderPending=!1;this.renderGen=0;this.selected=new Set;this.order=[];this.anchorBlob=null;this.trashMode="byfolder"}getViewType(){return ci}getDisplayText(){return"Trash"}getIcon(){return"trash-2"}async onOpen(){this.containerEl.addClass("stashpad-trash-view"),this.registerEvent(this.app.vault.on("create",e=>{e.path.startsWith("_deleted/")&&this.scheduleRender()})),this.registerEvent(this.app.vault.on("delete",e=>{e.path.startsWith("_deleted/")&&this.scheduleRender()})),this.registerDomEvent(document,"keydown",e=>{if(this.app.workspace.activeLeaf!==this.leaf)return;let t=e.target;if(!(t&&(t.tagName==="INPUT"||t.tagName==="TEXTAREA"||t.isContentEditable))&&(e.metaKey||e.ctrlKey)&&!e.altKey&&(e.key==="a"||e.key==="A")){if(this.order.length===0)return;e.preventDefault(),this.selectAll()}}),await this.render()}scheduleRender(){this.renderPending||(this.renderPending=!0,window.setTimeout(()=>{this.renderPending=!1,this.render()},150))}async render(){let e=++this.renderGen,t=this.contentEl;t.empty(),t.addClass("stashpad-trash-view-body"),this.order=[];let i=t.createDiv({cls:"stashpad-trash-view-header"});i.createEl("h3",{text:"Trash"});let s=i.createEl("button",{cls:"stashpad-trash-iconbtn"});(0,Ce.setIcon)(s,"refresh-cw"),s.setAttr("aria-label","Refresh"),s.onclick=()=>void this.render();let n=this.plugin.encryption?.isConfigured?.()?await this.plugin.listDeletedTrash():[];if(e!==this.renderGen)return;let o=await this.plugin.listPlaintextTrash();if(e!==this.renderGen)return;let a=[...n,...o],l=await this.plugin.listRawTrashStashpadNotes();if(e!==this.renderGen)return;if(a.length===0&&l.length===0){t.createDiv({cls:"stashpad-trash-empty",text:"Trash is empty. Securely-deleted notes land in the encrypted trash; plain deletes go to Obsidian's trash \u2014 both show here."});return}if(Pn(t,this.trashMode,{total:a.length+l.length,enc:a.length,dec:l.length},h=>{this.trashMode=h,this.clearSelection(),this.render()}),this.trashMode==="mixed"){this.renderMixed(t,a,l);return}let c=this.trashMode!=="unencrypted"&&a.length>0,d=this.trashMode!=="encrypted"&&l.length>0;if(!c&&!d){t.createDiv({cls:"stashpad-trash-empty",text:"Nothing in this view."});return}if(c){let h=i.createEl("button",{cls:"stashpad-trash-restore",text:"Restore all"});(0,Ce.setIcon)(h.createSpan({cls:"stashpad-btn-icon"}),"rotate-ccw"),h.onclick=async()=>{h.disabled=!0,await this.plugin.restoreAllTrash(),this.clearSelection(),await this.render()};let p=new Set(a.map(f=>f.blob));for(let f of[...this.selected])p.has(f)||this.selected.delete(f);if(this.selected.size>0){let f=t.createDiv({cls:"stashpad-trash-selbar"});f.createSpan({cls:"stashpad-trash-selcount",text:`${this.selected.size} selected`});let u=f.createEl("button",{cls:"stashpad-trash-restore",text:"Restore selected"});u.onclick=async()=>{u.disabled=!0;let m=0;for(let C of[...this.selected])await this.plugin.restoreDeletedAt(C,{silent:!0})||m++;m>0&&new Ce.Notice(`${m} item${m===1?"":"s"} couldn't be restored (locked key?) \u2014 still in trash.`),this.clearSelection(),await this.render()};let g=f.createEl("button",{cls:"stashpad-trash-delete mod-warning",text:"Delete selected"});g.onclick=()=>this.confirmPurge([...this.selected]);let I=f.createEl("button",{cls:"stashpad-trash-iconbtn",text:"Clear"});I.onclick=()=>{this.clearSelection(),this.render()}}}if(this.order=[],c)if(this.trashMode==="byfolder"){let h=new Map;for(let f of a){let u=f.meta?.title?f.meta.originalFolder||"(unknown folder)":" hidden";(h.get(u)??h.set(u,[]).get(u)).push(f)}let p=[...h.keys()].sort((f,u)=>f===" hidden"?1:u===" hidden"?-1:f.localeCompare(u));for(let f of p){let u=f===" hidden",g=t.createDiv({cls:"stashpad-trash-group"}),I=g.createDiv({cls:"stashpad-trash-group-head"});(0,Ce.setIcon)(I.createSpan({cls:"stashpad-trash-group-icon"}),u?"lock":"folder"),I.createSpan({text:u?"Hidden (title obscured)":f.split("/").pop()||f}),I.createSpan({cls:"stashpad-trash-group-count",text:String(h.get(f).length)});for(let m of h.get(f))this.encRow(g,m,u)}}else{let h=t.createDiv({cls:"stashpad-trash-group"}),p=h.createDiv({cls:"stashpad-trash-group-head"});(0,Ce.setIcon)(p.createSpan({cls:"stashpad-trash-group-icon"}),"trash-2"),p.createSpan({text:"Stashpad trash"}),p.createSpan({cls:"stashpad-trash-group-count",text:String(a.length)});for(let f of a)this.encRow(h,f,!f.meta?.title)}d&&this.renderRawSection(t,l)}encRow(e,t,i){let s=this.order.length;this.order.push(t.blob);let n=e.createDiv({cls:"stashpad-trash-row"});this.selected.has(t.blob)&&n.addClass("is-selected"),n.addEventListener("click",h=>{h.target.closest("button")||this.onRowClick(s,t.blob,h)});let o=n.createDiv({cls:"stashpad-trash-row-main"});o.createSpan({cls:"stashpad-trash-title",text:i?"Locked note":t.meta?.title||"Locked note"});let a=t.meta?.deletedAt?`deleted ${_n(t.meta.deletedAt).fromNow()}`:"deleted",l=t.meta&&t.meta.count>1?` \xB7 ${t.meta.count} ${t.meta.kind==="rawtrash"?"files":"notes"}`:"";o.createSpan({cls:"stashpad-trash-sub",text:a+l});let c=n.createEl("button",{cls:"stashpad-trash-restore",text:"Restore"});(0,Ce.setIcon)(c.createSpan({cls:"stashpad-btn-icon"}),"rotate-ccw"),c.onclick=async()=>{c.disabled=!0,await this.plugin.restoreDeletedAt(t.blob)?await this.render():c.disabled=!1};let d=n.createEl("button",{cls:"stashpad-trash-delete",attr:{"aria-label":"Delete permanently"}});(0,Ce.setIcon)(d,"trash-2"),d.onclick=()=>this.confirmPurge([t.blob])}renderMixed(e,t,i){let s=[];for(let o of t)s.push({ts:o.meta?.deletedAt&&Date.parse(String(o.meta.deletedAt))||0,kind:"enc",enc:o});for(let o of i)s.push({ts:o.mtime||0,kind:"raw",raw:o});s.sort((o,a)=>a.ts-o.ts);let n=e.createDiv({cls:"stashpad-trash-group"});for(let o of s){let a=n.createDiv({cls:"stashpad-trash-row"}),l=a.createDiv({cls:"stashpad-trash-row-main"}),c=o.kind==="enc"&&o.enc?.meta?.encrypted===!1,d=l.createSpan({cls:`stashpad-trash-kind is-${o.kind}`});if((0,Ce.setIcon)(d,o.kind==="enc"&&!c?"lock":"trash"),o.kind==="enc"&&o.enc){let h=o.enc,p=!h.meta?.title&&!c;l.createSpan({cls:"stashpad-trash-title",text:h.meta?.title||(c?"Deleted note":"Locked note")});let f=h.meta?.deletedAt?`deleted ${_n(h.meta.deletedAt).fromNow()}`:"deleted";l.createSpan({cls:"stashpad-trash-sub",text:`${f} \xB7 ${c?"unencrypted":"encrypted"}`});let u=a.createEl("button",{cls:"stashpad-trash-restore",text:"Restore"});(0,Ce.setIcon)(u.createSpan({cls:"stashpad-btn-icon"}),"rotate-ccw"),u.onclick=async()=>{u.disabled=!0,await this.plugin.restoreDeletedAt(h.blob)?await this.render():u.disabled=!1};let g=a.createEl("button",{cls:"stashpad-trash-delete",attr:{"aria-label":"Delete permanently"}});(0,Ce.setIcon)(g,"trash-2"),g.onclick=()=>this.confirmPurge([h.blob])}else if(o.raw){let h=o.raw;l.createSpan({cls:"stashpad-trash-title",text:h.title});let p=h.mtime?`deleted ${_n(h.mtime).fromNow()}`:"in Obsidian trash";l.createSpan({cls:"stashpad-trash-sub",text:`${p} \xB7 unencrypted`});let f=a.createEl("button",{cls:"stashpad-trash-restore",text:"Restore"});(0,Ce.setIcon)(f.createSpan({cls:"stashpad-btn-icon"}),"rotate-ccw"),f.onclick=async()=>{f.disabled=!0,await this.plugin.restoreRawTrashNote(h.path)?await this.render():f.disabled=!1}}}}renderRawSection(e,t){if(t.length===0)return;let i=e.createDiv({cls:"stashpad-trash-group"}),s=i.createDiv({cls:"stashpad-trash-group-head"});(0,Ce.setIcon)(s.createSpan({cls:"stashpad-trash-group-icon"}),"trash"),s.createSpan({text:"Obsidian trash (unencrypted)"}),s.createSpan({cls:"stashpad-trash-group-count",text:String(t.length)});for(let n of t){let o=i.createDiv({cls:"stashpad-trash-row"}),a=o.createDiv({cls:"stashpad-trash-row-main"});a.createSpan({cls:"stashpad-trash-title",text:n.title});let l=n.mtime?`deleted ${_n(n.mtime).fromNow()}`:"in Obsidian trash";a.createSpan({cls:"stashpad-trash-sub",text:l});let c=o.createEl("button",{cls:"stashpad-trash-restore",text:"Restore"});(0,Ce.setIcon)(c.createSpan({cls:"stashpad-btn-icon"}),"rotate-ccw"),c.onclick=async()=>{c.disabled=!0,await this.plugin.restoreRawTrashNote(n.path)?await this.render():c.disabled=!1}}}clearSelection(){this.selected.clear(),this.anchorBlob=null}selectAll(){if(this.order.length!==0){for(let e of this.order)this.selected.add(e);this.anchorBlob=this.order[this.order.length-1]??null,this.render()}}onRowClick(e,t,i){let s=this.anchorBlob!==null?this.order.indexOf(this.anchorBlob):-1;if(i.shiftKey&&s>=0){let[n,o]=s<e?[s,e]:[e,s];this.selected.clear();for(let a=n;a<=o;a++)this.selected.add(this.order[a])}else i.metaKey||i.ctrlKey?(this.selected.has(t)?this.selected.delete(t):this.selected.add(t),this.anchorBlob=t):(this.selected.size===1&&this.selected.has(t)?this.selected.clear():(this.selected.clear(),this.selected.add(t)),this.anchorBlob=t);this.render()}confirmPurge(e){if(e.length===0)return;let t=e.length;new j(this.app,t===1?"Delete permanently?":`Delete ${t} items permanently?`,`${t===1?"This encrypted item":`These ${t} encrypted items`} will be PERMANENTLY deleted and CANNOT be restored \u2014 there is no decrypted copy. Continue?`,"Delete forever",async i=>{if(i){for(let s of e)await this.plugin.purgeDeletedAt(s);this.clearSelection(),await this.render()}},"Cancel",!0).open()}async onClose(){this.contentEl.empty()}};async function _l(A){let{workspace:r}=A.app,e=r.getLeavesOfType(ci);if(e.length>0){r.revealLeaf(e[0]);return}let t=r.getMostRecentLeaf(),i=r.getLeaf("tab");await i.setViewState({type:ci,active:!0}),r.revealLeaf(i),yt(r,i,t,s=>A.registerEvent(s))}var ni=require("obsidian"),Hs=class Hs{constructor(r){this.plugin=r;this.tick=null;this.lastTouch=new Map;this.counting=new Set;this.countdownTimers=new Set}key(r,e){return`${r} ${e}`}delayMin(r){let e=r.peekMin;if(e!=null)return e;let i=(this.plugin.settings.folderEncPrefs??{})[r.folder.replace(/\/+$/,"")]?.reEncryptAfterMin;return i??this.plugin.settings.reEncryptAfterMin??0}anyArmed(){if((this.plugin.settings.reEncryptAfterMin??0)>0)return!0;for(let r of Object.values(this.plugin.settings.folderEncPrefs??{}))if((r?.reEncryptAfterMin??0)>0)return!0;return this.plugin.reEncryptWatching().some(r=>(r.peekMin??0)>0)}start(){let r=e=>{e&&this.lastTouch.set(e.replace(/\/+$/,""),Date.now())};this.plugin.registerEvent(this.plugin.app.vault.on("modify",e=>{e instanceof ni.TFile&&r(e.parent?.path??"")})),this.plugin.registerEvent(this.plugin.app.workspace.on("file-open",e=>{e&&r(e.parent?.path??"")})),this.tick=window.setInterval(()=>void this.poll(),3e4),this.plugin.registerInterval(this.tick)}folderHasOpenEditor(r){let e=r.replace(/\/+$/,""),t=!1;return this.plugin.app.workspace.iterateAllLeaves(i=>{let s=i.view;s instanceof ni.MarkdownView&&s.file&&(s.file.parent?.path?.replace(/\/+$/,"")??"")===e&&(t=!0)}),t}keyReady(r){let e=this.plugin.encryption;return e?.isConfigured?.()?e.hasFolderKey(r)&&e.isFolderUnlocked(r):!1}async poll(){if(!this.anyArmed())return;let r=Date.now();for(let e of this.plugin.reEncryptWatching()){let t=this.delayMin(e);if(t<=0)continue;let i=e.folder.replace(/\/+$/,""),s=this.key(i,e.rootId);if(this.counting.has(s))continue;let n=Math.max(Date.parse(e.unlockedAt)||0,this.lastTouch.get(i)??0);if(!(r<n+t*6e4)&&this.keyReady(i)){if(this.folderHasOpenEditor(i)){rA(this.lastTouch,i,r);continue}this.countdownThenLock(e,s)}}}countdownThenLock(r,e){this.counting.add(e);let t=r.folder.replace(/\/+$/,""),i=r.title||"a note",s=Date.now(),n=Hs.COUNTDOWN_SECS,o=!1,a=new ni.Notice("",0),l=()=>{window.clearInterval(h),this.countdownTimers.delete(h),a.hide(),this.counting.delete(e)},c=()=>{this.lastTouch.set(t,Date.now()),l()},d=()=>{a.noticeEl.empty(),a.noticeEl.createSpan({text:`\u{1F512} Re-encrypting \u201C${i}\u201D in ${n}s\u2026 `}),a.noticeEl.createEl("button",{text:"Keep unlocked"}).onclick=()=>{o=!0,c()}};d();let h=window.setInterval(async()=>{if(o)return;if((this.lastTouch.get(t)??0)>s){c();return}if(n-=1,n>0){d();return}if(l(),!this.plugin.reEncryptWatching().some(f=>f.folder===r.folder&&f.rootId===r.rootId))return;if(this.folderHasOpenEditor(t)){this.lastTouch.set(t,Date.now());return}if(!this.keyReady(t)){this.lastTouch.set(t,Date.now());return}await this.plugin.lockNoteSubtree(r.folder,r.rootId,null,{silent:!0})&&new ni.Notice(`Re-encrypted \u201C${i}\u201D.`)},1e3);this.countdownTimers.add(h),this.plugin.registerInterval(h)}dispose(){for(let r of this.countdownTimers)window.clearInterval(r);this.countdownTimers.clear(),this.counting.clear()}};Hs.COUNTDOWN_SECS=10,Hs.RECENT_EDIT_MS=2e4;var to=Hs;function rA(A,r,e){A.set(r.replace(/\/+$/,""),e)}ce();var W=require("obsidian");ce();ve();function oi(A){return A.kind==="folder"?`f:${A.folder}`:`n:${A.folder}:${A.id}`}var io=class A extends W.ItemView{constructor(e,t){super(e);this.plugin=t;this.renderTimer=null;this.dividerCleanup=null;this.pinExpanded=new Set;this.folderPinExpanded=new Set;this.homeColorByFolder=new Map}getViewType(){return bt}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()))}refresh(){this.scheduleRender()}scheduleRender(){this.renderTimer==null&&(this.renderTimer=window.setTimeout(()=>{this.renderTimer=null,this.containerEl.isConnected&&this.render()},100))}render(){let e=this.contentEl;e.empty(),e.addClass("stashpad-folderpanel-root");let t=this.clampFrac(this.plugin.settings.folderPanelPinnedFraction??.5),i=e.createDiv({cls:"stashpad-folderpanel-section stashpad-folderpanel-pinned"});i.style.flex=`0 0 ${(t*100).toFixed(2)}%`;let s=i.createDiv({cls:"stashpad-folderpanel-heading stashpad-folderpanel-heading-row"});s.createSpan({cls:"stashpad-folderpanel-heading-title",text:"Pinned"});let n=s.createEl("button",{cls:"stashpad-folderpanel-iconbtn"});(0,W.setIcon)(n,"list"),n.setAttr("aria-label","Pinned view options"),n.onclick=h=>{h.stopPropagation(),this.openPinnedOptionsMenu(h)},this.renderPinned(i.createDiv({cls:"stashpad-folderpanel-list stashpad-folderpanel-pins"}));let o=e.createDiv({cls:"stashpad-folderpanel-divider"});o.createDiv({cls:"stashpad-folderpanel-divider-grip"}),this.attachDividerDrag(e,i,o);let a=e.createDiv({cls:"stashpad-folderpanel-section stashpad-folderpanel-folders"});a.setCssStyles({flex:"1 1 0"});let l=a.createDiv({cls:"stashpad-folderpanel-heading stashpad-folderpanel-heading-row"}),c=l.createSpan({cls:"stashpad-folderpanel-heading-title stashpad-folderpanel-heading-switch",text:"Folders"});c.setAttr("aria-label","Open folder switcher"),c.onmousedown=h=>{h.button===0&&(h.preventDefault(),this.plugin.openFolderPicker())};let d=l.createEl("button",{cls:"stashpad-folderpanel-iconbtn stashpad-folderpanel-heading-newfolder"});if((0,W.setIcon)(d,"folder-plus"),d.setAttr("aria-label","New Stashpad folder (folder switcher)"),d.onmousedown=h=>{h.button===0&&(h.preventDefault(),h.stopPropagation(),this.plugin.openFolderPicker())},this.plugin.encryption?.isConfigured?.()){let h=l.createEl("button",{cls:"stashpad-folderpanel-iconbtn stashpad-folderpanel-heading-trash"});(0,W.setIcon)(h,"trash-2"),h.setAttr("aria-label","Open encrypted trash"),h.onmousedown=p=>{p.button===0&&(p.preventDefault(),p.stopPropagation(),this.plugin.openEncryptedTrash())}}this.renderFolders(a.createDiv({cls:"stashpad-folderpanel-list"}))}clampFrac(e){return Number.isFinite(e)?Math.max(.15,Math.min(.85,e)):.5}attachDividerDrag(e,t,i){let s=null,n=l=>{let c=e.getBoundingClientRect();if(c.height<=0)return;let d=this.clampFrac((l.clientY-c.top)/c.height);s=d,t.style.flex=`0 0 ${(d*100).toFixed(2)}%`},o=()=>{document.removeEventListener("pointermove",n),document.removeEventListener("pointerup",a),document.removeEventListener("pointercancel",a),document.body.removeClass("stashpad-folderpanel-resizing"),this.dividerCleanup=null},a=l=>{try{i.releasePointerCapture(l.pointerId)}catch{}l.type==="pointerup"&&s!=null&&(this.plugin.settings.folderPanelPinnedFraction=s,this.plugin.saveSettings()),o()};this.registerDomEvent(i,"pointerdown",l=>{l.preventDefault(),document.body.addClass("stashpad-folderpanel-resizing");try{i.setPointerCapture(l.pointerId)}catch{}document.addEventListener("pointermove",n),document.addEventListener("pointerup",a),document.addEventListener("pointercancel",a),this.dividerCleanup=o})}openPinnedOptionsMenu(e){let t=this.plugin.settings.folderPanelPinnedGrouping??"pin-order",i=new W.Menu;i.addItem(s=>s.setTitle("Sort by pin order").setChecked(t==="pin-order").onClick(()=>void this.setPinnedGrouping("pin-order"))),i.addItem(s=>s.setTitle("Group by folder").setChecked(t==="folder").onClick(()=>void this.setPinnedGrouping("folder"))),i.showAtMouseEvent(e)}async setPinnedGrouping(e){(this.plugin.settings.folderPanelPinnedGrouping??"pin-order")!==e&&(this.plugin.settings.folderPanelPinnedGrouping=e,await this.plugin.saveSettings(),this.render())}unifiedPinnedItems(){let e=[];for(let t of this.plugin.discoverStashpadFolders())this.folderState(t)==="pinned"&&e.push({kind:"folder",folder:A.clean(t),at:this.folderPinnedAt(t)});for(let t of this.plugin.listPinnedNotes())e.push({kind:"note",folder:t.folder,id:t.id,file:t.file,at:t.pinnedAt});return e.sort((t,i)=>t.at-i.at||oi(t).localeCompare(oi(i))),e}folderPinnedAt(e){let t=A.clean(e),i=(this.plugin.settings.folderPanelPinnedAt??{})[t];if(typeof i=="number")return i;let s=(this.plugin.settings.folderPanelPinned??[]).indexOf(t);return s>=0?s:0}ensureFolderPinOrder(){let e=this.plugin.settings;e.folderPanelPinnedAt=e.folderPanelPinnedAt??{};let t=!1;(e.folderPanelPinned??[]).forEach((i,s)=>{let n=A.clean(i);typeof e.folderPanelPinnedAt[n]!="number"&&(e.folderPanelPinnedAt[n]=s,t=!0)});for(let i of Object.keys(e.folderPanelPinnedAt))(e.folderPanelPinned??[]).includes(i)||(delete e.folderPanelPinnedAt[i],t=!0);t&&this.plugin.saveSettings()}renderPinned(e){this.ensureFolderPinOrder();let t=this.unifiedPinnedItems();if(t.length===0){e.createDiv({cls:"stashpad-folderpanel-empty",text:"Nothing pinned yet \u2014 pin a note or folder from its right-click menu."});return}let i=this.openFolders(),s=this.plugin.settings.folderPanelPinnedGrouping??"pin-order",n=new Map;if(t.forEach((p,f)=>n.set(p,f)),s!=="folder"){for(let p of t)this.renderPinnedItem(e,p,n.get(p),i,!0);return}let o=t.filter(p=>p.kind==="note"),a=t.filter(p=>p.kind==="folder"),l=new Map;for(let p of o){let f=l.get(p.folder);f||(f=[],l.set(p.folder,f)),f.push(p)}for(let p of a.filter(f=>!l.has(f.folder)).sort((f,u)=>f.at-u.at))this.renderPinnedItem(e,p,n.get(p),i,!1);let c=p=>{let f=1/0,u=a.find(g=>g.folder===p);u&&(f=Math.min(f,u.at));for(let g of l.get(p)??[])f=Math.min(f,g.at);return f},d=[...l.keys()].sort((p,f)=>c(p)-c(f)||p.localeCompare(f)),h=this.plugin.lastActiveStashpadLeaf?.view?.noteFolder;for(let p of d){let f=e.createDiv({cls:"stashpad-pinned-group-header"});p===h&&f.addClass("is-active-folder"),f.createSpan({cls:"stashpad-pinned-group-name",text:p.split("/").pop()||p});let u=[],g=a.find(C=>C.folder===p);g&&u.push(g),u.push(...l.get(p)??[]);let I=this.orderedGroupItems(p,u),m=I.map(oi);I.forEach((C,B)=>{let E=C.kind==="folder"?this.renderFolderRow(e,C.folder,i):this.renderPinNote(e,C.folder,C.id,C.file,B,!1);this.attachGroupItemDrag(E,p,B,m)})}}orderedGroupItems(e,t){let i=(this.plugin.settings.folderPanelGroupItemOrder??{})[A.clean(e)]??[],s=new Map(i.map((n,o)=>[n,o]));return t.slice().sort((n,o)=>{let a=s.has(oi(n))?s.get(oi(n)):1/0,l=s.has(oi(o))?s.get(oi(o)):1/0;return a-l||n.at-o.at})}async reorderGroupItem(e,t,i,s){if(i<0||i>=t.length)return;let n=t.slice(),[o]=n.splice(i,1),a=s>i?s-1:s;n.splice(Math.max(0,Math.min(a,n.length)),0,o),this.plugin.settings.folderPanelGroupItemOrder=this.plugin.settings.folderPanelGroupItemOrder??{},this.plugin.settings.folderPanelGroupItemOrder[A.clean(e)]=n,await this.plugin.saveSettings(),this.render()}attachGroupItemDrag(e,t,i,s){let n="application/x-stashpad-groupitem";e.draggable=!0,e.addEventListener("dragstart",o=>{o.dataTransfer?.setData(n,JSON.stringify({folder:t,idx:i})),o.dataTransfer&&(o.dataTransfer.effectAllowed="move"),e.addClass("is-dragging")}),e.addEventListener("dragend",()=>e.removeClass("is-dragging")),e.addEventListener("dragover",o=>{if(!o.dataTransfer?.types?.includes(n))return;o.preventDefault(),o.dataTransfer.dropEffect="move";let a=e.getBoundingClientRect(),l=o.clientY-a.top<a.height/2;e.toggleClass("drop-before",l),e.toggleClass("drop-after",!l)}),e.addEventListener("dragleave",()=>{e.removeClass("drop-before"),e.removeClass("drop-after")}),e.addEventListener("drop",o=>{if(!o.dataTransfer?.types?.includes(n))return;o.preventDefault(),e.removeClass("drop-before"),e.removeClass("drop-after");let a=null;try{a=JSON.parse(o.dataTransfer.getData(n)||"null")}catch{a=null}if(!a||a.folder!==t||a.idx===i)return;let l=e.getBoundingClientRect(),c=o.clientY-l.top<l.height/2;this.reorderGroupItem(t,s,a.idx,c?i:i+1)})}renderPinnedItem(e,t,i,s,n){if(t.kind==="folder"){let o=this.renderFolderRow(e,t.folder,s);n&&this.attachPinDrag(o,i)}else this.renderPinNote(e,t.folder,t.id,t.file,i,n)}attachPinDrag(e,t){e.draggable=!0,e.dataset.pinIdx=String(t),e.addEventListener("dragstart",i=>{i.dataTransfer?.setData("text/plain",String(t)),i.dataTransfer&&(i.dataTransfer.effectAllowed="move"),e.addClass("is-dragging")}),e.addEventListener("dragend",()=>e.removeClass("is-dragging")),e.addEventListener("dragover",i=>{i.preventDefault(),i.dataTransfer&&(i.dataTransfer.dropEffect="move");let s=e.getBoundingClientRect(),n=i.clientY-s.top<s.height/2;e.toggleClass("drop-before",n),e.toggleClass("drop-after",!n)}),e.addEventListener("dragleave",()=>{e.removeClass("drop-before"),e.removeClass("drop-after")}),e.addEventListener("drop",i=>{i.preventDefault(),e.removeClass("drop-before"),e.removeClass("drop-after");let s=parseInt(i.dataTransfer?.getData("text/plain")??"",10);if(!Number.isFinite(s)||s===t)return;let n=e.getBoundingClientRect(),o=i.clientY-n.top<n.height/2;this.reorderPinnedItem(s,o?t:t+1)})}async reorderPinnedItem(e,t){let i=this.unifiedPinnedItems();if(e<0||e>=i.length)return;let s=i[e],n=i.filter((d,h)=>h!==e),o=Math.max(0,Math.min(t>e?t-1:t,n.length)),a=n[o-1],l=n[o],c;if(!a&&!l?c=Date.now():a?l?c=(a.at+l.at)/2:c=a.at+1e3:c=l.at-1e3,s.kind==="folder")this.plugin.settings.folderPanelPinnedAt=this.plugin.settings.folderPanelPinnedAt??{},this.plugin.settings.folderPanelPinnedAt[s.folder]=c,await this.plugin.saveSettings();else try{await this.app.fileManager.processFrontMatter(s.file,d=>{d.pinnedAt=c})}catch(d){console.warn("[Stashpad] pin reorder failed",d)}this.render()}renderPinNote(e,t,i,s,n,o){let a=this.app.metadataCache.getFileCache(s)?.frontmatter??{},l=typeof a.color=="string"?a.color:null,c=a.completed===!0,d=this.childrenOf(t,i),h=d.length>0,p=`${t}|${i}`,f=this.pinExpanded.has(p),u=e.createDiv({cls:"stashpad-pinned-row"});l&&(u.addClass("has-color"),u.style.setProperty("--stashpad-note-color",l)),c&&u.addClass("is-completed"),o&&this.attachPinDrag(u,n);let g=u.createSpan({cls:"stashpad-pinned-toggle"});h&&(Ht(g,d.length,f),g.onclick=C=>{C.stopPropagation(),this.pinExpanded.has(p)?this.pinExpanded.delete(p):this.pinExpanded.add(p),this.render()});let I=u.createSpan({cls:"stashpad-pinned-icon"});(0,W.setIcon)(I,h?"folder-tree":"file-text"),l&&(I.style.color=l);let m=u.createSpan({cls:"stashpad-pinned-label",text:this.titleFromFile(s)});if(m.onclick=()=>{this.onNavigateAway(),this.plugin.revealNoteInStashpad(s)},u.createSpan({cls:"stashpad-pinned-folder",text:t.split("/").pop()||t}),u.oncontextmenu=C=>{C.preventDefault();let B=new W.Menu;B.addItem(E=>E.setTitle("Unpin from sidebar").setIcon("pin-off").onClick(()=>void this.plugin.unpinNote({folder:t,id:i}))),B.showAtMouseEvent(C)},h&&f){let C=e.createDiv({cls:"stashpad-pinned-children"});this.renderPinSubtree(C,t,i,1)}return u}renderPinSubtree(e,t,i,s){for(let n of this.childrenOf(t,i)){let o=this.app.metadataCache.getFileCache(n)?.frontmatter??{},a=typeof o.id=="string"?o.id:null;if(!a)continue;let l=typeof o.color=="string"?o.color:null,c=o.completed===!0,d=this.childrenOf(t,a),h=d.length>0,p=`${t}|${a}`,f=this.pinExpanded.has(p),u=e.createDiv({cls:"stashpad-pinned-subrow"});c&&u.addClass("is-completed"),u.style.paddingLeft=`${s*16}px`;let g=u.createSpan({cls:"stashpad-pinned-toggle"});h&&(Ht(g,d.length,f),g.onclick=C=>{C.stopPropagation(),this.pinExpanded.has(p)?this.pinExpanded.delete(p):this.pinExpanded.add(p),this.render()});let I=u.createSpan({cls:"stashpad-pinned-icon"});(0,W.setIcon)(I,"file-text"),l&&(I.style.color=l);let m=u.createSpan({cls:"stashpad-pinned-label",text:this.titleFromFile(n)});m.onclick=()=>{this.onNavigateAway(),this.plugin.revealNoteInStashpad(n)},h&&f&&this.renderPinSubtree(e,t,a,s+1)}}childrenOf(e,t){let i=[];for(let s of this.app.vault.getMarkdownFiles()){if((s.parent?.path?.replace(/\/+$/,"")??"")!==e)continue;let o=this.app.metadataCache.getFileCache(s)?.frontmatter;if(!o||typeof o.id!="string")continue;let a=o.parent;if(a===t||t===S&&(a==null||a===S)){if(o.id===S)continue;i.push(s)}}return i.sort((s,n)=>{let o=this.app.metadataCache.getFileCache(s)?.frontmatter?.created??"",a=this.app.metadataCache.getFileCache(n)?.frontmatter?.created??"";return String(o).localeCompare(String(a))}),i}onNavigateAway(){W.Platform.isMobile&&(this.plugin.suppressComposerAutofocusUntil=Date.now()+1500,this.app.workspace.leftSplit?.collapse?.())}titleFromFile(e){return e.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ").trim()||e.basename}openFolders(){let e=new Set,t=(this.plugin.settings.folder||"Stashpad").replace(/\/+$/,"");for(let i of this.app.workspace.getLeavesOfType($)){let s=(i.view?.noteFolder??"").replace(/\/+$/,"");s||(s=(((i.getViewState?.()?.state??{}).folderOverride??"")||t).replace(/\/+$/,"")),s&&e.add(s)}return e}static clean(e){return e.replace(/\/+$/,"")}folderState(e){let t=A.clean(e),i=this.plugin.settings;return(i.folderPanelPinned??[]).includes(t)?"pinned":(i.folderPanelDownranked??[]).includes(t)?"downranked":(i.folderPanelHidden??[]).includes(t)?"hidden":"normal"}async setFolderState(e,t){let i=A.clean(e),s=this.plugin.settings;s.folderPanelPinned=(s.folderPanelPinned??[]).filter(n=>n!==i),s.folderPanelDownranked=(s.folderPanelDownranked??[]).filter(n=>n!==i),s.folderPanelHidden=(s.folderPanelHidden??[]).filter(n=>n!==i),s.folderPanelPinnedAt=s.folderPanelPinnedAt??{},t==="pinned"?(s.folderPanelPinned.push(i),s.folderPanelPinnedAt[i]=Date.now()):(delete s.folderPanelPinnedAt[i],t==="downranked"?s.folderPanelDownranked.push(i):t==="hidden"&&s.folderPanelHidden.push(i)),await this.plugin.saveSettings(),this.render()}folderHomeColor(e){return this.homeColorByFolder.get(A.clean(e))??null}rebuildHomeColors(){this.homeColorByFolder.clear();for(let e of this.app.vault.getMarkdownFiles()){let t=this.app.metadataCache.getFileCache(e)?.frontmatter;if(!t||t.id!==S||typeof t.color!="string"||!t.color.trim())continue;let i=(e.parent?.path??"").replace(/\/+$/,"");i&&this.homeColorByFolder.set(i,t.color)}}renderFolders(e){let t=this.plugin.discoverStashpadFolders();if(t.length===0){e.createDiv({cls:"stashpad-folderpanel-empty",text:"No Stashpad folders yet."});return}this.rebuildHomeColors(),this.ensureFolderPinOrder();let i=this.openFolders(),s=[],n=[],o=[],a=[];for(let d of t)switch(this.folderState(d)){case"pinned":s.push(d);break;case"downranked":o.push(d);break;case"hidden":a.push(d);break;default:n.push(d)}s.sort((d,h)=>this.folderPinnedAt(d)-this.folderPinnedAt(h)||A.clean(d).localeCompare(A.clean(h)));let l=d=>(d.split("/").pop()||d).toLowerCase();n.sort((d,h)=>l(d).localeCompare(l(h))),o.sort((d,h)=>l(d).localeCompare(l(h)));let c=[...s,...n,...o];if(c.length===0&&a.length===0){e.createDiv({cls:"stashpad-folderpanel-empty",text:"No Stashpad folders yet."});return}for(let d of c){let h=this.renderFolderRow(e,d,i);this.folderState(d)==="pinned"&&this.attachFolderSectionDrag(h,s.indexOf(d),s)}a.length>0&&this.renderHiddenSection(e,a)}attachFolderSectionDrag(e,t,i){let s="application/x-stashpad-folder";e.draggable=!0,e.addEventListener("dragstart",n=>{n.dataTransfer?.setData(s,String(t)),n.dataTransfer&&(n.dataTransfer.effectAllowed="move"),e.addClass("is-dragging")}),e.addEventListener("dragend",()=>e.removeClass("is-dragging")),e.addEventListener("dragover",n=>{if(!n.dataTransfer?.types?.includes(s))return;n.preventDefault(),n.dataTransfer.dropEffect="move";let o=e.getBoundingClientRect(),a=n.clientY-o.top<o.height/2;e.toggleClass("drop-before",a),e.toggleClass("drop-after",!a)}),e.addEventListener("dragleave",()=>{e.removeClass("drop-before"),e.removeClass("drop-after")}),e.addEventListener("drop",n=>{if(!n.dataTransfer?.types?.includes(s))return;n.preventDefault(),e.removeClass("drop-before"),e.removeClass("drop-after");let o=parseInt(n.dataTransfer.getData(s)??"",10);if(!Number.isFinite(o)||o===t)return;let a=e.getBoundingClientRect(),l=n.clientY-a.top<a.height/2;this.reorderPinnedFolders(i,o,l?t:t+1)})}async reorderPinnedFolders(e,t,i){if(t<0||t>=e.length)return;let s=e[t],n=e.filter((d,h)=>h!==t),o=Math.max(0,Math.min(i>t?i-1:i,n.length)),a=n[o-1],l=n[o],c;!a&&!l?c=Date.now():a?l?c=(this.folderPinnedAt(a)+this.folderPinnedAt(l))/2:c=this.folderPinnedAt(a)+1e3:c=this.folderPinnedAt(l)-1e3,this.plugin.settings.folderPanelPinnedAt=this.plugin.settings.folderPanelPinnedAt??{},this.plugin.settings.folderPanelPinnedAt[A.clean(s)]=c,await this.plugin.saveSettings(),this.render()}renderFolderRow(e,t,i){let s=this.folderState(t),n=i.has(A.clean(t)),o=e.createDiv({cls:"stashpad-folderpanel-row stashpad-folderpanel-folder-row"});n&&o.addClass("is-open"),s==="downranked"&&o.addClass("is-downranked"),s==="pinned"&&o.addClass("is-pinned");let a=o.createSpan({cls:"stashpad-folderpanel-dot"});if(a.setAttr("aria-label",n?"Open in a tab":"Not open"),n&&a.setAttr("title","Open in a tab"),s==="pinned"){let m=o.createSpan({cls:"stashpad-folderpanel-pinmark"});(0,W.setIcon)(m,"pin"),m.setAttr("aria-label","Pinned")}let l=this.folderHomePinnedNotes(t),c=A.clean(t),d=this.folderPinExpanded.has(c);if(l.length>0){let m=o.createSpan({cls:"stashpad-folderpanel-pinreveal"});Ht(m,l.length,d),m.setAttr("aria-label",d?"Hide pinned notes":`${l.length} pinned note${l.length===1?"":"s"}`),m.addEventListener("mousedown",C=>{C.stopPropagation(),C.preventDefault()}),m.onclick=C=>{C.stopPropagation(),this.folderPinExpanded.has(c)?this.folderPinExpanded.delete(c):this.folderPinExpanded.add(c),this.render()}}let h=this.plugin.isArchiveFolder(t),p=o.createSpan({cls:"stashpad-folderpanel-folder-icon"});(0,W.setIcon)(p,this.plugin.getFolderIcon(t)??(h?"archive":"folder")),h&&p.setAttr("aria-label","Archive folder \u2014 de-indexed from search");let f=this.folderHomeColor(t);f&&(p.style.color=f);let u=t.split("/").pop()||t;o.createSpan({cls:"stashpad-folderpanel-row-label",text:u});let I=o.createDiv({cls:"stashpad-folderpanel-actions"}).createEl("button",{cls:"stashpad-folderpanel-iconbtn"});if((0,W.setIcon)(I,"plus-square"),I.setAttr("aria-label","Open in new tab"),I.onmousedown=m=>{m.button===0&&(m.preventDefault(),m.stopPropagation(),this.onNavigateAway(),this.plugin.activateViewForFolder(t))},o.addEventListener("mousedown",m=>{m.button===0&&(m.target?.closest?.(".stashpad-folderpanel-actions")||(this.onNavigateAway(),this.jumpToFolder(t)))}),o.oncontextmenu=m=>{m.preventDefault(),this.openFolderMenu(m,t)},l.length>0&&d){let m=e.createDiv({cls:"stashpad-folderpanel-pinlist"});for(let C of l){let B=m.createDiv({cls:"stashpad-folderpanel-pinrow"}),E=this.app.metadataCache.getFileCache(C)?.frontmatter??{},y=B.createSpan({cls:"stashpad-folderpanel-pinrow-icon"});(0,W.setIcon)(y,"arrow-up-to-line"),typeof E.color=="string"&&(y.style.color=E.color),B.createSpan({cls:"stashpad-folderpanel-pinrow-label",text:this.titleFromFile(C)}),B.onclick=()=>{this.onNavigateAway(),this.plugin.revealNoteInStashpad(C)}}}return o}folderHomePinnedNotes(e){return this.childrenOf(e,S).filter(t=>this.app.metadataCache.getFileCache(t)?.frontmatter?.listPinned===!0)}renderHiddenSection(e,t){let i=e.createDiv({cls:"stashpad-folderpanel-hidden"}),s=i.createDiv({cls:"stashpad-folderpanel-hidden-header"}),n=s.createSpan({cls:"stashpad-folderpanel-hidden-caret"});(0,W.setIcon)(n,"chevron-right"),s.createSpan({cls:"stashpad-folderpanel-hidden-title",text:`Hidden (${t.length})`});let o=i.createDiv({cls:"stashpad-folderpanel-hidden-body"});o.setCssStyles({display:"none"}),s.onclick=()=>{let a=o.style.display!=="none";o.setCssStyles({display:a?"none":""}),(0,W.setIcon)(n,a?"chevron-right":"chevron-down")};for(let a of t){let l=o.createDiv({cls:"stashpad-folderpanel-row stashpad-folderpanel-hidden-row"}),c=a.split("/").pop()||a;l.createSpan({cls:"stashpad-folderpanel-row-label",text:c});let d=l.createEl("button",{cls:"stashpad-folderpanel-iconbtn"});(0,W.setIcon)(d,"eye"),d.setAttr("aria-label","Unhide"),d.onclick=h=>{h.stopPropagation(),this.setFolderState(a,"normal")}}}jumpToFolder(e){this.plugin.openFolderInStashpad(e)}revealFolder(e){let t=this.app.vault.getAbstractFileByPath(e.replace(/\/+$/,""));if(!(t instanceof W.TFolder)){new W.Notice("Couldn't find that folder.");return}let i=this.app.workspace.getLeavesOfType("file-explorer")[0];if(!i){new W.Notice("File explorer isn't available.");return}this.app.workspace.revealLeaf(i),i.view?.revealInFolder?.(t)}openFolderMenu(e,t){let i=new W.Menu;i.addItem(n=>n.setTitle("Open in new tab").setIcon("plus-square").onClick(()=>void this.plugin.activateViewForFolder(t))),i.addItem(n=>n.setTitle("Reveal in file explorer").setIcon("folder-search").onClick(()=>this.revealFolder(t))),i.addSeparator();let s=this.folderState(t);i.addItem(n=>n.setTitle(s==="pinned"?"Unpin":"Pin to top").setIcon("pin").onClick(()=>void this.setFolderState(t,s==="pinned"?"normal":"pinned"))),i.addItem(n=>n.setTitle(s==="downranked"?"Remove downrank":"Downrank").setIcon("arrow-down").onClick(()=>void this.setFolderState(t,s==="downranked"?"normal":"downranked"))),i.addItem(n=>n.setTitle("Hide from list").setIcon("eye-off").onClick(()=>void this.setFolderState(t,"hidden"))),i.addSeparator(),i.addItem(n=>n.setTitle("Rename\u2026").setIcon("pencil").onClick(()=>this.renameFolder(t))),this.plugin.encryption?.isConfigured?.()&&(i.addSeparator(),i.addItem(n=>n.setTitle("Encrypt (lock) all notes in folder").setIcon("lock").onClick(()=>void this.plugin.lockFolder(t))),this.app.vault.getFiles().some(n=>n.extension==="stashenc"&&(n.parent?.path?.replace(/\/+$/,"")??"")===t.replace(/\/+$/,""))&&i.addItem(n=>n.setTitle("Decrypt (unlock) all notes in folder").setIcon("unlock").onClick(()=>void this.plugin.unlockFolder(t))),i.addItem(n=>n.setTitle("Open encrypted trash").setIcon("rotate-ccw").onClick(()=>this.plugin.openEncryptedTrash()))),i.addSeparator(),i.addItem(n=>{n.setTitle("Delete folder\u2026").setIcon("trash").onClick(()=>this.deleteFolder(t)),n.setWarning?.(!0)}),i.showAtMouseEvent(e)}renameFolder(e){let t=e.replace(/\/+$/,""),i=this.app.vault.getAbstractFileByPath(t);if(!(i instanceof W.TFolder)){new W.Notice("Couldn't find that folder.");return}let s=i.name;new Ta(this.app,s,async n=>{let o=n.trim().replace(/[\\/:]+/g,"").trim();if(!o||o===s)return;let l=`${i.parent?.path&&i.parent.path!=="/"?`${i.parent.path}/`:""}${o}`;if(this.app.vault.getAbstractFileByPath(l)){new W.Notice(`"${o}" already exists.`);return}if(!(this.app.vault.getAbstractFileByPath(t)instanceof W.TFolder)){new W.Notice("That folder no longer exists.");return}try{await this.app.fileManager.renameFile(i,l),await this.plugin.remapFolderPathInSettings(t,l),new W.Notice(`Renamed to "${o}".`)}catch(c){console.warn("[Stashpad] folder rename failed",c),new W.Notice("Rename failed (see console).")}}).open()}deleteFolder(e){let t=e.replace(/\/+$/,""),i=this.app.vault.getAbstractFileByPath(t);if(!(i instanceof W.TFolder)){new W.Notice("Couldn't find that folder.");return}let s=this.app.vault.getMarkdownFiles().filter(o=>(o.parent?.path?.replace(/\/+$/,"")??"")===t||o.path.startsWith(t+"/")).length,n=i.name;new j(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=>{o&&await this.plugin.deleteStashpadFolderWithUndo(i)}).open()}async onClose(){this.dividerCleanup?.(),this.contentEl.empty()}},Ta=class extends W.Modal{constructor(e,t,i){super(e);this.current=t;this.onSubmit=i;this.delivered=!1}onOpen(){this.modalEl.addClass("stashpad-compact-modal"),this.contentEl.empty(),this.titleEl.setText("Rename folder");let e=this.contentEl.createEl("input",{type:"text"});e.addClass("stashpad-folderpanel-rename-input"),e.value=this.current;let t=this.contentEl.createDiv({cls:"stashpad-folderpanel-rename-footer"});t.createEl("button",{text:"Cancel"}).onclick=()=>this.close();let i=t.createEl("button",{cls:"mod-cta",text:"Rename"}),s=()=>{this.delivered=!0;let n=e.value;this.close(),this.onSubmit(n)};i.onclick=s,this.scope.register([],"Enter",n=>{n.preventDefault(),e.value.trim()&&s()}),requestAnimationFrame(()=>{e.focus(),e.select()})}onClose(){this.contentEl.empty()}};async function so(A){let r=A.workspace.getLeavesOfType(bt);if(r.length>0){A.workspace.revealLeaf(r[0]);return}let e=A.workspace.getLeftLeaf(!1);if(!e){new W.Notice("Stashpad: couldn't open the folder panel.");return}await e.setViewState({type:bt,active:!0}),A.workspace.revealLeaf(e)}Xo();ve();ki();ui();pn();ce();var Ma="OKF Template.md",lA=`--- okfType: concept --- {{body}} -`,Na=["> Generated by Stashpad \u2014 this folder is an Open Knowledge Format (OKF) bundle.","> Field legend: `okfType`\u2192`type`, `okfTitle`\u2192`title`, `okfDescription`\u2192`description`, `okfTags`\u2192`tags`, `okfTimestamp`\u2192`timestamp`; `okfParent`/`okfChildren` are relative-markdown cross-links. Stashpad's own `id`/`parent` are extensions \u2014 ignore them for OKF."].join(` -`);function Ps(d){return d.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ").trim()||d.basename}function Zl(d){return`[${Ps(d)}](${encodeURI(d.name)})`}async function jl(d,r=xa){try{await d.vault.adapter.exists(r)||await d.vault.create(r,tA)}catch{}return r}function _l(d,r){if(!r)return[];let e=r.replace(/^\/+/,"");return Object.entries(d??{}).filter(([,t])=>(t??"").replace(/^\/+/,"")===e).map(([t])=>t.replace(/\/+$/,""))}async function Ta(d,r){let e=r.replace(/\/+$/,""),t=new Map,i=new Map;for(let o of d.vault.getMarkdownFiles()){if((o.parent?.path?.replace(/\/+$/,"")??"")!==e)continue;let a;try{a=ge(await d.vault.read(o)).fm}catch{continue}let l=typeof a.id=="string"?a.id:null;if(!l)continue;let c=typeof a.parent=="string"?a.parent:S;t.set(l,{file:o,id:l,parent:c,modified:typeof a.modified=="string"?a.modified:"",created:typeof a.created=="string"?a.created:""});let A=i.get(c)??[];A.push(l),i.set(c,A)}let s=0,n=0;for(let o of t.values()){if(o.id===S)continue;s+=1;let a=o.parent&&o.parent!==S&&t.get(o.parent)?Zl(t.get(o.parent).file):null,l=(i.get(o.id)??[]).map(c=>t.get(c)).filter(c=>!!c).map(c=>Zl(c.file));try{let c=!1;await d.fileManager.processFrontMatter(o.file,A=>{a?A.okfParent!==a&&(A.okfParent=a,c=!0):A.okfParent!==void 0&&(delete A.okfParent,c=!0);let h=Array.isArray(A.okfChildren)?A.okfChildren:[],p=h.length===l.length&&h.every((f,u)=>f===l[u]);if(l.length?p||(A.okfChildren=l,c=!0):A.okfChildren!==void 0&&(delete A.okfChildren,c=!0),A.okfType===void 0&&(A.okfType="concept",c=!0),A.okfTitle===void 0&&(A.okfTitle=Ps(o.file),c=!0),A.okfTimestamp===void 0){let f=o.modified||o.created;f&&(A.okfTimestamp=f,c=!0)}}),c&&(n+=1,await new Promise(A=>setTimeout(A,50)))}catch(c){console.warn("[Stashpad] OKF rebuild failed",o.file.path,c)}}try{await d.vault.adapter.write(`${e}/index.md`,await Ma(d,e))}catch(o){console.warn("[Stashpad] OKF index.md write failed",e,o)}return{checked:s,written:n}}async function Ma(d,r,e){let t=r.replace(/\/+$/,""),i=new Map,s=new Map;for(let A of d.vault.getMarkdownFiles()){if((A.parent?.path?.replace(/\/+$/,"")??"")!==t||A.name==="index.md")continue;let h;try{h=ge(await d.vault.read(A)).fm}catch{continue}let p=typeof h.id=="string"?h.id:null;!p||p===S||e&&!e.has(p)||i.set(p,{id:p,file:A,parent:typeof h.parent=="string"?h.parent:S,title:typeof h.okfTitle=="string"&&h.okfTitle?h.okfTitle:Ps(A),type:typeof h.okfType=="string"&&h.okfType?h.okfType:"concept",position:typeof h.position=="number"?h.position:Number.MAX_SAFE_INTEGER,created:typeof h.created=="string"?h.created:""})}for(let A of i.values()){let h=s.get(A.parent)??[];h.push(A),s.set(A.parent,h)}for(let A of s.values())A.sort((h,p)=>h.position-p.position||h.created.localeCompare(p.created));let n=[],o=(A,h,p)=>{if(!p.has(A.id)){p.add(A.id),n.push(`${" ".repeat(h)}- [${A.title}](${encodeURI(A.file.name)}) \u2014 ${A.type}`);for(let f of s.get(A.id)??[])o(f,h+1,p)}},a=new Set,l=[...i.values()].filter(A=>A.parent===S||!i.has(A.parent)).sort((A,h)=>A.position-h.position||A.created.localeCompare(h.created));for(let A of l)o(A,0,a);let c=t.split("/").pop()||t;return["---","type: index",`title: ${c} (OKF index)`,"---","",`# ${c}`,"",Na,"","## Concepts",n.length?n.join(` +`,Pa=["> Generated by Stashpad \u2014 this folder is an Open Knowledge Format (OKF) bundle.","> Field legend: `okfType`\u2192`type`, `okfTitle`\u2192`title`, `okfDescription`\u2192`description`, `okfTags`\u2192`tags`, `okfTimestamp`\u2192`timestamp`; `okfParent`/`okfChildren` are relative-markdown cross-links. Stashpad's own `id`/`parent` are extensions \u2014 ignore them for OKF."].join(` +`);function Rs(A){return A.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ").trim()||A.basename}function ec(A){return`[${Rs(A)}](${encodeURI(A.name)})`}async function tc(A,r=Ma){try{await A.vault.adapter.exists(r)||await A.vault.create(r,lA)}catch{}return r}function ic(A,r){if(!r)return[];let e=r.replace(/^\/+/,"");return Object.entries(A??{}).filter(([,t])=>(t??"").replace(/^\/+/,"")===e).map(([t])=>t.replace(/\/+$/,""))}async function Ha(A,r){let e=r.replace(/\/+$/,""),t=new Map,i=new Map;for(let o of A.vault.getMarkdownFiles()){if((o.parent?.path?.replace(/\/+$/,"")??"")!==e)continue;let a;try{a=ge(await A.vault.read(o)).fm}catch{continue}let l=typeof a.id=="string"?a.id:null;if(!l)continue;let c=typeof a.parent=="string"?a.parent:S;t.set(l,{file:o,id:l,parent:c,modified:typeof a.modified=="string"?a.modified:"",created:typeof a.created=="string"?a.created:""});let d=i.get(c)??[];d.push(l),i.set(c,d)}let s=0,n=0;for(let o of t.values()){if(o.id===S)continue;s+=1;let a=o.parent&&o.parent!==S&&t.get(o.parent)?ec(t.get(o.parent).file):null,l=(i.get(o.id)??[]).map(c=>t.get(c)).filter(c=>!!c).map(c=>ec(c.file));try{let c=!1;await A.fileManager.processFrontMatter(o.file,d=>{a?d.okfParent!==a&&(d.okfParent=a,c=!0):d.okfParent!==void 0&&(delete d.okfParent,c=!0);let h=Array.isArray(d.okfChildren)?d.okfChildren:[],p=h.length===l.length&&h.every((f,u)=>f===l[u]);if(l.length?p||(d.okfChildren=l,c=!0):d.okfChildren!==void 0&&(delete d.okfChildren,c=!0),d.okfType===void 0&&(d.okfType="concept",c=!0),d.okfTitle===void 0&&(d.okfTitle=Rs(o.file),c=!0),d.okfTimestamp===void 0){let f=o.modified||o.created;f&&(d.okfTimestamp=f,c=!0)}}),c&&(n+=1,await new Promise(d=>setTimeout(d,50)))}catch(c){console.warn("[Stashpad] OKF rebuild failed",o.file.path,c)}}try{await A.vault.adapter.write(`${e}/index.md`,await Ra(A,e))}catch(o){console.warn("[Stashpad] OKF index.md write failed",e,o)}return{checked:s,written:n}}async function Ra(A,r,e){let t=r.replace(/\/+$/,""),i=new Map,s=new Map;for(let d of A.vault.getMarkdownFiles()){if((d.parent?.path?.replace(/\/+$/,"")??"")!==t||d.name==="index.md")continue;let h;try{h=ge(await A.vault.read(d)).fm}catch{continue}let p=typeof h.id=="string"?h.id:null;!p||p===S||e&&!e.has(p)||i.set(p,{id:p,file:d,parent:typeof h.parent=="string"?h.parent:S,title:typeof h.okfTitle=="string"&&h.okfTitle?h.okfTitle:Rs(d),type:typeof h.okfType=="string"&&h.okfType?h.okfType:"concept",position:typeof h.position=="number"?h.position:Number.MAX_SAFE_INTEGER,created:typeof h.created=="string"?h.created:""})}for(let d of i.values()){let h=s.get(d.parent)??[];h.push(d),s.set(d.parent,h)}for(let d of s.values())d.sort((h,p)=>h.position-p.position||h.created.localeCompare(p.created));let n=[],o=(d,h,p)=>{if(!p.has(d.id)){p.add(d.id),n.push(`${" ".repeat(h)}- [${d.title}](${encodeURI(d.file.name)}) \u2014 ${d.type}`);for(let f of s.get(d.id)??[])o(f,h+1,p)}},a=new Set,l=[...i.values()].filter(d=>d.parent===S||!i.has(d.parent)).sort((d,h)=>d.position-h.position||d.created.localeCompare(h.created));for(let d of l)o(d,0,a);let c=t.split("/").pop()||t;return["---","type: index",`title: ${c} (OKF index)`,"---","",`# ${c}`,"",Pa,"","## Concepts",n.length?n.join(` `):"_No concepts yet._",""].join(` -`)}var iA=new TextEncoder,io=d=>iA.encode(d);function Hs(d){if(typeof d=="number"||typeof d=="boolean")return String(d);let r=String(d??"");return/[:#[\]{}",&*!|>%@`]|^\s|\s$|^$/.test(r)?JSON.stringify(r):r}function sA(d,r){let{fm:e}=ge(d),t=[];t.push(`type: ${Hs(typeof e.okfType=="string"&&e.okfType?e.okfType:"concept")}`),t.push(`title: ${Hs(typeof e.okfTitle=="string"&&e.okfTitle?e.okfTitle:Ps(r))}`),typeof e.okfDescription=="string"&&e.okfDescription&&t.push(`description: ${Hs(e.okfDescription)}`);let i=e.okfTags;if(Array.isArray(i)&&i.length){t.push("tags:");for(let a of i)t.push(` - ${Hs(a)}`)}let s=typeof e.okfTimestamp=="string"&&e.okfTimestamp||typeof e.modified=="string"&&e.modified||typeof e.created=="string"&&e.created||"";s&&t.push(`timestamp: ${Hs(s)}`);let n=t.join(` -`),o=d.match(/^---\r?\n/);return o?d.slice(0,o[0].length)+n+` -`+d.slice(o[0].length):`--- +`)}var cA=new TextEncoder,no=A=>cA.encode(A);function Us(A){if(typeof A=="number"||typeof A=="boolean")return String(A);let r=String(A??"");return/[:#[\]{}",&*!|>%@`]|^\s|\s$|^$/.test(r)?JSON.stringify(r):r}function dA(A,r){let{fm:e}=ge(A),t=[];t.push(`type: ${Us(typeof e.okfType=="string"&&e.okfType?e.okfType:"concept")}`),t.push(`title: ${Us(typeof e.okfTitle=="string"&&e.okfTitle?e.okfTitle:Rs(r))}`),typeof e.okfDescription=="string"&&e.okfDescription&&t.push(`description: ${Us(e.okfDescription)}`);let i=e.okfTags;if(Array.isArray(i)&&i.length){t.push("tags:");for(let a of i)t.push(` - ${Us(a)}`)}let s=typeof e.okfTimestamp=="string"&&e.okfTimestamp||typeof e.modified=="string"&&e.modified||typeof e.created=="string"&&e.created||"";s&&t.push(`timestamp: ${Us(s)}`);let n=t.join(` +`),o=A.match(/^---\r?\n/);return o?A.slice(0,o[0].length)+n+` +`+A.slice(o[0].length):`--- ${n} --- -${d}`}async function ec(d,r,e,t){let i=[],s=new Map;for(let n of r){let o=await d.vault.read(n);i.push({name:n.name,data:io(sA(o,n))});for(let a of o.match(/!\[\[([^\]]+?)\]\]/g)??[]){let l=a.slice(3,-2).split("|")[0].split("#")[0].trim(),c=d.metadataCache.getFirstLinkpathDest(l,n.path);c&&!s.has(c.name)&&s.set(c.name,c)}}for(let[n,o]of s)i.push({name:`_attachments/${n}`,data:new Uint8Array(await d.vault.readBinary(o))});return i.push({name:"index.md",data:io(await Ma(d,e,t))}),i.push({name:"_okf.md",data:io(`# About this bundle +${A}`}async function sc(A,r,e,t){let i=[],s=new Map;for(let n of r){let o=await A.vault.read(n);i.push({name:n.name,data:no(dA(o,n))});for(let a of o.match(/!\[\[([^\]]+?)\]\]/g)??[]){let l=a.slice(3,-2).split("|")[0].split("#")[0].trim(),c=A.metadataCache.getFirstLinkpathDest(l,n.path);c&&!s.has(c.name)&&s.set(c.name,c)}}for(let[n,o]of s)i.push({name:`_attachments/${n}`,data:new Uint8Array(await A.vault.readBinary(o))});return i.push({name:"index.md",data:no(await Ra(A,e,t))}),i.push({name:"_okf.md",data:no(`# About this bundle -${Na.replace(/^> /gm,"")} -`)}),i}async function tc(d){let{zipFiles:r}=await Promise.resolve().then(()=>(qn(),Fl));return r(d.map(e=>({name:e.name,data:e.data})))}function Ki(d,r){return d.toString(8).padStart(r-1,"0")+"\0"}function nA(d,r){let e=new Uint8Array(512),t=(s,n,o)=>{let a=io(s);e.set(a.subarray(0,o),n)};t(d.slice(0,100),0,100),t(Ki(420,8),100,8),t(Ki(0,8),108,8),t(Ki(0,8),116,8),t(Ki(r,12),124,12),t(Ki(0,12),136,12),t(" ",148,8),e[156]=48,t("ustar\0",257,6),t("00",263,2);let i=0;for(let s=0;s<512;s++)i+=e[s];return t(Ki(i,8),148,8),e}function oA(d){let r=[],e=0;for(let s of d){let n=nA(s.name,s.data.length);r.push(n,s.data),e+=512+s.data.length;let o=(512-s.data.length%512)%512;o&&(r.push(new Uint8Array(o)),e+=o)}r.push(new Uint8Array(1024)),e+=1024;let t=new Uint8Array(e),i=0;for(let s of r)t.set(s,i),i+=s.length;return t}async function aA(d){let r=new CompressionStream("gzip"),e=new Response(d).body.pipeThrough(r);return new Uint8Array(await new Response(e).arrayBuffer())}async function ic(d){return aA(oA(d))}Tt();Wt();var so=class{constructor(r,e,t){this.app=r;this.dirOk=!1;this.writeChain=Promise.resolve();this.baseDir=e.replace(/\/+$/,""),this.logPath=`${this.baseDir}/log.jsonl`,this.statePath=`${this.baseDir}/state.json`,this.getAuthor=t??(()=>"")}getLogPath(){return this.logPath}getDir(){return this.baseDir}async ensureDir(){if(this.dirOk)return;let r=this.app.vault.adapter,e=this.baseDir.split("/").filter(Boolean),t="";for(let i of e)t=t?`${t}/${i}`:i,await r.exists(t)||await r.mkdir(t);this.dirOk=!0}append(r){let e=r.author??this.getAuthor()??"",t={ts:new Date().toISOString(),...r};e?t.author=e:delete t.author;let i=JSON.stringify(t)+` -`;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 r=this.app.vault.adapter;if(!await r.exists(this.statePath))return{};try{return JSON.parse(await r.read(this.statePath))}catch{return{}}}async writeState(r){await this.ensureDir(),await this.app.vault.adapter.write(this.statePath,JSON.stringify(r,null,2))}};ce();var no=class{constructor(){this.undoStack=[];this.redoStack=[];this.cap=30}push(r){for(this.undoStack.push(r),this.redoStack.length=0;this.undoStack.length>this.cap;)this.undoStack.shift()}async undo(){let r=this.undoStack.pop();if(!r)return null;try{await r.undo()}catch(e){throw this.undoStack.push(r),console.error("Stashpad: undo failed",e),e}return this.redoStack.push(r),r}async redo(){let r=this.redoStack.pop();if(!r)return null;if(r.redo)try{await r.redo()}catch(e){throw this.redoStack.push(r),console.error("Stashpad: redo failed",e),e}return this.undoStack.push(r),r}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=[]}};en();var oo=class{constructor(r,e){this.app=r;this.data={version:1,authors:{}};this.loaded=!1;this.dirOk=!1;this.writeChain=Promise.resolve();this.path=`${e.replace(/\/+$/,"")}/authors.json`}getPath(){return this.path}async load(){if(!this.loaded){this.loaded=!0;try{let r=this.app.vault.adapter;if(await r.exists(this.path)){let e=JSON.parse(await r.read(this.path));e&&typeof e=="object"&&e.authors&&(this.data={version:typeof e.version=="number"?e.version:1,authors:e.authors})}}catch(r){console.warn("[Stashpad] author registry load failed; starting empty",r),this.data={version:1,authors:{}}}}}all(){return Object.values(this.data.authors).sort((r,e)=>(e.lastSeen??"").localeCompare(r.lastSeen??""))}get(r){return this.data.authors[r]??null}record(r){let e=(r.id??"").trim();if(!e)return!1;let t=r.at??new Date().toISOString(),i=(r.name??"").trim(),s=this.data.authors[e],n=!1;if(!s)this.data.authors[e]={id:e,name:i,role:r.role?.trim()||void 0,department:r.department?.trim()||void 0,firstSeen:t,lastSeen:t,renames:[]},n=!0;else{if(i&&i!==s.name&&(s.renames.push({from:s.name,to:i,at:t}),s.name=i,n=!0),r.role!==void 0){let o=r.role.trim()||void 0;o!==s.role&&(s.role=o,n=!0)}if(r.department!==void 0){let o=r.department.trim()||void 0;o!==s.department&&(s.department=o,n=!0)}s.lastSeen=t}return n&&this.save(),n}replaceAll(r,e){let t=e??new Date().toISOString(),i={};for(let s of r){let n=(s.id??"").trim();if(!n)continue;let o=this.data.authors[n],a=(s.name??"").trim()||o?.name||"",l=o?.renames?[...o.renames]:[];o&&a&&a!==o.name&&l.push({from:o.name,to:a,at:t}),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??t,lastSeen:t,renames:l}}this.data={version:1,authors:i},this.save()}async ensureDir(){if(this.dirOk)return;let r=this.app.vault.adapter,t=this.path.slice(0,this.path.lastIndexOf("/")).split("/").filter(Boolean),i="";for(let s of t)i=i?`${i}/${s}`:s,await r.exists(i)||await r.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(r){console.warn("[Stashpad] author registry save failed",r)}}),this.writeChain}};var ne=require("obsidian");ce();Tt();gi();Wt();Ys();ve();var ao=new Set(["_attachments","_authors","_exports","_imports","_processed","_archive",".archive","archive","trash"]),sc=new Set([ct,"edtz","stashenc","stashmeta"]),qi=class qi{constructor(r){this.plugin=r;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(r){this.armed=r}isArmed(){return this.armed}get app(){return this.plugin.app}importedOriginalsDir(r){let t=Nt(Date.now(),this.plugin.settings).replace(/[/\\:]+/g,"-").replace(/\s+/g," ").trim()||"undated";return`${r}/archive/_imported/${t}`}enqueue(r){this.armed&&this.plugin.settings.autoImport&&this.isEligiblePath(r)&&(this.pending.set(r.path,Date.now()),this.arm())}enqueueFolder(r){if(!this.armed||!this.plugin.settings.autoImport||this.suppressed.has(r.path))return;let e=r.parent?.path?.replace(/\/+$/,"")??"";this.plugin.discoverStashpadFolders().includes(e)&&(ao.has(r.name)||(this.pendingFolders.set(r.path,Date.now()),this.arm()))}arm(){this.drainTimer!=null&&window.clearTimeout(this.drainTimer),this.drainTimer=window.setTimeout(()=>void this.drain(),qi.DEBOUNCE_MS)}suppress(r,e=4e3){this.suppressed.add(r),window.setTimeout(()=>this.suppressed.delete(r),e)}async createNote(r,e){this.suppress(r,6e4),await this.app.vault.create(r,e)}isEligiblePath(r){if(this.suppressed.has(r.path)||sc.has(r.extension))return!1;let e=r.parent?.path?.replace(/\/+$/,"")??"",t=e.split("/").pop()??"";return ao.has(t)?!1:this.plugin.discoverStashpadFolders().includes(e)}async isStillImportable(r){if(!this.isEligiblePath(r))return!1;if(r.extension==="md")try{let{fm:e}=ge(await this.app.vault.read(r));if(e&&typeof e.id=="string"&&e.id)return!1}catch{}return!0}async drain(){if(this.drainTimer=null,!this.draining){this.draining=!0;try{let r=[...this.pending.keys()];this.pending.clear();let e=r.map(h=>this.app.vault.getAbstractFileByPath(h)).filter(h=>h instanceof ne.TFile),t=[];for(let h of e)await this.isStillImportable(h)&&t.push(h);let i=[...this.pendingFolders.keys()];this.pendingFolders.clear();let s=i.map(h=>this.app.vault.getAbstractFileByPath(h)).filter(h=>h instanceof ne.TFolder).map(h=>({folder:h,files:this.filesUnder(h.path)})).filter(h=>h.files.length>0),n=s.reduce((h,p)=>h+p.files.length,0),o=t.length+n;if(o===0)return;await this.plugin.importLog.load();let a=t,l=[],c=t.filter(h=>this.plugin.importLog.findDuplicate(h.name,h.stat?.size??null));if(c.length>0){let h=c.slice(0,5).map(u=>`\u2022 ${u.name}`).join(` +${Pa.replace(/^> /gm,"")} +`)}),i}async function nc(A){let{zipFiles:r}=await Promise.resolve().then(()=>($n(),bl));return r(A.map(e=>({name:e.name,data:e.data})))}function Ji(A,r){return A.toString(8).padStart(r-1,"0")+"\0"}function AA(A,r){let e=new Uint8Array(512),t=(s,n,o)=>{let a=no(s);e.set(a.subarray(0,o),n)};t(A.slice(0,100),0,100),t(Ji(420,8),100,8),t(Ji(0,8),108,8),t(Ji(0,8),116,8),t(Ji(r,12),124,12),t(Ji(0,12),136,12),t(" ",148,8),e[156]=48,t("ustar\0",257,6),t("00",263,2);let i=0;for(let s=0;s<512;s++)i+=e[s];return t(Ji(i,8),148,8),e}function hA(A){let r=[],e=0;for(let s of A){let n=AA(s.name,s.data.length);r.push(n,s.data),e+=512+s.data.length;let o=(512-s.data.length%512)%512;o&&(r.push(new Uint8Array(o)),e+=o)}r.push(new Uint8Array(1024)),e+=1024;let t=new Uint8Array(e),i=0;for(let s of r)t.set(s,i),i+=s.length;return t}async function pA(A){let r=new CompressionStream("gzip"),e=new Response(A).body.pipeThrough(r);return new Uint8Array(await new Response(e).arrayBuffer())}async function oc(A){return pA(hA(A))}Tt();Wt();var oo=class{constructor(r,e,t){this.app=r;this.dirOk=!1;this.writeChain=Promise.resolve();this.baseDir=e.replace(/\/+$/,""),this.logPath=`${this.baseDir}/log.jsonl`,this.statePath=`${this.baseDir}/state.json`,this.getAuthor=t??(()=>"")}getLogPath(){return this.logPath}getDir(){return this.baseDir}async ensureDir(){if(this.dirOk)return;let r=this.app.vault.adapter,e=this.baseDir.split("/").filter(Boolean),t="";for(let i of e)t=t?`${t}/${i}`:i,await r.exists(t)||await r.mkdir(t);this.dirOk=!0}append(r){let e=r.author??this.getAuthor()??"",t={ts:new Date().toISOString(),...r};e?t.author=e:delete t.author;let i=JSON.stringify(t)+` +`;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 r=this.app.vault.adapter;if(!await r.exists(this.statePath))return{};try{return JSON.parse(await r.read(this.statePath))}catch{return{}}}async writeState(r){await this.ensureDir(),await this.app.vault.adapter.write(this.statePath,JSON.stringify(r,null,2))}};ce();var ao=class{constructor(){this.undoStack=[];this.redoStack=[];this.cap=30}push(r){for(this.undoStack.push(r),this.redoStack.length=0;this.undoStack.length>this.cap;)this.undoStack.shift()}async undo(){let r=this.undoStack.pop();if(!r)return null;try{await r.undo()}catch(e){throw this.undoStack.push(r),console.error("Stashpad: undo failed",e),e}return this.redoStack.push(r),r}async redo(){let r=this.redoStack.pop();if(!r)return null;if(r.redo)try{await r.redo()}catch(e){throw this.redoStack.push(r),console.error("Stashpad: redo failed",e),e}return this.undoStack.push(r),r}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=[]}};sn();var ro=class{constructor(r,e){this.app=r;this.data={version:1,authors:{}};this.loaded=!1;this.dirOk=!1;this.writeChain=Promise.resolve();this.path=`${e.replace(/\/+$/,"")}/authors.json`}getPath(){return this.path}async load(){if(!this.loaded){this.loaded=!0;try{let r=this.app.vault.adapter;if(await r.exists(this.path)){let e=JSON.parse(await r.read(this.path));e&&typeof e=="object"&&e.authors&&(this.data={version:typeof e.version=="number"?e.version:1,authors:e.authors})}}catch(r){console.warn("[Stashpad] author registry load failed; starting empty",r),this.data={version:1,authors:{}}}}}all(){return Object.values(this.data.authors).sort((r,e)=>(e.lastSeen??"").localeCompare(r.lastSeen??""))}get(r){return this.data.authors[r]??null}record(r){let e=(r.id??"").trim();if(!e)return!1;let t=r.at??new Date().toISOString(),i=(r.name??"").trim(),s=this.data.authors[e],n=!1;if(!s)this.data.authors[e]={id:e,name:i,role:r.role?.trim()||void 0,department:r.department?.trim()||void 0,firstSeen:t,lastSeen:t,renames:[]},n=!0;else{if(i&&i!==s.name&&(s.renames.push({from:s.name,to:i,at:t}),s.name=i,n=!0),r.role!==void 0){let o=r.role.trim()||void 0;o!==s.role&&(s.role=o,n=!0)}if(r.department!==void 0){let o=r.department.trim()||void 0;o!==s.department&&(s.department=o,n=!0)}s.lastSeen=t}return n&&this.save(),n}replaceAll(r,e){let t=e??new Date().toISOString(),i={};for(let s of r){let n=(s.id??"").trim();if(!n)continue;let o=this.data.authors[n],a=(s.name??"").trim()||o?.name||"",l=o?.renames?[...o.renames]:[];o&&a&&a!==o.name&&l.push({from:o.name,to:a,at:t}),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??t,lastSeen:t,renames:l}}this.data={version:1,authors:i},this.save()}async ensureDir(){if(this.dirOk)return;let r=this.app.vault.adapter,t=this.path.slice(0,this.path.lastIndexOf("/")).split("/").filter(Boolean),i="";for(let s of t)i=i?`${i}/${s}`:s,await r.exists(i)||await r.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(r){console.warn("[Stashpad] author registry save failed",r)}}),this.writeChain}};var ne=require("obsidian");ce();Tt();ui();Wt();Vs();ve();var lo=new Set(["_attachments","_authors","_exports","_imports","_processed","_archive",".archive","archive","trash"]),ac=new Set([ct,"edtz","stashenc","stashmeta"]),qi=class qi{constructor(r){this.plugin=r;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(r){this.armed=r}isArmed(){return this.armed}get app(){return this.plugin.app}importedOriginalsDir(r){let t=Nt(Date.now(),this.plugin.settings).replace(/[/\\:]+/g,"-").replace(/\s+/g," ").trim()||"undated";return`${r}/archive/_imported/${t}`}enqueue(r){this.armed&&this.plugin.settings.autoImport&&this.isEligiblePath(r)&&(this.pending.set(r.path,Date.now()),this.arm())}enqueueFolder(r){if(!this.armed||!this.plugin.settings.autoImport||this.suppressed.has(r.path))return;let e=r.parent?.path?.replace(/\/+$/,"")??"";this.plugin.discoverStashpadFolders().includes(e)&&(lo.has(r.name)||(this.pendingFolders.set(r.path,Date.now()),this.arm()))}arm(){this.drainTimer!=null&&window.clearTimeout(this.drainTimer),this.drainTimer=window.setTimeout(()=>void this.drain(),qi.DEBOUNCE_MS)}suppress(r,e=4e3){this.suppressed.add(r),window.setTimeout(()=>this.suppressed.delete(r),e)}async createNote(r,e){this.suppress(r,6e4),await this.app.vault.create(r,e)}isEligiblePath(r){if(this.suppressed.has(r.path)||ac.has(r.extension))return!1;let e=r.parent?.path?.replace(/\/+$/,"")??"",t=e.split("/").pop()??"";return lo.has(t)?!1:this.plugin.discoverStashpadFolders().includes(e)}async isStillImportable(r){if(!this.isEligiblePath(r))return!1;if(r.extension==="md")try{let{fm:e}=ge(await this.app.vault.read(r));if(e&&typeof e.id=="string"&&e.id)return!1}catch{}return!0}async drain(){if(this.drainTimer=null,!this.draining){this.draining=!0;try{let r=[...this.pending.keys()];this.pending.clear();let e=r.map(h=>this.app.vault.getAbstractFileByPath(h)).filter(h=>h instanceof ne.TFile),t=[];for(let h of e)await this.isStillImportable(h)&&t.push(h);let i=[...this.pendingFolders.keys()];this.pendingFolders.clear();let s=i.map(h=>this.app.vault.getAbstractFileByPath(h)).filter(h=>h instanceof ne.TFolder).map(h=>({folder:h,files:this.filesUnder(h.path)})).filter(h=>h.files.length>0),n=s.reduce((h,p)=>h+p.files.length,0),o=t.length+n;if(o===0)return;await this.plugin.importLog.load();let a=t,l=[],c=t.filter(h=>this.plugin.importLog.findDuplicate(h.name,h.stat?.size??null));if(c.length>0){let h=c.slice(0,5).map(u=>`\u2022 ${u.name}`).join(` `),p=c.length>5?` \u2026and ${c.length-5} more`:"",f=await this.dupChoice(`${c.length} of these look like files you've imported before: ${h}${p} Replace the existing notes, skip the duplicates, or import them anyway as new notes?`);if(f==="skip"){let u=new Set(c.map(g=>g.path));if(a=t.filter(g=>!u.has(g.path)),a.length===0&&s.length===0){new ne.Notice(`Skipped ${c.length} duplicate file(s) \u2014 nothing new to import.`);return}}else if(f==="replace")for(let u of c){let g=this.plugin.importLog.findDuplicate(u.name,u.stat?.size??null);for(let I of g?.notePaths??[]){let m=this.app.vault.getAbstractFileByPath(I);if(m instanceof ne.TFile)try{l.push({path:I,content:await this.app.vault.read(m)}),await this.app.fileManager.trashFile(m)}catch(C){console.warn("[Stashpad] replace: couldn't remove prior note",I,C)}}}}if(o=a.length+n,o>=qi.BATCH_CONFIRM_AT){let h=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${h}. Proceed? -Markdown becomes notes (originals archived); other files move to _attachments with a linking note. Dropped folders move to _archive.`,"Import all")){new ne.Notice(`Import cancelled \u2014 ${o} file(s) left as-is.`);return}}let A=[];for(let h of a)try{let p=h.stat?.size??null,f=h.extension==="md"?await this.importMarkdown(h):await this.importOtherFile(h);f&&(A.push(f),this.plugin.importLog.append({ts:new Date().toISOString(),folder:f.folder,kind:f.kind,originalName:h.name,size:p,sourcePath:h.path,notePaths:f.kind==="folder"?f.notePaths:[f.notePath]}))}catch(p){console.warn("[Stashpad] import failed",h.path,p)}for(let{folder:h}of s)try{let p=await this.importFolder(h);p&&p.kind==="folder"&&(A.push(p),this.plugin.importLog.append({ts:new Date().toISOString(),folder:p.folder,kind:"folder",originalName:p.originalName,size:null,sourcePath:h.path,notePaths:p.notePaths}))}catch(p){console.warn("[Stashpad] folder import failed",h.path,p)}(A.length>0||l.length>0)&&this.announce(A,l)}finally{this.draining=!1}}}async importMarkdown(r){let e=r.parent.path.replace(/\/+$/,""),t=await this.app.vault.read(r),{fm:i,body:s}=ge(t),n=this.importedOriginalsDir(e);await this.ensureFolder(n);let o=await this.uniquePath(n,r.name);if(await this.app.fileManager.renameFile(r,o),!(this.app.vault.getAbstractFileByPath(o)instanceof ne.TFile))throw new Error(`archive move failed for ${r.path} \u2014 import aborted to avoid data loss`);let a={};for(let[h,p]of Object.entries(i))et.includes(h)||(a[h]=p);a.id=this.plugin.mintNoteId(),a.parent=S;let l=this.preservedTimes(i,r);a.created=l.created,l.modified&&(a.modified=l.modified),a.attachments=Array.isArray(i.attachments)?i.attachments:[],i.author!==void 0&&(a.author=i.author),i.contributors!==void 0&&(a.contributors=i.contributors),a.imported=!0;let c=xe(s)||r.basename,A=await this.uniquePath(e,Ne(c,a.id));return await this.createNote(A,Ot(a,s)),{kind:"md",folder:e,archivePath:o,notePath:A,originalName:r.name}}async importOtherFile(r){let e=r.parent.path.replace(/\/+$/,""),t=`${e}/_attachments`;await this.ensureFolder(t);let i=await this.uniquePath(t,r.name);await this.app.fileManager.renameFile(r,i);let s=r.basename,n=this.plugin.mintNoteId(),o={id:n,parent:S,created:new Date().toISOString(),attachments:[tt(i)],imported:!0},a=`${s} +Markdown becomes notes (originals archived); other files move to _attachments with a linking note. Dropped folders move to _archive.`,"Import all")){new ne.Notice(`Import cancelled \u2014 ${o} file(s) left as-is.`);return}}let d=[];for(let h of a)try{let p=h.stat?.size??null,f=h.extension==="md"?await this.importMarkdown(h):await this.importOtherFile(h);f&&(d.push(f),this.plugin.importLog.append({ts:new Date().toISOString(),folder:f.folder,kind:f.kind,originalName:h.name,size:p,sourcePath:h.path,notePaths:f.kind==="folder"?f.notePaths:[f.notePath]}))}catch(p){console.warn("[Stashpad] import failed",h.path,p)}for(let{folder:h}of s)try{let p=await this.importFolder(h);p&&p.kind==="folder"&&(d.push(p),this.plugin.importLog.append({ts:new Date().toISOString(),folder:p.folder,kind:"folder",originalName:p.originalName,size:null,sourcePath:h.path,notePaths:p.notePaths}))}catch(p){console.warn("[Stashpad] folder import failed",h.path,p)}(d.length>0||l.length>0)&&this.announce(d,l)}finally{this.draining=!1}}}async importMarkdown(r){let e=r.parent.path.replace(/\/+$/,""),t=await this.app.vault.read(r),{fm:i,body:s}=ge(t),n=this.importedOriginalsDir(e);await this.ensureFolder(n);let o=await this.uniquePath(n,r.name);if(await this.app.fileManager.renameFile(r,o),!(this.app.vault.getAbstractFileByPath(o)instanceof ne.TFile))throw new Error(`archive move failed for ${r.path} \u2014 import aborted to avoid data loss`);let a={};for(let[h,p]of Object.entries(i))et.includes(h)||(a[h]=p);a.id=this.plugin.mintNoteId(),a.parent=S;let l=this.preservedTimes(i,r);a.created=l.created,l.modified&&(a.modified=l.modified),a.attachments=Array.isArray(i.attachments)?i.attachments:[],i.author!==void 0&&(a.author=i.author),i.contributors!==void 0&&(a.contributors=i.contributors),a.imported=!0;let c=xe(s)||r.basename,d=await this.uniquePath(e,Ne(c,a.id));return await this.createNote(d,Ot(a,s)),{kind:"md",folder:e,archivePath:o,notePath:d,originalName:r.name}}async importOtherFile(r){let e=r.parent.path.replace(/\/+$/,""),t=`${e}/_attachments`;await this.ensureFolder(t);let i=await this.uniquePath(t,r.name);await this.app.fileManager.renameFile(r,i);let s=r.basename,n=this.plugin.mintNoteId(),o={id:n,parent:S,created:new Date().toISOString(),attachments:[tt(i)],imported:!0},a=`${s} ![[${i}]] -`,l=xe(s)||s,c=await this.uniquePath(e,Ne(l,n));return await this.createNote(c,Ot(o,a)),{kind:"file",folder:e,attachmentPath:i,notePath:c,originalName:r.name}}preservedTimes(r,e){let t=n=>typeof n=="string"&&n.trim().length>0&&!Number.isNaN(Date.parse(n)),i=t(r.created)?r.created:e.stat?.ctime?new Date(e.stat.ctime).toISOString():new Date().toISOString(),s=t(r.modified)?r.modified:e.stat?.mtime?new Date(e.stat.mtime).toISOString():null;return{created:i,modified:s}}filesUnder(r){let e=r.replace(/\/+$/,"")+"/";return this.app.vault.getFiles().filter(t=>t.path.startsWith(e))}async importFolder(r){let e=r.parent.path.replace(/\/+$/,""),t=r.name,i=this.importedOriginalsDir(e);await this.ensureFolder(i);let s=await this.uniquePath(i,t);await this.app.fileManager.renameFile(r,s);let n=this.app.vault.getAbstractFileByPath(s),o=new Set;for(let A of this.app.vault.getMarkdownFiles()){if((A.parent?.path?.replace(/\/+$/,"")??"")!==e)continue;let h=this.app.metadataCache.getFileCache(A)?.frontmatter?.id;typeof h=="string"&&h&&o.add(h)}let a=[],l=[],c=await this.createFolderNote(e,t,S,l,o);return n instanceof ne.TFolder&&await this.buildNotesFromArchive(n,e,c,l,o,a),a.length&&new ne.Notice(`Stashpad: ${a.length} attachment name collision(s) renamed on import \u2014 check ![[links]] in the imported notes.`),{kind:"folder",folder:e,archivePath:s,notePaths:l,attachmentPaths:[],originalName:t}}async createFolderNote(r,e,t,i,s){let n=this.plugin.mintNoteId();s.add(n);let o={id:n,parent:t,created:new Date().toISOString(),attachments:[]},a=xe(e)||e,l=await this.uniquePath(r,Ne(a,n));return await this.createNote(l,Ot(o,`${e} -`)),i.push(l),n}async mergeReservedFolder(r,e,t){await this.ensureFolder(e);for(let i of[...r.children])if(i instanceof ne.TFolder)await this.mergeReservedFolder(i,`${e}/${i.name}`,t);else if(i instanceof ne.TFile){let s=`${e}/${i.name}`;await this.app.vault.adapter.exists(s)&&(s=await this.uniquePath(e,i.name),t.push(`${i.name} \u2192 ${s.split("/").pop()}`)),await this.app.fileManager.renameFile(i,s)}}async buildNotesFromArchive(r,e,t,i,s,n){for(let o of[...r.children])if(o instanceof ne.TFolder)if(ao.has(o.name))await this.mergeReservedFolder(o,`${e}/${o.name}`,n);else{let a=await this.createFolderNote(e,o.name,t,i,s);await this.buildNotesFromArchive(o,e,a,i,s,n)}else if(o instanceof ne.TFile)if(o.extension==="md"){let a=await this.app.vault.read(o),{fm:l,body:c}=ge(a),A={};for(let[I,m]of Object.entries(l))et.includes(I)||(A[I]=m);let h=typeof l.id=="string"&&l.id?l.id:null,p=h&&!s.has(h)?h:this.plugin.mintNoteId();s.add(p),A.id=p,A.parent=t;let f=this.preservedTimes(l,o);A.created=f.created,f.modified&&(A.modified=f.modified),A.attachments=Array.isArray(l.attachments)?l.attachments:[];let u=xe(c)||o.basename,g=await this.uniquePath(e,Ne(u,A.id));await this.createNote(g,Ot(A,c)),i.push(g)}else{if(sc.has(o.extension))continue;{let a=this.plugin.mintNoteId(),l={id:a,parent:t,created:new Date().toISOString(),attachments:[tt(o.path)]},c=`${o.basename} +`,l=xe(s)||s,c=await this.uniquePath(e,Ne(l,n));return await this.createNote(c,Ot(o,a)),{kind:"file",folder:e,attachmentPath:i,notePath:c,originalName:r.name}}preservedTimes(r,e){let t=n=>typeof n=="string"&&n.trim().length>0&&!Number.isNaN(Date.parse(n)),i=t(r.created)?r.created:e.stat?.ctime?new Date(e.stat.ctime).toISOString():new Date().toISOString(),s=t(r.modified)?r.modified:e.stat?.mtime?new Date(e.stat.mtime).toISOString():null;return{created:i,modified:s}}filesUnder(r){let e=r.replace(/\/+$/,"")+"/";return this.app.vault.getFiles().filter(t=>t.path.startsWith(e))}async importFolder(r){let e=r.parent.path.replace(/\/+$/,""),t=r.name,i=this.importedOriginalsDir(e);await this.ensureFolder(i);let s=await this.uniquePath(i,t);await this.app.fileManager.renameFile(r,s);let n=this.app.vault.getAbstractFileByPath(s),o=new Set;for(let d of this.app.vault.getMarkdownFiles()){if((d.parent?.path?.replace(/\/+$/,"")??"")!==e)continue;let h=this.app.metadataCache.getFileCache(d)?.frontmatter?.id;typeof h=="string"&&h&&o.add(h)}let a=[],l=[],c=await this.createFolderNote(e,t,S,l,o);return n instanceof ne.TFolder&&await this.buildNotesFromArchive(n,e,c,l,o,a),a.length&&new ne.Notice(`Stashpad: ${a.length} attachment name collision(s) renamed on import \u2014 check ![[links]] in the imported notes.`),{kind:"folder",folder:e,archivePath:s,notePaths:l,attachmentPaths:[],originalName:t}}async createFolderNote(r,e,t,i,s){let n=this.plugin.mintNoteId();s.add(n);let o={id:n,parent:t,created:new Date().toISOString(),attachments:[]},a=xe(e)||e,l=await this.uniquePath(r,Ne(a,n));return await this.createNote(l,Ot(o,`${e} +`)),i.push(l),n}async mergeReservedFolder(r,e,t){await this.ensureFolder(e);for(let i of[...r.children])if(i instanceof ne.TFolder)await this.mergeReservedFolder(i,`${e}/${i.name}`,t);else if(i instanceof ne.TFile){let s=`${e}/${i.name}`;await this.app.vault.adapter.exists(s)&&(s=await this.uniquePath(e,i.name),t.push(`${i.name} \u2192 ${s.split("/").pop()}`)),await this.app.fileManager.renameFile(i,s)}}async buildNotesFromArchive(r,e,t,i,s,n){for(let o of[...r.children])if(o instanceof ne.TFolder)if(lo.has(o.name))await this.mergeReservedFolder(o,`${e}/${o.name}`,n);else{let a=await this.createFolderNote(e,o.name,t,i,s);await this.buildNotesFromArchive(o,e,a,i,s,n)}else if(o instanceof ne.TFile)if(o.extension==="md"){let a=await this.app.vault.read(o),{fm:l,body:c}=ge(a),d={};for(let[I,m]of Object.entries(l))et.includes(I)||(d[I]=m);let h=typeof l.id=="string"&&l.id?l.id:null,p=h&&!s.has(h)?h:this.plugin.mintNoteId();s.add(p),d.id=p,d.parent=t;let f=this.preservedTimes(l,o);d.created=f.created,f.modified&&(d.modified=f.modified),d.attachments=Array.isArray(l.attachments)?l.attachments:[];let u=xe(c)||o.basename,g=await this.uniquePath(e,Ne(u,d.id));await this.createNote(g,Ot(d,c)),i.push(g)}else{if(ac.has(o.extension))continue;{let a=this.plugin.mintNoteId(),l={id:a,parent:t,created:new Date().toISOString(),attachments:[tt(o.path)]},c=`${o.basename} ![[${o.path}]] -`,A=xe(o.basename)||o.basename,h=await this.uniquePath(e,Ne(A,a));await this.createNote(h,Ot(l,c)),i.push(h)}}}recordNotePaths(r){return r.kind==="folder"?r.notePaths:[r.notePath]}announce(r,e=[]){let t=r[0]?.folder??"",i=r.length,s=e.length?`, replaced ${e.length}`:"",n=!1,o=async()=>{n||(n=!0,await this.undo(r,e))};this.plugin.notifications.show({message:`Imported ${i} file${i===1?"":"s"}${s} into \`${t.split("/").pop()}\`.`,kind:"success",category:"import",duration:0,folder:t,affectedPaths:r.flatMap(a=>this.recordNotePaths(a)),actions:[...t?[{label:"Go to folder",onClick:()=>void this.plugin.activateViewForFolder(t)}]:[],{label:"Undo import",onClick:()=>void o()}]}),t&&this.plugin.getUndoStack(t).push({label:`Import ${i} file${i===1?"":"s"}`,undo:async()=>{await o()},redo:async()=>{}})}async undo(r,e=[]){for(let t of r)try{if(t.kind==="md"){let i=this.app.vault.getAbstractFileByPath(t.notePath);i instanceof ne.TFile&&await this.app.fileManager.trashFile(i);let s=this.app.vault.getAbstractFileByPath(t.archivePath);if(s instanceof ne.TFile){let n=await this.uniquePath(t.folder,t.originalName);this.suppress(n),await this.app.fileManager.renameFile(s,n)}}else if(t.kind==="file"){let i=this.app.vault.getAbstractFileByPath(t.notePath);i instanceof ne.TFile&&await this.app.fileManager.trashFile(i);let s=this.app.vault.getAbstractFileByPath(t.attachmentPath);if(s instanceof ne.TFile){let n=await this.uniquePath(t.folder,t.originalName);this.suppress(n),await this.app.fileManager.renameFile(s,n)}}else{for(let s of t.notePaths){let n=this.app.vault.getAbstractFileByPath(s);n instanceof ne.TFile&&await this.app.fileManager.trashFile(n)}for(let s of t.attachmentPaths){let n=this.app.vault.getAbstractFileByPath(s);n instanceof ne.TFile&&await this.app.fileManager.trashFile(n)}let i=this.app.vault.getAbstractFileByPath(t.archivePath);if(i instanceof ne.TFolder){let s=await this.uniquePath(t.folder,t.originalName);this.suppress(s),await this.app.fileManager.renameFile(i,s)}}}catch(i){console.warn("[Stashpad] import undo failed",t,i)}for(let t of e)try{await this.app.vault.adapter.exists(t.path)||await this.app.vault.create(t.path,t.content)}catch(i){console.warn("[Stashpad] import undo: couldn't restore replaced note",t.path,i)}new ne.Notice(`Undid import of ${r.length} file(s).`)}pickFilesInto(r){let e=document.createElement("input");e.type="file",e.multiple=!0,e.setCssStyles({display:"none"}),e.onchange=async()=>{let t=Array.from(e.files??[]);if(e.remove(),t.length===0)return;let i=[];for(let n of t)try{let o=await n.arrayBuffer(),a=await this.uniquePath(r,n.name);this.suppress(a,6e4),await this.app.vault.createBinary(a,o);let l=this.app.vault.getAbstractFileByPath(a);l instanceof ne.TFile&&i.push(l)}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(e),e.click()}async importLooseFilesIn(r){let e=r.replace(/\/+$/,""),t=this.app.vault.getFiles().filter(n=>(n.parent?.path?.replace(/\/+$/,"")??"")===e),i=[];for(let n of t)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(r){let e=r.replace(/\/+$/,""),t=this.app.vault.getAbstractFileByPath(e);if(!(t instanceof ne.TFolder))return 0;let i=t.children.filter(n=>n instanceof ne.TFolder&&!ao.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 r of[...this.pendingEncryptedStashes])this.app.vault.getAbstractFileByPath(r)instanceof ne.TFile||this.pendingEncryptedStashes.delete(r);return[...this.pendingEncryptedStashes]}clearPendingEncrypted(r){this.pendingEncryptedStashes.delete(r)}shouldNotifyEncrypted(){return Date.now()>=this.encryptedNotifySnoozeUntil}snoozeEncryptedNotify(r){this.encryptedNotifySnoozeUntil=r===1/0?Number.MAX_SAFE_INTEGER:Date.now()+r}parkEncrypted(r){return this.pendingEncryptedStashes.has(r)?!1:(this.pendingEncryptedStashes.add(r),this.encryptedNotifySnoozeUntil=0,!0)}async importPendingEncrypted(){let r=0,e=!1;for(let t of this.pendingEncryptedPaths()){let i=this.app.vault.getAbstractFileByPath(t);if(!(i instanceof ne.TFile))continue;let s=i.parent?.path?.replace(/\/+$/,"")??"";if(await this.importOneStash(i,s,this.liveRootIds(s),!1,{allowLater:!0,onLater:()=>{e=!0,this.snoozeEncryptedNotify(60*60*1e3)}})&&r++,e)break}return{imported:r,rescheduled:e}}liveRootIds(r){let e=new Set;for(let t of this.app.vault.getMarkdownFiles()){if((t.parent?.path?.replace(/\/+$/,"")??"")!==r)continue;let i=this.app.metadataCache.getFileCache(t)?.frontmatter?.id;typeof i=="string"&&i&&e.add(i)}return e}async importOneStash(r,e,t,i,s={}){try{let n=new Uint8Array(await this.app.vault.readBinary(r));if(i&&Ue(n))return this.pendingEncryptedStashes.add(r.path),!1;let o=await yi(this.app,n,{...s,secretId:pi(r.basename)});if(!o)return!1;let a=await We(this.app,o,e,t,{stripReserved:!0});if(a.colorAliases)for(let[l,c]of Object.entries(a.colorAliases))try{await this.plugin.setColorAlias(e,l,c)}catch{}try{await this.app.fileManager.trashFile(r)}catch{}this.pendingEncryptedStashes.delete(r.path);try{await this.plugin.newLog().append({type:"stash_import",id:S,payload:{from:r.path,into:e,noteCount:a.notesWritten,attachmentsWritten:a.attachmentsWritten,collisionsRenamed:a.collisionsRenamed,loose:!0}})}catch{}return!0}catch(n){return console.warn("[Stashpad] loose .stash import failed",r.path,n),!1}}async importLooseStashesIn(r,e={}){let t=r.replace(/\/+$/,""),i=this.app.vault.getFiles().filter(o=>(o.parent?.path?.replace(/\/+$/,"")??"")===t&&o.extension===ct);if(i.length===0)return 0;let s=this.liveRootIds(t),n=0;for(let o of i)await this.importOneStash(o,t,s,!!e.auto)&&n++;return n}async importLooseInto(r,e={}){let t=await this.importLooseFilesIn(r),i=await this.importLooseFoldersIn(r),s=await this.importLooseStashesIn(r,e);return{files:t,folders:i,stashes:s}}defaultDestination(){let e=this.plugin.lastActiveStashpadLeaf?.view?.noteFolder;return e&&this.plugin.discoverStashpadFolders().includes(e)?e:this.plugin.discoverStashpadFolders()[0]??null}confirm(r,e,t){return new Promise(i=>{new j(this.app,r,e,t,i).open()})}dupChoice(r){return new Promise(e=>{new us(this.app,r,e).open()})}async ensureFolder(r){let e=this.app.vault.adapter,t=r.split("/").filter(Boolean),i="";for(let s of t){i=i?`${i}/${s}`:s;try{await e.exists(i)||await e.mkdir(i)}catch(n){if(!/already exists/i.test(n.message))throw n}}}async uniquePath(r,e){let t=this.app.vault.adapter,i=e.lastIndexOf("."),s=i>0?e.slice(0,i):e,n=i>0?e.slice(i):"",o=`${r}/${e}`,a=0;for(;await t.exists(o);)a+=1,o=`${r}/${s}-${a}${n}`;return o}};qi.DEBOUNCE_MS=900,qi.BATCH_CONFIRM_AT=8;var ro=qi;var Rs=class Rs{constructor(r,e){this.app=r;this.entries=[];this.loaded=!1;this.dirOk=!1;this.writeChain=Promise.resolve();this.path=`${e.replace(/\/+$/,"")}/import-log.jsonl`}getPath(){return this.path}async load(){if(!this.loaded){this.loaded=!0;try{let r=this.app.vault.adapter;if(await r.exists(this.path)){let e=await r.read(this.path);for(let t of e.split(/\r?\n/))if(t.trim())try{this.entries.push(JSON.parse(t))}catch{}}}catch(r){console.warn("[Stashpad] import log load failed",r)}}}recent(){return[...this.entries].reverse()}findDuplicate(r,e){for(let t=this.entries.length-1;t>=0;t--){let i=this.entries[t];if(i.originalName===r&&(e==null||i.size==null||i.size===e))return i}return null}append(r){this.entries.push(r);let e=this.entries.length>Rs.MAX_ENTRIES;e&&(this.entries=this.entries.slice(-Rs.MAX_ENTRIES)),this.writeChain=this.writeChain.then(async()=>{try{if(await this.ensureDir(),e){let t=this.entries.map(i=>JSON.stringify(i)).join(` +`,d=xe(o.basename)||o.basename,h=await this.uniquePath(e,Ne(d,a));await this.createNote(h,Ot(l,c)),i.push(h)}}}recordNotePaths(r){return r.kind==="folder"?r.notePaths:[r.notePath]}announce(r,e=[]){let t=r[0]?.folder??"",i=r.length,s=e.length?`, replaced ${e.length}`:"",n=!1,o=async()=>{n||(n=!0,await this.undo(r,e))};this.plugin.notifications.show({message:`Imported ${i} file${i===1?"":"s"}${s} into \`${t.split("/").pop()}\`.`,kind:"success",category:"import",duration:0,folder:t,affectedPaths:r.flatMap(a=>this.recordNotePaths(a)),actions:[...t?[{label:"Go to folder",onClick:()=>void this.plugin.activateViewForFolder(t)}]:[],{label:"Undo import",onClick:()=>void o()}]}),t&&this.plugin.getUndoStack(t).push({label:`Import ${i} file${i===1?"":"s"}`,undo:async()=>{await o()},redo:async()=>{}})}async undo(r,e=[]){for(let t of r)try{if(t.kind==="md"){let i=this.app.vault.getAbstractFileByPath(t.notePath);i instanceof ne.TFile&&await this.app.fileManager.trashFile(i);let s=this.app.vault.getAbstractFileByPath(t.archivePath);if(s instanceof ne.TFile){let n=await this.uniquePath(t.folder,t.originalName);this.suppress(n),await this.app.fileManager.renameFile(s,n)}}else if(t.kind==="file"){let i=this.app.vault.getAbstractFileByPath(t.notePath);i instanceof ne.TFile&&await this.app.fileManager.trashFile(i);let s=this.app.vault.getAbstractFileByPath(t.attachmentPath);if(s instanceof ne.TFile){let n=await this.uniquePath(t.folder,t.originalName);this.suppress(n),await this.app.fileManager.renameFile(s,n)}}else{for(let s of t.notePaths){let n=this.app.vault.getAbstractFileByPath(s);n instanceof ne.TFile&&await this.app.fileManager.trashFile(n)}for(let s of t.attachmentPaths){let n=this.app.vault.getAbstractFileByPath(s);n instanceof ne.TFile&&await this.app.fileManager.trashFile(n)}let i=this.app.vault.getAbstractFileByPath(t.archivePath);if(i instanceof ne.TFolder){let s=await this.uniquePath(t.folder,t.originalName);this.suppress(s),await this.app.fileManager.renameFile(i,s)}}}catch(i){console.warn("[Stashpad] import undo failed",t,i)}for(let t of e)try{await this.app.vault.adapter.exists(t.path)||await this.app.vault.create(t.path,t.content)}catch(i){console.warn("[Stashpad] import undo: couldn't restore replaced note",t.path,i)}new ne.Notice(`Undid import of ${r.length} file(s).`)}pickFilesInto(r){let e=document.createElement("input");e.type="file",e.multiple=!0,e.setCssStyles({display:"none"}),e.onchange=async()=>{let t=Array.from(e.files??[]);if(e.remove(),t.length===0)return;let i=[];for(let n of t)try{let o=await n.arrayBuffer(),a=await this.uniquePath(r,n.name);this.suppress(a,6e4),await this.app.vault.createBinary(a,o);let l=this.app.vault.getAbstractFileByPath(a);l instanceof ne.TFile&&i.push(l)}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(e),e.click()}async importLooseFilesIn(r){let e=r.replace(/\/+$/,""),t=this.app.vault.getFiles().filter(n=>(n.parent?.path?.replace(/\/+$/,"")??"")===e),i=[];for(let n of t)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(r){let e=r.replace(/\/+$/,""),t=this.app.vault.getAbstractFileByPath(e);if(!(t instanceof ne.TFolder))return 0;let i=t.children.filter(n=>n instanceof ne.TFolder&&!lo.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 r of[...this.pendingEncryptedStashes])this.app.vault.getAbstractFileByPath(r)instanceof ne.TFile||this.pendingEncryptedStashes.delete(r);return[...this.pendingEncryptedStashes]}clearPendingEncrypted(r){this.pendingEncryptedStashes.delete(r)}shouldNotifyEncrypted(){return Date.now()>=this.encryptedNotifySnoozeUntil}snoozeEncryptedNotify(r){this.encryptedNotifySnoozeUntil=r===1/0?Number.MAX_SAFE_INTEGER:Date.now()+r}parkEncrypted(r){return this.pendingEncryptedStashes.has(r)?!1:(this.pendingEncryptedStashes.add(r),this.encryptedNotifySnoozeUntil=0,!0)}async importPendingEncrypted(){let r=0,e=!1;for(let t of this.pendingEncryptedPaths()){let i=this.app.vault.getAbstractFileByPath(t);if(!(i instanceof ne.TFile))continue;let s=i.parent?.path?.replace(/\/+$/,"")??"";if(await this.importOneStash(i,s,this.liveRootIds(s),!1,{allowLater:!0,onLater:()=>{e=!0,this.snoozeEncryptedNotify(60*60*1e3)}})&&r++,e)break}return{imported:r,rescheduled:e}}liveRootIds(r){let e=new Set;for(let t of this.app.vault.getMarkdownFiles()){if((t.parent?.path?.replace(/\/+$/,"")??"")!==r)continue;let i=this.app.metadataCache.getFileCache(t)?.frontmatter?.id;typeof i=="string"&&i&&e.add(i)}return e}async importOneStash(r,e,t,i,s={}){try{let n=new Uint8Array(await this.app.vault.readBinary(r));if(i&&Ue(n))return this.pendingEncryptedStashes.add(r.path),!1;let o=await wi(this.app,n,{...s,secretId:gi(r.basename)});if(!o)return!1;let a=await We(this.app,o,e,t,{stripReserved:!0});if(a.colorAliases)for(let[l,c]of Object.entries(a.colorAliases))try{await this.plugin.setColorAlias(e,l,c)}catch{}try{await this.app.fileManager.trashFile(r)}catch{}this.pendingEncryptedStashes.delete(r.path);try{await this.plugin.newLog().append({type:"stash_import",id:S,payload:{from:r.path,into:e,noteCount:a.notesWritten,attachmentsWritten:a.attachmentsWritten,collisionsRenamed:a.collisionsRenamed,loose:!0}})}catch{}return!0}catch(n){return console.warn("[Stashpad] loose .stash import failed",r.path,n),!1}}async importLooseStashesIn(r,e={}){let t=r.replace(/\/+$/,""),i=this.app.vault.getFiles().filter(o=>(o.parent?.path?.replace(/\/+$/,"")??"")===t&&o.extension===ct);if(i.length===0)return 0;let s=this.liveRootIds(t),n=0;for(let o of i)await this.importOneStash(o,t,s,!!e.auto)&&n++;return n}async importLooseInto(r,e={}){let t=await this.importLooseFilesIn(r),i=await this.importLooseFoldersIn(r),s=await this.importLooseStashesIn(r,e);return{files:t,folders:i,stashes:s}}defaultDestination(){let e=this.plugin.lastActiveStashpadLeaf?.view?.noteFolder;return e&&this.plugin.discoverStashpadFolders().includes(e)?e:this.plugin.discoverStashpadFolders()[0]??null}confirm(r,e,t){return new Promise(i=>{new j(this.app,r,e,t,i).open()})}dupChoice(r){return new Promise(e=>{new Is(this.app,r,e).open()})}async ensureFolder(r){let e=this.app.vault.adapter,t=r.split("/").filter(Boolean),i="";for(let s of t){i=i?`${i}/${s}`:s;try{await e.exists(i)||await e.mkdir(i)}catch(n){if(!/already exists/i.test(n.message))throw n}}}async uniquePath(r,e){let t=this.app.vault.adapter,i=e.lastIndexOf("."),s=i>0?e.slice(0,i):e,n=i>0?e.slice(i):"",o=`${r}/${e}`,a=0;for(;await t.exists(o);)a+=1,o=`${r}/${s}-${a}${n}`;return o}};qi.DEBOUNCE_MS=900,qi.BATCH_CONFIRM_AT=8;var co=qi;var Ls=class Ls{constructor(r,e){this.app=r;this.entries=[];this.loaded=!1;this.dirOk=!1;this.writeChain=Promise.resolve();this.path=`${e.replace(/\/+$/,"")}/import-log.jsonl`}getPath(){return this.path}async load(){if(!this.loaded){this.loaded=!0;try{let r=this.app.vault.adapter;if(await r.exists(this.path)){let e=await r.read(this.path);for(let t of e.split(/\r?\n/))if(t.trim())try{this.entries.push(JSON.parse(t))}catch{}}}catch(r){console.warn("[Stashpad] import log load failed",r)}}}recent(){return[...this.entries].reverse()}findDuplicate(r,e){for(let t=this.entries.length-1;t>=0;t--){let i=this.entries[t];if(i.originalName===r&&(e==null||i.size==null||i.size===e))return i}return null}append(r){this.entries.push(r);let e=this.entries.length>Ls.MAX_ENTRIES;e&&(this.entries=this.entries.slice(-Ls.MAX_ENTRIES)),this.writeChain=this.writeChain.then(async()=>{try{if(await this.ensureDir(),e){let t=this.entries.map(i=>JSON.stringify(i)).join(` `);await this.app.vault.adapter.write(this.path,t+` `)}else await this.app.vault.adapter.append(this.path,JSON.stringify(r)+` -`)}catch(t){console.warn("[Stashpad] import log append failed",t)}})}async ensureDir(){if(this.dirOk)return;let r=this.app.vault.adapter,t=this.path.slice(0,this.path.lastIndexOf("/")).split("/").filter(Boolean),i="";for(let s of t)i=i?`${i}/${s}`:s,await r.exists(i)||await r.mkdir(i);this.dirOk=!0}};Rs.MAX_ENTRIES=5e3;var lo=Rs;var Ao=class Ao{constructor(r,e){this.app=r;this.map=new Map;this.loaded=!1;this.dirty=!1;this.saveTimer=null;this.dirOk=!1;this.writeChain=Promise.resolve();this.path=`${e.replace(/\/+$/,"")}/render-cache.json`}async load(){if(!this.loaded){this.loaded=!0;try{let r=this.app.vault.adapter;if(await r.exists(this.path)){let e=JSON.parse(await r.read(this.path));if(e?.schema===1&&e.entries){for(let[t,i]of Object.entries(e.entries))this.map.set(t,i);for(let t of[...this.map.keys()])this.app.vault.getAbstractFileByPath(t)||(this.map.delete(t),this.dirty=!0)}}}catch(r){console.warn("[Stashpad] render cache load failed; starting empty",r),this.map.clear()}}}evict(r){this.map.delete(r)&&(this.dirty=!0,this.save())}get(r){return this.map.get(r)}has(r){return this.map.has(r)}set(r,e){this.map.set(r,e),this.dirty=!0,this.scheduleSave()}scheduleSave(){this.saveTimer==null&&(this.saveTimer=window.setTimeout(()=>{this.saveTimer=null,this.save()},Ao.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 r={schema:1,entries:Object.fromEntries(this.map)};await this.app.vault.adapter.write(this.path,JSON.stringify(r))}catch(r){this.dirty=!0,console.warn("[Stashpad] render cache save failed",r)}}),this.writeChain):this.writeChain}async ensureDir(){if(this.dirOk)return;let r=this.app.vault.adapter,t=this.path.slice(0,this.path.lastIndexOf("/")).split("/").filter(Boolean),i="";for(let s of t)i=i?`${i}/${s}`:s,await r.exists(i)||await r.mkdir(i);this.dirOk=!0}};Ao.SAVE_DEBOUNCE_MS=8e3;var co=Ao;var Pa="stashpad:unghost-after-reload",Ha=class extends N.FuzzySuggestModal{constructor(e,t,i){super(e);this.notes=t;this.onChoose=i;this.setPlaceholder("Multiple notes attach this file \u2014 pick one to open")}getItems(){return this.notes}getItemText(e){let i=(this.app.metadataCache.getFileCache(e)?.headings?.[0]?.heading||e.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ")).trim(),s=e.parent?.path??"";return s?`${i} \u2014 ${s}`:i}onChooseItem(e){this.onChoose(e)}},Ft=class Ft extends N.Plugin{constructor(){super(...arguments);this.settings={...Mt};this.reEncryptScheduler=null;this.usedNoteIds=null;this.debugBuffer=[];this.undoStacks=new Map;this.lastActiveStashpadLeaf=null;this.rebootstrapInProgress=!1;this.pendingEncBlobs=new Set;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.noteClipboard=null;this.noteClipboardNotice=null;this._renderCacheStore=null;this.knownStashpadFolders=new Set;this.suppressedFolderDeletes=new Set;this.sweptFolders=new Set;this.notifiedBuildVersion=null;this.authorRenameInFlight=new Set;this.reHomePending=new Set;this.archiveMigrationInFlight=!1;this.okfRebuildTimers=new Map;this.okfRebuildingFolders=new Set;this.archivePending=new Map;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.ACTIVE_VERSIONS_LS_KEY="stashpad:active-versions";this.pendingForkDeletes=new Set;this.writeChain=Promise.resolve();this.lastSeenSettingsRev=0;this.settingsBaseline={};this.externalReloadDebounced=(0,N.debounce)(()=>void this.onExternalDataJsonChange(),600,!1)}trace(e,t){if(!this.settings.debugTrace)return;let i="";if(t)try{i=" "+JSON.stringify(t)}catch{i=" [unserializable]"}let s=Math.round(performance.now());this.debugBuffer.push(`+${s}ms ${e}${i}`),this.debugBuffer.length>Ft.DEBUG_BUFFER_MAX&&this.debugBuffer.splice(0,this.debugBuffer.length-Ft.DEBUG_BUFFER_MAX)}getDebugTrace(){return this.debugBuffer.join(` -`)}clearDebugTrace(){this.debugBuffer=[]}get notifications(){return this._notifications||(this._notifications=new _s(this.app)),this._notifications}get authorRegistry(){return this._authorRegistry||(this._authorRegistry=new oo(this.app,this.pluginPrivatePath())),this._authorRegistry}get importService(){return this._importService||(this._importService=new ro(this)),this._importService}get importLog(){return this._importLog||(this._importLog=new lo(this.app,this.pluginPrivatePath())),this._importLog}clearNoteClipboard(){try{this.noteClipboardNotice?.hide()}catch{}this.noteClipboardNotice=null,this.noteClipboard=null}get renderCacheStore(){return this._renderCacheStore||(this._renderCacheStore=new co(this.app,this.pluginPrivatePath())),this._renderCacheStore}async onunload(){try{this.encryption?.dispose()}catch{}try{for(let e of this.archivePending.values())window.clearTimeout(e.timer);this.archivePending.clear()}catch{}try{this.reEncryptScheduler?.dispose()}catch{}try{await this._renderCacheStore?.save()}catch{}}pluginPrivatePath(e=""){let i=`${this.manifest.dir.replace(/\/+$/,"")}/.stashpad`;return e?`${i}/${e.replace(/^\/+/,"")}`:i}newLog(){return new so(this.app,this.pluginPrivatePath(),()=>(this.settings?.authorName??"").trim())}async migrateLegacyPaths(){let e=this.app.vault.adapter,t=this.pluginPrivatePath(),i=async()=>{let a=t.split("/").filter(Boolean),l="";for(let c of a)l=l?`${l}/${c}`:c,await e.exists(l)||await e.mkdir(l)},s=`${this.manifest.dir.replace(/\/+$/,"")}/data.json`,n=this.pluginPrivatePath("data.json");if(await e.exists(n))try{let a=await e.read(n);await e.write(s,a),await e.write(`${n}.bak`,a),await e.remove(n),console.debug("[Stashpad] relocated data.json \u2192 standard path (for Obsidian Sync)")}catch(a){console.warn("Stashpad: data.json relocation failed",a)}let o=".stashpad";if(await e.exists(o))try{await i();let a=await e.list(o);for(let l of a.files){let c=l.replace(/^.*\//,""),A=this.pluginPrivatePath(c);if(!await e.exists(A))try{let h=await e.read(l);await e.write(A,h),console.debug("[Stashpad] migrated",l,"\u2192",A)}catch(h){console.warn(`Stashpad: failed to migrate ${l}`,h)}}}catch(a){console.warn("Stashpad: .stashpad migration scan failed",a)}}async createNewStashpad(e){let t=e.trim().replace(/^\/+|\/+$/g,"");if(!t)throw new Error("Folder name is empty");let i=this.app.vault.adapter,s=t.split("/").filter(Boolean),n="";for(let c of s)n=n?`${n}/${c}`:c,await i.exists(n)||await i.mkdir(n);let o=`${t}/Home.md`;if(await i.exists(o)){let c=this.app.vault.getAbstractFileByPath(o);c&&await this.app.fileManager.processFrontMatter(c,A=>{(typeof A.id!="string"||!A.id)&&(A.id=S),"parent"in A||(A.parent=null),(typeof A.created!="string"||!A.created)&&(A.created=new Date().toISOString())});return}let a=new Date().toISOString(),l=["---",`id: ${S}`,"parent: null",`created: ${a}`,"---","Home"].join(` -`);await this.app.vault.create(o,l);try{await this.seedLocalAuthorStub(t)}catch{}try{await this.seedKnownAuthorsInFolder(t)}catch{}}collectColorsInFolder(e){let t=new Map,i=e.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,l=typeof a?.color=="string"?a.color.trim():"";if(!l||!/^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(l))continue;let c=l.toLowerCase();t.set(c,(t.get(c)??0)+1)}let s=[...t.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(e,t,i){let s=e.replace(/\/+$/,""),n=t.toLowerCase(),o=0;for(let l of this.app.vault.getMarkdownFiles()){let c=l.parent?.path?.replace(/\/+$/,"")??"";if(c!==s&&!c.startsWith(s+"/"))continue;let A=this.app.metadataCache.getFileCache(l)?.frontmatter;if((typeof A?.color=="string"?A.color.trim().toLowerCase():"")===n)try{await this.app.fileManager.processFrontMatter(l,p=>{i?p.color=i:delete p.color}),o++}catch(p){console.warn(`Stashpad: recolor failed for ${l.path}`,p)}}let a=this.settings.colorAliases?.[s];if(a){let l=a[n];l&&(delete a[n],i&&(a[i.toLowerCase()]=l),Object.keys(a).length===0&&delete this.settings.colorAliases[s],await this.saveSettings())}return o}getColorAlias(e,t){let i=e.replace(/\/+$/,""),s=this.settings.colorAliases?.[i];if(!s)return;let n=s[t.toLowerCase()];return n&&n.trim()?n:void 0}async setColorAlias(e,t,i){let s=e.replace(/\/+$/,""),n=t.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(e,t=2e3){let i=e.trim().replace(/^\/+|\/+$/g,"");if(!i)return;let s=Date.now();for(;Date.now()-s<t;){if(this.discoverStashpadFolders().includes(i))return;await new Promise(n=>setTimeout(n,80))}}importExcludePrefixList(){return(this.settings.importExcludePrefixes??"_").split(",").map(e=>e.trim()).filter(Boolean)}pathHasExcludedSegment(e){let t=this.importExcludePrefixList();return t.length?e.replace(/\/+$/,"").split("/").some(i=>t.some(s=>i.startsWith(s))):!1}discoverStashpadFolders(){let e=new Set;for(let i of this.app.vault.getMarkdownFiles()){let s=this.app.metadataCache.getFileCache(i)?.frontmatter;if(typeof s?.id!="string"||!s.id.trim()||!s||!("parent"in s))continue;let n=i.parent?.path?.replace(/\/+$/,"")??"";n&&!this.pathHasExcludedSegment(n)&&!qt(n)&&e.add(n)}let t=[...e].sort((i,s)=>i.localeCompare(s,void 0,{sensitivity:"base"})||(i<s?-1:i>s?1:0));return this.knownStashpadFolders=new Set(t),t}closeStashpadTabsFor(e){let t=0;for(let i of this.app.workspace.getLeavesOfType(z)){let s=i.view?.noteFolder??"";s||(s=((i.getViewState?.()?.state??{}).folderOverride??"")||this.settings.folder||"Stashpad"),s=(s||"").replace(/\/+$/,""),(s===e||s.startsWith(e+"/"))&&(i.detach(),t++)}return t}retargetStashpadViewsForFolderRename(e,t){let i=(e||"").replace(/\/+$/,""),s=(t||"").replace(/\/+$/,"");if(!i||i===s)return;let n=o=>{let a=(o??"").replace(/\/+$/,"");return a===i?s:a.startsWith(i+"/")?s+a.slice(i.length):null};for(let o of this.app.workspace.getLeavesOfType(z)){let a=o.getViewState(),l=a.state??{},c=o.isDeferred?void 0:o.view?.noteFolder,A=n(c??l.folderOverride);A&&o.setViewState({...a,state:{...a.state??{},folderOverride:A}})}}async remapFolderPathInSettings(e,t){let i=e.replace(/\/+$/,""),s=t.replace(/\/+$/,"");if(!i||!s||i===s)return;let n=this.settings,o=h=>h===i?s:h.startsWith(i+"/")?s+h.slice(i.length):h,a=h=>h&&h.map(o),l=h=>{if(!h)return h;let p={};for(let[f,u]of Object.entries(h))p[o(f)]=u;return p},c=JSON.stringify([n.folderPanelPinned,n.folderPanelDownranked,n.folderPanelHidden,n.archiveFolders,n.searchIncludedFolders,n.searchExcludedFolders,n.defaultArchiveFolder,n.folder,n.folderEncPrefs,n.viewModes,n.encryptionFilter]);n.folderPanelPinned=a(n.folderPanelPinned)??n.folderPanelPinned,n.folderPanelDownranked=a(n.folderPanelDownranked)??n.folderPanelDownranked,n.folderPanelHidden=a(n.folderPanelHidden)??n.folderPanelHidden,n.archiveFolders=a(n.archiveFolders)??n.archiveFolders,n.searchIncludedFolders=a(n.searchIncludedFolders)??n.searchIncludedFolders,n.searchExcludedFolders=a(n.searchExcludedFolders)??n.searchExcludedFolders,n.defaultArchiveFolder&&(n.defaultArchiveFolder=o(n.defaultArchiveFolder)),((n.folder||"").replace(/\/+$/,"")===i||(n.folder||"").startsWith(i+"/"))&&(n.folder=o((n.folder||"").replace(/\/+$/,""))),n.folderEncPrefs=l(n.folderEncPrefs)??n.folderEncPrefs,n.viewModes=l(n.viewModes)??n.viewModes,n.encryptionFilter&&(n.encryptionFilter=l(n.encryptionFilter)),JSON.stringify([n.folderPanelPinned,n.folderPanelDownranked,n.folderPanelHidden,n.archiveFolders,n.searchIncludedFolders,n.searchExcludedFolders,n.defaultArchiveFolder,n.folder,n.folderEncPrefs,n.viewModes,n.encryptionFilter])!==c&&await this.saveSettings()}async prunePlacementFor(e){let t=this.settings,i=o=>(o??[]).filter(a=>a!==e&&!a.startsWith(e+"/")),s=(t.folderPanelPinned?.length??0)+(t.folderPanelDownranked?.length??0)+(t.folderPanelHidden?.length??0);t.folderPanelPinned=i(t.folderPanelPinned),t.folderPanelDownranked=i(t.folderPanelDownranked),t.folderPanelHidden=i(t.folderPanelHidden),t.folderPanelPinned.length+t.folderPanelDownranked.length+t.folderPanelHidden.length!==s&&await this.saveSettings()}async deleteStashpadFolderWithUndo(e){let t=e.path.replace(/\/+$/,""),i=e.name,s=this.app.vault.adapter,n=".trash";try{await s.exists(n)||await s.mkdir(n)}catch(c){console.warn("[Stashpad] couldn't ensure .trash",c)}let o=`${n}/${i}`;for(let c=1;await s.exists(o);c++)o=`${n}/${i} (${c})`;this.suppressedFolderDeletes.add(t),window.setTimeout(()=>this.suppressedFolderDeletes.delete(t),5e3);let a=this.closeStashpadTabsFor(t);await this.prunePlacementFor(t),this.knownStashpadFolders.delete(t);try{await s.rename(t,o)}catch(c){console.warn("[Stashpad] folder delete failed",c),this.suppressedFolderDeletes.delete(t),new N.Notice("Delete failed (see console).");return}let l=a>0?`Deleted \u201C${i}\u201D \u2014 closed ${a} open tab${a===1?"":"s"}.`:`Deleted \u201C${i}\u201D.`;this.notifications.show({message:l,kind:"warning",category:"delete",duration:0,folder:t,actions:[{label:"Undo",onClick:async()=>{try{if(await s.exists(t)){new N.Notice(`Can't undo \u2014 \u201C${i}\u201D already exists.`);return}this.suppressedFolderDeletes.add(t),window.setTimeout(()=>this.suppressedFolderDeletes.delete(t),5e3),await s.rename(o,t),new N.Notice(`Restored \u201C${i}\u201D.`),this.activateViewForFolder(t)}catch(c){console.warn("[Stashpad] folder undo failed",c),new N.Notice("Undo failed (see console).")}}}]})}async handleStashpadFolderDeleted(e){let t=e.replace(/\/+$/,"");if(!t||this.suppressedFolderDeletes.has(t))return;let i=this.closeStashpadTabsFor(t);await this.prunePlacementFor(t),this.knownStashpadFolders.delete(t);let s=t.split("/").pop()||t;this.notifications.show({message:i>0?`Stashpad \u201C${s}\u201D was deleted \u2014 closed ${i} open tab${i===1?"":"s"}.`:`Stashpad \u201C${s}\u201D was deleted.`,kind:"warning",category:"delete",folder:t})}searchableFolders(e){let t=new Set(this.settings.searchIncludedFolders),i=new Set(this.settings.searchExcludedFolders),s=new Set((this.settings.archiveFolders??[]).map(c=>(c??"").replace(/\/+$/,""))),o=this.discoverStashpadFolders().filter(c=>s.has(c)?!1:t.size>0?t.has(c):!i.has(c)),a=(e||"").trim().replace(/\/+$/,""),l=o.filter(c=>c!==a);return a&&l.unshift(a),l}async maybeSweepFolder(e){let t=(e||"").trim().replace(/\/+$/,"");!t||this.sweptFolders.has(t)||(this.sweptFolders.add(t),setTimeout(()=>{this.runSweep(t,{silent:!0})},3e3))}async runIntegrityCheckOnFolder(e){let t=(e||"").trim().replace(/\/+$/,"");t&&await this.runSweep(t,{silent:!1})}async runSweep(e,t){try{let i=this.newLog(),s={},n=this.app.vault.getMarkdownFiles().filter(c=>c.path===e||c.path.startsWith(e+"/"));for(let c of n){let A=this.app.metadataCache.getFileCache(c)?.frontmatter,h=typeof A?.id=="string"?A.id.trim():"";if(!h)continue;let p=A&&"parent"in A?A.parent??null:null;s[h]={parent:p,path:c.path}}let o=await i.readState(),a=c=>c===e||c.startsWith(e+"/");if(!t.silent){for(let[c,A]of Object.entries(s)){let h=o[c];h?h.parent!==A.parent?await i.append({type:"parent_change",id:c,payload:{from:h.parent,to:A.parent}}):h.path!==A.path&&await i.append({type:"rename",id:c,payload:{from:h.path,to:A.path}}):await i.append({type:"create",id:c,payload:{path:A.path,parent:A.parent}})}for(let[c,A]of Object.entries(o))!s[c]&&a(A.path)&&await i.append({type:"missing",id:c,payload:{lastPath:A.path}})}let l={};for(let[c,A]of Object.entries(o))a(A.path)||(l[c]=A);for(let[c,A]of Object.entries(s))l[c]=A;await i.writeState(l)}catch(i){console.warn("Stashpad: integrity sweep failed",i)}}getUndoStack(e){let t=this.undoStacks.get(e);return t||(t=new no,this.undoStacks.set(e,t)),t}mintNoteId(){this.usedNoteIds===null&&this.rebuildUsedNoteIds();let e=this.usedNoteIds,t=mo(i=>e.has(i));return e.add(t),t}rebuildUsedNoteIds(){let e=new Set;for(let t of this.app.vault.getMarkdownFiles()){let i=this.app.metadataCache.getFileCache(t)?.frontmatter?.id;typeof i=="string"&&i.trim()&&e.add(i.trim())}this.usedNoteIds=e}async onload(){this.registerEvent(this.app.metadataCache.on("changed",(g,I,m)=>{let C=m?.frontmatter?.id;this.usedNoteIds&&typeof C=="string"&&C.trim()&&this.usedNoteIds.add(C.trim())})),await this.migrateLegacyPaths(),await this.loadSettings(),Te.enabled=!!this.settings.enablePerfProfiling,this.encryption=new rn(this.app,()=>({...ln(),...this.settings.encryption??{}}),async g=>{this.settings.encryption=g,await this.saveSettings()}),this.encryption.init().then(async()=>{try{let g=await this.encryption.migrateKeyfileToStashKeys();g>0&&new N.Notice(`Stashpad: moved ${g} folder key${g===1?"":"s"} to the new per-folder format.`)}catch(g){console.warn("[Stashpad] folder-key migration failed (keyfile still works)",g)}}),this.reEncryptScheduler=new _n(this),this.reEncryptScheduler.start(),this.settingTab=new pn(this.app,this),this.addSettingTab(this.settingTab),await this.renderCacheStore.load(),this.registerEvent(this.app.vault.on("delete",g=>this.renderCacheStore.evict(g.path))),this.registerEvent(this.app.vault.on("rename",(g,I)=>this.renderCacheStore.evict(I)));let e=(0,N.debounce)(()=>void this.flushForkSiblingPrune(),250,!0);this.registerEvent(this.app.vault.on("delete",g=>{g instanceof N.TFile&&g.extension==="md"&&(this.pendingForkDeletes.add(g.basename),e())})),this.registerEvent(this.app.vault.on("create",g=>this.onOkfFileEvent(g.path))),this.registerEvent(this.app.vault.on("delete",g=>this.onOkfFileEvent(g.path))),this.registerEvent(this.app.vault.on("rename",(g,I)=>{this.onOkfFileEvent(g.path),this.onOkfFileEvent(I)})),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.registerEvent(this.app.vault.on("create",g=>{g.path.endsWith(".stashenc")&&this.pendingEncBlobs.delete(g.path)})),this.registerEvent(this.app.vault.on("delete",g=>{g.path.endsWith(".stashenc")&&this.pendingEncBlobs.delete(g.path)})),this.app.workspace.onLayoutReady(()=>{this.reconcileLockedRegistry(),window.setTimeout(async()=>{try{await this.migrateArchiveFoldersToSubfolders()}catch(g){console.error("[Stashpad] archive migration failed",g)}try{await this.migrateDeletedToTrashSubfolders()}catch(g){console.error("[Stashpad] trash migration failed",g)}this.pruneZombieArchiveEntries()},5e3),window.setTimeout(()=>{if(!this.settings.reEncryptNudge)return;let g=this.reEncryptWatching().length;if(g===0)return;let I=new N.Notice("",0);I.noticeEl.createSpan({text:`\u{1F513} ${g} previously-encrypted note${g===1?" is":"s are"} still plaintext. `});let m=I.noticeEl.createEl("button",{text:"Review"});m.onclick=()=>{I.hide(),He(this,"watch")}},8e3),window.setTimeout(()=>void this.checkDueReminders(),6e3),this.registerInterval(window.setInterval(()=>void this.checkDueReminders(),5*60*1e3)),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(z,g=>new Ts(g,this)),this.registerView(Kt,g=>new yn(g,this)),this.registerView(St,g=>new Cn(g,this)),this.registerView(li,g=>new jn(g,this)),this.registerView(ci,g=>new Pn(g,this)),this.registerView(bt,g=>new eo(g,this)),this.registerView(Is,g=>new Si(g)),this.registerObsidianProtocolHandler(ys,g=>{this.handleDeepLink(g)}),this.registerEvent(this.app.workspace.on("active-leaf-change",g=>{g&&g.view.getViewType()===z&&(this.lastActiveStashpadLeaf=g,this.settings.autoOpenDetailPanel&&this.app.workspace.getLeavesOfType(Kt).length===0&&setTimeout(()=>{wn(this.app)},0),this.notifyStashpadSelectionChanged())}));let t=()=>{let g=Bt(),I=!!g&&this.app.workspace.activeLeaf&&this.app.workspace.activeLeaf.view===g,m=!!I&&this.settings.hideMobileToolbarInStashpad;document.body.classList.toggle("stashpad-hide-mobile-toolbar",m),document.body.classList.toggle("stashpad-active",!!I)};this.register(Pr(t)),this.registerEvent(this.app.workspace.on("active-leaf-change",t));let i=g=>{try{let I=Array.from(document.querySelectorAll("style")).filter(m=>(m.textContent??"").includes(".stashpad-"));for(let m of I){let C=m.id||"",B=C?`style[data-stashpad-source="${C}"]`:null;if(B&&g.head.querySelector(B))continue;let E=g.createElement("style");C?E.setAttribute("data-stashpad-source",C):E.setAttribute("data-stashpad-source","anon"),E.textContent=m.textContent??"",g.head.appendChild(E)}}catch(I){console.warn("[Stashpad] inject popout styles failed",I)}};this.registerEvent(this.app.workspace.on("window-open",g=>{let I=g?.doc??g?.win?.document??null;I&&i(I)})),this.registerEvent(this.app.workspace.on("file-menu",(g,I)=>{if(!(I instanceof N.TFolder))return;let m=I.path.replace(/\/+$/,"");g.addItem(B=>B.setTitle("\u{1F512} Encrypt with Stashpad").setIcon("lock").onClick(()=>void this.encryptFolderFromExplorer(m))),I.children?.some(B=>B instanceof N.TFile&&B.extension==="stashenc")&&!this.folderHasStashpadNotes(m)&&g.addItem(B=>B.setTitle("\u{1F513} Decrypt with Stashpad").setIcon("unlock").onClick(()=>void this.decryptFolderFromExplorer(m))),this.discoverStashpadFolders().includes(m)&&g.addItem(B=>{B.setTitle("Open folder in Stashpad").setIcon("layout-list").onClick(()=>void this.openFolderInStashpad(m))})})),this.registerEvent(this.app.workspace.on("file-menu",(g,I)=>{if(!(I instanceof N.TFile)||I.extension==="md")return;let m=this.findStashpadNotesEmbedding(I);m.length!==0&&g.addItem(C=>C.setTitle(m.length>1?"Open in Stashpad\u2026":"Open in Stashpad").setIcon("layout-list").onClick(()=>void this.revealAttachmentInStashpad(I,m)))})),setTimeout(()=>{try{let g=this.app.workspace;typeof g.iterateAllLeaves=="function"&&g.iterateAllLeaves(I=>{let m=I?.view?.containerEl?.ownerDocument;m&&m!==document&&i(m)})}catch{}},200),t(),this.register(()=>document.body.classList.remove("stashpad-hide-mobile-toolbar","stashpad-active"));let s=window.visualViewport,n=()=>{let g=document.querySelector(".mobile-toolbar, .mobile-toolbar-container"),I=g&&g.isConnected?g.offsetHeight:0;document.body.style.setProperty("--stashpad-toolbar-h",`${I}px`);let m=0;s&&(m=Math.max(0,window.innerHeight-s.height-s.offsetTop)),document.body.style.setProperty("--stashpad-vv-bottom-gap",`${m}px`),document.body.classList.toggle("stashpad-keyboard-open",m>100)};n(),s&&(s.addEventListener("resize",n),s.addEventListener("scroll",n),this.register(()=>{s.removeEventListener("resize",n),s.removeEventListener("scroll",n)})),window.addEventListener("resize",n),this.register(()=>window.removeEventListener("resize",n)),requestAnimationFrame(n),setTimeout(n,250),setTimeout(n,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)",()=>{Bn(this.app)}),this.addRibbonIcon("folders","Open Stashpad folder panel (sidebar)",()=>{to(this.app)}),this.addRibbonIcon("panel-right","Open Stashpad detail panel (right sidebar)",()=>{wn(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})}),this.addCommand({id:"stashpad-focus-last-tab",name:"Focus last Stashpad tab",callback:()=>void this.focusLastStashpadTab()}),this.addCommand({id:"stashpad-focus-folder-panel",name:"Focus folder panel",callback:()=>void this.focusFolderPanel()});let a=g=>{let I=Bt();I&&typeof I[g]=="function"&&I[g]()};this.addCommand({id:"stashpad-toggle-split",name:"Toggle split-on-newlines",callback:()=>a("toggleSplit")}),this.addCommand({id:"stashpad-fork-version",name:"Fork as a version (alternate draft in this sheet)",callback:()=>a("cmdForkVersion")}),this.addCommand({id:"stashpad-mark-version-final",name:"Mark version as final (sheet)",callback:()=>a("cmdMarkVersionFinal")}),this.addCommand({id:"stashpad-command-palette",name:"Command palette (Stashpad only)",callback:()=>a("openStashpadCommandPalette")}),this.addCommand({id:"stashpad-lock-selection",name:"Encrypt (lock) selection (notes + children)",callback:()=>a("cmdLockSelection")}),this.addCommand({id:"stashpad-lock-selection-hide-name",name:"Encrypt (lock) selection + hide filename (override folder setting)",callback:()=>a("cmdLockSelectionHideName")}),this.addCommand({id:"stashpad-unlock-all",name:"Decrypt (unlock) locked notes in view",callback:()=>a("cmdUnlockAll")}),this.addCommand({id:"stashpad-unlock-all-vault",name:"Decrypt (unlock) ALL locked notes in the vault",callback:()=>void this.unlockAllInVault()}),this.addCommand({id:"stashpad-copy-notes",name:"Copy notes (note clipboard \u2014 paste to duplicate)",callback:()=>a("cmdCopyNotes")}),this.addCommand({id:"stashpad-cut-notes",name:"Cut notes (paste in list to move, in composer to extract text)",callback:()=>a("cmdCutNotes")}),this.addCommand({id:"stashpad-paste-notes",name:"Paste notes (from the note clipboard)",callback:()=>a("cmdPasteNotes")}),this.addCommand({id:"stashpad-move-to-archive",name:"Move selection to archive",callback:()=>a("cmdMoveToArchive")}),this.addCommand({id:"stashpad-encrypt-delete",name:"Encrypt (lock) & delete selection (to encrypted trash)",callback:()=>a("cmdEncryptDelete")}),this.addCommand({id:"stashpad-delete-unencrypted",name:"Delete selection to Obsidian's trash (unencrypted)",callback:()=>a("cmdDeleteUnencrypted")}),this.addCommand({id:"stashpad-restore-trash",name:"Open aggregated Trash view",callback:()=>this.openEncryptedTrash()}),this.addCommand({id:"stashpad-open-all-encrypted",name:"Open aggregated Encrypted notes view",callback:()=>void He(this,"encrypted")}),this.addCommand({id:"stashpad-open-all-archived",name:"Open aggregated Archived view",callback:()=>void He(this,"archived")}),this.addCommand({id:"stashpad-open-all-tasks",name:"Open aggregated Tasks view",callback:()=>void He(this,"tasks")}),this.addCommand({id:"stashpad-open-watchlist",name:"Open aggregated Previously encrypted view",callback:()=>void He(this,"watch")}),this.addCommand({id:"stashpad-encrypt-applicable",name:"Encrypt (lock) everything applicable (re-encrypt sweep)",callback:()=>void this.encryptEverythingApplicable()}),this.addCommand({id:"stashpad-close-duplicate-tabs",name:"Close duplicate & orphaned Stashpad tabs (tidy up)",callback:()=>void this.closeDuplicateStashpadTabs()}),this.addCommand({id:"stashpad-claim-selected-author",name:"Claim authorship of selected notes",callback:()=>a("claimSelectedAsAuthor")}),this.addCommand({id:"stashpad-claim-folder-author",name:"Claim authorship of all unauthored notes in this folder",callback:()=>a("claimFolderAsAuthor")}),this.addCommand({id:"stashpad-claim-selected-contributor",name:"Claim selected notes (author if unowned, else add me as contributor)",callback:()=>a("claimSelectedWithContributor")}),this.addCommand({id:"stashpad-claim-folder-contributor",name:"Claim all notes in this folder (author if unowned, else add me as contributor)",callback:()=>a("claimFolderWithContributor")}),this.addCommand({id:"stashpad-pick-destination",name:"Pick destination for next note",callback:()=>a("openDestinationPicker")}),this.addCommand({id:"stashpad-search",name:"Search Stashpad notes",callback:()=>a("openSearchModal")}),this.addCommand({id:"stashpad-search-in-parent",name:"Search in current parent",callback:()=>a("openSearchInParentModal")}),this.addCommand({id:"stashpad-move-picker",name:"Move selection (picker)",callback:()=>a("cmdMovePicker")}),this.addCommand({id:"stashpad-merge",name:"Merge selection",callback:()=>a("cmdMerge")}),this.addCommand({id:"stashpad-copy",name:"Copy selection",callback:()=>a("cmdCopy")}),this.addCommand({id:"stashpad-copy-tree",name:"Copy focused subtree",callback:()=>a("cmdCopyTree")}),this.addCommand({id:"stashpad-dismiss-notifications",name:"Dismiss all notifications",callback:()=>{let g=Array.from(document.querySelectorAll(".notice"));for(let I of g)I.parentElement?.removeChild(I);new N.Notice(g.length?`Dismissed ${g.length} notification${g.length===1?"":"s"}.`:"No notifications to dismiss.")}}),this.addCommand({id:"stashpad-resend-reminders",name:"Resend reminders for incomplete due tasks (show my backlog)",callback:()=>void this.resendDueReminders()}),this.addCommand({id:"stashpad-copy-link",name:"Copy Stashpad link (deep link / URL) to note",callback:()=>a("cmdCopyStashpadLink")}),this.addCommand({id:"stashpad-open-link",name:"Open Stashpad link (paste a deep link / URL)",callback:()=>this.openDeepLinkModal()}),this.addCommand({id:"stashpad-copy-outline",name:"Copy as outline (nested embeds)",callback:()=>a("cmdCopyOutline")}),this.addCommand({id:"stashpad-split",name:"Split note\u2026",callback:()=>a("cmdSplit")}),this.addCommand({id:"stashpad-edit-note",name:"Open note in Obsidian editor (new tab)",callback:()=>a("cmdOpenInEditor")}),this.addCommand({id:"stashpad-edit-inapp",name:"Edit note in Stashpad\u2026",callback:()=>a("cmdEdit")}),this.addCommand({id:"stashpad-edit-parent-inapp",name:"Edit parent note in Stashpad\u2026",callback:()=>a("cmdEditParent")}),this.addCommand({id:"stashpad-edit-parent",name:"Edit parent note in new tab",callback:()=>a("cmdOpenParentInEditor")}),this.addCommand({id:"stashpad-delete",name:"Delete selection",callback:()=>a("cmdDelete")}),this.addCommand({id:"stashpad-move-up",name:"Move note up",callback:()=>a("cmdMoveUp")}),this.addCommand({id:"stashpad-move-down",name:"Move note down",callback:()=>a("cmdMoveDown")}),this.addCommand({id:"stashpad-move-to-top",name:"Move note to top",callback:()=>a("cmdMoveToTop")}),this.addCommand({id:"stashpad-move-to-bottom",name:"Move note to bottom",callback:()=>a("cmdMoveToBottom")}),this.addCommand({id:"stashpad-outdent",name:"Outdent (move to grandparent)",callback:()=>a("cmdOutdent")}),this.addCommand({id:"stashpad-set-color",name:"Set note color\u2026",callback:()=>a("cmdSetColor")}),this.addCommand({id:"stashpad-clone",name:"Clone selection (duplicate / copy notes)",callback:()=>a("cmdClone")}),this.addCommand({id:"stashpad-fork-note",name:"Fork into a separate note (copy under a chosen parent)",callback:()=>a("cmdForkNote")}),this.addCommand({id:"stashpad-insert-template",name:"Insert template (clone an existing note)",callback:()=>a("cmdInsertTemplate")}),this.addCommand({id:"stashpad-toggle-expand",name:"Show more / show less (expand toggle)",callback:()=>a("cmdToggleExpand")}),this.addCommand({id:"stashpad-expand-all",name:"Expand all (show every note's full body)",callback:()=>a("cmdExpandAll")}),this.addCommand({id:"stashpad-collapse-all",name:"Collapse all (clamp every note's body)",callback:()=>a("cmdCollapseAll")}),this.addCommand({id:"stashpad-pick-move",name:"Move (in-list, arrow + Enter)",callback:()=>a("cmdInListPicker")}),this.addCommand({id:"stashpad-open-in-new-tab",name:"Open in new Stashpad tab",callback:()=>a("cmdOpenInNewStashpadTab")}),this.addCommand({id:"stashpad-toggle-complete",name:"Toggle complete (strikethrough)",callback:()=>a("cmdToggleComplete")}),this.addCommand({id:"stashpad-toggle-task",name:"Toggle task (todo)",callback:()=>a("cmdToggleTask")}),this.addCommand({id:"stashpad-set-due",name:"Set due date\u2026",callback:()=>a("cmdSetDue")}),this.addCommand({id:"stashpad-dump-perf",name:"Dump performance profile (copy to clipboard)",callback:async()=>{if(!this.settings.enablePerfProfiling){new N.Notice("Enable \u201CPerformance profiling\u201D in Stashpad settings first, then use the app and run this again.");return}let g=Te.report();console.log(g);try{await navigator.clipboard.writeText(g)}catch{}new N.Notice("Performance profile copied to clipboard (also in the console).")}}),this.addCommand({id:"stashpad-reset-perf",name:"Reset performance profile",callback:()=>{Te.reset(),new N.Notice("Performance profile reset.")}}),this.addCommand({id:"stashpad-jump-to-top",name:"Jump to top of list",callback:()=>a("jumpToTop")}),this.addCommand({id:"stashpad-jump-to-bottom",name:"Jump to bottom of list",callback:()=>a("jumpToBottom")}),this.addCommand({id:"stashpad-assign",name:"Assign task to\u2026",callback:()=>a("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(()=>(ve(),ms));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 I=this.importService.defaultDestination();return g?!!I:(I&&this.runImportLooseFiles(I),!0)}}),this.addCommand({id:"stashpad-rerun-slug-pass",name:"Re-run filename (slug) pass on this folder",checkCallback:g=>{let I=this.importService.defaultDestination();return g?!!I:(I&&this.runFolderSlugPass(I),!0)}}),this.addCommand({id:"stashpad-rerun-frontmatter-backfill",name:"Re-run frontmatter backfill (recovery links) on this folder",checkCallback:g=>{let I=this.importService.defaultDestination();return g?!!I:(I&&this.runFolderFrontmatterBackfill(I),!0)}}),this.addCommand({id:"stashpad-select-all",name:"Select all visible notes",callback:()=>a("cmdSelectAll")}),this.addCommand({id:"stashpad-copy-codeblock",name:"Copy code from codeblock",callback:()=>a("cmdCopyCodeBlock")}),this.addCommand({id:"stashpad-open-panels",name:"Open Stashpad panels (sidebar)",callback:()=>void Bn(this.app)}),this.addCommand({id:"stashpad-open-folder-panel",name:"Open folder panel (sidebar)",callback:()=>void to(this.app)}),this.addCommand({id:"stashpad-open-detail",name:"Open Stashpad detail panel (right sidebar)",callback:()=>void wn(this.app)}),this.addCommand({id:"stashpad-reveal-active-note",name:"Open this note in Stashpad",checkCallback:g=>{let I=this.app.workspace.getActiveFile();return I?I.extension==="md"&&this.isStashpadNoteFile(I)?(g||this.revealNoteInStashpad(I),!0):I.extension!=="md"?(g||this.revealAttachmentInStashpad(I),!0):!1:!1}});let l=Object.keys(Bs);for(let g of l){let I=Bs[g];this.addCommand({id:`stashpad-open-panels-${g}`,name:`Open Stashpad panel: ${I.label}`,callback:async()=>{await Bn(this.app),this.app.workspace.getLeavesOfType(St)[0]?.view?.setActivePanel?.(g)}})}this.addCommand({id:"stashpad-task-review",name:"Open daily task review",callback:()=>new Di(this.app,this).open()}),this.addCommand({id:"stashpad-swap-with-parent",name:"Swap with parent (ouroboros)",callback:()=>a("cmdSwapWithParent")}),this.addCommand({id:"stashpad-toggle-pin",name:"Pin / unpin selected note (sidebar)",callback:()=>a("cmdTogglePin")}),this.addCommand({id:"stashpad-list-pin",name:"Pin / unpin to top of list",callback:()=>a("cmdToggleListPin")}),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:()=>a("cmdCloneStashpadTab")}),this.addCommand({id:"stashpad-undo",name:"Undo last Stashpad action",callback:()=>a("cmdUndo")}),this.addCommand({id:"stashpad-redo",name:"Redo last undone Stashpad action",callback:()=>a("cmdRedo")}),this.addCommand({id:"stashpad-export-stash",name:"Export selection (.stash / OKF / plain .zip)\u2026",callback:()=>a("cmdExportStash")}),this.addCommand({id:"stashpad-import-stash",name:"Import .stash file\u2026",callback:()=>a("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 I=Bt(),m=I&&I.noteFolder;return m?(g||(new N.Notice(`Running integrity check on "${m}"\u2026`),this.runIntegrityCheckOnFolder(m).then(()=>{new N.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 N.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 N.Notice(`Author registry rebuild failed: ${g.message}`)}}}),this.addCommand({id:"stashpad-restore-author-stubs",name:"Restore missing author stubs (from registry)",callback:async()=>{new N.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 N.Notice(`Restore author stubs failed: ${g.message}`)}}}),this.addCommand({id:"stashpad-sync-authors",name:"Sync authors across all folders (multiplayer)",callback:()=>void this.syncAuthorsAcrossFolders()}),this.addCommand({id:"stashpad-rebootstrap-all",name:"Rebootstrap all Stashpad folders (backfill metadata + rename stale titles)",callback:()=>{this.runRebootstrapWithUI().catch(()=>{})}}),this.addCommand({id:"stashpad-adopt-note",name:"Adopt active note into Stashpad (fill missing frontmatter)",checkCallback:g=>{let I=this.app.workspace.getActiveFile();return!I||I.extension!=="md"?!1:(g||this.adoptNote(I),!0)}}),this.addCommand({id:"stashpad-open-notification-history",name:"Open notification history",callback:()=>{Promise.resolve().then(()=>(ve(),ms)).then(({NotificationHistoryModal:g,LogModal:I})=>{new g(this.app,this.notifications,async()=>{let m=this.app.vault.adapter,C=this.pluginPrivatePath("log.jsonl");if(!await m.exists(C)){new N.Notice("No log yet \u2014 make some changes first.");return}let B=await m.read(C);new I(this.app,B,C).open()},this.settings.authorId||null,m=>this.lookupNoteAuthorIds(m)).open()})}});let c=[{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 c){let I=`stashpad-toggle-${String(g.key).replace(/[A-Z]/g,m=>`-${m.toLowerCase()}`)}`;this.addCommand({id:I,name:`Toggle: ${g.label}`,callback:async()=>{let m=!this.settings[g.key];this.settings[g.key]=m,await this.saveSettings(),new N.Notice(`${g.label}: ${m?"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(()=>{g?.modalEl?.querySelector?.("input[type='search']")?.focus()},0))}});for(let g of hn)this.addCommand({id:`stashpad-open-settings-${g.id}`,name:`Open Stashpad settings: ${g.label}`,callback:()=>{let I=this.app.setting;!I?.open||!I?.openTabById||(I.open(),I.openTabById(this.manifest.id))}});let A=()=>{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(()=>(es(),Xs)),I=await g(this.app,this,this.settings);if(I.error==="no-dest"){new N.Notice("Set a Designated Stashpad folder for Index in settings first.",6e3),A();return}if(I.error==="no-home"){new N.Notice(`"${this.settings.jdIndexStashpadFolder}" has no Stashpad home note. Open the folder in Stashpad first to create one.`,7e3);return}let{buildJdPreviewNotice:m}=await Promise.resolve().then(()=>(es(),Xs));m(this.app,I)}catch(g){console.error("[stashpad] preview failed",g),new N.Notice(`Preview failed: ${g?.message??g}`,8e3)}}}),this.addCommand({id:"stashpad-decrypt-folder-bundle",name:"Decrypt a folder bundle (encrypted non-Stashpad folder)\u2026",callback:async()=>{if(!this.encryption.isConfigured()){new N.Notice("Stashpad encryption isn't set up.");return}let g=await $l(this.app);if(!g.length){new N.Notice("No encrypted folder bundles found in this vault.");return}new Ua(this.app,g,I=>void this.decryptFolderFromExplorer(I.folder)).open()}}),this.addCommand({id:"stashpad-build-jd-index",name:"Build JD index notes (creates Stashpad-note hierarchy)",callback:async()=>{try{let{buildJdIndexNotes:g,scanForJdNotes:I,JdBuildConfirmModal:m}=await Promise.resolve().then(()=>(es(),Xs));if(!(this.settings.jdIndexStashpadFolder??"").trim().replace(/^\/+|\/+$/g,"")){new N.Notice("Set a Designated Stashpad folder for Index in settings first.",6e3),A();return}let B=I(this.app,this,this.settings);new m(this.app,this,this.settings,B.indexed.length,async()=>{try{let y=await g(this.app,this,this.settings);if(y.error==="no-dest"){new N.Notice("Set a Designated Stashpad folder for Index in settings first.",6e3),A();return}if(y.error==="dest-not-stashpad"){new N.Notice(`"${y.destFolder}" isn't a known Stashpad folder. Pick a real Stashpad folder in settings.`,7e3),A();return}this.settings.jdIndexHasBuilt=!0,await this.saveSettings(),new N.Notice(`Index built: ${y.created} created, ${y.updated} updated, ${y.skipped} skipped \u2192 ${y.destFolder}`,6e3)}catch(y){console.error("[stashpad] build failed",y),new N.Notice(`Build failed: ${y?.message??y}`,8e3)}}).open()}catch(g){console.error("[stashpad] build failed",g),new N.Notice(`Build failed: ${g?.message??g}`,8e3)}}});let h=g=>{if(g.extension!==ct)return;let I=(this.settings.importDropFolder||"").trim().replace(/^\/+|\/+$/g,""),m=(this.settings.exportFolder||"").trim().replace(/^\/+|\/+$/g,""),C=g.parent?.path||"",B=C.split("/").pop()??"";if(I&&B===I){if(m&&C.endsWith(`/${m}`))return;let E=C.slice(0,C.length-I.length).replace(/\/+$/,"")||this.settings.folder;this.autoImportStash(g,E);return}this.settings.autoImport&&this.importService.isArmed()&&(qt(g.path)||this.discoverStashpadFolders().includes(C)&&this.autoImportStash(g,C))};this.registerEvent(this.app.vault.on("create",g=>{g instanceof N.TFile&&h(g)})),this.registerEvent(this.app.vault.on("rename",g=>{g instanceof N.TFile&&h(g)}));let p=g=>{if(g.extension!=="md")return;let I=g.parent?.path?.replace(/\/+$/,"")??"";this.discoverStashpadFolders().includes(I)&&setTimeout(()=>{this.fixOrphanParentForFile(g)},800)},f=g=>{if(g.extension!=="md")return;let I=(this.settings.importDropFolder||"").trim().replace(/^\/+|\/+$/g,"");if(!I)return;let m=g.parent?.path?.replace(/\/+$/,"")??"";if((m.split("/").pop()??"")!==I)return;let B=m.slice(0,m.length-I.length).replace(/\/+$/,"");!B||!this.discoverStashpadFolders().includes(B)||setTimeout(()=>{this.adoptMarkdownDrop(g,B)},200)};this.registerEvent(this.app.vault.on("create",g=>{g instanceof N.TFile&&(p(g),f(g))})),this.registerEvent(this.app.vault.on("rename",g=>{g instanceof N.TFile&&(p(g),f(g))})),this.registerEvent(this.app.vault.on("delete",g=>{if(!(g instanceof N.TFolder))return;let I=g.path.replace(/\/+$/,"");this.knownStashpadFolders.has(I)&&this.handleStashpadFolderDeleted(I)})),this.registerEvent(this.app.vault.on("rename",(g,I)=>{g instanceof N.TFile&&this.maybeReHomeOnCrossFolderMove(g,I)})),this.registerEvent(this.app.vault.on("rename",(g,I)=>{g instanceof N.TFile&&this.maybeArchiveOnMoveIn(g,I)})),this.registerEvent(this.app.vault.on("rename",(g,I)=>{g instanceof N.TFolder&&(this.retargetStashpadViewsForFolderRename(I,g.path),this.remapFolderPathInSettings(I,g.path))}));let u=`${this.manifest.dir.replace(/\/+$/,"")}/data.json`;this.registerEvent(this.app.vault.on("raw",g=>{g===u&&this.scheduleExternalDataJsonReload()})),this.registerEvent(this.app.vault.on("create",g=>{g instanceof N.TFile?this.importService.enqueue(g):g instanceof N.TFolder&&this.importService.enqueueFolder(g)})),this.registerEvent(this.app.vault.on("rename",g=>{g instanceof N.TFile?this.importService.enqueue(g):g instanceof N.TFolder&&this.importService.enqueueFolder(g)})),this.registerEvent(this.app.vault.on("rename",(g,I)=>{g instanceof N.TFile&&this.maybeAdoptAuthorRename(g,I)})),this.registerDomEvent(window,"focus",()=>void this.checkForSyncedBuild()),setTimeout(()=>void this.checkForSyncedBuild(),5e3),this.registerInterval(window.setInterval(()=>void this.checkForSyncedBuild(),45e3))}async checkForSyncedBuild(){try{let e=this.manifest.dir;if(!e)return;let t=`${e.replace(/\/+$/,"")}/manifest.json`,i=this.app.vault.adapter;if(!await i.exists(t))return;let s=JSON.parse(await i.read(t))?.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(e){console.debug("[Stashpad] synced-build check failed",e)}}reloadAppForUpdate(){try{window.localStorage?.setItem(Pa,"1")}catch{}try{if(this.app.commands?.executeCommandById?.("app:reload"))return}catch(e){console.warn("[Stashpad] app:reload command failed",e)}try{window.location.reload()}catch{new N.Notice("Reload Obsidian (close + reopen) to apply the Stashpad update.")}}async unghostStashpadTabsIfFlagged(){let e=!1;try{e=window.localStorage?.getItem(Pa)==="1"}catch{}if(e){try{window.localStorage?.removeItem(Pa)}catch{}for(let t of this.app.workspace.getLeavesOfType(z))try{let i=t;i.isDeferred&&typeof i.loadIfDeferred=="function"&&await i.loadIfDeferred()}catch(i){console.warn("[Stashpad] un-ghost leaf failed",i)}}}isSemverGreater(e,t){let i=e.split(".").map(o=>parseInt(o,10)||0),s=t.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,l=s[o]??0;if(a!==l)return a>l}return!1}parseAuthorFilePath(e){let t=e.match(/\/_authors\/([^/]+?)-([a-z0-9]{4,12})\.md$/i);return t?{name:t[1].replace(/-/g," "),id:t[2]}:null}authorNameToSafe(e){return e.replace(/[^\w\- ]+/g,"").trim().replace(/\s+/g,"-")||"author"}async syncAuthorFilesToName(){let e=(this.settings.authorId??"").trim(),t=(this.settings.authorName??"").trim();if(!e||!t)return;let i=this.authorNameToSafe(t);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!==e)continue;let l=`${n}/${i}-${e}.md`,c=o;if(o.path!==l)try{this.authorRenameInFlight.add(o.path),this.authorRenameInFlight.add(l),await this.app.fileManager.renameFile(o,l);let A=this.app.vault.getAbstractFileByPath(l);A&&(c=A)}catch(A){this.authorRenameInFlight.delete(o.path),this.authorRenameInFlight.delete(l),console.warn("[Stashpad] author file rename failed",A);continue}try{await this.refreshAuthorStub(c)}catch{}}}}async refreshAuthorStub(e){let t=(this.settings.authorName??"").trim(),i=(this.settings.authorRole??"").trim(),s=(this.settings.authorDepartment??"").trim();if(t)try{let n=await this.app.vault.read(e),o=n.replace(/^# .*$/m,`# ${t}`);o!==n&&await this.app.vault.modify(e,o),await this.app.fileManager.processFrontMatter(e,a=>{a.aliases=[t],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(e,t){let i=this.authorRenameInFlight.delete(e.path),s=this.authorRenameInFlight.delete(t);if(i||s)return;let n=this.parseAuthorFilePath(e.path);if(!n)return;let o=(this.settings.authorId??"").trim();if(!o||n.id!==o)return;let a=n.name.trim();!a||a===(this.settings.authorName??"").trim()||(this.settings.authorName=a,await this.saveSettings(),await this.syncAuthorFilesToName())}async adoptMarkdownDrop(e,t){try{let i=this.app.vault.adapter,s=e.name,n=s.lastIndexOf("."),o=n>0?s.slice(0,n):s,a=n>0?s.slice(n):"",l=0;for(;await i.exists(`${t}/${s}`);)l+=1,s=`${o}-${l}${a}`;let c=`${t}/${s}`;await this.app.fileManager.renameFile(e,c);let A=this.app.vault.getAbstractFileByPath(c);A instanceof N.TFile&&setTimeout(()=>{this.fixOrphanParentForFile(A)},500),this.notifications.show({message:`Imported \`${e.name}\` \u2192 \`${t}\``,kind:"success",category:"import",folder:t,affectedPaths:[c]})}catch(i){console.warn("Stashpad: markdown drop adoption failed",i),this.notifications.show({message:`Couldn't import \`${e.name}\`: ${i.message}`,kind:"error",category:"import"})}}async fixOrphanParentForFile(e){try{let t=this.app.metadataCache.getFileCache(e)?.frontmatter,i=typeof t?.id=="string"?t.id.trim():"",s=t?.parent,n=typeof s=="string"?s.trim()!=="":s!=null,o=typeof t?.created=="string"&&t.created.trim()!=="",a=!i,l=!n,c=!o;if(!a&&!l&&!c)return;let A,h=!1,p=!1;if(await this.app.fileManager.processFrontMatter(e,g=>{if(a&&(typeof g.id=="string"&&g.id.trim()||(A=this.mintNoteId(),g.id=A)),l){let I=g.parent;(typeof I=="string"?I.trim()!=="":I!=null)||(g.parent=S,h=!0)}c&&(typeof g.created=="string"&&g.created.trim()||(g.created=new Date(e.stat.ctime).toISOString(),p=!0))}),!A&&!h&&!p)return;let f=this.newLog(),u=A||i;u&&await f.append({type:"parent_change",id:u,payload:{from:null,to:S,reason:"orphan_auto_fix",path:e.path,addedId:!!A,addedParent:h,addedCreated:p}}),new N.Notice(`Adopted ${e.basename} \u2192 Home`)}catch(t){console.warn("Stashpad: orphan auto-fix failed",t)}}maybeReHomeOnCrossFolderMove(e,t){if(e.extension!=="md")return;let i=e.parent?.path?.replace(/\/+$/,"")??"",s=t.lastIndexOf("/"),n=(s>=0?t.slice(0,s):"").replace(/\/+$/,"");i!==n&&this.discoverStashpadFolders().includes(i)&&(this.reHomePending.has(e.path)||(this.reHomePending.add(e.path),setTimeout(()=>{this.reHomePending.delete(e.path),this.reHomeDanglingParent(e,i)},900)))}async reHomeDanglingParent(e,t){try{let i=this.app.metadataCache.getFileCache(e)?.frontmatter,s=typeof i?.id=="string"?i.id.trim():"",n=typeof i?.parent=="string"?i.parent.trim():"";if(!s||!n||n===S||this.app.vault.getMarkdownFiles().some(a=>(a.parent?.path?.replace(/\/+$/,"")??"")===t&&this.app.metadataCache.getFileCache(a)?.frontmatter?.id===n))return;await this.app.fileManager.processFrontMatter(e,a=>{let l=typeof a.parent=="string"?a.parent.trim():"";l&&l!==S&&(a.parent=S)}),await this.newLog().append({type:"parent_change",id:s,payload:{from:n,to:S,reason:"rehome_cross_folder_move",path:e.path}}),new N.Notice(`Re-homed ${e.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(e,t){try{let i=new Uint8Array(await this.app.vault.readBinary(e));if(Ue(i)){this.importService.parkEncrypted(e.path),this.notifyPendingEncrypted();return}let s=await yi(this.app,i);if(!s)return;let n=Bt(),o=new Set;if(n&&typeof n.collectExistingIds=="function"&&n.noteFolder===t)for(let c of n.collectExistingIds())o.add(c);else for(let c of this.app.vault.getMarkdownFiles()){if(!c.path.startsWith(t+"/"))continue;let A=this.app.metadataCache.getFileCache(c)?.frontmatter?.id;typeof A=="string"&&o.add(A)}let a=await We(this.app,s,t,o,{stripReserved:!0});try{await this.newLog().append({type:"stash_import",id:S,payload:{from:e.path,into:t,noteCount:a.notesWritten,attachmentsWritten:a.attachmentsWritten,collisionsRenamed:a.collisionsRenamed,auto:!0}})}catch{}try{await this.app.fileManager.trashFile(e)}catch{}let l=[`Auto-imported ${a.notesWritten} note${a.notesWritten===1?"":"s"} from ${e.name}`];a.attachmentsWritten&&l.push(`+ ${a.attachmentsWritten} attachment${a.attachmentsWritten===1?"":"s"}`),a.collisionsRenamed&&l.push(`(${a.collisionsRenamed} renamed)`),this.notifications.show({message:l.join(" "),kind:"success",category:"import",folder:t}),n&&typeof n.debouncedRender=="function"&&n.debouncedRender()}catch(i){this.notifications.show({message:`Stashpad: auto-import failed +`)}catch(t){console.warn("[Stashpad] import log append failed",t)}})}async ensureDir(){if(this.dirOk)return;let r=this.app.vault.adapter,t=this.path.slice(0,this.path.lastIndexOf("/")).split("/").filter(Boolean),i="";for(let s of t)i=i?`${i}/${s}`:s,await r.exists(i)||await r.mkdir(i);this.dirOk=!0}};Ls.MAX_ENTRIES=5e3;var Ao=Ls;var po=class po{constructor(r,e){this.app=r;this.map=new Map;this.loaded=!1;this.dirty=!1;this.saveTimer=null;this.dirOk=!1;this.writeChain=Promise.resolve();this.path=`${e.replace(/\/+$/,"")}/render-cache.json`}async load(){if(!this.loaded){this.loaded=!0;try{let r=this.app.vault.adapter;if(await r.exists(this.path)){let e=JSON.parse(await r.read(this.path));if(e?.schema===1&&e.entries){for(let[t,i]of Object.entries(e.entries))this.map.set(t,i);for(let t of[...this.map.keys()])this.app.vault.getAbstractFileByPath(t)||(this.map.delete(t),this.dirty=!0)}}}catch(r){console.warn("[Stashpad] render cache load failed; starting empty",r),this.map.clear()}}}evict(r){this.map.delete(r)&&(this.dirty=!0,this.save())}get(r){return this.map.get(r)}has(r){return this.map.has(r)}set(r,e){this.map.set(r,e),this.dirty=!0,this.scheduleSave()}scheduleSave(){this.saveTimer==null&&(this.saveTimer=window.setTimeout(()=>{this.saveTimer=null,this.save()},po.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 r={schema:1,entries:Object.fromEntries(this.map)};await this.app.vault.adapter.write(this.path,JSON.stringify(r))}catch(r){this.dirty=!0,console.warn("[Stashpad] render cache save failed",r)}}),this.writeChain):this.writeChain}async ensureDir(){if(this.dirOk)return;let r=this.app.vault.adapter,t=this.path.slice(0,this.path.lastIndexOf("/")).split("/").filter(Boolean),i="";for(let s of t)i=i?`${i}/${s}`:s,await r.exists(i)||await r.mkdir(i);this.dirOk=!0}};po.SAVE_DEBOUNCE_MS=8e3;var ho=po;var $i={"history.json":["notifiedDueKeys","persistReminderLog","lastSubmitted","drafts"]},ai=Object.values($i).flat(),rc="data.json.pre-split.bak",go=class A{constructor(r){this.plugin=r;this.baseline={};this.revs=new Map}dir(){return this.plugin.manifest.dir??""}pathFor(r){return`${this.dir()}/${r}`}fileNames(){return["data.json",...Object.keys($i)]}watchPaths(){return this.fileNames().map(r=>this.pathFor(r))}async readSplit(r){try{let e=this.pathFor(r),t=this.plugin.app.vault.adapter;if(!await t.exists(e))return null;let i=await t.read(e),s=JSON.parse(i);return s&&typeof s=="object"?s:null}catch{return null}}async writeSplit(r,e,t){let i=JSON.stringify({...e,rev:t},null,2);await this.plugin.app.vault.adapter.write(this.pathFor(r),i)}static pick(r,e){let t={};for(let i of e)r[i]!==void 0&&(t[i]=r[i]);return t}snapshotKeys(r,e){for(let t of e)this.baseline[t]=JSON.stringify(r[t])}async loadAll(){let r=await this.plugin.loadData()??{},e={...r};for(let[i,s]of Object.entries($i)){let n=await this.readSplit(i);if(n){for(let o of s)n[o]!==void 0&&(e[o]=n[o]);this.revs.set(i,typeof n.rev=="number"?n.rev:0)}else this.revs.set(i,0)}return ai.filter(i=>r[i]!==void 0).length&&await this.migrate(r,e),this.snapshotKeys(e,Object.keys(e)),this.revs.set("data.json",typeof e.settingsRev=="number"?e.settingsRev:0),e}async migrate(r,e){let t=this.plugin.app.vault.adapter;try{let i=this.pathFor(rc);await t.exists(i)||await t.write(i,JSON.stringify(r,null,2));for(let[o,a]of Object.entries($i)){let l=A.pick(e,a);Object.keys(l).length!==0&&(await this.writeSplit(o,l,(this.revs.get(o)??0)+1),this.revs.set(o,(this.revs.get(o)??0)+1))}let s={},n=new Set(ai);for(let[o,a]of Object.entries(r))n.has(o)||(s[o]=a);await this.plugin.saveData(s),console.info(`[Stashpad] settings split: moved ${ai.length} keys out of data.json (backup: ${rc}).`)}catch(i){console.error("[Stashpad] settings split migration failed \u2014 continuing on data.json.",i)}}async saveSplit(r){let e={adopted:{},any:!1};for(let[t,i]of Object.entries($i)){let s=i.some(l=>JSON.stringify(r[l])!==this.baseline[l]),n=await this.readSplit(t);if(n){let l=[];for(let d of i){let h=JSON.stringify(r[d]),p=JSON.stringify(n[d]),f=h!==this.baseline[d],u=p!==this.baseline[d];!f&&u&&n[d]!==void 0&&(r[d]=n[d],l.push(d))}l.length&&(e.adopted[t]=l,e.any=!0);let c=typeof n.rev=="number"?n.rev:0;c>(this.revs.get(t)??0)&&this.revs.set(t,c)}if(!s&&!e.adopted[t])continue;let o=A.pick(r,i);if(Object.keys(o).length===0)continue;let a=(this.revs.get(t)??0)+1;await this.writeSplit(t,o,a),this.revs.set(t,a),this.snapshotKeys(r,i)}return e}coreDirty(r){let e=new Set(ai);for(let t of Object.keys(r))if(!(e.has(t)||t==="settingsRev")&&JSON.stringify(r[t])!==this.baseline[t])return!0;return!1}markCoreSaved(r){let e=new Set(ai);this.snapshotKeys(r,Object.keys(r).filter(t=>!e.has(t)))}async adoptExternal(r){let e={adopted:{},any:!1};for(let[t,i]of Object.entries($i)){let s=await this.readSplit(t);if(!s)continue;let n=typeof s.rev=="number"?s.rev:0;if(n<=(this.revs.get(t)??0))continue;let o=[];for(let a of i)s[a]!==void 0&&JSON.stringify(s[a])!==JSON.stringify(r[a])&&(r[a]=s[a],o.push(a));this.revs.set(t,n),o.length&&(this.snapshotKeys(r,i),e.adopted[t]=o,e.any=!0)}return e}rebaseline(r){this.snapshotKeys(r,Object.keys(r))}};var Ua="stashpad:unghost-after-reload",La=class extends N.FuzzySuggestModal{constructor(e,t,i){super(e);this.notes=t;this.onChoose=i;this.setPlaceholder("Multiple notes attach this file \u2014 pick one to open")}getItems(){return this.notes}getItemText(e){let i=(this.app.metadataCache.getFileCache(e)?.headings?.[0]?.heading||e.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ")).trim(),s=e.parent?.path??"";return s?`${i} \u2014 ${s}`:i}onChooseItem(e){this.onChoose(e)}},kt=class kt extends N.Plugin{constructor(){super(...arguments);this.settings={...Mt};this.reEncryptScheduler=null;this.usedNoteIds=null;this.debugBuffer=[];this.undoStacks=new Map;this.lastActiveStashpadLeaf=null;this.rebootstrapInProgress=!1;this.pendingEncBlobs=new Set;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.noteClipboard=null;this.noteClipboardNotice=null;this._renderCacheStore=null;this.knownStashpadFolders=new Set;this.suppressedFolderDeletes=new Set;this.sweptFolders=new Set;this.notifiedBuildVersion=null;this.pendingBuildVersion=null;this.authorRenameInFlight=new Set;this.reHomePending=new Set;this.archiveMigrationInFlight=!1;this.okfRebuildTimers=new Map;this.okfRebuildingFolders=new Set;this.archivePending=new Map;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.ACTIVE_VERSIONS_LS_KEY="stashpad:active-versions";this.pendingForkDeletes=new Set;this.writeChain=Promise.resolve();this.lastSeenSettingsRev=0;this.settingsBaseline={};this.store=new go(this);this.externalReloadDebounced=(0,N.debounce)(()=>void this.onExternalDataJsonChange(),600,!1)}trace(e,t){if(!this.settings.debugTrace)return;let i="";if(t)try{i=" "+JSON.stringify(t)}catch{i=" [unserializable]"}let s=Math.round(performance.now());this.debugBuffer.push(`+${s}ms ${e}${i}`),this.debugBuffer.length>kt.DEBUG_BUFFER_MAX&&this.debugBuffer.splice(0,this.debugBuffer.length-kt.DEBUG_BUFFER_MAX)}getDebugTrace(){return this.debugBuffer.join(` +`)}clearDebugTrace(){this.debugBuffer=[]}get notifications(){return this._notifications||(this._notifications=new tn(this.app)),this._notifications}get authorRegistry(){return this._authorRegistry||(this._authorRegistry=new ro(this.app,this.pluginPrivatePath())),this._authorRegistry}get importService(){return this._importService||(this._importService=new co(this)),this._importService}get importLog(){return this._importLog||(this._importLog=new Ao(this.app,this.pluginPrivatePath())),this._importLog}clearNoteClipboard(){try{this.noteClipboardNotice?.hide()}catch{}this.noteClipboardNotice=null,this.noteClipboard=null}get renderCacheStore(){return this._renderCacheStore||(this._renderCacheStore=new ho(this.app,this.pluginPrivatePath())),this._renderCacheStore}async onunload(){try{this.encryption?.dispose()}catch{}try{for(let e of this.archivePending.values())window.clearTimeout(e.timer);this.archivePending.clear()}catch{}try{this.reEncryptScheduler?.dispose()}catch{}try{await this._renderCacheStore?.save()}catch{}}pluginPrivatePath(e=""){let i=`${this.manifest.dir.replace(/\/+$/,"")}/.stashpad`;return e?`${i}/${e.replace(/^\/+/,"")}`:i}newLog(){return new oo(this.app,this.pluginPrivatePath(),()=>(this.settings?.authorName??"").trim())}async migrateLegacyPaths(){let e=this.app.vault.adapter,t=this.pluginPrivatePath(),i=async()=>{let a=t.split("/").filter(Boolean),l="";for(let c of a)l=l?`${l}/${c}`:c,await e.exists(l)||await e.mkdir(l)},s=`${this.manifest.dir.replace(/\/+$/,"")}/data.json`,n=this.pluginPrivatePath("data.json");if(await e.exists(n))try{let a=await e.read(n);await e.write(s,a),await e.write(`${n}.bak`,a),await e.remove(n),console.debug("[Stashpad] relocated data.json \u2192 standard path (for Obsidian Sync)")}catch(a){console.warn("Stashpad: data.json relocation failed",a)}let o=".stashpad";if(await e.exists(o))try{await i();let a=await e.list(o);for(let l of a.files){let c=l.replace(/^.*\//,""),d=this.pluginPrivatePath(c);if(!await e.exists(d))try{let h=await e.read(l);await e.write(d,h),console.debug("[Stashpad] migrated",l,"\u2192",d)}catch(h){console.warn(`Stashpad: failed to migrate ${l}`,h)}}}catch(a){console.warn("Stashpad: .stashpad migration scan failed",a)}}async createNewStashpad(e){let t=e.trim().replace(/^\/+|\/+$/g,"");if(!t)throw new Error("Folder name is empty");let i=this.app.vault.adapter,s=t.split("/").filter(Boolean),n="";for(let c of s)n=n?`${n}/${c}`:c,await i.exists(n)||await i.mkdir(n);let o=`${t}/Home.md`;if(await i.exists(o)){let c=this.app.vault.getAbstractFileByPath(o);c&&await this.app.fileManager.processFrontMatter(c,d=>{(typeof d.id!="string"||!d.id)&&(d.id=S),"parent"in d||(d.parent=null),(typeof d.created!="string"||!d.created)&&(d.created=new Date().toISOString())});return}let a=new Date().toISOString(),l=["---",`id: ${S}`,"parent: null",`created: ${a}`,"---","Home"].join(` +`);await this.app.vault.create(o,l);try{await this.seedLocalAuthorStub(t)}catch{}try{await this.seedKnownAuthorsInFolder(t)}catch{}}collectColorsInFolder(e){let t=new Map,i=e.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,l=typeof a?.color=="string"?a.color.trim():"";if(!l||!/^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(l))continue;let c=l.toLowerCase();t.set(c,(t.get(c)??0)+1)}let s=[...t.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(e,t,i){let s=e.replace(/\/+$/,""),n=t.toLowerCase(),o=0;for(let l of this.app.vault.getMarkdownFiles()){let c=l.parent?.path?.replace(/\/+$/,"")??"";if(c!==s&&!c.startsWith(s+"/"))continue;let d=this.app.metadataCache.getFileCache(l)?.frontmatter;if((typeof d?.color=="string"?d.color.trim().toLowerCase():"")===n)try{await this.app.fileManager.processFrontMatter(l,p=>{i?p.color=i:delete p.color}),o++}catch(p){console.warn(`Stashpad: recolor failed for ${l.path}`,p)}}let a=this.settings.colorAliases?.[s];if(a){let l=a[n];l&&(delete a[n],i&&(a[i.toLowerCase()]=l),Object.keys(a).length===0&&delete this.settings.colorAliases[s],await this.saveSettings())}return o}getColorAlias(e,t){let i=e.replace(/\/+$/,""),s=this.settings.colorAliases?.[i];if(!s)return;let n=s[t.toLowerCase()];return n&&n.trim()?n:void 0}async setColorAlias(e,t,i){let s=e.replace(/\/+$/,""),n=t.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(e,t=2e3){let i=e.trim().replace(/^\/+|\/+$/g,"");if(!i)return;let s=Date.now();for(;Date.now()-s<t;){if(this.discoverStashpadFolders().includes(i))return;await new Promise(n=>setTimeout(n,80))}}importExcludePrefixList(){return(this.settings.importExcludePrefixes??"_").split(",").map(e=>e.trim()).filter(Boolean)}pathHasExcludedSegment(e){let t=this.importExcludePrefixList();return t.length?e.replace(/\/+$/,"").split("/").some(i=>t.some(s=>i.startsWith(s))):!1}discoverStashpadFolders(){let e=new Set;for(let i of this.app.vault.getMarkdownFiles()){let s=this.app.metadataCache.getFileCache(i)?.frontmatter;if(typeof s?.id!="string"||!s.id.trim()||!s||!("parent"in s))continue;let n=i.parent?.path?.replace(/\/+$/,"")??"";n&&!this.pathHasExcludedSegment(n)&&!Jt(n)&&e.add(n)}let t=[...e].sort((i,s)=>i.localeCompare(s,void 0,{sensitivity:"base"})||(i<s?-1:i>s?1:0));return this.knownStashpadFolders=new Set(t),t}closeStashpadTabsFor(e){let t=0;for(let i of this.app.workspace.getLeavesOfType($)){let s=i.view?.noteFolder??"";s||(s=((i.getViewState?.()?.state??{}).folderOverride??"")||this.settings.folder||"Stashpad"),s=(s||"").replace(/\/+$/,""),(s===e||s.startsWith(e+"/"))&&(i.detach(),t++)}return t}retargetStashpadViewsForFolderRename(e,t){let i=(e||"").replace(/\/+$/,""),s=(t||"").replace(/\/+$/,"");if(!i||i===s)return;let n=o=>{let a=(o??"").replace(/\/+$/,"");return a===i?s:a.startsWith(i+"/")?s+a.slice(i.length):null};for(let o of this.app.workspace.getLeavesOfType($)){let a=o.getViewState(),l=a.state??{},c=o.isDeferred?void 0:o.view?.noteFolder,d=n(c??l.folderOverride);d&&o.setViewState({...a,state:{...a.state??{},folderOverride:d}})}}async remapFolderPathInSettings(e,t){let i=e.replace(/\/+$/,""),s=t.replace(/\/+$/,"");if(!i||!s||i===s)return;let n=this.settings,o=h=>h===i?s:h.startsWith(i+"/")?s+h.slice(i.length):h,a=h=>h&&h.map(o),l=h=>{if(!h)return h;let p={};for(let[f,u]of Object.entries(h))p[o(f)]=u;return p},c=JSON.stringify([n.folderPanelPinned,n.folderPanelDownranked,n.folderPanelHidden,n.archiveFolders,n.searchIncludedFolders,n.searchExcludedFolders,n.defaultArchiveFolder,n.folder,n.folderEncPrefs,n.viewModes,n.encryptionFilter]);n.folderPanelPinned=a(n.folderPanelPinned)??n.folderPanelPinned,n.folderPanelDownranked=a(n.folderPanelDownranked)??n.folderPanelDownranked,n.folderPanelHidden=a(n.folderPanelHidden)??n.folderPanelHidden,n.archiveFolders=a(n.archiveFolders)??n.archiveFolders,n.searchIncludedFolders=a(n.searchIncludedFolders)??n.searchIncludedFolders,n.searchExcludedFolders=a(n.searchExcludedFolders)??n.searchExcludedFolders,n.defaultArchiveFolder&&(n.defaultArchiveFolder=o(n.defaultArchiveFolder)),((n.folder||"").replace(/\/+$/,"")===i||(n.folder||"").startsWith(i+"/"))&&(n.folder=o((n.folder||"").replace(/\/+$/,""))),n.folderEncPrefs=l(n.folderEncPrefs)??n.folderEncPrefs,n.viewModes=l(n.viewModes)??n.viewModes,n.encryptionFilter&&(n.encryptionFilter=l(n.encryptionFilter)),JSON.stringify([n.folderPanelPinned,n.folderPanelDownranked,n.folderPanelHidden,n.archiveFolders,n.searchIncludedFolders,n.searchExcludedFolders,n.defaultArchiveFolder,n.folder,n.folderEncPrefs,n.viewModes,n.encryptionFilter])!==c&&await this.saveSettings()}async prunePlacementFor(e){let t=this.settings,i=o=>(o??[]).filter(a=>a!==e&&!a.startsWith(e+"/")),s=(t.folderPanelPinned?.length??0)+(t.folderPanelDownranked?.length??0)+(t.folderPanelHidden?.length??0);t.folderPanelPinned=i(t.folderPanelPinned),t.folderPanelDownranked=i(t.folderPanelDownranked),t.folderPanelHidden=i(t.folderPanelHidden),t.folderPanelPinned.length+t.folderPanelDownranked.length+t.folderPanelHidden.length!==s&&await this.saveSettings()}async deleteStashpadFolderWithUndo(e){let t=e.path.replace(/\/+$/,""),i=e.name,s=this.app.vault.adapter,n=".trash";try{await s.exists(n)||await s.mkdir(n)}catch(c){console.warn("[Stashpad] couldn't ensure .trash",c)}let o=`${n}/${i}`;for(let c=1;await s.exists(o);c++)o=`${n}/${i} (${c})`;this.suppressedFolderDeletes.add(t),window.setTimeout(()=>this.suppressedFolderDeletes.delete(t),5e3);let a=this.closeStashpadTabsFor(t);await this.prunePlacementFor(t),this.knownStashpadFolders.delete(t);try{await s.rename(t,o)}catch(c){console.warn("[Stashpad] folder delete failed",c),this.suppressedFolderDeletes.delete(t),new N.Notice("Delete failed (see console).");return}let l=a>0?`Deleted \u201C${i}\u201D \u2014 closed ${a} open tab${a===1?"":"s"}.`:`Deleted \u201C${i}\u201D.`;this.notifications.show({message:l,kind:"warning",category:"delete",duration:0,folder:t,actions:[{label:"Undo",onClick:async()=>{try{if(await s.exists(t)){new N.Notice(`Can't undo \u2014 \u201C${i}\u201D already exists.`);return}this.suppressedFolderDeletes.add(t),window.setTimeout(()=>this.suppressedFolderDeletes.delete(t),5e3),await s.rename(o,t),new N.Notice(`Restored \u201C${i}\u201D.`),this.activateViewForFolder(t)}catch(c){console.warn("[Stashpad] folder undo failed",c),new N.Notice("Undo failed (see console).")}}}]})}async handleStashpadFolderDeleted(e){let t=e.replace(/\/+$/,"");if(!t||this.suppressedFolderDeletes.has(t))return;let i=this.closeStashpadTabsFor(t);await this.prunePlacementFor(t),this.knownStashpadFolders.delete(t);let s=t.split("/").pop()||t;this.notifications.show({message:i>0?`Stashpad \u201C${s}\u201D was deleted \u2014 closed ${i} open tab${i===1?"":"s"}.`:`Stashpad \u201C${s}\u201D was deleted.`,kind:"warning",category:"delete",folder:t})}searchableFolders(e){let t=new Set(this.settings.searchIncludedFolders),i=new Set(this.settings.searchExcludedFolders),s=new Set((this.settings.archiveFolders??[]).map(c=>(c??"").replace(/\/+$/,""))),o=this.discoverStashpadFolders().filter(c=>s.has(c)?!1:t.size>0?t.has(c):!i.has(c)),a=(e||"").trim().replace(/\/+$/,""),l=o.filter(c=>c!==a);return a&&l.unshift(a),l}async maybeSweepFolder(e){let t=(e||"").trim().replace(/\/+$/,"");!t||this.sweptFolders.has(t)||(this.sweptFolders.add(t),setTimeout(()=>{this.runSweep(t,{silent:!0})},3e3))}async runIntegrityCheckOnFolder(e){let t=(e||"").trim().replace(/\/+$/,"");t&&await this.runSweep(t,{silent:!1})}async runSweep(e,t){try{let i=this.newLog(),s={},n=this.app.vault.getMarkdownFiles().filter(c=>c.path===e||c.path.startsWith(e+"/"));for(let c of n){let d=this.app.metadataCache.getFileCache(c)?.frontmatter,h=typeof d?.id=="string"?d.id.trim():"";if(!h)continue;let p=d&&"parent"in d?d.parent??null:null;s[h]={parent:p,path:c.path}}let o=await i.readState(),a=c=>c===e||c.startsWith(e+"/");if(!t.silent){for(let[c,d]of Object.entries(s)){let h=o[c];h?h.parent!==d.parent?await i.append({type:"parent_change",id:c,payload:{from:h.parent,to:d.parent}}):h.path!==d.path&&await i.append({type:"rename",id:c,payload:{from:h.path,to:d.path}}):await i.append({type:"create",id:c,payload:{path:d.path,parent:d.parent}})}for(let[c,d]of Object.entries(o))!s[c]&&a(d.path)&&await i.append({type:"missing",id:c,payload:{lastPath:d.path}})}let l={};for(let[c,d]of Object.entries(o))a(d.path)||(l[c]=d);for(let[c,d]of Object.entries(s))l[c]=d;await i.writeState(l)}catch(i){console.warn("Stashpad: integrity sweep failed",i)}}getUndoStack(e){let t=this.undoStacks.get(e);return t||(t=new ao,this.undoStacks.set(e,t)),t}mintNoteId(){this.usedNoteIds===null&&this.rebuildUsedNoteIds();let e=this.usedNoteIds,t=yo(i=>e.has(i));return e.add(t),t}rebuildUsedNoteIds(){let e=new Set;for(let t of this.app.vault.getMarkdownFiles()){let i=this.app.metadataCache.getFileCache(t)?.frontmatter?.id;typeof i=="string"&&i.trim()&&e.add(i.trim())}this.usedNoteIds=e}async onload(){this.registerEvent(this.app.metadataCache.on("changed",(g,I,m)=>{let C=m?.frontmatter?.id;this.usedNoteIds&&typeof C=="string"&&C.trim()&&this.usedNoteIds.add(C.trim())})),await this.migrateLegacyPaths(),await this.loadSettings(),Te.enabled=!!this.settings.enablePerfProfiling,this.encryption=new cn(this.app,()=>({...dn(),...this.settings.encryption??{}}),async g=>{this.settings.encryption=g,await this.saveSettings()}),this.encryption.init().then(async()=>{try{let g=await this.encryption.migrateKeyfileToStashKeys();g>0&&new N.Notice(`Stashpad: moved ${g} folder key${g===1?"":"s"} to the new per-folder format.`)}catch(g){console.warn("[Stashpad] folder-key migration failed (keyfile still works)",g)}}),this.reEncryptScheduler=new to(this),this.reEncryptScheduler.start(),this.settingTab=new un(this.app,this),this.addSettingTab(this.settingTab),await this.renderCacheStore.load(),this.registerEvent(this.app.vault.on("delete",g=>this.renderCacheStore.evict(g.path))),this.registerEvent(this.app.vault.on("rename",(g,I)=>this.renderCacheStore.evict(I)));let e=(0,N.debounce)(()=>void this.flushForkSiblingPrune(),250,!0);this.registerEvent(this.app.vault.on("delete",g=>{g instanceof N.TFile&&g.extension==="md"&&(this.pendingForkDeletes.add(g.basename),e())})),this.registerEvent(this.app.vault.on("create",g=>this.onOkfFileEvent(g.path))),this.registerEvent(this.app.vault.on("delete",g=>this.onOkfFileEvent(g.path))),this.registerEvent(this.app.vault.on("rename",(g,I)=>{this.onOkfFileEvent(g.path),this.onOkfFileEvent(I)})),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.registerEvent(this.app.vault.on("create",g=>{g.path.endsWith(".stashenc")&&this.pendingEncBlobs.delete(g.path)})),this.registerEvent(this.app.vault.on("delete",g=>{g.path.endsWith(".stashenc")&&this.pendingEncBlobs.delete(g.path)})),this.app.workspace.onLayoutReady(()=>{this.reconcileLockedRegistry(),window.setTimeout(async()=>{try{await this.migrateArchiveFoldersToSubfolders()}catch(g){console.error("[Stashpad] archive migration failed",g)}try{await this.migrateDeletedToTrashSubfolders()}catch(g){console.error("[Stashpad] trash migration failed",g)}this.pruneZombieArchiveEntries()},5e3),window.setTimeout(()=>{if(!this.settings.reEncryptNudge)return;let g=this.reEncryptWatching().length;if(g===0)return;let I=new N.Notice("",0);I.noticeEl.createSpan({text:`\u{1F513} ${g} previously-encrypted note${g===1?" is":"s are"} still plaintext. `});let m=I.noticeEl.createEl("button",{text:"Review"});m.onclick=()=>{I.hide(),He(this,"watch")}},8e3),window.setTimeout(()=>void this.checkDueReminders(),6e3),this.registerInterval(window.setInterval(()=>void this.checkDueReminders(),5*60*1e3)),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($,g=>new Ps(g,this)),this.registerView(Kt,g=>new En(g,this)),this.registerView(St,g=>new yn(g,this)),this.registerView(ci,g=>new eo(g,this)),this.registerView(di,g=>new Rn(g,this)),this.registerView(bt,g=>new io(g,this)),this.registerView(Cs,g=>new bi(g)),this.registerObsidianProtocolHandler(Es,g=>{this.handleDeepLink(g)}),this.registerEvent(this.app.workspace.on("active-leaf-change",g=>{g&&g.view.getViewType()===$&&(this.lastActiveStashpadLeaf=g,this.settings.autoOpenDetailPanel&&this.app.workspace.getLeavesOfType(Kt).length===0&&setTimeout(()=>{vn(this.app)},0),this.notifyStashpadSelectionChanged())}));let t=()=>{let g=Bt(),I=!!g&&this.app.workspace.activeLeaf&&this.app.workspace.activeLeaf.view===g,m=!!I&&this.settings.hideMobileToolbarInStashpad;document.body.classList.toggle("stashpad-hide-mobile-toolbar",m),document.body.classList.toggle("stashpad-active",!!I)};this.register(Ur(t)),this.registerEvent(this.app.workspace.on("active-leaf-change",t));let i=g=>{try{let I=Array.from(document.querySelectorAll("style")).filter(m=>(m.textContent??"").includes(".stashpad-"));for(let m of I){let C=m.id||"",B=C?`style[data-stashpad-source="${C}"]`:null;if(B&&g.head.querySelector(B))continue;let E=g.createElement("style");C?E.setAttribute("data-stashpad-source",C):E.setAttribute("data-stashpad-source","anon"),E.textContent=m.textContent??"",g.head.appendChild(E)}}catch(I){console.warn("[Stashpad] inject popout styles failed",I)}};this.registerEvent(this.app.workspace.on("window-open",g=>{let I=g?.doc??g?.win?.document??null;I&&i(I)})),this.registerEvent(this.app.workspace.on("file-menu",(g,I)=>{if(!(I instanceof N.TFolder))return;let m=I.path.replace(/\/+$/,"");g.addItem(B=>B.setTitle("\u{1F512} Encrypt with Stashpad").setIcon("lock").onClick(()=>void this.encryptFolderFromExplorer(m))),I.children?.some(B=>B instanceof N.TFile&&B.extension==="stashenc")&&!this.folderHasStashpadNotes(m)&&g.addItem(B=>B.setTitle("\u{1F513} Decrypt with Stashpad").setIcon("unlock").onClick(()=>void this.decryptFolderFromExplorer(m))),this.discoverStashpadFolders().includes(m)&&g.addItem(B=>{B.setTitle("Open folder in Stashpad").setIcon("layout-list").onClick(()=>void this.openFolderInStashpad(m))})})),this.registerEvent(this.app.workspace.on("file-menu",(g,I)=>{if(!(I instanceof N.TFile)||I.extension==="md")return;let m=this.findStashpadNotesEmbedding(I);m.length!==0&&g.addItem(C=>C.setTitle(m.length>1?"Open in Stashpad\u2026":"Open in Stashpad").setIcon("layout-list").onClick(()=>void this.revealAttachmentInStashpad(I,m)))})),setTimeout(()=>{try{let g=this.app.workspace;typeof g.iterateAllLeaves=="function"&&g.iterateAllLeaves(I=>{let m=I?.view?.containerEl?.ownerDocument;m&&m!==document&&i(m)})}catch{}},200),t(),this.register(()=>document.body.classList.remove("stashpad-hide-mobile-toolbar","stashpad-active"));let s=window.visualViewport,n=()=>{let g=document.querySelector(".mobile-toolbar, .mobile-toolbar-container"),I=g&&g.isConnected?g.offsetHeight:0;document.body.style.setProperty("--stashpad-toolbar-h",`${I}px`);let m=0;s&&(m=Math.max(0,window.innerHeight-s.height-s.offsetTop)),document.body.style.setProperty("--stashpad-vv-bottom-gap",`${m}px`),document.body.classList.toggle("stashpad-keyboard-open",m>100)};n(),s&&(s.addEventListener("resize",n),s.addEventListener("scroll",n),this.register(()=>{s.removeEventListener("resize",n),s.removeEventListener("scroll",n)})),window.addEventListener("resize",n),this.register(()=>window.removeEventListener("resize",n)),requestAnimationFrame(n),setTimeout(n,250),setTimeout(n,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)",()=>{wn(this.app)}),this.addRibbonIcon("folders","Open Stashpad folder panel (sidebar)",()=>{so(this.app)}),this.addRibbonIcon("panel-right","Open Stashpad detail panel (right sidebar)",()=>{vn(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})}),this.addCommand({id:"stashpad-focus-last-tab",name:"Focus last Stashpad tab",callback:()=>void this.focusLastStashpadTab()}),this.addCommand({id:"stashpad-focus-folder-panel",name:"Focus folder panel",callback:()=>void this.focusFolderPanel()});let a=g=>{let I=Bt();I&&typeof I[g]=="function"&&I[g]()};this.addCommand({id:"stashpad-toggle-split",name:"Toggle split-on-newlines",callback:()=>a("toggleSplit")}),this.addCommand({id:"stashpad-fork-version",name:"Fork as a version (alternate draft in this sheet)",callback:()=>a("cmdForkVersion")}),this.addCommand({id:"stashpad-mark-version-final",name:"Mark version as final (sheet)",callback:()=>a("cmdMarkVersionFinal")}),this.addCommand({id:"stashpad-command-palette",name:"Command palette (Stashpad only)",callback:()=>a("openStashpadCommandPalette")}),this.addCommand({id:"stashpad-lock-selection",name:"Encrypt (lock) selection (notes + children)",callback:()=>a("cmdLockSelection")}),this.addCommand({id:"stashpad-lock-selection-hide-name",name:"Encrypt (lock) selection + hide filename (override folder setting)",callback:()=>a("cmdLockSelectionHideName")}),this.addCommand({id:"stashpad-unlock-all",name:"Decrypt (unlock) locked notes in view",callback:()=>a("cmdUnlockAll")}),this.addCommand({id:"stashpad-unlock-all-vault",name:"Decrypt (unlock) ALL locked notes in the vault",callback:()=>void this.unlockAllInVault()}),this.addCommand({id:"stashpad-copy-notes",name:"Copy notes (note clipboard \u2014 paste to duplicate)",callback:()=>a("cmdCopyNotes")}),this.addCommand({id:"stashpad-cut-notes",name:"Cut notes (paste in list to move, in composer to extract text)",callback:()=>a("cmdCutNotes")}),this.addCommand({id:"stashpad-paste-notes",name:"Paste notes (from the note clipboard)",callback:()=>a("cmdPasteNotes")}),this.addCommand({id:"stashpad-move-to-archive",name:"Move selection to archive",callback:()=>a("cmdMoveToArchive")}),this.addCommand({id:"stashpad-encrypt-delete",name:"Encrypt (lock) & delete selection (to encrypted trash)",callback:()=>a("cmdEncryptDelete")}),this.addCommand({id:"stashpad-delete-unencrypted",name:"Delete selection to Obsidian's trash (unencrypted)",callback:()=>a("cmdDeleteUnencrypted")}),this.addCommand({id:"stashpad-restore-trash",name:"Open aggregated Trash view",callback:()=>this.openEncryptedTrash()}),this.addCommand({id:"stashpad-open-all-encrypted",name:"Open aggregated Encrypted notes view",callback:()=>void He(this,"encrypted")}),this.addCommand({id:"stashpad-open-all-archived",name:"Open aggregated Archived view",callback:()=>void He(this,"archived")}),this.addCommand({id:"stashpad-open-all-tasks",name:"Open aggregated Tasks view",callback:()=>void He(this,"tasks")}),this.addCommand({id:"stashpad-open-watchlist",name:"Open aggregated Previously encrypted view",callback:()=>void He(this,"watch")}),this.addCommand({id:"stashpad-encrypt-applicable",name:"Encrypt (lock) everything applicable (re-encrypt sweep)",callback:()=>void this.encryptEverythingApplicable()}),this.addCommand({id:"stashpad-close-duplicate-tabs",name:"Close duplicate & orphaned Stashpad tabs (tidy up)",callback:()=>void this.closeDuplicateStashpadTabs()}),this.addCommand({id:"stashpad-claim-selected-author",name:"Claim authorship of selected notes",callback:()=>a("claimSelectedAsAuthor")}),this.addCommand({id:"stashpad-claim-folder-author",name:"Claim authorship of all unauthored notes in this folder",callback:()=>a("claimFolderAsAuthor")}),this.addCommand({id:"stashpad-claim-selected-contributor",name:"Claim selected notes (author if unowned, else add me as contributor)",callback:()=>a("claimSelectedWithContributor")}),this.addCommand({id:"stashpad-claim-folder-contributor",name:"Claim all notes in this folder (author if unowned, else add me as contributor)",callback:()=>a("claimFolderWithContributor")}),this.addCommand({id:"stashpad-pick-destination",name:"Pick destination for next note",callback:()=>a("openDestinationPicker")}),this.addCommand({id:"stashpad-search",name:"Search Stashpad notes",callback:()=>a("openSearchModal")}),this.addCommand({id:"stashpad-search-in-parent",name:"Search in current parent",callback:()=>a("openSearchInParentModal")}),this.addCommand({id:"stashpad-move-picker",name:"Move selection (picker)",callback:()=>a("cmdMovePicker")}),this.addCommand({id:"stashpad-merge",name:"Merge selection",callback:()=>a("cmdMerge")}),this.addCommand({id:"stashpad-copy",name:"Copy selection",callback:()=>a("cmdCopy")}),this.addCommand({id:"stashpad-copy-tree",name:"Copy focused subtree",callback:()=>a("cmdCopyTree")}),this.addCommand({id:"stashpad-dismiss-notifications",name:"Dismiss all notifications",callback:()=>{let g=Array.from(document.querySelectorAll(".notice"));for(let I of g)I.parentElement?.removeChild(I);new N.Notice(g.length?`Dismissed ${g.length} notification${g.length===1?"":"s"}.`:"No notifications to dismiss.")}}),this.addCommand({id:"stashpad-resend-reminders",name:"Resend reminders for incomplete due tasks (show my backlog)",callback:()=>void this.resendDueReminders()}),this.addCommand({id:"stashpad-copy-link",name:"Copy Stashpad link (deep link / URL) to note",callback:()=>a("cmdCopyStashpadLink")}),this.addCommand({id:"stashpad-open-link",name:"Open Stashpad link (paste a deep link / URL)",callback:()=>this.openDeepLinkModal()}),this.addCommand({id:"stashpad-copy-outline",name:"Copy as outline (nested embeds)",callback:()=>a("cmdCopyOutline")}),this.addCommand({id:"stashpad-split",name:"Split note\u2026",callback:()=>a("cmdSplit")}),this.addCommand({id:"stashpad-edit-note",name:"Open note in Obsidian editor (new tab)",callback:()=>a("cmdOpenInEditor")}),this.addCommand({id:"stashpad-edit-inapp",name:"Edit note in Stashpad\u2026",callback:()=>a("cmdEdit")}),this.addCommand({id:"stashpad-edit-parent-inapp",name:"Edit parent note in Stashpad\u2026",callback:()=>a("cmdEditParent")}),this.addCommand({id:"stashpad-edit-parent",name:"Edit parent note in new tab",callback:()=>a("cmdOpenParentInEditor")}),this.addCommand({id:"stashpad-delete",name:"Delete selection",callback:()=>a("cmdDelete")}),this.addCommand({id:"stashpad-move-up",name:"Move note up",callback:()=>a("cmdMoveUp")}),this.addCommand({id:"stashpad-move-down",name:"Move note down",callback:()=>a("cmdMoveDown")}),this.addCommand({id:"stashpad-move-to-top",name:"Move note to top",callback:()=>a("cmdMoveToTop")}),this.addCommand({id:"stashpad-move-to-bottom",name:"Move note to bottom",callback:()=>a("cmdMoveToBottom")}),this.addCommand({id:"stashpad-outdent",name:"Outdent (move to grandparent)",callback:()=>a("cmdOutdent")}),this.addCommand({id:"stashpad-set-color",name:"Set note color\u2026",callback:()=>a("cmdSetColor")}),this.addCommand({id:"stashpad-clone",name:"Clone selection (duplicate / copy notes)",callback:()=>a("cmdClone")}),this.addCommand({id:"stashpad-fork-note",name:"Fork into a separate note (copy under a chosen parent)",callback:()=>a("cmdForkNote")}),this.addCommand({id:"stashpad-insert-template",name:"Insert template (clone an existing note)",callback:()=>a("cmdInsertTemplate")}),this.addCommand({id:"stashpad-toggle-expand",name:"Show more / show less (expand toggle)",callback:()=>a("cmdToggleExpand")}),this.addCommand({id:"stashpad-expand-all",name:"Expand all (show every note's full body)",callback:()=>a("cmdExpandAll")}),this.addCommand({id:"stashpad-collapse-all",name:"Collapse all (clamp every note's body)",callback:()=>a("cmdCollapseAll")}),this.addCommand({id:"stashpad-pick-move",name:"Move (in-list, arrow + Enter)",callback:()=>a("cmdInListPicker")}),this.addCommand({id:"stashpad-open-in-new-tab",name:"Open in new Stashpad tab",callback:()=>a("cmdOpenInNewStashpadTab")}),this.addCommand({id:"stashpad-toggle-complete",name:"Toggle complete (strikethrough)",callback:()=>a("cmdToggleComplete")}),this.addCommand({id:"stashpad-toggle-task",name:"Toggle task (todo)",callback:()=>a("cmdToggleTask")}),this.addCommand({id:"stashpad-set-due",name:"Set due date\u2026",callback:()=>a("cmdSetDue")}),this.addCommand({id:"stashpad-dump-perf",name:"Dump performance profile (copy to clipboard)",callback:async()=>{if(!this.settings.enablePerfProfiling){new N.Notice("Enable \u201CPerformance profiling\u201D in Stashpad settings first, then use the app and run this again.");return}let g=Te.report();console.log(g);try{await navigator.clipboard.writeText(g)}catch{}new N.Notice("Performance profile copied to clipboard (also in the console).")}}),this.addCommand({id:"stashpad-reset-perf",name:"Reset performance profile",callback:()=>{Te.reset(),new N.Notice("Performance profile reset.")}}),this.addCommand({id:"stashpad-jump-to-top",name:"Jump to top of list",callback:()=>a("jumpToTop")}),this.addCommand({id:"stashpad-jump-to-bottom",name:"Jump to bottom of list",callback:()=>a("jumpToBottom")}),this.addCommand({id:"stashpad-assign",name:"Assign task to\u2026",callback:()=>a("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(()=>(ve(),Bs));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 I=this.importService.defaultDestination();return g?!!I:(I&&this.runImportLooseFiles(I),!0)}}),this.addCommand({id:"stashpad-rerun-slug-pass",name:"Re-run filename (slug) pass on this folder",checkCallback:g=>{let I=this.importService.defaultDestination();return g?!!I:(I&&this.runFolderSlugPass(I),!0)}}),this.addCommand({id:"stashpad-rerun-frontmatter-backfill",name:"Re-run frontmatter backfill (recovery links) on this folder",checkCallback:g=>{let I=this.importService.defaultDestination();return g?!!I:(I&&this.runFolderFrontmatterBackfill(I),!0)}}),this.addCommand({id:"stashpad-select-all",name:"Select all visible notes",callback:()=>a("cmdSelectAll")}),this.addCommand({id:"stashpad-copy-codeblock",name:"Copy code from codeblock",callback:()=>a("cmdCopyCodeBlock")}),this.addCommand({id:"stashpad-open-panels",name:"Open Stashpad panels (sidebar)",callback:()=>void wn(this.app)}),this.addCommand({id:"stashpad-open-folder-panel",name:"Open folder panel (sidebar)",callback:()=>void so(this.app)}),this.addCommand({id:"stashpad-open-detail",name:"Open Stashpad detail panel (right sidebar)",callback:()=>void vn(this.app)}),this.addCommand({id:"stashpad-reveal-active-note",name:"Open this note in Stashpad",checkCallback:g=>{let I=this.app.workspace.getActiveFile();return I?I.extension==="md"&&this.isStashpadNoteFile(I)?(g||this.revealNoteInStashpad(I),!0):I.extension!=="md"?(g||this.revealAttachmentInStashpad(I),!0):!1:!1}});let l=Object.keys(ws);for(let g of l){let I=ws[g];this.addCommand({id:`stashpad-open-panels-${g}`,name:`Open Stashpad panel: ${I.label}`,callback:async()=>{await wn(this.app),this.app.workspace.getLeavesOfType(St)[0]?.view?.setActivePanel?.(g)}})}this.addCommand({id:"stashpad-task-review",name:"Open daily task review",callback:()=>new xi(this.app,this).open()}),this.addCommand({id:"stashpad-swap-with-parent",name:"Swap with parent (ouroboros)",callback:()=>a("cmdSwapWithParent")}),this.addCommand({id:"stashpad-toggle-pin",name:"Pin / unpin selected note (sidebar)",callback:()=>a("cmdTogglePin")}),this.addCommand({id:"stashpad-list-pin",name:"Pin / unpin to top of list",callback:()=>a("cmdToggleListPin")}),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:()=>a("cmdCloneStashpadTab")}),this.addCommand({id:"stashpad-undo",name:"Undo last Stashpad action",callback:()=>a("cmdUndo")}),this.addCommand({id:"stashpad-redo",name:"Redo last undone Stashpad action",callback:()=>a("cmdRedo")}),this.addCommand({id:"stashpad-export-stash",name:"Export selection (.stash / OKF / plain .zip)\u2026",callback:()=>a("cmdExportStash")}),this.addCommand({id:"stashpad-import-stash",name:"Import .stash file\u2026",callback:()=>a("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 I=Bt(),m=I&&I.noteFolder;return m?(g||(new N.Notice(`Running integrity check on "${m}"\u2026`),this.runIntegrityCheckOnFolder(m).then(()=>{new N.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 N.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 N.Notice(`Author registry rebuild failed: ${g.message}`)}}}),this.addCommand({id:"stashpad-restore-author-stubs",name:"Restore missing author stubs (from registry)",callback:async()=>{new N.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 N.Notice(`Restore author stubs failed: ${g.message}`)}}}),this.addCommand({id:"stashpad-sync-authors",name:"Sync authors across all folders (multiplayer)",callback:()=>void this.syncAuthorsAcrossFolders()}),this.addCommand({id:"stashpad-rebootstrap-all",name:"Rebootstrap all Stashpad folders (backfill metadata + rename stale titles)",callback:()=>{this.runRebootstrapWithUI().catch(()=>{})}}),this.addCommand({id:"stashpad-adopt-note",name:"Adopt active note into Stashpad (fill missing frontmatter)",checkCallback:g=>{let I=this.app.workspace.getActiveFile();return!I||I.extension!=="md"?!1:(g||this.adoptNote(I),!0)}}),this.addCommand({id:"stashpad-open-notification-history",name:"Open notification history",callback:()=>{Promise.resolve().then(()=>(ve(),Bs)).then(({NotificationHistoryModal:g,LogModal:I})=>{new g(this.app,this.notifications,async()=>{let m=this.app.vault.adapter,C=this.pluginPrivatePath("log.jsonl");if(!await m.exists(C)){new N.Notice("No log yet \u2014 make some changes first.");return}let B=await m.read(C);new I(this.app,B,C).open()},this.settings.authorId||null,m=>this.lookupNoteAuthorIds(m)).open()})}});let c=[{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:"openParentTabOnMoveIn",label:"Open new parent in a background tab 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 c){let I=`stashpad-toggle-${String(g.key).replace(/[A-Z]/g,m=>`-${m.toLowerCase()}`)}`;this.addCommand({id:I,name:`Toggle: ${g.label}`,callback:async()=>{let m=!this.settings[g.key];this.settings[g.key]=m,await this.saveSettings(),new N.Notice(`${g.label}: ${m?"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(()=>{g?.modalEl?.querySelector?.("input[type='search']")?.focus()},0))}});for(let g of gn)this.addCommand({id:`stashpad-open-settings-${g.id}`,name:`Open Stashpad settings: ${g.label}`,callback:()=>{let I=this.app.setting;!I?.open||!I?.openTabById||(I.open(),I.openTabById(this.manifest.id))}});let d=()=>{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(()=>(is(),js)),I=await g(this.app,this,this.settings);if(I.error==="no-dest"){new N.Notice("Set a Designated Stashpad folder for Index in settings first.",6e3),d();return}if(I.error==="no-home"){new N.Notice(`"${this.settings.jdIndexStashpadFolder}" has no Stashpad home note. Open the folder in Stashpad first to create one.`,7e3);return}let{buildJdPreviewNotice:m}=await Promise.resolve().then(()=>(is(),js));m(this.app,I)}catch(g){console.error("[stashpad] preview failed",g),new N.Notice(`Preview failed: ${g?.message??g}`,8e3)}}}),this.addCommand({id:"stashpad-decrypt-folder-bundle",name:"Decrypt a folder bundle (encrypted non-Stashpad folder)\u2026",callback:async()=>{if(!this.encryption.isConfigured()){new N.Notice("Stashpad encryption isn't set up.");return}let g=await Vl(this.app);if(!g.length){new N.Notice("No encrypted folder bundles found in this vault.");return}new Oa(this.app,g,I=>void this.decryptFolderFromExplorer(I.folder)).open()}}),this.addCommand({id:"stashpad-build-jd-index",name:"Build JD index notes (creates Stashpad-note hierarchy)",callback:async()=>{try{let{buildJdIndexNotes:g,scanForJdNotes:I,JdBuildConfirmModal:m}=await Promise.resolve().then(()=>(is(),js));if(!(this.settings.jdIndexStashpadFolder??"").trim().replace(/^\/+|\/+$/g,"")){new N.Notice("Set a Designated Stashpad folder for Index in settings first.",6e3),d();return}let B=I(this.app,this,this.settings);new m(this.app,this,this.settings,B.indexed.length,async()=>{try{let y=await g(this.app,this,this.settings);if(y.error==="no-dest"){new N.Notice("Set a Designated Stashpad folder for Index in settings first.",6e3),d();return}if(y.error==="dest-not-stashpad"){new N.Notice(`"${y.destFolder}" isn't a known Stashpad folder. Pick a real Stashpad folder in settings.`,7e3),d();return}this.settings.jdIndexHasBuilt=!0,await this.saveSettings(),new N.Notice(`Index built: ${y.created} created, ${y.updated} updated, ${y.skipped} skipped \u2192 ${y.destFolder}`,6e3)}catch(y){console.error("[stashpad] build failed",y),new N.Notice(`Build failed: ${y?.message??y}`,8e3)}}).open()}catch(g){console.error("[stashpad] build failed",g),new N.Notice(`Build failed: ${g?.message??g}`,8e3)}}});let h=g=>{if(g.extension!==ct)return;let I=(this.settings.importDropFolder||"").trim().replace(/^\/+|\/+$/g,""),m=(this.settings.exportFolder||"").trim().replace(/^\/+|\/+$/g,""),C=g.parent?.path||"",B=C.split("/").pop()??"";if(I&&B===I){if(m&&C.endsWith(`/${m}`))return;let E=C.slice(0,C.length-I.length).replace(/\/+$/,"")||this.settings.folder;this.autoImportStash(g,E);return}this.settings.autoImport&&this.importService.isArmed()&&(Jt(g.path)||this.discoverStashpadFolders().includes(C)&&this.autoImportStash(g,C))};this.registerEvent(this.app.vault.on("create",g=>{g instanceof N.TFile&&h(g)})),this.registerEvent(this.app.vault.on("rename",g=>{g instanceof N.TFile&&h(g)}));let p=g=>{if(g.extension!=="md")return;let I=g.parent?.path?.replace(/\/+$/,"")??"";this.discoverStashpadFolders().includes(I)&&setTimeout(()=>{this.fixOrphanParentForFile(g)},800)},f=g=>{if(g.extension!=="md")return;let I=(this.settings.importDropFolder||"").trim().replace(/^\/+|\/+$/g,"");if(!I)return;let m=g.parent?.path?.replace(/\/+$/,"")??"";if((m.split("/").pop()??"")!==I)return;let B=m.slice(0,m.length-I.length).replace(/\/+$/,"");!B||!this.discoverStashpadFolders().includes(B)||setTimeout(()=>{this.adoptMarkdownDrop(g,B)},200)};this.registerEvent(this.app.vault.on("create",g=>{g instanceof N.TFile&&(p(g),f(g))})),this.registerEvent(this.app.vault.on("rename",g=>{g instanceof N.TFile&&(p(g),f(g))})),this.registerEvent(this.app.vault.on("delete",g=>{if(!(g instanceof N.TFolder))return;let I=g.path.replace(/\/+$/,"");this.knownStashpadFolders.has(I)&&this.handleStashpadFolderDeleted(I)})),this.registerEvent(this.app.vault.on("rename",(g,I)=>{g instanceof N.TFile&&this.maybeReHomeOnCrossFolderMove(g,I)})),this.registerEvent(this.app.vault.on("rename",(g,I)=>{g instanceof N.TFile&&this.maybeArchiveOnMoveIn(g,I)})),this.registerEvent(this.app.vault.on("rename",(g,I)=>{g instanceof N.TFolder&&(this.retargetStashpadViewsForFolderRename(I,g.path),this.remapFolderPathInSettings(I,g.path))}));let u=new Set(this.store.watchPaths());this.registerEvent(this.app.vault.on("raw",g=>{u.has(g)&&this.scheduleExternalDataJsonReload()})),this.registerEvent(this.app.vault.on("create",g=>{g instanceof N.TFile?this.importService.enqueue(g):g instanceof N.TFolder&&this.importService.enqueueFolder(g)})),this.registerEvent(this.app.vault.on("rename",g=>{g instanceof N.TFile?this.importService.enqueue(g):g instanceof N.TFolder&&this.importService.enqueueFolder(g)})),this.registerEvent(this.app.vault.on("rename",(g,I)=>{g instanceof N.TFile&&this.maybeAdoptAuthorRename(g,I)})),this.registerDomEvent(window,"focus",()=>void this.checkForSyncedBuild()),setTimeout(()=>void this.checkForSyncedBuild(),5e3),this.registerInterval(window.setInterval(()=>void this.checkForSyncedBuild(),45e3))}async checkForSyncedBuild(){try{let e=this.manifest.dir;if(!e)return;let t=`${e.replace(/\/+$/,"")}/manifest.json`,i=this.app.vault.adapter;if(!await i.exists(t))return;let s=JSON.parse(await i.read(t))?.version,n=this.manifest.version;if(typeof s!="string"||!s||s===n||!this.isSemverGreater(s,n)||this.notifiedBuildVersion===s)return;if(this.pendingBuildVersion!==s){this.pendingBuildVersion=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(e){console.debug("[Stashpad] synced-build check failed",e)}}reloadAppForUpdate(){try{window.localStorage?.setItem(Ua,"1")}catch{}try{if(this.app.commands?.executeCommandById?.("app:reload"))return}catch(e){console.warn("[Stashpad] app:reload command failed",e)}try{window.location.reload()}catch{new N.Notice("Reload Obsidian (close + reopen) to apply the Stashpad update.")}}async unghostStashpadTabsIfFlagged(){let e=!1;try{e=window.localStorage?.getItem(Ua)==="1"}catch{}if(e){try{window.localStorage?.removeItem(Ua)}catch{}for(let t of this.app.workspace.getLeavesOfType($))try{let i=t;i.isDeferred&&typeof i.loadIfDeferred=="function"&&await i.loadIfDeferred()}catch(i){console.warn("[Stashpad] un-ghost leaf failed",i)}}}isSemverGreater(e,t){let i=e.split(".").map(o=>parseInt(o,10)||0),s=t.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,l=s[o]??0;if(a!==l)return a>l}return!1}parseAuthorFilePath(e){let t=e.match(/\/_authors\/([^/]+?)-([a-z0-9]{4,12})\.md$/i);return t?{name:t[1].replace(/-/g," "),id:t[2]}:null}authorNameToSafe(e){return e.replace(/[^\w\- ]+/g,"").trim().replace(/\s+/g,"-")||"author"}async syncAuthorFilesToName(){let e=(this.settings.authorId??"").trim(),t=(this.settings.authorName??"").trim();if(!e||!t)return;let i=this.authorNameToSafe(t);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!==e)continue;let l=`${n}/${i}-${e}.md`,c=o;if(o.path!==l)try{this.authorRenameInFlight.add(o.path),this.authorRenameInFlight.add(l),await this.app.fileManager.renameFile(o,l);let d=this.app.vault.getAbstractFileByPath(l);d&&(c=d)}catch(d){this.authorRenameInFlight.delete(o.path),this.authorRenameInFlight.delete(l),console.warn("[Stashpad] author file rename failed",d);continue}try{await this.refreshAuthorStub(c)}catch{}}}}async refreshAuthorStub(e){let t=(this.settings.authorName??"").trim(),i=(this.settings.authorRole??"").trim(),s=(this.settings.authorDepartment??"").trim();if(t)try{let n=await this.app.vault.read(e),o=n.replace(/^# .*$/m,`# ${t}`);o!==n&&await this.app.vault.modify(e,o),await this.app.fileManager.processFrontMatter(e,a=>{a.aliases=[t],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(e,t){let i=this.authorRenameInFlight.delete(e.path),s=this.authorRenameInFlight.delete(t);if(i||s)return;let n=this.parseAuthorFilePath(e.path);if(!n)return;let o=(this.settings.authorId??"").trim();if(!o||n.id!==o)return;let a=n.name.trim();!a||a===(this.settings.authorName??"").trim()||(this.settings.authorName=a,await this.saveSettings(),await this.syncAuthorFilesToName())}async adoptMarkdownDrop(e,t){try{let i=this.app.vault.adapter,s=e.name,n=s.lastIndexOf("."),o=n>0?s.slice(0,n):s,a=n>0?s.slice(n):"",l=0;for(;await i.exists(`${t}/${s}`);)l+=1,s=`${o}-${l}${a}`;let c=`${t}/${s}`;await this.app.fileManager.renameFile(e,c);let d=this.app.vault.getAbstractFileByPath(c);d instanceof N.TFile&&setTimeout(()=>{this.fixOrphanParentForFile(d)},500),this.notifications.show({message:`Imported \`${e.name}\` \u2192 \`${t}\``,kind:"success",category:"import",folder:t,affectedPaths:[c]})}catch(i){console.warn("Stashpad: markdown drop adoption failed",i),this.notifications.show({message:`Couldn't import \`${e.name}\`: ${i.message}`,kind:"error",category:"import"})}}async fixOrphanParentForFile(e){try{let t=this.app.metadataCache.getFileCache(e)?.frontmatter,i=typeof t?.id=="string"?t.id.trim():"",s=t?.parent,n=typeof s=="string"?s.trim()!=="":s!=null,o=typeof t?.created=="string"&&t.created.trim()!=="",a=!i,l=!n,c=!o;if(!a&&!l&&!c)return;let d,h=!1,p=!1;if(await this.app.fileManager.processFrontMatter(e,g=>{if(a&&(typeof g.id=="string"&&g.id.trim()||(d=this.mintNoteId(),g.id=d)),l){let I=g.parent;(typeof I=="string"?I.trim()!=="":I!=null)||(g.parent=S,h=!0)}c&&(typeof g.created=="string"&&g.created.trim()||(g.created=new Date(e.stat.ctime).toISOString(),p=!0))}),!d&&!h&&!p)return;let f=this.newLog(),u=d||i;u&&await f.append({type:"parent_change",id:u,payload:{from:null,to:S,reason:"orphan_auto_fix",path:e.path,addedId:!!d,addedParent:h,addedCreated:p}}),new N.Notice(`Adopted ${e.basename} \u2192 Home`)}catch(t){console.warn("Stashpad: orphan auto-fix failed",t)}}maybeReHomeOnCrossFolderMove(e,t){if(e.extension!=="md")return;let i=e.parent?.path?.replace(/\/+$/,"")??"",s=t.lastIndexOf("/"),n=(s>=0?t.slice(0,s):"").replace(/\/+$/,"");i!==n&&this.discoverStashpadFolders().includes(i)&&(this.reHomePending.has(e.path)||(this.reHomePending.add(e.path),setTimeout(()=>{this.reHomePending.delete(e.path),this.reHomeDanglingParent(e,i)},900)))}async reHomeDanglingParent(e,t){try{let i=this.app.metadataCache.getFileCache(e)?.frontmatter,s=typeof i?.id=="string"?i.id.trim():"",n=typeof i?.parent=="string"?i.parent.trim():"";if(!s||!n||n===S||this.app.vault.getMarkdownFiles().some(a=>(a.parent?.path?.replace(/\/+$/,"")??"")===t&&this.app.metadataCache.getFileCache(a)?.frontmatter?.id===n))return;await this.app.fileManager.processFrontMatter(e,a=>{let l=typeof a.parent=="string"?a.parent.trim():"";l&&l!==S&&(a.parent=S)}),await this.newLog().append({type:"parent_change",id:s,payload:{from:n,to:S,reason:"rehome_cross_folder_move",path:e.path}}),new N.Notice(`Re-homed ${e.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(e,t){try{let i=new Uint8Array(await this.app.vault.readBinary(e));if(Ue(i)){this.importService.parkEncrypted(e.path),this.notifyPendingEncrypted();return}let s=await wi(this.app,i);if(!s)return;let n=Bt(),o=new Set;if(n&&typeof n.collectExistingIds=="function"&&n.noteFolder===t)for(let c of n.collectExistingIds())o.add(c);else for(let c of this.app.vault.getMarkdownFiles()){if(!c.path.startsWith(t+"/"))continue;let d=this.app.metadataCache.getFileCache(c)?.frontmatter?.id;typeof d=="string"&&o.add(d)}let a=await We(this.app,s,t,o,{stripReserved:!0});try{await this.newLog().append({type:"stash_import",id:S,payload:{from:e.path,into:t,noteCount:a.notesWritten,attachmentsWritten:a.attachmentsWritten,collisionsRenamed:a.collisionsRenamed,auto:!0}})}catch{}try{await this.app.fileManager.trashFile(e)}catch{}let l=[`Auto-imported ${a.notesWritten} note${a.notesWritten===1?"":"s"} from ${e.name}`];a.attachmentsWritten&&l.push(`+ ${a.attachmentsWritten} attachment${a.attachmentsWritten===1?"":"s"}`),a.collisionsRenamed&&l.push(`(${a.collisionsRenamed} renamed)`),this.notifications.show({message:l.join(" "),kind:"success",category:"import",folder:t}),n&&typeof n.debouncedRender=="function"&&n.debouncedRender()}catch(i){this.notifications.show({message:`Stashpad: auto-import failed File: \`${e.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:[e.path],actions:ts(this.app,e.path,N.Platform.isMobile)}),console.error(i)}}lookupNoteAuthorIds(e){let t=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!==e)continue;let o=i(n?.author);o&&t.add(o);let a=n?.contributors;if(Array.isArray(a))for(let l of a){let c=i(l);c&&t.add(c)}break}return Array.from(t)}lookupNoteAuthorId(e){return this.lookupNoteAuthorIds(e)[0]??null}async runRebootstrapWithUI(){let t=new N.Notice("",0).noticeEl;t.empty(),t.addClass("stashpad-progress-notice"),t.createDiv({cls:"stashpad-progress-title",text:"Rebootstrapping Stashpad folders\u2026"});let s=t.createDiv({cls:"stashpad-progress-bar"}).createDiv({cls:"stashpad-progress-fill"}),n=t.createDiv({cls:"stashpad-progress-sub",text:"Counting notes\u2026"}),o=(a,l,c)=>{let A=l>0?Math.min(100,Math.round(a/l*100)):0;s.style.width=`${A}%`,n.setText(c?`${c} \xB7 ${A}%`:`${A}%`)};try{let a=await this.rebootstrapAllFolders(o),l=a.imported+a.attachmentsLinked+a.attachmentsRenamed+a.fmWritten+a.slugsRenamed,c=[];return c.push(`Checked ${a.touched.length} folder${a.touched.length===1?"":"s"} (${a.fmChecked} note${a.fmChecked===1?"":"s"})`),l===0?c.push("everything already in sync \u2014 no changes needed"):(a.fmWritten>0&&c.push(`updated frontmatter on ${a.fmWritten} note${a.fmWritten===1?"":"s"}`),a.slugsRenamed>0&&c.push(`renamed ${a.slugsRenamed} note${a.slugsRenamed===1?"":"s"} to match body`),a.imported>0&&c.push(`imported ${a.imported} loose file${a.imported===1?"":"s"}`),a.attachmentsLinked>0&&c.push(`linked attachments on ${a.attachmentsLinked} note${a.attachmentsLinked===1?"":"s"}`),a.attachmentsRenamed>0&&c.push(`renamed ${a.attachmentsRenamed} attachment${a.attachmentsRenamed===1?"":"s"}`)),a.authors>0&&c.push(`${a.authors} author${a.authors===1?"":"s"} in registry`),t.empty(),t.removeClass("stashpad-progress-notice"),t.addClass("stashpad-progress-done"),t.createDiv({cls:"stashpad-progress-title",text:"\u2713 Rebootstrap complete"}),t.createDiv({cls:"stashpad-progress-sub",text:`${c.join("; ")}.`}),a.attachmentsSkipped>0&&new N.Notice(`Stashpad: ${a.attachmentsSkipped} attachment${a.attachmentsSkipped===1?"":"s"} need renaming, but skipped to protect links. Enable Settings \u2192 Files & Links \u2192 \u201CAutomatically update internal links\u201D, then rebootstrap again.`,12e3),a}catch(a){throw t.empty(),t.removeClass("stashpad-progress-notice"),t.addClass("stashpad-progress-error"),t.createDiv({cls:"stashpad-progress-title",text:"Rebootstrap failed"}),t.createDiv({cls:"stashpad-progress-sub",text:a.message}),a}}async rebootstrapAllFolders(e){this.rebootstrapInProgress=!0;try{return await this.rebootstrapAllFoldersInner(e)}finally{window.setTimeout(()=>{this.rebootstrapInProgress=!1;for(let t of this.app.workspace.getLeavesOfType(z))t.view?.forceReconcileRender?.()},2500)}}async rebootstrapAllFoldersInner(e){let t="__root__",i=new Set;for(let y of this.app.vault.getMarkdownFiles()){if(this.app.metadataCache.getFileCache(y)?.frontmatter?.id!==t)continue;let Q=y.parent?.path;Q&&i.add(Q)}let s=new Map;for(let y of this.app.vault.getMarkdownFiles()){let v=y.parent?.path;v&&i.has(v)&&s.set(v,(s.get(v)??0)+1)}let n=Math.max(1,[...s.values()].reduce((y,v)=>y+v,0)),o=0;e?.(0,n,"Starting\u2026");let a=(this.settings.importDropFolder||"").trim().replace(/^\/+|\/+$/g,""),l=(this.settings.exportFolder||"").trim().replace(/^\/+|\/+$/g,""),c=[],A=async y=>{if(y&&!await this.app.vault.adapter.exists(y))try{await this.app.vault.createFolder(y)}catch(v){let Q=v?.message??"";if(!/already exists/i.test(Q))throw v}},h=0,p=0,f=0,u=0,g=0,I=0,m=!!this.app.vault.getConfig?.("alwaysUpdateLinks"),C=new Set(this.okfActiveFolders());for(let y of i){let v=s.get(y)??1;e?.(o,n,`Processing \u201C${y.split("/").pop()||y}\u201D (${v} note${v===1?"":"s"})`);try{if(a&&await A(`${y}/${a}`),l&&await A(`${y}/${l}`),this.settings.autoImport)try{let F=await this.importService.importLooseInto(y);u+=F.files+F.folders+F.stashes}catch(F){console.warn("Stashpad: loose sweep failed",y,F)}let Q=await Pi(this.app,y);h+=Q.checked,p+=Q.written,f+=await this.rebootstrapFolderSlugs(y);let w=await this.rebootstrapFolderAttachments(y,m);if(g+=w.renamed,I+=w.skipped,C.has(y.replace(/\/+$/,"")))try{await Ta(this.app,y)}catch(F){console.warn("Stashpad: OKF rebuild during rebootstrap failed",y,F)}c.push(y)}catch(Q){console.warn(`Stashpad: rebootstrap skipped ${y}`,Q)}finally{o+=v,e?.(o,n,`Processing \u201C${y.split("/").pop()||y}\u201D`)}}e?.(n,n,"Finalizing\u2026");let B=0;try{B=(await this.rebuildAuthorRegistry()).total}catch(y){console.warn("Stashpad: rebootstrap author-registry rebuild failed",y)}let E=0;try{E=await this.convertAttachmentsToLinks()}catch(y){console.warn("Stashpad: attachment-link conversion failed",y)}return{touched:c,fmChecked:h,fmWritten:p,slugsRenamed:f,authors:B,imported:u,attachmentsLinked:E,attachmentsRenamed:g,attachmentsSkipped:I}}async rebootstrapFolderSlugs(e){let t="__root__",i=e.replace(/\/+$/,""),s=this.settings.slugStopWords??st,n=0,o=this.app.vault.getMarkdownFiles().filter(a=>(a.parent?.path?.replace(/\/+$/,"")??"")===i);for(let a of o){let l=this.app.metadataCache.getFileCache(a)?.frontmatter?.id,c=typeof l=="string"?l:null,h=nt(a.basename)??(ji(c)?c:null);if(!(!h||h===t)&&c===h)try{let p=await this.app.vault.cachedRead(a),f=p.startsWith("---")?p.slice(p.indexOf(` ----`,3)+4).replace(/^\r?\n/,""):p,u=xe(f,s),g=Ne(u,h);if(a.name===g)continue;let I=a.parent?`${a.parent.path}/${g}`:g;if(this.app.vault.getAbstractFileByPath(I))continue;await this.app.fileManager.renameFile(a,I),n+=1}catch(p){console.warn(`Stashpad: slug rebootstrap skipped ${a.path}`,p)}}return n}async rebootstrapFolderAttachments(e,t){let i=`${e.replace(/\/+$/,"")}/_attachments`,s=this.app.vault.getAbstractFileByPath(i);if(!(s instanceof N.TFolder))return{renamed:0,skipped:0};let n=s.children.filter(l=>l instanceof N.TFile),o=0,a=0;for(let l of n){let c=rr(l.name);if(!c)continue;let A=zs(c.rest,c.stamp);if(l.name===A)continue;if(!t){a+=1;continue}let h=`${i}/${A}`;if(!this.app.vault.getAbstractFileByPath(h))try{await this.app.fileManager.renameFile(l,h),o+=1,await new Promise(p=>setTimeout(p,30))}catch(p){console.warn(`Stashpad: attachment rebootstrap skipped ${l.path}`,p)}}return{renamed:o,skipped:a}}onStashpadSelectionChange(e){return this.stashpadSelectionListeners.add(e),()=>this.stashpadSelectionListeners.delete(e)}notifyStashpadSelectionChanged(){for(let e of this.stashpadSelectionListeners)try{e()}catch(t){console.warn("[Stashpad] selection listener failed",t)}}onStashpadContentChange(e){return this.stashpadContentListeners.add(e),()=>this.stashpadContentListeners.delete(e)}notifyStashpadContentChanged(){for(let e of this.stashpadContentListeners)try{e()}catch(t){console.warn("[Stashpad] content listener failed",t)}}getActiveStashpadSelection(){let t=this.lastActiveStashpadLeaf?.view;if(!t||t.getViewType?.()!==z)return null;let i=t.noteFolder??"";if(!i)return null;let s=t.currentChildren??[],n;if(typeof t.cursorIdx=="number"&&t.cursorIdx>=0&&(n=s[t.cursorIdx]),!n&&t.selection?.size>0){let o=t.firstSelectedId??[...t.selection][0];n=s.find(a=>a.id===o)}return n?.file?{folder:i,id:n.id,file:n.file}:null}fileForPin(e,t){let i=e.replace(/\/+$/,"");for(let s of this.app.vault.getMarkdownFiles())if((s.parent?.path?.replace(/\/+$/,"")??"")===i&&this.app.metadataCache.getFileCache(s)?.frontmatter?.id===t)return s;return null}async pinNote(e){let t=this.fileForPin(e.folder,e.id);t&&this.app.metadataCache.getFileCache(t)?.frontmatter?.pinned!==!0&&(await this.app.fileManager.processFrontMatter(t,i=>{i.pinned=!0,i.pinnedAt=Date.now()}),this.refreshPanelsView())}async unpinNote(e){let t=this.fileForPin(e.folder,e.id);t&&this.app.metadataCache.getFileCache(t)?.frontmatter?.pinned===!0&&(await this.app.fileManager.processFrontMatter(t,i=>{delete i.pinned,delete i.pinnedAt}),this.refreshPanelsView())}isPinned(e){let t=this.fileForPin(e.folder,e.id);return t?this.app.metadataCache.getFileCache(t)?.frontmatter?.pinned===!0:!1}listPinnedNotes(){let e=new Set(this.discoverStashpadFolders()),t=[];for(let i of this.app.vault.getMarkdownFiles()){let s=i.parent?.path?.replace(/\/+$/,"")??"";if(!e.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;t.push({folder:s,id:n.id,pinnedAt:o,file:i})}return t.sort((i,s)=>i.pinnedAt-s.pinnedAt||i.file.path.localeCompare(s.file.path)),t}async migratePinnedNotesToFrontmatter(){let e=this.settings.pinnedNotes??[];if(e.length===0)return;let t=Date.now()-e.length*1e3;for(let i of e){let s=this.fileForPin(i.folder,i.id);if(!s){t+=1e3;continue}try{if(this.app.metadataCache.getFileCache(s)?.frontmatter?.pinned!==!0){let n=t;await this.app.fileManager.processFrontMatter(s,o=>{o.pinned=!0,o.pinnedAt=n})}}catch(n){console.warn("[Stashpad] pin migration failed for",i,n)}t+=1e3}this.settings.pinnedNotes=[],await this.saveSettings(),this.refreshPanelsView()}refreshPanelsView(){let e=this.app.workspace.getLeavesOfType(St);for(let t of e){let i=t.view;i&&typeof i.render=="function"&&i.render()}}refreshAllStashpadViews(){for(let e of this.app.workspace.getLeavesOfType(z)){let t=e.view;t&&typeof t.render=="function"&&t.render()}}refreshFolderPanels(){for(let e of this.app.workspace.getLeavesOfType(bt)){let t=e.view;t&&typeof t.refresh=="function"&&t.refresh()}}getFolderIcon(e){let t=(e||"").replace(/\/+$/,""),i=this.settings.folderIcons?.[t];return i&&i.trim()?i.trim():void 0}async setFolderIcon(e,t){let i=(e||"").replace(/\/+$/,""),s={...this.settings.folderIcons??{}};t&&t.trim()?s[i]=t.trim():delete s[i],this.settings.folderIcons=s,await this.saveSettings(),this.refreshFolderIconFor(i)}refreshFolderIconFor(e){let t=(e||"").replace(/\/+$/,"");for(let i of this.app.workspace.getLeavesOfType(z)){let s=i.view;if(s&&(s.noteFolder||"").replace(/\/+$/,"")===t){try{i.updateHeader?.()}catch{}try{s.refreshFolderSwitcherIcon?.()}catch{}}}this.refreshFolderPanels()}openFolderPicker(){let e=I=>{let C=I.getViewState().state?.folderOverride;return typeof C=="string"&&C.trim()?C.trim().replace(/^\/+|\/+$/g,""):(this.settings.folder||"Stashpad").trim().replace(/^\/+|\/+$/g,"")},t=this.app.workspace.getLeavesOfType(z),i=this.discoverStashpadFolders(),s=Bt(),n=s?(s.noteFolder??"").trim().replace(/^\/+|\/+$/g,""):"",o=new Set;for(let I of this.app.vault.getAllLoadedFiles())if(I.children){let m=I.path;m&&m!=="/"&&!m.startsWith(".")&&o.add(m)}let a=I=>{let m=I.split("/").filter(Boolean).pop()??"";return m?new Set([this.settings.importDropFolder,this.settings.exportFolder,"_attachments","_processed","_authors","_exports","_imports","_archive",".archive","_deleted"].map(B=>(B??"").trim().replace(/^\/+|\/+$/g,"")).filter(Boolean)).has(m):!1},l=new Set,c=[],A=[],h=new Set;for(let I of t){let m=e(I);if(h.has(m))continue;h.add(m),l.add(m);let C=m.split("/").pop()||m;if(this.settings.foldersAlwaysNewTab){c.push({kind:"open",folder:m,label:`Open "${C}" in new tab`,icon:this.isArchiveFolder(m)?"archive":"layout-template"});continue}c.push({kind:"reveal",folder:m,label:`Reveal "${C}" tab`,leaf:I,icon:this.isArchiveFolder(m)?"archive":"layout-grid"}),A.push({kind:"open-anyway",folder:m,label:`Open "${C}" in another new tab`,icon:"layout-template"})}for(let I of i.filter(m=>!l.has(m))){let m=I.split("/").pop()||I;c.push({kind:"open",folder:I,label:`Open "${m}" in new tab`,icon:this.isArchiveFolder(I)?"archive":"layout-template"})}let p=I=>I.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ").trim()||I.basename,f=this.settings.folderSwitcherIncludePinned?this.listPinnedNotes().map(I=>({kind:"pinned",folder:I.folder,file:I.file,label:p(I.file),icon:"pin"})):[],u=this,g=new class extends N.SuggestModal{getSuggestions(I){let m=I.trim().toLowerCase(),C=m?m.split(/\s+/).filter(Boolean):[],B=Q=>{if(!C.length)return!0;let w=Q.toLowerCase();for(let F of C)if(!w.includes(F))return!1;return!0},E=m?c.filter(Q=>{let w="folder"in Q?Q.folder:"";return B(Q.label)||B(w)}):c.slice();if(m&&s&&n)for(let Q of i){if(Q.toLowerCase()===n.toLowerCase())continue;let w=Q.split("/").pop()??Q,F=`${Q} ${w}`;B(F)&&E.push({kind:"switch-current",folder:Q,label:`Switch this tab to "${w}"`,icon:"folder-input"})}for(let Q of f)(B(Q.label)||B("folder"in Q?Q.folder:""))&&E.push(Q);let y=I.trim().replace(/^\/+|\/+$/g,"");if(y&&!a(y)){let Q=Array.from(o).find(F=>F.toLowerCase()===y.toLowerCase()),w=i.some(F=>F.toLowerCase()===y.toLowerCase());if(Q&&!w)E.push({kind:"convert",folder:Q,label:`Convert \u201C${Xi(Q)}\u201D into a Stashpad\u2026`,icon:"folder-cog"});else if(!Q){let F=Xi(y);E.push({kind:"create",folder:y,label:`+ Create new Stashpad \u201C${F}\u201D`,icon:"folder-plus"})}}let v=A.filter(Q=>B(Q.label)||B("folder"in Q?Q.folder:""));return E.push(...v),B("trash deleted encrypted")&&E.push({kind:"trash",label:"Open Trash",icon:"trash-2"}),E}renderSuggestion(I,m){m.addClass("stashpad-suggest-item"),m.addClass("stashpad-ribbon-suggest-item"),I.kind==="create"&&m.addClass("stashpad-suggest-create");let C=m.createSpan({cls:"stashpad-ribbon-suggest-icon"});(0,N.setIcon)(C,I.icon);let B=m.createDiv({cls:"stashpad-ribbon-suggest-body"});B.createDiv({cls:"stashpad-suggest-title",text:I.label}),"folder"in I&&I.folder&&I.label!==I.folder&&B.createDiv({cls:"stashpad-suggest-preview",text:I.folder})}async onChooseSuggestion(I){if(I.kind==="trash"){u.openEncryptedTrash();return}if(I.kind==="pinned"){await u.revealNoteInStashpad(I.file);return}if(I.kind==="reveal"){u.app.workspace.revealLeaf(I.leaf);return}if(I.kind==="open"||I.kind==="open-anyway"){await u.activateViewForFolder(I.folder);return}if(I.kind==="switch-current"){let m=s;m&&typeof m.setFolderOverride=="function"&&(await m.setFolderOverride(I.folder),u.app.workspace.revealLeaf(m.leaf));return}if(I.kind==="create"){try{let m=Xi(I.folder);await u.app.vault.adapter.exists(m)||await u.app.vault.createFolder(m),await u.activateViewForFolder(m)}catch(m){new N.Notice(`Stashpad: couldn't create folder (${m.message})`)}return}if(I.kind==="convert"){let{ConfirmModal:m}=await Promise.resolve().then(()=>(ve(),ms)),C=I.folder,B=[`\u201C${C}\u201D already exists as a regular vault folder.`,"Converting adds a Home note + _imports / _exports subfolders, and imports the existing loose files and subfolders inside it as notes.","(Files already structured as notes, and reserved subfolders, are left alone.)"];new m(u.app,"Convert into a Stashpad?",B.join(` -`),"Convert & import",async E=>{if(E)try{await u.activateViewForFolder(C),await u.runImportLooseFiles(C)}catch(y){new N.Notice(`Stashpad: couldn't convert folder (${y.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 e=Bt(),t=e?.folderOverride??null,i=e?.focusId??"__root__",s=!!e?.compactMode,n=this.app.workspace.openPopoutLeaf?.();if(!n){new N.Notice("Stashpad: couldn't open popout window on this build.");return}await n.setViewState({type:z,active:!0,state:{folderOverride:t,focusId:i,tinyMode:!0,tinyAlwaysOnTop:!1,compactMode:s}});try{this.app.workspace.revealLeaf(n)}catch{}}async activateView(e={reveal:!0}){let{workspace:t}=this.app;if(e.reveal){let s=t.getLeavesOfType(z);if(s.length>0){t.revealLeaf(s[0]);return}}let i=t.getLeaf("tab");await i.setViewState({type:z,active:!0}),t.revealLeaf(i)}async focusLastStashpadTab(){let e=this.app.workspace,t=e.getLeavesOfType(z),i=this.lastActiveStashpadLeaf&&t.includes(this.lastActiveStashpadLeaf)?this.lastActiveStashpadLeaf:t[0]??null;if(!i){await this.activateView({reveal:!0});return}e.revealLeaf(i),e.setActiveLeaf(i,{focus:!0})}async focusFolderPanel(){await to(this.app);let e=this.app.workspace.getLeavesOfType(bt)[0];e&&this.app.workspace.setActiveLeaf(e,{focus:!0})}async reconcileLockedRegistry(){let e=this.settings.lockedSubtrees??[],t=[];for(let n of e){let o=(n.folder??"").replace(/\/+$/,"");if(!(o==="_deleted"||o.startsWith("_deleted/")))try{await this.app.vault.adapter.exists(n.blob)&&t.push(n)}catch{t.push(n)}}let i=t.length!==e.length,s=new Set(t.map(n=>n.blob));for(let n of this.app.vault.getFiles()){if(n.extension!=="stashenc"||s.has(n.path))continue;let o=n.parent?.path?.replace(/\/+$/,"")??"";if(o==="_deleted"||o.startsWith("_deleted/"))continue;let a=await zn(this.app,n.path);a&&(t.push({folder:o,blob:n.path,parentId:a.parentId,title:a.title,count:a.count,created:a.created,rootId:a.rootId,prevSibling:a.prevSibling}),i=!0)}i&&(this.settings.lockedSubtrees=t,await this.saveSettings(),this.refreshAllStashpadViews?.())}lockedSubtreesFor(e,t){let i=e.replace(/\/+$/,""),s=[],n=new Set;for(let o of this.settings.lockedSubtrees??[])(o.folder??"").replace(/\/+$/,"")===i&&(o.parentId??S)===t&&(s.push({blob:o.blob,title:o.title??"",count:o.count??0,created:o.created??"",rootId:o.rootId,parentId:o.parentId??S,prevSibling:o.prevSibling??null}),n.add(o.blob));for(let o of this.app.vault.getFiles()){if(o.extension!=="stashenc"||n.has(o.path))continue;let a=o.parent?.path?.replace(/\/+$/,"")??"";a!==i||a==="_deleted"||a.startsWith("_deleted/")||t===S&&s.push({blob:o.path,title:o.basename,count:0,created:"",rootId:void 0,parentId:S,prevSibling:null})}return s}lockedSubtreesInFolder(e){let t=e.replace(/\/+$/,""),i=[],s=new Set;for(let n of this.settings.lockedSubtrees??[])(n.folder??"").replace(/\/+$/,"")===t&&(i.push({blob:n.blob,title:n.title??"",count:n.count??0,created:n.created??"",rootId:n.rootId,parentId:n.parentId??S}),s.add(n.blob));for(let n of this.app.vault.getFiles()){if(n.extension!=="stashenc"||s.has(n.path))continue;let o=n.parent?.path?.replace(/\/+$/,"")??"";o!==t||o==="_deleted"||o.startsWith("_deleted/")||i.push({blob:n.path,title:n.basename,count:0,created:"",rootId:void 0,parentId:S})}return i}async ensureFolderUnlocked(e){if(!this.encryption.hasFolderKey(e))return new N.Notice("This folder isn't encrypted. Give it a password in Settings \u2192 Stashpad \u2192 Encryption \u2192 Per-Folder Passwords."),null;if(this.encryption.isFolderUnlocked(e))return this.encryption.getFolderKey(e);if(await this.encryption.tryAutoUnlockFolder(e))return this.encryption.getFolderKey(e);let t=e.split("/").pop()||e;return await new Promise(s=>{new Le(this.app,{mode:"unlock",offerKeychain:!0,title:`Unlock \u201C${t}\u201D`,intro:"Enter this folder's password.",onSubmit:async({current:n,remember:o})=>await this.encryption.unlockFolder(e,n,o)?(s(!0),null):"Wrong password. Try again.",onCancel:()=>s(!1)}).open()})?this.encryption.getFolderKey(e):null}isTrashBlobPath(e){let t=e.replace(/\/[^/]*$/,"").replace(/\/+$/,"");return t==="_deleted"||t.startsWith("_deleted/")||t==="trash"||t.endsWith("/trash")}encryptionState(){let e=s=>this.isTrashBlobPath(s),t=!1,i=!1;for(let s of this.app.vault.getFiles())if(s.extension==="stashenc"&&(e(s.path)?i=!0:t=!0,t&&i))return{live:t,trash:i};for(let s of this.pendingEncBlobs)if(e(s)?i=!0:t=!0,t&&i)break;return{live:t,trash:i}}async encryptionStateStrict(){let e=this.encryptionState(),t=e.trash;if(!t)try{t=(await Wn(this.app,this.trashSubfolderDirs())).length>0}catch{}if(!t)try{t=(await this.app.vault.adapter.list(si)).files.some(s=>s.endsWith(".stashenc"))}catch{}return{live:e.live,trash:t}}watchReEncrypt(e){let t=e.folder.replace(/\/+$/,""),i=(this.settings.reEncryptWatch??[]).filter(s=>!(s.folder===t&&s.rootId===e.rootId));this.settings.reEncryptWatch=[...i,{folder:t,rootId:e.rootId,title:e.title,count:e.count,via:e.via,unlockedAt:new Date().toISOString()}]}reEncryptDisplayTitle(e){if(e.title&&e.title.trim())return e.title.trim();if(e.rootId){let t=e.folder.replace(/\/+$/,""),i=this.app.vault.getMarkdownFiles().find(s=>(s.parent?.path?.replace(/\/+$/,"")??"")===t&&nt(s.name)===e.rootId);if(i){let s=this.app.metadataCache.getFileCache(i)?.headings?.find(o=>o.level===1)?.heading;if(s&&s.trim())return s.trim();let n=i.basename.replace(new RegExp(`[-_]+${e.rootId}$`),"").replace(/[-_]+/g," ").trim();if(n)return n}}return"(untitled)"}unwatchReEncrypt(e,t){let i=e.replace(/\/+$/,""),s=this.settings.reEncryptWatch??[],n=s.filter(o=>!(o.folder===i&&o.rootId===t));n.length!==s.length&&(this.settings.reEncryptWatch=n)}reEncryptWatching(){return(this.settings.reEncryptWatch??[]).filter(e=>!e.removed)}pruneReEncryptWatch(){let e=this.settings.reEncryptWatch??[];if(e.length===0)return!1;let t=n=>{let o=new Set;for(let a of this.app.vault.getMarkdownFiles()){if((a.parent?.path?.replace(/\/+$/,"")??"")!==n)continue;let l=this.app.metadataCache.getFileCache(a)?.frontmatter?.id;typeof l=="string"&&o.add(l)}return o},i=new Map,s=e.filter(n=>{let o=n.folder.replace(/\/+$/,"");return i.has(o)||i.set(o,t(o)),i.get(o).has(n.rootId)});return s.length===e.length?!1:(this.settings.reEncryptWatch=s,!0)}async encryptEverythingApplicable(){this.pruneReEncryptWatch()&&await this.saveSettings();let e=[];for(let i of this.reEncryptWatching())e.push({label:this.reEncryptDisplayTitle(i),detail:`${i.folder} \u2014 ${i.via==="restore"?"restored from trash":"unlocked"} (was encrypted)`,run:async()=>!!await this.lockNoteSubtree(i.folder,i.rootId,null,{silent:!0})});let t=new Set((this.settings.lockedSubtrees??[]).map(i=>i.rootId));for(let[i,s]of Object.entries(this.settings.folderEncPrefs??{})){if(!s?.encryptContent)continue;let n=this.app.vault.getMarkdownFiles().filter(o=>{if((o.parent?.path?.replace(/\/+$/,"")??"")!==i)return!1;let a=this.app.metadataCache.getFileCache(o)?.frontmatter?.id;return typeof a=="string"&&a!==S&&!t.has(a)}).length;n>0&&e.push({label:`Everything in \u201C${i.split("/").pop()||i}\u201D (${n} plaintext note${n===1?"":"s"})`,detail:`${i} \u2014 the folder is set to encrypt its notes`,run:async()=>(await this.lockFolder(i),!0)})}for(let[i,s]of Object.entries(this.settings.folderEncPrefs??{})){if(!s?.archiveEncryptContent)continue;let n=this.archivedPlainNotesIn(Dt(i)).length;n>0&&e.push({label:`${n} archived note${n===1?"":"s"} in \u201C${i.split("/").pop()||i}/archive\u201D`,detail:`${i} \u2014 the folder encrypts its archive`,run:async()=>(await this.encryptExistingArchiveNotes(i),!0)})}if(e.length===0){new N.Notice("Nothing needs re-encrypting \u2014 everything applicable is already locked.");return}new fs(this.app,e.map(({label:i,detail:s})=>({label:i,detail:s})),async i=>{let s=0,n=0,o=i.length>2?new N.Notice("",0):null;for(let a=0;a<i.length;a++){o?.setMessage(`\u{1F512} Re-encrypting ${a+1}/${i.length}\u2026`);try{await e[i[a]].run()?s++:n++}catch(l){n++,console.warn("[Stashpad] sweep item failed",e[i[a]].label,l)}}o?.hide(),this.notifications.show({message:`Re-encrypt sweep: ${s} done${n?`, ${n} FAILED (see console)`:""}, ${e.length-i.length} skipped.`,kind:n?"warning":"success",category:"system",folder:""})}).open()}async lockNoteSubtree(e,t,i=null,s={}){let n=(s.blobFolder??e).replace(/\/+$/,""),o=await this.ensureFolderUnlocked(n);if(!o)return null;try{let a=!!s.blobFolder&&s.blobFolder.replace(/\/+$/,"")!==e.replace(/\/+$/,""),l=(this.settings.folderEncPrefs??{})[n]??{},c=s.hideTitle??(a?l.archiveEncryptFilenames:l.encryptFilenames)??!1,A=await Ml(this.app,e,t,o,i,c,s.blobFolder);this.pendingEncBlobs.add(A.blobPath);let h=(s.blobFolder??e).replace(/\/+$/,"");return this.settings.lockedSubtrees=[...(this.settings.lockedSubtrees??[]).filter(p=>p.blob!==A.blobPath),{folder:h,blob:A.blobPath,parentId:A.parentId,title:A.title,count:A.noteCount,created:A.created,rootId:A.rootId,prevSibling:i}],this.unwatchReEncrypt(e,A.rootId),this.unwatchReEncrypt(h,A.rootId),await this.saveSettings(),A.unpurged.length>0?new N.Notice(`\u26A0\uFE0F Locked, but ${A.unpurged.length} file${A.unpurged.length===1?" is":"s are"} still in plaintext (couldn't be removed or changed during the lock): -${A.unpurged.join(` -`)}`,0):s.silent||this.notifications.show({message:`Locked ${A.title?`\u201C${A.title}\u201D`:"a note"} (${A.noteCount} note${A.noteCount===1?"":"s"}).`,kind:"success",category:"system",folder:e}),A}catch(a){return console.warn("[Stashpad] lock failed",a),new N.Notice(`Couldn't lock: ${a.message}`),null}}async unlockBundleCore(e,t,i){let s=(i??e.replace(/\/[^/]*$/,"")).replace(/\/+$/,""),n=new Set;for(let o of this.app.vault.getMarkdownFiles())if((o.parent?.path?.replace(/\/+$/,"")??"")===s)try{let a=ge(await this.app.vault.read(o)).fm.id;typeof a=="string"&&n.add(a)}catch{}return Pl(this.app,e,t,n,i)}async unlockBundleAt(e,t={}){let i=e.replace(/\/[^/]*$/,"").replace(/\/+$/,""),s=await this.ensureFolderUnlocked(i);if(!s)return!1;let n=(t.destFolder??e.replace(/\/[^/]*$/,"")).replace(/\/+$/,"");try{let o=await this.unlockBundleCore(e,s,t.destFolder);this.pendingEncBlobs.delete(e);let a=(this.settings.lockedSubtrees??[]).find(l=>l.blob===e);return a?.rootId&&this.watchReEncrypt({folder:n,rootId:a.rootId,title:a.title??"",count:a.count??o.notesWritten,via:"unlock"}),this.settings.lockedSubtrees=(this.settings.lockedSubtrees??[]).filter(l=>l.blob!==e),await this.saveSettings(),t.silent||this.notifications.show({message:`Unlocked ${o.notesWritten} note${o.notesWritten===1?"":"s"}.`,kind:"success",category:"system",folder:n}),!0}catch(o){return console.warn("[Stashpad] unlock failed",o),new N.Notice(`Couldn't unlock: ${o.message}`),!1}}async lockFolder(e){let t=e.replace(/\/+$/,"");if(!await this.ensureFolderUnlocked(t))return 0;let i=[];for(let A of this.app.vault.getMarkdownFiles()){if((A.parent?.path?.replace(/\/+$/,"")??"")!==t)continue;let h;try{h=ge(await this.app.vault.read(A)).fm}catch{continue}let p=h.id;typeof p!="string"||p===S||(typeof h.parent=="string"?h.parent:S)!==S||i.push(p)}let s=new Set((this.settings.lockedSubtrees??[]).map(A=>A.rootId).filter(A=>!!A)),n=i.filter(A=>!s.has(A));if(n.length===0)return new N.Notice("Nothing to lock in this folder."),0;let a=(await new xi(this.app).load(t))[S]??[],l=n.length>3?new N.Notice("",0):null,c=0;for(let A=0;A<n.length;A++){let h=n[A];l?.setMessage(`\u{1F512} Encrypting ${A+1}/${n.length}\u2026`);let p=a.indexOf(h),f=p>0?a[p-1]:null;await this.lockNoteSubtree(t,h,f,{silent:!0})&&c++}return l?.hide(),c>0&&this.notifications.show({message:`Locked ${c} note${c===1?"":"s"} in \u201C${t.split("/").pop()}\u201D.`,kind:"success",category:"system",folder:t,actions:[{label:"All encrypted",onClick:()=>void He(this,"encrypted")}]}),c}async unlockFolder(e){let t=e.replace(/\/+$/,"");if(!await this.ensureFolderUnlocked(t))return 0;let i=this.app.vault.getFiles().filter(o=>o.extension==="stashenc"&&(o.parent?.path?.replace(/\/+$/,"")??"")===t).map(o=>o.path);if(i.length===0)return new N.Notice("No locked notes in this folder."),0;let s=i.length>3?new N.Notice("",0):null,n=0;for(let o=0;o<i.length;o++){s?.setMessage(`\u{1F513} Decrypting ${o+1}/${i.length}\u2026`);try{await this.unlockBundleAt(i[o],{silent:!0})&&n++}catch(a){console.warn("[Stashpad] folder unlock skipped",i[o],a)}}return s?.hide(),n>0&&this.notifications.show({message:`Unlocked ${n} note${n===1?"":"s"} in \u201C${t.split("/").pop()}\u201D.`,kind:"success",category:"system",folder:t}),n}async unlockAllInVault(){if(!this.encryption.isConfigured())return new N.Notice("Set up encryption first (Settings \u2192 Stashpad \u2192 Encryption)."),0;let e=this.app.vault.getFiles().filter(c=>c.extension==="stashenc"&&!this.isTrashBlobPath(c.path)).map(c=>c.path);if(e.length===0)return new N.Notice("No locked notes anywhere in the vault."),0;let t=e.length>3?new N.Notice("",0):null,i=new Map,s=async c=>{if(i.has(c))return i.get(c);let A=null;return this.encryption.hasFolderKey(c)&&(this.encryption.isFolderUnlocked(c)||await this.encryption.tryAutoUnlockFolder(c))&&(A=this.encryption.getFolderKey(c)),i.set(c,A),A},n=0,o=[],a=new Set;for(let c=0;c<e.length;c++){t?.setMessage(`\u{1F513} Decrypting ${c+1}/${e.length}\u2026`);let A=e[c].replace(/\/[^/]*$/,"").replace(/\/+$/,""),h=await s(A);if(!h){a.add(A||"(vault root)");continue}try{let p=await this.unlockBundleCore(e[c],h);n+=p.notesWritten,o.push(e[c])}catch(p){console.warn("[Stashpad] vault unlock skipped",e[c],p)}}if(o.length>0){let c=new Set(o);this.settings.lockedSubtrees=(this.settings.lockedSubtrees??[]).filter(A=>!c.has(A.blob)),await this.saveSettings()}t?.hide();for(let c of i.values())try{c?.fill(0)}catch{}let l=e[0].replace(/\/[^/]*$/,"");return n>0&&this.notifications.show({message:`Unlocked ${n} note${n===1?"":"s"} across the vault.`,kind:"success",category:"system",folder:l}),a.size>0&&new N.Notice(`Skipped ${a.size} locked folder${a.size===1?"":"s"} (no key unlocked): ${[...a].map(c=>c.split("/").pop()||c).join(", ")}. Open each to unlock it, then run this again.`,0),n}exportLockedSubtree(e){return zl(this,e)}async openWorkbench(e,t,i){let s=this.app.workspace.getMostRecentLeaf(),n=this.app.workspace.getLeaf("tab");await n.setViewState({type:Is,active:!0}),n.view instanceof Si&&n.view.setContext({body:e,cbs:t,init:i,prevLeaf:s}),this.app.workspace.revealLeaf(n)}folderHasStashpadNotes(e){let t=e.replace(/\/+$/,"");return this.discoverStashpadFolders().some(i=>t===i||t.startsWith(i+"/")||i.startsWith(t+"/"))}encStamp(){let e=new Date,t=i=>String(i).padStart(2,"0");return`${e.getFullYear()}${t(e.getMonth()+1)}${t(e.getDate())}-${t(e.getHours())}${t(e.getMinutes())}`}folderKeyLabelFor(e){let t=(this.settings.authorName||"").trim(),i=t?t.split(/\s+/).map(s=>s[0]).join(""):(this.settings.authorId||"anon").slice(0,4);return`${this.encStamp()} - ${e} - ${i}`}async encryptFolderFromExplorer(e){let t=e.split("/").pop()||e;if(this.folderHasStashpadNotes(e)){await this.encryptStashpadFolder(e,t);return}if(await ka(this.app,e)){new N.Notice(`\u201C${t}\u201D is already encrypted as a Stashpad bundle. Use \u201CDecrypt with Stashpad\u201D to open it.`);return}await this.encryptRawFolder(e,t)}async encryptStashpadFolder(e,t){if(this.encryption.hasOwnFolderKey(e)){await this.ensureFolderUnlocked(e)&&await this.lockFolder(e);return}let i=this.folderKeyLabelFor(t);new Le(this.app,{mode:"setup",offerKeychain:!0,title:`Encrypt \u201C${t}\u201D with Stashpad`,intro:"Give this folder its own password. Any Stashpad notes inside it get encrypted under it; you'll re-enter the password to unlock.",onSubmit:async({next:s,remember:n})=>{if(!s)return"Enter a password.";try{await this.encryption.setupFolderKey(e,s,i,n)}catch(a){return a.message}let o=await this.lockFolder(e);return new N.Notice(o>0?`Encrypted ${o} note${o===1?"":"s"} in \u201C${t}\u201D.`:`\u201C${t}\u201D now has a Stashpad password \u2014 notes added here will use it.`),this.refreshFolderPanels?.(),null}}).open()}async encryptRawFolder(e,t){let i=async s=>{let n=this.encryption.folderKeyEntry(e)?.keyId;try{let o=await ql(this.app,e,s,n,this.encStamp());o.unpurged.length?new N.Notice(`Encrypted \u201C${t}\u201D (${o.fileCount} files) \u2014 but ${o.unpurged.length} file(s) changed mid-encrypt and were left in place.`):new N.Notice(`Encrypted \u201C${t}\u201D \u2014 ${o.fileCount} file(s) bundled into one encrypted file.`)}catch(o){return o.message}return this.refreshFolderPanels?.(),null};new j(this.app,`Encrypt \u201C${t}\u201D \u2014 non-Stashpad folder`,`This isn't a Stashpad folder, so its files can't be locked individually. +Inspect with the buttons below \u2014 rename to .zip to crack it open in an archive tool.`,kind:"error",category:"import",affectedPaths:[e.path],actions:ss(this.app,e.path,N.Platform.isMobile)}),console.error(i)}}lookupNoteAuthorIds(e){let t=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!==e)continue;let o=i(n?.author);o&&t.add(o);let a=n?.contributors;if(Array.isArray(a))for(let l of a){let c=i(l);c&&t.add(c)}break}return Array.from(t)}lookupNoteAuthorId(e){return this.lookupNoteAuthorIds(e)[0]??null}async runRebootstrapWithUI(){let t=new N.Notice("",0).noticeEl;t.empty(),t.addClass("stashpad-progress-notice"),t.createDiv({cls:"stashpad-progress-title",text:"Rebootstrapping Stashpad folders\u2026"});let s=t.createDiv({cls:"stashpad-progress-bar"}).createDiv({cls:"stashpad-progress-fill"}),n=t.createDiv({cls:"stashpad-progress-sub",text:"Counting notes\u2026"}),o=(a,l,c)=>{let d=l>0?Math.min(100,Math.round(a/l*100)):0;s.style.width=`${d}%`,n.setText(c?`${c} \xB7 ${d}%`:`${d}%`)};try{let a=await this.rebootstrapAllFolders(o),l=a.imported+a.attachmentsLinked+a.attachmentsRenamed+a.fmWritten+a.slugsRenamed,c=[];return c.push(`Checked ${a.touched.length} folder${a.touched.length===1?"":"s"} (${a.fmChecked} note${a.fmChecked===1?"":"s"})`),l===0?c.push("everything already in sync \u2014 no changes needed"):(a.fmWritten>0&&c.push(`updated frontmatter on ${a.fmWritten} note${a.fmWritten===1?"":"s"}`),a.slugsRenamed>0&&c.push(`renamed ${a.slugsRenamed} note${a.slugsRenamed===1?"":"s"} to match body`),a.imported>0&&c.push(`imported ${a.imported} loose file${a.imported===1?"":"s"}`),a.attachmentsLinked>0&&c.push(`linked attachments on ${a.attachmentsLinked} note${a.attachmentsLinked===1?"":"s"}`),a.attachmentsRenamed>0&&c.push(`renamed ${a.attachmentsRenamed} attachment${a.attachmentsRenamed===1?"":"s"}`)),a.authors>0&&c.push(`${a.authors} author${a.authors===1?"":"s"} in registry`),t.empty(),t.removeClass("stashpad-progress-notice"),t.addClass("stashpad-progress-done"),t.createDiv({cls:"stashpad-progress-title",text:"\u2713 Rebootstrap complete"}),t.createDiv({cls:"stashpad-progress-sub",text:`${c.join("; ")}.`}),a.attachmentsSkipped>0&&new N.Notice(`Stashpad: ${a.attachmentsSkipped} attachment${a.attachmentsSkipped===1?"":"s"} need renaming, but skipped to protect links. Enable Settings \u2192 Files & Links \u2192 \u201CAutomatically update internal links\u201D, then rebootstrap again.`,12e3),a}catch(a){throw t.empty(),t.removeClass("stashpad-progress-notice"),t.addClass("stashpad-progress-error"),t.createDiv({cls:"stashpad-progress-title",text:"Rebootstrap failed"}),t.createDiv({cls:"stashpad-progress-sub",text:a.message}),a}}async rebootstrapAllFolders(e){this.rebootstrapInProgress=!0;try{return await this.rebootstrapAllFoldersInner(e)}finally{window.setTimeout(()=>{this.rebootstrapInProgress=!1;for(let t of this.app.workspace.getLeavesOfType($))t.view?.forceReconcileRender?.()},2500)}}async rebootstrapAllFoldersInner(e){let t="__root__",i=new Set;for(let y of this.app.vault.getMarkdownFiles()){if(this.app.metadataCache.getFileCache(y)?.frontmatter?.id!==t)continue;let Q=y.parent?.path;Q&&i.add(Q)}let s=new Map;for(let y of this.app.vault.getMarkdownFiles()){let v=y.parent?.path;v&&i.has(v)&&s.set(v,(s.get(v)??0)+1)}let n=Math.max(1,[...s.values()].reduce((y,v)=>y+v,0)),o=0;e?.(0,n,"Starting\u2026");let a=(this.settings.importDropFolder||"").trim().replace(/^\/+|\/+$/g,""),l=(this.settings.exportFolder||"").trim().replace(/^\/+|\/+$/g,""),c=[],d=async y=>{if(y&&!await this.app.vault.adapter.exists(y))try{await this.app.vault.createFolder(y)}catch(v){let Q=v?.message??"";if(!/already exists/i.test(Q))throw v}},h=0,p=0,f=0,u=0,g=0,I=0,m=!!this.app.vault.getConfig?.("alwaysUpdateLinks"),C=new Set(this.okfActiveFolders());for(let y of i){let v=s.get(y)??1;e?.(o,n,`Processing \u201C${y.split("/").pop()||y}\u201D (${v} note${v===1?"":"s"})`);try{if(a&&await d(`${y}/${a}`),l&&await d(`${y}/${l}`),this.settings.autoImport)try{let k=await this.importService.importLooseInto(y);u+=k.files+k.folders+k.stashes}catch(k){console.warn("Stashpad: loose sweep failed",y,k)}let Q=await Hi(this.app,y);h+=Q.checked,p+=Q.written,f+=await this.rebootstrapFolderSlugs(y);let w=await this.rebootstrapFolderAttachments(y,m);if(g+=w.renamed,I+=w.skipped,C.has(y.replace(/\/+$/,"")))try{await Ha(this.app,y)}catch(k){console.warn("Stashpad: OKF rebuild during rebootstrap failed",y,k)}c.push(y)}catch(Q){console.warn(`Stashpad: rebootstrap skipped ${y}`,Q)}finally{o+=v,e?.(o,n,`Processing \u201C${y.split("/").pop()||y}\u201D`)}}e?.(n,n,"Finalizing\u2026");let B=0;try{B=(await this.rebuildAuthorRegistry()).total}catch(y){console.warn("Stashpad: rebootstrap author-registry rebuild failed",y)}let E=0;try{E=await this.convertAttachmentsToLinks()}catch(y){console.warn("Stashpad: attachment-link conversion failed",y)}return{touched:c,fmChecked:h,fmWritten:p,slugsRenamed:f,authors:B,imported:u,attachmentsLinked:E,attachmentsRenamed:g,attachmentsSkipped:I}}async rebootstrapFolderSlugs(e){let t="__root__",i=e.replace(/\/+$/,""),s=this.settings.slugStopWords??st,n=0,o=this.app.vault.getMarkdownFiles().filter(a=>(a.parent?.path?.replace(/\/+$/,"")??"")===i);for(let a of o){let l=this.app.metadataCache.getFileCache(a)?.frontmatter?.id,c=typeof l=="string"?l:null,h=nt(a.basename)??(es(c)?c:null);if(!(!h||h===t)&&c===h)try{let p=await this.app.vault.cachedRead(a),f=p.startsWith("---")?p.slice(p.indexOf(` +---`,3)+4).replace(/^\r?\n/,""):p,u=xe(f,s),g=Ne(u,h);if(a.name===g)continue;let I=a.parent?`${a.parent.path}/${g}`:g;if(this.app.vault.getAbstractFileByPath(I))continue;await this.app.fileManager.renameFile(a,I),n+=1}catch(p){console.warn(`Stashpad: slug rebootstrap skipped ${a.path}`,p)}}return n}async rebootstrapFolderAttachments(e,t){let i=`${e.replace(/\/+$/,"")}/_attachments`,s=this.app.vault.getAbstractFileByPath(i);if(!(s instanceof N.TFolder))return{renamed:0,skipped:0};let n=s.children.filter(l=>l instanceof N.TFile),o=0,a=0;for(let l of n){let c=dr(l.name);if(!c)continue;let d=Ws(c.rest,c.stamp);if(l.name===d)continue;if(!t){a+=1;continue}let h=`${i}/${d}`;if(!this.app.vault.getAbstractFileByPath(h))try{await this.app.fileManager.renameFile(l,h),o+=1,await new Promise(p=>setTimeout(p,30))}catch(p){console.warn(`Stashpad: attachment rebootstrap skipped ${l.path}`,p)}}return{renamed:o,skipped:a}}onStashpadSelectionChange(e){return this.stashpadSelectionListeners.add(e),()=>this.stashpadSelectionListeners.delete(e)}notifyStashpadSelectionChanged(){for(let e of this.stashpadSelectionListeners)try{e()}catch(t){console.warn("[Stashpad] selection listener failed",t)}}onStashpadContentChange(e){return this.stashpadContentListeners.add(e),()=>this.stashpadContentListeners.delete(e)}notifyStashpadContentChanged(){for(let e of this.stashpadContentListeners)try{e()}catch(t){console.warn("[Stashpad] content listener failed",t)}}getActiveStashpadSelection(){let t=this.lastActiveStashpadLeaf?.view;if(!t||t.getViewType?.()!==$)return null;let i=t.noteFolder??"";if(!i)return null;let s=t.currentChildren??[],n;if(typeof t.cursorIdx=="number"&&t.cursorIdx>=0&&(n=s[t.cursorIdx]),!n&&t.selection?.size>0){let o=t.firstSelectedId??[...t.selection][0];n=s.find(a=>a.id===o)}return n?.file?{folder:i,id:n.id,file:n.file}:null}fileForPin(e,t){let i=e.replace(/\/+$/,"");for(let s of this.app.vault.getMarkdownFiles())if((s.parent?.path?.replace(/\/+$/,"")??"")===i&&this.app.metadataCache.getFileCache(s)?.frontmatter?.id===t)return s;return null}async pinNote(e){let t=this.fileForPin(e.folder,e.id);t&&this.app.metadataCache.getFileCache(t)?.frontmatter?.pinned!==!0&&(await this.app.fileManager.processFrontMatter(t,i=>{i.pinned=!0,i.pinnedAt=Date.now()}),this.refreshPanelsView())}async unpinNote(e){let t=this.fileForPin(e.folder,e.id);t&&this.app.metadataCache.getFileCache(t)?.frontmatter?.pinned===!0&&(await this.app.fileManager.processFrontMatter(t,i=>{delete i.pinned,delete i.pinnedAt}),this.refreshPanelsView())}isPinned(e){let t=this.fileForPin(e.folder,e.id);return t?this.app.metadataCache.getFileCache(t)?.frontmatter?.pinned===!0:!1}listPinnedNotes(){let e=new Set(this.discoverStashpadFolders()),t=[];for(let i of this.app.vault.getMarkdownFiles()){let s=i.parent?.path?.replace(/\/+$/,"")??"";if(!e.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;t.push({folder:s,id:n.id,pinnedAt:o,file:i})}return t.sort((i,s)=>i.pinnedAt-s.pinnedAt||i.file.path.localeCompare(s.file.path)),t}async migratePinnedNotesToFrontmatter(){let e=this.settings.pinnedNotes??[];if(e.length===0)return;let t=Date.now()-e.length*1e3;for(let i of e){let s=this.fileForPin(i.folder,i.id);if(!s){t+=1e3;continue}try{if(this.app.metadataCache.getFileCache(s)?.frontmatter?.pinned!==!0){let n=t;await this.app.fileManager.processFrontMatter(s,o=>{o.pinned=!0,o.pinnedAt=n})}}catch(n){console.warn("[Stashpad] pin migration failed for",i,n)}t+=1e3}this.settings.pinnedNotes=[],await this.saveSettings(),this.refreshPanelsView()}refreshPanelsView(){let e=this.app.workspace.getLeavesOfType(St);for(let t of e){let i=t.view;i&&typeof i.render=="function"&&i.render()}}refreshAllStashpadViews(){for(let e of this.app.workspace.getLeavesOfType($)){let t=e.view;t&&typeof t.render=="function"&&t.render()}}refreshFolderPanels(){for(let e of this.app.workspace.getLeavesOfType(bt)){let t=e.view;t&&typeof t.refresh=="function"&&t.refresh()}}getFolderIcon(e){let t=(e||"").replace(/\/+$/,""),i=this.settings.folderIcons?.[t];return i&&i.trim()?i.trim():void 0}async setFolderIcon(e,t){let i=(e||"").replace(/\/+$/,""),s={...this.settings.folderIcons??{}};t&&t.trim()?s[i]=t.trim():delete s[i],this.settings.folderIcons=s,await this.saveSettings(),this.refreshFolderIconFor(i)}refreshFolderIconFor(e){let t=(e||"").replace(/\/+$/,"");for(let i of this.app.workspace.getLeavesOfType($)){let s=i.view;if(s&&(s.noteFolder||"").replace(/\/+$/,"")===t){try{i.updateHeader?.()}catch{}try{s.refreshFolderSwitcherIcon?.()}catch{}}}this.refreshFolderPanels()}openFolderPicker(){let e=I=>{let C=I.getViewState().state?.folderOverride;return typeof C=="string"&&C.trim()?C.trim().replace(/^\/+|\/+$/g,""):(this.settings.folder||"Stashpad").trim().replace(/^\/+|\/+$/g,"")},t=this.app.workspace.getLeavesOfType($),i=this.discoverStashpadFolders(),s=Bt(),n=s?(s.noteFolder??"").trim().replace(/^\/+|\/+$/g,""):"",o=new Set;for(let I of this.app.vault.getAllLoadedFiles())if(I.children){let m=I.path;m&&m!=="/"&&!m.startsWith(".")&&o.add(m)}let a=I=>{let m=I.split("/").filter(Boolean).pop()??"";return m?new Set([this.settings.importDropFolder,this.settings.exportFolder,"_attachments","_processed","_authors","_exports","_imports","_archive",".archive","_deleted"].map(B=>(B??"").trim().replace(/^\/+|\/+$/g,"")).filter(Boolean)).has(m):!1},l=new Set,c=[],d=[],h=new Set;for(let I of t){let m=e(I);if(h.has(m))continue;h.add(m),l.add(m);let C=m.split("/").pop()||m;if(this.settings.foldersAlwaysNewTab){c.push({kind:"open",folder:m,label:`Open "${C}" in new tab`,icon:this.isArchiveFolder(m)?"archive":"layout-template"});continue}c.push({kind:"reveal",folder:m,label:`Reveal "${C}" tab`,leaf:I,icon:this.isArchiveFolder(m)?"archive":"layout-grid"}),d.push({kind:"open-anyway",folder:m,label:`Open "${C}" in another new tab`,icon:"layout-template"})}for(let I of i.filter(m=>!l.has(m))){let m=I.split("/").pop()||I;c.push({kind:"open",folder:I,label:`Open "${m}" in new tab`,icon:this.isArchiveFolder(I)?"archive":"layout-template"})}let p=I=>I.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ").trim()||I.basename,f=this.settings.folderSwitcherIncludePinned?this.listPinnedNotes().map(I=>({kind:"pinned",folder:I.folder,file:I.file,label:p(I.file),icon:"pin"})):[],u=this,g=new class extends N.SuggestModal{getSuggestions(I){let m=I.trim().toLowerCase(),C=m?m.split(/\s+/).filter(Boolean):[],B=Q=>{if(!C.length)return!0;let w=Q.toLowerCase();for(let k of C)if(!w.includes(k))return!1;return!0},E=m?c.filter(Q=>{let w="folder"in Q?Q.folder:"";return B(Q.label)||B(w)}):c.slice();if(m&&s&&n)for(let Q of i){if(Q.toLowerCase()===n.toLowerCase())continue;let w=Q.split("/").pop()??Q,k=`${Q} ${w}`;B(k)&&E.push({kind:"switch-current",folder:Q,label:`Switch this tab to "${w}"`,icon:"folder-input"})}for(let Q of f)(B(Q.label)||B("folder"in Q?Q.folder:""))&&E.push(Q);let y=I.trim().replace(/^\/+|\/+$/g,"");if(y&&!a(y)){let Q=Array.from(o).find(k=>k.toLowerCase()===y.toLowerCase()),w=i.some(k=>k.toLowerCase()===y.toLowerCase());if(Q&&!w)E.push({kind:"convert",folder:Q,label:`Convert \u201C${ji(Q)}\u201D into a Stashpad\u2026`,icon:"folder-cog"});else if(!Q){let k=ji(y);E.push({kind:"create",folder:y,label:`+ Create new Stashpad \u201C${k}\u201D`,icon:"folder-plus"})}}let v=d.filter(Q=>B(Q.label)||B("folder"in Q?Q.folder:""));return E.push(...v),B("trash deleted encrypted")&&E.push({kind:"trash",label:"Open Trash",icon:"trash-2"}),E}renderSuggestion(I,m){m.addClass("stashpad-suggest-item"),m.addClass("stashpad-ribbon-suggest-item"),I.kind==="create"&&m.addClass("stashpad-suggest-create");let C=m.createSpan({cls:"stashpad-ribbon-suggest-icon"});(0,N.setIcon)(C,I.icon);let B=m.createDiv({cls:"stashpad-ribbon-suggest-body"});B.createDiv({cls:"stashpad-suggest-title",text:I.label}),"folder"in I&&I.folder&&I.label!==I.folder&&B.createDiv({cls:"stashpad-suggest-preview",text:I.folder})}async onChooseSuggestion(I){if(I.kind==="trash"){u.openEncryptedTrash();return}if(I.kind==="pinned"){await u.revealNoteInStashpad(I.file);return}if(I.kind==="reveal"){u.app.workspace.revealLeaf(I.leaf);return}if(I.kind==="open"||I.kind==="open-anyway"){await u.activateViewForFolder(I.folder);return}if(I.kind==="switch-current"){let m=s;m&&typeof m.setFolderOverride=="function"&&(await m.setFolderOverride(I.folder),u.app.workspace.revealLeaf(m.leaf));return}if(I.kind==="create"){try{let m=ji(I.folder);await u.app.vault.adapter.exists(m)||await u.app.vault.createFolder(m),await u.activateViewForFolder(m)}catch(m){new N.Notice(`Stashpad: couldn't create folder (${m.message})`)}return}if(I.kind==="convert"){let{ConfirmModal:m}=await Promise.resolve().then(()=>(ve(),Bs)),C=I.folder,B=[`\u201C${C}\u201D already exists as a regular vault folder.`,"Converting adds a Home note + _imports / _exports subfolders, and imports the existing loose files and subfolders inside it as notes.","(Files already structured as notes, and reserved subfolders, are left alone.)"];new m(u.app,"Convert into a Stashpad?",B.join(` +`),"Convert & import",async E=>{if(E)try{await u.activateViewForFolder(C),await u.runImportLooseFiles(C)}catch(y){new N.Notice(`Stashpad: couldn't convert folder (${y.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 e=Bt(),t=e?.folderOverride??null,i=e?.focusId??"__root__",s=!!e?.compactMode,n=this.app.workspace.openPopoutLeaf?.();if(!n){new N.Notice("Stashpad: couldn't open popout window on this build.");return}await n.setViewState({type:$,active:!0,state:{folderOverride:t,focusId:i,tinyMode:!0,tinyAlwaysOnTop:!1,compactMode:s}});try{this.app.workspace.revealLeaf(n)}catch{}}async activateView(e={reveal:!0}){let{workspace:t}=this.app;if(e.reveal){let s=t.getLeavesOfType($);if(s.length>0){t.revealLeaf(s[0]);return}}let i=t.getLeaf("tab");await i.setViewState({type:$,active:!0}),t.revealLeaf(i)}async focusLastStashpadTab(){let e=this.app.workspace,t=e.getLeavesOfType($),i=this.lastActiveStashpadLeaf&&t.includes(this.lastActiveStashpadLeaf)?this.lastActiveStashpadLeaf:t[0]??null;if(!i){await this.activateView({reveal:!0});return}e.revealLeaf(i),e.setActiveLeaf(i,{focus:!0})}async focusFolderPanel(){await so(this.app);let e=this.app.workspace.getLeavesOfType(bt)[0];e&&this.app.workspace.setActiveLeaf(e,{focus:!0})}async reconcileLockedRegistry(){let e=this.settings.lockedSubtrees??[],t=[];for(let n of e){let o=(n.folder??"").replace(/\/+$/,"");if(!(o==="_deleted"||o.startsWith("_deleted/")))try{await this.app.vault.adapter.exists(n.blob)&&t.push(n)}catch{t.push(n)}}let i=t.length!==e.length,s=new Set(t.map(n=>n.blob));for(let n of this.app.vault.getFiles()){if(n.extension!=="stashenc"||s.has(n.path))continue;let o=n.parent?.path?.replace(/\/+$/,"")??"";if(o==="_deleted"||o.startsWith("_deleted/"))continue;let a=await Wn(this.app,n.path);a&&(t.push({folder:o,blob:n.path,parentId:a.parentId,title:a.title,count:a.count,created:a.created,rootId:a.rootId,prevSibling:a.prevSibling}),i=!0)}i&&(this.settings.lockedSubtrees=t,await this.saveSettings(),this.refreshAllStashpadViews?.())}lockedSubtreesFor(e,t){let i=e.replace(/\/+$/,""),s=[],n=new Set;for(let o of this.settings.lockedSubtrees??[])(o.folder??"").replace(/\/+$/,"")===i&&(o.parentId??S)===t&&(s.push({blob:o.blob,title:o.title??"",count:o.count??0,created:o.created??"",rootId:o.rootId,parentId:o.parentId??S,prevSibling:o.prevSibling??null}),n.add(o.blob));for(let o of this.app.vault.getFiles()){if(o.extension!=="stashenc"||n.has(o.path))continue;let a=o.parent?.path?.replace(/\/+$/,"")??"";a!==i||a==="_deleted"||a.startsWith("_deleted/")||t===S&&s.push({blob:o.path,title:o.basename,count:0,created:"",rootId:void 0,parentId:S,prevSibling:null})}return s}lockedSubtreesInFolder(e){let t=e.replace(/\/+$/,""),i=[],s=new Set;for(let n of this.settings.lockedSubtrees??[])(n.folder??"").replace(/\/+$/,"")===t&&(i.push({blob:n.blob,title:n.title??"",count:n.count??0,created:n.created??"",rootId:n.rootId,parentId:n.parentId??S}),s.add(n.blob));for(let n of this.app.vault.getFiles()){if(n.extension!=="stashenc"||s.has(n.path))continue;let o=n.parent?.path?.replace(/\/+$/,"")??"";o!==t||o==="_deleted"||o.startsWith("_deleted/")||i.push({blob:n.path,title:n.basename,count:0,created:"",rootId:void 0,parentId:S})}return i}async ensureFolderUnlocked(e){if(!this.encryption.hasFolderKey(e))return new N.Notice("This folder isn't encrypted. Give it a password in Settings \u2192 Stashpad \u2192 Encryption \u2192 Per-Folder Passwords."),null;if(this.encryption.isFolderUnlocked(e))return this.encryption.getFolderKey(e);if(await this.encryption.tryAutoUnlockFolder(e))return this.encryption.getFolderKey(e);let t=e.split("/").pop()||e;return await new Promise(s=>{new Le(this.app,{mode:"unlock",offerKeychain:!0,title:`Unlock \u201C${t}\u201D`,intro:"Enter this folder's password.",onSubmit:async({current:n,remember:o})=>await this.encryption.unlockFolder(e,n,o)?(s(!0),null):"Wrong password. Try again.",onCancel:()=>s(!1)}).open()})?this.encryption.getFolderKey(e):null}isTrashBlobPath(e){let t=e.replace(/\/[^/]*$/,"").replace(/\/+$/,"");return t==="_deleted"||t.startsWith("_deleted/")||t==="trash"||t.endsWith("/trash")}encryptionState(){let e=s=>this.isTrashBlobPath(s),t=!1,i=!1;for(let s of this.app.vault.getFiles())if(s.extension==="stashenc"&&(e(s.path)?i=!0:t=!0,t&&i))return{live:t,trash:i};for(let s of this.pendingEncBlobs)if(e(s)?i=!0:t=!0,t&&i)break;return{live:t,trash:i}}async encryptionStateStrict(){let e=this.encryptionState(),t=e.trash;if(!t)try{t=(await Zn(this.app,this.trashSubfolderDirs())).length>0}catch{}if(!t)try{t=(await this.app.vault.adapter.list(si)).files.some(s=>s.endsWith(".stashenc"))}catch{}return{live:e.live,trash:t}}watchReEncrypt(e){let t=e.folder.replace(/\/+$/,""),i=(this.settings.reEncryptWatch??[]).filter(s=>!(s.folder===t&&s.rootId===e.rootId));this.settings.reEncryptWatch=[...i,{folder:t,rootId:e.rootId,title:e.title,count:e.count,via:e.via,unlockedAt:new Date().toISOString()}]}reEncryptDisplayTitle(e){if(e.title&&e.title.trim())return e.title.trim();if(e.rootId){let t=e.folder.replace(/\/+$/,""),i=this.app.vault.getMarkdownFiles().find(s=>(s.parent?.path?.replace(/\/+$/,"")??"")===t&&nt(s.name)===e.rootId);if(i){let s=this.app.metadataCache.getFileCache(i)?.headings?.find(o=>o.level===1)?.heading;if(s&&s.trim())return s.trim();let n=i.basename.replace(new RegExp(`[-_]+${e.rootId}$`),"").replace(/[-_]+/g," ").trim();if(n)return n}}return"(untitled)"}unwatchReEncrypt(e,t){let i=e.replace(/\/+$/,""),s=this.settings.reEncryptWatch??[],n=s.filter(o=>!(o.folder===i&&o.rootId===t));n.length!==s.length&&(this.settings.reEncryptWatch=n)}reEncryptWatching(){return(this.settings.reEncryptWatch??[]).filter(e=>!e.removed)}pruneReEncryptWatch(){let e=this.settings.reEncryptWatch??[];if(e.length===0)return!1;let t=n=>{let o=new Set;for(let a of this.app.vault.getMarkdownFiles()){if((a.parent?.path?.replace(/\/+$/,"")??"")!==n)continue;let l=this.app.metadataCache.getFileCache(a)?.frontmatter?.id;typeof l=="string"&&o.add(l)}return o},i=new Map,s=e.filter(n=>{let o=n.folder.replace(/\/+$/,"");return i.has(o)||i.set(o,t(o)),i.get(o).has(n.rootId)});return s.length===e.length?!1:(this.settings.reEncryptWatch=s,!0)}async encryptEverythingApplicable(){this.pruneReEncryptWatch()&&await this.saveSettings();let e=[];for(let i of this.reEncryptWatching())e.push({label:this.reEncryptDisplayTitle(i),detail:`${i.folder} \u2014 ${i.via==="restore"?"restored from trash":"unlocked"} (was encrypted)`,run:async()=>!!await this.lockNoteSubtree(i.folder,i.rootId,null,{silent:!0})});let t=new Set((this.settings.lockedSubtrees??[]).map(i=>i.rootId));for(let[i,s]of Object.entries(this.settings.folderEncPrefs??{})){if(!s?.encryptContent)continue;let n=this.app.vault.getMarkdownFiles().filter(o=>{if((o.parent?.path?.replace(/\/+$/,"")??"")!==i)return!1;let a=this.app.metadataCache.getFileCache(o)?.frontmatter?.id;return typeof a=="string"&&a!==S&&!t.has(a)}).length;n>0&&e.push({label:`Everything in \u201C${i.split("/").pop()||i}\u201D (${n} plaintext note${n===1?"":"s"})`,detail:`${i} \u2014 the folder is set to encrypt its notes`,run:async()=>(await this.lockFolder(i),!0)})}for(let[i,s]of Object.entries(this.settings.folderEncPrefs??{})){if(!s?.archiveEncryptContent)continue;let n=this.archivedPlainNotesIn(Dt(i)).length;n>0&&e.push({label:`${n} archived note${n===1?"":"s"} in \u201C${i.split("/").pop()||i}/archive\u201D`,detail:`${i} \u2014 the folder encrypts its archive`,run:async()=>(await this.encryptExistingArchiveNotes(i),!0)})}if(e.length===0){new N.Notice("Nothing needs re-encrypting \u2014 everything applicable is already locked.");return}new ms(this.app,e.map(({label:i,detail:s})=>({label:i,detail:s})),async i=>{let s=0,n=0,o=i.length>2?new N.Notice("",0):null;for(let a=0;a<i.length;a++){o?.setMessage(`\u{1F512} Re-encrypting ${a+1}/${i.length}\u2026`);try{await e[i[a]].run()?s++:n++}catch(l){n++,console.warn("[Stashpad] sweep item failed",e[i[a]].label,l)}}o?.hide(),this.notifications.show({message:`Re-encrypt sweep: ${s} done${n?`, ${n} FAILED (see console)`:""}, ${e.length-i.length} skipped.`,kind:n?"warning":"success",category:"system",folder:""})}).open()}async lockNoteSubtree(e,t,i=null,s={}){let n=(s.blobFolder??e).replace(/\/+$/,""),o=await this.ensureFolderUnlocked(n);if(!o)return null;try{let a=!!s.blobFolder&&s.blobFolder.replace(/\/+$/,"")!==e.replace(/\/+$/,""),l=(this.settings.folderEncPrefs??{})[n]??{},c=s.hideTitle??(a?l.archiveEncryptFilenames:l.encryptFilenames)??!1,d=await Rl(this.app,e,t,o,i,c,s.blobFolder);this.pendingEncBlobs.add(d.blobPath);let h=(s.blobFolder??e).replace(/\/+$/,"");return this.settings.lockedSubtrees=[...(this.settings.lockedSubtrees??[]).filter(p=>p.blob!==d.blobPath),{folder:h,blob:d.blobPath,parentId:d.parentId,title:d.title,count:d.noteCount,created:d.created,rootId:d.rootId,prevSibling:i}],this.unwatchReEncrypt(e,d.rootId),this.unwatchReEncrypt(h,d.rootId),await this.saveSettings(),d.unpurged.length>0?new N.Notice(`\u26A0\uFE0F Locked, but ${d.unpurged.length} file${d.unpurged.length===1?" is":"s are"} still in plaintext (couldn't be removed or changed during the lock): +${d.unpurged.join(` +`)}`,0):s.silent||this.notifications.show({message:`Locked ${d.title?`\u201C${d.title}\u201D`:"a note"} (${d.noteCount} note${d.noteCount===1?"":"s"}).`,kind:"success",category:"system",folder:e}),d}catch(a){return console.warn("[Stashpad] lock failed",a),new N.Notice(`Couldn't lock: ${a.message}`),null}}async unlockBundleCore(e,t,i){let s=(i??e.replace(/\/[^/]*$/,"")).replace(/\/+$/,""),n=new Set;for(let o of this.app.vault.getMarkdownFiles())if((o.parent?.path?.replace(/\/+$/,"")??"")===s)try{let a=ge(await this.app.vault.read(o)).fm.id;typeof a=="string"&&n.add(a)}catch{}return Ul(this.app,e,t,n,i)}async unlockBundleAt(e,t={}){let i=e.replace(/\/[^/]*$/,"").replace(/\/+$/,""),s=await this.ensureFolderUnlocked(i);if(!s)return!1;let n=(t.destFolder??e.replace(/\/[^/]*$/,"")).replace(/\/+$/,"");try{let o=await this.unlockBundleCore(e,s,t.destFolder);this.pendingEncBlobs.delete(e);let a=(this.settings.lockedSubtrees??[]).find(l=>l.blob===e);return a?.rootId&&this.watchReEncrypt({folder:n,rootId:a.rootId,title:a.title??"",count:a.count??o.notesWritten,via:"unlock"}),this.settings.lockedSubtrees=(this.settings.lockedSubtrees??[]).filter(l=>l.blob!==e),await this.saveSettings(),t.silent||this.notifications.show({message:`Unlocked ${o.notesWritten} note${o.notesWritten===1?"":"s"}.`,kind:"success",category:"system",folder:n}),!0}catch(o){return console.warn("[Stashpad] unlock failed",o),new N.Notice(`Couldn't unlock: ${o.message}`),!1}}async lockFolder(e){let t=e.replace(/\/+$/,"");if(!await this.ensureFolderUnlocked(t))return 0;let i=[];for(let d of this.app.vault.getMarkdownFiles()){if((d.parent?.path?.replace(/\/+$/,"")??"")!==t)continue;let h;try{h=ge(await this.app.vault.read(d)).fm}catch{continue}let p=h.id;typeof p!="string"||p===S||(typeof h.parent=="string"?h.parent:S)!==S||i.push(p)}let s=new Set((this.settings.lockedSubtrees??[]).map(d=>d.rootId).filter(d=>!!d)),n=i.filter(d=>!s.has(d));if(n.length===0)return new N.Notice("Nothing to lock in this folder."),0;let a=(await new Ni(this.app).load(t))[S]??[],l=n.length>3?new N.Notice("",0):null,c=0;for(let d=0;d<n.length;d++){let h=n[d];l?.setMessage(`\u{1F512} Encrypting ${d+1}/${n.length}\u2026`);let p=a.indexOf(h),f=p>0?a[p-1]:null;await this.lockNoteSubtree(t,h,f,{silent:!0})&&c++}return l?.hide(),c>0&&this.notifications.show({message:`Locked ${c} note${c===1?"":"s"} in \u201C${t.split("/").pop()}\u201D.`,kind:"success",category:"system",folder:t,actions:[{label:"All encrypted",onClick:()=>void He(this,"encrypted")}]}),c}async unlockFolder(e){let t=e.replace(/\/+$/,"");if(!await this.ensureFolderUnlocked(t))return 0;let i=this.app.vault.getFiles().filter(o=>o.extension==="stashenc"&&(o.parent?.path?.replace(/\/+$/,"")??"")===t).map(o=>o.path);if(i.length===0)return new N.Notice("No locked notes in this folder."),0;let s=i.length>3?new N.Notice("",0):null,n=0;for(let o=0;o<i.length;o++){s?.setMessage(`\u{1F513} Decrypting ${o+1}/${i.length}\u2026`);try{await this.unlockBundleAt(i[o],{silent:!0})&&n++}catch(a){console.warn("[Stashpad] folder unlock skipped",i[o],a)}}return s?.hide(),n>0&&this.notifications.show({message:`Unlocked ${n} note${n===1?"":"s"} in \u201C${t.split("/").pop()}\u201D.`,kind:"success",category:"system",folder:t}),n}async unlockAllInVault(){if(!this.encryption.isConfigured())return new N.Notice("Set up encryption first (Settings \u2192 Stashpad \u2192 Encryption)."),0;let e=this.app.vault.getFiles().filter(c=>c.extension==="stashenc"&&!this.isTrashBlobPath(c.path)).map(c=>c.path);if(e.length===0)return new N.Notice("No locked notes anywhere in the vault."),0;let t=e.length>3?new N.Notice("",0):null,i=new Map,s=async c=>{if(i.has(c))return i.get(c);let d=null;return this.encryption.hasFolderKey(c)&&(this.encryption.isFolderUnlocked(c)||await this.encryption.tryAutoUnlockFolder(c))&&(d=this.encryption.getFolderKey(c)),i.set(c,d),d},n=0,o=[],a=new Set;for(let c=0;c<e.length;c++){t?.setMessage(`\u{1F513} Decrypting ${c+1}/${e.length}\u2026`);let d=e[c].replace(/\/[^/]*$/,"").replace(/\/+$/,""),h=await s(d);if(!h){a.add(d||"(vault root)");continue}try{let p=await this.unlockBundleCore(e[c],h);n+=p.notesWritten,o.push(e[c])}catch(p){console.warn("[Stashpad] vault unlock skipped",e[c],p)}}if(o.length>0){let c=new Set(o);this.settings.lockedSubtrees=(this.settings.lockedSubtrees??[]).filter(d=>!c.has(d.blob)),await this.saveSettings()}t?.hide();for(let c of i.values())try{c?.fill(0)}catch{}let l=e[0].replace(/\/[^/]*$/,"");return n>0&&this.notifications.show({message:`Unlocked ${n} note${n===1?"":"s"} across the vault.`,kind:"success",category:"system",folder:l}),a.size>0&&new N.Notice(`Skipped ${a.size} locked folder${a.size===1?"":"s"} (no key unlocked): ${[...a].map(c=>c.split("/").pop()||c).join(", ")}. Open each to unlock it, then run this again.`,0),n}exportLockedSubtree(e){return Xl(this,e)}async openWorkbench(e,t,i){let s=this.app.workspace.getMostRecentLeaf(),n=this.app.workspace.getLeaf("tab");await n.setViewState({type:Cs,active:!0}),n.view instanceof bi&&n.view.setContext({body:e,cbs:t,init:i,prevLeaf:s}),this.app.workspace.revealLeaf(n)}folderHasStashpadNotes(e){let t=e.replace(/\/+$/,"");return this.discoverStashpadFolders().some(i=>t===i||t.startsWith(i+"/")||i.startsWith(t+"/"))}encStamp(){let e=new Date,t=i=>String(i).padStart(2,"0");return`${e.getFullYear()}${t(e.getMonth()+1)}${t(e.getDate())}-${t(e.getHours())}${t(e.getMinutes())}`}folderKeyLabelFor(e){let t=(this.settings.authorName||"").trim(),i=t?t.split(/\s+/).map(s=>s[0]).join(""):(this.settings.authorId||"anon").slice(0,4);return`${this.encStamp()} - ${e} - ${i}`}async encryptFolderFromExplorer(e){let t=e.split("/").pop()||e;if(this.folderHasStashpadNotes(e)){await this.encryptStashpadFolder(e,t);return}if(await Da(this.app,e)){new N.Notice(`\u201C${t}\u201D is already encrypted as a Stashpad bundle. Use \u201CDecrypt with Stashpad\u201D to open it.`);return}await this.encryptRawFolder(e,t)}async encryptStashpadFolder(e,t){if(this.encryption.hasOwnFolderKey(e)){await this.ensureFolderUnlocked(e)&&await this.lockFolder(e);return}let i=this.folderKeyLabelFor(t);new Le(this.app,{mode:"setup",offerKeychain:!0,title:`Encrypt \u201C${t}\u201D with Stashpad`,intro:"Give this folder its own password. Any Stashpad notes inside it get encrypted under it; you'll re-enter the password to unlock.",onSubmit:async({next:s,remember:n})=>{if(!s)return"Enter a password.";try{await this.encryption.setupFolderKey(e,s,i,n)}catch(a){return a.message}let o=await this.lockFolder(e);return new N.Notice(o>0?`Encrypted ${o} note${o===1?"":"s"} in \u201C${t}\u201D.`:`\u201C${t}\u201D now has a Stashpad password \u2014 notes added here will use it.`),this.refreshFolderPanels?.(),null}}).open()}async encryptRawFolder(e,t){let i=async s=>{let n=this.encryption.folderKeyEntry(e)?.keyId;try{let o=await Yl(this.app,e,s,n,this.encStamp());o.unpurged.length?new N.Notice(`Encrypted \u201C${t}\u201D (${o.fileCount} files) \u2014 but ${o.unpurged.length} file(s) changed mid-encrypt and were left in place.`):new N.Notice(`Encrypted \u201C${t}\u201D \u2014 ${o.fileCount} file(s) bundled into one encrypted file.`)}catch(o){return o.message}return this.refreshFolderPanels?.(),null};new j(this.app,`Encrypt \u201C${t}\u201D \u2014 non-Stashpad folder`,`This isn't a Stashpad folder, so its files can't be locked individually. Stashpad will bundle EVERY file in this folder into one encrypted file and permanently delete the originals (no copy left in Obsidian's trash \u2014 that would defeat encryption). -This can't be undone with Cmd+Z; the only way back is \u201CDecrypt with Stashpad\u201D + the password. Continue?`,"Bundle & encrypt",s=>{if(!s)return;if(this.encryption.hasOwnFolderKey(e)){(async()=>{let o=await this.ensureFolderUnlocked(e);if(!o)return;let a=await i(o);a&&new N.Notice(a)})();return}let n=this.folderKeyLabelFor(t);new Le(this.app,{mode:"setup",offerKeychain:!0,title:`Encrypt \u201C${t}\u201D with Stashpad`,intro:"Set a password for this bundle. You'll re-enter it to decrypt the whole folder.",onSubmit:async({next:o,remember:a})=>{if(!o)return"Enter a password.";try{await this.encryption.setupFolderKey(e,o,n,a)}catch(c){return c.message}let l=this.encryption.getFolderKey(e);return l?await i(l):"Couldn't derive the folder key."}}).open()}).open()}async decryptFolderFromExplorer(e){let t=await ka(this.app,e);if(!t){new N.Notice("No Stashpad bundle found in this folder.");return}let i=e.split("/").pop()||e,s=await this.ensureFolderUnlocked(e);if(s){try{let n=await Jl(this.app,t,s);new N.Notice(`Decrypted \u201C${i}\u201D \u2014 restored ${n.filesWritten} file(s).`)}catch(n){new N.Notice(`Couldn't decrypt: ${n.message}`)}this.refreshFolderPanels?.()}}async encryptDeleteSubtree(e,t){let i=await this.ensureFolderUnlocked(e);if(!i)return null;try{let s=new Date().toISOString(),o=(((this.settings.folderEncPrefs??{})[e.replace(/\/+$/,"")]??{}).trashEncryptFilenames??!1)||(this.settings.encryptTrashFilenames??!1),a=this.encryption.folderKeyEntry(e)?.keyId,l=await Hl(this.app,e,t,i,s,o,a,bs(e));return this.pendingEncBlobs.add(l.blobPath),this.unwatchReEncrypt(e,t),await this.saveSettings(),l.unpurged.length>0&&new N.Notice(`\u26A0\uFE0F Sent to encrypted trash, but ${l.unpurged.length} file${l.unpurged.length===1?" is":"s are"} still in plaintext (couldn't be removed or changed during the delete): +This can't be undone with Cmd+Z; the only way back is \u201CDecrypt with Stashpad\u201D + the password. Continue?`,"Bundle & encrypt",s=>{if(!s)return;if(this.encryption.hasOwnFolderKey(e)){(async()=>{let o=await this.ensureFolderUnlocked(e);if(!o)return;let a=await i(o);a&&new N.Notice(a)})();return}let n=this.folderKeyLabelFor(t);new Le(this.app,{mode:"setup",offerKeychain:!0,title:`Encrypt \u201C${t}\u201D with Stashpad`,intro:"Set a password for this bundle. You'll re-enter it to decrypt the whole folder.",onSubmit:async({next:o,remember:a})=>{if(!o)return"Enter a password.";try{await this.encryption.setupFolderKey(e,o,n,a)}catch(c){return c.message}let l=this.encryption.getFolderKey(e);return l?await i(l):"Couldn't derive the folder key."}}).open()}).open()}async decryptFolderFromExplorer(e){let t=await Da(this.app,e);if(!t){new N.Notice("No Stashpad bundle found in this folder.");return}let i=e.split("/").pop()||e,s=await this.ensureFolderUnlocked(e);if(s){try{let n=await zl(this.app,t,s);new N.Notice(`Decrypted \u201C${i}\u201D \u2014 restored ${n.filesWritten} file(s).`)}catch(n){new N.Notice(`Couldn't decrypt: ${n.message}`)}this.refreshFolderPanels?.()}}async encryptDeleteSubtree(e,t){let i=await this.ensureFolderUnlocked(e);if(!i)return null;try{let s=new Date().toISOString(),o=(((this.settings.folderEncPrefs??{})[e.replace(/\/+$/,"")]??{}).trashEncryptFilenames??!1)||(this.settings.encryptTrashFilenames??!1),a=this.encryption.folderKeyEntry(e)?.keyId,l=await Ll(this.app,e,t,i,s,o,a,xs(e));return this.pendingEncBlobs.add(l.blobPath),this.unwatchReEncrypt(e,t),await this.saveSettings(),l.unpurged.length>0&&new N.Notice(`\u26A0\uFE0F Sent to encrypted trash, but ${l.unpurged.length} file${l.unpurged.length===1?" is":"s are"} still in plaintext (couldn't be removed or changed during the delete): ${l.unpurged.join(` -`)}`,0),l.blobPath}catch(s){return console.warn("[Stashpad] encrypt-delete failed",s),new N.Notice(`Couldn't encrypt-delete: ${s.message}`,0),null}}async plaintextDeleteSubtree(e,t){try{let i=new Date().toISOString(),s=await Ul(this.app,e,t,i,bs(e));return this.unwatchReEncrypt(e,t),s.unpurged.length>0&&new N.Notice(`\u26A0\uFE0F Sent to trash, but ${s.unpurged.length} file${s.unpurged.length===1?" is":"s are"} still in place (couldn't be removed or changed during the delete): +`)}`,0),l.blobPath}catch(s){return console.warn("[Stashpad] encrypt-delete failed",s),new N.Notice(`Couldn't encrypt-delete: ${s.message}`,0),null}}async plaintextDeleteSubtree(e,t){try{let i=new Date().toISOString(),s=await Ol(this.app,e,t,i,xs(e));return this.unwatchReEncrypt(e,t),s.unpurged.length>0&&new N.Notice(`\u26A0\uFE0F Sent to trash, but ${s.unpurged.length} file${s.unpurged.length===1?" is":"s are"} still in place (couldn't be removed or changed during the delete): ${s.unpurged.join(` -`)}`,0),s.blobPath}catch(i){return console.warn("[Stashpad] plaintext trash delete failed",i),new N.Notice(`Couldn't delete to trash: ${i.message}`,0),null}}async listPlaintextTrash(){let e=await Gl(this.app,this.trashSubfolderDirs()),t=[];for(let i of e)t.push({blob:i,meta:await At(this.app,i)});return t}async restoreDeletedAt(e,t={}){let i=await At(this.app,e);if(e.endsWith(`.${ks}`)||i?.encrypted===!1)try{let n=await Ss(this.app,e,i),o=new Set;for(let l of this.app.vault.getMarkdownFiles())if((l.parent?.path?.replace(/\/+$/,"")??"")===n.replace(/\/+$/,""))try{let c=ge(await this.app.vault.read(l)).fm.id;typeof c=="string"&&o.add(c)}catch{}let a=await Ll(this.app,e,o);this.pendingEncBlobs.delete(e);try{await this.newLog().append({type:"restore",id:i?.rootId||S,payload:{to:a.restoredTo,from:"trash",encrypted:!1}})}catch{}return t.silent||this.notifications.show({message:`Restored ${a.notesWritten} note${a.notesWritten===1?"":"s"} to \u201C${a.restoredTo.split("/").pop()}\u201D.`,kind:"success",category:"system",folder:a.restoredTo,actions:[{label:"Go to folder",onClick:()=>void this.activateViewForFolder(a.restoredTo)}]}),!0}catch(n){return console.warn("[Stashpad] restore plaintext trash failed",n),new N.Notice(`Couldn't restore: ${n.message}`,0),!1}let s=null;if(i?.keyId){let n=this.encryption.folderPathByKeyId(i.keyId);s=n?await this.ensureFolderUnlocked(n):null}if(!s)return t.silent||new N.Notice("Couldn't unlock the folder key this trashed note was encrypted with."),!1;if(i?.kind==="rawtrash")try{let n=await Kl(this.app,e,s);return this.pendingEncBlobs.delete(e),t.silent||this.notifications.show({message:`Restored ${n.filesWritten} file${n.filesWritten===1?"":"s"} to Obsidian's trash (${si}/).`,kind:"success",category:"system",folder:""}),!0}catch(n){return console.warn("[Stashpad] trash-backfill restore failed",n),new N.Notice(`Couldn't restore: ${n.message}`,0),!1}try{let n=await Ss(this.app,e,i,s),o=new Set;for(let l of this.app.vault.getMarkdownFiles())if((l.parent?.path?.replace(/\/+$/,"")??"")===n.replace(/\/+$/,""))try{let c=ge(await this.app.vault.read(l)).fm.id;typeof c=="string"&&o.add(c)}catch{}let a=await Rl(this.app,e,s,o);this.pendingEncBlobs.delete(e);try{await this.newLog().append({type:"restore",id:i?.rootId||S,payload:{to:a.restoredTo,from:"trash",encrypted:!0}})}catch{}return i?.rootId&&(this.watchReEncrypt({folder:a.restoredTo,rootId:i.rootId,title:i.title||"",count:i.count??a.notesWritten,via:"restore"}),await this.saveSettings()),t.silent||this.notifications.show({message:`Restored ${a.notesWritten} note${a.notesWritten===1?"":"s"} to \u201C${a.restoredTo.split("/").pop()}\u201D.`,kind:"success",category:"system",folder:a.restoredTo,actions:[{label:"Go to folder",onClick:()=>void this.activateViewForFolder(a.restoredTo)}]}),!0}catch(n){return console.warn("[Stashpad] restore-from-trash failed",n),new N.Notice(`Couldn't restore: ${n.message}`,0),!1}}async purgeDeletedAt(e){try{return await Fa(this.app,e),this.pendingEncBlobs.delete(e),!0}catch(t){return console.warn("[Stashpad] purge-from-trash failed",e,t),new N.Notice(`Couldn't delete: ${t.message}`,0),!1}}async purgeAllLockedContent(){let e=s=>this.isTrashBlobPath(s),t=new Set;for(let s of this.app.vault.getFiles())s.extension==="stashenc"&&!e(s.path)&&t.add(s.path);for(let s of this.pendingEncBlobs)e(s)||t.add(s);let i=0;for(let s of t)try{await Fa(this.app,s),this.pendingEncBlobs.delete(s),i++}catch(n){console.warn("[Stashpad] purge locked content failed",s,n)}return this.settings.lockedSubtrees=(this.settings.lockedSubtrees??[]).filter(s=>!t.has(s.blob)),await this.saveSettings(),i}async listRawTrashStashpadNotes(){let e=si,t=[];try{if(!await this.app.vault.adapter.exists(e))return t;let i=await this.app.vault.adapter.list(e);for(let s of i.files){if(!s.endsWith(".md"))continue;let n="";try{n=await this.app.vault.adapter.read(s)}catch{continue}let o=/^---\r?\n([\s\S]*?)\r?\n---/.exec(n);if(!o)continue;let a=o[1];if(!/^id:\s*\S/m.test(a)||!/^parent:\s*/m.test(a))continue;let l=s.split("/").pop()||s,c=l.replace(/\.md$/,"").replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ").trim()||l,A=0;try{A=(await this.app.vault.adapter.stat(s))?.mtime??0}catch{}t.push({path:s,name:l,title:c,mtime:A})}}catch{}return t}async restoreRawTrashNote(e){let t=(this.settings.folder||"Stashpad").trim().replace(/^\/+|\/+$/g,"")||"Stashpad",i=e.split("/").pop()||e;try{if(!await this.app.vault.adapter.exists(t))try{await this.app.vault.createFolder(t)}catch{}let s=`${t}/${i}`;return await this.app.vault.adapter.exists(s)&&(s=`${t}/${i.replace(/\.md$/,"")}-restored-${Date.now()}.md`),await this.app.vault.adapter.rename(e,s),this.notifications.show({message:`Restored "${i}" to ${t}/. If its parent lives in another folder, move it from there.`,kind:"success",category:"system",folder:t,actions:[{label:"Go to folder",onClick:()=>void this.activateViewForFolder(t)}]}),!0}catch(s){return new N.Notice(`Couldn't restore: ${s.message}`),!1}}archivedPlainNotesIn(e){let t=e.replace(/\/+$/,""),i=t+"/",s=[];for(let n of this.app.vault.getMarkdownFiles()){let o=n.parent?.path?.replace(/\/+$/,"")??"";if(!(o===t||o.startsWith(i)))continue;let a=this.app.metadataCache.getFileCache(n)?.frontmatter?.id;typeof a=="string"&&a&&s.push(n)}return s}async unarchiveNote(e){let i=(e.parent?.path??"").replace(/\/+$/,"").split("/"),s=i.indexOf("archive"),n=s>0?i.slice(0,s).join("/"):(this.settings.folder||"Stashpad").trim().replace(/^\/+|\/+$/g,"")||"Stashpad";if((e.parent?.path??"")===n)return new N.Notice("Already in the default folder."),!1;try{if(!await this.app.vault.adapter.exists(n))try{await this.app.vault.createFolder(n)}catch{}let o=`${n}/${e.name}`;return await this.app.vault.adapter.exists(o)&&(o=`${n}/${e.basename}-restored-${Date.now()}.md`),await this.app.fileManager.renameFile(e,o),this.notifications.show({message:`Un-archived "${e.basename}" to ${n}/.`,kind:"success",category:"system",folder:n}),!0}catch(o){return new N.Notice(`Couldn't un-archive: ${o.message}`),!1}}trashSubfolderDirs(){return this.discoverStashpadFolders().map(e=>bs(e))}async listDeletedTrash(){let e=await Wn(this.app,this.trashSubfolderDirs()),t=[];for(let i of e)t.push({blob:i,meta:await At(this.app,i)});return t}async restoreAllTrash(){let e=[...await this.listDeletedTrash(),...await this.listPlaintextTrash()];if(e.length===0)return new N.Notice("Nothing to restore."),0;let t=e.length>3?new N.Notice("",0):null,i=0;for(let s=0;s<e.length;s++){t?.setMessage(`\u{1F513} Restoring ${s+1}/${e.length}\u2026`);try{await this.restoreDeletedAt(e[s].blob,{silent:!0})&&i++}catch(n){console.warn("[Stashpad] restore-all skipped",e[s].blob,n)}}return t?.hide(),i>0&&this.notifications.show({message:`Restored ${i} note${i===1?"":"s"} from encrypted trash.`,kind:"success",category:"system",folder:""}),i}openEncryptedTrash(e){Xl(this)}async openRestoreTrashPicker(){if(!this.encryption.isConfigured()){new N.Notice("Set up encryption first (Settings \u2192 Stashpad \u2192 Encryption).");return}let e=await this.listDeletedTrash();if(e.length===0){new N.Notice("Encrypted trash is empty.");return}let t=e.map(({blob:i,meta:s})=>({blob:i,label:s?.title||i.split("/").pop()?.replace(/\.stashenc$/,"")||"Locked note",folder:s?.originalFolder||"(unknown)"}));new Xn(this.app,t,i=>{this.restoreDeletedAt(i)}).open()}isArchiveFolder(e){let t=e.replace(/\/+$/,"");return Ks(t)||(this.settings.archiveFolders??[]).includes(t)?!0:!!(this.settings.folderEncPrefs??{})[t]?.archive}archiveEncryptFor(e){let t=e.replace(/\/+$/,"");return t.endsWith("/archive")&&(t=t.slice(0,-8)),(this.settings.folderEncPrefs??{})[t]?.archiveEncryptContent??!1}async migrateArchiveFoldersToSubfolders(){if(!this.settings.migratedArchiveToSubfolders){this.archiveMigrationInFlight=!0;try{await this.migrateArchiveFoldersToSubfoldersInner()}finally{window.setTimeout(()=>{this.archiveMigrationInFlight=!1},4e3)}}}async migrateArchiveFoldersToSubfoldersInner(){let e=new Set((this.settings.archiveFolders??[]).map(l=>l.replace(/\/+$/,"")));for(let[l,c]of Object.entries(this.settings.folderEncPrefs??{}))c?.archive&&e.add(l.replace(/\/+$/,""));let t=this.newLog(),i=[],s=0,n=[],o=`${this.pluginPrivatePath()}/archive-migration-journal.json`,a=async()=>{try{await this.app.vault.adapter.write(o,JSON.stringify({ts:new Date().toISOString(),moves:n},null,1))}catch{}};for(let l of[...e].sort()){let c=this.app.vault.getAbstractFileByPath(l);if(!(c instanceof N.TFolder))continue;let A=Dt(l);try{await this.app.vault.adapter.exists(A)||await this.app.vault.createFolder(A)}catch{}let h=0,p=0;for(let f of[...c.children]){if(!(f instanceof N.TFile)||f.extension!=="md")continue;let u;try{u=ge(await this.app.vault.read(f)).fm.id}catch{p++,s++;continue}if(u===S)continue;let g=`${A}/${f.name}`,I=f.path;try{for(let m=1;await this.app.vault.adapter.exists(g);m++)g=`${A}/${f.basename}-${m}.md`;if(n.push({folder:l,from:I,to:g,ok:!1}),await this.app.fileManager.renameFile(f,g),!(this.app.vault.getAbstractFileByPath(g)instanceof N.TFile))throw new Error("rename did not land");n[n.length-1].ok=!0,h++}catch(m){p++,s++,console.warn("[Stashpad] archive migration move failed",I,m)}}if(await a(),p===0){let f={...this.settings.folderEncPrefs??{}},u={...f[l]??{}};delete u.archive,f[l]=u,this.settings.folderEncPrefs=f}i.push(`"${l}": ${h} note${h===1?"":"s"} \u2192 ${A}/${p?` (${p} failed \u2014 left in place)`:""}`),t.append({type:"archive_migration",id:"",payload:{folder:l,dest:A,moved:h,failed:p}})}s===0?(this.settings.archiveFolders=[],this.settings.defaultArchiveFolder=void 0,this.settings.migratedArchiveToSubfolders=!0,await this.saveSettings()):(await this.saveSettings(),new N.Notice(`Stashpad archive update: ${s} note${s===1?"":"s"} couldn't be moved (see the developer console). Nothing was deleted \u2014 the migration will retry on the next launch. A recovery journal of every move is at ${this.pluginPrivatePath()}/archive-migration-journal.json.`,0)),i.length&&new N.Notice(`Stashpad archive update: dedicated archive folders are now regular folders \u2014 archived notes moved into each folder's own "archive/" subfolder. +`)}`,0),s.blobPath}catch(i){return console.warn("[Stashpad] plaintext trash delete failed",i),new N.Notice(`Couldn't delete to trash: ${i.message}`,0),null}}async listPlaintextTrash(){let e=await Jl(this.app,this.trashSubfolderDirs()),t=[];for(let i of e)t.push({blob:i,meta:await At(this.app,i)});return t}async restoreDeletedAt(e,t={}){let i=await At(this.app,e);if(e.endsWith(`.${bs}`)||i?.encrypted===!1)try{let n=await Ds(this.app,e,i),o=new Set;for(let l of this.app.vault.getMarkdownFiles())if((l.parent?.path?.replace(/\/+$/,"")??"")===n.replace(/\/+$/,""))try{let c=ge(await this.app.vault.read(l)).fm.id;typeof c=="string"&&o.add(c)}catch{}let a=await Kl(this.app,e,o);this.pendingEncBlobs.delete(e);try{await this.newLog().append({type:"restore",id:i?.rootId||S,payload:{to:a.restoredTo,from:"trash",encrypted:!1}})}catch{}return t.silent||this.notifications.show({message:`Restored ${a.notesWritten} note${a.notesWritten===1?"":"s"} to \u201C${a.restoredTo.split("/").pop()}\u201D.`,kind:"success",category:"system",folder:a.restoredTo,actions:[{label:"Go to folder",onClick:()=>void this.activateViewForFolder(a.restoredTo)}]}),!0}catch(n){return console.warn("[Stashpad] restore plaintext trash failed",n),new N.Notice(`Couldn't restore: ${n.message}`,0),!1}let s=null;if(i?.keyId){let n=this.encryption.folderPathByKeyId(i.keyId);s=n?await this.ensureFolderUnlocked(n):null}if(!s)return t.silent||new N.Notice("Couldn't unlock the folder key this trashed note was encrypted with."),!1;if(i?.kind==="rawtrash")try{let n=await $l(this.app,e,s);return this.pendingEncBlobs.delete(e),t.silent||this.notifications.show({message:`Restored ${n.filesWritten} file${n.filesWritten===1?"":"s"} to Obsidian's trash (${si}/).`,kind:"success",category:"system",folder:""}),!0}catch(n){return console.warn("[Stashpad] trash-backfill restore failed",n),new N.Notice(`Couldn't restore: ${n.message}`,0),!1}try{let n=await Ds(this.app,e,i,s),o=new Set;for(let l of this.app.vault.getMarkdownFiles())if((l.parent?.path?.replace(/\/+$/,"")??"")===n.replace(/\/+$/,""))try{let c=ge(await this.app.vault.read(l)).fm.id;typeof c=="string"&&o.add(c)}catch{}let a=await Gl(this.app,e,s,o);this.pendingEncBlobs.delete(e);try{await this.newLog().append({type:"restore",id:i?.rootId||S,payload:{to:a.restoredTo,from:"trash",encrypted:!0}})}catch{}return i?.rootId&&(this.watchReEncrypt({folder:a.restoredTo,rootId:i.rootId,title:i.title||"",count:i.count??a.notesWritten,via:"restore"}),await this.saveSettings()),t.silent||this.notifications.show({message:`Restored ${a.notesWritten} note${a.notesWritten===1?"":"s"} to \u201C${a.restoredTo.split("/").pop()}\u201D.`,kind:"success",category:"system",folder:a.restoredTo,actions:[{label:"Go to folder",onClick:()=>void this.activateViewForFolder(a.restoredTo)}]}),!0}catch(n){return console.warn("[Stashpad] restore-from-trash failed",n),new N.Notice(`Couldn't restore: ${n.message}`,0),!1}}async purgeDeletedAt(e){try{return await ba(this.app,e),this.pendingEncBlobs.delete(e),!0}catch(t){return console.warn("[Stashpad] purge-from-trash failed",e,t),new N.Notice(`Couldn't delete: ${t.message}`,0),!1}}async purgeAllLockedContent(){let e=s=>this.isTrashBlobPath(s),t=new Set;for(let s of this.app.vault.getFiles())s.extension==="stashenc"&&!e(s.path)&&t.add(s.path);for(let s of this.pendingEncBlobs)e(s)||t.add(s);let i=0;for(let s of t)try{await ba(this.app,s),this.pendingEncBlobs.delete(s),i++}catch(n){console.warn("[Stashpad] purge locked content failed",s,n)}return this.settings.lockedSubtrees=(this.settings.lockedSubtrees??[]).filter(s=>!t.has(s.blob)),await this.saveSettings(),i}async listRawTrashStashpadNotes(){let e=si,t=[];try{if(!await this.app.vault.adapter.exists(e))return t;let i=await this.app.vault.adapter.list(e);for(let s of i.files){if(!s.endsWith(".md"))continue;let n="";try{n=await this.app.vault.adapter.read(s)}catch{continue}let o=/^---\r?\n([\s\S]*?)\r?\n---/.exec(n);if(!o)continue;let a=o[1];if(!/^id:\s*\S/m.test(a)||!/^parent:\s*/m.test(a))continue;let l=s.split("/").pop()||s,c=l.replace(/\.md$/,"").replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ").trim()||l,d=0;try{d=(await this.app.vault.adapter.stat(s))?.mtime??0}catch{}t.push({path:s,name:l,title:c,mtime:d})}}catch{}return t}async restoreRawTrashNote(e){let t=(this.settings.folder||"Stashpad").trim().replace(/^\/+|\/+$/g,"")||"Stashpad",i=e.split("/").pop()||e;try{if(!await this.app.vault.adapter.exists(t))try{await this.app.vault.createFolder(t)}catch{}let s=`${t}/${i}`;return await this.app.vault.adapter.exists(s)&&(s=`${t}/${i.replace(/\.md$/,"")}-restored-${Date.now()}.md`),await this.app.vault.adapter.rename(e,s),this.notifications.show({message:`Restored "${i}" to ${t}/. If its parent lives in another folder, move it from there.`,kind:"success",category:"system",folder:t,actions:[{label:"Go to folder",onClick:()=>void this.activateViewForFolder(t)}]}),!0}catch(s){return new N.Notice(`Couldn't restore: ${s.message}`),!1}}archivedPlainNotesIn(e){let t=e.replace(/\/+$/,""),i=t+"/",s=[];for(let n of this.app.vault.getMarkdownFiles()){let o=n.parent?.path?.replace(/\/+$/,"")??"";if(!(o===t||o.startsWith(i)))continue;let a=this.app.metadataCache.getFileCache(n)?.frontmatter?.id;typeof a=="string"&&a&&s.push(n)}return s}async unarchiveNote(e){let i=(e.parent?.path??"").replace(/\/+$/,"").split("/"),s=i.indexOf("archive"),n=s>0?i.slice(0,s).join("/"):(this.settings.folder||"Stashpad").trim().replace(/^\/+|\/+$/g,"")||"Stashpad";if((e.parent?.path??"")===n)return new N.Notice("Already in the default folder."),!1;try{if(!await this.app.vault.adapter.exists(n))try{await this.app.vault.createFolder(n)}catch{}let o=`${n}/${e.name}`;return await this.app.vault.adapter.exists(o)&&(o=`${n}/${e.basename}-restored-${Date.now()}.md`),await this.app.fileManager.renameFile(e,o),this.notifications.show({message:`Un-archived "${e.basename}" to ${n}/.`,kind:"success",category:"system",folder:n}),!0}catch(o){return new N.Notice(`Couldn't un-archive: ${o.message}`),!1}}trashSubfolderDirs(){return this.discoverStashpadFolders().map(e=>xs(e))}async listDeletedTrash(){let e=await Zn(this.app,this.trashSubfolderDirs()),t=[];for(let i of e)t.push({blob:i,meta:await At(this.app,i)});return t}async restoreAllTrash(){let e=[...await this.listDeletedTrash(),...await this.listPlaintextTrash()];if(e.length===0)return new N.Notice("Nothing to restore."),0;let t=e.length>3?new N.Notice("",0):null,i=0;for(let s=0;s<e.length;s++){t?.setMessage(`\u{1F513} Restoring ${s+1}/${e.length}\u2026`);try{await this.restoreDeletedAt(e[s].blob,{silent:!0})&&i++}catch(n){console.warn("[Stashpad] restore-all skipped",e[s].blob,n)}}return t?.hide(),i>0&&this.notifications.show({message:`Restored ${i} note${i===1?"":"s"} from encrypted trash.`,kind:"success",category:"system",folder:""}),i}openEncryptedTrash(e){_l(this)}async openRestoreTrashPicker(){if(!this.encryption.isConfigured()){new N.Notice("Set up encryption first (Settings \u2192 Stashpad \u2192 Encryption).");return}let e=await this.listDeletedTrash();if(e.length===0){new N.Notice("Encrypted trash is empty.");return}let t=e.map(({blob:i,meta:s})=>({blob:i,label:s?.title||i.split("/").pop()?.replace(/\.stashenc$/,"")||"Locked note",folder:s?.originalFolder||"(unknown)"}));new jn(this.app,t,i=>{this.restoreDeletedAt(i)}).open()}isArchiveFolder(e){let t=e.replace(/\/+$/,"");return qs(t)||(this.settings.archiveFolders??[]).includes(t)?!0:!!(this.settings.folderEncPrefs??{})[t]?.archive}archiveEncryptFor(e){let t=e.replace(/\/+$/,"");return t.endsWith("/archive")&&(t=t.slice(0,-8)),(this.settings.folderEncPrefs??{})[t]?.archiveEncryptContent??!1}async migrateArchiveFoldersToSubfolders(){if(!this.settings.migratedArchiveToSubfolders){this.archiveMigrationInFlight=!0;try{await this.migrateArchiveFoldersToSubfoldersInner()}finally{window.setTimeout(()=>{this.archiveMigrationInFlight=!1},4e3)}}}async migrateArchiveFoldersToSubfoldersInner(){let e=new Set((this.settings.archiveFolders??[]).map(l=>l.replace(/\/+$/,"")));for(let[l,c]of Object.entries(this.settings.folderEncPrefs??{}))c?.archive&&e.add(l.replace(/\/+$/,""));let t=this.newLog(),i=[],s=0,n=[],o=`${this.pluginPrivatePath()}/archive-migration-journal.json`,a=async()=>{try{await this.app.vault.adapter.write(o,JSON.stringify({ts:new Date().toISOString(),moves:n},null,1))}catch{}};for(let l of[...e].sort()){let c=this.app.vault.getAbstractFileByPath(l);if(!(c instanceof N.TFolder))continue;let d=Dt(l);try{await this.app.vault.adapter.exists(d)||await this.app.vault.createFolder(d)}catch{}let h=0,p=0;for(let f of[...c.children]){if(!(f instanceof N.TFile)||f.extension!=="md")continue;let u;try{u=ge(await this.app.vault.read(f)).fm.id}catch{p++,s++;continue}if(u===S)continue;let g=`${d}/${f.name}`,I=f.path;try{for(let m=1;await this.app.vault.adapter.exists(g);m++)g=`${d}/${f.basename}-${m}.md`;if(n.push({folder:l,from:I,to:g,ok:!1}),await this.app.fileManager.renameFile(f,g),!(this.app.vault.getAbstractFileByPath(g)instanceof N.TFile))throw new Error("rename did not land");n[n.length-1].ok=!0,h++}catch(m){p++,s++,console.warn("[Stashpad] archive migration move failed",I,m)}}if(await a(),p===0){let f={...this.settings.folderEncPrefs??{}},u={...f[l]??{}};delete u.archive,f[l]=u,this.settings.folderEncPrefs=f}i.push(`"${l}": ${h} note${h===1?"":"s"} \u2192 ${d}/${p?` (${p} failed \u2014 left in place)`:""}`),t.append({type:"archive_migration",id:"",payload:{folder:l,dest:d,moved:h,failed:p}})}s===0?(this.settings.archiveFolders=[],this.settings.defaultArchiveFolder=void 0,this.settings.migratedArchiveToSubfolders=!0,await this.saveSettings()):(await this.saveSettings(),new N.Notice(`Stashpad archive update: ${s} note${s===1?"":"s"} couldn't be moved (see the developer console). Nothing was deleted \u2014 the migration will retry on the next launch. A recovery journal of every move is at ${this.pluginPrivatePath()}/archive-migration-journal.json.`,0)),i.length&&new N.Notice(`Stashpad archive update: dedicated archive folders are now regular folders \u2014 archived notes moved into each folder's own "archive/" subfolder. ${i.join(` `)} -Find everything in the aggregated Archived view. (This notice stays until dismissed.)`,0)}async migrateDeletedToTrashSubfolders(){if(this.settings.migratedTrashToSubfolders)return;let e=this.app.vault.adapter,t=this.newLog(),i=0,s=0,n=0,o=[],a=`${this.pluginPrivatePath()}/trash-migration-journal.json`;try{let l=await Wn(this.app);for(let c of l){let A=await At(this.app,c),h=A?.kind==="deleted"&&A.originalFolder?A.originalFolder.replace(/\/+$/,""):"";if(!h||!(this.app.vault.getAbstractFileByPath(h)instanceof N.TFolder)){s++;continue}let p=bs(h);try{await e.exists(p)||await e.mkdir(p);let f=c.split("/").pop(),u=`${p}/${f}`;for(let B=1;await e.exists(u);B++)u=`${p}/${f.replace(/\.stashenc$/,"")} (${B}).stashenc`;o.push({from:c,to:u,ok:!1});let g=new Uint8Array(await e.readBinary(c));await e.writeBinary(u,g.slice().buffer);let I=new Uint8Array(await e.readBinary(u));if(I.length!==g.length)throw new Error("copy verify failed (length)");for(let B=0;B<g.length;B++)if(I[B]!==g[B])throw new Error("copy verify failed (content)");let m=c.replace(/\.stashenc$/,".stashmeta"),C=u.replace(/\.stashenc$/,".stashmeta");try{if(await e.exists(m)){let B=await e.read(m);if(await e.write(C,B),await e.read(C)!==B)throw new Error("sidecar verify failed");await e.remove(m)}}catch(B){throw new Error(`sidecar copy failed: ${B.message}`)}await e.remove(c),o[o.length-1].ok=!0,i++}catch(f){n++,console.warn("[Stashpad] trash migration move failed",c,f)}}try{await e.write(a,JSON.stringify({ts:new Date().toISOString(),moves:o},null,1))}catch{}}catch(l){console.error("[Stashpad] trash migration failed",l);return}t.append({type:"archive_migration",id:"",payload:{what:"trash-subfolders",moved:i,left:s,failed:n}}),n===0&&(this.settings.migratedTrashToSubfolders=!0,await this.saveSettings()),(i>0||n>0)&&new N.Notice(`Stashpad trash update: ${i} encrypted-trash item${i===1?"":"s"} moved into per-folder "trash/" subfolders${s?` (${s} stayed in _deleted/ \u2014 unknown or missing origin)`:""}${n?` \u2014 ${n} failed; will retry next launch`:""}. Everything stays visible in the Trash view.`,0)}async pruneZombieArchiveEntries(){let e=o=>this.app.vault.getAbstractFileByPath(o)instanceof N.TFolder,t=this.settings.archiveFolders??[],i=t.filter(o=>e(o.replace(/\/+$/,""))),s=i.length!==t.length,n=(this.settings.defaultArchiveFolder??"").replace(/\/+$/,"");n&&!e(n)&&(this.settings.defaultArchiveFolder=void 0,s=!0),s&&(this.settings.archiveFolders=i,await this.saveSettings(),console.info(`[Stashpad] pruned ${t.length-i.length} stale archive-folder entr${t.length-i.length===1?"y":"ies"}.`))}async ensureOkfTemplate(){let e=await jl(this.app,this.settings.okfTemplatePath||void 0);return this.settings.okfTemplatePath!==e&&(this.settings.okfTemplatePath=e,await this.saveSettings()),e}okfTemplatePathOrDefault(){return this.settings.okfTemplatePath||xa}okfActiveFolders(){return this.settings.okfEnabled?_l(this.settings.noteTemplates,this.okfTemplatePathOrDefault()).filter(e=>!this.isArchiveFolder(e)):[]}async rebuildOkfSuppressed(e){this.okfRebuildingFolders.add(e);try{return await Ta(this.app,e)}finally{window.setTimeout(()=>{this.okfRebuildingFolders.delete(e);for(let t of this.app.workspace.getLeavesOfType(z)){let i=t.view;i?.noteFolder===e&&i.forceReconcileRender?.()}},600)}}onOkfFileEvent(e){if(!this.settings.okfEnabled||!e.toLowerCase().endsWith(".md"))return;let t=e.lastIndexOf("/"),i=(t>=0?e.slice(0,t):"").replace(/\/+$/,"");(t>=0?e.slice(t+1):e)!=="index.md"&&(/(^|\/)(_imports|_exports|_attachments|_deleted|\.stashpad)(\/|$)/.test(e)||this.okfActiveFolders().includes(i)&&this.scheduleOkfRebuild(i))}scheduleOkfRebuild(e){let t=this.okfRebuildTimers.get(e);t!=null&&window.clearTimeout(t),this.okfRebuildTimers.set(e,window.setTimeout(()=>{this.okfRebuildTimers.delete(e),this.okfActiveFolders().includes(e)&&this.rebuildOkfSuppressed(e).catch(i=>console.warn("[Stashpad] OKF auto-rebuild failed",e,i))},2500))}async rebuildAllOkf(){let e=this.okfActiveFolders(),t=0,i=0;for(let s of e){let n=await this.rebuildOkfSuppressed(s);t+=n.checked,i+=n.written}return{folders:e.length,checked:t,written:i}}async exportOkf(e,t,i,s){let n=e.replace(/\/+$/,""),o=[],a=[],l=[],c=new Set;for(let I of t){let m=await Qt(this.app,n,I);if(m){o.push({id:m.rootNote.id,file:m.rootNote.file}),l.push(m.rootNote.file),c.add(m.rootNote.id);for(let C of m.descendants)a.push({id:C.id,file:C.file}),l.push(C.file),c.add(C.id)}}if(!l.length)return[];let A=(i||"okf-export").replace(/[\\/:*?"<>|]+/g," ").replace(/\s+/g," ").trim().slice(0,80)||"okf-export",h=new Date().toISOString().replace(/\D/g,"").slice(0,14),p=(this.settings.exportFolder||"_exports").trim().replace(/^\/+|\/+$/g,""),f=`${n}/${p}`;for(let I of[n,f])try{await this.app.vault.adapter.exists(I)||await this.app.vault.adapter.mkdir(I)}catch{}let u=[],g=async(I,m)=>{let C=`${f}/${I}`;await this.app.vault.createBinary(C,m.buffer.slice(m.byteOffset,m.byteOffset+m.byteLength)),u.push(C)};if(s.zip||s.targz){let I=await ec(this.app,l,n,c);s.zip&&await g(`${A}-${h}.okf.zip`,await tc(I)),s.targz&&await g(`${A}-${h}.okf.tar.gz`,await ic(I))}if(s.stash){let I=await vt(this.app,{rootNotes:o,allDescendants:a,sourceFolder:n});await g(`${A}-${h}.${ct}`,I)}return u}async idsInFolder(e){let t=e.replace(/\/+$/,""),i=new Set;for(let s of this.app.vault.getMarkdownFiles())if((s.parent?.path?.replace(/\/+$/,"")??"")===t)try{let n=ge(await this.app.vault.read(s)).fm.id;typeof n=="string"&&i.add(n)}catch{}return i}async crossFolderPaste(e,t,i,s,n){let o=i.replace(/\/+$/,"");if(this.isArchiveFolder(o))return new N.Notice(`"${o.split("/").pop()}" is an archive folder, so cross-folder paste is disabled there. Use the "Move selection to archive" command instead \u2014 it runs the proper archive flow (and encrypts, if that folder encrypts its archive).`),null;let a=[],l=[],c=[],A=[];for(let w of t){let F=await Qt(this.app,e,w);if(F){c.push(F.rootNote.id),a.push({id:F.rootNote.id,file:F.rootNote.file}),A.push(F.rootNote.file);for(let D of F.descendants)l.push({id:D.id,file:D.file}),A.push(D.file)}}if(!a.length)return null;let h=a.length+l.length,p=[],f=[];n==="cut"&&(p=await this.exclusiveAttachmentsOf(A),f=await this.snapshotPaths([...A.map(w=>w.path),...p.map(w=>w.path)]));let u=await vt(this.app,{rootNotes:a,allDescendants:l,sourceFolder:e}),g=await this.idsInFolder(o),I=new Set(this.filesUnder(o)),m=await We(this.app,u,o,g,{dedupeExisting:!1,forceNewIds:n==="copy",reparentRootsTo:s}),C=this.filesUnder(o).filter(w=>!I.has(w)),B=await this.snapshotPaths(C),E=c.map(w=>m.idRemap[w]).filter(w=>!!w);if(n==="cut"){for(let w of A)try{await this.app.fileManager.trashFile(w)}catch(F){console.warn("[Stashpad] cross-folder move: couldn't trash source note",w.path,F)}for(let w of p)try{await this.app.fileManager.trashFile(w)}catch(F){console.warn("[Stashpad] cross-folder move: couldn't trash source attachment",w.path,F)}}let y=async()=>{for(let w of[...C].reverse()){let F=this.app.vault.getAbstractFileByPath(w);if(F)try{await this.app.fileManager.trashFile(F)}catch{}}};return{rootIds:E,noteCount:h,undo:n==="cut"?async()=>{await y(),await this.restoreSnapshot(f)}:async()=>{await y()},redo:n==="cut"?async()=>{await this.restoreSnapshot(B);for(let w of f){let F=this.app.vault.getAbstractFileByPath(w.path);if(F)try{await this.app.fileManager.trashFile(F)}catch{}}}:async()=>{await this.restoreSnapshot(B)}}}async trashSubtrees(e,t){let i=[];for(let o of t){let a=await Qt(this.app,e,o);a&&i.push(a.rootNote.file,...a.descendants.map(l=>l.file))}if(!i.length)return[];let s=await this.exclusiveAttachmentsOf(i),n=[];for(let o of[...i,...s])try{await this.app.fileManager.trashFile(o),n.push(o)}catch(a){console.warn("[Stashpad] trashSubtrees: couldn't trash",o.path,a)}return n}async exclusiveAttachmentsOf(e){let t=new Set(e.map(n=>n.path)),i=new Map;for(let n of e)for(let o of await ii(this.app,n))i.set(o.path,o);let s=this.app.metadataCache.resolvedLinks??{};for(let n of Object.keys(s))if(!t.has(n))for(let o of Object.keys(s[n]??{}))i.delete(o);return[...i.values()]}async subtreeFilePaths(e,t){let i=[];for(let n of t){let o=await Qt(this.app,e,n);o&&i.push(o.rootNote.file,...o.descendants.map(a=>a.file))}if(!i.length)return[];let s=await this.exclusiveAttachmentsOf(i);return[...i.map(n=>n.path),...s.map(n=>n.path)]}async orderedSubtreeNodes(e,t){let i=[],s=new Set,n=o=>{let a=this.app.metadataCache.getFileCache(o)?.frontmatter?.position;return typeof a=="number"?a:Number.MAX_SAFE_INTEGER};for(let o of t){let a=await Qt(this.app,e,o);if(!a)continue;let l=new Map;for(let A of a.descendants){if(!A.parent)continue;let h=l.get(A.parent)??[];h.push({id:A.id,file:A.file,created:A.created}),l.set(A.parent,h)}for(let A of l.values())A.sort((h,p)=>n(h.file)-n(p.file)||h.created.localeCompare(p.created));let c=(A,h)=>{if(!s.has(A.id)){s.add(A.id),i.push({file:A.file,created:A.created,depth:h});for(let p of l.get(A.id)??[])c(p,h+1)}};c({id:a.rootNote.id,file:a.rootNote.file,created:a.rootNote.created},0)}return i}filesUnder(e){let t=e.replace(/\/+$/,"")+"/";return this.app.vault.getFiles().filter(i=>i.path.startsWith(t)).map(i=>i.path)}async snapshotPaths(e){let t=[];for(let i of e){let s=this.app.vault.getAbstractFileByPath(i);if(!s)continue;let n=!i.toLowerCase().endsWith(".md");try{n?t.push({path:i,binary:n,data:await this.app.vault.readBinary(s)}):t.push({path:i,binary:n,text:await this.app.vault.read(s)})}catch(o){console.warn("[Stashpad] snapshotPaths: couldn't read",i,o)}}return t}async restoreSnapshot(e){for(let t of e){let i=t.path.split("/").slice(0,-1).join("/");await this.ensureVaultFolder(i);let s=this.app.vault.getAbstractFileByPath(t.path);try{t.binary?s?await this.app.vault.adapter.writeBinary(t.path,t.data):await this.app.vault.createBinary(t.path,t.data):s?await this.app.vault.modify(s,t.text??""):await this.app.vault.create(t.path,t.text??"")}catch(n){console.warn("[Stashpad] restoreSnapshot: couldn't write",t.path,n)}}}async ensureVaultFolder(e){if(!e)return;let t="";for(let i of e.split("/"))if(t=t?`${t}/${i}`:i,!await this.app.vault.adapter.exists(t))try{await this.app.vault.createFolder(t)}catch{}}refreshOpenViewsForFolder(e){let t=e.replace(/\/+$/,"");for(let i of this.app.workspace.getLeavesOfType(z)){let s=i.view;if((s?.noteFolder?.replace(/\/+$/,"")??"")===t)try{s.tree?.rebuild?.(e),s.render?.()}catch(n){console.warn("[Stashpad] refresh view failed",n)}}}maybeArchiveOnMoveIn(e,t){if(e.extension!=="md")return;let i=e.parent?.path?.replace(/\/+$/,"")??"",s=t.lastIndexOf("/"),n=(s>=0?t.slice(0,s):"").replace(/\/+$/,"");if(i===n||!this.isArchiveFolder(i)||!this.encryption.isConfigured())return;let o=this.archivePending.get(i);o||(o={paths:new Set,timer:0},this.archivePending.set(i,o)),o.paths.add(e.path),window.clearTimeout(o.timer),o.timer=window.setTimeout(()=>{this.archivePending.delete(i),this.archiveSweep(i,[...o.paths])},1800)}async encryptExistingArchiveNotes(e){let t=Dt(e.replace(/\/+$/,"")),i=this.archivedPlainNotesIn(t).map(s=>s.path);return i.length===0?0:(await this.archiveSweep(t,i),i.length-this.archivedPlainNotesIn(t).length)}async archiveSweep(e,t){if(this.archiveMigrationInFlight||!this.isArchiveFolder(e))return;let i=e.replace(/\/+$/,"");if(!this.archiveEncryptFor(i))return;let s=[];for(let c of t){let A=this.app.vault.getAbstractFileByPath(c);if(!(A instanceof N.TFile)||(A.parent?.path?.replace(/\/+$/,"")??"")!==i)continue;let h;try{h=ge(await this.app.vault.read(A)).fm}catch{continue}let p=typeof h.id=="string"?h.id:null;!p||p===S||s.push({id:p,parent:typeof h.parent=="string"?h.parent:null})}if(s.length===0)return;let n=new Set(s.map(c=>c.id)),o=new Set((this.settings.lockedSubtrees??[]).map(c=>c.rootId).filter(c=>!!c)),a=s.filter(c=>!o.has(c.id)&&!(c.parent&&n.has(c.parent)));if(a.length===0||!this.encryption.hasFolderKey(i))return;if(!await this.ensureFolderUnlocked(i)){new N.Notice(`\u26A0\uFE0F Archive folder "${i.split("/").pop()}": ${a.length} arriving note${a.length===1?"":"s"} NOT encrypted (couldn't unlock the folder password). Unlock it and lock them manually.`,0);return}let l=0;for(let c of a)await this.lockNoteSubtree(i,c.id,null,{silent:!0})&&l++;l>0&&this.notifications.show({message:`Archived (encrypted) ${l} note${l===1?"":"s"} moved into \u201C${i.split("/").pop()}\u201D.`,kind:"success",category:"system",folder:i,actions:[{label:"All archived",onClick:()=>void He(this,"archived")}]})}async activateViewForFolder(e){let t=(e||"").replace(/^\/+|\/+$/g,"");if(!t)return null;let i=this.app.workspace.getLeaf("tab");return await i.setViewState({type:z,active:!0,state:{folderOverride:t}}),this.app.workspace.revealLeaf(i),i}navigateLeafTo(e,t,i){let s=e?.view;if(s?.navigateTo&&(!s.tree||s.tree.get(i))){s.navigateTo(i);return}this.navigateWhenReady(t,i)}async openFolderInStashpad(e){let t=(e||"").replace(/^\/+|\/+$/g,"");if(!t)return;if(this.settings.foldersAlwaysNewTab){await this.activateViewForFolder(t);return}let i=await this.findStashpadLeafForFolder(t);if(i){this.app.workspace.revealLeaf(i),this.app.workspace.setActiveLeaf(i,{focus:!0});return}await this.activateViewForFolder(t)}async findStashpadLeafForFolder(e){let t=e.replace(/\/+$/,""),i=this.app.workspace.getLeavesOfType(z),s=i.find(o=>!o.isDeferred&&(o.view?.noteFolder??"").replace(/\/+$/,"")===t);if(s)return s;let n=i.find(o=>o.isDeferred&&(o.getViewState()?.state?.folderOverride??"").replace(/\/+$/,"")===t);if(n){try{await n.loadIfDeferred?.()}catch{}return n}return null}isStashpadNoteFile(e){let t=e.parent?.path?.replace(/\/+$/,"")??"";if(!this.discoverStashpadFolders().includes(t))return!1;let i=this.app.metadataCache.getFileCache(e)?.frontmatter?.id;return typeof i=="string"&&i.length>0}async revealNoteInStashpad(e){let t=e.parent?.path?.replace(/\/+$/,"")??"",i=this.app.metadataCache.getFileCache(e)?.frontmatter?.id;if(!t||typeof i!="string"||!i){new N.Notice("That note isn't a Stashpad note.");return}await this.revealNoteByRef(t,i)}findStashpadNotesEmbedding(e){let t=e.path,i=this.app.metadataCache.resolvedLinks||{},s=[];for(let n of Object.keys(i)){if(!i[n][t])continue;let o=this.app.vault.getAbstractFileByPath(n);o instanceof N.TFile&&this.isStashpadNoteFile(o)&&s.push(o)}return s}async revealAttachmentInStashpad(e,t){let i=t??this.findStashpadNotesEmbedding(e);if(i.length===0){new N.Notice("No Stashpad note references this attachment.");return}if(i.length===1){await this.revealNoteInStashpad(i[0]);return}new Ha(this.app,i,s=>void this.revealNoteInStashpad(s)).open()}async revealNoteByRef(e,t){let i=e.replace(/\/+$/,""),s=await this.findStashpadLeafForFolder(i);if(s){this.app.workspace.revealLeaf(s),this.app.workspace.setActiveLeaf(s,{focus:!0}),this.navigateLeafTo(s,i,t);return}let n=await this.activateViewForFolder(i);this.navigateLeafTo(n,i,t)}async openSchedulerForRef(e,t){await this.revealNoteByRef(e,t);let i=e.replace(/\/+$/,""),n=(await this.findStashpadLeafForFolder(i))?.view;n instanceof Ts?n.cmdSetDue(n.tree.get(t)):new N.Notice("Couldn\u2019t open the scheduler for that task.")}resolveNoteFileInFolder(e,t){let i=e.replace(/\/+$/,"");for(let s of this.app.vault.getMarkdownFiles())if((s.parent?.path?.replace(/\/+$/,"")??"")===i&&this.app.metadataCache.getFileCache(s)?.frontmatter?.id===t)return s;return null}async handleDeepLink(e,t={}){let i=(e.folder||"").replace(/^\/+|\/+$/g,""),s=(e.note||"").trim(),n=jr(e),o=c=>(t.silent||new N.Notice(c),!1);if(!i)return o("Stashpad link: missing \u201Cfolder\u201D.");if(!(this.app.vault.getAbstractFileByPath(i)instanceof N.TFolder))return o(`Stashpad link: folder \u201C${i}\u201D not found.`);await new Promise(c=>this.app.workspace.onLayoutReady(()=>c()));let l=null;if(s){for(let c=0;c<12&&!l;c++)l=this.resolveNoteFileInFolder(i,s),l||await new Promise(A=>window.setTimeout(A,150));if(!l)return o(`Stashpad link: note \u201C${s}\u201D not found in ${i}.`)}await this.openDeepLinkTarget(i,s,t);for(let c of n)if(c!=="reveal"){if(c==="open"){l&&await this.app.workspace.getLeaf("tab").openFile(l);continue}console.warn(`[stashpad] deep link: unknown action \u201C${c}\u201D \u2014 skipped.`)}return!0}async openDeepLinkTarget(e,t,i={}){let s=e.replace(/\/+$/,"");if(!i.forceNewTab){let o=this.app.workspace.activeLeaf,a=await this.findStashpadLeafForFolder(s);if(a&&a!==o){this.app.workspace.revealLeaf(a),this.app.workspace.setActiveLeaf(a,{focus:!0}),t&&this.navigateLeafTo(a,s,t);return}}let n=await this.activateViewForFolder(s);t&&this.navigateLeafTo(n,s,t)}openDeepLinkModal(){new ps(this.app,e=>{let i=e.split(/\s+/).map(s=>s.trim()).filter(Boolean).map(s=>({raw:s,parsed:Zr(s)})).filter(s=>!!s.parsed);if(i.length===0){new N.Notice("That doesn't look like a Stashpad link.");return}this.openDeepLinks(i)}).open()}async openDeepLinks(e){let t=this.app.vault.getName(),i=e.length>1,s=0,n=0,o=0;for(let{raw:l,parsed:c}of e){if(c.vault&&c.vault!==t){this.handOffToObsidian(l),n++,await new Promise(h=>window.setTimeout(h,350));continue}if(await this.handleDeepLink(c,{forceNewTab:i,silent:!0})){s++;continue}o++}let a=[];s&&a.push(`opened ${s}`),n&&a.push(`sent ${n} to Obsidian (other vault)`),o&&a.push(`${o} not found`),new N.Notice(`Stashpad link${e.length===1?"":"s"}: ${a.join(" \xB7 ")||"nothing to open"}.`)}handOffToObsidian(e){try{let t=window.require?.("electron")?.shell;if(t?.openExternal){t.openExternal(e);return}}catch{}try{window.open(e)}catch{}}async closeDuplicateStashpadTabs(){let e=this.app.workspace.getLeavesOfType(z),t=this.app.workspace.activeLeaf;for(let u of e)try{await u.loadIfDeferred?.()}catch{}let i=u=>u.getViewState()?.state??{},s=u=>{let g=i(u);return(u.isDeferred?g.folderOverride??"":u.view?.noteFolder??g.folderOverride??"").replace(/\/+$/,"")},n=u=>{let g=i(u);return(u.isDeferred?g.focusId:u.view?.focusId??g.focusId)||S},o=u=>{let g=u.view;return!!g&&g.getViewType?.()===z&&typeof g.navigateTo=="function"&&typeof g.noteFolder=="string"},a=new Map;for(let u of this.app.vault.getMarkdownFiles()){let g=(u.parent?.path??"").replace(/\/+$/,""),I=this.app.metadataCache.getFileCache(u)?.frontmatter?.id;typeof I=="string"&&I&&(a.get(g)??a.set(g,new Set).get(g)).add(I)}let l=0,c=[];for(let u of e){let g=s(u),I=n(u);if(g&&I&&I!==S){let m=!u.isDeferred&&!!u.view?.tree?.get?.(I),C=a.get(g)?.has(I)??!1;if(!m&&!C){u.detach(),l++;continue}}c.push(u)}let A=new Map;for(let u of c){let g=s(u);if(!g)continue;let I=g+" "+n(u);(A.get(I)??A.set(I,[]).get(I)).push(u)}let h=0;for(let u of A.values()){if(u.length<=1)continue;u.sort((I,m)=>{let C=B=>B===t?2:B.isDeferred?0:1;return C(m)-C(I)});let g=null;for(let I of u){try{await I.loadIfDeferred?.()}catch{}if(o(I)){g=I;break}}g||(g=u[0]);for(let I of u)I!==g&&(I.detach(),h++)}let p=this.app.workspace.getLeavesOfType(z).length,f=document.createDocumentFragment();return f.createEl("div",{text:h+l>0?"Stashpad tabs cleaned up:":"Stashpad tabs - nothing to clean up:"}),f.createEl("div",{text:`\u2022 ${h} duplicate tab${h===1?"":"s"} closed`}),f.createEl("div",{text:`\u2022 ${l} orphaned tab${l===1?"":"s"} pruned (note no longer exists)`}),f.createEl("div",{text:`\u2022 ${p} Stashpad tab${p===1?"":"s"} remaining`}),new N.Notice(f,7e3),h+l}navigateWhenReady(e,t,i=15){let s=e.replace(/\/+$/,""),n=this.app.workspace.getLeavesOfType(z).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(t))){n.navigateTo(t);return}i>0?window.setTimeout(()=>this.navigateWhenReady(e,t,i-1),90):n&&typeof n.navigateTo=="function"&&n.navigateTo(t)}collectAuthoredFolders(){let e=(this.settings.authorId??"").trim();if(!e)return[];let t=`-${e}`,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:"",l=Array.isArray(o.contributors)?o.contributors.filter(u=>typeof u=="string"):[],c=a.includes(t),A=l.some(u=>u.includes(t));if(!c&&!A)continue;let h=n.parent?.path??"",p=i.find(u=>h===u||h.startsWith(u+"/"));if(!p)continue;s.has(p)||s.set(p,{authored:0,contributed:0});let f=s.get(p);c&&f.authored++,A&&f.contributed++}return[...s.entries()].map(([n,o])=>({folder:n,...o})).sort((n,o)=>o.authored+o.contributed-(n.authored+n.contributed))}parseAuthorRef(e){return gt(e)}authorRefFor(e,t,i){let s=i.replace(/[^\w\- ]+/g,"").trim().replace(/\s+/g,"-")||"author",n=`${e.replace(/\/+$/,"")}/_authors/${s}-${t}.md`,o=i.replace(/[\[\]|]/g,"").trim()||s;return`[[${n}|${o}]]`}async ensureAuthorStubFor(e,t,i){if(!t||!i)return!1;this.authorRegistry.record({id:t,name:i});let s=`${e.replace(/\/+$/,"")}/_authors`;if(this.app.vault.getMarkdownFiles().some(c=>c.path.startsWith(s+"/")&&this.parseAuthorFilePath(c.path)?.id===t))return!1;let o=this.authorRegistry.get(t),a=this.authorNameToSafe(i),l=`${s}/${a}-${t}.md`;try{return await this.ensureFolderPath(s),await this.app.vault.adapter.exists(l)?!1:(await this.app.vault.create(l,this.buildAuthorStub({id:t,name:i,role:o?.role,department:o?.department},new Date().toISOString())),!0)}catch(c){return console.warn("[Stashpad] ensureAuthorStubFor failed",l,c),!1}}async seedKnownAuthorsInFolder(e){let t=0;for(let i of this.collectKnownAuthors())await this.ensureAuthorStubFor(e,i.id,i.name)&&t++;return t}async autoResolveDueTask(e,t,i){try{await this.app.fileManager.processFrontMatter(e,s=>{let n=s.due!=null?Date.parse(String(s.due)):NaN;if(Number.isFinite(n)&&n>i)return;let o=vn(s.repeat);o?(s.due=new Date(Qn(o,Number.isFinite(n)?n:null,i)).toISOString(),delete s.completed):s.completed=!0})}catch(s){console.warn("[Stashpad] auto-resolve failed",e.path,s)}}async checkDueReminders(){let e=Date.now(),t=new Set(this.settings.notifiedDueKeys??[]),i=(this.settings.authorId??"").trim(),s=[],n={...this.settings.persistReminderLog??{}},o=!1,a=new Set;for(let l of this.app.vault.getMarkdownFiles()){if(l.path.includes("/_authors/"))continue;let c=this.app.metadataCache.getFileCache(l)?.frontmatter;if(!c||c.due==null)continue;let A=typeof c.id=="string"?c.id:"";if(!A)continue;let h=String(c.due),p=typeof c.due=="number"?c.due:Date.parse(h);if(!Number.isFinite(p)||p>e)continue;if(c.completed!==!0){let I=ta(c.autoDoneAfter);if(I!=null&&e>=p+I){await this.autoResolveDueTask(l,p,e);continue}}if(c.completed===!0)continue;let f=xt(c);if(f.length>0&&!(i&&f.some(I=>I.id===i)))continue;let u=ta(c.remindEvery);if(u!=null){a.add(A);let I=n[A]??0;e-I>=u&&(n[A]=e,o=!0,s.push({id:A,folder:(l.parent?.path??"").replace(/\/+$/,""),file:l,dueMs:p,key:`${A}@persist`}));continue}let g=`${A}@${h}`;t.has(g)||s.push({id:A,folder:(l.parent?.path??"").replace(/\/+$/,""),file:l,dueMs:p,key:g})}for(let l of Object.keys(n))a.has(l)||(delete n[l],o=!0);o&&(this.settings.persistReminderLog=n,await this.saveSettings()),s.length!==0&&(this.settings.notifiedDueKeys=[...this.settings.notifiedDueKeys??[],...s.filter(l=>!l.key.endsWith("@persist")).map(l=>l.key)].slice(-2e3),await this.saveSettings(),await this.showDueToasts(s))}async showDueToasts(e){if(e.length===0)return;let t=async i=>{try{let n=ge(await this.app.vault.cachedRead(i)).body.split(/\r?\n/).map(o=>o.trim()).find(o=>o.length>0);if(n)return n.replace(/^[#>\-*\s]+/,"").slice(0,60)}catch{}return i.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ")};if(e.length<=3)for(let i of e){let s=await t(i.file);this.notifications.show({message:`\u23F0 Task due: \u201C${s}\u201D (${it(i.dueMs,this.settings)})`,kind:"warning",category:"reminder",duration:0,folder:i.folder,affectedIds:[i.id],onBodyClick:()=>void this.openDeepLinkTarget(i.folder,i.id),overlayAction:{label:"Snooze",icon:"alarm-clock-check",title:"Snooze / reschedule\u2026",onClick:()=>void this.openSchedulerForRef(i.folder,i.id)}})}else this.notifications.show({message:`\u23F0 ${e.length} tasks are due \u2014 open the Tasks panel to review.`,kind:"warning",category:"reminder",duration:0,folder:""})}async resendDueReminders(){let e=Date.now(),t=(this.settings.authorId??"").trim(),i=[];for(let s of this.app.vault.getMarkdownFiles()){if(s.path.includes("/_authors/"))continue;let n=this.app.metadataCache.getFileCache(s)?.frontmatter;if(!n||n.due==null)continue;let o=typeof n.id=="string"?n.id:"";if(!o||n.completed===!0)continue;let a=typeof n.due=="number"?n.due:Date.parse(String(n.due));if(!Number.isFinite(a)||a>e)continue;let l=xt(n);l.length>0&&!(t&&l.some(c=>c.id===t))||i.push({id:o,folder:(s.parent?.path??"").replace(/\/+$/,""),file:s,dueMs:a})}if(i.length===0){new N.Notice("No incomplete tasks are due \u2014 your backlog is clear. \u{1F389}");return}await this.showDueToasts(i)}async syncAuthorsAcrossFolders(){await this.rebuildAuthorRegistry();let e=this.collectKnownAuthors(),t=this.discoverStashpadFolders();if(!e.length||!t.length){new N.Notice("No authors or Stashpad folders to sync.");return}let i=t.length*e.length>8?new N.Notice("",0):null,s=0;for(let n of t){i?.setMessage(`Syncing authors \u2192 ${n.split("/").pop()}\u2026`);for(let o of e)await this.ensureAuthorStubFor(n,o.id,o.name)&&s++}i?.hide(),this.notifications.show({message:`Synced authors across ${t.length} folder${t.length===1?"":"s"} \u2014 ${s} new stub${s===1?"":"s"} (${e.length} author${e.length===1?"":"s"} known).`,kind:"success",category:"system",folder:""})}collectKnownAuthors(){let e=new Map,t=(this.settings.authorId??"").trim(),i=(this.settings.authorName??"").trim();t&&i&&e.set(t,i);for(let s of this.authorRegistry.all())e.has(s.id)||e.set(s.id,s.name);for(let s of this.app.vault.getMarkdownFiles()){if(!s.path.includes("/_authors/"))continue;let n=this.parseAuthorFilePath(s.path);if(!n)continue;let o=this.app.metadataCache.getFileCache(s)?.frontmatter,l=((Array.isArray(o?.aliases)?o.aliases.find(c=>typeof c=="string")??"":typeof o?.aliases=="string"?o.aliases:"")||(typeof o?.name=="string"?o.name:"")||n.name).trim();e.has(n.id)||e.set(n.id,l),this.authorRegistry.record({id:n.id,name:l})}return[...e.entries()].map(([s,n])=>({id:s,name:n}))}async rebuildAuthorRegistry(){let e=this.discoverStashpadFolders(),t=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 l of o.contributors)typeof l=="string"&&a.push(l);for(let l of a){let c=this.parseAuthorRef(l);if(c)if(!t.has(c.id))t.set(c.id,{id:c.id,name:c.name,fromStub:!1}),i++;else{let A=t.get(c.id);!A.name&&c.name&&(A.name=c.name)}}}let s=0;for(let n of e){let o=`${n}/_authors`;for(let a of this.app.vault.getMarkdownFiles()){if(!a.path.startsWith(o+"/"))continue;let l=this.parseAuthorFilePath(a.path);if(!l)continue;let c=this.app.metadataCache.getFileCache(a)?.frontmatter,h=((Array.isArray(c?.aliases)?c.aliases.find(g=>typeof g=="string")??"":typeof c?.aliases=="string"?c.aliases:"")||(typeof c?.name=="string"?c.name:"")||l.name).trim(),p=typeof c?.role=="string"?c.role:void 0,f=typeof c?.department=="string"?c.department:void 0,u=t.get(l.id);u||s++,t.set(l.id,{id:l.id,name:h||u?.name,role:p??u?.role,department:f??u?.department,fromStub:!0})}}return await this.authorRegistry.load(),this.authorRegistry.replaceAll([...t.values()]),await this.authorRegistry.save(),{total:t.size,fromStubs:s,fromNotes:i}}buildAuthorStub(e,t){let i=a=>a.replace(/[\r\n]+/g," ").trim(),s=a=>i(a).replace(/\\/g,"\\\\").replace(/"/g,'\\"'),n=i(e.name),o=["---",`authorId: ${e.id}`,"aliases:",` - "${s(e.name)}"`];return e.role&&o.push(`role: "${s(e.role)}"`),e.department&&o.push(`department: "${s(e.department)}"`),o.push(`created: ${t}`,"---",`# ${n}`),o.join(` -`)}async restoreMissingAuthorStubs(){await this.authorRegistry.load();let e=this.authorRegistry.all().filter(n=>n.id&&n.name),t=this.discoverStashpadFolders(),i=this.app.vault.getMarkdownFiles(),s=0;for(let n of t){let o=`${n}/_authors`,a=new Set;for(let l of i){if(!l.path.startsWith(o+"/"))continue;let c=this.parseAuthorFilePath(l.path)?.id;c&&a.add(c)}for(let l of e){if(a.has(l.id))continue;let c=this.authorNameToSafe(l.name),A=`${o}/${c}-${l.id}.md`;try{if(await this.ensureFolderPath(o),await this.app.vault.adapter.exists(A))continue;await this.app.vault.create(A,this.buildAuthorStub(l,l.firstSeen??new Date().toISOString())),s++}catch(h){console.warn("[Stashpad] restore author stub failed",A,h)}}}return{created:s,folders:t.length}}async convertAttachmentsToLinks(){let e=0,t=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+"/")||qt(n.path))continue;let a=this.app.metadataCache.getFileCache(n)?.frontmatter;if(!a||typeof a.id!="string"||!a.id)continue;let l=a.attachments,c=Array.isArray(l),A=typeof l=="string"&&l.trim().length>0;if(!(!c&&!A||!(A?!t(l):l.some(p=>typeof p=="string"&&p.trim()&&!t(p)))))try{await this.app.fileManager.processFrontMatter(n,p=>{Array.isArray(p.attachments)?p.attachments=p.attachments.map(f=>typeof f=="string"&&f.trim()?tt(f):f):typeof p.attachments=="string"&&p.attachments.trim()&&(p.attachments=[tt(p.attachments)])}),e++}catch(p){console.warn("[Stashpad] attachment-link conversion failed",n.path,p)}}}return e}syncObsidianExcludedArchives(){try{let e=this.app.vault;if(typeof e.getConfig!="function"||typeof e.setConfig!="function")return;let t=Array.isArray(e.getConfig("userIgnoreFilters"))?e.getConfig("userIgnoreFilters"):[],i=new Set(t),s=!1;for(let n of this.discoverStashpadFolders()){let o=`${n.replace(/\/+$/,"")}/_archive/`;i.has(o)||(i.add(o),s=!0)}s&&e.setConfig("userIgnoreFilters",[...i])}catch(e){console.warn("[Stashpad] couldn't update Obsidian excluded files",e)}}openImportPicker(){let e=this.discoverStashpadFolders();if(e.length===0){new N.Notice("No Stashpad folders to import into.");return}if(e.length===1){this.importService.pickFilesInto(e[0]);return}let t=this.importService.defaultDestination()??e[0];new Ra(this.app,t,e,i=>this.importService.pickFilesInto(i)).open()}async runImportLooseFiles(e){let t=e.split("/").pop()||e,i=0,s=0,n=0;try{({files:i,folders:s,stashes:n}=await this.importService.importLooseInto(e))}catch(c){this.notifications.show({message:`Stashpad: import failed in \`${t}\` +Find everything in the aggregated Archived view. (This notice stays until dismissed.)`,0)}async migrateDeletedToTrashSubfolders(){if(this.settings.migratedTrashToSubfolders)return;let e=this.app.vault.adapter,t=this.newLog(),i=0,s=0,n=0,o=[],a=`${this.pluginPrivatePath()}/trash-migration-journal.json`;try{let l=await Zn(this.app);for(let c of l){let d=await At(this.app,c),h=d?.kind==="deleted"&&d.originalFolder?d.originalFolder.replace(/\/+$/,""):"";if(!h||!(this.app.vault.getAbstractFileByPath(h)instanceof N.TFolder)){s++;continue}let p=xs(h);try{await e.exists(p)||await e.mkdir(p);let f=c.split("/").pop(),u=`${p}/${f}`;for(let B=1;await e.exists(u);B++)u=`${p}/${f.replace(/\.stashenc$/,"")} (${B}).stashenc`;o.push({from:c,to:u,ok:!1});let g=new Uint8Array(await e.readBinary(c));await e.writeBinary(u,g.slice().buffer);let I=new Uint8Array(await e.readBinary(u));if(I.length!==g.length)throw new Error("copy verify failed (length)");for(let B=0;B<g.length;B++)if(I[B]!==g[B])throw new Error("copy verify failed (content)");let m=c.replace(/\.stashenc$/,".stashmeta"),C=u.replace(/\.stashenc$/,".stashmeta");try{if(await e.exists(m)){let B=await e.read(m);if(await e.write(C,B),await e.read(C)!==B)throw new Error("sidecar verify failed");await e.remove(m)}}catch(B){throw new Error(`sidecar copy failed: ${B.message}`)}await e.remove(c),o[o.length-1].ok=!0,i++}catch(f){n++,console.warn("[Stashpad] trash migration move failed",c,f)}}try{await e.write(a,JSON.stringify({ts:new Date().toISOString(),moves:o},null,1))}catch{}}catch(l){console.error("[Stashpad] trash migration failed",l);return}t.append({type:"archive_migration",id:"",payload:{what:"trash-subfolders",moved:i,left:s,failed:n}}),n===0&&(this.settings.migratedTrashToSubfolders=!0,await this.saveSettings()),(i>0||n>0)&&new N.Notice(`Stashpad trash update: ${i} encrypted-trash item${i===1?"":"s"} moved into per-folder "trash/" subfolders${s?` (${s} stayed in _deleted/ \u2014 unknown or missing origin)`:""}${n?` \u2014 ${n} failed; will retry next launch`:""}. Everything stays visible in the Trash view.`,0)}async pruneZombieArchiveEntries(){let e=o=>this.app.vault.getAbstractFileByPath(o)instanceof N.TFolder,t=this.settings.archiveFolders??[],i=t.filter(o=>e(o.replace(/\/+$/,""))),s=i.length!==t.length,n=(this.settings.defaultArchiveFolder??"").replace(/\/+$/,"");n&&!e(n)&&(this.settings.defaultArchiveFolder=void 0,s=!0),s&&(this.settings.archiveFolders=i,await this.saveSettings(),console.info(`[Stashpad] pruned ${t.length-i.length} stale archive-folder entr${t.length-i.length===1?"y":"ies"}.`))}async ensureOkfTemplate(){let e=await tc(this.app,this.settings.okfTemplatePath||void 0);return this.settings.okfTemplatePath!==e&&(this.settings.okfTemplatePath=e,await this.saveSettings()),e}okfTemplatePathOrDefault(){return this.settings.okfTemplatePath||Ma}okfActiveFolders(){return this.settings.okfEnabled?ic(this.settings.noteTemplates,this.okfTemplatePathOrDefault()).filter(e=>!this.isArchiveFolder(e)):[]}async rebuildOkfSuppressed(e){this.okfRebuildingFolders.add(e);try{return await Ha(this.app,e)}finally{window.setTimeout(()=>{this.okfRebuildingFolders.delete(e);for(let t of this.app.workspace.getLeavesOfType($)){let i=t.view;i?.noteFolder===e&&i.forceReconcileRender?.()}},600)}}onOkfFileEvent(e){if(!this.settings.okfEnabled||!e.toLowerCase().endsWith(".md"))return;let t=e.lastIndexOf("/"),i=(t>=0?e.slice(0,t):"").replace(/\/+$/,"");(t>=0?e.slice(t+1):e)!=="index.md"&&(/(^|\/)(_imports|_exports|_attachments|_deleted|\.stashpad)(\/|$)/.test(e)||this.okfActiveFolders().includes(i)&&this.scheduleOkfRebuild(i))}scheduleOkfRebuild(e){let t=this.okfRebuildTimers.get(e);t!=null&&window.clearTimeout(t),this.okfRebuildTimers.set(e,window.setTimeout(()=>{this.okfRebuildTimers.delete(e),this.okfActiveFolders().includes(e)&&this.rebuildOkfSuppressed(e).catch(i=>console.warn("[Stashpad] OKF auto-rebuild failed",e,i))},2500))}async rebuildAllOkf(){let e=this.okfActiveFolders(),t=0,i=0;for(let s of e){let n=await this.rebuildOkfSuppressed(s);t+=n.checked,i+=n.written}return{folders:e.length,checked:t,written:i}}async exportOkf(e,t,i,s){let n=e.replace(/\/+$/,""),o=[],a=[],l=[],c=new Set;for(let I of t){let m=await Qt(this.app,n,I);if(m){o.push({id:m.rootNote.id,file:m.rootNote.file}),l.push(m.rootNote.file),c.add(m.rootNote.id);for(let C of m.descendants)a.push({id:C.id,file:C.file}),l.push(C.file),c.add(C.id)}}if(!l.length)return[];let d=(i||"okf-export").replace(/[\\/:*?"<>|]+/g," ").replace(/\s+/g," ").trim().slice(0,80)||"okf-export",h=new Date().toISOString().replace(/\D/g,"").slice(0,14),p=(this.settings.exportFolder||"_exports").trim().replace(/^\/+|\/+$/g,""),f=`${n}/${p}`;for(let I of[n,f])try{await this.app.vault.adapter.exists(I)||await this.app.vault.adapter.mkdir(I)}catch{}let u=[],g=async(I,m)=>{let C=`${f}/${I}`;await this.app.vault.createBinary(C,m.buffer.slice(m.byteOffset,m.byteOffset+m.byteLength)),u.push(C)};if(s.zip||s.targz){let I=await sc(this.app,l,n,c);s.zip&&await g(`${d}-${h}.okf.zip`,await nc(I)),s.targz&&await g(`${d}-${h}.okf.tar.gz`,await oc(I))}if(s.stash){let I=await vt(this.app,{rootNotes:o,allDescendants:a,sourceFolder:n});await g(`${d}-${h}.${ct}`,I)}return u}async idsInFolder(e){let t=e.replace(/\/+$/,""),i=new Set;for(let s of this.app.vault.getMarkdownFiles())if((s.parent?.path?.replace(/\/+$/,"")??"")===t)try{let n=ge(await this.app.vault.read(s)).fm.id;typeof n=="string"&&i.add(n)}catch{}return i}async crossFolderPaste(e,t,i,s,n){let o=i.replace(/\/+$/,"");if(this.isArchiveFolder(o))return new N.Notice(`"${o.split("/").pop()}" is an archive folder, so cross-folder paste is disabled there. Use the "Move selection to archive" command instead \u2014 it runs the proper archive flow (and encrypts, if that folder encrypts its archive).`),null;let a=[],l=[],c=[],d=[];for(let w of t){let k=await Qt(this.app,e,w);if(k){c.push(k.rootNote.id),a.push({id:k.rootNote.id,file:k.rootNote.file}),d.push(k.rootNote.file);for(let D of k.descendants)l.push({id:D.id,file:D.file}),d.push(D.file)}}if(!a.length)return null;let h=a.length+l.length,p=[],f=[];n==="cut"&&(p=await this.exclusiveAttachmentsOf(d),f=await this.snapshotPaths([...d.map(w=>w.path),...p.map(w=>w.path)]));let u=await vt(this.app,{rootNotes:a,allDescendants:l,sourceFolder:e}),g=await this.idsInFolder(o),I=new Set(this.filesUnder(o)),m=await We(this.app,u,o,g,{dedupeExisting:!1,forceNewIds:n==="copy",reparentRootsTo:s}),C=this.filesUnder(o).filter(w=>!I.has(w)),B=await this.snapshotPaths(C),E=c.map(w=>m.idRemap[w]).filter(w=>!!w);if(n==="cut"){for(let w of d)try{await this.app.fileManager.trashFile(w)}catch(k){console.warn("[Stashpad] cross-folder move: couldn't trash source note",w.path,k)}for(let w of p)try{await this.app.fileManager.trashFile(w)}catch(k){console.warn("[Stashpad] cross-folder move: couldn't trash source attachment",w.path,k)}}let y=async()=>{for(let w of[...C].reverse()){let k=this.app.vault.getAbstractFileByPath(w);if(k)try{await this.app.fileManager.trashFile(k)}catch{}}};return{rootIds:E,noteCount:h,undo:n==="cut"?async()=>{await y(),await this.restoreSnapshot(f)}:async()=>{await y()},redo:n==="cut"?async()=>{await this.restoreSnapshot(B);for(let w of f){let k=this.app.vault.getAbstractFileByPath(w.path);if(k)try{await this.app.fileManager.trashFile(k)}catch{}}}:async()=>{await this.restoreSnapshot(B)}}}async trashSubtrees(e,t){let i=[];for(let o of t){let a=await Qt(this.app,e,o);a&&i.push(a.rootNote.file,...a.descendants.map(l=>l.file))}if(!i.length)return[];let s=await this.exclusiveAttachmentsOf(i),n=[];for(let o of[...i,...s])try{await this.app.fileManager.trashFile(o),n.push(o)}catch(a){console.warn("[Stashpad] trashSubtrees: couldn't trash",o.path,a)}return n}async exclusiveAttachmentsOf(e){let t=new Set(e.map(n=>n.path)),i=new Map;for(let n of e)for(let o of await ii(this.app,n))i.set(o.path,o);let s=this.app.metadataCache.resolvedLinks??{};for(let n of Object.keys(s))if(!t.has(n))for(let o of Object.keys(s[n]??{}))i.delete(o);return[...i.values()]}async subtreeFilePaths(e,t){let i=[];for(let n of t){let o=await Qt(this.app,e,n);o&&i.push(o.rootNote.file,...o.descendants.map(a=>a.file))}if(!i.length)return[];let s=await this.exclusiveAttachmentsOf(i);return[...i.map(n=>n.path),...s.map(n=>n.path)]}async orderedSubtreeNodes(e,t){let i=[],s=new Set,n=o=>{let a=this.app.metadataCache.getFileCache(o)?.frontmatter?.position;return typeof a=="number"?a:Number.MAX_SAFE_INTEGER};for(let o of t){let a=await Qt(this.app,e,o);if(!a)continue;let l=new Map;for(let d of a.descendants){if(!d.parent)continue;let h=l.get(d.parent)??[];h.push({id:d.id,file:d.file,created:d.created}),l.set(d.parent,h)}for(let d of l.values())d.sort((h,p)=>n(h.file)-n(p.file)||h.created.localeCompare(p.created));let c=(d,h)=>{if(!s.has(d.id)){s.add(d.id),i.push({file:d.file,created:d.created,depth:h});for(let p of l.get(d.id)??[])c(p,h+1)}};c({id:a.rootNote.id,file:a.rootNote.file,created:a.rootNote.created},0)}return i}filesUnder(e){let t=e.replace(/\/+$/,"")+"/";return this.app.vault.getFiles().filter(i=>i.path.startsWith(t)).map(i=>i.path)}async snapshotPaths(e){let t=[];for(let i of e){let s=this.app.vault.getAbstractFileByPath(i);if(!s)continue;let n=!i.toLowerCase().endsWith(".md");try{n?t.push({path:i,binary:n,data:await this.app.vault.readBinary(s)}):t.push({path:i,binary:n,text:await this.app.vault.read(s)})}catch(o){console.warn("[Stashpad] snapshotPaths: couldn't read",i,o)}}return t}async restoreSnapshot(e){for(let t of e){let i=t.path.split("/").slice(0,-1).join("/");await this.ensureVaultFolder(i);let s=this.app.vault.getAbstractFileByPath(t.path);try{t.binary?s?await this.app.vault.adapter.writeBinary(t.path,t.data):await this.app.vault.createBinary(t.path,t.data):s?await this.app.vault.modify(s,t.text??""):await this.app.vault.create(t.path,t.text??"")}catch(n){console.warn("[Stashpad] restoreSnapshot: couldn't write",t.path,n)}}}async ensureVaultFolder(e){if(!e)return;let t="";for(let i of e.split("/"))if(t=t?`${t}/${i}`:i,!await this.app.vault.adapter.exists(t))try{await this.app.vault.createFolder(t)}catch{}}refreshOpenViewsForFolder(e){let t=e.replace(/\/+$/,"");for(let i of this.app.workspace.getLeavesOfType($)){let s=i.view;if((s?.noteFolder?.replace(/\/+$/,"")??"")===t)try{s.tree?.rebuild?.(e),s.render?.()}catch(n){console.warn("[Stashpad] refresh view failed",n)}}}maybeArchiveOnMoveIn(e,t){if(e.extension!=="md")return;let i=e.parent?.path?.replace(/\/+$/,"")??"",s=t.lastIndexOf("/"),n=(s>=0?t.slice(0,s):"").replace(/\/+$/,"");if(i===n||!this.isArchiveFolder(i)||!this.encryption.isConfigured())return;let o=this.archivePending.get(i);o||(o={paths:new Set,timer:0},this.archivePending.set(i,o)),o.paths.add(e.path),window.clearTimeout(o.timer),o.timer=window.setTimeout(()=>{this.archivePending.delete(i),this.archiveSweep(i,[...o.paths])},1800)}async encryptExistingArchiveNotes(e){let t=Dt(e.replace(/\/+$/,"")),i=this.archivedPlainNotesIn(t).map(s=>s.path);return i.length===0?0:(await this.archiveSweep(t,i),i.length-this.archivedPlainNotesIn(t).length)}async archiveSweep(e,t){if(this.archiveMigrationInFlight||!this.isArchiveFolder(e))return;let i=e.replace(/\/+$/,"");if(!this.archiveEncryptFor(i))return;let s=[];for(let c of t){let d=this.app.vault.getAbstractFileByPath(c);if(!(d instanceof N.TFile)||(d.parent?.path?.replace(/\/+$/,"")??"")!==i)continue;let h;try{h=ge(await this.app.vault.read(d)).fm}catch{continue}let p=typeof h.id=="string"?h.id:null;!p||p===S||s.push({id:p,parent:typeof h.parent=="string"?h.parent:null})}if(s.length===0)return;let n=new Set(s.map(c=>c.id)),o=new Set((this.settings.lockedSubtrees??[]).map(c=>c.rootId).filter(c=>!!c)),a=s.filter(c=>!o.has(c.id)&&!(c.parent&&n.has(c.parent)));if(a.length===0||!this.encryption.hasFolderKey(i))return;if(!await this.ensureFolderUnlocked(i)){new N.Notice(`\u26A0\uFE0F Archive folder "${i.split("/").pop()}": ${a.length} arriving note${a.length===1?"":"s"} NOT encrypted (couldn't unlock the folder password). Unlock it and lock them manually.`,0);return}let l=0;for(let c of a)await this.lockNoteSubtree(i,c.id,null,{silent:!0})&&l++;l>0&&this.notifications.show({message:`Archived (encrypted) ${l} note${l===1?"":"s"} moved into \u201C${i.split("/").pop()}\u201D.`,kind:"success",category:"system",folder:i,actions:[{label:"All archived",onClick:()=>void He(this,"archived")}]})}async activateViewForFolder(e){let t=(e||"").replace(/^\/+|\/+$/g,"");if(!t)return null;let i=this.app.workspace.getLeaf("tab");return await i.setViewState({type:$,active:!0,state:{folderOverride:t}}),this.app.workspace.revealLeaf(i),i}navigateLeafTo(e,t,i){let s=e?.view;if(s?.navigateTo&&(!s.tree||s.tree.get(i))){s.navigateTo(i);return}this.navigateWhenReady(t,i)}async openFolderInStashpad(e){let t=(e||"").replace(/^\/+|\/+$/g,"");if(!t)return;if(this.settings.foldersAlwaysNewTab){await this.activateViewForFolder(t);return}let i=await this.findStashpadLeafForFolder(t);if(i){this.app.workspace.revealLeaf(i),this.app.workspace.setActiveLeaf(i,{focus:!0});return}await this.activateViewForFolder(t)}async findStashpadLeafForFolder(e){let t=e.replace(/\/+$/,""),i=this.app.workspace.getLeavesOfType($),s=i.find(o=>!o.isDeferred&&(o.view?.noteFolder??"").replace(/\/+$/,"")===t);if(s)return s;let n=i.find(o=>o.isDeferred&&(o.getViewState()?.state?.folderOverride??"").replace(/\/+$/,"")===t);if(n){try{await n.loadIfDeferred?.()}catch{}return n}return null}isStashpadNoteFile(e){let t=e.parent?.path?.replace(/\/+$/,"")??"";if(!this.discoverStashpadFolders().includes(t))return!1;let i=this.app.metadataCache.getFileCache(e)?.frontmatter?.id;return typeof i=="string"&&i.length>0}async revealNoteInStashpad(e){let t=e.parent?.path?.replace(/\/+$/,"")??"",i=this.app.metadataCache.getFileCache(e)?.frontmatter?.id;if(!t||typeof i!="string"||!i){new N.Notice("That note isn't a Stashpad note.");return}await this.revealNoteByRef(t,i)}findStashpadNotesEmbedding(e){let t=e.path,i=this.app.metadataCache.resolvedLinks||{},s=[];for(let n of Object.keys(i)){if(!i[n][t])continue;let o=this.app.vault.getAbstractFileByPath(n);o instanceof N.TFile&&this.isStashpadNoteFile(o)&&s.push(o)}return s}async revealAttachmentInStashpad(e,t){let i=t??this.findStashpadNotesEmbedding(e);if(i.length===0){new N.Notice("No Stashpad note references this attachment.");return}if(i.length===1){await this.revealNoteInStashpad(i[0]);return}new La(this.app,i,s=>void this.revealNoteInStashpad(s)).open()}async revealNoteByRef(e,t){let i=e.replace(/\/+$/,""),s=await this.findStashpadLeafForFolder(i);if(s){this.app.workspace.revealLeaf(s),this.app.workspace.setActiveLeaf(s,{focus:!0}),this.navigateLeafTo(s,i,t);return}let n=await this.activateViewForFolder(i);this.navigateLeafTo(n,i,t)}async openSchedulerForRef(e,t){await this.revealNoteByRef(e,t);let i=e.replace(/\/+$/,""),n=(await this.findStashpadLeafForFolder(i))?.view;n instanceof Ps?n.cmdSetDue(n.tree.get(t)):new N.Notice("Couldn\u2019t open the scheduler for that task.")}resolveNoteFileInFolder(e,t){let i=e.replace(/\/+$/,"");for(let s of this.app.vault.getMarkdownFiles())if((s.parent?.path?.replace(/\/+$/,"")??"")===i&&this.app.metadataCache.getFileCache(s)?.frontmatter?.id===t)return s;return null}async handleDeepLink(e,t={}){let i=(e.folder||"").replace(/^\/+|\/+$/g,""),s=(e.note||"").trim(),n=tl(e),o=c=>(t.silent||new N.Notice(c),!1);if(!i)return o("Stashpad link: missing \u201Cfolder\u201D.");if(!(this.app.vault.getAbstractFileByPath(i)instanceof N.TFolder))return o(`Stashpad link: folder \u201C${i}\u201D not found.`);await new Promise(c=>this.app.workspace.onLayoutReady(()=>c()));let l=null;if(s){for(let c=0;c<12&&!l;c++)l=this.resolveNoteFileInFolder(i,s),l||await new Promise(d=>window.setTimeout(d,150));if(!l)return o(`Stashpad link: note \u201C${s}\u201D not found in ${i}.`)}await this.openDeepLinkTarget(i,s,t);for(let c of n)if(c!=="reveal"){if(c==="open"){l&&await this.app.workspace.getLeaf("tab").openFile(l);continue}console.warn(`[stashpad] deep link: unknown action \u201C${c}\u201D \u2014 skipped.`)}return!0}async openDeepLinkTarget(e,t,i={}){let s=e.replace(/\/+$/,"");if(!i.forceNewTab){let o=this.app.workspace.activeLeaf,a=await this.findStashpadLeafForFolder(s);if(a&&a!==o){this.app.workspace.revealLeaf(a),this.app.workspace.setActiveLeaf(a,{focus:!0}),t&&this.navigateLeafTo(a,s,t);return}}let n=await this.activateViewForFolder(s);t&&this.navigateLeafTo(n,s,t)}openDeepLinkModal(){new us(this.app,e=>{let i=e.split(/\s+/).map(s=>s.trim()).filter(Boolean).map(s=>({raw:s,parsed:el(s)})).filter(s=>!!s.parsed);if(i.length===0){new N.Notice("That doesn't look like a Stashpad link.");return}this.openDeepLinks(i)}).open()}async openDeepLinks(e){let t=this.app.vault.getName(),i=e.length>1,s=0,n=0,o=0;for(let{raw:l,parsed:c}of e){if(c.vault&&c.vault!==t){this.handOffToObsidian(l),n++,await new Promise(h=>window.setTimeout(h,350));continue}if(await this.handleDeepLink(c,{forceNewTab:i,silent:!0})){s++;continue}o++}let a=[];s&&a.push(`opened ${s}`),n&&a.push(`sent ${n} to Obsidian (other vault)`),o&&a.push(`${o} not found`),new N.Notice(`Stashpad link${e.length===1?"":"s"}: ${a.join(" \xB7 ")||"nothing to open"}.`)}handOffToObsidian(e){try{let t=window.require?.("electron")?.shell;if(t?.openExternal){t.openExternal(e);return}}catch{}try{window.open(e)}catch{}}async closeDuplicateStashpadTabs(){let e=this.app.workspace.getLeavesOfType($),t=this.app.workspace.activeLeaf;for(let u of e)try{await u.loadIfDeferred?.()}catch{}let i=u=>u.getViewState()?.state??{},s=u=>{let g=i(u);return(u.isDeferred?g.folderOverride??"":u.view?.noteFolder??g.folderOverride??"").replace(/\/+$/,"")},n=u=>{let g=i(u);return(u.isDeferred?g.focusId:u.view?.focusId??g.focusId)||S},o=u=>{let g=u.view;return!!g&&g.getViewType?.()===$&&typeof g.navigateTo=="function"&&typeof g.noteFolder=="string"},a=new Map;for(let u of this.app.vault.getMarkdownFiles()){let g=(u.parent?.path??"").replace(/\/+$/,""),I=this.app.metadataCache.getFileCache(u)?.frontmatter?.id;typeof I=="string"&&I&&(a.get(g)??a.set(g,new Set).get(g)).add(I)}let l=0,c=[];for(let u of e){let g=s(u),I=n(u);if(g&&I&&I!==S){let m=!u.isDeferred&&!!u.view?.tree?.get?.(I),C=a.get(g)?.has(I)??!1;if(!m&&!C){u.detach(),l++;continue}}c.push(u)}let d=new Map;for(let u of c){let g=s(u);if(!g)continue;let I=g+" "+n(u);(d.get(I)??d.set(I,[]).get(I)).push(u)}let h=0;for(let u of d.values()){if(u.length<=1)continue;u.sort((I,m)=>{let C=B=>B===t?2:B.isDeferred?0:1;return C(m)-C(I)});let g=null;for(let I of u){try{await I.loadIfDeferred?.()}catch{}if(o(I)){g=I;break}}g||(g=u[0]);for(let I of u)I!==g&&(I.detach(),h++)}let p=this.app.workspace.getLeavesOfType($).length,f=document.createDocumentFragment();return f.createEl("div",{text:h+l>0?"Stashpad tabs cleaned up:":"Stashpad tabs - nothing to clean up:"}),f.createEl("div",{text:`\u2022 ${h} duplicate tab${h===1?"":"s"} closed`}),f.createEl("div",{text:`\u2022 ${l} orphaned tab${l===1?"":"s"} pruned (note no longer exists)`}),f.createEl("div",{text:`\u2022 ${p} Stashpad tab${p===1?"":"s"} remaining`}),new N.Notice(f,7e3),h+l}navigateWhenReady(e,t,i=15){let s=e.replace(/\/+$/,""),n=this.app.workspace.getLeavesOfType($).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(t))){n.navigateTo(t);return}i>0?window.setTimeout(()=>this.navigateWhenReady(e,t,i-1),90):n&&typeof n.navigateTo=="function"&&n.navigateTo(t)}collectAuthoredFolders(){let e=(this.settings.authorId??"").trim();if(!e)return[];let t=`-${e}`,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:"",l=Array.isArray(o.contributors)?o.contributors.filter(u=>typeof u=="string"):[],c=a.includes(t),d=l.some(u=>u.includes(t));if(!c&&!d)continue;let h=n.parent?.path??"",p=i.find(u=>h===u||h.startsWith(u+"/"));if(!p)continue;s.has(p)||s.set(p,{authored:0,contributed:0});let f=s.get(p);c&&f.authored++,d&&f.contributed++}return[...s.entries()].map(([n,o])=>({folder:n,...o})).sort((n,o)=>o.authored+o.contributed-(n.authored+n.contributed))}parseAuthorRef(e){return gt(e)}authorRefFor(e,t,i){let s=i.replace(/[^\w\- ]+/g,"").trim().replace(/\s+/g,"-")||"author",n=`${e.replace(/\/+$/,"")}/_authors/${s}-${t}.md`,o=i.replace(/[\[\]|]/g,"").trim()||s;return`[[${n}|${o}]]`}async ensureAuthorStubFor(e,t,i){if(!t||!i)return!1;this.authorRegistry.record({id:t,name:i});let s=`${e.replace(/\/+$/,"")}/_authors`;if(this.app.vault.getMarkdownFiles().some(c=>c.path.startsWith(s+"/")&&this.parseAuthorFilePath(c.path)?.id===t))return!1;let o=this.authorRegistry.get(t),a=this.authorNameToSafe(i),l=`${s}/${a}-${t}.md`;try{return await this.ensureFolderPath(s),await this.app.vault.adapter.exists(l)?!1:(await this.app.vault.create(l,this.buildAuthorStub({id:t,name:i,role:o?.role,department:o?.department},new Date().toISOString())),!0)}catch(c){return console.warn("[Stashpad] ensureAuthorStubFor failed",l,c),!1}}async seedKnownAuthorsInFolder(e){let t=0;for(let i of this.collectKnownAuthors())await this.ensureAuthorStubFor(e,i.id,i.name)&&t++;return t}async autoResolveDueTask(e,t,i){try{await this.app.fileManager.processFrontMatter(e,s=>{let n=s.due!=null?Date.parse(String(s.due)):NaN;if(Number.isFinite(n)&&n>i)return;let o=kn(s.repeat);o?(s.due=new Date(Fn(o,Number.isFinite(n)?n:null,i)).toISOString(),delete s.completed):s.completed=!0})}catch(s){console.warn("[Stashpad] auto-resolve failed",e.path,s)}}async checkDueReminders(){let e=Date.now(),t=new Set(this.settings.notifiedDueKeys??[]),i=(this.settings.authorId??"").trim(),s=[],n={...this.settings.persistReminderLog??{}},o=!1,a=new Set;for(let l of this.app.vault.getMarkdownFiles()){if(l.path.includes("/_authors/"))continue;let c=this.app.metadataCache.getFileCache(l)?.frontmatter;if(!c||c.due==null)continue;let d=typeof c.id=="string"?c.id:"";if(!d)continue;let h=String(c.due),p=typeof c.due=="number"?c.due:Date.parse(h);if(!Number.isFinite(p)||p>e)continue;if(c.completed!==!0){let I=na(c.autoDoneAfter);if(I!=null&&e>=p+I){await this.autoResolveDueTask(l,p,e);continue}}if(c.completed===!0)continue;let f=xt(c);if(f.length>0&&!(i&&f.some(I=>I.id===i)))continue;let u=na(c.remindEvery);if(u!=null){a.add(d);let I=n[d]??0;e-I>=u&&(n[d]=e,o=!0,s.push({id:d,folder:(l.parent?.path??"").replace(/\/+$/,""),file:l,dueMs:p,key:`${d}@persist`}));continue}let g=`${d}@${h}`;t.has(g)||s.push({id:d,folder:(l.parent?.path??"").replace(/\/+$/,""),file:l,dueMs:p,key:g})}for(let l of Object.keys(n))a.has(l)||(delete n[l],o=!0);o&&(this.settings.persistReminderLog=n,await this.saveSettings()),s.length!==0&&(this.settings.notifiedDueKeys=[...this.settings.notifiedDueKeys??[],...s.filter(l=>!l.key.endsWith("@persist")).map(l=>l.key)].slice(-2e3),await this.saveSettings(),await this.showDueToasts(s))}async showDueToasts(e){if(e.length===0)return;let t=async i=>{try{let n=ge(await this.app.vault.cachedRead(i)).body.split(/\r?\n/).map(o=>o.trim()).find(o=>o.length>0);if(n)return n.replace(/^[#>\-*\s]+/,"").slice(0,60)}catch{}return i.basename.replace(/-[a-z0-9]{4,12}$/,"").replace(/-/g," ")};if(e.length<=3)for(let i of e){let s=await t(i.file);this.notifications.show({message:`\u23F0 Task due: \u201C${s}\u201D (${it(i.dueMs,this.settings)})`,kind:"warning",category:"reminder",duration:0,folder:i.folder,affectedIds:[i.id],onBodyClick:()=>void this.openDeepLinkTarget(i.folder,i.id),overlayAction:{label:"Snooze",icon:"alarm-clock-check",title:"Snooze / reschedule\u2026",onClick:()=>void this.openSchedulerForRef(i.folder,i.id)}})}else this.notifications.show({message:`\u23F0 ${e.length} tasks are due \u2014 open the Tasks panel to review.`,kind:"warning",category:"reminder",duration:0,folder:""})}async resendDueReminders(){let e=Date.now(),t=(this.settings.authorId??"").trim(),i=[];for(let s of this.app.vault.getMarkdownFiles()){if(s.path.includes("/_authors/"))continue;let n=this.app.metadataCache.getFileCache(s)?.frontmatter;if(!n||n.due==null)continue;let o=typeof n.id=="string"?n.id:"";if(!o||n.completed===!0)continue;let a=typeof n.due=="number"?n.due:Date.parse(String(n.due));if(!Number.isFinite(a)||a>e)continue;let l=xt(n);l.length>0&&!(t&&l.some(c=>c.id===t))||i.push({id:o,folder:(s.parent?.path??"").replace(/\/+$/,""),file:s,dueMs:a})}if(i.length===0){new N.Notice("No incomplete tasks are due \u2014 your backlog is clear. \u{1F389}");return}await this.showDueToasts(i)}async syncAuthorsAcrossFolders(){await this.rebuildAuthorRegistry();let e=this.collectKnownAuthors(),t=this.discoverStashpadFolders();if(!e.length||!t.length){new N.Notice("No authors or Stashpad folders to sync.");return}let i=t.length*e.length>8?new N.Notice("",0):null,s=0;for(let n of t){i?.setMessage(`Syncing authors \u2192 ${n.split("/").pop()}\u2026`);for(let o of e)await this.ensureAuthorStubFor(n,o.id,o.name)&&s++}i?.hide(),this.notifications.show({message:`Synced authors across ${t.length} folder${t.length===1?"":"s"} \u2014 ${s} new stub${s===1?"":"s"} (${e.length} author${e.length===1?"":"s"} known).`,kind:"success",category:"system",folder:""})}collectKnownAuthors(){let e=new Map,t=(this.settings.authorId??"").trim(),i=(this.settings.authorName??"").trim();t&&i&&e.set(t,i);for(let s of this.authorRegistry.all())e.has(s.id)||e.set(s.id,s.name);for(let s of this.app.vault.getMarkdownFiles()){if(!s.path.includes("/_authors/"))continue;let n=this.parseAuthorFilePath(s.path);if(!n)continue;let o=this.app.metadataCache.getFileCache(s)?.frontmatter,l=((Array.isArray(o?.aliases)?o.aliases.find(c=>typeof c=="string")??"":typeof o?.aliases=="string"?o.aliases:"")||(typeof o?.name=="string"?o.name:"")||n.name).trim();e.has(n.id)||e.set(n.id,l),this.authorRegistry.record({id:n.id,name:l})}return[...e.entries()].map(([s,n])=>({id:s,name:n}))}async rebuildAuthorRegistry(){let e=this.discoverStashpadFolders(),t=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 l of o.contributors)typeof l=="string"&&a.push(l);for(let l of a){let c=this.parseAuthorRef(l);if(c)if(!t.has(c.id))t.set(c.id,{id:c.id,name:c.name,fromStub:!1}),i++;else{let d=t.get(c.id);!d.name&&c.name&&(d.name=c.name)}}}let s=0;for(let n of e){let o=`${n}/_authors`;for(let a of this.app.vault.getMarkdownFiles()){if(!a.path.startsWith(o+"/"))continue;let l=this.parseAuthorFilePath(a.path);if(!l)continue;let c=this.app.metadataCache.getFileCache(a)?.frontmatter,h=((Array.isArray(c?.aliases)?c.aliases.find(g=>typeof g=="string")??"":typeof c?.aliases=="string"?c.aliases:"")||(typeof c?.name=="string"?c.name:"")||l.name).trim(),p=typeof c?.role=="string"?c.role:void 0,f=typeof c?.department=="string"?c.department:void 0,u=t.get(l.id);u||s++,t.set(l.id,{id:l.id,name:h||u?.name,role:p??u?.role,department:f??u?.department,fromStub:!0})}}return await this.authorRegistry.load(),this.authorRegistry.replaceAll([...t.values()]),await this.authorRegistry.save(),{total:t.size,fromStubs:s,fromNotes:i}}buildAuthorStub(e,t){let i=a=>a.replace(/[\r\n]+/g," ").trim(),s=a=>i(a).replace(/\\/g,"\\\\").replace(/"/g,'\\"'),n=i(e.name),o=["---",`authorId: ${e.id}`,"aliases:",` - "${s(e.name)}"`];return e.role&&o.push(`role: "${s(e.role)}"`),e.department&&o.push(`department: "${s(e.department)}"`),o.push(`created: ${t}`,"---",`# ${n}`),o.join(` +`)}async restoreMissingAuthorStubs(){await this.authorRegistry.load();let e=this.authorRegistry.all().filter(n=>n.id&&n.name),t=this.discoverStashpadFolders(),i=this.app.vault.getMarkdownFiles(),s=0;for(let n of t){let o=`${n}/_authors`,a=new Set;for(let l of i){if(!l.path.startsWith(o+"/"))continue;let c=this.parseAuthorFilePath(l.path)?.id;c&&a.add(c)}for(let l of e){if(a.has(l.id))continue;let c=this.authorNameToSafe(l.name),d=`${o}/${c}-${l.id}.md`;try{if(await this.ensureFolderPath(o),await this.app.vault.adapter.exists(d))continue;await this.app.vault.create(d,this.buildAuthorStub(l,l.firstSeen??new Date().toISOString())),s++}catch(h){console.warn("[Stashpad] restore author stub failed",d,h)}}}return{created:s,folders:t.length}}async convertAttachmentsToLinks(){let e=0,t=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+"/")||Jt(n.path))continue;let a=this.app.metadataCache.getFileCache(n)?.frontmatter;if(!a||typeof a.id!="string"||!a.id)continue;let l=a.attachments,c=Array.isArray(l),d=typeof l=="string"&&l.trim().length>0;if(!(!c&&!d||!(d?!t(l):l.some(p=>typeof p=="string"&&p.trim()&&!t(p)))))try{await this.app.fileManager.processFrontMatter(n,p=>{Array.isArray(p.attachments)?p.attachments=p.attachments.map(f=>typeof f=="string"&&f.trim()?tt(f):f):typeof p.attachments=="string"&&p.attachments.trim()&&(p.attachments=[tt(p.attachments)])}),e++}catch(p){console.warn("[Stashpad] attachment-link conversion failed",n.path,p)}}}return e}syncObsidianExcludedArchives(){try{let e=this.app.vault;if(typeof e.getConfig!="function"||typeof e.setConfig!="function")return;let t=Array.isArray(e.getConfig("userIgnoreFilters"))?e.getConfig("userIgnoreFilters"):[],i=new Set(t),s=!1;for(let n of this.discoverStashpadFolders()){let o=`${n.replace(/\/+$/,"")}/_archive/`;i.has(o)||(i.add(o),s=!0)}s&&e.setConfig("userIgnoreFilters",[...i])}catch(e){console.warn("[Stashpad] couldn't update Obsidian excluded files",e)}}openImportPicker(){let e=this.discoverStashpadFolders();if(e.length===0){new N.Notice("No Stashpad folders to import into.");return}if(e.length===1){this.importService.pickFilesInto(e[0]);return}let t=this.importService.defaultDestination()??e[0];new Ga(this.app,t,e,i=>this.importService.pickFilesInto(i)).open()}async runImportLooseFiles(e){let t=e.split("/").pop()||e,i=0,s=0,n=0;try{({files:i,folders:s,stashes:n}=await this.importService.importLooseInto(e))}catch(c){this.notifications.show({message:`Stashpad: import failed in \`${t}\` Error: ${c.message}`,kind:"error",category:"import",folder:e}),console.error("[Stashpad] runImportLooseFiles failed",e,c);return}let o=i+s+n,a=this.lastActiveStashpadLeaf?.view;o>0&&a?.noteFolder===e&&a?.tree&&(a.tree.rebuild(e),a.render?.());let l;if(o===0)l=`Nothing to import in \`${t}\` \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"}`),l=`Imported ${c.join(" + ")} in \`${t}\`.`}this.notifications.show({message:l,kind:o>0?"success":"info",category:"import",folder:e})}refreshViewIfShowing(e){let t=this.lastActiveStashpadLeaf?.view;t?.noteFolder===e&&t?.tree&&(t.tree.rebuild(e),t.render?.())}async runFolderSlugPass(e){let t=e.split("/").pop()||e,i=0;try{i=await this.rebootstrapFolderSlugs(e)}catch(s){this.notifications.show({message:`Stashpad: slug pass failed in \`${t}\` -${s.message}`,kind:"error",category:"system",folder:e}),console.error("[Stashpad] runFolderSlugPass failed",e,s);return}this.refreshViewIfShowing(e),this.notifications.show({message:i>0?`Renamed ${i} stale filename${i===1?"":"s"} in \`${t}\`.`:`No stale filenames in \`${t}\` \u2014 all slugs match their notes.`,kind:i>0?"success":"info",category:"system",folder:e})}async runFolderFrontmatterBackfill(e){let t=e.split("/").pop()||e,i=0,s=0;try{let n=await Pi(this.app,e);i=n.written,s=n.checked}catch(n){this.notifications.show({message:`Stashpad: frontmatter backfill failed in \`${t}\` -${n.message}`,kind:"error",category:"system",folder:e}),console.error("[Stashpad] runFolderFrontmatterBackfill failed",e,n);return}this.notifications.show({message:i>0?`Backfilled recovery links on ${i} note${i===1?"":"s"} in \`${t}\` (${s} checked).`:`Recovery links already up to date in \`${t}\` (${s} checked).`,kind:i>0?"success":"info",category:"system",folder:e})}async runAutoImportSweep(){if(!this.settings.autoImport||!this.importService.isArmed()||this.autoSweepInProgress)return;this.autoSweepInProgress=!0;let e=0,t=0,i=0;try{for(let n of this.discoverStashpadFolders())try{let o=await this.importService.importLooseInto(n,{auto:!0});e+=o.files,t+=o.folders,i+=o.stashes}catch(o){console.warn("[Stashpad] auto-import sweep failed",n,o)}}finally{this.autoSweepInProgress=!1}if(e+t+i>0){let n=this.lastActiveStashpadLeaf?.view;n?.tree&&n?.noteFolder&&(n.tree.rebuild(n.noteFolder),n.render?.());let o=[];e&&o.push(`${e} file${e===1?"":"s"}`),t&&o.push(`${t} folder${t===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 e=this.importService.pendingEncryptedPaths();if(e.length===0||!this.importService.shouldNotifyEncrypted())return;this.importService.snoozeEncryptedNotify(60*60*1e3);let t=e.length;this.notifications.show({message:`${t} encrypted .stash bundle${t===1?"":"s"} waiting to import. Import ${t===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:e,rescheduled:t}=await this.importService.importPendingEncrypted();if(e>0){let i=this.lastActiveStashpadLeaf?.view;i?.tree&&i?.noteFolder&&(i.tree.rebuild(i.noteFolder),i.render?.()),this.notifications.show({message:`Imported ${e} encrypted .stash bundle${e===1?"":"s"}.`,kind:"success",category:"import"})}}async seedLocalAuthorStub(e){let t=(this.settings.authorId??"").trim(),i=(this.settings.authorName??"").trim();if(!t||!i)return!1;let s=`${e.replace(/\/+$/,"")}/_authors`;if(this.app.vault.getMarkdownFiles().some(l=>l.path.startsWith(s+"/")&&this.parseAuthorFilePath(l.path)?.id===t))return!1;let o=this.authorNameToSafe(i),a=`${s}/${o}-${t}.md`;try{return await this.ensureFolderPath(s),await this.app.vault.adapter.exists(a)?!1:(await this.app.vault.create(a,this.buildAuthorStub({id:t,name:i,role:this.settings.authorRole,department:this.settings.authorDepartment},new Date().toISOString())),this.authorRegistry.record({id:t,name:i,role:this.settings.authorRole,department:this.settings.authorDepartment}),!0)}catch(l){return console.warn("[Stashpad] seedLocalAuthorStub failed",a,l),!1}}async seedLocalAuthorStubsEverywhere(){if(!(this.settings.authorName??"").trim())return 0;let t=0;for(let i of this.discoverStashpadFolders())await this.seedLocalAuthorStub(i)&&t++;return t}async ensureFolderPath(e){let t=this.app.vault.adapter,i=e.split("/").filter(Boolean),s="";for(let n of i){s=s?`${s}/${n}`:n;try{await t.exists(s)||await t.mkdir(s)}catch(o){if(!/already exists/i.test(o.message))throw o}}}async loadSettings(){let e=await this.loadData()??{};this.lastSeenSettingsRev=typeof e?.settingsRev=="number"?e.settingsRev:0,typeof e?.confirmMultiDelete=="boolean"&&(typeof e.confirmBulkDelete!="boolean"&&(e.confirmBulkDelete=e.confirmMultiDelete),typeof e.confirmAttachmentDelete!="boolean"&&(e.confirmAttachmentDelete=e.confirmMultiDelete),delete e.confirmMultiDelete),typeof e?.jdIndexDestFolder=="string"&&typeof e?.jdIndexStashpadFolder!="string"&&(e.jdIndexStashpadFolder=e.jdIndexDestFolder),e?.shortcuts&&e.shortcuts.openEditor==="E"&&(e.shortcuts.openEditor="Mod+Shift+E"),e?.bindings?.openEditor&&e.bindings.openEditor.primary==="E"&&(e.bindings.openEditor.primary="Mod+Shift+E"),this.settings={...Mt,...e,shortcuts:{...Mt.shortcuts,...e?.shortcuts??{}},mod:{...Mt.mod,...e?.mod??{}},bindings:rA(e?.bindings,e?.shortcuts,e?.mod),customPalette:Array.isArray(e?.customPalette)?e.customPalette.filter(t=>typeof t=="string"&&/^#[0-9a-f]{6}$/i.test(t)):[],colorAliases:e?.colorAliases&&typeof e.colorAliases=="object"?e.colorAliases:{},noteTemplates:e?.noteTemplates&&typeof e.noteTemplates=="object"?e.noteTemplates:{},authorName:typeof e?.authorName=="string"?e.authorName:"",authorId:typeof e?.authorId=="string"?e.authorId:"",authorRole:typeof e?.authorRole=="string"?e.authorRole:"",authorDepartment:typeof e?.authorDepartment=="string"?e.authorDepartment:"",showAuthor:typeof e?.showAuthor=="boolean"?e.showAuthor:!0,showContributors:typeof e?.showContributors=="boolean"?e.showContributors:!0,showLastEdit:typeof e?.showLastEdit=="boolean"?e.showLastEdit:!0,viewModes:e?.viewModes&&typeof e.viewModes=="object"&&!Array.isArray(e.viewModes)?e.viewModes:{},includeAttachmentsInEverything:e?.includeAttachmentsInEverything&&typeof e.includeAttachmentsInEverything=="object"&&!Array.isArray(e.includeAttachmentsInEverything)?e.includeAttachmentsInEverything:{},hideChildlessNotes:e?.hideChildlessNotes&&typeof e.hideChildlessNotes=="object"&&!Array.isArray(e.hideChildlessNotes)?e.hideChildlessNotes:{},hideCompletedNotes:e?.hideCompletedNotes&&typeof e.hideCompletedNotes=="object"&&!Array.isArray(e.hideCompletedNotes)?e.hideCompletedNotes:{},mutedNotificationCategories:Array.isArray(e?.mutedNotificationCategories)?e.mutedNotificationCategories.filter(t=>typeof t=="string"):[],notificationHistoryLimit:typeof e?.notificationHistoryLimit=="number"&&Number.isFinite(e.notificationHistoryLimit)?e.notificationHistoryLimit:5e3,notifiedDueKeys:Array.isArray(e?.notifiedDueKeys)?e.notifiedDueKeys.filter(t=>typeof t=="string").slice(-2e3):[],drafts:lA(e?.drafts),lastSubmitted:e?.lastSubmitted&&typeof e.lastSubmitted=="object"?e.lastSubmitted:{},slugStopWords:Array.isArray(e?.slugStopWords)?e.slugStopWords:[...st],migratedToggleTaskG:e?.migratedToggleTaskG===!0,dueQuickAdjusts:Array.isArray(e?.dueQuickAdjusts)?e.dueQuickAdjusts.filter(t=>typeof t=="string"):["5m","15m","30m","1h","1d","1w"]},cs(this.settings),this.snapshotSettingsBaseline(),this.settings.migratedToggleTaskG||(this.settings.bindings.toggleTask?.primary==="H"&&(this.settings.bindings.toggleTask.primary="G"),this.settings.migratedToggleTaskG=!0,await this.saveSettings()),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 e=this.app.vault.adapter,t=this.notificationsPath();try{if(await e.exists(t)){let i=await e.read(t),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 e=this.notifications.recent().slice().reverse(),t=this.notificationsPath(),i=t.replace(/\/[^/]+$/,""),s=this.app.vault.adapter;i&&!await s.exists(i)&&await s.mkdir(i),await s.write(t,JSON.stringify(e))}catch(e){console.warn("[Stashpad] failed to save notification history",e)}}readLastCursorFile(){try{let e=window.localStorage.getItem(this.LAST_CURSOR_LS_KEY);if(!e)return{};let t=JSON.parse(e);return t&&typeof t=="object"?t:{}}catch{return{}}}loadLastCursor(e){let i=this.readLastCursorFile()[e]??{};return new Map(Object.entries(i))}saveLastCursor(e,t,i){try{let s=this.readLastCursorFile();s[e]||(s[e]={}),s[e][t]=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 e=window.localStorage.getItem(this.LAST_SELECTION_LS_KEY);if(!e)return{};let t=JSON.parse(e);return t&&typeof t=="object"?t:{}}catch{return{}}}loadLastSelection(e){let i=this.readLastSelectionFile()[e]??{},s=new Map;for(let[n,o]of Object.entries(i))Array.isArray(o)&&s.set(n,o.filter(a=>typeof a=="string"));return s}saveLastSelection(e,t,i){try{let s=this.readLastSelectionFile();s[e]||(s[e]={}),i.length?s[e][t]=i:delete s[e][t],window.localStorage.setItem(this.LAST_SELECTION_LS_KEY,JSON.stringify(s))}catch(s){console.warn("[Stashpad] failed to save last-selection",s)}}readActiveVersionsFile(){try{let e=window.localStorage.getItem(this.ACTIVE_VERSIONS_LS_KEY);if(!e)return{};let t=JSON.parse(e);return t&&typeof t=="object"?t:{}}catch{return{}}}loadActiveVersions(e){let t=this.readActiveVersionsFile();return new Map(Object.entries(t[e]??{}))}saveActiveVersion(e,t,i){try{let s=this.readActiveVersionsFile();s[e]||(s[e]={}),s[e][t]=i,window.localStorage.setItem(this.ACTIVE_VERSIONS_LS_KEY,JSON.stringify(s))}catch(s){console.warn("[Stashpad] failed to save active-version",s)}}async flushForkSiblingPrune(){let e=new Set(this.pendingForkDeletes);if(this.pendingForkDeletes.clear(),!!e.size)for(let t of this.app.vault.getMarkdownFiles()){let i=this.app.metadataCache.getFileCache(t)?.frontmatter?.[je];if(Array.isArray(i)&&i.some(s=>e.has(Gs(s)??"")))try{await this.app.fileManager.processFrontMatter(t,s=>{let o=(Array.isArray(s[je])?s[je]:[]).filter(a=>!e.has(Gs(a)??""));o.length?s[je]=o:delete s[je]})}catch{}}}queueWrite(){let e=this.writeChain.then(()=>this.guardedSave());return this.writeChain=e.catch(()=>{}),e}scheduleExternalDataJsonReload(){this.externalReloadDebounced()}async onExternalDataJsonChange(){let e=null;try{e=await this.loadData()}catch{return}if(!e)return;let t=typeof e.settingsRev=="number"?e.settingsRev:0;if(t<=this.lastSeenSettingsRev)return;let i=this.settings,s=!1,n=!1;for(let o of Ft.COLLISION_PROTECTED_KEYS)e[o]!==void 0&&JSON.stringify(e[o])!==JSON.stringify(i[o])&&(i[o]=e[o],n=!0,o.startsWith("folderPanel")&&(s=!0));this.lastSeenSettingsRev=t,n&&(cs(this.settings),this.snapshotSettingsBaseline(),s&&this.refreshFolderPanels())}snapshotSettingsBaseline(){for(let e of Ft.COLLISION_PROTECTED_KEYS)this.settingsBaseline[e]=JSON.stringify(this.settings[e])}async guardedSave(){let e=null;try{e=await this.loadData()}catch{}let t=typeof e?.settingsRev=="number"?e.settingsRev:0;if(e){let s=[];for(let n of Ft.COLLISION_PROTECTED_KEYS){let o=JSON.stringify(this.settings[n])!==this.settingsBaseline[n],a=JSON.stringify(e[n])!==this.settingsBaseline[n];!o&&a&&e[n]!==void 0&&(this.settings[n]=e[n],s.push(n))}s.length&&(console.warn(`[Stashpad] settings collision: on-disk protected keys differ from our baseline (disk rev ${t}, we knew ${this.lastSeenSettingsRev}); adopted: ${s.join(", ")}.`),new N.Notice(`Stashpad: another Obsidian instance (or a synced machine) changed this vault's settings. Merged instead of overwriting (${s.join(", ")}). If encryption behaves oddly, restart Obsidian.`,1e4),cs(this.settings),s.some(n=>n.startsWith("folderPanel"))&&this.refreshFolderPanels()),t>this.lastSeenSettingsRev&&(this.lastSeenSettingsRev=t)}let i=Math.max(t,this.lastSeenSettingsRev)+1;this.settings.settingsRev=i,await this.saveData(this.settings),this.lastSeenSettingsRev=i,this.snapshotSettingsBaseline()}async saveSettings(){await this.queueWrite(),cs(this.settings),Te.enabled=!!this.settings.enablePerfProfiling;let e=(this.settings.authorId??"").trim();e&&this.authorRegistry.record({id:e,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 e=new Set(this.discoverStashpadFolders());if(e.size===0){new N.Notice("No Stashpad folders found.");return}let t=new Set,i=this.app.vault.getMarkdownFiles();for(let h of i){let p=this.app.metadataCache.getFileCache(h)?.frontmatter,f=typeof p?.id=="string"?p.id.trim():"";f&&t.add(f)}let{newId:s}=await Promise.resolve().then(()=>(pt(),Co)),n=()=>{for(let h=0;h<100;h++){let p=s();if(!t.has(p))return t.add(p),p}for(let h=8;h<=16;h+=2){let p=s(h);if(!t.has(p))return t.add(p),p}throw new Error("Could not generate a unique id")},o=[];for(let h of i){let p=h.parent?.path?.replace(/\/+$/,"")??"";if(!e.has(p))continue;let f=this.app.metadataCache.getFileCache(h)?.frontmatter,u=typeof f?.id=="string"?f.id.trim():"",g=f?.parent,I=typeof g=="string"?g.trim()!=="":g!=null,m=typeof f?.created=="string"&&f.created.trim()!=="",C=!u,B=!I,E=!m;!C&&!B&&!E||o.push({file:h,addId:C,addParent:B,addCreated:E})}if(o.length===0){new N.Notice("Nothing to fix \u2014 every note in a Stashpad folder already has id + parent + created.");return}let a=0,l=0,c=this.newLog();for(let h of o)try{let p;await this.app.fileManager.processFrontMatter(h.file,g=>{if(h.addId&&(typeof g.id=="string"&&g.id.trim()||(p=n(),g.id=p)),h.addParent){let I=g.parent;(typeof I=="string"?I.trim()!=="":I!=null)||(g.parent=S)}h.addCreated&&(typeof g.created=="string"&&g.created.trim()||(g.created=new Date(h.file.stat.ctime).toISOString()))});let f=this.app.metadataCache.getFileCache(h.file)?.frontmatter,u=p??f?.id??"";u&&await c.append({type:"parent_change",id:u,payload:{from:null,to:S,reason:"orphan_fix",path:h.file.path,addedId:h.addId,addedParent:h.addParent,addedCreated:h.addCreated}}),a++}catch(p){console.warn("Stashpad: orphan fix failed for",h.file.path,p),l++}let A=l?` (${l} failed \u2014 see console)`:"";new N.Notice(`Fixed ${a} note${a===1?"":"s"} in Stashpad folders${A}.`)}async adoptNote(e){let{newId:t}=await Promise.resolve().then(()=>(pt(),Co)),i=new Set;for(let c of this.app.vault.getMarkdownFiles()){if(c.path===e.path)continue;let A=this.app.metadataCache.getFileCache(c)?.frontmatter,h=typeof A?.id=="string"?A.id.trim():"";h&&i.add(h)}let s=()=>{for(let c=0;c<50;c++){let A=t();if(!i.has(A))return A}for(let c=8;c<=16;c+=2){let A=t(c);if(!i.has(A))return A}throw new Error("Could not generate a unique id")},n=[],o=[];try{await this.app.fileManager.processFrontMatter(e,c=>{let A=typeof c.id=="string"?c.id.trim():"";!A||/\s/.test(A)||i.has(A)?(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=S,n.push("parent")),typeof c.created=="string"&&c.created.trim()!==""?o.push("created"):(c.created=new Date(e.stat.ctime).toISOString(),n.push("created"))})}catch(c){new N.Notice(`Adopt failed: ${c.message}`);return}let a=!1;try{let c=this.app.metadataCache.getFileCache(e)?.frontmatter,A=typeof c?.id=="string"?c.id.trim():"";if(A&&e.basename&&!e.basename.endsWith(`-${A}`)){let h=`${e.parent?e.parent.path+"/":""}${e.basename}-${A}.md`;await this.app.vault.adapter.exists(h)||(await this.app.fileManager.renameFile(e,h),a=!0)}}catch(c){console.warn("Stashpad: adopt rename failed",c)}if(n.length===0&&!a){new N.Notice(`Already a Stashpad note (${o.join(", ")} present).`);return}let l=[];n.length&&l.push(`added: ${n.join(", ")}`),a&&l.push("renamed with id"),new N.Notice(`Adopted into Stashpad \u2014 ${l.join("; ")}.`);try{let c=this.newLog(),A=this.app.metadataCache.getFileCache(e)?.frontmatter,h=A?.id??"";h&&await c.append({type:"create",id:h,payload:{path:e.path,parent:A?.parent??S,source:"adopt",added:n}})}catch{}}};Ft.DEBUG_BUFFER_MAX=300,Ft.COLLISION_PROTECTED_KEYS=["encryption","lockedSubtrees","folderEncPrefs","archiveFolders","folderPanelPinned","folderPanelDownranked","folderPanelHidden","folderPanelPinnedGrouping"];var ho=Ft;function rA(d,r,e){let t=Xo();for(let i of Zt){let s=r&&typeof r[i.id]=="string"?r[i.id]:e&&typeof e[i.id]=="string"?e[i.id]:null;s!=null&&s!==""&&(t[i.id].primary=s)}if(d&&typeof d=="object")for(let i of Zt){let s=d[i.id];!s||typeof s!="object"||(t[i.id]={primary:typeof s.primary=="string"?s.primary:t[i.id].primary,secondary:typeof s.secondary=="string"?s.secondary:"",preferRight:!!s.preferRight,useBoth:!!s.useBoth})}for(let i of Zt){if(!i.defaultSecondary&&!i.defaultUseBoth)continue;let s=t[i.id];s.primary===i.defaultPrimary&&!s.secondary&&!s.useBoth&&(s.secondary=i.defaultSecondary??"",s.useBoth=!!i.defaultUseBoth)}return t}function lA(d){let r={};if(!d||typeof d!="object")return r;for(let[e,t]of Object.entries(d))if(typeof t=="string")r[e]=t;else if(t&&typeof t=="object"){for(let i of Object.values(t))if(typeof i=="string"&&i.length>0){r[e]=i;break}}return r}var Ra=class extends N.SuggestModal{constructor(e,t,i,s){super(e);this.def=t;this.folders=i;this.onPick=s;this.setPlaceholder("Choose a Stashpad folder to import into\u2026")}getSuggestions(e){let t=e.toLowerCase();return[this.def,...this.folders.filter(s=>s!==this.def)].filter(s=>s.toLowerCase().includes(t)).map(s=>({label:s,folder:s,current:s===this.def}))}renderSuggestion(e,t){t.createDiv({text:e.label}),e.current&&(t.createDiv({cls:"stashpad-suggest-note",text:"current"}),t.addClass("is-pinned-import-target"))}onChooseSuggestion(e){this.onPick(e.folder)}},Ua=class extends N.SuggestModal{constructor(e,t,i){super(e);this.bundles=t;this.onPick=i;this.setPlaceholder("Choose an encrypted folder bundle to decrypt\u2026")}getSuggestions(e){let t=e.toLowerCase();return this.bundles.filter(i=>i.folder.toLowerCase().includes(t))}renderSuggestion(e,t){t.createDiv({text:e.folder||"(vault root)"}),t.createDiv({cls:"stashpad-suggest-note",text:e.blobPath})}onChooseSuggestion(e){this.onPick(e)}}; +${s.message}`,kind:"error",category:"system",folder:e}),console.error("[Stashpad] runFolderSlugPass failed",e,s);return}this.refreshViewIfShowing(e),this.notifications.show({message:i>0?`Renamed ${i} stale filename${i===1?"":"s"} in \`${t}\`.`:`No stale filenames in \`${t}\` \u2014 all slugs match their notes.`,kind:i>0?"success":"info",category:"system",folder:e})}async runFolderFrontmatterBackfill(e){let t=e.split("/").pop()||e,i=0,s=0;try{let n=await Hi(this.app,e);i=n.written,s=n.checked}catch(n){this.notifications.show({message:`Stashpad: frontmatter backfill failed in \`${t}\` +${n.message}`,kind:"error",category:"system",folder:e}),console.error("[Stashpad] runFolderFrontmatterBackfill failed",e,n);return}this.notifications.show({message:i>0?`Backfilled recovery links on ${i} note${i===1?"":"s"} in \`${t}\` (${s} checked).`:`Recovery links already up to date in \`${t}\` (${s} checked).`,kind:i>0?"success":"info",category:"system",folder:e})}async runAutoImportSweep(){if(!this.settings.autoImport||!this.importService.isArmed()||this.autoSweepInProgress)return;this.autoSweepInProgress=!0;let e=0,t=0,i=0;try{for(let n of this.discoverStashpadFolders())try{let o=await this.importService.importLooseInto(n,{auto:!0});e+=o.files,t+=o.folders,i+=o.stashes}catch(o){console.warn("[Stashpad] auto-import sweep failed",n,o)}}finally{this.autoSweepInProgress=!1}if(e+t+i>0){let n=this.lastActiveStashpadLeaf?.view;n?.tree&&n?.noteFolder&&(n.tree.rebuild(n.noteFolder),n.render?.());let o=[];e&&o.push(`${e} file${e===1?"":"s"}`),t&&o.push(`${t} folder${t===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 e=this.importService.pendingEncryptedPaths();if(e.length===0||!this.importService.shouldNotifyEncrypted())return;this.importService.snoozeEncryptedNotify(60*60*1e3);let t=e.length;this.notifications.show({message:`${t} encrypted .stash bundle${t===1?"":"s"} waiting to import. Import ${t===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:e,rescheduled:t}=await this.importService.importPendingEncrypted();if(e>0){let i=this.lastActiveStashpadLeaf?.view;i?.tree&&i?.noteFolder&&(i.tree.rebuild(i.noteFolder),i.render?.()),this.notifications.show({message:`Imported ${e} encrypted .stash bundle${e===1?"":"s"}.`,kind:"success",category:"import"})}}async seedLocalAuthorStub(e){let t=(this.settings.authorId??"").trim(),i=(this.settings.authorName??"").trim();if(!t||!i)return!1;let s=`${e.replace(/\/+$/,"")}/_authors`;if(this.app.vault.getMarkdownFiles().some(l=>l.path.startsWith(s+"/")&&this.parseAuthorFilePath(l.path)?.id===t))return!1;let o=this.authorNameToSafe(i),a=`${s}/${o}-${t}.md`;try{return await this.ensureFolderPath(s),await this.app.vault.adapter.exists(a)?!1:(await this.app.vault.create(a,this.buildAuthorStub({id:t,name:i,role:this.settings.authorRole,department:this.settings.authorDepartment},new Date().toISOString())),this.authorRegistry.record({id:t,name:i,role:this.settings.authorRole,department:this.settings.authorDepartment}),!0)}catch(l){return console.warn("[Stashpad] seedLocalAuthorStub failed",a,l),!1}}async seedLocalAuthorStubsEverywhere(){if(!(this.settings.authorName??"").trim())return 0;let t=0;for(let i of this.discoverStashpadFolders())await this.seedLocalAuthorStub(i)&&t++;return t}async ensureFolderPath(e){let t=this.app.vault.adapter,i=e.split("/").filter(Boolean),s="";for(let n of i){s=s?`${s}/${n}`:n;try{await t.exists(s)||await t.mkdir(s)}catch(o){if(!/already exists/i.test(o.message))throw o}}}async loadSettings(){let e=await this.store.loadAll()??{};this.lastSeenSettingsRev=typeof e?.settingsRev=="number"?e.settingsRev:0,typeof e?.confirmMultiDelete=="boolean"&&(typeof e.confirmBulkDelete!="boolean"&&(e.confirmBulkDelete=e.confirmMultiDelete),typeof e.confirmAttachmentDelete!="boolean"&&(e.confirmAttachmentDelete=e.confirmMultiDelete),delete e.confirmMultiDelete),typeof e?.jdIndexDestFolder=="string"&&typeof e?.jdIndexStashpadFolder!="string"&&(e.jdIndexStashpadFolder=e.jdIndexDestFolder),e?.shortcuts&&e.shortcuts.openEditor==="E"&&(e.shortcuts.openEditor="Mod+Shift+E"),e?.bindings?.openEditor&&e.bindings.openEditor.primary==="E"&&(e.bindings.openEditor.primary="Mod+Shift+E"),this.settings={...Mt,...e,shortcuts:{...Mt.shortcuts,...e?.shortcuts??{}},mod:{...Mt.mod,...e?.mod??{}},bindings:gA(e?.bindings,e?.shortcuts,e?.mod),customPalette:Array.isArray(e?.customPalette)?e.customPalette.filter(t=>typeof t=="string"&&/^#[0-9a-f]{6}$/i.test(t)):[],colorAliases:e?.colorAliases&&typeof e.colorAliases=="object"?e.colorAliases:{},noteTemplates:e?.noteTemplates&&typeof e.noteTemplates=="object"?e.noteTemplates:{},authorName:typeof e?.authorName=="string"?e.authorName:"",authorId:typeof e?.authorId=="string"?e.authorId:"",authorRole:typeof e?.authorRole=="string"?e.authorRole:"",authorDepartment:typeof e?.authorDepartment=="string"?e.authorDepartment:"",showAuthor:typeof e?.showAuthor=="boolean"?e.showAuthor:!0,showContributors:typeof e?.showContributors=="boolean"?e.showContributors:!0,showLastEdit:typeof e?.showLastEdit=="boolean"?e.showLastEdit:!0,viewModes:e?.viewModes&&typeof e.viewModes=="object"&&!Array.isArray(e.viewModes)?e.viewModes:{},includeAttachmentsInEverything:e?.includeAttachmentsInEverything&&typeof e.includeAttachmentsInEverything=="object"&&!Array.isArray(e.includeAttachmentsInEverything)?e.includeAttachmentsInEverything:{},hideChildlessNotes:e?.hideChildlessNotes&&typeof e.hideChildlessNotes=="object"&&!Array.isArray(e.hideChildlessNotes)?e.hideChildlessNotes:{},hideCompletedNotes:e?.hideCompletedNotes&&typeof e.hideCompletedNotes=="object"&&!Array.isArray(e.hideCompletedNotes)?e.hideCompletedNotes:{},mutedNotificationCategories:Array.isArray(e?.mutedNotificationCategories)?e.mutedNotificationCategories.filter(t=>typeof t=="string"):[],notificationHistoryLimit:typeof e?.notificationHistoryLimit=="number"&&Number.isFinite(e.notificationHistoryLimit)?e.notificationHistoryLimit:5e3,notifiedDueKeys:Array.isArray(e?.notifiedDueKeys)?e.notifiedDueKeys.filter(t=>typeof t=="string").slice(-2e3):[],drafts:uA(e?.drafts),lastSubmitted:e?.lastSubmitted&&typeof e.lastSubmitted=="object"?e.lastSubmitted:{},slugStopWords:Array.isArray(e?.slugStopWords)?e.slugStopWords:[...st],migratedToggleTaskG:e?.migratedToggleTaskG===!0,dueQuickAdjusts:Array.isArray(e?.dueQuickAdjusts)?e.dueQuickAdjusts.filter(t=>typeof t=="string"):["5m","15m","30m","1h","1d","1w"]},As(this.settings),this.snapshotSettingsBaseline(),this.settings.migratedToggleTaskG||(this.settings.bindings.toggleTask?.primary==="H"&&(this.settings.bindings.toggleTask.primary="G"),this.settings.migratedToggleTaskG=!0,await this.saveSettings()),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 e=this.app.vault.adapter,t=this.notificationsPath();try{if(await e.exists(t)){let i=await e.read(t),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 e=this.notifications.recent().slice().reverse(),t=this.notificationsPath(),i=t.replace(/\/[^/]+$/,""),s=this.app.vault.adapter;i&&!await s.exists(i)&&await s.mkdir(i),await s.write(t,JSON.stringify(e))}catch(e){console.warn("[Stashpad] failed to save notification history",e)}}readLastCursorFile(){try{let e=window.localStorage.getItem(this.LAST_CURSOR_LS_KEY);if(!e)return{};let t=JSON.parse(e);return t&&typeof t=="object"?t:{}}catch{return{}}}loadLastCursor(e){let i=this.readLastCursorFile()[e]??{};return new Map(Object.entries(i))}saveLastCursor(e,t,i){try{let s=this.readLastCursorFile();s[e]||(s[e]={}),s[e][t]=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 e=window.localStorage.getItem(this.LAST_SELECTION_LS_KEY);if(!e)return{};let t=JSON.parse(e);return t&&typeof t=="object"?t:{}}catch{return{}}}loadLastSelection(e){let i=this.readLastSelectionFile()[e]??{},s=new Map;for(let[n,o]of Object.entries(i))Array.isArray(o)&&s.set(n,o.filter(a=>typeof a=="string"));return s}saveLastSelection(e,t,i){try{let s=this.readLastSelectionFile();s[e]||(s[e]={}),i.length?s[e][t]=i:delete s[e][t],window.localStorage.setItem(this.LAST_SELECTION_LS_KEY,JSON.stringify(s))}catch(s){console.warn("[Stashpad] failed to save last-selection",s)}}readActiveVersionsFile(){try{let e=window.localStorage.getItem(this.ACTIVE_VERSIONS_LS_KEY);if(!e)return{};let t=JSON.parse(e);return t&&typeof t=="object"?t:{}}catch{return{}}}loadActiveVersions(e){let t=this.readActiveVersionsFile();return new Map(Object.entries(t[e]??{}))}saveActiveVersion(e,t,i){try{let s=this.readActiveVersionsFile();s[e]||(s[e]={}),s[e][t]=i,window.localStorage.setItem(this.ACTIVE_VERSIONS_LS_KEY,JSON.stringify(s))}catch(s){console.warn("[Stashpad] failed to save active-version",s)}}async flushForkSiblingPrune(){let e=new Set(this.pendingForkDeletes);if(this.pendingForkDeletes.clear(),!!e.size)for(let t of this.app.vault.getMarkdownFiles()){let i=this.app.metadataCache.getFileCache(t)?.frontmatter?.[je];if(Array.isArray(i)&&i.some(s=>e.has(Ks(s)??"")))try{await this.app.fileManager.processFrontMatter(t,s=>{let o=(Array.isArray(s[je])?s[je]:[]).filter(a=>!e.has(Ks(a)??""));o.length?s[je]=o:delete s[je]})}catch{}}}queueWrite(){let e=this.writeChain.then(()=>this.guardedSave());return this.writeChain=e.catch(()=>{}),e}scheduleExternalDataJsonReload(){this.externalReloadDebounced()}async onExternalDataJsonChange(){let e=this.settings,t=!1,i=!1;try{(await this.store.adoptExternal(e)).any&&(i=!0)}catch{}let s=null;try{s=await this.loadData()}catch{s=null}let n=typeof s?.settingsRev=="number"?s.settingsRev:0;if(s&&n>this.lastSeenSettingsRev){for(let o of kt.COLLISION_PROTECTED_KEYS)s[o]!==void 0&&JSON.stringify(s[o])!==JSON.stringify(e[o])&&(e[o]=s[o],i=!0,o.startsWith("folderPanel")&&(t=!0));this.lastSeenSettingsRev=n}i&&(As(this.settings),this.snapshotSettingsBaseline(),t&&this.refreshFolderPanels())}snapshotSettingsBaseline(){for(let e of kt.COLLISION_PROTECTED_KEYS)this.settingsBaseline[e]=JSON.stringify(this.settings[e])}async guardedSave(){let e=null,t=!1;try{e=await this.loadData()}catch{}let i=typeof e?.settingsRev=="number"?e.settingsRev:0;if(e){let l=[];for(let c of kt.COLLISION_PROTECTED_KEYS){let d=JSON.stringify(this.settings[c])!==this.settingsBaseline[c],h=JSON.stringify(e[c])!==this.settingsBaseline[c];!d&&h&&e[c]!==void 0&&(this.settings[c]=e[c],l.push(c))}l.length&&(t=!0,console.warn(`[Stashpad] settings collision: on-disk protected keys differ from our baseline (disk rev ${i}, we knew ${this.lastSeenSettingsRev}); adopted: ${l.join(", ")}.`),new N.Notice(`Stashpad: another Obsidian instance (or a synced machine) changed this vault's settings. Merged instead of overwriting (${l.join(", ")}). If encryption behaves oddly, restart Obsidian.`,1e4),As(this.settings),l.some(c=>c.startsWith("folderPanel"))&&this.refreshFolderPanels()),i>this.lastSeenSettingsRev&&(this.lastSeenSettingsRev=i)}let s=this.settings,n=this.store.coreDirty(s)||t,o=Math.max(i,this.lastSeenSettingsRev)+1;n&&(this.settings.settingsRev=o);let a=this.settings;try{await this.store.saveSplit(a)}catch(l){console.warn("[Stashpad] history.json write failed \u2014 continuing with data.json.",l)}if(n){let l={},c=new Set(ai);for(let[d,h]of Object.entries(a))c.has(d)||(l[d]=h);await this.saveData(l),this.lastSeenSettingsRev=o,this.store.markCoreSaved(a)}this.snapshotSettingsBaseline()}async saveSettings(){await this.queueWrite(),As(this.settings),Te.enabled=!!this.settings.enablePerfProfiling;let e=(this.settings.authorId??"").trim();e&&this.authorRegistry.record({id:e,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 e=new Set(this.discoverStashpadFolders());if(e.size===0){new N.Notice("No Stashpad folders found.");return}let t=new Set,i=this.app.vault.getMarkdownFiles();for(let h of i){let p=this.app.metadataCache.getFileCache(h)?.frontmatter,f=typeof p?.id=="string"?p.id.trim():"";f&&t.add(f)}let{newId:s}=await Promise.resolve().then(()=>(pt(),wo)),n=()=>{for(let h=0;h<100;h++){let p=s();if(!t.has(p))return t.add(p),p}for(let h=8;h<=16;h+=2){let p=s(h);if(!t.has(p))return t.add(p),p}throw new Error("Could not generate a unique id")},o=[];for(let h of i){let p=h.parent?.path?.replace(/\/+$/,"")??"";if(!e.has(p))continue;let f=this.app.metadataCache.getFileCache(h)?.frontmatter,u=typeof f?.id=="string"?f.id.trim():"",g=f?.parent,I=typeof g=="string"?g.trim()!=="":g!=null,m=typeof f?.created=="string"&&f.created.trim()!=="",C=!u,B=!I,E=!m;!C&&!B&&!E||o.push({file:h,addId:C,addParent:B,addCreated:E})}if(o.length===0){new N.Notice("Nothing to fix \u2014 every note in a Stashpad folder already has id + parent + created.");return}let a=0,l=0,c=this.newLog();for(let h of o)try{let p;await this.app.fileManager.processFrontMatter(h.file,g=>{if(h.addId&&(typeof g.id=="string"&&g.id.trim()||(p=n(),g.id=p)),h.addParent){let I=g.parent;(typeof I=="string"?I.trim()!=="":I!=null)||(g.parent=S)}h.addCreated&&(typeof g.created=="string"&&g.created.trim()||(g.created=new Date(h.file.stat.ctime).toISOString()))});let f=this.app.metadataCache.getFileCache(h.file)?.frontmatter,u=p??f?.id??"";u&&await c.append({type:"parent_change",id:u,payload:{from:null,to:S,reason:"orphan_fix",path:h.file.path,addedId:h.addId,addedParent:h.addParent,addedCreated:h.addCreated}}),a++}catch(p){console.warn("Stashpad: orphan fix failed for",h.file.path,p),l++}let d=l?` (${l} failed \u2014 see console)`:"";new N.Notice(`Fixed ${a} note${a===1?"":"s"} in Stashpad folders${d}.`)}async adoptNote(e){let{newId:t}=await Promise.resolve().then(()=>(pt(),wo)),i=new Set;for(let c of this.app.vault.getMarkdownFiles()){if(c.path===e.path)continue;let d=this.app.metadataCache.getFileCache(c)?.frontmatter,h=typeof d?.id=="string"?d.id.trim():"";h&&i.add(h)}let s=()=>{for(let c=0;c<50;c++){let d=t();if(!i.has(d))return d}for(let c=8;c<=16;c+=2){let d=t(c);if(!i.has(d))return d}throw new Error("Could not generate a unique id")},n=[],o=[];try{await this.app.fileManager.processFrontMatter(e,c=>{let d=typeof c.id=="string"?c.id.trim():"";!d||/\s/.test(d)||i.has(d)?(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=S,n.push("parent")),typeof c.created=="string"&&c.created.trim()!==""?o.push("created"):(c.created=new Date(e.stat.ctime).toISOString(),n.push("created"))})}catch(c){new N.Notice(`Adopt failed: ${c.message}`);return}let a=!1;try{let c=this.app.metadataCache.getFileCache(e)?.frontmatter,d=typeof c?.id=="string"?c.id.trim():"";if(d&&e.basename&&!e.basename.endsWith(`-${d}`)){let h=`${e.parent?e.parent.path+"/":""}${e.basename}-${d}.md`;await this.app.vault.adapter.exists(h)||(await this.app.fileManager.renameFile(e,h),a=!0)}}catch(c){console.warn("Stashpad: adopt rename failed",c)}if(n.length===0&&!a){new N.Notice(`Already a Stashpad note (${o.join(", ")} present).`);return}let l=[];n.length&&l.push(`added: ${n.join(", ")}`),a&&l.push("renamed with id"),new N.Notice(`Adopted into Stashpad \u2014 ${l.join("; ")}.`);try{let c=this.newLog(),d=this.app.metadataCache.getFileCache(e)?.frontmatter,h=d?.id??"";h&&await c.append({type:"create",id:h,payload:{path:e.path,parent:d?.parent??S,source:"adopt",added:n}})}catch{}}};kt.DEBUG_BUFFER_MAX=300,kt.COLLISION_PROTECTED_KEYS=["encryption","lockedSubtrees","folderEncPrefs","archiveFolders","folderPanelPinned","folderPanelDownranked","folderPanelHidden","folderPanelPinnedGrouping"];var uo=kt;function gA(A,r,e){let t=_o();for(let i of Zt){let s=r&&typeof r[i.id]=="string"?r[i.id]:e&&typeof e[i.id]=="string"?e[i.id]:null;s!=null&&s!==""&&(t[i.id].primary=s)}if(A&&typeof A=="object")for(let i of Zt){let s=A[i.id];!s||typeof s!="object"||(t[i.id]={primary:typeof s.primary=="string"?s.primary:t[i.id].primary,secondary:typeof s.secondary=="string"?s.secondary:"",preferRight:!!s.preferRight,useBoth:!!s.useBoth})}for(let i of Zt){if(!i.defaultSecondary&&!i.defaultUseBoth)continue;let s=t[i.id];s.primary===i.defaultPrimary&&!s.secondary&&!s.useBoth&&(s.secondary=i.defaultSecondary??"",s.useBoth=!!i.defaultUseBoth)}return t}function uA(A){let r={};if(!A||typeof A!="object")return r;for(let[e,t]of Object.entries(A))if(typeof t=="string")r[e]=t;else if(t&&typeof t=="object"){for(let i of Object.values(t))if(typeof i=="string"&&i.length>0){r[e]=i;break}}return r}var Ga=class extends N.SuggestModal{constructor(e,t,i,s){super(e);this.def=t;this.folders=i;this.onPick=s;this.setPlaceholder("Choose a Stashpad folder to import into\u2026")}getSuggestions(e){let t=e.toLowerCase();return[this.def,...this.folders.filter(s=>s!==this.def)].filter(s=>s.toLowerCase().includes(t)).map(s=>({label:s,folder:s,current:s===this.def}))}renderSuggestion(e,t){t.createDiv({text:e.label}),e.current&&(t.createDiv({cls:"stashpad-suggest-note",text:"current"}),t.addClass("is-pinned-import-target"))}onChooseSuggestion(e){this.onPick(e.folder)}},Oa=class extends N.SuggestModal{constructor(e,t,i){super(e);this.bundles=t;this.onPick=i;this.setPlaceholder("Choose an encrypted folder bundle to decrypt\u2026")}getSuggestions(e){let t=e.toLowerCase();return this.bundles.filter(i=>i.folder.toLowerCase().includes(t))}renderSuggestion(e,t){t.createDiv({text:e.folder||"(vault root)"}),t.createDiv({cls:"stashpad-suggest-note",text:e.blobPath})}onChooseSuggestion(e){this.onPick(e)}}; /*! Bundled license information: hash-wasm/dist/index.esm.js: diff --git a/manifest.json b/manifest.json index 2cce2f2..3bdb6df 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "stashpad", "name": "Stashpad", - "version": "0.188.1", + "version": "0.191.0", "minAppVersion": "1.13.0", "description": "A chat-style, nested-notes workspace: rapid capture, outliner navigation, fast search, tasks, and per-folder templates, with one-click Open Knowledge Format (OKF) export for LLMs and agents.", "author": "Human", diff --git a/package.json b/package.json index 1bd64f3..8c0533d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "stashpad-obsidian", - "version": "0.188.1", + "version": "0.191.0", "private": true, "scripts": { "dev": "node esbuild.config.mjs", diff --git a/release-notes/0.191.0.md b/release-notes/0.191.0.md new file mode 100644 index 0000000..c8ed151 --- /dev/null +++ b/release-notes/0.191.0.md @@ -0,0 +1,48 @@ +# 0.191.0 + +Covers everything since 0.188.1 (0.189.0, 0.189.1, 0.190.0, 0.191.0). + +## Moving notes (0.191.0) + +- **Nesting a note into another opens that parent in a background tab.** When you + move a note into another note — by drag-and-drop or the in-list "Nest under…" + picker — its new home opens in a background Stashpad tab, so it's one click away + without pulling you out of what you were doing. Focus never leaves your current + tab. + + It skips itself when there's nothing useful to open: a move to Home, or a parent + that's already open in a tab (so repeated nesting into the same parent doesn't pile + up duplicates). Also skipped when "Navigate into parent after moving a note IN" is + on, since that already takes you there. + + New Behavior setting — **"Open the new parent in a background tab after moving a + note IN"** — on by default. + +## Smoother behaviour during a sync (0.190.0) + +- **The list no longer thrashes while a sync lands.** Stashpad re-rendered once per + file change, so a sync bringing in hundreds of files made the list flicker and + appear to render, stop, and render again. It now detects a burst of machine-driven + changes and settles once things go quiet, instead of re-rendering many times a + second. Ordinary editing is unchanged and just as responsive. +- **No more repeated "a newer build synced in" nudges.** That notice now waits for the + incoming version to settle, so a sync rewriting `manifest.json` mid-flight can't + spam it. + +## Settings storage (0.189.0, 0.189.1) + +- **Per-device churn moved out of `data.json`.** Reminder bookkeeping and unsent + composer drafts now live in a separate `history.json` beside it. Previously every + settings write rewrote one big file, so dismissing a reminder rewrote your hotkeys + and vice versa; the two are now independent. + + Everything that needs to travel between your devices — preferences, hotkeys, folder + pins, encryption state — deliberately **stays** in `data.json`, which is the file + Obsidian Sync syncs. + + Your existing settings migrate automatically on first launch, and a one-time backup + is written to `data.json.pre-split.bak` first. Nothing is lost. + + One behaviour change worth knowing: reminder "already notified" state is now + per-device, so a reminder shown on your desktop no longer silences the same + reminder on your phone. Unsent composer drafts are likewise per-device now. diff --git a/src/main.ts b/src/main.ts index 1188d17..a68b412 100644 --- a/src/main.ts +++ b/src/main.ts @@ -39,6 +39,7 @@ import { ImportService } from "./import-service"; import { ImportLog } from "./import-log"; import { perf } from "./perf"; import { RenderCacheStore } from "./render-cache-store"; +import { SettingsStore, MOVED_KEYS } from "./settings-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. */ @@ -1847,6 +1848,7 @@ export default class StashpadPlugin extends Plugin { { 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: "openParentTabOnMoveIn", label: "Open new parent in a background tab 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" }, @@ -2148,9 +2150,11 @@ export default class StashpadPlugin extends Plugin { // to our own data.json, then re-read + adopt the collision-protected keys and // refresh the folder panel. Our own writes are skipped via the settingsRev // guard in onExternalDataJsonChange. - const dataJsonPath = `${(this.manifest as any).dir.replace(/\/+$/, "")}/data.json`; + // 0.189.0: watch every file the settings store owns, not just data.json — the + // split files need the same "another window wrote this" adoption path. + const ownedPaths = new Set(this.store.watchPaths()); this.registerEvent((this.app.vault as any).on("raw", (changedPath: string) => { - if (changedPath === dataJsonPath) this.scheduleExternalDataJsonReload(); + if (ownedPaths.has(changedPath)) this.scheduleExternalDataJsonReload(); })); // 0.79.1: auto-import — any file appearing directly in a Stashpad @@ -2202,6 +2206,9 @@ export default class StashpadPlugin extends Plugin { * 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; + /** On-disk version seen on the PREVIOUS check — must match the current one before + * we announce it, so a mid-sync manifest churn doesn't spam the notice. */ + private pendingBuildVersion: string | null = null; private async checkForSyncedBuild(): Promise<void> { try { const dir = (this.manifest as any).dir as string | undefined; @@ -2219,6 +2226,15 @@ export default class StashpadPlugin extends Plugin { // focus forever. Silently ignore older/equal on-disk versions. if (!this.isSemverGreater(onDisk, loaded)) return; if (this.notifiedBuildVersion === onDisk) return; + // 0.190.0: require the on-disk version to hold STILL across two consecutive + // checks before nudging. Mid-sync, manifest.json can land, get rewritten, or + // flip versions repeatedly — announcing each transient state is what spammed + // the notice during a big sync. Waiting one interval means we only ever + // announce a build that actually settled. + if (this.pendingBuildVersion !== onDisk) { + this.pendingBuildVersion = onDisk; + return; + } this.notifiedBuildVersion = onDisk; this.notifications.show({ message: `A newer Stashpad build synced in (\`${loaded}\` → \`${onDisk}\`). Reload the app to apply it.`, @@ -6411,7 +6427,12 @@ export default class StashpadPlugin extends Plugin { } async loadSettings(): Promise<void> { - const data = (await this.loadData()) ?? {}; + // 0.189.0: merges data.json + history.json into the historic settings shape and + // performs the one-time split migration (backing data.json up first). Callers + // downstream see exactly the object they always did. + // eslint-disable-next-line @typescript-eslint/no-explicit-any -- same loose shape + // loadData() returned; the legacy-key migrations below index it dynamically. + const data = (((await this.store.loadAll()) ?? {}) as any); // 0.137.3: collision guard — remember the on-disk write generation we // loaded from, so a save can detect that another instance wrote since. this.lastSeenSettingsRev = typeof data?.settingsRev === "number" ? data.settingsRev : 0; @@ -6736,6 +6757,10 @@ export default class StashpadPlugin extends Plugin { private static readonly COLLISION_PROTECTED_KEYS = ["encryption", "lockedSubtrees", "folderEncPrefs", "archiveFolders", "folderPanelPinned", "folderPanelDownranked", "folderPanelHidden", "folderPanelPinnedGrouping"] as const; private lastSeenSettingsRev = 0; private settingsBaseline: Record<string, string | undefined> = {}; + /** 0.189.0: persistence layer. data.json keeps everything that must sync; the + * per-device reminder/draft churn lives in history.json so a reminder firing no + * longer rewrites the whole settings blob. See docs/data-split-plan.md. */ + private store = new SettingsStore(this); private externalReloadDebounced = debounce(() => void this.onExternalDataJsonChange(), 600, false); /** Coalesce a burst of `raw` data.json events (a sync often writes in chunks). */ @@ -6747,21 +6772,33 @@ export default class StashpadPlugin extends Plugin { * folder panel so synced pins/hides show without a reload. Skips our own writes * via the settingsRev guard (our writes never raise diskRev above lastSeen). */ private async onExternalDataJsonChange(): Promise<void> { - let disk: Record<string, unknown> | null = null; - try { disk = (await this.loadData()) as Record<string, unknown> | null; } catch { return; } - if (!disk) return; - const diskRev = typeof disk.settingsRev === "number" ? (disk.settingsRev as number) : 0; - if (diskRev <= this.lastSeenSettingsRev) return; // our own write (or nothing newer) const s = this.settings as unknown as Record<string, unknown>; let panelChanged = false, anyChanged = false; - for (const k of StashpadPlugin.COLLISION_PROTECTED_KEYS) { - if (disk[k] === undefined) continue; - if (JSON.stringify(disk[k]) === JSON.stringify(s[k])) continue; - s[k] = disk[k]; - anyChanged = true; - if (k.startsWith("folderPanel")) panelChanged = true; + + // 0.189.0: adopt the SPLIT files first. They carry their own per-file revs, so a + // history.json write from another window must be picked up even when data.json + // is untouched — the old early-return on data.json's rev would have skipped it. + try { + const rep = await this.store.adoptExternal(s); + if (rep.any) anyChanged = true; + } catch { /* non-fatal: split files are device-local churn */ } + + let disk: Record<string, unknown> | null = null; + try { disk = (await this.loadData()) as Record<string, unknown> | null; } catch { disk = null; } + const diskRev = typeof disk?.settingsRev === "number" ? (disk.settingsRev as number) : 0; + // Only walk data.json's protected keys when it actually moved on disk; our own + // writes never raise diskRev above lastSeen. + if (disk && diskRev > this.lastSeenSettingsRev) { + for (const k of StashpadPlugin.COLLISION_PROTECTED_KEYS) { + if (disk[k] === undefined) continue; + if (JSON.stringify(disk[k]) === JSON.stringify(s[k])) continue; + s[k] = disk[k]; + anyChanged = true; + if (k.startsWith("folderPanel")) panelChanged = true; + } + this.lastSeenSettingsRev = diskRev; } - this.lastSeenSettingsRev = diskRev; + if (anyChanged) { setSettings(this.settings); this.snapshotSettingsBaseline(); @@ -6777,6 +6814,9 @@ export default class StashpadPlugin extends Plugin { private async guardedSave(): Promise<void> { let disk: Record<string, unknown> | null = null; + /** Set when the collision guard adopted a disk value — forces the data.json + * write even if none of OUR core keys changed, so the merged result lands. */ + let adoptedAny = false; try { disk = (await this.loadData()) as Record<string, unknown> | null; } catch { /* first write / unreadable */ } const diskRev = typeof disk?.settingsRev === "number" ? (disk.settingsRev as number) : 0; // 0.140.2: adopt on CONTENT change, not just a higher rev. Two instances @@ -6796,6 +6836,7 @@ export default class StashpadPlugin extends Plugin { } } if (adopted.length) { + adoptedAny = true; console.warn(`[Stashpad] settings collision: on-disk protected keys differ from our baseline (disk rev ${diskRev}, we knew ${this.lastSeenSettingsRev}); adopted: ${adopted.join(", ")}.`); new Notice(`Stashpad: another Obsidian instance (or a synced machine) changed this vault's settings. Merged instead of overwriting (${adopted.join(", ")}). If encryption behaves oddly, restart Obsidian.`, 10000); setSettings(this.settings); @@ -6804,10 +6845,31 @@ export default class StashpadPlugin extends Plugin { } if (diskRev > this.lastSeenSettingsRev) this.lastSeenSettingsRev = diskRev; } + const all0 = this.settings as unknown as Record<string, unknown>; + // Skip the data.json write entirely when only per-device churn changed — that's + // the other half of the split: a reminder firing must not rewrite your hotkeys. + const coreDirty = this.store.coreDirty(all0) || adoptedAny; const rev = Math.max(diskRev, this.lastSeenSettingsRev) + 1; - (this.settings as unknown as Record<string, unknown>).settingsRev = rev; - await this.saveData(this.settings); - this.lastSeenSettingsRev = rev; + if (coreDirty) (this.settings as unknown as Record<string, unknown>).settingsRev = rev; + // 0.189.0: the per-device churn keys go to history.json (written only when they + // actually changed), and data.json is written WITHOUT them. The guarded-merge + // logic above still governs data.json's collision-protected keys. + const all = this.settings as unknown as Record<string, unknown>; + // Isolated: history.json is per-device churn, so a failure there must never + // block the (more important) data.json write that follows. + try { + await this.store.saveSplit(all); + } catch (e) { + console.warn("[Stashpad] history.json write failed — continuing with data.json.", e); + } + if (coreDirty) { + const core: Record<string, unknown> = {}; + const moved = new Set<string>(MOVED_KEYS); + for (const [k, v] of Object.entries(all)) if (!moved.has(k)) core[k] = v; + await this.saveData(core); + this.lastSeenSettingsRev = rev; + this.store.markCoreSaved(all); + } this.snapshotSettingsBaseline(); } diff --git a/src/settings-store.ts b/src/settings-store.ts new file mode 100644 index 0000000..1fe0eca --- /dev/null +++ b/src/settings-store.ts @@ -0,0 +1,271 @@ +import type { Plugin } from "obsidian"; + +/** 0.189.0 — persistence layer for plugin settings, split across several files. + * + * Everything used to live in one `data.json`: 94 keys, ~15 KB, rewritten in full by + * all 85 `saveSettings()` call sites. Ticking a task rewrote your hotkeys, and one + * stale write from a synced device could clobber every domain at once. + * + * This store keeps the IN-MEMORY settings object exactly as it was — callers still + * read `plugin.settings.x` and call `saveSettings()` — and changes only where each + * key lands on disk: + * + * data.json everything that must sync across devices (core prefs, hotkeys, + * folder-panel pins, encryption state). Obsidian-native, written + * via saveData, and still guarded by COLLISION_PROTECTED_KEYS. + * history.json per-device reminder/draft churn. Device-local by design. + * + * Two properties matter: + * 1. A save only rewrites files whose contents ACTUALLY changed (the churn win) — + * so ticking a task no longer rewrites your hotkeys, and a reminder firing no + * longer rewrites your whole settings blob. + * 2. Each file is guarded independently against a concurrent writer (a second + * Obsidian window on the same vault): before writing we re-read the file, and + * for any key WE didn't change but disk did, we adopt disk's value instead of + * clobbering it — the same rule as COLLISION_PROTECTED_KEYS, per file. */ + +/** Keys moved OUT of data.json. Anything not listed here stays in data.json. + * + * SCOPE IS DELIBERATELY NARROW: Obsidian Sync only syncs `<pluginDir>/data.json` + * (learned the hard way in 0.113.0 — a relocated copy meant keybindings and pinned + * folders stopped propagating between devices). So anything that must sync — + * hotkeys, folder-panel pins, encryption prefs, core toggles — STAYS in data.json. + * Only per-device, machine-written churn moves out; that state is arguably wrong to + * sync anyway (one device's "already notified you about this reminder" shouldn't + * silence another's). */ +export const SPLIT_FILES: Record<string, readonly string[]> = { + "history.json": ["notifiedDueKeys", "persistReminderLog", "lastSubmitted", "drafts"], +}; + +/** Flat list of every key that no longer belongs in data.json. */ +export const MOVED_KEYS: readonly string[] = Object.values(SPLIT_FILES).flat(); + +/** Filename of the one-time pre-split backup. Never overwritten once created. */ +export const BACKUP_FILE = "data.json.pre-split.bak"; + +type Bag = Record<string, unknown>; + +/** Reported back to the caller so it can notify / refresh UI for adopted domains. */ +export interface AdoptionReport { + /** file → keys whose on-disk value we adopted instead of overwriting. */ + adopted: Record<string, string[]>; + /** True when anything at all was adopted. */ + any: boolean; +} + +export class SettingsStore { + /** key → JSON of the value as we last read/wrote it. The arbiter for "did WE + * change this, or did disk?" — same idea as the old settingsBaseline. */ + private baseline: Record<string, string | undefined> = {}; + /** file → last known rev (monotonic, bumped on each write of that file). */ + private revs = new Map<string, number>(); + + constructor(private plugin: Plugin) {} + + private dir(): string { + // manifest.dir is `.obsidian/plugins/stashpad` (or the user's configDir equivalent). + return this.plugin.manifest.dir ?? ""; + } + + private pathFor(file: string): string { + return `${this.dir()}/${file}`; + } + + /** Every file this store owns, data.json included. */ + fileNames(): string[] { + return ["data.json", ...Object.keys(SPLIT_FILES)]; + } + + /** Absolute-ish vault paths for all owned files — used by the external-change watcher. */ + watchPaths(): string[] { + return this.fileNames().map((f) => this.pathFor(f)); + } + + private async readSplit(file: string): Promise<Bag | null> { + try { + const p = this.pathFor(file); + const adapter = this.plugin.app.vault.adapter; + if (!(await adapter.exists(p))) return null; + const raw = await adapter.read(p); + const parsed: unknown = JSON.parse(raw); + return parsed && typeof parsed === "object" ? (parsed as Bag) : null; + } catch { + // Unreadable/corrupt → treat as absent. The caller falls back to whatever is + // already in memory (data.json copy or defaults) and NEVER to empty. + return null; + } + } + + private async writeSplit(file: string, payload: Bag, rev: number): Promise<void> { + const body = JSON.stringify({ ...payload, rev }, null, 2); + await this.plugin.app.vault.adapter.write(this.pathFor(file), body); + } + + private static pick(src: Bag, keys: readonly string[]): Bag { + const out: Bag = {}; + for (const k of keys) if (src[k] !== undefined) out[k] = src[k]; + return out; + } + + private snapshotKeys(src: Bag, keys: readonly string[]): void { + for (const k of keys) this.baseline[k] = JSON.stringify(src[k]); + } + + /** Read every file and merge into ONE object with the historic settings shape. + * Split files win over data.json (data.json's copies are stale leftovers from + * before migration); a missing split file falls back to data.json's copy, so a + * deleted/unreadable file never reads as "user cleared these settings". */ + async loadAll(): Promise<Bag> { + const base = ((await this.plugin.loadData()) as Bag | null) ?? {}; + const merged: Bag = { ...base }; + + for (const [file, keys] of Object.entries(SPLIT_FILES)) { + const disk = await this.readSplit(file); + if (disk) { + for (const k of keys) if (disk[k] !== undefined) merged[k] = disk[k]; + this.revs.set(file, typeof disk.rev === "number" ? disk.rev : 0); + } else { + this.revs.set(file, 0); + } + } + + // One-time migration: data.json still carrying moved keys means this is a + // pre-split install (or a partial migration that was interrupted). + const leftovers = MOVED_KEYS.filter((k) => base[k] !== undefined); + if (leftovers.length) await this.migrate(base, merged); + + this.snapshotKeys(merged, Object.keys(merged)); + this.revs.set("data.json", typeof merged.settingsRev === "number" ? (merged.settingsRev as number) : 0); + return merged; + } + + /** Move the split keys out of data.json, after taking a full one-time backup. + * Idempotent: once data.json no longer carries the keys this never runs again. */ + private async migrate(base: Bag, merged: Bag): Promise<void> { + const adapter = this.plugin.app.vault.adapter; + try { + // 1. Full backup FIRST — nothing destructive happens before this lands. + const backupPath = this.pathFor(BACKUP_FILE); + if (!(await adapter.exists(backupPath))) { + await adapter.write(backupPath, JSON.stringify(base, null, 2)); + } + + // 2. Write each split file from the merged view. + for (const [file, keys] of Object.entries(SPLIT_FILES)) { + const payload = SettingsStore.pick(merged, keys); + // Don't create an empty file for a domain this vault never used. + if (Object.keys(payload).length === 0) continue; + await this.writeSplit(file, payload, (this.revs.get(file) ?? 0) + 1); + this.revs.set(file, (this.revs.get(file) ?? 0) + 1); + } + + // 3. Strip the moved keys from data.json and rewrite it. + const stripped: Bag = {}; + const moved = new Set(MOVED_KEYS); + for (const [k, v] of Object.entries(base)) if (!moved.has(k)) stripped[k] = v; + await this.plugin.saveData(stripped); + console.info(`[Stashpad] settings split: moved ${MOVED_KEYS.length} keys out of data.json (backup: ${BACKUP_FILE}).`); + } catch (e) { + // A failed migration is survivable: data.json still holds everything, and the + // merged in-memory view is correct, so the app runs normally and we retry next load. + console.error("[Stashpad] settings split migration failed — continuing on data.json.", e); + } + } + + /** Write the SPLIT files (data.json stays the caller's job — it still runs through + * the collision-protected guardedSave in main.ts). Files whose contents didn't + * change are skipped entirely; concurrent edits we'd otherwise clobber are adopted. */ + async saveSplit(settings: Bag): Promise<AdoptionReport> { + const report: AdoptionReport = { adopted: {}, any: false }; + + for (const [file, keys] of Object.entries(SPLIT_FILES)) { + const changed = keys.some((k) => JSON.stringify(settings[k]) !== this.baseline[k]); + const disk = await this.readSplit(file); + + // Collision guard: adopt any key WE didn't touch but disk did. + if (disk) { + const adopted: string[] = []; + for (const k of keys) { + const ours = JSON.stringify(settings[k]); + const theirs = JSON.stringify(disk[k]); + const oursChanged = ours !== this.baseline[k]; + const diskChanged = theirs !== this.baseline[k]; + if (!oursChanged && diskChanged && disk[k] !== undefined) { + settings[k] = disk[k]; + adopted.push(k); + } + } + if (adopted.length) { + report.adopted[file] = adopted; + report.any = true; + } + const diskRev = typeof disk.rev === "number" ? disk.rev : 0; + if (diskRev > (this.revs.get(file) ?? 0)) this.revs.set(file, diskRev); + } + + // Nothing of ours to persist for this domain → don't touch the file at all. + if (!changed && !report.adopted[file]) continue; + + const payload = SettingsStore.pick(settings, keys); + if (Object.keys(payload).length === 0) continue; // never write an empty domain over a populated one + const rev = (this.revs.get(file) ?? 0) + 1; + await this.writeSplit(file, payload, rev); + this.revs.set(file, rev); + this.snapshotKeys(settings, keys); + } + + return report; + } + + /** Did any key that still lives in data.json change since we last read/wrote it? + * Lets the caller skip the data.json write entirely when only per-device churn + * moved — so a reminder firing no longer rewrites your hotkeys. `settingsRev` is + * excluded because it's bookkeeping we bump *because* of a write, not a reason + * to write. */ + coreDirty(settings: Bag): boolean { + const moved = new Set(MOVED_KEYS); + for (const k of Object.keys(settings)) { + if (moved.has(k) || k === "settingsRev") continue; + if (JSON.stringify(settings[k]) !== this.baseline[k]) return true; + } + return false; + } + + /** Re-baseline the data.json-owned keys after the caller writes them. */ + markCoreSaved(settings: Bag): void { + const moved = new Set(MOVED_KEYS); + this.snapshotKeys(settings, Object.keys(settings).filter((k) => !moved.has(k))); + } + + /** An outside writer (other window / synced device) touched one of our files: + * re-read it and adopt any key that differs from our baseline and that we didn't + * change ourselves. Returns which keys changed so the caller can refresh UI. */ + async adoptExternal(settings: Bag): Promise<AdoptionReport> { + const report: AdoptionReport = { adopted: {}, any: false }; + for (const [file, keys] of Object.entries(SPLIT_FILES)) { + const disk = await this.readSplit(file); + if (!disk) continue; + const diskRev = typeof disk.rev === "number" ? disk.rev : 0; + if (diskRev <= (this.revs.get(file) ?? 0)) continue; // our own write, or nothing newer + const adopted: string[] = []; + for (const k of keys) { + if (disk[k] === undefined) continue; + if (JSON.stringify(disk[k]) === JSON.stringify(settings[k])) continue; + settings[k] = disk[k]; + adopted.push(k); + } + this.revs.set(file, diskRev); + if (adopted.length) { + this.snapshotKeys(settings, keys); + report.adopted[file] = adopted; + report.any = true; + } + } + return report; + } + + /** Re-baseline everything (after an external adoption or a forced reload). */ + rebaseline(settings: Bag): void { + this.snapshotKeys(settings, Object.keys(settings)); + } +} diff --git a/src/settings.ts b/src/settings.ts index d5d87b7..7fde165 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -519,6 +519,12 @@ export interface StashpadSettings { * new parent; on, the view also drills into that parent so the user * lands inside it. */ autoNavOnMoveIn: boolean; + /** 0.191.0: after moving/nesting a note INTO another note, open that destination + * parent in a BACKGROUND Stashpad tab — so the note's new home is one click away + * without yanking you out of what you were doing. Distinct from autoNavOnMoveIn, + * which drills the CURRENT view into the parent (and steals your place). On by + * default; skipped when the destination is Home/root or already open in a tab. */ + openParentTabOnMoveIn: boolean; /** 0.73.14: when on, the row under the keyboard cursor temporarily * un-clamps its body — showing the full content as the user * arrow-keys through the list. Moving the cursor away re-collapses @@ -690,6 +696,7 @@ export const DEFAULT_SETTINGS: StashpadSettings = { notificationHistoryLimit: 5000, notifiedDueKeys: [], autoNavOnMoveIn: false, + openParentTabOnMoveIn: true, autoNavOnMoveOut: false, autoExpandCursorRow: false, expandBodiesByDefault: false, @@ -1531,6 +1538,8 @@ export class StashpadSettingTab extends PluginSettingTab { cats.movingNotes.push(toggle("Navigate into parent after moving a note IN", "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.", () => this.plugin.settings.autoNavOnMoveIn, (v) => { this.plugin.settings.autoNavOnMoveIn = v; }, ["navigate", "move", "in"])); + cats.movingNotes.push(toggle("Open the new parent in a background tab after moving a note IN", "When you nest a note into another note, open that parent in a background Stashpad tab so its new home is one click away — without stealing focus from what you're doing. Skipped when the destination is Home or already open in a tab. On by default.", + () => this.plugin.settings.openParentTabOnMoveIn, (v) => { this.plugin.settings.openParentTabOnMoveIn = v; }, ["background", "tab", "move", "in", "parent"])); cats.movingNotes.push(toggle("Navigate to destination after moving a note OUT", "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.", () => this.plugin.settings.autoNavOnMoveOut, (v) => { this.plugin.settings.autoNavOnMoveOut = v; }, ["navigate", "move", "out"])); cats.listDisplay.push(toggle("Double-click a note to open it", "Double-click (or double-tap on mobile) a note in the list to focus/open it — the same as pressing → or clicking the enter arrow. Single click still just selects. On by default.", diff --git a/src/view.ts b/src/view.ts index 441e3d5..d5f287d 100644 --- a/src/view.ts +++ b/src/view.ts @@ -62,6 +62,21 @@ import type StashpadPlugin from "./main"; const IMG_EXT = new Set(["png", "jpg", "jpeg", "gif", "webp", "svg", "bmp", "avif"]); +/** 0.190.0 — sync-storm detection for the render debounce. + * + * More than RENDER_BURST_THRESHOLD change events inside RENDER_BURST_WINDOW_MS is + * machine-driven, not human: Obsidian debounces its own metadataCache while you + * type, so a person editing rarely exceeds ~2 change events a second. A sync + * landing a few hundred files easily sustains 5–20/s. + * + * Threshold tuned by measurement: a realistic storm arrives BURSTY, with gaps + * larger than the old 80ms debounce (~150ms apart), so the old code rendered once + * per event. At 4-per-second the detector engages a few events in and then + * coalesces the rest into a single settle render. */ +const RENDER_CALM_MS = 900; +const RENDER_BURST_THRESHOLD = 5; +const RENDER_STORM_DELAY_MS = 700; + const VIEW_MODE_LABELS: Record<ViewMode, string> = { nested: "Nested", @@ -166,7 +181,18 @@ export class StashpadView extends ItemView { private slugDebouncers = new Map<string, ReturnType<typeof debounce>>(); private attachmentDebouncers = new Map<string, ReturnType<typeof debounce>>(); /** public: called by AuthorshipTracker (the host interface). */ - debouncedRender: ReturnType<typeof debounce>; + debouncedRender: { (): void; cancel?: () => void }; + /** 0.190.0: adaptive render coalescing. A fixed 80ms debounce re-fires every + * ~80ms for the ENTIRE duration of a sync storm (hundreds of files landing over + * many seconds), which is what made the list flicker and appear to render/stop/ + * render. We count change events in a rolling window and, once it looks like a + * storm rather than typing, stretch the debounce so we render ONCE after things + * go quiet instead of ~12x/second. */ + private renderBurstCount = 0; + private renderBurstWindowAt = 0; + private renderTimer: number | null = null; + /** True while change events are arriving faster than a human could cause. */ + private renderStorm = false; // Bulk-render suppression: while a bulk op runs (a long split paste, // rebootstrap), metadata-driven re-renders are dropped so the list doesn't // flicker per-note as files parse and fmSync writes recovery fields. One @@ -379,7 +405,36 @@ export class StashpadView extends ItemView { const base = mode === "manual" ? this.order.getOrder(folder, parentId) : computeSortedIds(this, parentId, mode); return this.hoistListPinned(parentId, base); }); - this.debouncedRender = debounce(() => { if (this.renderSuppressed()) return; this.render(); }, 80); + // 0.190.0: adaptive — 80ms when a human is driving, stretched to a quiet-period + // wait during a sync storm so the list settles once instead of thrashing. + const scheduleRender = (): void => { + const now = Date.now(); + // Reset only after a genuine QUIET GAP. (A fixed rolling window was the first + // attempt and it silently defeated itself: the window boundary cleared the + // storm flag every second, dropping straight back to the snappy delay and + // re-rendering — measured as no improvement at all.) + if (now - this.renderBurstWindowAt > RENDER_CALM_MS) { + this.renderBurstCount = 0; + this.renderStorm = false; + } + this.renderBurstWindowAt = now; + this.renderBurstCount++; + if (this.renderBurstCount > RENDER_BURST_THRESHOLD) this.renderStorm = true; + const delay = this.renderStorm ? RENDER_STORM_DELAY_MS : 80; + if (this.renderTimer != null) window.clearTimeout(this.renderTimer); + this.renderTimer = window.setTimeout(() => { + this.renderTimer = null; + // NB: don't clear the storm flag here — the storm ends when events stop + // arriving (the calm check above), not when we happen to get a render in. + if (this.renderSuppressed()) return; + this.render(); + }, delay); + }; + this.debouncedRender = Object.assign(scheduleRender, { + cancel: () => { + if (this.renderTimer != null) { window.clearTimeout(this.renderTimer); this.renderTimer = null; } + }, + }); this.authorship = new AuthorshipTracker(this); this.dnd = new ViewDnD(this); // 0.83.2: back the body render cache with the plugin's persisted store @@ -8045,6 +8100,10 @@ export class StashpadView extends ItemView { if (await this.changeParent(t, target.id, { silentSuccess: true })) movedTargets.push(t); } this.notifyBatchMove(movedTargets, target.id, childCounts); + // 0.191.0: surface the new home in a BACKGROUND tab (setting-gated, on by + // default). Skipped when autoNavOnMoveIn is on — that already drills you into + // the parent, so a tab would just duplicate where you already are. + if (!this.plugin.settings.autoNavOnMoveIn) void this.openParentInBackgroundTab(target.id); // 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 @@ -9371,6 +9430,41 @@ export class StashpadView extends ItemView { // --- Open in new Stashpad tab --- + /** 0.191.0: open a Stashpad tab focused on `focusId` WITHOUT stealing focus — + * used after nesting a note into another note so its new home is one click away + * while you keep working. Gated by the openParentTabOnMoveIn setting. + * + * No-ops when the destination is Home/root (nothing meaningful to open) or when a + * Stashpad tab is already focused there (so repeated nesting into the same parent + * doesn't pile up duplicate tabs). Focus is restored to whatever leaf was active + * before, which is what makes it a genuine background tab. */ + async openParentInBackgroundTab(focusId: StashpadId): Promise<void> { + if (!this.plugin.settings.openParentTabOnMoveIn) return; + if (!focusId || focusId === ROOT_ID) return; + const ws = this.app.workspace; + // Already open on that parent? Leave it alone. + let existing = false; + ws.iterateAllLeaves((l) => { + const v: any = l.view; + if (v?.getViewType?.() === STASHPAD_VIEW_TYPE && v?.focusId === focusId && v?.noteFolder === this.noteFolder) existing = true; + }); + if (existing) return; + const active = ws.activeLeaf; + try { + const leaf = ws.getLeaf("tab"); + await leaf.setViewState({ + type: STASHPAD_VIEW_TYPE, + active: false, + state: { focusId, timeFilter: this.timeFilter, folderOverride: this.folderOverride }, + }); + // getLeaf("tab") fronts the new tab; hand focus straight back so the move + // never interrupts the user's place. + if (active) ws.setActiveLeaf(active, { focus: true }); + } catch (e) { + console.warn("[Stashpad] background parent tab failed", e); + } + } + private async openInNewStashpadTab(focusId: StashpadId): Promise<void> { const ws = this.app.workspace; const originLeaf = this.leaf; @@ -10365,6 +10459,11 @@ export class StashpadView extends ItemView { }], }); + // 0.191.0: open the destination parent in a BACKGROUND tab so the moved note's + // new home is one click away without stealing focus (setting-gated, on by + // default; no-ops for a move to Home or when that parent is already open). + void this.openParentInBackgroundTab(targetParentId); + // Undo: revert each parent change AND restore the order snapshots for every affected parent. this.plugin.getUndoStack(folder).push({ label: `Move + reorder (${sourceIds.length})`,