@3sln/trove 0.0.12 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -1
- package/package.json +2 -1
- package/packages/core/src/collections/index.js +71 -10
- package/packages/core/src/encryption/keys.js +4 -3
- package/packages/core/src/encryption/policy.js +14 -7
- package/packages/core/src/encryption/rotation.js +46 -12
- package/packages/core/src/errors.js +8 -0
- package/packages/core/src/index.js +8 -2
- package/packages/core/src/indexers/contribution.js +18 -17
- package/packages/core/src/indexing.js +8 -4
- package/packages/core/src/issues.js +8 -0
- package/packages/core/src/links.js +21 -9
- package/packages/core/src/metadata/interface.js +22 -0
- package/packages/core/src/metadata/memory.js +15 -0
- package/packages/core/src/metadata/sqlite.js +23 -1
- package/packages/core/src/plugins/contributions.js +13 -0
- package/packages/core/src/rateLimit.js +253 -0
- package/packages/core/src/scan.js +44 -16
- package/packages/core/src/sidecar/document.js +18 -14
- package/packages/core/src/sidecar/index.js +9 -10
- package/packages/core/src/sidecar/manager.js +10 -15
- package/packages/core/src/uploads.js +40 -15
- package/packages/core/src/vfs.js +59 -34
- package/packages/plugin-sdk/src/browser.js +155 -0
- package/packages/plugin-sdk/src/protocol.js +13 -1
- package/packages/server/src/adapters/bun.js +1 -2
- package/packages/server/src/adapters/node.js +1 -2
- package/packages/server/src/engine/index.js +1 -1
- package/packages/server/src/engine/providers/access.js +17 -34
- package/packages/server/src/engine/providers/core.js +112 -14
- package/packages/server/src/index.js +145 -103
- package/packages/server/src/mcp/index.js +7 -12
- package/packages/server/src/mcp/tools.js +24 -29
- package/packages/server/src/router.js +31 -8
- package/packages/server/src/routes.js +74 -113
- package/packages/server/src/scope.js +78 -0
- package/packages/web/dist/assets/main-828yzsr7.js +511 -0
- package/packages/web/dist/assets/main-828yzsr7.js.map +120 -0
- package/packages/web/dist/index.html +1 -1
- package/packages/web/dist/sw.js +1 -1
- package/packages/web/src/bl/actions.js +226 -104
- package/packages/web/src/bl/activity.js +32 -82
- package/packages/web/src/bl/index.js +23 -11
- package/packages/web/src/bl/launcher.js +2 -9
- package/packages/web/src/bl/links.js +31 -18
- package/packages/web/src/bl/offline.js +24 -10
- package/packages/web/src/bl/pluginInstall.js +29 -26
- package/packages/web/src/bl/queries.js +76 -68
- package/packages/web/src/bl/services.js +22 -14
- package/packages/web/src/bl/social.js +39 -25
- package/packages/web/src/bl/state.js +22 -4
- package/packages/web/src/bl/viewState.js +9 -0
- package/packages/web/src/bl/watchQuery.js +1 -8
- package/packages/web/src/dispatch.js +26 -0
- package/packages/web/src/platform/api.js +32 -0
- package/packages/web/src/platform/commands.js +14 -15
- package/packages/web/src/platform/context.js +3 -58
- package/packages/web/src/platform/contributions.js +1 -35
- package/packages/web/src/platform/fileChunks.js +281 -0
- package/packages/web/src/platform/index.js +8 -9
- package/packages/web/src/platform/mediaUrls.js +10 -0
- package/packages/web/src/platform/navigation.js +35 -21
- package/packages/web/src/platform/pickers.js +39 -19
- package/packages/web/src/platform/pluginHost.js +4 -1
- package/packages/web/src/platform/pluginRpc.js +47 -2
- package/packages/web/src/platform/spatialNav.js +1 -1
- package/packages/web/src/platform/viewport.js +14 -6
- package/packages/web/src/platform/voiceSearch.js +17 -9
- package/packages/web/src/platform/whenclause.js +9 -19
- package/packages/web/src/runtime.js +2 -37
- package/packages/web/src/ui/activate.js +18 -2
- package/packages/web/src/ui/components/activityPanel.js +1 -1
- package/packages/web/src/ui/components/adminView.js +4 -7
- package/packages/web/src/ui/components/editorArea.js +10 -1
- package/packages/web/src/ui/components/launcher.js +29 -13
- package/packages/web/src/ui/components/openers/index.js +17 -22
- package/packages/web/src/ui/components/openers/markdown.js +2 -2
- package/packages/web/src/ui/components/overlays.js +31 -5
- package/packages/web/src/ui/components/pluginReview.js +7 -4
- package/packages/web/src/ui/components/pluginsView.js +1 -1
- package/packages/web/src/ui/components/settingsView.js +30 -27
- package/packages/web/src/ui/components/statusBar.js +8 -6
- package/packages/web/src/ui/components/views/grid.js +2 -2
- package/packages/web/src/ui/components/views/parts.js +1 -1
- package/packages/web/src/ui/compositions/workbench.js +20 -6
- package/packages/web/src/ui/sanitize.js +0 -5
- package/packages/web/src/workbench.js +37 -19
- package/packages/web/dist/assets/main-c9dnnnc6.js +0 -356
- package/packages/web/dist/assets/main-c9dnnnc6.js.map +0 -118
|
@@ -0,0 +1,511 @@
|
|
|
1
|
+
import{a as $G,c as U1,d as DG}from"./chunk-4xqbzebh.js";var vB={};U1(vB,{wbr:()=>OH,video:()=>xH,vdom:()=>N0,ul:()=>QH,u:()=>PH,track:()=>TH,tr:()=>tH,title:()=>q1,time:()=>NH,thead:()=>rH,th:()=>iH,tfoot:()=>oH,textarea:()=>$6,template:()=>I6,td:()=>sH,tbody:()=>nH,table:()=>aH,svg:()=>uH,sup:()=>qH,summary:()=>W6,sub:()=>zH,style:()=>O1,strong:()=>VH,special:()=>M1,span:()=>MH,source:()=>fH,small:()=>RH,slot:()=>U6,settings:()=>z1,select:()=>G6,section:()=>p1,script:()=>j1,schedule:()=>F6,samp:()=>FH,s:()=>IH,reconcile:()=>V1,q:()=>UH,progress:()=>H6,pre:()=>AH,portal:()=>vH,picture:()=>bH,param:()=>hH,p:()=>e1,output:()=>X6,option:()=>L6,optgroup:()=>Y6,ol:()=>t1,object:()=>yH,noscript:()=>S1,nav:()=>m1,meter:()=>E6,meta:()=>N1,math:()=>mH,mark:()=>WH,map:()=>wH,main:()=>u1,link:()=>P1,li:()=>r1,legend:()=>K6,label:()=>J6,kbd:()=>ZH,ins:()=>DH,input:()=>C6,img:()=>_H,iframe:()=>gH,i:()=>$H,html:()=>jC,hr:()=>i1,header:()=>k1,h6:()=>f1,h5:()=>v1,h4:()=>b1,h3:()=>h1,h2:()=>y1,h1:()=>g1,h:()=>F1,form:()=>B6,footer:()=>x1,flush:()=>R6,figure:()=>o1,figcaption:()=>s1,fieldset:()=>Q6,embed:()=>kH,em:()=>GH,dt:()=>n1,dodo:()=>dE,dl:()=>a1,div:()=>d1,dialog:()=>Z6,dfn:()=>HH,details:()=>D6,del:()=>XH,dd:()=>c1,datalist:()=>A6,data:()=>LH,colgroup:()=>dH,col:()=>cH,code:()=>YH,clear:()=>M6,cite:()=>EH,caption:()=>lH,canvas:()=>pH,button:()=>eH,br:()=>KH,blockquote:()=>l1,b:()=>JH,audio:()=>SH,aside:()=>T1,article:()=>w1,area:()=>jH,alias:()=>R1,address:()=>_1,abbr:()=>CH,a:()=>BH});var sQ=Symbol("ELEMENT_NODE"),OC=Symbol("ALIAS_NODE"),$B=Symbol("SPECIAL_NODE"),bB=Symbol("OPAQUE_NODE"),wA=Symbol("NODE_STATE");var E1=new Set(["__proto__","constructor","prototype"]),pE=(A,Q)=>Object.prototype.hasOwnProperty.call(A,Q);function Y1(A,Q){return typeof Q==="string"&&A.toLowerCase()===Q.toLowerCase()}class DB{constructor(A,Q,B){this.type=A,this.tag=Q,this.args=B}key(A){return this.k=A,this}on(A){return this.hooks=A,this}opaque(){if(this.type!==sQ)throw Error(".opaque() can only be used on element nodes (h).");return this.type=bB,this}}function L1(A,Q){if(A===Q)return!1;if(A&&Q&&typeof A==="object"&&typeof Q==="object"){if(A.constructor!==Q.constructor)return!0;if(Array.isArray(A)){if(A.length!==Q.length)return!0;for(let B=0;B<A.length;B++)if(A[B]!==Q[B])return!0;return!1}if(A.constructor===Object){let B=Object.keys(A);if(B.length!==Object.keys(Q).length)return!0;for(let C of B)if(!pE(Q,C)||A[C]!==Q[C])return!0;return!1}}return!0}function X1(A){return Array.isArray(A)||A!=null&&typeof A[Symbol.iterator]==="function"&&typeof A!=="string"}function H1(A){return(...Q)=>new DB(OC,A,Q)}function G1(A){return(...Q)=>new DB($B,A,Q)}function $1(A,Q){if(A.namespaceURI==="http://www.w3.org/1999/xhtml")switch(Q){case"svg":return"http://www.w3.org/2000/svg";case"math":return"http://www.w3.org/1998/Math/MathML"}return A.namespaceURI??A.host?.namespaceURI??"http://www.w3.org/1999/xhtml"}function lE(A){return{originalProps:Object.create(null),newVdom:A}}function q0(A,Q,B){let C=A.ownerDocument.createElementNS($1(A,Q),Q);return C[wA]=lE(B),C}var cE=new WeakMap;function D1(A){let Q=[],B=A;while(B)if(Q.push(B),B.parentElement)B=B.parentElement;else B=B.getRootNode()?.host;return Q}function mE(A,Q){for(let B of Q)A.add(B)}function Z1(A,Q){let B=Q??A?.defaultView??globalThis;return B.Node?.prototype??B.Element?.prototype}function W1(A){let Q=new Set;return A.addEventListener("focusin",(B)=>{Q.clear(),mE(Q,B.composedPath())}),A.addEventListener("focusout",(B)=>{if(!B.relatedTarget)Q.clear()}),mE(Q,D1(A.activeElement)),cE.set(A,Q),Q}var N0=(A)=>{let Q=A?.shouldUpdate??L1,B=A?.isMap??(($)=>$?.constructor===Object),C=A?.mapIter??(($)=>Object.entries($)),J=A?.mapGet??(($,W)=>$[W]),K=A?.mapMerge??((...$)=>Object.assign({},...$)),E=A?.newMap??(($)=>({...$})),Y=A?.mapPut??(($,W,Z)=>{return $[W]=Z,$}),L=A?.isSeq??X1,X=A?.seqIter??(($)=>$),H=A?.convertName??(($)=>$),G=A?.convertTagName??H,D=A?.convertPropName??H,U=A?.convertStyleName??H,F=A?.convertDataName??H,R=A?.convertClassName??H,V=A?.convertHookName??H,w=A?.listenerKey??"listener",m=A?.captureKey??"capture",b=A?.passiveKey??"passive",z=E({});function p($){if($==null)return[][Symbol.iterator]();if(typeof $[Symbol.iterator]==="function")return $[Symbol.iterator]();if(typeof $.next==="function")return $;return[$][Symbol.iterator]()}function k($,W,Z,j,x){if($==null)return;for(let _ in $)if(pE($,_))W(_,$[_],Z,j,x)}function v($,W,Z,j,x){if($==null)return;let _=p(C($)),n;while(!(n=_.next()).done){let HA=n.value;W(HA[0],HA[1],Z,j,x)}}let O=A?.mapEach??(A?.mapIter?v:k);function g($){return $===null||$===void 0||$===!1}function e($,W,Z){let j=p(X(W)),x;while(!(x=j.next()).done){let _=x.value;if(Z&&g(_))continue;if(!L(_))$.push(_);else e($,_,Z)}}function AA($,W){let Z=[];return e(Z,$,W),Z}let QA=A?.flattenSeq??AA;function QQ($,W){let Z=[];for(let j=W;j<$.length;j++){let x=$[j];if(g(x))continue;if(!L(x))Z.push(x);else e(Z,x,!0)}return Z}function IA($){return g($)?"":String($)}function FA($,W,...Z){if(!B(W)){if(W!==null&&W!==void 0)Z.unshift(W);W=z}return new DB(sQ,G($),[W,...Z])}function LA($,W,Z){Z.setProperty(U($),W)}function t($,W,Z,j){if(J(j,$)!==void 0)return;Z.removeProperty(U($))}function WA($,W,Z){let j=$.style;O(Z,LA,j),O(W,t,j,Z)}function XA($,W,Z){Z.setAttribute(D($),W)}function aQ($,W,Z,j){if(J(j,$)!==void 0)return;Z.removeAttribute(D($))}function OA($,W,Z){O(Z,XA,$),O(W,aQ,$,Z)}function iA($,W,Z){Z.dataset[F($)]=W}function jA($,W,Z,j){if(J(j,$)!==void 0)return;delete Z.dataset[F($)]}function RA($,W,Z){O(Z,iA,$),O(W,jA,$,Z)}function r($,W,Z){let j=new Set;for(let x of QA(W,!0)){let _=R(x);if(_)j.add(_)}for(let x of QA(Z,!0)){let _=R(x);if(!_)continue;j.delete(_),$.classList.add(_)}for(let x of j)$.classList.remove(x)}function pA($,W,Z,j){if(E1.has(Z)){console.error(`Refusing to assign unsafe prop name '${Z}' to a DOM node.`);return}let x=W.originalProps;if(!(Z in x))x[Z]=$[Z];$[Z]=j===void 0?x[Z]:j}function PQ($,W,Z){let j=W.originalProps;if(Z in j)$[Z]=j[Z],delete j[Z]}function OQ($,W,Z,j,x){let _=D($),n=J(j,$);if(Object.is(W,n))return;switch(_){case"$styling":{if(!B(W))throw Error("invalid value for styling prop");WA(Z,n??z,W??z);break}case"$classes":{if(!L(W))throw Error("invalid value for classes prop");r(Z,n??[],W??[]);break}case"$attrs":{if(!B(W))throw Error("invalid value for attrs prop");OA(Z,n??z,W??z);break}case"$dataset":{if(!B(W))throw Error("invalid value for dataset prop");RA(Z,n??z,W??z);break}default:{if(x)pA(Z,Z[wA],_,W);else if(W===void 0)Z.removeAttribute(_);else Z.setAttribute(_,W);break}}}function LB($,W,Z,j,x){if(J(j,$)!==void 0)return;let _=D($);switch(_){case"$styling":WA(Z,W??z,z);break;case"$classes":r(Z,W??[],[]);break;case"$attrs":OA(Z,W??z,z);break;case"$dataset":RA(Z,W??z,z);break;default:{if(x)PQ(Z,Z[wA],_);else Z.removeAttribute(_);break}}}function jQ($,W){let Z=$[wA],j=$.namespaceURI==="http://www.w3.org/1999/xhtml",x=Z.vdom?.args[0]??z;O(W,OQ,$,x,j),O(x,LB,$,W,j)}function SQ($,W,Z){if(typeof Z==="function")$.addEventListener(W,Z);else if(Z!=null)$.addEventListener(W,J(Z,w),{capture:!!J(Z,m),passive:!!J(Z,b)})}function _Q($,W,Z){if(typeof Z==="function")$.removeEventListener(W,Z);else if(Z!=null)$.removeEventListener(W,J(Z,w),!!J(Z,m))}function wQ($,W,Z){let j=V($);if(j[0]==="$")return;SQ(Z,j,W)}function yB($,W,Z,j){let x=V($);if(x[0]==="$")return;let _=J(j,$);if(W===_)return;_Q(Z,x,_),SQ(Z,x,W)}function rX($,W,Z,j){let x=V($);if(x[0]==="$"||J(j,$)!==void 0)return;_Q(Z,x,W)}function hE($,W){let Z=$[wA],j=W??z;if(!Z.vdom){O(j,wQ,$);return}let x=Z.vdom.hooks??z;O(j,yB,$,x),O(x,rX,$,j)}function z0($){let W=$[wA],Z=W.newVdom,j=W.vdom,x=Z.args;switch(Z.type){case sQ:{jQ($,x[0]),hB($,QQ(x,1));break}case bB:{jQ($,x[0]);break}case OC:{let _=Z.tag.apply($,Z.args);if(g(_))hB($,[]);else if(L(_))hB($,QA(_,!0));else hB($,[_]);break}case $B:{try{Z.tag.update?.($,Z.args,j?.args)}catch(_){console.error(_)}break}}if(Z.hooks||j?.hooks)hE($,Z.hooks??z);try{Z.hooks?.$update?.($,Z,j)}catch(_){console.error(_)}W.vdom=Z,delete W.newVdom}function tX($,W){if(typeof W!=="object"||W===null)return $.ownerDocument.createTextNode(IA(W));let Z;switch(W.type){case sQ:case bB:Z=q0($,W.tag,W);break;case OC:Z=q0($,"udom-alias",W),Z.style.display="contents";break;case $B:Z=q0($,"udom-special",W),Z.style.display="contents";break;default:throw Error("Invalid VDOM node")}return Z}function bE($){if($.children)for(let W of $.children)PC(W)}function PC($){let W=$[wA];if(!W)return;let{vdom:Z}=W;if(!Z){delete $[wA];return}if(Z.hooks)hE($,z);if(Z.type===sQ||Z.type===bB)jQ($,z);if(Z.type===sQ||Z.type===OC)bE($);delete $[wA];try{if(Z.type===$B)Z.tag.detach?.($);Z.hooks?.$detach?.($)}catch(j){console.error(j)}}function eX($,W){let Z=$[wA];if(Q(Z.vdom.args,W.args)||Q(Z.vdom.hooks,W.hooks))Z.newVdom=W;return $}function A1($){let W=new Map,Z={nodes:[],cursor:0};for(let j of $.childNodes){if(j.nodeType===3){Z.nodes.push(j);continue}let x=j[wA],_=x?.vdom;if(_===void 0){if(x?.newVdom)throw Error("Attempt to reconcile against a target while already working on a reconciliation against that same target, this is not allowed");continue}let n=W.get(_.tag);if(!n)n={nodesForKey:null,nodesWithoutKey:{nodes:[],cursor:0}},W.set(_.tag,n);if(_.k!==void 0){if(!n.nodesForKey)n.nodesForKey=new Map;let HA=n.nodesForKey.get(_.k);if(HA)HA.nodes.push(j);else n.nodesForKey.set(_.k,{nodes:[j],cursor:0})}else n.nodesWithoutKey.nodes.push(j)}return{byTag:W,textNodes:Z}}function vE($){if(!$||$.cursor>=$.nodes.length)return;return $.nodes[$.cursor++]}function Q1($,W,Z,j){let x=$.firstChild;for(let _=0;_<W.length;_++){let n=W[_];if(n===x){x=x.nextSibling;continue}(j&&n.isConnected?j:Z).call($,n,x)}}function B1($,W,Z,j){let x=W[j],_=x;for(let HA=j-1;HA>=0;HA--){let IQ=W[HA];if(IQ!==_.previousSibling)Z.call($,IQ,_);_=IQ}let n=x.nextSibling;for(let HA=j+1;HA<W.length;HA++){let IQ=W[HA];if(IQ===n)n=n.nextSibling;else Z.call($,IQ,n)}}function C1($,W){for(let Z=0;Z<$.length;Z++)if(W.has($[Z]))return Z;return-1}function J1($){let W=$[wA];if(!W?.newVdom)return;if(!W.vdom)try{if(W.newVdom.hooks?.$attach?.($),W.newVdom.type===$B)W.newVdom.tag.attach?.($)}catch(Z){console.error(Z)}z0($)}function hB($,W){let Z=$.firstChild?new Set($.childNodes):null,{byTag:j,textNodes:x}=A1($),_=[];for(let MA of W){let nQ;if(MA instanceof DB){let HB=j.get(MA.tag),GB=HB?vE(MA.k!==void 0?HB.nodesForKey?.get(MA.k):HB.nodesWithoutKey):void 0;nQ=GB?eX(GB,MA):tX($,MA)}else{let HB=vE(x),GB=IA(MA);if(HB){if(nQ=HB,nQ.nodeValue!==GB)nQ.nodeValue=GB}else nQ=$.ownerDocument.createTextNode(GB)}Z?.delete(nQ),_.push(nQ)}if(Z)for(let MA of Z)PC(MA),$.removeChild(MA);if(_.length===0)return;let n=$.ownerDocument,HA=Z1(n,A?.window),IQ=HA.insertBefore,fE=typeof HA.moveBefore==="function"?HA.moveBefore:null,uE=$.isConnected,XB=-1;if(uE&&!fE){let MA=cE.get(n)??W1(n);if(XB=C1(_,MA),XB!==-1&&_[XB].parentNode!==$)XB=-1}if(XB===-1)Q1($,_,IQ,uE?fE:null);else B1($,_,IQ,XB);for(let MA=0;MA<_.length;MA++)J1(_[MA])}function K1($,W){let Z=$[wA];if(W===null||W===void 0){if(Z)PC($);else bE($);$.replaceChildren();return}if(L(W)){hB($,QA(W,!0));return}if(W instanceof DB){if(Z){if(Z.vdom.type===W.type&&Z.vdom.tag===W.tag){if(Q(Z.vdom.args,W.args)||Q(Z.vdom.hooks,W.hooks))Z.newVdom=W,z0($);return}PC($)}switch(W.type){case sQ:case bB:if(!Y1($.nodeName,G(W.tag)))throw Error("incompatible target for vdom");break}$[wA]=lE(W);try{if(W.hooks?.$attach?.($),W.type===$B)W.tag.attach?.($)}catch(j){console.error(j)}z0($);return}throw Error("invalid vdom")}return{h:FA,alias:H1,special:G1,reconcile:K1,settings:{shouldUpdate:Q,isMap:B,mapIter:C,mapEach:O,mapGet:J,mapMerge:K,newMap:E,mapPut:Y,isSeq:L,flattenSeq:QA,seqIter:X,convertTagName:G,convertPropName:D,convertStyleName:U,convertDataName:F,convertClassName:R,convertHookName:V,convertName:H,listenerKey:w,captureKey:m,passiveKey:b}}};function jC({h:A}){return{title:(...Q)=>A("title",...Q),meta:(Q)=>A("meta",Q),link:(Q)=>A("link",Q),style:(...Q)=>A("style",...Q),script:(...Q)=>A("script",...Q),noscript:(...Q)=>A("noscript",...Q),address:(...Q)=>A("address",...Q),article:(...Q)=>A("article",...Q),aside:(...Q)=>A("aside",...Q),footer:(...Q)=>A("footer",...Q),header:(...Q)=>A("header",...Q),h1:(...Q)=>A("h1",...Q),h2:(...Q)=>A("h2",...Q),h3:(...Q)=>A("h3",...Q),h4:(...Q)=>A("h4",...Q),h5:(...Q)=>A("h5",...Q),h6:(...Q)=>A("h6",...Q),main:(...Q)=>A("main",...Q),nav:(...Q)=>A("nav",...Q),section:(...Q)=>A("section",...Q),blockquote:(...Q)=>A("blockquote",...Q),dd:(...Q)=>A("dd",...Q),div:(...Q)=>A("div",...Q),dl:(...Q)=>A("dl",...Q),dt:(...Q)=>A("dt",...Q),figcaption:(...Q)=>A("figcaption",...Q),figure:(...Q)=>A("figure",...Q),hr:()=>A("hr"),li:(...Q)=>A("li",...Q),ol:(...Q)=>A("ol",...Q),p:(...Q)=>A("p",...Q),pre:(...Q)=>A("pre",...Q),ul:(...Q)=>A("ul",...Q),a:(...Q)=>A("a",...Q),abbr:(...Q)=>A("abbr",...Q),b:(...Q)=>A("b",...Q),br:()=>A("br"),cite:(...Q)=>A("cite",...Q),code:(...Q)=>A("code",...Q),data:(...Q)=>A("data",...Q),del:(...Q)=>A("del",...Q),dfn:(...Q)=>A("dfn",...Q),em:(...Q)=>A("em",...Q),i:(...Q)=>A("i",...Q),ins:(...Q)=>A("ins",...Q),kbd:(...Q)=>A("kbd",...Q),mark:(...Q)=>A("mark",...Q),q:(...Q)=>A("q",...Q),s:(...Q)=>A("s",...Q),samp:(...Q)=>A("samp",...Q),small:(...Q)=>A("small",...Q),span:(...Q)=>A("span",...Q),strong:(...Q)=>A("strong",...Q),sub:(...Q)=>A("sub",...Q),sup:(...Q)=>A("sup",...Q),time:(...Q)=>A("time",...Q),u:(...Q)=>A("u",...Q),wbr:()=>A("wbr"),area:(Q)=>A("area",Q),audio:(...Q)=>A("audio",...Q),img:(Q)=>A("img",Q),map:(...Q)=>A("map",...Q),track:(Q)=>A("track",Q),video:(...Q)=>A("video",...Q),embed:(Q)=>A("embed",Q),iframe:(...Q)=>A("iframe",...Q),object:(...Q)=>A("object",...Q),param:(Q)=>A("param",Q),picture:(...Q)=>A("picture",...Q),portal:(...Q)=>A("portal",...Q),source:(Q)=>A("source",Q),svg:(...Q)=>A("svg",...Q),math:(...Q)=>A("math",...Q),canvas:(...Q)=>A("canvas",...Q),caption:(...Q)=>A("caption",...Q),col:(Q)=>A("col",Q),colgroup:(...Q)=>A("colgroup",...Q),table:(...Q)=>A("table",...Q),tbody:(...Q)=>A("tbody",...Q),td:(...Q)=>A("td",...Q),tfoot:(...Q)=>A("tfoot",...Q),th:(...Q)=>A("th",...Q),thead:(...Q)=>A("thead",...Q),tr:(...Q)=>A("tr",...Q),button:(...Q)=>A("button",...Q),datalist:(...Q)=>A("datalist",...Q),fieldset:(...Q)=>A("fieldset",...Q),form:(...Q)=>A("form",...Q),input:(Q)=>A("input",Q),label:(...Q)=>A("label",...Q),legend:(...Q)=>A("legend",...Q),meter:(...Q)=>A("meter",...Q),optgroup:(...Q)=>A("optgroup",...Q),option:(...Q)=>A("option",...Q),output:(...Q)=>A("output",...Q),progress:(...Q)=>A("progress",...Q),select:(...Q)=>A("select",...Q),textarea:(...Q)=>A("textarea",...Q),details:(...Q)=>A("details",...Q),dialog:(...Q)=>A("dialog",...Q),summary:(...Q)=>A("summary",...Q),slot:(...Q)=>A("slot",...Q),template:(...Q)=>A("template",...Q)}}function P0({window:A}={}){let Q=!1,B=0,C=[];function J(){return A??globalThis}function K(U){let F=J().requestAnimationFrame;return typeof F==="function"?F.call(J(),U):setTimeout(U,16)}function E(U){let F=J().cancelAnimationFrame;if(typeof F==="function")F.call(J(),U);else clearTimeout(U)}function Y(){return J().performance?.now()??Date.now()}function L(U){for(let F of U)try{F()}catch(R){console.error("Error in scheduled function:",R)}}function X(){let U=Y();B=0;while(C.length>0){let F=C.splice(0,100);if(L(F),Y()-U>10&&C.length>0){B=K(X);return}}Q=!1}function H(U,{signal:F}={}){if(F?.aborted)return;let R=U;if(F)R=()=>{if(!F.aborted)U()};if(C.push(R),!Q)Q=!0,B=K(X)}function G(){if(B)E(B),B=0;Q=!0;while(C.length>0){let U=C;C=[],L(U)}Q=!1}function D(){if(B)E(B);C=[],Q=!1,B=0}return{schedule:H,flush:G,clear:D}}function dE(A){let Q=N0(A),B=jC(Q),C=A?.scheduler??P0(A);return{...Q,...B,...C}}var I1=dE();var{h:F1,alias:R1,special:M1,reconcile:V1,settings:z1,title:q1,meta:N1,link:P1,style:O1,script:j1,noscript:S1,address:_1,article:w1,aside:T1,footer:x1,header:k1,h1:g1,h2:y1,h3:h1,h4:b1,h5:v1,h6:f1,main:u1,nav:m1,section:p1,blockquote:l1,dd:c1,div:d1,dl:a1,dt:n1,figcaption:s1,figure:o1,hr:i1,li:r1,ol:t1,p:e1,pre:AH,ul:QH,a:BH,abbr:CH,b:JH,br:KH,cite:EH,code:YH,data:LH,del:XH,dfn:HH,em:GH,i:$H,ins:DH,kbd:ZH,mark:WH,q:UH,s:IH,samp:FH,small:RH,span:MH,strong:VH,sub:zH,sup:qH,time:NH,u:PH,wbr:OH,area:jH,audio:SH,img:_H,map:wH,track:TH,video:xH,embed:kH,iframe:gH,object:yH,param:hH,picture:bH,portal:vH,source:fH,svg:uH,math:mH,canvas:pH,caption:lH,col:cH,colgroup:dH,table:aH,tbody:nH,td:sH,tfoot:oH,th:iH,thead:rH,tr:tH,button:eH,datalist:A6,fieldset:Q6,form:B6,input:C6,label:J6,legend:K6,meter:E6,optgroup:Y6,option:L6,output:X6,progress:H6,select:G6,textarea:$6,details:D6,dialog:Z6,summary:W6,slot:U6,template:I6,schedule:F6,flush:R6,clear:M6}=I1;function V6(A,{signal:Q}={}){queueMicrotask(()=>{if(!Q?.aborted)A()})}function z6(A){return(Q)=>A("pre",{$styling:{"background-color":"#fdd",color:"#330",padding:"1em","white-space":"pre-wrap"}},A("strong",null,`Error: ${Q?.message??String(Q)}`),`
|
|
2
|
+
|
|
3
|
+
`,Q?.stack??"")}function aE(A){return A!=null&&typeof A.special==="function"&&typeof A.reconcile==="function"}function O0(A){let Q=aE(A)?{dodo:A}:A,B=Q?.dodo;if(!aE(B))throw Error("a dodo instance must be provided in settings, e.g. reactive({dodo})");return{schedule:typeof B.schedule==="function"?B.schedule:V6,renderError:z6(B.h),...Q,dodo:B,...B.settings}}var BQ=Symbol("dodo.reactive.PENDING"),VA=Symbol("dodo.reactive.NOTHING");function iQ(A){return A!=null&&typeof A.onDirty==="function"&&typeof A.getValue==="function"}function ZB(A){return iQ(A)?A.getValue():A}function q6(A){if(typeof A==="function")return A;if(A&&typeof A.unsubscribe==="function")return()=>A.unsubscribe();return()=>{}}function j0(){let A=new Set;return{listeners:A,notify(){for(let Q of Array.from(A))try{Q()}catch(B){console.error("Error in dodo cell listener:",B)}}}}function S0(A,Q){let{listeners:B,notify:C}=j0(),J=null;return{onDirty(K){if(B.add(K),B.size===1)try{J=q6(A(C))}catch(Y){throw B.delete(K),Y}let E=!1;return()=>{if(E)return;if(E=!0,B.delete(K),B.size===0&&J){let Y=J;J=null,Y()}}},getValue(){return Q()}}}function c(A){let Q=A,{listeners:B,notify:C}=j0();return{onDirty(J){return B.add(J),()=>B.delete(J)},getValue(){return Q},setValue(J){if(Object.is(J,Q))return;Q=J,C()},update(J){this.setValue(J(Q))}}}function nE(A){return{onDirty(){return()=>{}},getValue(){return A}}}function BA(A,Q){let B=Array.isArray(A)?A:[A],{listeners:C,notify:J}=j0(),K=null,E=VA,Y=()=>{E=VA,J()},L=()=>{let X=Array(B.length);for(let H=0;H<B.length;H++){let G=ZB(B[H]);if(G===BQ)return BQ;X[H]=G}return Q(...X)};return{onDirty(X){if(C.add(X),C.size===1)E=VA,K=B.map((G)=>iQ(G)?G.onDirty(Y):null);let H=!1;return()=>{if(H)return;if(H=!0,C.delete(X),C.size===0&&K){for(let G of K)G?.();K=null,E=VA}}},getValue(){if(E===VA||!K)E=L();return E}}}function SC(A,Q){return BA([A],Q)}function _C(A,{initial:Q=BQ}={}){return N6(A,{initial:Q},(B,C)=>B.subscribe({next:C.next,error:C.error,complete:C.complete}))}function N6(A,{initial:Q},B){let C=Q,J=VA;return S0((E)=>{return B(A,{next(L){C=L,J=VA,E()},error(L){J=L,E()},complete(){}})},()=>{if(J!==VA)throw J;return C})}function sE(A){return{subscribe(Q){let B=typeof Q==="function"?{next:Q}:Q??{},C=()=>{let K;try{K=ZB(A)}catch(E){B.error?.(E);return}if(K!==BQ)B.next?.(K)},J=iQ(A)?A.onDirty(C):()=>{};return C(),{unsubscribe:J}}}}function TQ(A,Q){let B=()=>{let J;try{J=ZB(A)}catch(K){console.error("Error reading cell in effect:",K);return}if(J===BQ)return;Q(J)},C=iQ(A)?A.onDirty(B):()=>{};return B(),C}var oQ=Symbol("dodo.reactive.watch");function wC(A){let Q=O0(A),{dodo:B,schedule:C,renderError:J}=Q,{special:K,reconcile:E}=B,Y=Q.mapGet??((G,D)=>G[D]),L=(G,D)=>G==null?void 0:Y(G,D),X=Q.shouldUpdate??((G,D)=>G!==D);return{watch:K({attach(G){G[oQ]={source:VA,builder:null,placeholder:void 0,errorBuilder:void 0,unsubscribe:null,abortController:null,renderScheduled:!1,lastValue:VA,lastBuilder:VA}},update(G,[D,U,F]){let R=G[oQ];if(!R)return;if(R.builder=U,R.placeholder=L(F,"placeholder"),R.errorBuilder=L(F,"error"),R.source!==D){if(R.unsubscribe?.(),R.unsubscribe=null,R.abortController?.abort(),R.abortController=new AbortController,R.source=D,R.lastValue=VA,iQ(D))try{R.unsubscribe=D.onDirty(()=>this.invalidate(G))}catch(V){this.renderError(G,V);return}}this.render(G)},invalidate(G){let D=G[oQ];if(!D||D.renderScheduled)return;D.renderScheduled=!0,C(()=>this.render(G),{signal:D.abortController?.signal})},render(G){let D=G[oQ];if(!D)return;D.renderScheduled=!1;let U;try{U=ZB(D.source===VA?void 0:D.source)}catch(F){this.renderError(G,F);return}if(D.builder===D.lastBuilder&&D.lastValue!==VA&&!X(D.lastValue,U))return;D.lastValue=U,D.lastBuilder=D.builder;try{if(U===BQ)E(G,D.placeholder?[D.placeholder()]:[]);else E(G,[D.builder(U)])}catch(F){this.renderError(G,F)}},renderError(G,D){let U=G[oQ];if(!U)return;U.lastValue=VA,U.lastBuilder=VA,console.error("Error in watched cell:",D);try{E(G,[(U.errorBuilder??J)(D)])}catch(F){console.error("Error rendering the error view:",F)}},detach(G){let D=G[oQ];if(!D)return;D.unsubscribe?.(),D.abortController?.abort(),delete G[oQ],E(G,null)}})}}var{watch:CQ}=wC({dodo:vB});var T=vB;var oE={watch:CQ,cell:c,derive:BA,constant:nE,mapCell:SC,connectable:S0,fromObservable:_C,toObservable:sE,effect:TQ,isCell:iQ,readCell:ZB,PENDING:BQ};var f=Object.freeze({NOT_FOUND:"not_found",ALREADY_EXISTS:"already_exists",INVALID:"invalid",CONFLICT:"conflict",UNAUTHORIZED:"unauthorized",FORBIDDEN:"forbidden",UNSUPPORTED:"unsupported",QUOTA:"quota",TOO_LARGE:"too_large",BAD_RANGE:"bad_range",TRANSIENT:"transient",TIMEOUT:"timeout",ABORTED:"aborted",INTERNAL:"internal"}),P6=new Set([f.TRANSIENT,f.TIMEOUT,f.QUOTA]),O6={[f.NOT_FOUND]:404,[f.ALREADY_EXISTS]:409,[f.INVALID]:400,[f.CONFLICT]:412,[f.UNAUTHORIZED]:401,[f.FORBIDDEN]:403,[f.UNSUPPORTED]:501,[f.QUOTA]:429,[f.TOO_LARGE]:413,[f.BAD_RANGE]:416,[f.TRANSIENT]:503,[f.TIMEOUT]:504,[f.ABORTED]:499,[f.INTERNAL]:500};class q extends Error{constructor(A,Q,B={}){super(Q,B.cause!==void 0?{cause:B.cause}:void 0);if(this.name="TroveError",this.code=A||f.INTERNAL,this.retryable=B.retryable??P6.has(this.code),this.details=B.details??null,this.status=O6[this.code]??500,this.code===f.QUOTA&&!this.retryable)this.status=507}toJSON(){return{error:{code:this.code,message:this.message,retryable:this.retryable,...this.details?{details:this.details}:{}}}}static notFound(A,Q){return new q(f.NOT_FOUND,A?`${A} not found`:"Not found",Q)}static alreadyExists(A,Q){return new q(f.ALREADY_EXISTS,`${A} already exists`,Q)}static invalid(A,Q){return new q(f.INVALID,A,Q)}static conflict(A,Q){return new q(f.CONFLICT,A,Q)}static unsupported(A,Q){return new q(f.UNSUPPORTED,A,Q)}static transient(A,Q){return new q(f.TRANSIENT,A,{retryable:!0,...Q})}static timeout(A,Q){return new q(f.TIMEOUT,A,{retryable:!0,...Q})}static aborted(A="Operation aborted",Q){return new q(f.ABORTED,A,{retryable:!1,...Q})}static unauthorized(A="Unauthorized",Q){return new q(f.UNAUTHORIZED,A,Q)}static tooLarge(A="Too large",Q){return new q(f.TOO_LARGE,A,{retryable:!1,...Q})}static badRange(A="Range not satisfiable",Q){return new q(f.BAD_RANGE,A,{retryable:!1,...Q})}static forbidden(A="Forbidden",Q){return new q(f.FORBIDDEN,A,Q)}static rateLimited(A,Q){return new q(f.QUOTA,A,{retryable:!0,...Q})}static internal(A="Internal error",Q){return new q(f.INTERNAL,A,Q)}}function fB(A,Q="Unexpected error"){if(A instanceof q)return A;if(A?.name==="AbortError"||A?.code==="ABORT_ERR")return q.aborted(A.message||"Operation aborted",{cause:A});if(new Set(["ECONNRESET","ECONNREFUSED","ETIMEDOUT","EAI_AGAIN","EPIPE","ENOTFOUND","UND_ERR_SOCKET"]).has(A?.code)||A instanceof TypeError&&/fetch|network/i.test(A.message||""))return q.transient(A.message||"Network error",{cause:A});switch(A?.code){case"ENOENT":return q.notFound(null,{cause:A});case"EEXIST":return q.alreadyExists("Path",{cause:A});case"EACCES":case"EPERM":return new q(f.FORBIDDEN,"Permission denied",{cause:A});case"ENOSPC":return new q(f.QUOTA,"The storage volume is full — free some space and try again",{cause:A,retryable:!1});case"EDQUOT":return new q(f.QUOTA,"The storage quota for this volume has been reached",{cause:A,retryable:!1});case"EFBIG":return new q(f.QUOTA,"That file is larger than this filesystem can store",{cause:A,retryable:!1})}return q.internal(A?.message||Q,{cause:A})}function iE(A){if(A instanceof q)return A.retryable;return fB(A).retryable}function rE(A=""){let Q=(globalThis.crypto?.randomUUID?.()??j6()).replace(/-/g,"");return A?`${A}_${Q}`:Q}function j6(){let A="";for(let Q=0;Q<32;Q++)A+=Math.floor(Math.random()*16).toString(16);return A}function tE(A){let Q=String(A||"").lastIndexOf(".");return Q>0?String(A).slice(Q).toLowerCase():""}function TC(A,Q){if(!A||!Q)return!1;if(typeof A.match==="function")try{if(A.match(Q))return!0}catch{}let B=tE(Q.name||"");if(B&&(A.ext||[]).some((K)=>(K.startsWith(".")?K:"."+K).toLowerCase()===B))return!0;let C=Q.contentType||"";return(A.mime||A.contentType||[]).some((K)=>K.endsWith("/*")?C.startsWith(K.slice(0,-1)):C===K)}var WB="trove+contrib:",eE="core",S6=/^(?:core|[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)+)$/,_6=/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;function w6(A){return typeof A==="string"&&S6.test(A)}function xC(A){return typeof A==="string"&&_6.test(A)}function JQ(A){return kC(A),`${A.domain}/${A.name}`}function xQ(A,Q){if(!xC(Q))throw q.invalid(`Invalid contribution name "${Q}"`);return`${WB}${JQ(A)}/${Q}`}var T6="workbench";function A8(A){return`${WB}${eE}/${T6}/${A}`}function kQ(A){if(typeof A!=="string"||!A.startsWith(WB))return null;let Q=A.slice(WB.length),B=Q.indexOf("/"),C=Q.indexOf("/",B+1);if(B<0||C<0)return null;let J=Q.slice(0,B),K=Q.slice(B+1,C),E=Q.slice(C+1);if(!J||!K||!E)return null;return{domain:J,plugin:K,name:E,pluginId:`${J}/${K}`}}function Q8(A,Q){let B=kQ(Q);return!!B&&B.pluginId===`${A.domain}/${A.name}`}function kC(A){if(!w6(A?.domain))throw q.invalid(`Plugin manifest needs a valid "domain" (got ${JSON.stringify(A?.domain)})`);if(!xC(A?.name))throw q.invalid(`Plugin manifest needs a valid "name" (got ${JSON.stringify(A?.name)})`);if(A.domain===eE)throw q.invalid('The "core" domain is reserved for built-in contributions')}var C8={command:{normalize:(A)=>({title:A.title||null,category:A.category||null,icon:A.icon||null,when:A.when||null,palette:A.palette!==!1,offline:!!A.offline})},opener:{needsEntry:!0,normalize:(A)=>({title:A.title||null,match:B8(A.match),priority:A.priority??50,when:A.when||null,offline:!!A.offline,dock:A.dock||null})},indexer:{needsEntry:!0,normalize:(A)=>({title:A.title||null,match:B8(A.match)})},statusItem:{normalize:(A)=>{let Q=A.slot==="left"?"left":"right",B=A.render||"html";if(B!=="html")throw q.invalid(`statusItem "render" must be "html" (got ${JSON.stringify(B)})`);return{slot:Q,render:B,order:A.order??0,when:A.when||null,offline:!!A.offline,command:A.command||null}}},register:{normalize:(A)=>({default:A.default??null,description:A.description||null})},keymap:{normalize:(A)=>{if(!A.path||typeof A.path!=="string")throw q.invalid('keymap contribution needs a "path" to a JSON file in the package');return{path:A.path}}}},_0=Object.keys(C8);function FQ(A){let Q=A?.contributes;if(Q==null)return[];if(typeof Q!=="object"||Array.isArray(Q))throw q.invalid('manifest "contributes" must be a map of name -> contribution');let B=[];for(let[C,J]of Object.entries(Q)){if(!J||typeof J!=="object")throw q.invalid(`Contribution "${C}" must be an object`);if(!xC(C))throw q.invalid(`Invalid contribution name "${C}"`);let K=C8[J.type];if(!K)throw q.invalid(`Contribution "${C}" has unknown type ${JSON.stringify(J.type)} (expected one of ${_0.join(", ")})`);let E=J.entry||A.entry;if(K.needsEntry&&!E)throw q.invalid(`Contribution "${C}" (${J.type}) needs an "entry" module`);B.push({name:C,uri:xQ(A,C),pluginId:JQ(A),type:J.type,...K.normalize(J),...K.needsEntry?{entry:E}:{}})}return B}function x6(A,Q){return FQ(A).filter((B)=>B.type===Q)}function w0(A){return x6(A,"indexer").map((Q)=>({id:Q.uri,name:Q.name,title:Q.title||Q.name,match:Q.match,entry:Q.entry}))}function J8(A){let Q;try{Q=JSON.parse(A)}catch(C){throw q.invalid("Keymap file is not valid JSON",{cause:C})}let B=Array.isArray(Q)?Q:Array.isArray(Q?.bindings)?Q.bindings:null;if(!B)throw q.invalid("Keymap file must be a JSON array of bindings");return B.filter((C)=>C&&typeof C.key==="string"&&typeof C.command==="string").map((C)=>({key:C.key,command:C.command,when:typeof C.when==="string"?C.when:null,args:Array.isArray(C.args)?C.args:void 0}))}function B8(A){if(!A||typeof A!=="object"||Array.isArray(A))return{};let Q=(K)=>K==null?void 0:(Array.isArray(K)?K:[K]).filter((E)=>typeof E==="string"),B={},C=Q(A.ext),J=Q(A.mime??A.contentType);if(C)B.ext=C;if(J)B.mime=J;if(typeof A.match==="function")B.match=A.match;return B}var k6=[..._0,"view"];function gC(A){return String(A).startsWith(WB)?A:A8(A)}class T0{constructor(){this.items=new Map,this.cell=c([])}#A(){this.cell.setValue([...this.items.values()])}register(A,Q){let B=Q?.type;if(!k6.includes(B))throw Error(`Unknown contribution type "${B}" for ${A}`);let C=gC(A),J=kQ(C);if(!J)throw Error(`Not a contribution URI: ${C}`);let K=Q.pluginId??(J.domain==="core"?null:J.pluginId),E={...Q,uri:C,type:B,id:J.domain==="core"?J.name:C,name:J.name,pluginId:K};return this.items.set(C,E),this.#A(),()=>this.unregister(C)}update(A,Q){let B=gC(A),C=this.items.get(B);if(!C)return!1;return this.items.set(B,{...C,...Q}),this.#A(),!0}unregister(A){if(this.items.delete(gC(A)))this.#A()}get(A){return A?this.items.get(gC(A))||null:null}all(){return[...this.items.values()]}ofType(A){return this.all().filter((Q)=>Q.type===A)}observe(){return this.cell}openersFor(A){return this.ofType("opener").filter((Q)=>TC(Q.match,A)).sort((Q,B)=>(B.priority??0)-(Q.priority??0))}keybindings(){return this.ofType("keymap").flatMap((A)=>(A.bindings||[]).map((Q)=>({...Q,keymap:A.uri,pluginId:A.pluginId})))}}var x0=new Map;function g6(A){if(!A)return()=>!0;if(x0.has(A))return x0.get(A);let Q;try{Q=new E8(A).parseExpression()}catch(B){console.warn(`Invalid when clause: "${A}" — ${B.message}`),Q=()=>!1}return x0.set(A,Q),Q}function K8(A,Q){return g6(A)(Q||{})}var yC=/\s*(=~|==|!=|>=|<=|&&|\|\||[()!<>]|trove\+contrib:[A-Za-z0-9_./-]+|\/(?:\\.|[^/])*\/[a-z]*|'(?:\\.|[^'])*'|"(?:\\.|[^"])*"|[A-Za-z0-9_.:-]+)/y;class E8{constructor(A){this.src=A,this.tokens=this.#A(A),this.pos=0}#A(A){let Q=[],B=0;yC.lastIndex=0;while(B<A.length){yC.lastIndex=B;let C=yC.exec(A);if(!C||C.index==null){if(!A.slice(B).trim())break;throw Error(`Unexpected "${A.slice(B)}"`)}Q.push(C[1]),B=yC.lastIndex}return Q}#Q(){return this.tokens[this.pos]}#B(){return this.tokens[this.pos++]}#C(A){if(this.#Q()!==A)throw Error(`Expected "${A}"`);this.pos++}parseExpression(){let A=this.#J();if(this.pos!==this.tokens.length)throw Error(`Trailing "${this.#Q()}"`);return A}#J(){let A=this.#K();while(this.#Q()==="||"){this.#B();let Q=this.#K(),B=A;A=(C)=>B(C)||Q(C)}return A}#K(){let A=this.#E();while(this.#Q()==="&&"){this.#B();let Q=this.#E(),B=A;A=(C)=>B(C)&&Q(C)}return A}#E(){if(this.#Q()==="!"){this.#B();let A=this.#E();return(Q)=>!A(Q)}return this.#Y()}#Y(){let A=this.#L(),Q=this.#Q();if(["==","!=",">=","<=",">","<","=~"].includes(Q)){if(this.#B(),Q==="=~"){let C=this.#B(),J=y6(C);return(K)=>J.test(String(A(K)??""))}let B=this.#L();return(C)=>b6(Q,A(C),B(C))}return(B)=>h6(A(B))}#L(){let A=this.#B();if(A===void 0)throw Error("Unexpected end");if(A==="("){let Q=this.#J();return this.#C(")"),Q}if(A==="true")return()=>!0;if(A==="false")return()=>!1;if(/^-?\d+(\.\d+)?$/.test(A)){let Q=Number(A);return()=>Q}if(A[0]==="'"||A[0]==='"'){let Q=A.slice(1,-1).replace(/\\(.)/g,"$1");return()=>Q}return(Q)=>Q[A]}}function y6(A){let Q=/^\/((?:\\.|[^/])*)\/([a-z]*)$/.exec(A);if(!Q)throw Error(`Bad regex ${A}`);return new RegExp(Q[1],Q[2])}function h6(A){return!(A===void 0||A===null||A===!1||A===""||A===0)}function b6(A,Q,B){switch(A){case"==":return Q==B;case"!=":return Q!=B;case">":return Q>B;case"<":return Q<B;case">=":return Q>=B;case"<=":return Q<=B}return!1}var v6=(A)=>({onDirty:()=>()=>{},getValue:()=>A});class k0{#A=new Map;#Q=new Map;#B=c({});constructor(A={}){let Q={platform:Y8(),isMac:/mac/i.test(Y8()),...A};for(let[B,C]of Object.entries(Q))this.register(B,v6(C))}register(A,Q){if(this.#A.has(A))throw Error(`Context key "${A}" already has an owner`);return this.#A.set(A,Q),this.#Q.set(A,Q.onDirty(()=>this.#C(A))),this.#C(A),()=>this.unregister(A)}unregister(A){let Q=this.#Q.get(A);if(!Q)return;Q(),this.#Q.delete(A),this.#A.delete(A),this.#C(A)}#C(){this.#J()}own(A,Q=void 0){let B=c(Q),C=this.register(A,B);return{set:(J)=>B.setValue(J),dispose:C}}#J(){let A={};for(let[Q,B]of this.#A)A[Q]=B.getValue();this.#B.setValue(A)}snapshot(){return this.#B.getValue()}get(A){return this.#A.get(A)?.getValue()}observe(){return this.#B}evaluate(A){return K8(A,this.snapshot())}}function Y8(){return typeof navigator<"u"?navigator.platform||navigator.userAgent||"":""}var lA=(A,Q)=>A.dispatch(Q).next(["complete","error","abort"]);class g0{constructor(A,Q,B){this.contributions=A,this.context=Q,this.notifications=B,this.handlers=new Map,this.dispatch=()=>{throw Error("CommandService has no dispatcher yet — see createApp")}}register(A,Q){let B=typeof A==="string"?{id:A,actions:Q}:A;if(B.actions)this.handlers.set(B.id,B.actions);let C=this.contributions.register(B.id,{type:"command",title:B.title??B.id,category:B.category,icon:B.icon,when:B.when,palette:B.palette??!0,pluginId:B.pluginId,offline:B.offline});return()=>{this.handlers.delete(B.id),C()}}isEnabled(A){let Q=this.contributions.get(A);if(Q?.when&&!this.context.evaluate(Q.when))return!1;return this.isAvailable(Q)}isAvailable(A){if(!A)return!0;return this.availability?this.availability(A):!0}async execute(A,...Q){let B=this.handlers.get(A);if(!B){this.notifications.error(`Command not found: ${A}`);return}let C=this.contributions.get(A);if(!this.isAvailable(C)){this.notifications.warn(`“${C?.title||A}” isn’t available right now.`);return}if(!this.isEnabled(A))return;try{let J=B(...Q);if(!J)return;for(let K of[].concat(J))if((await lA(this,K))?.type!=="complete")break}catch(J){throw console.error(`Command ${A} failed`,J),this.notifications.error(J?.message||`Command failed: ${A}`),J}}paletteCommands(){return this.contributions.ofType("command").filter((A)=>A.palette!==!1&&(!A.when||this.context.evaluate(A.when))).sort((A,Q)=>(A.category||"").localeCompare(Q.category||"")||A.title.localeCompare(Q.title))}}function y0(A){let Q=A.trim().toLowerCase().split("+").map((K)=>K.trim()),B=new Set,C="";for(let K of Q)if(["ctrl","control"].includes(K))B.add("ctrl");else if(["cmd","meta","super","win"].includes(K))B.add("meta");else if(K==="alt"||K==="option")B.add("alt");else if(K==="shift")B.add("shift");else if(["ctrlcmd","mod"].includes(K))B.add(L8()?"meta":"ctrl");else C=K;return[...["ctrl","meta","alt","shift"].filter((K)=>B.has(K)),C].filter(Boolean).join("+")}function h0(A){let Q=[];if(A.ctrlKey)Q.push("ctrl");if(A.metaKey)Q.push("meta");if(A.altKey)Q.push("alt");if(A.shiftKey)Q.push("shift");let B=A.key.toLowerCase();return B={" ":"space",escape:"escape",enter:"enter",arrowup:"up",arrowdown:"down",arrowleft:"left",arrowright:"right"}[B]||B,[...Q.filter((J)=>B!==J),B].join("+")}class UB{constructor(A,Q,B,C=null){this.contributions=A,this.commands=Q,this.context=B,this.settings=C,this.chordPrefix=null,this.chordTimer=null,this._onKeyDown=this.#B.bind(this)}install(A=window){return A.addEventListener("keydown",this._onKeyDown),()=>A.removeEventListener("keydown",this._onKeyDown)}overrides(){return this.settings?.get("keybindings.overrides")||{}}static bindingId(A){return`${A.command}\x00${y0(A.defaultKey||A.key)}`}rebind(A,Q){if(!this.settings)return;let B=typeof A==="string"?this.#A(A):UB.bindingId(A);if(!B)return;let C={...this.overrides()};if(Q)C[B]=Q;else delete C[B];this.settings.set("keybindings.overrides",C)}#A(A){let Q=this.contributions.keybindings().find((B)=>B?.command===A&&B.key);return Q?UB.bindingId({...Q,defaultKey:Q.key}):null}resolved(){let A=this.overrides();return this.contributions.keybindings().filter((Q)=>Q?.key&&Q.command).map((Q)=>{let B=y0(Q.key),C=UB.bindingId({command:Q.command,defaultKey:B});return{...Q,defaultKey:B,bindingId:C,key:y0(A[C]||Q.key)}})}#Q(A){let Q=this.context.snapshot(),B=this.resolved();for(let C=B.length-1;C>=0;C--){let J=B[C];if(J.key!==A)continue;if(J.when&&!this.context.evaluate(J.when))continue;return J}return null}#B(A){if(A.defaultPrevented)return;let Q=h0(A),B=A.ctrlKey||A.metaKey||A.altKey;if(f6(A.target)&&!B&&A.key!=="Escape"){this.#C();return}let J=this.chordPrefix?`${this.chordPrefix} ${Q}`:Q,K=this.#Q(J);if(K){A.preventDefault(),this.#C(),this.commands.execute(K.command,...K.args||[]);return}if(!this.chordPrefix&&this.resolved().some((E)=>E.key.startsWith(Q+" "))){A.preventDefault(),this.chordPrefix=Q,this.chordTimer=setTimeout(()=>this.#C(),1500);return}this.#C()}#C(){if(this.chordPrefix=null,this.chordTimer)clearTimeout(this.chordTimer);this.chordTimer=null}labelFor(A){let Q=this.resolved().find((B)=>B.command===A);return Q?b0(Q.key):null}}function f6(A){if(!A)return!1;let Q=A.tagName;return Q==="INPUT"||Q==="TEXTAREA"||Q==="SELECT"||A.isContentEditable}function L8(){return typeof navigator<"u"&&/mac/i.test(navigator.platform||navigator.userAgent||"")}function b0(A){let Q=L8(),B=Q?{ctrl:"⌃",meta:"⌘",alt:"⌥",shift:"⇧",enter:"↵",escape:"esc",up:"↑",down:"↓",left:"←",right:"→",space:"␣"}:{ctrl:"Ctrl",meta:"Win",alt:"Alt",shift:"Shift",enter:"Enter",escape:"Esc",up:"↑",down:"↓",left:"←",right:"→",space:"Space"};return A.split(" ").map((C)=>C.split("+").map((J)=>B[J]||(J.length===1?J.toUpperCase():J[0].toUpperCase()+J.slice(1))).join(Q?"":"+")).join(" ")}var H8="trove.settings";class v0{constructor(){this.schema=new Map,this.values=u6(),this.cell=c(this.effective())}register(A){for(let Q of[].concat(A))this.schema.set(Q.key,Q);return this.cell.setValue(this.effective()),()=>{for(let Q of[].concat(A))this.schema.delete(Q.key);this.cell.setValue(this.effective())}}get(A){if(A in this.values)return this.values[A];return this.schema.get(A)?.default}set(A,Q){let B=this.schema.get(A);if(B&&Q===B.default)delete this.values[A];else this.values[A]=Q;X8(this.values),this.cell.setValue(this.effective())}reset(A){delete this.values[A],X8(this.values),this.cell.setValue(this.effective())}effective(){let A={};for(let[Q,B]of this.schema)A[Q]=Q in this.values?this.values[Q]:B.default;for(let[Q,B]of Object.entries(this.values))if(!(Q in A))A[Q]=B;return A}observe(){return this.cell}grouped(){let A=new Map;for(let Q of[...this.schema.values()].sort((B,C)=>(B.order??0)-(C.order??0))){if(Q.hidden)continue;let B=Q.category||"General";if(!A.has(B))A.set(B,[]);A.get(B).push({...Q,value:this.get(Q.key)})}return[...A.entries()].map(([Q,B])=>({category:Q,items:B}))}scopedFor(A){let Q=`${A}.`;return{register:(B)=>this.register([].concat(B).map((C)=>({...C,key:Q+C.key,category:C.category||A}))),get:(B)=>this.get(Q+B),set:(B,C)=>this.set(Q+B,C)}}}function u6(){try{return JSON.parse(localStorage.getItem(H8))||{}}catch{return{}}}function X8(A){try{localStorage.setItem(H8,JSON.stringify(A))}catch{}}var m6=0;class f0{constructor(){this.items=[],this.cell=c([])}observe(){return this.cell}#A(A,Q,B={}){let C={id:++m6,level:A,message:Q,actions:B.actions||null,createdAt:Date.now(),sticky:B.sticky||A==="error"};if(this.items=[...this.items,C],this.cell.setValue(this.items),!C.sticky)setTimeout(()=>this.dismiss(C.id),B.timeout??4000);return C.id}info(A,Q){return this.#A("info",A,Q)}success(A,Q){return this.#A("success",A,Q)}warn(A,Q){return this.#A("warn",A,Q)}error(A,Q){return this.#A("error",A,Q)}update(A,Q){this.items=this.items.map((B)=>B.id===A?{...B,...Q}:B),this.cell.setValue(this.items)}dismiss(A){this.items=this.items.filter((Q)=>Q.id!==A),this.cell.setValue(this.items)}}var p6={retries:4,minDelayMs:250,maxDelayMs:8000,factor:2,jitter:!0};function l6(A,Q){return new Promise((B,C)=>{if(Q?.aborted)return C(q.aborted());let J=(Y)=>(L)=>{clearTimeout(K),Q?.removeEventListener("abort",E),Y(L)},K=setTimeout(()=>J(B)(),A),E=()=>J(C)(q.aborted());Q?.addEventListener("abort",E,{once:!0})})}async function IB(A,Q={}){let B={...p6,...Q},C=B.shouldRetry??iE,J=0;for(;;){if(B.signal?.aborted)throw q.aborted();try{return await A(J)}catch(K){let E=fB(K);if(!(J<B.retries&&C(E)&&E.code!=="aborted"))throw E;let L=Math.min(B.maxDelayMs,B.minDelayMs*B.factor**J),X=B.jitter?Math.random()*L:L;B.onRetry?.({attempt:J+1,delayMs:X,error:E}),await l6(X,B.signal),J++}}}class u0{constructor({baseUrl:A="",fetch:Q=globalThis.fetch.bind(globalThis),token:B=null}={}){this.baseUrl=A.replace(/\/$/,""),this._fetch=Q,this._token=B}token(){return(typeof this._token==="function"?this._token():this._token)||null}authHeaders(){let A=this.token();return A?{authorization:`Bearer ${A}`}:{}}async request(A,Q,{body:B,query:C,signal:J,raw:K}={}){let E=this.baseUrl+Q+(C?"?"+new URLSearchParams(C):"");return IB(async()=>{let Y=await this._fetch(E,{method:A,headers:{...this.authHeaders(),...B?{"content-type":"application/json"}:{}},body:B?JSON.stringify(B):void 0,signal:J});if(Y.status===429||Y.status>=500){if(!K){let H;try{let G=await Y.text();H=(G?JSON.parse(G):null)?.error}catch{}if(H&&H.retryable===!1)throw new q(H.code,H.message,{retryable:!1,details:H.details});throw q.transient(H?.message||`Server ${Y.status}`)}throw q.transient(`Server ${Y.status}`)}if(K)return Y;let L=await Y.text(),X=L?JSON.parse(L):null;if(!Y.ok){let H=X?.error||{code:"internal",message:`Request failed (${Y.status})`};throw new q(H.code,H.message,{retryable:H.retryable,details:H.details})}return X},{signal:J,retries:3})}capabilities(){return this.request("GET","/api/capabilities")}async reachable(A=4000){try{let Q=AbortSignal.timeout?AbortSignal.timeout(A):void 0;return(await this._fetch(this.baseUrl+"/api/capabilities",{method:"GET",signal:Q,headers:this.authHeaders()})).ok}catch{return!1}}list(A,Q={}){return this.request("GET",`${this.#A(A)}/items`,{query:Q})}stat(A,{collection:Q,...B}={}){let C=String(A).startsWith("trove:")?"uri":"id",J=Q?`${this.#A(Q)}/items/resolve`:"/api/items/resolve";return this.request("GET",J,{query:{[C]:A,...B}})}#A(A){if(!A)throw Error("This call is scoped to a collection — pass one");return`/api/collections/${encodeURIComponent(A)}`}backlinks(A,Q={}){return this.request("GET","/api/items/backlinks",{query:{id:A,...Q}})}rename(A,Q){return this.request("POST","/api/items/rename",{body:{id:A,newName:Q}})}remove(A){return this.request("POST","/api/items/delete",{body:{id:A}})}trash(A){return this.request("GET",`${this.#A(A)}/trash`)}restore(A){return this.request("POST","/api/trash/restore",{body:{id:A}})}purgeTrash({id:A,collection:Q}={}){return A?this.request("POST","/api/trash/purge",{body:{id:A}}):this.request("POST",`${this.#A(Q)}/trash/purge`)}search(A,{collection:Q,...B}={}){let C=Q?`${this.#A(Q)}/search`:"/api/search";return this.request("GET",C,{query:{q:A,...B}})}query(A,{collection:Q,...B}={}){let C=Q?`${this.#A(Q)}/query`:"/api/query";return this.request("POST",C,{body:{q:A,...B}})}tagSearch(A,Q,{collection:B,...C}={}){let J=B?`${this.#A(B)}/tags/search`:"/api/tags/search";return this.request("POST",J,{body:{filters:A,q:Q,...C}})}indexers(){return this.request("GET","/api/indexers")}tasks(){return this.request("GET","/api/tasks")}cancelTask(A){return this.request("POST",`/api/tasks/${encodeURIComponent(A)}/cancel`)}dismissTask(A){return this.request("DELETE",`/api/tasks/${encodeURIComponent(A)}`)}issues(){return this.request("GET","/api/issues")}retryIssue(A){return this.request("POST",`/api/issues/${encodeURIComponent(A)}/retry`)}dismissIssue(A){return this.request("DELETE",`/api/issues/${encodeURIComponent(A)}`)}reindex(){return this.request("POST","/api/reindex")}scanCollection(A){return this.request("POST",`/api/collections/${encodeURIComponent(A)}/scan`)}checkStorage(){return this.request("POST","/api/diagnostics/storage")}async installPlugin(A,Q){let B=Q&&Q.length?"?grants="+encodeURIComponent(Q.join(",")):"",C=await this._fetch(this.baseUrl+"/api/plugins/install"+B,{method:"POST",body:A,headers:this.authHeaders()}),J=await C.json().catch(()=>null);if(!C.ok){let K=J?.error||{code:"internal",message:`Install failed (${C.status})`};throw new q(K.code,K.message,{details:K.details})}return J.install}installedPlugins(){return this.request("GET","/api/plugins/installed")}async pluginPackage(A){let Q=await this._fetch(`${this.baseUrl}/api/plugins/${encodeURIComponent(A)}/package`,{headers:this.authHeaders()});if(!Q.ok)throw new q("not_found",`Package for "${A}" not found`);return new Uint8Array(await Q.arrayBuffer())}uninstallPluginServer(A){return this.request("DELETE",`/api/plugins/${encodeURIComponent(A)}/install`)}pushIndex(A,Q,B){return this.request("POST",`/api/index/${encodeURIComponent(A)}`,{body:{nodeId:Q,...B}})}me(){return this.request("GET","/api/me")}collections(){return this.request("GET","/api/collections")}createCollection(A){return this.request("POST","/api/collections",{body:A})}updateCollection(A,Q){return this.request("PATCH",`/api/collections/${encodeURIComponent(A)}`,{body:Q})}rotationEstimate(A){return this.request("GET",`/api/collections/${encodeURIComponent(A)}/rotate/estimate`)}collectionGrants(A){return this.request("GET",`/api/collections/${encodeURIComponent(A)}/grants`)}setCollectionGrant(A,Q){return this.request("POST",`/api/collections/${encodeURIComponent(A)}/grants`,{body:Q})}rotationState(A){return this.request("GET",`/api/collections/${encodeURIComponent(A)}/rotate`)}beginRotation(A){return this.request("POST",`/api/collections/${encodeURIComponent(A)}/rotate`)}cancelRotation(A){return this.request("DELETE",`/api/collections/${encodeURIComponent(A)}/rotate`)}sidecar(A){return this.request("GET",`/api/items/${encodeURIComponent(A)}/sidecar`)}addComment(A,{body:Q,parentId:B,mentions:C}={}){return this.request("POST",`/api/items/${encodeURIComponent(A)}/comments`,{body:{body:Q,parentId:B,mentions:C}})}editComment(A,Q,B){return this.request("POST",`/api/items/${encodeURIComponent(A)}/comments/${encodeURIComponent(Q)}/edit`,{body:{body:B}})}deleteComment(A,Q){return this.request("DELETE",`/api/items/${encodeURIComponent(A)}/comments/${encodeURIComponent(Q)}`)}reactComment(A,Q,B,C){return this.request("POST",`/api/items/${encodeURIComponent(A)}/comments/${encodeURIComponent(Q)}/react`,{body:{emoji:B,on:C}})}setTag(A,Q,B){return this.request("POST",`/api/items/${encodeURIComponent(A)}/tags`,{body:{name:Q,value:B}})}removeTag(A,Q){return this.request("DELETE",`/api/items/${encodeURIComponent(A)}/tags/${encodeURIComponent(Q)}`)}notifications(){return this.request("GET","/api/notifications")}markNotificationsRead(A){return this.request("POST","/api/notifications/read",{body:{ids:A}})}vapidKey(){return this.request("GET","/api/push/vapid")}apiKeys(){return this.request("GET","/api/keys")}mintApiKey({name:A,scopes:Q,expiresAt:B=null}){return this.request("POST","/api/keys",{body:{name:A,scopes:Q,expiresAt:B}})}revokeApiKey(A){return this.request("DELETE",`/api/keys/${encodeURIComponent(A)}`)}subscribePush(A){return this.request("POST","/api/push/subscribe",{body:{subscription:A}})}downloadUrl(A,{attachment:Q}={}){return`${this.baseUrl}/api/items/download?id=${encodeURIComponent(A)}${Q?"&disposition=attachment":""}`}mintUrls(A,Q="media"){return this.request("POST","/api/items/urls",{body:{ids:A,op:Q}})}async download(A,Q,{attachment:B=!0}={}){let C=this.downloadUrl(A,{attachment:B});if(!this.token())return{url:C,streamed:!0};let J=await this._fetch(C,{headers:this.authHeaders()});if(!J.ok)throw new q("internal",`Download failed (${J.status})`);return{url:URL.createObjectURL(await J.blob()),streamed:!1,revoke:!0}}async readBytes(A,{signal:Q}={}){let B=await this._fetch(this.downloadUrl(A),{signal:Q,headers:this.authHeaders()});if(!B.ok)throw new q("internal",`Download failed (${B.status})`);return new Uint8Array(await B.arrayBuffer())}async readText(A,Q){return new TextDecoder().decode(await this.readBytes(A,Q))}async readRange(A,{start:Q=0,end:B,signal:C}={}){let J=B==null?`bytes=${Q}-`:`bytes=${Q}-${B-1}`,K=await this._fetch(this.downloadUrl(A),{signal:C,headers:{...this.authHeaders(),range:J}});if(K.status===416)return{bytes:new Uint8Array(0),etag:K.headers.get("etag"),total:0};if(!K.ok&&K.status!==206)throw new q("internal",`Read failed (${K.status})`);let E=new Uint8Array(await K.arrayBuffer()),Y=Number(/\/(\d+)$/.exec(K.headers.get("content-range")||"")?.[1])||(K.status===200?E.length:null);return{bytes:E,etag:K.headers.get("etag"),total:Y}}async readTextCapped(A,{maxBytes:Q=524288,size:B=null,signal:C}={}){let J=B==null||B>Q,K=await this._fetch(this.downloadUrl(A),{signal:C,headers:{...this.authHeaders(),...J?{range:`bytes=0-${Q-1}`}:{}}});if(K.status===416)return{text:"",truncated:!1,total:0};if(!K.ok&&K.status!==206)throw new q("internal",`Download failed (${K.status})`);let E=new Uint8Array(await K.arrayBuffer()),Y=Number(/\/(\d+)$/.exec(K.headers.get("content-range")||"")?.[1])||null,L=E.length>=Q&&(Y==null||Y>E.length),X=new TextDecoder("utf-8",{fatal:!1}).decode(E);if(L){let H=X.lastIndexOf(`
|
|
4
|
+
`);if(H>0)X=X.slice(0,H)}return{text:X,truncated:L,total:Y}}async upload(A,Q){let B=Q.name||A.name||"untitled",C=A.size,J=(k)=>IB(k,{signal:Q.signal,retries:4,onRetry:({attempt:v,delayMs:O,error:g})=>Q.onRetry?.({attempt:v,delayMs:O,message:g.message})}),K=await J(()=>this.request("POST",`${this.#A(Q.collection)}/uploads`,{body:{name:B,size:C,contentType:A.type||void 0},signal:Q.signal}));if(K.uploadId)Q.onStart?.(K.uploadId);let E=new G8(C,Q.onProgress),Y=K.transfer||{},L=K.endpoints?.complete||`/api/uploads/${K.uploadId}/complete`;if(K.strategy==="single"){let k=A;return await J(()=>hC(Y.url||K.url,k,{headers:Y.requiredHeaders,signal:Q.signal,onProgress:(O)=>E.set("single",O)})),(await J(()=>this.request("POST",L,{body:{},signal:Q.signal}))).node}if(K.strategy==="direct-single"){let k=A;return await J(()=>hC(this.baseUrl+this.#Q(K,1),k,{headers:{...this.authHeaders(),...Y.authHeaders},signal:Q.signal,onProgress:(O)=>E.set(1,O)})),(await J(()=>this.request("POST",L,{body:{},signal:Q.signal}))).node}let X=K.partSize,H=K.partCount??Math.ceil(C/X),G=new Set;try{let k=K.endpoints?.status||`/api/uploads/${K.uploadId}/status`,v=await this.request("GET",k,{signal:Q.signal});G=new Set(v.received||[])}catch{}let D=[],U=[];for(let k=1;k<=H;k++){let v=(k-1)*X,O=A.slice(v,Math.min(v+X,C));U.push({n:k,blob:O})}let F=Array(H),R=Math.min(Q.concurrency??4,U.length),V=0,w=new AbortController,m=()=>w.abort();if(Q.signal)if(Q.signal.aborted)w.abort();else Q.signal.addEventListener("abort",m,{once:!0});let b=async()=>{while(V<U.length){if(w.signal.aborted)return;let{n:k,blob:v}=U[V++];if(G.has(k)){E.set(k,v.size);continue}let O=await IB(()=>this.#B(K,k,v,{signal:w.signal,onProgress:(g)=>E.set(k,g)}),{signal:w.signal,retries:4,onRetry:({attempt:g,delayMs:e,error:AA})=>Q.onRetry?.({attempt:g,delayMs:e,part:k,message:AA.message})});F[k-1]={partNumber:k,etag:O}}};try{await Promise.all(Array.from({length:R},b))}catch(k){throw w.abort(),k}finally{Q.signal?.removeEventListener("abort",m)}let z=F.filter(Boolean);return(await J(()=>this.request("POST",L,{body:{parts:z},signal:Q.signal}))).node}#Q(A,Q){return(A.transfer?.partUrl||`/api/uploads/${A.uploadId}/parts/{partNumber}`).replace("{partNumber}",String(Q))}async#B(A,Q,B,{signal:C,onProgress:J}){let K=A.transfer||{};if(A.strategy==="presign"){let L=(K.parts||A.parts)?.find((D)=>D.partNumber===Q)?.url;if(!L){let D=A.endpoints?.sign||`/api/uploads/${A.uploadId}/parts/{partNumber}/sign`;L=(await this.request("POST",D.replace("{partNumber}",String(Q)),{signal:C})).url}let H=(await hC(L,B,{signal:C,onProgress:J,wantEtag:!0})).etag,G=A.endpoints?.report||`/api/uploads/${A.uploadId}/parts/{partNumber}/report`;return await this.request("POST",G.replace("{partNumber}",String(Q)),{body:{etag:H},signal:C}),H}return(await hC(this.baseUrl+this.#Q(A,Q),B,{headers:{...this.authHeaders(),...K.authHeaders},signal:C,onProgress:J,wantJson:!0})).json?.etag}async abortUpload(A){return this.request("DELETE",`/api/uploads/${A}`)}}class G8{constructor(A,Q){this.total=A,this.cb=Q,this.parts=new Map}set(A,Q){let B=this.parts.get(A)||0;if(Q<B)return;if(this.parts.set(A,Q),!this.cb)return;let C=0;for(let K of this.parts.values())C+=K;let J=Math.min(C,this.total);this.cb({loaded:J,total:this.total,ratio:this.total?J/this.total:1})}}function hC(A,Q,{signal:B,onProgress:C,wantEtag:J,wantJson:K,headers:E}={}){return new Promise((Y,L)=>{let X=new XMLHttpRequest;X.open("PUT",A,!0);for(let[H,G]of Object.entries(E||{}))try{X.setRequestHeader(H,G)}catch{}if(B){if(B.aborted)return X.abort(),L(q.aborted());B.addEventListener("abort",()=>X.abort(),{once:!0})}X.upload.onprogress=(H)=>C?.(H.loaded),X.onload=()=>{if(X.status>=200&&X.status<300){let H={status:X.status};if(J)H.etag=X.getResponseHeader("ETag")||X.getResponseHeader("etag");if(K)try{H.json=JSON.parse(X.responseText)}catch{}Y(H)}else if(X.status===429||X.status>=500)L(q.transient(`Upload part failed (${X.status})`));else L(new q("internal",`Upload failed (${X.status})`))},X.onerror=()=>L(q.transient("Network error during upload")),X.onabort=()=>L(q.aborted()),X.send(Q)})}var CA=Uint8Array,gA=Uint16Array,r0=Int32Array,bC=new CA([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]),vC=new CA([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]),d0=new CA([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),F8=function(A,Q){var B=new gA(31);for(var C=0;C<31;++C)B[C]=Q+=1<<A[C-1];var J=new r0(B[30]);for(var C=1;C<30;++C)for(var K=B[C];K<B[C+1];++K)J[K]=K-B[C]<<5|C;return{b:B,r:J}},R8=F8(bC,2),M8=R8.b,a0=R8.r;M8[28]=258,a0[258]=28;var V8=F8(vC,0),c6=V8.b,$8=V8.r,n0=new gA(32768);for(u=0;u<32768;++u)KQ=(u&43690)>>1|(u&21845)<<1,KQ=(KQ&52428)>>2|(KQ&13107)<<2,KQ=(KQ&61680)>>4|(KQ&3855)<<4,n0[u]=((KQ&65280)>>8|(KQ&255)<<8)>>1;var KQ,u,YQ=function(A,Q,B){var C=A.length,J=0,K=new gA(Q);for(;J<C;++J)if(A[J])++K[A[J]-1];var E=new gA(Q);for(J=1;J<Q;++J)E[J]=E[J-1]+K[J-1]<<1;var Y;if(B){Y=new gA(1<<Q);var L=15-Q;for(J=0;J<C;++J)if(A[J]){var X=J<<4|A[J],H=Q-A[J],G=E[A[J]-1]++<<H;for(var D=G|(1<<H)-1;G<=D;++G)Y[n0[G]>>L]=X}}else{Y=new gA(C);for(J=0;J<C;++J)if(A[J])Y[J]=n0[E[A[J]-1]++]>>15-A[J]}return Y},gQ=new CA(288);for(u=0;u<144;++u)gQ[u]=8;var u;for(u=144;u<256;++u)gQ[u]=9;var u;for(u=256;u<280;++u)gQ[u]=7;var u;for(u=280;u<288;++u)gQ[u]=8;var u,pB=new CA(32);for(u=0;u<32;++u)pB[u]=5;var u,d6=YQ(gQ,9,0),a6=YQ(gQ,9,1),n6=YQ(pB,5,0),s6=YQ(pB,5,1),m0=function(A){var Q=A[0];for(var B=1;B<A.length;++B)if(A[B]>Q)Q=A[B];return Q},rA=function(A,Q,B){var C=Q/8|0;return(A[C]|A[C+1]<<8)>>(Q&7)&B},p0=function(A,Q){var B=Q/8|0;return(A[B]|A[B+1]<<8|A[B+2]<<16)>>(Q&7)},t0=function(A){return(A+7)/8|0},lB=function(A,Q,B){if(Q==null||Q<0)Q=0;if(B==null||B>A.length)B=A.length;return new CA(A.subarray(Q,B))};var o6=["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"],zA=function(A,Q,B){var C=Error(Q||o6[A]);if(C.code=A,Error.captureStackTrace)Error.captureStackTrace(C,zA);if(!B)throw C;return C},i6=function(A,Q,B,C){var J=A.length,K=C?C.length:0;if(!J||Q.f&&!Q.l)return B||new CA(0);var E=!B,Y=E||Q.i!=2,L=Q.i;if(E)B=new CA(J*3);var X=function(SQ){var _Q=B.length;if(SQ>_Q){var wQ=new CA(Math.max(_Q*2,SQ));wQ.set(B),B=wQ}},H=Q.f||0,G=Q.p||0,D=Q.b||0,U=Q.l,F=Q.d,R=Q.m,V=Q.n,w=J*8;do{if(!U){H=rA(A,G,1);var m=rA(A,G+1,3);if(G+=3,!m){var b=t0(G)+4,z=A[b-4]|A[b-3]<<8,p=b+z;if(p>J){if(L)zA(0);break}if(Y)X(D+z);B.set(A.subarray(b,p),D),Q.b=D+=z,Q.p=G=p*8,Q.f=H;continue}else if(m==1)U=a6,F=s6,R=9,V=5;else if(m==2){var k=rA(A,G,31)+257,v=rA(A,G+10,15)+4,O=k+rA(A,G+5,31)+1;G+=14;var g=new CA(O),e=new CA(19);for(var AA=0;AA<v;++AA)e[d0[AA]]=rA(A,G+AA*3,7);G+=v*3;var QA=m0(e),QQ=(1<<QA)-1,IA=YQ(e,QA,1);for(var AA=0;AA<O;){var FA=IA[rA(A,G,QQ)];G+=FA&15;var b=FA>>4;if(b<16)g[AA++]=b;else{var LA=0,t=0;if(b==16)t=3+rA(A,G,3),G+=2,LA=g[AA-1];else if(b==17)t=3+rA(A,G,7),G+=3;else if(b==18)t=11+rA(A,G,127),G+=7;while(t--)g[AA++]=LA}}var WA=g.subarray(0,k),XA=g.subarray(k);R=m0(WA),V=m0(XA),U=YQ(WA,R,1),F=YQ(XA,V,1)}else zA(1);if(G>w){if(L)zA(0);break}}if(Y)X(D+131072);var aQ=(1<<R)-1,OA=(1<<V)-1,iA=G;for(;;iA=G){var LA=U[p0(A,G)&aQ],jA=LA>>4;if(G+=LA&15,G>w){if(L)zA(0);break}if(!LA)zA(2);if(jA<256)B[D++]=jA;else if(jA==256){iA=G,U=null;break}else{var RA=jA-254;if(jA>264){var AA=jA-257,r=bC[AA];RA=rA(A,G,(1<<r)-1)+M8[AA],G+=r}var pA=F[p0(A,G)&OA],PQ=pA>>4;if(!pA)zA(3);G+=pA&15;var XA=c6[PQ];if(PQ>3){var r=vC[PQ];XA+=p0(A,G)&(1<<r)-1,G+=r}if(G>w){if(L)zA(0);break}if(Y)X(D+131072);var OQ=D+RA;if(D<XA){var LB=K-XA,jQ=Math.min(XA,OQ);if(LB+D<0)zA(3);for(;D<jQ;++D)B[D]=C[LB+D]}for(;D<OQ;++D)B[D]=B[D-XA]}}if(Q.l=U,Q.p=iA,Q.b=D,Q.f=H,U)H=1,Q.m=R,Q.d=F,Q.n=V}while(!H);return D!=B.length&&E?lB(B,0,D):B.subarray(0,D)},RQ=function(A,Q,B){B<<=Q&7;var C=Q/8|0;A[C]|=B,A[C+1]|=B>>8},uB=function(A,Q,B){B<<=Q&7;var C=Q/8|0;A[C]|=B,A[C+1]|=B>>8,A[C+2]|=B>>16},l0=function(A,Q){var B=[];for(var C=0;C<A.length;++C)if(A[C])B.push({s:C,f:A[C]});var J=B.length,K=B.slice();if(!J)return{t:q8,l:0};if(J==1){var E=new CA(B[0].s+1);return E[B[0].s]=1,{t:E,l:1}}B.sort(function(p,k){return p.f-k.f}),B.push({s:-1,f:25001});var Y=B[0],L=B[1],X=0,H=1,G=2;B[0]={s:-1,f:Y.f+L.f,l:Y,r:L};while(H!=J-1)Y=B[B[X].f<B[G].f?X++:G++],L=B[X!=H&&B[X].f<B[G].f?X++:G++],B[H++]={s:-1,f:Y.f+L.f,l:Y,r:L};var D=K[0].s;for(var C=1;C<J;++C)if(K[C].s>D)D=K[C].s;var U=new gA(D+1),F=s0(B[H-1],U,0);if(F>Q){var C=0,R=0,V=F-Q,w=1<<V;K.sort(function(k,v){return U[v.s]-U[k.s]||k.f-v.f});for(;C<J;++C){var m=K[C].s;if(U[m]>Q)R+=w-(1<<F-U[m]),U[m]=Q;else break}R>>=V;while(R>0){var b=K[C].s;if(U[b]<Q)R-=1<<Q-U[b]++-1;else++C}for(;C>=0&&R;--C){var z=K[C].s;if(U[z]==Q)--U[z],++R}F=Q}return{t:new CA(U),l:F}},s0=function(A,Q,B){return A.s==-1?Math.max(s0(A.l,Q,B+1),s0(A.r,Q,B+1)):Q[A.s]=B},D8=function(A){var Q=A.length;while(Q&&!A[--Q]);var B=new gA(++Q),C=0,J=A[0],K=1,E=function(L){B[C++]=L};for(var Y=1;Y<=Q;++Y)if(A[Y]==J&&Y!=Q)++K;else{if(!J&&K>2){for(;K>138;K-=138)E(32754);if(K>2)E(K>10?K-11<<5|28690:K-3<<5|12305),K=0}else if(K>3){E(J),--K;for(;K>6;K-=6)E(8304);if(K>2)E(K-3<<5|8208),K=0}while(K--)E(J);K=1,J=A[Y]}return{c:B.subarray(0,C),n:Q}},mB=function(A,Q){var B=0;for(var C=0;C<Q.length;++C)B+=A[C]*Q[C];return B},z8=function(A,Q,B){var C=B.length,J=t0(Q+2);A[J]=C&255,A[J+1]=C>>8,A[J+2]=A[J]^255,A[J+3]=A[J+1]^255;for(var K=0;K<C;++K)A[J+K+4]=B[K];return(J+4+C)*8},Z8=function(A,Q,B,C,J,K,E,Y,L,X,H){RQ(Q,H++,B),++J[256];var G=l0(J,15),D=G.t,U=G.l,F=l0(K,15),R=F.t,V=F.l,w=D8(D),m=w.c,b=w.n,z=D8(R),p=z.c,k=z.n,v=new gA(19);for(var O=0;O<m.length;++O)++v[m[O]&31];for(var O=0;O<p.length;++O)++v[p[O]&31];var g=l0(v,7),e=g.t,AA=g.l,QA=19;for(;QA>4&&!e[d0[QA-1]];--QA);var QQ=X+5<<3,IA=mB(J,gQ)+mB(K,pB)+E,FA=mB(J,D)+mB(K,R)+E+14+3*QA+mB(v,e)+2*v[16]+3*v[17]+7*v[18];if(L>=0&&QQ<=IA&&QQ<=FA)return z8(Q,H,A.subarray(L,L+X));var LA,t,WA,XA;if(RQ(Q,H,1+(FA<IA)),H+=2,FA<IA){LA=YQ(D,U,0),t=D,WA=YQ(R,V,0),XA=R;var aQ=YQ(e,AA,0);RQ(Q,H,b-257),RQ(Q,H+5,k-1),RQ(Q,H+10,QA-4),H+=14;for(var O=0;O<QA;++O)RQ(Q,H+3*O,e[d0[O]]);H+=3*QA;var OA=[m,p];for(var iA=0;iA<2;++iA){var jA=OA[iA];for(var O=0;O<jA.length;++O){var RA=jA[O]&31;if(RQ(Q,H,aQ[RA]),H+=e[RA],RA>15)RQ(Q,H,jA[O]>>5&127),H+=jA[O]>>12}}}else LA=d6,t=gQ,WA=n6,XA=pB;for(var O=0;O<Y;++O){var r=C[O];if(r>255){var RA=r>>18&31;if(uB(Q,H,LA[RA+257]),H+=t[RA+257],RA>7)RQ(Q,H,r>>23&31),H+=bC[RA];var pA=r&31;if(uB(Q,H,WA[pA]),H+=XA[pA],pA>3)uB(Q,H,r>>5&8191),H+=vC[pA]}else uB(Q,H,LA[r]),H+=t[r]}return uB(Q,H,LA[256]),H+t[256]},r6=new r0([65540,131080,131088,131104,262176,1048704,1048832,2114560,2117632]),q8=new CA(0),t6=function(A,Q,B,C,J,K){var E=K.z||A.length,Y=new CA(C+E+5*(1+Math.ceil(E/7000))+J),L=Y.subarray(C,Y.length-J),X=K.l,H=(K.r||0)&7;if(Q){if(H)L[0]=K.r>>3;var G=r6[Q-1],D=G>>13,U=G&8191,F=(1<<B)-1,R=K.p||new gA(32768),V=K.h||new gA(F+1),w=Math.ceil(B/3),m=2*w,b=function(yB){return(A[yB]^A[yB+1]<<w^A[yB+2]<<m)&F},z=new r0(25000),p=new gA(288),k=new gA(32),v=0,O=0,g=K.i||0,e=0,AA=K.w||0,QA=0;for(;g+2<E;++g){var QQ=b(g),IA=g&32767,FA=V[QQ];if(R[IA]=FA,V[QQ]=IA,AA<=g){var LA=E-g;if((v>7000||e>24576)&&(LA>423||!X)){H=Z8(A,L,0,z,p,k,O,e,QA,g-QA,H),e=v=O=0,QA=g;for(var t=0;t<286;++t)p[t]=0;for(var t=0;t<30;++t)k[t]=0}var WA=2,XA=0,aQ=U,OA=IA-FA&32767;if(LA>2&&QQ==b(g-OA)){var iA=Math.min(D,LA)-1,jA=Math.min(32767,g),RA=Math.min(258,LA);while(OA<=jA&&--aQ&&IA!=FA){if(A[g+WA]==A[g+WA-OA]){var r=0;for(;r<RA&&A[g+r]==A[g+r-OA];++r);if(r>WA){if(WA=r,XA=OA,r>iA)break;var pA=Math.min(OA,r-2),PQ=0;for(var t=0;t<pA;++t){var OQ=g-OA+t&32767,LB=R[OQ],jQ=OQ-LB&32767;if(jQ>PQ)PQ=jQ,FA=OQ}}}IA=FA,FA=R[IA],OA+=IA-FA&32767}}if(XA){z[e++]=268435456|a0[WA]<<18|$8[XA];var SQ=a0[WA]&31,_Q=$8[XA]&31;O+=bC[SQ]+vC[_Q],++p[257+SQ],++k[_Q],AA=g+WA,++v}else z[e++]=A[g],++p[A[g]]}}for(g=Math.max(g,AA);g<E;++g)z[e++]=A[g],++p[A[g]];if(H=Z8(A,L,X,z,p,k,O,e,QA,g-QA,H),!X)K.r=H&7|L[H/8|0]<<3,H-=7,K.h=V,K.p=R,K.i=g,K.w=AA}else{for(var g=K.w||0;g<E+X;g+=65535){var wQ=g+65535;if(wQ>=E)L[H/8|0]=X,wQ=E;H=z8(L,H+1,A.subarray(g,wQ))}K.i=E}return lB(Y,0,C+t0(H)+J)},e6=function(){var A=new Int32Array(256);for(var Q=0;Q<256;++Q){var B=Q,C=9;while(--C)B=(B&1&&-306674912)^B>>>1;A[Q]=B}return A}(),AG=function(){var A=-1;return{p:function(Q){var B=A;for(var C=0;C<Q.length;++C)B=e6[B&255^Q[C]]^B>>>8;A=B},d:function(){return~A}}};var QG=function(A,Q,B,C,J){if(!J){if(J={l:1},Q.dictionary){var K=Q.dictionary.subarray(-32768),E=new CA(K.length+A.length);E.set(K),E.set(A,K.length),A=E,J.w=K.length}}return t6(A,Q.level==null?6:Q.level,Q.mem==null?J.l?Math.ceil(Math.max(8,Math.min(13,Math.log(A.length)))*1.5):20:12+Q.mem,B,C,J)},N8=function(A,Q){var B={};for(var C in A)B[C]=A[C];for(var C in Q)B[C]=Q[C];return B};var EQ=function(A,Q){return A[Q]|A[Q+1]<<8},cA=function(A,Q){return(A[Q]|A[Q+1]<<8|A[Q+2]<<16|A[Q+3]<<24)>>>0},c0=function(A,Q){return cA(A,Q)+cA(A,Q+4)*4294967296},UA=function(A,Q,B){for(;B;++Q)A[Q]=B,B>>>=8};function BG(A,Q){return QG(A,Q||{},0,0)}function CG(A,Q){return i6(A,{i:2},Q&&Q.out,Q&&Q.dictionary)}var P8=function(A,Q,B,C){for(var J in A){var K=A[J],E=Q+J,Y=C;if(Array.isArray(K))Y=N8(C,K[1]),K=K[0];if(ArrayBuffer.isView(K))B[E]=[K,Y];else B[E+="/"]=[new CA(0),Y],P8(K,E,B,C)}},W8=typeof TextEncoder<"u"&&new TextEncoder,o0=typeof TextDecoder<"u"&&new TextDecoder,JG=0;try{o0.decode(q8,{stream:!0}),JG=1}catch(A){}var KG=function(A){for(var Q="",B=0;;){var C=A[B++],J=(C>127)+(C>223)+(C>239);if(B+J>A.length)return{s:Q,r:lB(A,B-1)};if(!J)Q+=String.fromCharCode(C);else if(J==3)C=((C&15)<<18|(A[B++]&63)<<12|(A[B++]&63)<<6|A[B++]&63)-65536,Q+=String.fromCharCode(55296|C>>10,56320|C&1023);else if(J&1)Q+=String.fromCharCode((C&31)<<6|A[B++]&63);else Q+=String.fromCharCode((C&15)<<12|(A[B++]&63)<<6|A[B++]&63)}};function U8(A,Q){if(Q){var B=new CA(A.length);for(var C=0;C<A.length;++C)B[C]=A.charCodeAt(C);return B}if(W8)return W8.encode(A);var J=A.length,K=new CA(A.length+(A.length>>1)),E=0,Y=function(H){K[E++]=H};for(var C=0;C<J;++C){if(E+5>K.length){var L=new CA(E+8+(J-C<<1));L.set(K),K=L}var X=A.charCodeAt(C);if(X<128||Q)Y(X);else if(X<2048)Y(192|X>>6),Y(128|X&63);else if(X>55295&&X<57344)X=65536+(X&1047552)|A.charCodeAt(++C)&1023,Y(240|X>>18),Y(128|X>>12&63),Y(128|X>>6&63),Y(128|X&63);else Y(224|X>>12),Y(128|X>>6&63),Y(128|X&63)}return lB(K,0,E)}function EG(A,Q){if(Q){var B="";for(var C=0;C<A.length;C+=16384)B+=String.fromCharCode.apply(null,A.subarray(C,C+16384));return B}else if(o0)return o0.decode(A);else{var J=KG(A),K=J.s,B=J.r;if(B.length)zA(8);return K}}var YG=function(A,Q){return Q+30+EQ(A,Q+26)+EQ(A,Q+28)},LG=function(A,Q,B){var C=EQ(A,Q+28),J=EQ(A,Q+30),K=EG(A.subarray(Q+46,Q+46+C),!(EQ(A,Q+8)&2048)),E=Q+46+C,Y=XG(A,E,J,B,cA(A,Q+20),cA(A,Q+24),cA(A,Q+42)),L=Y[0],X=Y[1],H=Y[2];return[EQ(A,Q+10),L,X,K,E+J+EQ(A,Q+32),H]},XG=function(A,Q,B,C,J,K,E){var Y=J==4294967295,L=K==4294967295,X=E==4294967295,H=Q+B,G=Y+L+X;if(C&&G){for(;Q+4<H;Q+=4+EQ(A,Q+2))if(EQ(A,Q)==1)return[Y?c0(A,Q+4+8*L):J,L?c0(A,Q+4):K,X?c0(A,Q+4+8*(L+Y)):E,1];if(C<2)zA(13)}return[J,K,E,0]},i0=function(A){var Q=0;if(A)for(var B in A){var C=A[B].length;if(C>65535)zA(9);Q+=C+4}return Q},I8=function(A,Q,B,C,J,K,E,Y){var L=C.length,X=B.extra,H=Y&&Y.length,G=i0(X);if(UA(A,Q,E!=null?33639248:67324752),Q+=4,E!=null)A[Q++]=20,A[Q++]=B.os;A[Q]=20,Q+=2,A[Q++]=B.flag<<1|(K<0&&8),A[Q++]=J&&8,A[Q++]=B.compression&255,A[Q++]=B.compression>>8;var D=new Date(B.mtime==null?Date.now():B.mtime),U=D.getFullYear()-1980;if(U<0||U>119)zA(10);if(UA(A,Q,U<<25|D.getMonth()+1<<21|D.getDate()<<16|D.getHours()<<11|D.getMinutes()<<5|D.getSeconds()>>1),Q+=4,K!=-1)UA(A,Q,B.crc),UA(A,Q+4,K<0?-K-2:K),UA(A,Q+8,B.size);if(UA(A,Q+12,L),UA(A,Q+14,G),Q+=16,E!=null)UA(A,Q,H),UA(A,Q+6,B.attrs),UA(A,Q+10,E),Q+=14;if(A.set(C,Q),Q+=L,G)for(var F in X){var R=X[F],V=R.length;UA(A,Q,+F),UA(A,Q+2,V),A.set(R,Q+4),Q+=4+V}if(H)A.set(Y,Q),Q+=H;return Q},HG=function(A,Q,B,C,J){UA(A,Q,101010256),UA(A,Q+8,B),UA(A,Q+10,B),UA(A,Q+12,C),UA(A,Q+16,J)};function O8(A,Q){if(!Q)Q={};var B={},C=[];P8(A,"",B,Q);var J=0,K=0;for(var E in B){var Y=B[E],L=Y[0],X=Y[1],H=X.level==0?0:8,G=U8(E),D=G.length,U=X.comment,F=U&&U8(U),R=F&&F.length,V=i0(X.extra);if(D>65535)zA(11);var w=H?BG(L,X):L,m=w.length,b=AG();b.p(L),C.push(N8(X,{size:L.length,crc:b.d(),c:w,f:G,m:F,u:D!=E.length||F&&U.length!=R,o:J,compression:H})),J+=30+D+V+m,K+=76+2*(D+V)+(R||0)+m}var z=new CA(K+22),p=J,k=K-J;for(var v=0;v<C.length;++v){var G=C[v];I8(z,G.o,G,G.f,G.u,G.c.length);var O=30+G.f.length+i0(G.extra);z.set(G.c,G.o+O),I8(z,J,G,G.f,G.u,G.c.length,G.o,G.m),J+=16+O+(G.m?G.m.length:0)}return HG(z,J,C.length,k,p),z}function j8(A,Q){var B={},C=A.length-22;for(;cA(A,C)!=101010256;--C)if(!C||A.length-C>65558)zA(13);var J=EQ(A,C+8);if(!J)return{};var K=cA(A,C+16),E=cA(A,C-20)==117853008;if(E){var Y=cA(A,C-12);if(E=cA(A,Y)==101075792,E)J=cA(A,Y+32),K=cA(A,Y+48)}var L=Q&&Q.filter;for(var X=0;X<J;++X){var H=LG(A,K,E),G=H[0],D=H[1],U=H[2],F=H[3],R=H[4],V=H[5],w=YG(A,V);if(K=R,!L||L({name:F,size:D,originalSize:U,compression:G}))if(!G)B[F]=lB(A,w,w+D);else if(G==8)B[F]=CG(A.subarray(w,w+D),{out:new CA(U)});else zA(14,"unknown compression type "+G)}return B}function GG(){return new Promise((A,Q)=>{let B=indexedDB.open("trove-plugins",1);B.onupgradeneeded=()=>{let C=B.result;if(!C.objectStoreNames.contains("installs"))C.createObjectStore("installs",{keyPath:"id"})},B.onsuccess=()=>A(B.result),B.onerror=()=>Q(B.error)})}function fC(A,Q,B){return new Promise((C,J)=>{let K=A.transaction("installs",Q),E=K.objectStore("installs"),Y;Promise.resolve(B(E)).then((L)=>Y=L),K.oncomplete=()=>C(Y),K.onerror=()=>J(K.error)})}var S8=(A)=>new Promise((Q,B)=>{A.onsuccess=()=>Q(A.result),A.onerror=()=>B(A.error)});class e0{constructor(){this._db=null}async#A(){return this._db??=await GG()}async save(A){let Q=await this.#A();return await fC(Q,"readwrite",(B)=>B.put(A)),A}async get(A){let Q=await this.#A();return fC(Q,"readonly",(B)=>S8(B.get(A)))}async list(){let A=await this.#A();return fC(A,"readonly",(Q)=>S8(Q.getAll()))}async remove(A){let Q=await this.#A();await fC(Q,"readwrite",(B)=>B.delete(A))}async patch(A,Q){let B=await this.get(A);if(!B)return null;let C={...B,...Q};return await this.save(C),C}}var uC=null;function ZG(){if(!uC)uC=import("./chunk-h05bxfbs.js").then((m)=>$G(m.default,1)).then((A)=>(A.default||A)({locateFile:()=>"/sql-wasm.wasm"})).catch((A)=>{throw uC=null,A});return uC}var WG="trove-plugin-clientdb",mC="dbs";function UG(){return new Promise((A,Q)=>{let B=indexedDB.open(WG,1);B.onupgradeneeded=()=>{let C=B.result;if(!C.objectStoreNames.contains(mC))C.createObjectStore(mC)},B.onsuccess=()=>A(B.result),B.onerror=()=>Q(B.error)})}function AJ(A,Q){return UG().then((B)=>new Promise((C,J)=>{let K=B.transaction(mC,A),E;Promise.resolve(Q(K.objectStore(mC))).then((Y)=>E=Y),K.oncomplete=()=>{B.close(),C(E)},K.onerror=()=>{B.close(),J(K.error)}}))}var IG=(A)=>new Promise((Q,B)=>{A.onsuccess=()=>Q(A.result),A.onerror=()=>B(A.error)}),FG=(A)=>AJ("readonly",(Q)=>IG(Q.get(A))),RG=(A,Q)=>AJ("readwrite",(B)=>B.put(Q,A)),MG=(A)=>AJ("readwrite",(Q)=>Q.delete(A));class _8{constructor(A,Q){this.key=A,this.db=Q,this._saveTimer=null}#A(){clearTimeout(this._saveTimer),this._saveTimer=setTimeout(()=>{this.flush().catch((A)=>{console.error(`persisting plugin storage "${this.key}" failed`,A),this.onError?.(A,this.key)})},150)}async flush(){clearTimeout(this._saveTimer),this._saveTimer=null,await RG(this.key,this.db.export())}async exec(A){return this.db.exec(A),this.#A(),{ok:!0}}async run(A,...Q){return this.db.run(A,Q),this.#A(),{ok:!0}}async get(A,...Q){let B=this.db.prepare(A);try{return B.bind(Q),B.step()?B.getAsObject():null}finally{B.free()}}async all(A,...Q){let B=this.db.prepare(A),C=[];try{B.bind(Q);while(B.step())C.push(B.getAsObject())}finally{B.free()}return C}async batch(A=[]){this.db.run("BEGIN");try{for(let{sql:Q,params:B=[]}of A)this.db.run(Q,B);this.db.run("COMMIT")}catch(Q){try{this.db.run("ROLLBACK")}catch{}throw Q}return this.#A(),{ok:!0}}close(){clearTimeout(this._saveTimer),this.db.close()}}class QJ{constructor({onError:A}={}){this._pool=new Map,this.onError=A||null}async obtain(A){let Q=this._pool.get(A);if(!Q){let B=await ZG(),C=await FG(A);Q=new _8(A,new B.Database(C||void 0)),Q.onError=this.onError,this._pool.set(A,Q)}return Q}async drop(A){let Q=this._pool.get(A);if(Q)Q.close(),this._pool.delete(A);await MG(A)}}var w8=new TextEncoder;function BJ(A){let Q=atob(A.replace(/-/g,"+").replace(/_/g,"/")),B=new Uint8Array(Q.length);for(let C=0;C<Q.length;C++)B[C]=Q.charCodeAt(C);return B}function T8(A){let Q=new Uint8Array(A),B="";for(let C=0;C<Q.length;C++)B+=Q[C].toString(16).padStart(2,"0");return B}async function x8(A){return new Uint8Array(await crypto.subtle.digest("SHA-256",A))}function VG(A){let Q={...A};return delete Q.signature,JSON.stringify(CJ(Q))}function CJ(A){if(Array.isArray(A))return A.map(CJ);if(A&&typeof A==="object"){let Q={};for(let B of Object.keys(A).sort())Q[B]=CJ(A[B]);return Q}return A}async function zG(A){let Q=[...A.keys()].filter((E)=>E!=="manifest.json").sort(),B=[];for(let E of Q){let Y=A.get(E),L=w8.encode(E),X=new Uint8Array(4);new DataView(X.buffer).setUint32(0,Y.length),B.push(L,new Uint8Array([0]),X,Y)}let C=B.reduce((E,Y)=>E+Y.length,0),J=new Uint8Array(C),K=0;for(let E of B)J.set(E,K),K+=E.length;return T8(await x8(J))}async function qG(A){return T8(await x8(BJ(A)))}async function NG({manifest:A,files:Q}){if(!A.signature||!A.publicKey)return{signed:!1,valid:!1};let B=await zG(Q);if(A.contentHash&&A.contentHash!==B)return{signed:!0,valid:!1,reason:"File contents do not match the manifest hash"};try{let C=await crypto.subtle.importKey("spki",BJ(A.publicKey),{name:"ECDSA",namedCurve:"P-256"},!1,["verify"]);if(!await crypto.subtle.verify({name:"ECDSA",hash:"SHA-256"},C,BJ(A.signature),w8.encode(VG(A))))return{signed:!0,valid:!1,reason:"Signature does not verify"};return{signed:!0,valid:!0,fingerprint:await qG(A.publicKey)}}catch(C){return{signed:!0,valid:!1,reason:"Bad key/signature: "+C.message}}}function PG(A,Q,B){let C=(E)=>(E||"").toLowerCase().replace(/:/g,""),J=C(Q),K=[B.name,`${B.domain}/${B.name}`];for(let E of A?.keys||[]){if(C(E.fingerprint)!==J)continue;if((E.plugins||[]).some((Y)=>Y==="*"||K.includes(Y)))return!0}return!1}async function k8({manifest:A,files:Q},B){let C=await NG({manifest:A,files:Q});if(!C.signed)return{status:"unverified",reason:"Package is not signed"};if(!C.valid)return{status:"invalid",reason:C.reason||"Invalid signature — the package may have been tampered with"};let J=null;try{J=await B(A.domain)}catch{}if(J&&PG(J,C.fingerprint,A))return{status:"verified",domain:A.domain,fingerprint:C.fingerprint};return{status:"signed",domain:A.domain,fingerprint:C.fingerprint,reason:J?"Domain does not list this key":"Could not reach the domain"}}function JJ(A){let Q=/^([a-z][a-z0-9+.-]*:\/\/)\*\.(.+)$/i.exec(A),B=!!Q,C;try{C=new URL(B?Q[1]+Q[2]:A)}catch{throw Error(`Invalid network endpoint "${A}" (must be an absolute http(s) URL)`)}if(C.protocol!=="http:"&&C.protocol!=="https:")throw Error(`Network endpoint "${A}" must use http or https`);let J=C.hostname.toLowerCase();if(!J)throw Error(`Network endpoint "${A}" has no host`);return{scheme:C.protocol,host:J,wildcard:B,port:C.port,pathPrefix:C.pathname||"/",raw:A}}function g8(A){let Q=[];for(let B of A||[])try{Q.push(JJ(B))}catch{}return Q}function OG(A,Q){let B;try{B=new URL(Q)}catch{return!1}if(B.protocol!==A.scheme)return!1;let C=B.hostname.toLowerCase();if(A.wildcard){if(C!==A.host&&!C.endsWith("."+A.host))return!1}else if(C!==A.host)return!1;if(B.port!==A.port)return!1;return B.pathname.startsWith(A.pathPrefix)}function pC(A,Q){return g8(A).some((B)=>OG(B,Q))}function lC(A){return g8(A).map((Q)=>({scheme:Q.scheme.replace(":",""),host:(Q.wildcard?"*.":"")+Q.host+(Q.port?":"+Q.port:""),path:Q.pathPrefix==="/"?"":Q.pathPrefix,raw:Q.raw}))}var jG={files:"Read your files, folders, and search index (via the host).",storage:"Keep its own SQLite database(s) — on the server and/or on this device.",ui:"Show a popup panel and toasts.",commands:"Add commands to the palette, and run the specific host commands it lists.",opener:"Preview/open file types.",indexer:"Add searchable content to your files.",network:"Connect to the internet — only the endpoints it declares (shown below).",media:"Show playback controls on your lock screen and notifications while it plays media.",dock:"Keep its viewer in a small floating window when you navigate away."},KJ=new Set;function y8(A){let Q=YJ(A,"storage");if(!Q)return{plugin:!1,domain:!1};if(Q===!0||typeof Q==="object"&&!("plugin"in Q)&&!("domain"in Q))return{plugin:!0,domain:!1};return{plugin:!!Q.plugin,domain:!!Q.domain}}function SG(A){return jG[A]||A}function h8(A){let Q=A&&A.capabilities,B={};if(Array.isArray(Q)){for(let C of Q)if(C)B[C]={}}else if(Q&&typeof Q==="object")for(let[C,J]of Object.entries(Q)){if(J===!1||J==null)continue;B[C]=J===!0?{}:J}return B}function EJ(A){return Object.keys(h8(A))}function YJ(A,Q){let B=h8(A);return Object.prototype.hasOwnProperty.call(B,Q)?B[Q]:null}function rQ(A){let Q=YJ(A,"network");if(Q){if(Array.isArray(Q))return Q;if(Array.isArray(Q.endpoints))return Q.endpoints;if(Array.isArray(Q.prefixes))return Q.prefixes}if(Array.isArray(A.network))return A.network;return[]}function dA(A){let Q=A?.displayName??A?.name;return typeof Q==="string"&&Q.trim()?Q:"Plugin"}function b8(A){let Q=YJ(A,"commands");if(!Q)return[];if(Array.isArray(Q))return Q.filter(Boolean);if(Array.isArray(Q.execute))return Q.execute.filter(Boolean);return[]}function cC(A,Q,B){if(!Q)return!1;if(kQ(Q)&&Q8(A,Q))return!0;return b8(A).includes(Q)}function tQ(A){let Q;try{Q=j8(A instanceof Uint8Array?A:new Uint8Array(A))}catch(K){throw Error("Not a valid zip archive: "+K.message)}let B=new Map;for(let[K,E]of Object.entries(Q))if(!K.endsWith("/"))B.set(K.replace(/^\.?\//,""),E);let C=B.get("manifest.json");if(!C)throw Error("Package is missing manifest.json");let J;try{J=JSON.parse(new TextDecoder().decode(C))}catch(K){throw Error("manifest.json is not valid JSON: "+K.message)}return _G(J,B),{manifest:J,files:B,raw:A}}function _G(A,Q){let B=(C,J)=>{if(!C)throw Error(J)};if(kC(A),B(A.entry,"manifest.entry (path to the plugin script) is required"),B(Q.has(A.entry),`entry "${A.entry}" is not in the package`),A.capabilities!=null)B(Array.isArray(A.capabilities)||typeof A.capabilities==="object","capabilities must be an object of { capability: options } (or an array of ids)");if(A.icon)B(Q.has(A.icon),`icon "${A.icon}" is not in the package`);for(let C of FQ(A)){if(C.entry)B(Q.has(C.entry),`contribution "${C.name}" points at "${C.entry}", which is not in the package`);if(C.type==="keymap")B(Q.has(C.path),`keymap "${C.name}" points at "${C.path}", which is not in the package`)}for(let C of rQ(A))JJ(C)}async function v8(A,Q=globalThis.fetch.bind(globalThis)){let B;try{B=await Q(A)}catch(J){throw Error("Could not fetch the plugin: "+J.message)}if(!B.ok)throw Error(`Could not fetch the plugin (HTTP ${B.status})`);let C=new Uint8Array(await B.arrayBuffer());return tQ(C)}function f8(A,Q){let B=A.manifest,C=FQ(B).map((E)=>({kind:E.type,name:E.name,uri:E.uri,title:E.title||E.name,detail:E.type==="opener"||E.type==="indexer"?wG(E.match):E.type==="statusItem"?`${E.slot} of the status bar${E.command?` — runs ${E.command}`:""}`:E.type==="keymap"?E.path:"",offline:!!E.offline})),J=Q?.status==="verified",K=y8(B);return{id:JQ(B),name:dA(B),version:B.version||"0.0.0",description:B.description||"",author:B.author||"Unknown",domain:B.domain,capabilities:EJ(B).map((E)=>({id:E,description:SG(E),adminOnly:KJ.has(E)})),contributions:C,settings:(B.settings||[]).map((E)=>({key:E.key,title:E.title||E.key,type:E.type,secret:!!E.secret})),network:lC(rQ(B)),commands:b8(B),storage:K.plugin||K.domain?{plugin:K.plugin,domain:K.domain,domainBlocked:K.domain&&!J}:null,fileCount:A.files.size,sizeBytes:[...A.files.values()].reduce((E,Y)=>E+Y.length,0),trust:Q}}function LJ(A,Q){let B=y8(A);return{plugin:B.plugin,domain:B.domain&&Q?.status==="verified"}}function wG(A){if(!A)return"";let Q=[];if(A.ext?.length)Q.push(A.ext.join(", "));if(A.mime?.length)Q.push(A.mime.join(", "));return Q.join(" · ")}class XJ{constructor(){this.owner=null}#A(){return typeof navigator<"u"?navigator.mediaSession:null}apply(A,Q,B={}){let C=this.#A();if(!C)return{ok:!1};if(A&&Q!=="clear")this.owner=A,A.mediaOwner=!0;try{if(Q==="metadata")C.metadata=typeof MediaMetadata<"u"?new MediaMetadata({title:B.title||"",artist:B.artist||"",album:B.album||"",artwork:B.artwork||[]}):C.metadata;else if(Q==="playbackState")C.playbackState=B.state||"none";else if(Q==="position"&&C.setPositionState)C.setPositionState({duration:B.duration||0,position:B.position||0,playbackRate:B.playbackRate||1});else if(Q==="action"){if(C.setActionHandler?.(B.action,B.on?()=>A?.channel?.emit("media:action",{action:B.action}):null),A)A.mediaActions||=new Set,B.on?A.mediaActions.add(B.action):A.mediaActions.delete(B.action)}else if(Q==="clear"){if(A&&this.owner&&this.owner!==A)return{ok:!0};this.releaseActions(A),C.metadata=null,C.playbackState="none",this.owner=null}}catch{}return{ok:!0}}releaseActions(A){let Q=this.#A();if(!Q||!A?.mediaActions)return;for(let B of A.mediaActions)try{Q.setActionHandler?.(B,null)}catch{}A.mediaActions.clear()}releaseFrame(A){if(this.owner===A)this.owner=null,this.apply(A,"clear",{});this.releaseActions(A)}}class HJ{constructor({destroyFrame:A,openFile:Q,onChange:B}={}){this.destroyFrame=A,this.openFile=Q,this.onChange=B||(()=>{}),this.docked=null,this.el=null}place(A,Q,B,C=""){this.stopPlace(A);let J=A.iframe;J.style.cssText=`position:fixed;border:0;visibility:visible;display:block;background:transparent;z-index:${B};margin:0;padding:0;border-radius:${C};`;let K=()=>{let L=Q.getBoundingClientRect(),X=L.width>0&&L.height>0&&document.contains(Q);J.style.left=`${L.left}px`,J.style.top=`${L.top}px`,J.style.width=`${L.width}px`,J.style.height=`${L.height}px`,J.style.visibility=X?"visible":"hidden"};K();let E=typeof ResizeObserver<"u"?new ResizeObserver(K):null;if(E?.observe(Q),document.body)E?.observe(document.body);let Y=typeof IntersectionObserver<"u"?new IntersectionObserver(K,{threshold:[0,1]}):null;Y?.observe(Q),window.addEventListener("scroll",K,!0),window.addEventListener("resize",K),A.place={target:Q,stop:()=>{E?.disconnect(),Y?.disconnect(),window.removeEventListener("scroll",K,!0),window.removeEventListener("resize",K)}}}stopPlace(A){if(A.place)A.place.stop(),A.place=null}hide(A){this.stopPlace(A),A.iframe.style.cssText="position:fixed;left:0;top:0;width:0;height:0;border:0;visibility:hidden;"}releaseFrame(A){if(this.stopPlace(A),this.docked===A)this.docked=null,this.#A()}#A(){if(this.el)this.el.style.display="none"}dock(A){if(this.docked&&this.docked!==A)this.closeDock(this.docked);let Q=A.dock?.minSize||{width:300,height:90},B=this.#Q();B.style.width=`${u8(Q.width,200,480)}px`,B.style.height=`${u8(Q.height,56,360)+26}px`,B.querySelector(".vd-title").textContent=A.node?.name||(A.record.manifest.displayName||A.record.manifest.name),B.style.display="flex",this.place(A,B.querySelector(".vd-body"),61,"0 0 11px 11px"),this.docked=A,A.channel?.emit("dock:state",{docked:!0}),this.onChange()}undock(A){if(this.#A(),this.docked===A)this.docked=null;A.channel?.emit("dock:state",{docked:!1})}closeDock(A){if(this.#A(),this.docked===A)this.docked=null;A.channel?.emit("dock:state",{docked:!1,closed:!0}),this.destroyFrame?.(A),this.onChange()}#Q(){if(this.el)return this.el;let A=document.createElement("div");return A.className="viewer-dock",A.innerHTML='<div class="vd-bar"><span class="vd-title"></span><button class="vd-expand" title="Reopen">↗</button><button class="vd-close" title="Close">✕</button></div><div class="vd-body"></div>',A.querySelector(".vd-expand").addEventListener("click",()=>{let Q=this.docked;if(Q?.node)this.openFile?.(Q.node,Q.openerId)}),A.querySelector(".vd-close").addEventListener("click",()=>{if(this.docked)this.closeDock(this.docked)}),document.body.appendChild(A),this.el=A,A}}function u8(A,Q,B){return Math.max(Q,Math.min(B,A||Q))}function yA(A){console.error(A)}var FB="The provider has been disposed";class l{static deps=[];async obtain(A={}){throw Error("obtain() not implemented")}release(A,Q={}){}async flush(){}static fromSingleton(A,{dispose:Q,deps:B=[]}={}){return class extends l{static deps=B;#A;#Q=!1;constructor(J={}){super();this.#A=J}async obtain(){return A}release(){}async dispose(){if(this.#Q)return;if(this.#Q=!0,typeof Q==="function")await Q(A,this.#A)}}}static fromPool(A,Q,{size:B=1,deps:C=[]}={}){if(!Number.isInteger(B)||B<1)throw RangeError("fromPool() requires an integer size of at least 1");return class extends l{static deps=C;#A;#Q=[];#B=new Set;#C=[];#J=0;#K=!1;constructor(K={}){super();this.#A=K}async#E(K){try{await Q(K,this.#A)}catch(E){yA(E)}}#Y(){while(this.#C.length>0){if(this.#Q.length>0){let E=this.#Q.shift();this.#B.add(E),this.#C.shift().resolve(E);continue}if(this.#J>=B)return;let K=this.#C.shift();this.#J++,Promise.resolve().then(()=>A(this.#A)).then((E)=>{if(this.#K){this.#J--,this.#E(E),K.reject(Error(FB));return}this.#B.add(E),K.resolve(E)},(E)=>{this.#J--,K.reject(E),this.#Y()})}}async obtain(){if(this.#K)throw Error(FB);let K=Promise.withResolvers();return this.#C.push(K),this.#Y(),await K.promise}release(K){if(!this.#B.delete(K))return;if(this.#K){this.#J--,this.#E(K);return}this.#Q.push(K),this.#Y()}async dispose(){if(this.#K)return;this.#K=!0;let K=this.#C.splice(0);for(let{reject:Y}of K)Y(Error(FB));let E=this.#Q.splice(0);this.#J-=E.length,await Promise.all(E.map((Y)=>this.#E(Y)))}}}static fromLazySingleton(A,Q,{deps:B=[]}={}){return class extends l{static deps=B;#A;#Q=null;#B=null;#C=!1;constructor(J={}){super();this.#A=J}async obtain(){if(this.#C)throw Error(FB);this.#Q??=Promise.resolve().then(()=>A(this.#A));try{return this.#B=await this.#Q,this.#B}catch(J){throw this.#Q=null,this.#B=null,J}}release(){}async dispose(){if(this.#C)return;if(this.#C=!0,!this.#Q||typeof Q!=="function")return;let J=this.#B??await this.#Q.catch(()=>null);if(J!=null)await Q(J,this.#A)}}}static fromRefCounted(A,Q,{deps:B=[]}={}){return class extends l{static deps=B;#A;#Q=0;#B=null;#C=null;#J=null;#K=!1;constructor(J={}){super();this.#A=J}async obtain(){if(this.#K)throw Error(FB);this.#Q++;while(this.#J)await this.#J;if(this.#K)throw this.#Q--,Error(FB);if(!this.#B)this.#B=Promise.resolve().then(()=>A(this.#A));try{return this.#C=await this.#B,this.#C}catch(J){if(this.#Q--,this.#Q<=0)this.#Q=0,this.#B=null,this.#C=null;throw J}}async release(){if(this.#Q<=0)return;if(this.#Q--,this.#Q>0)return;let J=this.#C,K=this.#B;if(this.#C=null,this.#B=null,!K)return;this.#J=(async()=>{try{let E=J??await K.catch(()=>null);if(E!=null)await Q(E,this.#A)}catch(E){yA(E)}finally{this.#J=null}})(),await this.#J}async dispose(){if(this.#K=!0,this.#Q>0)this.#Q=1,await this.release();while(this.#J)await this.#J}}}}class GJ{#A;#Q=!1;constructor(A,Q){this.resources=A,this.#A=Q}get released(){return this.#Q}async release(){if(this.#Q)return;this.#Q=!0;for(let{name:A,provider:Q,options:B}of this.#A)try{await Q.release(this.resources[A],B)}catch(C){yA(C)}this.#A=[]}}class yQ{#A=new Map;#Q=new WeakMap;#B;#C=!1;constructor({providers:A,feed:Q}={}){if(this.#B=Q??new EventTarget,!A)return;let B=(C,J)=>{if(this.#A.has(C))return this.#A.get(C);let K=A[C];if(!K)throw Error(`Dependency not found: ${C}`);let E=[...J,C];if(J.includes(C))throw Error(`Cyclic dependency detected: ${E.join(" -> ")}`);let Y={};for(let X of K.deps??[])Y[X]=B(X,E);let L=new K(Y,{engineFeed:this.#B,container:this});return this.#A.set(C,L),L};for(let C of Object.keys(A))B(C,[])}get feed(){return this.#B}get disposed(){return this.#C}has(A){return this.#A.has(A)}get(A){let Q=this.#A.get(A);if(!Q)throw Error(`Dependency not found: ${A}`);return Q}resolve(A){if(!A)return{};let Q=this.#Q.get(A);if(Q)return Q;let B={};if(Array.isArray(A))for(let C of A)B[C]={provider:this.get(C),options:void 0};else for(let C of Object.keys(A))B[C]={provider:this.get(C),options:A[C]};return this.#Q.set(A,B),B}resolveAll(...A){let Q=A.filter(Boolean);if(Q.length===1)return this.resolve(Q[0]);return Object.assign({},...Q.map((B)=>this.resolve(B)))}async lease(...A){if(this.#C)throw Error("The container has been disposed");let Q=this.resolveAll(...A),B={},C=[];try{for(let[J,{provider:K,options:E}]of Object.entries(Q))B[J]=await K.obtain(E),C.push({name:J,provider:K,options:E})}catch(J){throw await new GJ(B,C).release(),J}return new GJ(B,C)}async use(A,Q){let B=await this.lease(A);try{return await Q(B.resources)}finally{await B.release()}}async dispose(){if(this.#C)return;this.#C=!0;let A=[...this.#A.values()].reverse();for(let Q of A)try{await Q.flush?.()}catch(B){yA(B)}for(let Q of A)try{await Q.dispose?.()}catch(B){yA(B)}}}var TG=typeof ErrorEvent==="function"?ErrorEvent:class extends Event{constructor(Q,{error:B,message:C=""}={}){super(Q);this.error=B,this.message=C}};function xG(A){return A&&typeof A.message==="string"?A.message:String(A)}class l8 extends Event{constructor({reason:A,error:Q=null}={}){super("abort");this.reason=A,this.error=Q}}var m8=["complete","error","abort"];function kG(){return typeof DOMException==="function"?new DOMException("The dispatch was aborted","AbortError"):Object.assign(Error("The dispatch was aborted"),{name:"AbortError"})}class P{execute(){throw Error("execute() not implemented")}}class $J extends EventTarget{#A=new AbortController;#Q;#B=null;constructor(){super();for(let A of m8)this.addEventListener(A,(Q)=>{this.#B??={type:A,event:Q}},{once:!0})}get signal(){return this.#A.signal}get settled(){return this.#B?.type??null}get reason(){return this.#Q}abort(A){if(this.#A.signal.aborted)return;this.#Q=A??kG(),this.#A.abort(this.#Q)}next(A,{signal:Q}={}){let B=new Set(Array.isArray(A)?A:[A]);if(B.size===0)throw TypeError("next() requires at least one event name");let C=B.has("abort");return new Promise((J,K)=>{if(Q?.aborted){K(Q.reason);return}if(this.#A.signal.aborted&&!C&&!this.#B){K(this.#Q);return}if(this.#B){this.#C(J,K,this.#B,B);return}let E=new AbortController,Y={signal:E.signal},L=(X)=>(H)=>{E.abort(),X(H)};for(let X of B)this.addEventListener(X,L(J),Y);for(let X of m8){if(B.has(X))continue;this.addEventListener(X,(H)=>L(K)(p8(X,H,B)),Y)}if(!C)this.#A.signal.addEventListener("abort",()=>L(K)(this.#Q),Y);Q?.addEventListener("abort",()=>L(K)(Q.reason),Y)})}#C(A,Q,B,C){if(C.has(B.type))A(B.event);else Q(p8(B.type,B.event,C))}}function p8(A,Q,B){if(A==="error")return Q.error;if(A==="abort")return Q.reason;return gG(B)}function gG(A){return Error(`The dispatch completed without emitting ${[...A].map((Q)=>`'${Q}'`).join(" or ")}`)}class dC{#A;#Q;constructor({container:A,interceptors:Q}={}){this.#A=A??new yQ,this.#Q=Q?[...Q]:[]}get container(){return this.#A}get feed(){return this.#A.feed}dispatch(A){if(!(A instanceof P))throw TypeError("dispatch() requires an instance of Action");let Q=this.#A,B=this.#Q,C=Q.feed,J=new $J;return setTimeout(async()=>{let K=[],E={},Y=null,L=(X)=>{if(X!==void 0)E=X};try{for(let H of B){if(K.push(H),!H.enter)continue;L(await Q.use(H.deps,(G)=>H.enter(G,{dispatchFeed:J,engineFeed:C,signal:J.signal,state:E,action:A})))}let X=await Q.lease(A.constructor.deps,A.deps);try{await A.execute(X.resources,{dispatchFeed:J,engineFeed:C,signal:J.signal,state:E})}finally{await X.release()}}catch(X){Y=X}finally{for(let X=K.length-1;X>=0;X--){let H=K[X],G=J.signal.aborted;try{if(G&&H.abort)L(await Q.use(H.deps,(D)=>H.abort(D,{dispatchFeed:J,engineFeed:C,signal:J.signal,action:A,state:E,reason:J.reason,error:Y})));else if(Y&&H.error){let D={dispatchFeed:J,engineFeed:C,signal:J.signal,action:A,state:E,error:Y,handled:()=>{Y=null}};L(await Q.use(H.deps,(U)=>H.error(U,D)))}else if(!Y&&H.leave)L(await Q.use(H.deps,(D)=>H.leave(D,{dispatchFeed:J,engineFeed:C,signal:J.signal,state:E,action:A})))}catch(D){Y=D}}if(J.signal.aborted)J.dispatchEvent(new l8({reason:J.reason,error:Y}));else if(Y)J.dispatchEvent(new TG("error",{error:Y,message:xG(Y)}));else J.dispatchEvent(new Event("complete"))}}),J}}class LQ{boot(){throw Error("boot() not implemented, and no fetch() to fall back to")}kill(){}}class c8{#A;#Q;#B=null;#C=null;#J=!1;#K=null;#E=Promise.withResolvers();#Y=!1;#L=void 0;#X=!1;#H=void 0;#$=void 0;observers=new Set;constructor(A,Q){this.#A=A,this.#Q=Q,this.notify=this.notify.bind(this)}get hasValue(){return this.#Y}get currentValue(){return this.#L}get received(){return this.#E.promise}get bootFeed(){return this.#H}get killFeed(){return this.#$}#Z(A,Q){let B=this.#A._dispatch(A);return B.addEventListener("error",(C)=>{yA(Error(`${this.#Q.constructor.name} ${Q} (${A.constructor.name}) failed`,{cause:C.error}))},{once:!0}),B}notify(A){if(this.#X)return;if(this.#L=A,!this.#Y)this.#Y=!0,this.#E.resolve(!0);for(let Q of[...this.observers])try{Q.next?.(A)}catch(B){yA(B)}}boot(){if(this.#C)return this.#C;return this.#C=(async()=>{try{if(this.#Q.bootAction)this.#H=this.#Z(this.#Q.bootAction,"bootAction");this.#B=await this.#A._container.lease(this.#Q.constructor.deps,this.#Q.deps);let A={notify:this.notify,engineFeed:this.#A._container.feed,bootFeed:this.#H};if(this.#Q.boot===LQ.prototype.boot){if(typeof this.#Q.fetch!=="function")throw Error(`${this.#Q.constructor.name} implements neither boot() nor fetch()`);this.notify(await this.#Q.fetch(this.#B.resources,A)),await this.#D()}else await this.#Q.boot(this.#B.resources,A)}catch(A){yA(A),await this.#D(A)}finally{this.#J=!0}})(),this.#C}kill(){if(this.#K)return this.#K;return this.#K=this.#J?this.#G():Promise.resolve(this.#C).then(()=>this.#G()),this.#K}async#G(){if(this.#X)return;try{if(this.#Q.killAction)this.#$=this.#Z(this.#Q.killAction,"killAction");if(this.#Q.kill)await this.#Q.kill(this.#B?.resources??{},{bootFeed:this.#H,killFeed:this.#$,engineFeed:this.#A._container.feed,notify:this.notify})}catch(A){yA(A)}finally{await this.#D()}}async#D(A){if(this.#X)return;this.#X=!0,this.#A._evict(this.#Q,this);let Q=[...this.observers];this.observers.clear();for(let C of Q)try{if(A!==void 0&&C.error)C.error(A);else C.complete?.()}catch(J){yA(J)}if(!this.#Y)this.#E.resolve(!1);let B=this.#B;if(this.#B=null,B)await B.release()}}class aC{#A;#Q;#B;#C=!1;constructor({container:A,dispatcher:Q,createControllerMap:B}={}){this.#A=A??new yQ,this.#Q=Q??null,this.#B=B?.()??new Map}get container(){return this.#A}get feed(){return this.#A.feed}get _container(){return this.#A}_dispatch(A){if(!this.#Q)throw Error("A query declared a bootAction/killAction but no dispatcher was given to QueryStore");return this.#Q.dispatch(A)}_evict(A,Q){if(this.#B.get(A)===Q)this.#B.delete(A)}#J(A){return[A.constructor.deps,A.deps]}query(A){if(!(A instanceof LQ))throw TypeError("query() requires an instance of Query");return{subscribe:(Q)=>{if(this.#C)throw Error("The query store has been disposed");let B=typeof Q==="function"?{next:Q}:Q||{},C=this.#B.get(A);if(C){if(C.observers.add(B),C.hasValue)try{B.next?.(C.currentValue)}catch(K){yA(K)}}else C=new c8(this,A),this.#B.set(A,C),C.observers.add(B),C.boot();let J=!1;return{get closed(){return J},unsubscribe:()=>{if(J)return;if(J=!0,C.observers.delete(B),C.observers.size===0)this._evict(A,C),C.kill()}}},peek:async()=>{let Q=this.#B.get(A);if(Q&&await Q.received)return Q.currentValue;if(typeof A.fetch!=="function")throw TypeError(`${A.constructor.name} is not active and does not implement fetch()`);let B=await this.#A.lease(...this.#J(A));try{return await A.fetch(B.resources,{engineFeed:this.#A.feed,bootFeed:Q?.bootFeed,killFeed:Q?.killFeed})}finally{await B.release()}}}}async dispose(){if(this.#C)return;this.#C=!0;for(let A of[...this.#B.values?.()??[]])await A.kill()}}class nC{#A;#Q;#B;#C=!1;constructor({providers:A,interceptors:Q,hooks:B,container:C,dispatcher:J,queries:K}={}){this.#A=C??new yQ({providers:A}),this.#Q=J??new dC({container:this.#A,interceptors:Q}),this.#B=K??new aC({container:this.#A,dispatcher:this.#Q,createControllerMap:B?.createQueryControllersMap})}get container(){return this.#A}get dispatcher(){return this.#Q}get queries(){return this.#B}get feed(){return this.#A.feed}dispatch(A){return this.#Q.dispatch(A)}query(A){return this.#B.query(A)}async dispose(){if(this.#C)return;this.#C=!0,await this.#B.dispose(),await this.#A.dispose()}}function sC(A,Q,B,C){let J=A?.[Q];return J&&J.ref===B?J:{ref:B,...C}}var cB="promptValue",dB="pluginReview";function d8(A,Q){let B=A?.[cB];return B&&B.ref===Q?B.value:Q?.value??""}function a8(A){let Q=aB(A);if(Q.status==="invalid")return{status:Q.status,allowed:!1,requiresAcknowledgement:!1,headline:"This package has been altered",detail:`${Q.explanation}. It was signed, and the signature does not match its contents — so it is not what its author published. Trove will not install it.`};if(Q.status==="unverified")return{status:Q.status,allowed:!0,requiresAcknowledgement:!0,headline:"Unsigned — for development only",detail:"Nobody has signed this package, so there is no way to tell who wrote it or whether it has been altered since. Install it only if you built it yourself or you trust wherever you got it from."};if(Q.status==="signed")return{status:Q.status,allowed:!0,requiresAcknowledgement:!1,headline:"Signed, but the domain does not vouch for the key",detail:`${Q.explanation}. The signature is real; what is unproven is that ${Q.domain||"the publisher"} authorised it.`};return{status:Q.status,allowed:!0,requiresAcknowledgement:!1,headline:null,detail:null}}function aB(A){let Q=A||{};switch(Q.status){case"verified":return{status:"verified",tone:"verified",icon:"check",domain:Q.domain||null,explanation:Q.domain?`Signed by a key published at ${Q.domain}`:"Signed by a key the publishing domain vouches for",severity:0};case"signed":return{status:"signed",tone:"signed",icon:"info",domain:Q.domain||null,explanation:Q.reason||"Signed, but the domain does not vouch for the key",severity:1};case"invalid":return{status:"invalid",tone:"invalid",icon:"warn",domain:Q.domain||null,explanation:Q.reason||"The signature did not verify — this package may have been altered",severity:3};default:return{status:"unverified",tone:"unverified",icon:"warn",domain:Q.domain||null,explanation:Q.reason||"This plugin is not signed",severity:2}}}async function n8(A,Q){try{let B=new Uint8Array(await Q.arrayBuffer());await o8(A,tQ(B))}catch(B){A.notifications.error(`Couldn't read the plugin: ${B.message}`)}}async function s8(A,Q){try{let B=await v8(Q,(C,J)=>fetch(C,J));await o8(A,B)}catch(B){A.notifications.error(`Couldn't fetch the plugin: ${B.message}`)}}async function o8({notifications:A,overlay:Q,plugins:B,social:C,workbench:J},K){let E=dA(K.manifest);if(B.plugins.has(JQ(K.manifest))){A.warn(`“${E}” is already installed.`);return}let Y={status:"unverified"};try{Y=await B.assessTrust(K)}catch{}let L=a8(Y);if(!L.allowed){A.error(`“${E}” was not installed. ${L.detail}`,{sticky:!0});return}Q.set({dialog:{kind:"plugin-review",summary:f8(K,Y),policy:L,isAdmin:!!C.get().admin,installActions:[new DJ(K,Y,E)]}})}function yG(A,Q=null){return{...A?.meta||{},...Q||A?.tags||{}}}function hG(A,Q){if(Q.present)return A!=null&&A!==!1&&A!=="";if(A==null)return!1;let B=Number(A),C=Number(Q.value),J=A!==""&&A!==!0&&A!==!1&&Q.value!==""&&Q.value!=null&&!Number.isNaN(B)&&!Number.isNaN(C),K=J?B:String(A).toLowerCase(),E=J?C:String(Q.value).toLowerCase();switch(Q.op){case"!=":return K!==E;case"<":return K<E;case"<=":return K<=E;case">":return K>E;case">=":return K>=E;default:return K===E}}function i8(A,Q,B=null){let C=yG(A,B);return(Q||[]).every((J)=>hG(C[J.key],J))}var bG=/#([\w.-]+)(?::(<=|>=|!=|=|<|>)?("[^"]*"|[^#\s]+)?)?/g;function nB(A){let Q=[],B=A;for(let C of A.matchAll(bG)){let[,J,K,E]=C,Y=E&&E.startsWith('"')?E.slice(1,-1):E;Q.push(Y==null||Y===""?{key:J,present:!0}:{key:J,op:K||"=",value:Y,present:!1}),B=B.replace(C[0]," ")}return{text:B.replace(/\s+/g," ").trim(),filters:Q}}function r8(A,Q){if(!Q||!Q.length)return!0;return i8(A,Q)}function oC(A){return A.present?`#${A.key}`:`#${A.key}:${A.op}${A.value}`}function sB(A){let Q=(A?.name||"").toLowerCase();return Q.includes(".")?Q.slice(Q.lastIndexOf(".")):""}var t8=[{kind:"audio",icon:"file-audio",mime:["audio/"],ext:[".mp3",".flac",".wav",".opus",".ogg",".m4a",".m4b"]},{kind:"image",icon:"file-image",mime:["image/"],ext:[".png",".jpg",".jpeg",".gif",".webp",".svg",".avif"]},{kind:"video",icon:"file-video",mime:["video/"],ext:[".mp4",".webm",".mkv",".mov"]},{kind:"text",icon:"file-text",mime:["text/","application/json"],ext:[".txt",".md",".markdown",".json",".js",".mjs",".ts",".jsx",".tsx",".css",".html",".xml",".yaml",".yml",".toml",".ini",".log",".csv",".py",".rb",".go",".rs",".sh",".c",".h",".cpp",".java"]}];function vG(A,Q,B){if(A.ext.includes(Q))return!0;return A.mime.some((C)=>C.endsWith("/")?B.startsWith(C):B===C)}function e8(A){let Q=sB(A),B=A?.contentType||"";for(let C of t8)if(vG(C,Q,B))return C.kind;return"file"}var fG={...Object.fromEntries(t8.map((A)=>[A.kind,A.icon])),file:"file"};function MQ(A){return fG[e8(A)]||"file"}function AY(A){return e8(A)==="text"}var RB="openers.associations";function ZJ(A,Q){return{id:A.id,title:A.title??A.name??A.id,match:A.match??null,priority:A.priority??0,pluginId:A.pluginId??null,source:A.pluginId?Q?.plugins?.get(A.pluginId)?.manifest?.displayName||A.pluginId:"Built-in"}}function QY(A,Q){return(A||[]).filter((B)=>TC(B.match,Q))}function BY(A){return sB(A)||A?.contentType||""}function CY(A){let Q=sB(A);if(Q)return`${Q} files`;let B=A?.contentType||"";return B?`${B} files`:"this file type"}function JY(A,Q){return A.contributions.openersFor(Q).filter((B)=>(!B.when||A.context.evaluate(B.when))&&A.plugins.isAvailable(B)).sort((B,C)=>(C.priority??0)-(B.priority??0)).map((B)=>ZJ(B,A.plugins))}function KY(A,Q){let B=A.settings.get(RB)||{},C=sB(Q),J=Q?.contentType||"",K=J.includes("/")?`${J.slice(0,J.indexOf("/")+1)}*`:"";return C&&B[C]||J&&B[J]||K&&B[K]||null}function EY(A,Q,B){let C={...A||{}};if(B)C[Q]=B;else delete C[Q];return C}var LY="trove:",XY=255;var HY=/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;function iC(A){if(typeof A!=="string"||!A.toLowerCase().startsWith(LY))return null;let Q;try{Q=new URL(A)}catch{return null}let B=Q.pathname,C=B.indexOf("/"),J=C<0?B:B.slice(0,C);if(!HY.test(J))return null;let K=Q.searchParams.get("id"),E=Q.searchParams.get("name"),Y="";if(C>=0)try{Y=decodeURIComponent(B.slice(C+1))}catch{return null}if(K!=null&&(E!=null||Y))return null;let L=K!=null?"id":"name",X=K!=null?K:E!=null?E:Y;if(!X||X.length>XY)return null;return{collection:J,by:L,value:X}}function YY({collection:A,by:Q,value:B}){return`${LY}${A}?${Q}=${encodeURIComponent(B)}`}function oB(A,Q="name"){let B=A?.collectionId||"default";if(Q==="id"){if(!A?.id)throw q.invalid("trove: link by id needs a node id");return YY({collection:B,by:"id",value:A.id})}if(!A?.name)throw q.invalid("trove: link by name needs a node name");return YY({collection:B,by:"name",value:A.name})}var uG="/c";function GY(A,Q="",B="name"){if(!A?.collectionId)throw q.invalid("An item needs a collection to be linked to");let C=B==="id"?`id:${A.id}`:encodeURIComponent(A.name);if(!C||B==="id"&&!A.id)throw q.invalid("Nothing to link to");let J=`${uG}/${encodeURIComponent(A.collectionId)}/i/${C}`;return Q?`${String(Q).replace(/\/$/,"")}${J}`:J}function $Y(A){let Q;try{Q=A.startsWith("/")?A:new URL(A).pathname}catch{return null}let B=/^\/c\/([^/]+)\/i\/(.+)$/.exec(Q);if(!B)return null;let C,J;try{C=decodeURIComponent(B[1]),J=decodeURIComponent(B[2])}catch{return null}if(!HY.test(C))return null;let K=J.startsWith("id:"),E=K?J.slice(3):J;if(!E||E.length>XY)return null;return{collection:C,by:K?"id":"name",value:E}}function iB(A){let Q=A?.selection||[],B=A?.selectionNodes;if(B?.length)return B.filter((C)=>Q.includes(C.id));return(A?.items||[]).filter((C)=>Q.includes(C.id))}class WJ{#A;constructor(A=null){this.#A={items:[]},this.cell=c(this.#A),this._controllers=new Map,this.activity=A,this._tasks=new Map,this._retries=new Map}get(){return this.#A}observe(){return this.cell}#Q(){this.cell.setValue(this.#A)}start(A,Q,B,C,{retry:J=null}={}){if(this._controllers.set(A,C),J)this._retries.set(A,J);this.#A={items:[...this.#A.items,{id:A,name:Q,direction:"up",ratio:0,loaded:0,total:B,status:"active",error:null,retryable:!!J}]},this.#Q(),this.#B(A,Q,B)}#B(A,Q,B){let C=this.activity?.start({kind:"transfer",title:`Uploading ${Q}`,total:B||null,unit:"bytes",onCancel:()=>this.cancel(A)});if(C)this._tasks.set(A,C)}retry(A){let Q=this._retries.get(A);if(!Q)return null;let B=this.#A.items.find((C)=>C.id===A);if(!B||B.status==="active")return null;return Q()}restart(A,Q){this._controllers.set(A,Q);let B=this.#A.items.find((C)=>C.id===A);this.#A={items:this.#A.items.map((C)=>C.id===A?{...C,status:"active",error:null,ratio:0,loaded:0}:C)},this.#Q(),this.#B(A,B?.name||"file",B?.total||null)}progress(A,{loaded:Q,total:B,ratio:C}){this.#A={items:this.#A.items.map((J)=>J.id===A?{...J,loaded:Q,total:B,ratio:C}:J)},this.#Q(),this._tasks.get(A)?.progress({done:Q,total:B||null})}finish(A,Q="done",B=null){this.#A={items:this.#A.items.map((J)=>J.id===A?{...J,status:Q,error:B,ratio:Q==="done"?1:J.ratio}:J)},this._controllers.delete(A),this.#Q();let C=this._tasks.get(A);if(C){if(Q==="done")C.succeed();else if(Q==="cancelled")C.cancel();else C.fail(B||Error("Upload failed"));this._tasks.delete(A)}if(Q==="done")setTimeout(()=>this.dismiss(A),4000)}cancel(A){this._controllers.get(A)?.abort(),this.finish(A,"cancelled")}dismiss(A){this.#A={items:this.#A.items.filter((Q)=>Q.id!==A)},this._retries.delete(A),this.#Q()}clearDone(){let A=this.#A.items.filter((B)=>B.status==="active"),Q=new Set(A.map((B)=>B.id));for(let B of[...this._retries.keys()])if(!Q.has(B))this._retries.delete(B);this.#A={items:A},this.#Q()}}function rC(A){let Q=A?.draft?.caps||{},B=Object.entries(Q).filter(([,C])=>C.length).map(([C,J])=>({collectionId:C,capabilities:J}));return B.length?B:null}function DY(A,{open:Q,scan:B,rotate:C,create:J,access:K}){let E=A?.collectionId;return{rows:(A?.collections||[]).map((L)=>({id:L.id,name:L.name||L.id,driver:L.driver||"unknown",system:!!L.system,current:L.id===E,fingerprint:L.encryption?.fingerprint||null,encrypted:!!L.encryption,capabilities:L.capabilities||[],actions:{open:[Q(L.id)],scan:[Q(L.id),B()],rotate:L.encryption?[Q(L.id),C()]:null,access:L.capabilities?.includes("admin")?[K(L.id)]:null}})),canCreate:!!A?.canCreateCollection,create:[J()]}}function tC(A,Q,B){let C=A?.collectionId,J=(A?.collections||[]).map((K)=>({label:K.name||K.id,icon:K.id===C?"check":"files",actions:[Q(K.id)]}));if(A?.canCreateCollection){if(J.length)J.push({sep:!0});J.push({label:"New collection…",icon:"plus",actions:[B()]})}return J}function ZY(A){return new Promise((Q)=>{let B=document.createElement("input");B.type="file",A(B),B.style.display="none",document.body.appendChild(B);let C=(K)=>{Q(K),B.remove(),window.removeEventListener("focus",J)},J=()=>setTimeout(()=>{if(!B.files.length)C(null)},300);B.addEventListener("change",()=>C(B.files),{once:!0}),window.addEventListener("focus",J),B.click()})}function WY(){return ZY((A)=>{A.multiple=!0})}function UY(){return ZY((A)=>{A.accept=".zip,application/zip"}).then((A)=>A?.[0]??null)}function IY(A,Q){let B=document.createElement("a");B.href=A,B.download=Q||"",document.body.appendChild(B),B.click(),B.remove()}function hQ(A={}){let Q=c(A);return{observe:()=>Q,get:()=>Q.getValue(),set:(B)=>Q.setValue({...Q.getValue(),...B})}}var FY=(A)=>hQ({items:[],loading:!1,error:null,selection:[],sort:A.get("explorer.sort"),order:A.get("explorer.sortOrder"),collectionId:null,collections:[],canCreateCollection:!1,gate:null,stats:null,usage:null,nextCursor:null,loadingMore:!1,trash:null,selectionNodes:null}),RY=()=>hQ({query:"",mode:"hybrid",results:[],loading:!1,error:null,ran:!1,paletteFiles:[],paletteQuery:"",paletteLoading:!1,paletteError:null,filtered:!1,offline:!1,resolved:null}),MY=()=>hQ({keys:[],loading:!1,loaded:!1,error:null,minted:null,busy:null,draft:null,forbidden:!1}),VY=()=>hQ({}),zY=()=>hQ({palette:null,dialog:null,contextMenu:null,pluginPanel:null,activityPanel:!1}),qY=()=>hQ({activity:"home",sidebarVisible:!0,launch:{query:"",index:0},aclFor:null,searchModal:!1,sheet:null,infoPanel:!1});function UJ(A,Q,B){return(A+Q+B)%B}var NY=()=>hQ({collectionId:null,grants:[],admins:[],loading:!1,error:null,busy:!1}),PY=()=>hQ({collectionId:null,rotation:null,estimate:null,loading:!1,error:null,busy:!1});class hA extends P{static deps=["api","explorer","notifications","settings"];constructor(A){super();this.collectionId=A}async execute(A){let{api:Q,explorer:B,notifications:C,settings:J}=A,K=this.collectionId||B.get().collectionId;if(!K){B.set({loading:!1,gate:"choose"});return}let E=K!==B.get().collectionId;B.set({loading:!0,error:null,collectionId:K,...E?{trash:null}:{}});try{let Y=J.get("explorer.sort"),L=J.get("explorer.sortOrder"),X=await Q.list(K,{sort:Y,order:L});B.set({items:X.items,loading:!1,selection:[],sort:Y,order:L,collectionId:X.collectionId||K,stats:X.stats||null,usage:X.usage||null,nextCursor:X.nextCursor||null}),J.set("explorer.lastCollection",K),B.set({gate:null})}catch(Y){B.set({loading:!1,error:Y.message}),C.error(`Couldn't load this collection: ${Y.message}`)}}}class IJ extends P{static deps=["api","explorer"];async execute(A){try{let Q=await A.api.collections(),B=Q.collections||[];return A.explorer.set({collections:B,canCreateCollection:!!Q.canCreate}),B}catch{return[]}}}class FJ extends P{static deps=["api","engine","explorer","notifications","settings"];async execute(A){let Q=$Y(typeof location<"u"?location.pathname:"");if(Q)return this.#A(A,Q);let B=[],C=!1;try{let E=await A.api.collections();B=E.collections||[],C=!!E.canCreate,A.explorer.set({collections:B,canCreateCollection:C})}catch(E){A.explorer.set({loading:!1,error:`Couldn't load your collections: ${E.message}`});return}let J=B.map((E)=>E.id),K=A.settings.get("explorer.lastCollection");if(!J.length){A.explorer.set({loading:!1,items:[],collections:[],gate:C?"create":null,error:C?null:"You do not have access to any collections yet. Ask an administrator to grant you one."});return}if(!K||!J.includes(K)){A.explorer.set({loading:!1,items:[],gate:"choose",error:null});return}return A.explorer.set({gate:null}),A.engine.dispatch(new hA(K))}async#A(A,Q){let{api:B,engine:C,explorer:J,notifications:K}=A;if(typeof history<"u")history.replaceState(null,"","/");let E=[];try{let L=await B.collections();E=L.collections||[],J.set({collections:E,canCreateCollection:!!L.canCreate})}catch(L){J.set({loading:!1,error:`Couldn’t load your collections: ${L.message}`});return}if(!E.some((L)=>L.id===Q.collection)){J.set({loading:!1,items:[],gate:null,error:`This link points at a collection you do not have access to (“${Q.collection}”). Ask whoever shared it to grant you access.`});return}J.set({gate:null}),await lA(C,new hA(Q.collection));let Y;try{Y=(Q.by==="id"?await B.stat(Q.value):await B.stat(Q.value,{collection:Q.collection}))?.node||null}catch{Y=null}if(!Y?.id){K.warn(Q.by==="name"?`“${Q.value}” is not in this collection any more — it may have been renamed or removed.`:"That item no longer exists.");return}C.dispatch(new aA(Y,{reset:!0}))}}class N extends P{static deps=["commands"];constructor(A,...Q){super();this.id=A,this.args=Q}async execute({commands:A}){return A.execute(this.id,...this.args)}}class RJ extends P{static deps=["notifications","plugins"];constructor(A){super();this.pluginId=A}async execute(A){try{await A.plugins.uninstall(this.pluginId)}catch(Q){A.notifications.error(`Couldn’t uninstall: ${Q.message}`)}}}class OY extends P{static deps=["api","engine","notifications"];constructor(A){super();this.record=A}async execute(A){try{let Q=await A.api.createCollection(this.record);A.notifications.success(`Created collection “${Q.collection.name}”`),await lA(A.engine,new IJ),A.engine.dispatch(new hA(Q.collection.id))}catch(Q){A.notifications.error(`Couldn’t create collection: ${Q.message}`)}}}class MJ extends P{static deps=["api","explorer","notifications"];async execute(A){let{api:Q,explorer:B,notifications:C}=A,J=B.get().nextCursor;if(!J||B.get().loadingMore)return;B.set({loadingMore:!0});try{let K=await Q.list(B.get().collectionId,{sort:B.get().sort,order:B.get().order,cursor:J});B.set({items:[...B.get().items,...K.items],nextCursor:K.nextCursor||null,loadingMore:!1})}catch(K){B.set({loadingMore:!1}),C.error(`Couldn't load more: ${K.message}`)}}}class rB extends P{static deps=["engine","explorer"];async execute(A){return A.engine.dispatch(new hA(A.explorer.get().collectionId))}}class eQ extends P{static deps=["api","engine","explorer","notifications"];constructor(A="list",Q=null){super();this.op=A,this.id=Q}async execute(A){let{api:Q,explorer:B,notifications:C}=A,J=B.get().collectionId;if(this.op==="hide"){B.set({trash:null});return}try{if(this.op==="restore"){let{node:E}=await Q.restore(this.id);C.success(`Restored “${E.name}”`)}else if(this.op==="purge")await Q.purgeTrash({id:this.id});else if(this.op==="empty"){let{purged:E}=await Q.purgeTrash({collection:J});C.success(`Deleted ${E} item${E===1?"":"s"} for good`)}let{items:K}=await Q.trash(J);if(B.set({trash:K}),this.op!=="list")A.engine.dispatch(new hA(J))}catch(K){C.error(`Trash: ${K.message}`)}}}class jY extends P{static deps=["api","engine","navigation","notifications"];constructor(A){super();this.ids=A}async execute(A){try{for(let Q of this.ids)await A.api.remove(Q);A.notifications.info(`Deleted ${this.ids.length} item${this.ids.length>1?"s":""}`);for(let Q of this.ids)A.navigation.forget(Q)}catch(Q){A.notifications.error(`Couldn’t delete: ${Q.message}`)}A.engine.dispatch(new rB)}}class SY extends P{static deps=["api","engine","navigation","notifications"];constructor(A,Q){super();this.id=A,this.newName=Q}async execute(A){try{let Q=await A.api.rename(this.id,this.newName);A.navigation.updateTabNode(Q.node),A.engine.dispatch(new rB)}catch(Q){A.notifications.error(`Couldn’t rename: ${Q.message}`)}}}class aA extends P{static deps=["context","contributions","engine","plugins","settings"];constructor(A,Q={}){super();this.node=A,this.opts=Q}async execute(A){if(!this.node)return;let Q=(J)=>A.engine.dispatch(new HQ(this.node,J,{reset:!!this.opts.reset}));if(this.opts.openerId)return Q(this.opts.openerId);let B=JY(A,this.node),C=KY(A,this.node);if(C&&B.some((J)=>J.id===C))return Q(C);if(B.length>1)return A.engine.dispatch(new sA({kind:"opener-chooser",node:this.node,openers:B,reset:!!this.opts.reset}));Q(B[0]?.id||"core.fallback")}}class tB extends P{static deps=["api","engine","explorer","notifications","settings","transfers"];constructor(A,Q){super();this.files=A,this.collectionId=Q}async execute(A){let Q=this.collectionId||A.explorer.get().collectionId;if(!Q){A.notifications.error("Open a collection before uploading");return}let B=A.settings.get("uploads.concurrency"),C=[...this.files].map((J)=>this.#A(A,J,Q,B));await Promise.allSettled(C),A.engine.dispatch(new hA(Q))}async#A(A,Q,B,C,J=null){let{api:K,notifications:E,transfers:Y}=A,L=J||rE("xfer"),X=new AbortController;if(J)Y.restart(L,X);else Y.start(L,Q.name,Q.size,X,{retry:()=>this.#A(A,Q,B,C,L)});let H=null;try{let G=await K.upload(Q,{collection:B,concurrency:C,signal:X.signal,onStart:(D)=>{H=D},onProgress:(D)=>Y.progress(L,D)});if(Y.finish(L,"done"),G?.name&&G.name!==Q.name)E.info(`"${Q.name}" already existed — saved as "${G.name}".`)}catch(G){if(H)K.abortUpload(H).catch(()=>{});if(G.code==="aborted")Y.finish(L,"cancelled");else Y.finish(L,"error",G.message),E.error(`Upload failed: ${Q.name} — ${G.message}. Retry it from the transfers tray.`)}}}class MB extends P{static deps=["api","explorer","offline","search"];constructor(A,Q){super();this.filters=A||[],this.text=Q||""}async execute(A){let{api:Q,search:B}=A;if(!this.filters.length){B.set({results:[],ran:!1,filtered:!1});return}if(B.set({query:this.text,loading:!0,error:null,filtered:!0}),A.offline&&!A.offline.get().online){let C=(A.explorer.get().items||[]).filter((J)=>r8(J,this.filters));B.set({results:C.map((J)=>({node:J})),loading:!1,ran:!0,filtered:!0,offline:!0});return}try{let C=await Q.tagSearch(this.filters,this.text.trim()||void 0,{limit:100});B.set({results:(C.items||[]).map((J)=>({node:J})),loading:!1,ran:!0,filtered:!0,offline:!1})}catch(C){B.set({loading:!1,error:C.message,ran:!0,filtered:!0})}}}class VJ extends P{static deps=["api","overlay","search"];constructor(A){super();this.query=A}async execute(A){let{api:Q,overlay:B,search:C}=A;if(B.get().palette?.mode!=="files")return;let J=(this.query||"").trim();if(!J){C.set({paletteFiles:[],paletteQuery:"",paletteError:null,paletteLoading:!1});return}C.set({paletteQuery:J,paletteLoading:!0,paletteError:null});try{let K=await Q.search(J,{mode:"keyword",limit:30});if(C.get().paletteQuery!==J)return;C.set({paletteFiles:K.results||[],paletteLoading:!1})}catch(K){if(C.get().paletteQuery!==J)return;C.set({paletteFiles:[],paletteLoading:!1,paletteError:K?.message||"Search failed"})}}}class VQ extends P{static deps=["api","contributions","offline","search","settings"];constructor(A,Q){super();this.query=A,this.mode=Q}async execute(A){let{api:Q,contributions:B,search:C,settings:J}=A,K=this.query.trim();if(!K){C.set({query:"",results:[],ran:!1,error:null,resolved:null});return}let E=this.mode||J.get("search.mode");C.set({query:this.query,mode:E,loading:!0,error:null,resolved:null,filtered:!1});let Y=()=>C.get().query!==this.query,L=A.offline;if(L&&!L.get().online){try{let X=await L.searchOffline(K,{limit:40});if(Y())return;C.set({results:X,loading:!1,ran:!0,offline:!0,resolved:null})}catch(X){if(Y())return;C.set({results:[],loading:!1,ran:!0,offline:!0,error:X.message})}return}try{let X=B.ofType("view").map((G)=>({id:G.id,title:G.title||G.id})),H=await Q.query(K,{mode:E,limit:40,views:X});if(Y())return;C.set({results:H.results,resolved:H.resolved||null,loading:!1,ran:!0,offline:!1})}catch(X){if(Y())return;if(L){let H=await L.searchOffline(K,{limit:40});if(Y())return;C.set({results:H,loading:!1,ran:!0,offline:!0,error:H.length?null:X.message})}else C.set({loading:!1,error:X.message,ran:!0})}}}class eB extends P{static deps=["api","apiKeys"];async execute(A){A.apiKeys.set({loading:!0,error:null});try{let Q=await A.api.apiKeys();A.apiKeys.set({keys:Q.keys||[],loading:!1,loaded:!0,error:null})}catch(Q){if(Q?.status===403||Q?.code==="forbidden"){A.apiKeys.set({keys:[],loading:!1,loaded:!0,error:null,forbidden:!0});return}A.apiKeys.set({loading:!1,error:Q?.message||"Could not load API keys"})}}}class _Y extends P{static deps=["api","apiKeys","notifications"];constructor(A){super();this.spec=A}async execute(A){A.apiKeys.set({busy:"mint",error:null});try{let{key:Q,secret:B}=await A.api.mintApiKey(this.spec);A.apiKeys.set({minted:{key:Q,secret:B},busy:null});let C=await A.api.apiKeys().catch(()=>null);if(C)A.apiKeys.set({keys:C.keys||[]});return Q}catch(Q){return A.apiKeys.set({busy:null,error:Q?.message||"Could not create the key"}),A.notifications.error(Q?.message||"Could not create the key"),null}}}class zJ extends P{static deps=["api","apiKeys","notifications"];constructor(A){super();this.id=A}async execute(A){A.apiKeys.set({busy:this.id,error:null});try{await A.api.revokeApiKey(this.id);let Q=await A.api.apiKeys().catch(()=>null);A.apiKeys.set({busy:null,...Q?{keys:Q.keys||[]}:{}}),A.notifications.success("Key revoked")}catch(Q){A.apiKeys.set({busy:null}),A.notifications.error(Q?.message||"Could not revoke the key")}}}class qJ extends P{static deps=["keybindings"];constructor(A,Q){super();this.bindingId=A,this.key=Q}async execute({keybindings:A}){let Q=A.resolved().find((B)=>B.bindingId===this.bindingId);if(!Q)return;A.rebind(Q,this.key)}}class tA extends P{static deps=["notifications"];constructor(A,Q="Copied"){super();this.text=A,this.label=Q}async execute({notifications:A}){try{await navigator.clipboard.writeText(this.text),A.success(this.label)}catch{A.info(this.text,{sticky:!0})}}}class NJ extends P{static deps=["notifications"];constructor(A){super();this.id=A}async execute({notifications:A}){A.dismiss(this.id)}}class XQ extends P{static deps=["workbench"];async execute({workbench:A}){this.apply(A)}}class bA extends P{static deps=["overlay"];async execute({overlay:A}){this.apply(A)}}class wY extends P{static deps=["navigation"];async execute({navigation:A}){this.apply(A)}}class TA extends bA{apply(A){A.set({dialog:null})}}class AC extends bA{constructor(A){super();this.patch=A}apply(A){let Q=A.get().dialog;if(Q)A.set({dialog:{...Q,...this.patch}})}}class VB extends bA{apply(A){A.set({contextMenu:null})}}class QC extends bA{apply(A){A.set({palette:null})}}class PJ extends bA{constructor(A){super();this.query=A}apply(A){let Q=A.get().palette;if(Q)A.set({palette:{...Q,query:this.query,index:0}})}}class OJ extends bA{constructor(A){super();this.index=A}apply(A){let Q=A.get().palette;if(Q)A.set({palette:{...Q,index:this.index}})}}class eC extends bA{constructor(A,Q){super();this.delta=A,this.count=Q}apply(A){let Q=A.get().palette;if(!Q||!this.count)return;A.set({palette:{...Q,index:UJ(Q.index,this.delta,this.count)}})}}class jJ extends XQ{apply(A){A.set({searchModal:!0,launch:{query:"",index:0}})}}class zB extends XQ{apply(A){A.set({searchModal:!1})}}class SJ extends XQ{constructor(A){super();this.collectionId=A}apply(A){A.set({aclFor:A.get().aclFor===this.collectionId?null:this.collectionId})}}class AB extends XQ{constructor(A){super();this.query=A}apply(A){A.set({launch:{query:this.query,index:0}})}}class _J extends XQ{constructor(A){super();this.index=A}apply(A){A.set({launch:{...A.get().launch,index:this.index}})}}class A0 extends XQ{constructor(A){super();this.which=A}apply(A){A.set({sheet:A.get().sheet===this.which?null:this.which})}}class nA extends XQ{apply(A){A.set({sheet:null})}}class BC extends XQ{constructor(A){super();this.open=A}apply(A){A.set({infoPanel:this.open??!A.get().infoPanel})}}class CC extends bA{constructor(A){super();this.pluginId=A}apply(A){A.set({pluginPanel:this.pluginId})}}class wJ extends bA{apply(A){A.set({pluginPanel:null})}}class HQ extends P{static deps=["navigation","workbench"];constructor(A,Q,B={}){super();this.node=A,this.openerId=Q,this.opts=B}async execute({navigation:A,workbench:Q}){Q.set({activity:"home",searchModal:!1}),A.openFile(this.node,this.openerId,this.opts)}}class JC extends P{static deps=["activity"];async execute(A){this.apply(A.activity)}}class SA extends P{static deps=["activity","overlay"];constructor(A){super();this.which=A}async execute({activity:A,overlay:Q}){let B=this.which??!Q.get().activityPanel;if(Q.set({activityPanel:B}),B)await A.refresh()}}class TJ extends JC{constructor(A){super();this.id=A}apply(A){A.cancel(this.id)}}class xJ extends JC{constructor(A){super();this.id=A}apply(A){A.dismiss(this.id)}}class kJ extends JC{constructor(A){super();this.id=A}apply(A){A.retryIssue(this.id)}}class gJ extends JC{constructor(A){super();this.id=A}apply(A){A.dismissIssue(this.id)}}class KC extends P{static deps=["transfers"];async execute(A){this.apply(A.transfers)}}class EC extends KC{constructor(A){super();this.id=A}apply(A){A.cancel(this.id)}}class yJ extends KC{constructor(A){super();this.id=A}apply(A){A.retry(this.id)}}class hJ extends KC{constructor(A){super();this.id=A}apply(A){A.dismiss(this.id)}}class bJ extends KC{apply(A){A.clearDone()}}class GQ extends P{static deps=["social"];async execute(A){return this.apply(A.social)}}class zQ extends GQ{constructor(A){super();this.open=A}apply(A){A.toggleInbox(this.open)}}class YC extends GQ{apply(A){return A.enablePush()}}class Q0 extends GQ{constructor(A){super();this.body=A}apply(A){return A.comment(this.body)}}class vJ extends GQ{constructor(A){super();this.commentId=A}apply(A){return A.deleteComment(this.commentId)}}class fJ extends GQ{constructor(A,Q){super();this.commentId=A,this.emoji=Q}apply(A){return A.react(this.commentId,this.emoji)}}class B0 extends GQ{constructor(A){super();this.target=A}apply(A){A.setReplyTo(this.target)}}class uJ extends GQ{constructor(A,Q){super();this.name=A,this.value=Q}apply(A){A.addTag(this.name,this.value)}}class mJ extends GQ{constructor(A){super();this.name=A}apply(A){A.removeTag(this.name)}}class LC extends GQ{constructor(A){super();this.nodeId=A}apply(A){A.loadSidecar(this.nodeId)}}class qB extends P{static deps=["apiKeys"];async execute(A){this.apply(A.apiKeys)}}class C0 extends qB{constructor(A){super();this.patch=A}apply(A){let Q=A.get().draft;if(Q)A.set({draft:{...Q,...this.patch}})}}class pJ extends qB{constructor(A,Q){super();this.collectionId=A,this.capability=Q}apply(A){let Q=A.get().draft;if(!Q)return;let B={...Q.caps},C=new Set(B[this.collectionId]||[]);if(C.has(this.capability))C.delete(this.capability);else C.add(this.capability);if(C.size)B[this.collectionId]=[...C];else delete B[this.collectionId];A.set({draft:{...Q,caps:B}})}}class lJ extends P{static deps=["explorer","workbench"];constructor(A,Q){super();this.delta=A,this.nodes=Q}async execute({workbench:A,explorer:Q}){let B=this.nodes.length;if(!B)return;let C=UJ(A.get().launch.index,this.delta,B);A.set({launch:{...A.get().launch,index:C}}),TY(Q,this.nodes[C])}}class cJ extends P{static deps=["explorer","workbench"];constructor(A,Q){super();this.index=A,this.node=Q}async execute({workbench:A,explorer:Q}){A.set({launch:{...A.get().launch,index:this.index}}),TY(Q,this.node)}}function TY(A,Q){let B=Q?.id?[Q.id]:[],C=A.get().selection;if(B.length===C.length&&B.every((J,K)=>J===C[K]))return;A.set({selection:B,selectionNodes:Q?[Q]:null})}class QB extends P{static deps=["viewState"];constructor(A,Q){super();this.key=A,this.value=Q}async execute({viewState:A}){A.set({[this.key]:this.value})}}class $Q extends bA{constructor(A,Q=null){super();this.items=A,this.at=Q?.rect?{prefer:Q.prefer||"down",rect:{left:Q.rect.left,top:Q.rect.top,right:Q.rect.right,bottom:Q.rect.bottom}}:Q?{x:Q.x,y:Q.y}:null}apply(A){A.set({contextMenu:{items:this.items,at:this.at}})}}class sA extends bA{constructor(A){super();this.dialog=A}apply(A){A.set({dialog:this.dialog})}}class bQ extends P{static deps=["settings"];constructor(A,Q){super();this.key=A,this.value=Q}async execute({settings:A}){A.set(this.key,this.value)}}class XC extends P{static deps=["settings"];constructor(A,Q){super();this.typeKey=A,this.openerId=Q}async execute({settings:A}){if(!this.typeKey)return;A.set(RB,EY(A.get(RB),this.typeKey,this.openerId))}}class dJ extends wY{apply(A){A.back()}}class vQ extends P{static deps=["navigation","workbench"];async execute({navigation:A,workbench:Q}){Q.set({activity:"home",searchModal:!1}),A.reset()}}class aJ extends P{static deps=["plugins"];constructor(A){super();this.pluginId=A}async execute({plugins:A}){return A.refresh(this.pluginId)}}class nJ extends P{static deps=["plugins"];constructor(A,Q,B){super();this.pluginId=A,this.key=Q,this.value=B}async execute({plugins:A}){return A.setSecret(this.pluginId,this.key,this.value)}}class sJ extends P{static deps=["api","engine","notifications","workbench"];constructor(A){super();this.nodeId=A}async execute({api:A,engine:Q,notifications:B,workbench:C}){let J;try{({node:J}=await A.stat(this.nodeId))}catch(K){B.warn(K?.status===403||K?.code==="forbidden"?"You no longer have access to that item.":"That item no longer exists.");return}await lA(Q,new aA(J)),C.set({infoPanel:!0})}}class oJ extends P{static deps=["overlay","viewState"];async execute(A){let B=(A.viewState.get()[cB]?.value??"").trim();if(A.overlay.set({dialog:null}),B)await this.withValue(B,A)}}class xY extends oJ{static deps=["engine","overlay","viewState"];constructor(A){super();this.node=A}async withValue(A,{engine:Q}){if(A!==this.node.name)Q.dispatch(new SY(this.node.id,A))}}class DJ extends P{static deps=["notifications","overlay","plugins","viewState","workbench"];constructor(A,Q,B){super();this.pkg=A,this.trust=Q,this.label=B}async execute({notifications:A,overlay:Q,plugins:B,viewState:C,workbench:J}){let K=[...C.get()[dB]?.grants||[]];Q.set({dialog:null}),J.set({activity:"plugins",sidebarVisible:!0});let E=A.info(`Installing “${this.label}”…`,{sticky:!0});try{await B.install(this.pkg,{grants:K,trust:this.trust}),A.dismiss(E),A.success(`Installed “${this.label}”`)}catch(Y){A.dismiss(E),A.error(`Install failed: ${Y.message}`)}}}class iJ extends oJ{static deps=["notifications","overlay","plugins","social","viewState","workbench"];async withValue(A,Q){await s8(Q,A)}}class rJ extends P{static deps=["engine","overlay"];constructor(A){super();this.record=A}async execute({engine:A,overlay:Q}){if(Q.set({dialog:null}),this.record)A.dispatch(new OY(this.record))}}class tJ extends P{static deps=["viewState"];constructor(A,Q,B,C={}){super();this.key=A,this.ref=Q,this.patch=B,this.fallback=C}async execute({viewState:A}){let Q=A.get()[this.key],B=Q&&Q.ref===this.ref?Q.form:this.fallback;A.set({[this.key]:{ref:this.ref,form:{...B,...this.patch}}})}}function HC({explorer:A,navigation:Q,notifications:B},C=null){let J=C||iB(A.get())[0]||Q.activeTab()?.node;if(!J)B.info("Pick a file first — highlight one in the list, or open it.");return J}class J0 extends bA{constructor(A="commands",Q=""){super();this.mode=A,this.query=Q}apply(A){A.set({palette:{mode:this.mode,query:this.query,index:0}})}}class GC extends XQ{constructor(A){super();this.activity=A}apply(A){A.set({activity:this.activity,sidebarVisible:!0})}}class eJ extends P{static deps=["navigation","overlay","workbench"];async execute({navigation:A,overlay:Q,workbench:B}){let C=Q.get(),J=B.get();if(C.contextMenu)return Q.set({contextMenu:null});if(C.dialog)return Q.set({dialog:null});if(J.sheet)return B.set({sheet:null});if(J.searchModal)return B.set({searchModal:!1});if(C.palette)return Q.set({palette:null});if(C.pluginPanel)return Q.set({pluginPanel:null});if(C.activityPanel)return Q.set({activityPanel:!1});if(A.get().stack.length>1)A.back()}}class AK extends P{static deps=["engine","voice"];async execute({engine:A,voice:Q}){await Q.run({onText:(B,{final:C})=>{if(!B)return;if(A.dispatch(new AB(B)),C)A.dispatch(new VQ(B))}})}}class QK extends P{static deps=["activity","api","engine","notifications"];async execute({activity:A,api:Q,engine:B,notifications:C}){try{let J=await Q.reindex();if(await A.refreshTasks(),B.dispatch(new SA(!0)),J.alreadyRunning)C.info("A rebuild is already running")}catch(J){C.error(`Couldn't rebuild the index: ${J.message}`)}}}class BK extends P{static deps=["activity","api","engine","explorer","notifications"];async execute({activity:A,api:Q,engine:B,explorer:C,notifications:J}){let K=C.get().collectionId;if(!K)return J.info("Open a collection first — a scan is per collection.");try{let E=await Q.scanCollection(K);if(await A.refreshTasks(),B.dispatch(new SA(!0)),E.alreadyRunning)J.info("A scan of this collection is already running");A.followUp()}catch(E){J.error(`Couldn't scan “${K}”: ${E.message}`)}}}class CK extends P{static deps=["activity","api","engine","notifications"];async execute({activity:A,api:Q,engine:B,notifications:C}){try{let J=await Q.checkStorage();await A.refresh(),B.dispatch(new SA(!0));let K=(J.results||[]).reduce((E,Y)=>E+(Y.findings?.length||0),0);if(K)C.warn(`Found ${K} storage problem${K===1?"":"s"} — see Activity`);else if(!J.checked)C.info("There are no collections to check yet");else if(!J.corsChecked)C.info("Stores are reachable. Browser access was not checked — this drive has no public URL configured.");else C.success("Stores are reachable and allow browser access")}catch(J){C.error(`Couldn't check the stores: ${J.message}`)}}}class JK extends P{static deps=["engine","explorer"];async execute({engine:A,explorer:Q}){let B=Q.get().collectionId,C=await WY();if(C?.length)await lA(A,new tB(C,B))}}class K0 extends P{static deps=["engine","explorer","navigation","notifications"];constructor(A="trove",Q=null){super();this.kind=A,this.node=Q}async execute(A){let Q=HC(A,this.node);if(!Q)return;return A.engine.dispatch(this.kind==="share"?new tA(GY(Q,location.origin),"Link copied — anyone with access to this collection can open it"):new tA(oB(Q),`Copied ${oB(Q)}`))}}class KK extends P{static deps=["engine","explorer","navigation","notifications"];constructor(A=null){super();this.node=A}async execute(A){let Q=HC(A,this.node);if(!Q)return;A.engine.dispatch(new sA({kind:"prompt",title:"Rename",label:"New name",value:Q.name,confirmLabel:"Rename",confirmActions:[new xY(Q)]}))}}class EK extends P{static deps=["engine","explorer","navigation","notifications","settings"];async execute(A){let Q=iB(A.explorer.get()),B=Q.length?null:A.navigation.activeTab()?.node;if(B)Q.push(B);if(!Q.length){A.notifications.info("Pick a file first — highlight one in the list, or open it.");return}let C=new jY(Q.map((J)=>J.id));if(!A.settings.get("explorer.confirmDelete"))return A.engine.dispatch(C);A.engine.dispatch(new sA({kind:"confirm",title:`Move ${Q.length} item${Q.length>1?"s":""} to the trash?`,body:Q.length===1?`"${Q[0].name}" leaves the drive but is kept, and can be restored from the trash.`:"They leave the drive but are kept, and can be restored from the trash.",confirmLabel:"Move to trash",confirmActions:[C]}))}}class YK extends P{static deps=["engine"];async execute({engine:A}){A.dispatch(new eQ("list")),A.dispatch(new vQ)}}class LK extends P{static deps=["engine","explorer","navigation","notifications"];constructor(A=null){super();this.node=A}async execute(A){let Q=HC(A,this.node);if(Q)return A.engine.dispatch(new aA(Q))}}class XK extends P{static deps=["api","explorer","navigation","notifications"];constructor(A=null){super();this.node=A}async execute(A){let Q=HC(A,this.node);if(!Q?.id)return;try{let{url:B,revoke:C}=await A.api.download(Q.id,Q.name);if(IY(B,Q.name),C)setTimeout(()=>URL.revokeObjectURL(B),60000)}catch(B){A.notifications.error(`Couldn't download ${Q.name}: ${B.message}`)}}}class E0 extends P{static deps=["explorer","navigation","notifications","offline"];constructor(A=null,Q=!0){super();this.node=A,this.pinned=Q}async execute(A){let Q=HC(A,this.node);if(!Q?.id)return;return this.pinned?A.offline.pin(Q):A.offline.unpin(Q.id)}}class HK extends qB{apply(A){A.set({draft:{name:"",expiresInDays:"",caps:{}},error:null})}}class GK extends qB{apply(A){A.set({draft:null})}}class $K extends qB{apply(A){if(A.get().minted)A.set({minted:null})}}class DK extends P{static deps=["apiKeys","engine"];async execute({apiKeys:A,engine:Q}){let B=A.get().draft,C=rC(A.get());if(!B?.name?.trim()||!C)return;let J=Number(B.expiresInDays),K=B.expiresInDays!==""&&Number.isFinite(J)&&J>0?Date.now()+J*86400000:null;return A.set({draft:null}),Q.dispatch(new _Y({name:B.name.trim(),scopes:C,expiresAt:K}))}}class ZK extends P{static deps=["engine","explorer","notifications"];constructor(A=null){super();this.collectionId=A}async execute({engine:A,explorer:Q,notifications:B}){if(this.collectionId){A.dispatch(new hA(this.collectionId)),A.dispatch(new vQ);return}let C=tC(Q.get(),(J)=>new N("collections.switch",J),()=>new N("collections.create"));if(!C.length)return B.info("This drive has one collection.");A.dispatch(new $Q(C))}}class WK extends P{static deps=["navigation","notifications","workbench"];async execute({navigation:A,notifications:Q,workbench:B}){if(!A.activeTab()){Q.info("Open a file to see its details and conversation.");return}B.set({infoPanel:!B.get().infoPanel})}}class UK extends P{static deps=["notifications","overlay","plugins","social","workbench"];async execute(A){let Q=await UY();if(Q)await n8(A,Q)}}class IK extends P{static deps=["plugins"];constructor(A,Q,B=[]){super();this.pluginId=A,this.name=Q,this.args=B}async execute({plugins:A}){return A.invokeCommand(this.pluginId,this.name,this.args)}}class FK extends P{static deps=["social"];constructor(A){super();this.nodeId=A}async execute({social:A}){if(A.get().sidecar?.nodeId===this.nodeId)A.loadSidecar(null)}}class Y0 extends P{static deps=["acl","api","notifications"];constructor(A){super();this.collectionId=A}async execute({acl:A,api:Q,notifications:B}){let C=this.collectionId;if(!C)return;A.set({collectionId:C,loading:!0,error:null});try{let J=await Q.collectionGrants(C);A.set({grants:J?.grants||[],admins:J?.admins||[],loading:!1})}catch(J){if(A.set({loading:!1,error:J?.message||"Could not read the access list"}),J?.status!==403)B.error?.(J?.message||"Could not read the access list")}}}class RK extends P{static deps=["acl","api","engine","notifications"];constructor(A,Q){super();this.collectionId=A,this.grant=Q}async execute({acl:A,api:Q,engine:B,notifications:C}){A.set({busy:!0});try{await Q.setCollectionGrant(this.collectionId,this.grant);let J=this.grant.type==="anyone"?"everyone":this.grant.subject;C.success?.(this.grant.capabilities?.length?`Access for ${J} updated`:`Access for ${J} removed`)}catch(J){C.error?.(J?.message||"Could not change access")}finally{A.set({busy:!1}),await lA(B,new Y0(this.collectionId))}}}class NB extends P{static deps=["api","explorer","notifications","rotation"];constructor(A=null){super();this.collectionId=A}async execute({api:A,explorer:Q,notifications:B,rotation:C}){let J=this.collectionId||Q.get().collectionId;if(!J)return;let K=C.get().collectionId!==J;C.set(K?{collectionId:J,rotation:null,estimate:null,loading:!0,error:null}:{collectionId:J,loading:!0,error:null});try{let[E,Y]=await Promise.all([A.rotationState(J),A.rotationEstimate(J).catch(()=>null)]);C.set({rotation:E?.rotation??null,estimate:Y??null,loading:!1})}catch(E){if(C.set({loading:!1,error:E?.message||"Could not read the rotation state"}),E?.status!==403)B.error?.(E?.message||"Could not read the rotation state")}}}class MK extends P{static deps=["api","engine","explorer","notifications","rotation"];async execute({api:A,engine:Q,explorer:B,notifications:C,rotation:J}){let K=B.get().collectionId;if(!K)return;J.set({busy:!0});try{let E=await A.beginRotation(K);J.set({rotation:E?.rotation??null,busy:!1}),Q.dispatch(new IJ),C.info("Key rotation started. It runs in the background and survives a reload.")}catch(E){J.set({busy:!1}),C.error(E?.message||"Could not start the rotation")}return Q.dispatch(new NB)}}class VK extends P{static deps=["api","engine","explorer","notifications","rotation"];async execute({api:A,engine:Q,explorer:B,notifications:C,rotation:J}){let K=B.get().collectionId;if(!K)return;J.set({busy:!0});try{await A.cancelRotation(K),C.info("Rotation stopped. Files already moved stay on the new key.")}catch(E){C.error(E?.message||"Could not stop the rotation")}return J.set({busy:!1}),Q.dispatch(new NB)}}class zK{constructor(A,Q={}){if(this.port=A,this.onCall=Q.onCall,this.onEvent=Q.onEvent,this.targetOrigin=Q.targetOrigin,this.seq=0,this.pending=new Map,this._listener=(B)=>this._receive(B.data,B),typeof A.addEventListener==="function")A.addEventListener("message",this._listener);else A.onmessage=this._listener;A.start?.()}_post(A,Q){if(this.targetOrigin)this.port.postMessage(A,this.targetOrigin,Q);else this.port.postMessage(A,Q)}call(A,Q,{timeout:B=30000,transfer:C}={}){let J=++this.seq;return new Promise((K,E)=>{let Y=B?setTimeout(()=>{this.pending.delete(J),E(Error(`RPC timeout: ${A}`))},B):null;this.pending.set(J,{resolve:K,reject:E,timer:Y}),this._post({__trove:"req",id:J,method:A,params:Q},C)})}emit(A,Q,B){this._post({__trove:"event",method:A,params:Q},B)}async _receive(A,Q){if(!A||A.__trove==null)return;if(A.__trove==="res"){let B=this.pending.get(A.id);if(!B)return;if(this.pending.delete(A.id),B.timer)clearTimeout(B.timer);if(A.error)B.reject(Object.assign(Error(A.error.message),A.error));else B.resolve(A.result);return}if(A.__trove==="event"){try{await this.onEvent?.(A.method,A.params,Q)}catch(B){console.error("rpc event handler error",B)}return}if(A.__trove==="req"){let B,C;try{B=await this.onCall?.(A.method,A.params,Q)}catch(J){C={message:J?.message||String(J),code:J?.code||"error"}}this._post({__trove:"res",id:A.id,result:B,error:C})}}dispose(){if(typeof this.port.removeEventListener==="function")this.port.removeEventListener("message",this._listener);for(let A of this.pending.values()){if(A.timer)clearTimeout(A.timer);A.reject(Error("RPC channel disposed"))}this.pending.clear(),this.port.close?.()}}var qK=`// Injectable browser build of the Trove plugin SDK — a single self-contained IIFE
|
|
5
|
+
// with NO imports, so the host can inline it into a sandboxed iframe's srcdoc
|
|
6
|
+
// alongside the plugin's entry script. The iframe runs on an opaque origin
|
|
7
|
+
// (sandbox="allow-scripts", no allow-same-origin), so it can't fetch its own
|
|
8
|
+
// package files; instead it reaches everything — resources, files, settings,
|
|
9
|
+
// storage — through the host over a transferred MessagePort. Package resources
|
|
10
|
+
// are handed back as raw bytes (or iframe-local blob: URLs), never host URLs, so
|
|
11
|
+
// the plugin only ever holds opaque handles.
|
|
12
|
+
//
|
|
13
|
+
// Plugins use it as: trove.activate(async (ctx) => { ... })
|
|
14
|
+
(function () {
|
|
15
|
+
'use strict';
|
|
16
|
+
// Wire-protocol version this SDK speaks. MUST equal PROTOCOL_VERSION in
|
|
17
|
+
// protocol.js — this file is injected as text and cannot import it, so
|
|
18
|
+
// protocol.test.js asserts the two stay in step.
|
|
19
|
+
const SDK_PROTOCOL_VERSION = '1.0';
|
|
20
|
+
let port = null, manifest = null, capabilities = [], storageScopes = {}, online = true, seq = 0, role = 'primary';
|
|
21
|
+
const pending = new Map();
|
|
22
|
+
const commandHandlers = new Map();
|
|
23
|
+
const openerHandlers = new Map();
|
|
24
|
+
let onConnectivity = null, onDeactivate = null, onSettingsChange = null, onDock = null;
|
|
25
|
+
const mediaHandlers = {}; // action -> handler, for OS media-session controls
|
|
26
|
+
|
|
27
|
+
const now = () => { try { return Date.now(); } catch { return 0; } };
|
|
28
|
+
|
|
29
|
+
// The HOST times its own calls out; this side did not, and \`pending\` was never
|
|
30
|
+
// rejected — not on a dropped reply, not on port close. A plugin awaiting one hung
|
|
31
|
+
// forever with no way to find out, and the entry leaked with it.
|
|
32
|
+
const CALL_TIMEOUT_MS = 30_000;
|
|
33
|
+
|
|
34
|
+
function call(method, params, transfer) {
|
|
35
|
+
const id = ++seq;
|
|
36
|
+
return new Promise((resolve, reject) => {
|
|
37
|
+
const timer = setTimeout(() => {
|
|
38
|
+
pending.delete(id);
|
|
39
|
+
reject(new Error(\`Timed out waiting for the host to answer "\${method}"\`));
|
|
40
|
+
}, CALL_TIMEOUT_MS);
|
|
41
|
+
if (timer && timer.unref) timer.unref();
|
|
42
|
+
pending.set(id, { resolve, reject, timer });
|
|
43
|
+
port.postMessage({ __trove: 'req', id, method, params }, transfer || []);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
const emit = (method, params) => port.postMessage({ __trove: 'event', method, params });
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* A file's bytes, addressable without holding them.
|
|
50
|
+
*
|
|
51
|
+
* \`Blob\` is already the browser's interface for exactly that — \`slice()\` is free,
|
|
52
|
+
* \`stream()\` is a reader, and everything that eats bytes eats a Blob — so a range reader
|
|
53
|
+
* wears the interface that exists rather than inventing a parallel vocabulary.
|
|
54
|
+
*
|
|
55
|
+
* THE SHARP EDGE, and it is sharp: a Blob SUBCLASS only overrides what JavaScript calls.
|
|
56
|
+
* Anything reading the blob's internal bytes — \`URL.createObjectURL\`, \`new
|
|
57
|
+
* Response(blob)\`, \`fetch(url, {body})\`, and structured clone through \`postMessage\` —
|
|
58
|
+
* bypasses every override here and sees the empty blob passed to \`super()\`. Two
|
|
59
|
+
* consequences the design is built around:
|
|
60
|
+
*
|
|
61
|
+
* 1. A RemoteBlob cannot be posted INTO this frame from the host; it would arrive as a
|
|
62
|
+
* plain, empty Blob. It is constructed here, in the frame that uses it.
|
|
63
|
+
* 2. \`local()\` is the escape hatch for all of them. A realized Blob really does hold
|
|
64
|
+
* its bytes, so it works with \`createObjectURL\` — which is the download-then-play
|
|
65
|
+
* path for anything that cannot be streamed.
|
|
66
|
+
*/
|
|
67
|
+
class RemoteBlob extends Blob {
|
|
68
|
+
constructor(id, { size = 0, type = '', etag = null, start = 0, end = null } = {}) {
|
|
69
|
+
super();
|
|
70
|
+
this.id = id;
|
|
71
|
+
this.type = type;
|
|
72
|
+
this.etag = etag;
|
|
73
|
+
// A window on the source. \`size\` is this window's length, which is what makes
|
|
74
|
+
// \`slice()\` of a slice behave the way a caller expects.
|
|
75
|
+
this._start = start;
|
|
76
|
+
this._end = end == null ? size : end;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
get size() { return Math.max(0, this._end - this._start); }
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* A window on the same source. No bytes move and none need to exist yet.
|
|
83
|
+
*
|
|
84
|
+
* Negative indices count from the end, as \`Blob.slice\` does — which is what makes
|
|
85
|
+
* "the last 64 KiB" expressible, and reading the tail of a file is half of what a
|
|
86
|
+
* container parser does.
|
|
87
|
+
*/
|
|
88
|
+
slice(begin = 0, finish = this.size, type = this.type) {
|
|
89
|
+
const len = this.size;
|
|
90
|
+
const from = begin < 0 ? Math.max(0, len + begin) : Math.min(begin, len);
|
|
91
|
+
const to = finish < 0 ? Math.max(0, len + finish) : Math.min(finish, len);
|
|
92
|
+
const win = new RemoteBlob(this.id, {
|
|
93
|
+
type, etag: this.etag,
|
|
94
|
+
start: this._start + from,
|
|
95
|
+
end: this._start + Math.max(from, to),
|
|
96
|
+
});
|
|
97
|
+
return win;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* The bytes of this window.
|
|
102
|
+
*
|
|
103
|
+
* A \`signal\` is checked BEFORE the call and not during it: an in-flight request over
|
|
104
|
+
* the port cannot be recalled, so the honest granularity is per read. \`chunks()\` is
|
|
105
|
+
* where cancelling actually bites, because there the reads are small and there are
|
|
106
|
+
* many of them.
|
|
107
|
+
*/
|
|
108
|
+
async bytes({ signal } = {}) {
|
|
109
|
+
if (signal && signal.aborted) throw new Error('Aborted');
|
|
110
|
+
const r = await call('files:bytes', { id: this.id, start: this._start, end: this._end });
|
|
111
|
+
// Every read refreshes the etag, because a file overwritten in place keeps its id
|
|
112
|
+
// and anything cached off these bytes has to notice.
|
|
113
|
+
if (r.etag) this.etag = r.etag;
|
|
114
|
+
return new Uint8Array(r.bytes);
|
|
115
|
+
}
|
|
116
|
+
async arrayBuffer() { return (await this.bytes()).buffer; }
|
|
117
|
+
async text() { return new TextDecoder().decode(await this.bytes()); }
|
|
118
|
+
|
|
119
|
+
/** One window at a time, so a caller can walk a large file without holding it. */
|
|
120
|
+
async *chunks({ size = 4 * 1024 * 1024, signal } = {}) {
|
|
121
|
+
for (let at = 0; at < this.size; at += size) {
|
|
122
|
+
yield this.slice(at, Math.min(at + size, this.size)).bytes({ signal });
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
stream() {
|
|
127
|
+
const iter = this.chunks();
|
|
128
|
+
return new ReadableStream({
|
|
129
|
+
async pull(controller) {
|
|
130
|
+
const { value, done } = await iter.next();
|
|
131
|
+
if (done) controller.close();
|
|
132
|
+
else controller.enqueue(value);
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* REALIZE the bytes into an ordinary Blob.
|
|
139
|
+
*
|
|
140
|
+
* The escape hatch named above, and the download half of "this book cannot be
|
|
141
|
+
* streamed, here is a Download button". \`onProgress\` fires once with \`loaded: 0\`
|
|
142
|
+
* BEFORE the first chunk, so a bar appears at 0% instead of jumping in partway.
|
|
143
|
+
*/
|
|
144
|
+
async local({ onProgress, signal, chunkSize = 4 * 1024 * 1024 } = {}) {
|
|
145
|
+
const total = this.size;
|
|
146
|
+
const parts = [];
|
|
147
|
+
let loaded = 0;
|
|
148
|
+
if (onProgress) onProgress({ loaded: 0, total, ratio: 0 });
|
|
149
|
+
for await (const chunk of this.chunks({ size: chunkSize, signal })) {
|
|
150
|
+
parts.push(chunk);
|
|
151
|
+
loaded += chunk.length;
|
|
152
|
+
if (onProgress) onProgress({ loaded, total, ratio: total ? loaded / total : 0 });
|
|
153
|
+
}
|
|
154
|
+
return new Blob(parts, { type: this.type });
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// What this frame reports about itself on every heartbeat. Contributions are the
|
|
159
|
+
// host's own manifest reading — all the plugin can usefully say is which of its
|
|
160
|
+
// declared contributions it actually bound a handler to, plus whether it thinks
|
|
161
|
+
// it's online.
|
|
162
|
+
function buildManifest() {
|
|
163
|
+
return {
|
|
164
|
+
domain: manifest && manifest.domain, name: manifest && manifest.name,
|
|
165
|
+
online, role, ts: now(),
|
|
166
|
+
handlers: [...commandHandlers.keys()],
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
const announce = () => port && emit('manifest', buildManifest());
|
|
170
|
+
|
|
171
|
+
function onPort(e) {
|
|
172
|
+
const m = e.data;
|
|
173
|
+
if (!m || m.__trove == null) return;
|
|
174
|
+
if (m.__trove === 'res') {
|
|
175
|
+
const p = pending.get(m.id);
|
|
176
|
+
if (!p) return;
|
|
177
|
+
clearTimeout(p.timer);
|
|
178
|
+
pending.delete(m.id);
|
|
179
|
+
m.error ? p.reject(Object.assign(new Error(m.error.message), m.error)) : p.resolve(m.result);
|
|
180
|
+
} else if (m.__trove === 'req') {
|
|
181
|
+
Promise.resolve().then(() => dispatch(m.method, m.params))
|
|
182
|
+
.then((result) => port.postMessage({ __trove: 'res', id: m.id, result }))
|
|
183
|
+
.catch((err) => port.postMessage({ __trove: 'res', id: m.id, error: { message: err.message } }));
|
|
184
|
+
} else if (m.__trove === 'event') {
|
|
185
|
+
dispatchEvent(m.method, m.params);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function dispatch(method, params) {
|
|
190
|
+
if (method === 'command:execute') {
|
|
191
|
+
const h = commandHandlers.get(params.id);
|
|
192
|
+
// Throw, like \`opener:open\` two lines down. Resolving \`undefined\` for an id with
|
|
193
|
+
// no handler told the host the command had RUN when nothing had.
|
|
194
|
+
if (!h) throw new Error(\`No handler registered for command "\${params.id}"\`);
|
|
195
|
+
return h(...(params.args || []));
|
|
196
|
+
}
|
|
197
|
+
if (method === 'opener:open') {
|
|
198
|
+
// An opener frame boots at that opener's entry module and runs exactly one
|
|
199
|
+
// opener, so an unkeyed onOpen(fn) handler is the normal case.
|
|
200
|
+
const f = openerHandlers.get(params.openerId) || openerHandlers.get('*');
|
|
201
|
+
if (!f) throw new Error('no opener ' + params.openerId);
|
|
202
|
+
return f(params.file, params.context);
|
|
203
|
+
}
|
|
204
|
+
if (method === 'manifest') return buildManifest();
|
|
205
|
+
throw new Error('Unknown host call ' + method);
|
|
206
|
+
}
|
|
207
|
+
async function dispatchEvent(method, params) {
|
|
208
|
+
if (method === 'deactivate') return onDeactivate && onDeactivate();
|
|
209
|
+
if (method === 'connectivity') { online = !!params.online; try { onConnectivity && (await onConnectivity({ online })); } catch (e) { console.error(e); } announce(); }
|
|
210
|
+
if (method === 'settings:changed') { try { onSettingsChange && onSettingsChange(params.key, params.value); } catch (e) { console.error(e); } }
|
|
211
|
+
// The OS/host fired a media transport control (play/pause/next/seek…).
|
|
212
|
+
if (method === 'media:action') { try { mediaHandlers[params.action] && mediaHandlers[params.action](params); } catch (e) { console.error(e); } }
|
|
213
|
+
// The host docked or undocked this viewer (see ctx.dock).
|
|
214
|
+
if (method === 'dock:state') { try { onDock && onDock(params); } catch (e) { console.error(e); } }
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function requireCap(cap) { if (!capabilities.includes(cap)) throw new Error('Plugin lacks capability "' + cap + '"'); }
|
|
218
|
+
|
|
219
|
+
// Storage: one async SQL handle (mirrors the host SqliteDatabase interface) per
|
|
220
|
+
// scope+side, over RPC. Only granted scopes are exposed on ctx.storage.
|
|
221
|
+
function sqlHandle(scope, side) {
|
|
222
|
+
var send = function (op, extra) { return call('storage:sql', Object.assign({ scope: scope, side: side, op: op }, extra)); };
|
|
223
|
+
return {
|
|
224
|
+
exec: function (sql) { return send('exec', { sql: sql }); },
|
|
225
|
+
run: function (sql) { return send('run', { sql: sql, params: [].slice.call(arguments, 1) }); },
|
|
226
|
+
get: function (sql) { return send('get', { sql: sql, params: [].slice.call(arguments, 1) }); },
|
|
227
|
+
all: function (sql) { return send('all', { sql: sql, params: [].slice.call(arguments, 1) }); },
|
|
228
|
+
batch: function (statements) { return send('batch', { statements: statements }); },
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
function scopeHandle(scope) {
|
|
232
|
+
return { server: sqlHandle(scope, 'server'), client: sqlHandle(scope, 'client') };
|
|
233
|
+
}
|
|
234
|
+
function makeStorage() {
|
|
235
|
+
var s = {};
|
|
236
|
+
if (storageScopes.plugin) s.plugin = scopeHandle('plugin');
|
|
237
|
+
if (storageScopes.domain) s.domain = scopeHandle('domain');
|
|
238
|
+
return s;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function hasHeader(h, name) { name = name.toLowerCase(); for (var k in h) if (k.toLowerCase() === name) return true; return false; }
|
|
242
|
+
// Wrap the host's brokered-fetch result in a minimal Response-like object.
|
|
243
|
+
function makeResponse(r) {
|
|
244
|
+
var bytes = new Uint8Array(r.bytes || new ArrayBuffer(0));
|
|
245
|
+
var decode = function () { return new TextDecoder().decode(bytes); };
|
|
246
|
+
return {
|
|
247
|
+
ok: r.ok, status: r.status, statusText: r.statusText, url: r.url, headers: r.headers || {},
|
|
248
|
+
arrayBuffer: function () { return Promise.resolve(bytes.slice().buffer); },
|
|
249
|
+
bytes: function () { return Promise.resolve(bytes); },
|
|
250
|
+
text: function () { return Promise.resolve(decode()); },
|
|
251
|
+
json: function () { return Promise.resolve(JSON.parse(decode())); },
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
function makeContext() {
|
|
256
|
+
return {
|
|
257
|
+
manifest, capabilities,
|
|
258
|
+
// Which instance this is: 'primary' is the plugin's single background frame
|
|
259
|
+
// (register commands/indexers, do one-time setup here); 'viewer' is a
|
|
260
|
+
// per-open frame hosting an opener for one file (drive media/dock from here).
|
|
261
|
+
role,
|
|
262
|
+
get online() { return online; },
|
|
263
|
+
// Contributions are DECLARED IN THE MANIFEST (openers, indexers, commands,
|
|
264
|
+
// statusItems, keybindings). The host registers them before this code runs, so
|
|
265
|
+
// a plugin never registers anything at runtime — it only supplies the behaviour
|
|
266
|
+
// for what it declared, addressed by id.
|
|
267
|
+
commands: {
|
|
268
|
+
/** Implement a command this plugin's manifest declares, by its short name. */
|
|
269
|
+
handle(name, handler) { commandHandlers.set(name, handler); return this; },
|
|
270
|
+
/**
|
|
271
|
+
* Run a command. Its OWN commands by short name; anyone else's by full address
|
|
272
|
+
* (a built-in like 'explorer.download', or a \`trove+contrib:\` URI) — and only
|
|
273
|
+
* if the manifest's \`commands\` capability lists it.
|
|
274
|
+
*/
|
|
275
|
+
execute(id) { const a = [].slice.call(arguments, 1); return call('command:execute', { id, args: a }); },
|
|
276
|
+
},
|
|
277
|
+
/** Implement the opener this frame was booted for (its entry module). The id is
|
|
278
|
+
* optional — an opener frame runs exactly one opener. */
|
|
279
|
+
onOpen(idOrHandler, maybeHandler) {
|
|
280
|
+
const [id, handler] = typeof idOrHandler === 'function' ? ['*', idOrHandler] : [idOrHandler, maybeHandler];
|
|
281
|
+
openerHandlers.set(id, handler);
|
|
282
|
+
return this;
|
|
283
|
+
},
|
|
284
|
+
// NOTE: there is no onIndex(). Indexers run on the SERVER (in its isolate
|
|
285
|
+
// runtime), not in this sandbox — indexing has to happen once per upload for the
|
|
286
|
+
// drive, not in whichever tab is open. An indexer's entry module is plain ESM
|
|
287
|
+
// exporting \`index(node, ctx)\`; it doesn't use this SDK at all. What a plugin can
|
|
288
|
+
// do from here is PUSH contributions for a node via ctx.files.index (the
|
|
289
|
+
// \`indexer\` capability).
|
|
290
|
+
// Package resources — opaque handles. read() copies bytes into the iframe;
|
|
291
|
+
// url() wraps them in an iframe-local blob: URL.
|
|
292
|
+
resources: {
|
|
293
|
+
list() { return call('resources:list', {}); },
|
|
294
|
+
async read(path) { const r = await call('resources:read', { path }); return new Uint8Array(r.bytes); },
|
|
295
|
+
async text(path) { return new TextDecoder().decode(await this.read(path)); },
|
|
296
|
+
async url(path, type) {
|
|
297
|
+
const bytes = await this.read(path);
|
|
298
|
+
return URL.createObjectURL(new Blob([bytes], { type: type || 'application/octet-stream' }));
|
|
299
|
+
},
|
|
300
|
+
},
|
|
301
|
+
ui: {
|
|
302
|
+
toast: (text, opts) => emit('ui:toast', Object.assign({ text }, opts)),
|
|
303
|
+
showPanel: () => call('ui:showPanel', {}),
|
|
304
|
+
setBadge: (text) => emit('ui:badge', { text }),
|
|
305
|
+
/**
|
|
306
|
+
* Drive a status-bar slot this plugin's manifest declares. \`html\` is sanitized
|
|
307
|
+
* by the host down to a small inline-formatting allowlist before it renders.
|
|
308
|
+
* ctx.ui.status('sync').set('<b>3</b> queued')
|
|
309
|
+
* ctx.ui.status('sync').hide()
|
|
310
|
+
*/
|
|
311
|
+
status(name) {
|
|
312
|
+
return {
|
|
313
|
+
set: (html, opts) => call('ui:status', Object.assign({ name, html, visible: true }, opts || {})),
|
|
314
|
+
show: () => call('ui:status', { name, visible: true }),
|
|
315
|
+
hide: () => call('ui:status', { name, visible: false }),
|
|
316
|
+
};
|
|
317
|
+
},
|
|
318
|
+
},
|
|
319
|
+
/**
|
|
320
|
+
* Registers — context value slots this plugin's manifest declares, which
|
|
321
|
+
* when-clauses (its own keymap's, its commands') read by contribution URI.
|
|
322
|
+
* ctx.registers.set('busy', true)
|
|
323
|
+
*/
|
|
324
|
+
registers: {
|
|
325
|
+
set: (name, value) => call('context:setRegister', { name, value }),
|
|
326
|
+
},
|
|
327
|
+
// Media session — surfaces this viewer's playback to the OS (lock-screen /
|
|
328
|
+
// notification transport controls, so phones can play/pause/seek). The host
|
|
329
|
+
// owns navigator.mediaSession; action handlers are called back over RPC.
|
|
330
|
+
media: {
|
|
331
|
+
setMetadata: (m) => (requireCap('media'), call('media:metadata', m || {})),
|
|
332
|
+
setPlaybackState: (state) => (requireCap('media'), call('media:playbackState', { state })),
|
|
333
|
+
setPositionState: (p) => (requireCap('media'), call('media:position', p || {})),
|
|
334
|
+
setActionHandler: (action, handler) => { requireCap('media'); if (handler) mediaHandlers[action] = handler; else delete mediaHandlers[action]; return call('media:action', { action, on: !!handler }); },
|
|
335
|
+
clear: () => call('media:clear', {}),
|
|
336
|
+
},
|
|
337
|
+
// Dock — register this viewer to persist as a small floating frame when the
|
|
338
|
+
// user navigates away (a docked video = picture-in-picture; docked audio = a
|
|
339
|
+
// mini transport). Enable while playing/active, disable otherwise. \`minSize\`/
|
|
340
|
+
// \`maxSize\` are {width,height} constraints. onDock is notified on (un)dock.
|
|
341
|
+
dock: {
|
|
342
|
+
enable: (opts) => (requireCap('dock'), call('dock:enable', opts || {})),
|
|
343
|
+
disable: () => (requireCap('dock'), call('dock:disable', {})),
|
|
344
|
+
close: () => call('dock:close', {}),
|
|
345
|
+
onChange: (fn) => { onDock = fn; },
|
|
346
|
+
},
|
|
347
|
+
// Network — there is no direct fetch in the sandbox; the host performs the
|
|
348
|
+
// request, but ONLY to endpoints declared in the manifest's \`network\` list
|
|
349
|
+
// (and only with the "network" capability). Returns a Response-like object.
|
|
350
|
+
net: {
|
|
351
|
+
fetch(url, opts) {
|
|
352
|
+
requireCap('network');
|
|
353
|
+
opts = opts || {};
|
|
354
|
+
var body = opts.body;
|
|
355
|
+
var headers = Object.assign({}, opts.headers);
|
|
356
|
+
if (body && typeof body === 'object' && !(body instanceof ArrayBuffer) && !(body instanceof Uint8Array)) {
|
|
357
|
+
body = JSON.stringify(body);
|
|
358
|
+
if (!hasHeader(headers, 'content-type')) headers['Content-Type'] = 'application/json';
|
|
359
|
+
}
|
|
360
|
+
// \`.buffer\` ignores byteOffset/byteLength, so any view produced by \`subarray\` or
|
|
361
|
+
// \`slice\` — or a view into a pooled buffer — sent the WHOLE backing store: the wrong
|
|
362
|
+
// payload, and an out-of-band leak of whatever else was in it.
|
|
363
|
+
if (ArrayBuffer.isView(body)) {
|
|
364
|
+
body = body.buffer.slice(body.byteOffset, body.byteOffset + body.byteLength);
|
|
365
|
+
}
|
|
366
|
+
return call('net:fetch', { url: String(url), method: opts.method || 'GET', headers: headers, body: body })
|
|
367
|
+
.then(makeResponse);
|
|
368
|
+
},
|
|
369
|
+
},
|
|
370
|
+
files: {
|
|
371
|
+
read: (id, opts) => (requireCap('files'), call('files:read', Object.assign({ id }, opts))),
|
|
372
|
+
list: (pathOrId, opts) => (requireCap('files'), call('files:list', Object.assign({ pathOrId }, opts))),
|
|
373
|
+
stat: (id) => (requireCap('files'), call('files:stat', { id })),
|
|
374
|
+
downloadUrl: (id) => (requireCap('files'), call('files:downloadUrl', { id })),
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* A file's bytes as a Blob you can slice, stream and realize — see RemoteBlob.
|
|
378
|
+
*
|
|
379
|
+
* \`stat\` first, because a Blob has to know its own size before \`slice\` means
|
|
380
|
+
* anything. One round trip, and every later read is a range.
|
|
381
|
+
*/
|
|
382
|
+
async blob(id) {
|
|
383
|
+
requireCap('files');
|
|
384
|
+
const { node } = await call('files:stat', { id });
|
|
385
|
+
return new RemoteBlob(id, { size: node.size || 0, type: node.contentType || '', etag: node.etag || null });
|
|
386
|
+
},
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* A URL a media element can load by itself, for streaming.
|
|
390
|
+
*
|
|
391
|
+
* It is MINTED — it carries its own grant and expires — which is the one place a
|
|
392
|
+
* host URL deliberately reaches a plugin. \`<audio src>\` is the only way to play a
|
|
393
|
+
* progressive MP4 without a fragmenter: MSE refuses one, and a Blob has to be
|
|
394
|
+
* whole before it can become an object URL. Use \`blob(id)\` for the parsing (a
|
|
395
|
+
* container's chapters are a few kilobytes out of a few hundred megabytes) and
|
|
396
|
+
* this for the playing.
|
|
397
|
+
*/
|
|
398
|
+
mediaUrl: (id, opts) => (requireCap('files'), call('files:mediaUrl', Object.assign({ id }, opts))),
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* Keeping a file, which is a DIFFERENT act from reading one.
|
|
402
|
+
*
|
|
403
|
+
* Ranging over a file stores nothing. \`start(id)\` is someone asking to have it
|
|
404
|
+
* offline, and from then on every chunk a read fetches is kept and the background
|
|
405
|
+
* filler skips it — so a book listened straight through downloads itself exactly
|
|
406
|
+
* once, and a book skipped around in fills its gaps.
|
|
407
|
+
*/
|
|
408
|
+
offline: {
|
|
409
|
+
start: (id) => (requireCap('files'), call('files:offline:start', { id })),
|
|
410
|
+
status: (id) => (requireCap('files'), call('files:offline:status', { id })),
|
|
411
|
+
cancel: (id) => (requireCap('files'), call('files:offline:cancel', { id })),
|
|
412
|
+
remove: (id) => (requireCap('files'), call('files:offline:remove', { id })),
|
|
413
|
+
},
|
|
414
|
+
// index(indexerId, nodeId, contribution) where contribution is
|
|
415
|
+
// { semanticTexts?, tags?, metadata? }. Legacy (indexerId, nodeId, documents[], facet)
|
|
416
|
+
// is still accepted when the 3rd arg is an array of documents.
|
|
417
|
+
//
|
|
418
|
+
// "Contribution" here is per-node ENRICHMENT — what an indexer says ABOUT a file,
|
|
419
|
+
// addressed by contributorId. It is a different noun from the \`contributes\` map in
|
|
420
|
+
// your manifest, which declares extension points addressed by URI. A plugin
|
|
421
|
+
// declares an \`indexer\` contribution (that sense) and it produces contributions
|
|
422
|
+
// (this sense).
|
|
423
|
+
index: (indexerId, nodeId, contribution, facet) => {
|
|
424
|
+
requireCap('indexer');
|
|
425
|
+
var payload = Array.isArray(contribution) ? { documents: contribution, facet: facet } : (contribution || {});
|
|
426
|
+
return call('files:index', Object.assign({ indexerId: indexerId, nodeId: nodeId }, payload));
|
|
427
|
+
},
|
|
428
|
+
},
|
|
429
|
+
// Persistent storage: an isolated SQLite database per granted scope. \`plugin\`
|
|
430
|
+
// is private to this plugin; \`domain\` (verified packages only) is shared with
|
|
431
|
+
// the vendor's other plugins. Each scope exposes a \`.server\` handle (and, from
|
|
432
|
+
// Stage 3, an on-device \`.client\` handle) with the same async SQL surface.
|
|
433
|
+
storage: makeStorage(),
|
|
434
|
+
// The plugin's own settings (declared in the manifest). getSecret reads a
|
|
435
|
+
// secret-typed value the host stores separately.
|
|
436
|
+
settings: {
|
|
437
|
+
get: (key) => call('settings:get', { key }),
|
|
438
|
+
getSecret: (key) => call('settings:getSecret', { key }),
|
|
439
|
+
set: (key, value) => call('settings:set', { key, value }),
|
|
440
|
+
onChange: (fn) => { onSettingsChange = fn; },
|
|
441
|
+
},
|
|
442
|
+
onConnectivity: (fn) => { onConnectivity = fn; },
|
|
443
|
+
announce,
|
|
444
|
+
onDeactivate: (fn) => { onDeactivate = fn; },
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
async function activate(setup) {
|
|
449
|
+
await new Promise((resolve) => {
|
|
450
|
+
function onInit(e) {
|
|
451
|
+
if (!e.data || e.data.__trove !== 'init') return;
|
|
452
|
+
window.removeEventListener('message', onInit);
|
|
453
|
+
manifest = e.data.manifest; capabilities = e.data.capabilities || []; storageScopes = e.data.storage || {}; online = e.data.online != null ? e.data.online : true; role = e.data.role || 'primary';
|
|
454
|
+
port = e.ports[0];
|
|
455
|
+
port.onmessage = onPort;
|
|
456
|
+
resolve();
|
|
457
|
+
}
|
|
458
|
+
window.addEventListener('message', onInit);
|
|
459
|
+
parent.postMessage({ __trove: 'ready', protocolVersion: SDK_PROTOCOL_VERSION }, '*');
|
|
460
|
+
});
|
|
461
|
+
const ctx = makeContext();
|
|
462
|
+
try {
|
|
463
|
+
await setup(ctx);
|
|
464
|
+
await call('activated', { ok: true });
|
|
465
|
+
announce();
|
|
466
|
+
} catch (err) {
|
|
467
|
+
await call('activated', { ok: false, error: err && err.message });
|
|
468
|
+
throw err;
|
|
469
|
+
}
|
|
470
|
+
return ctx;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
globalThis.trove = { activate };
|
|
474
|
+
})();
|
|
475
|
+
`;var NK="1.0";function kY(A){return String(A||"").split(".")[0]||"0"}function gY(A){if(!A)return!0;return kY(A)===kY("1.0")}var yY;(function(A){A[A.Static=1]="Static",A[A.Dynamic=2]="Dynamic",A[A.ImportMeta=3]="ImportMeta",A[A.StaticSourcePhase=4]="StaticSourcePhase",A[A.DynamicSourcePhase=5]="DynamicSourcePhase",A[A.StaticDeferPhase=6]="StaticDeferPhase",A[A.DynamicDeferPhase=7]="DynamicDeferPhase"})(yY||(yY={}));var pG=new Uint8Array(new Uint16Array([1]).buffer)[0]===1;function PK(A,Q="@"){if(!o)return OK.then(()=>PK(A));let B=A.length+1,C=(o.__heap_base.value||o.__heap_base)+4*B-o.memory.buffer.byteLength;C>0&&o.memory.grow(Math.ceil(C/65536));let J=o.sa(B-1);if((pG?cG:lG)(A,new Uint16Array(o.memory.buffer,J,B)),!o.parse())throw Object.assign(Error(`Parse error ${Q}:${A.slice(0,o.e()).split(`
|
|
476
|
+
`).length}:${o.e()-A.lastIndexOf(`
|
|
477
|
+
`,o.e()-1)}`),{idx:o.e()});let K=[],E=[];for(;o.ri();){let L=o.is(),X=o.ie(),H=o.it(),G=o.ai(),D=o.id(),U=o.ss(),F=o.se(),R;o.ip()&&(R=Y(A.slice(D===-1?L-1:L,D===-1?X+1:X))),K.push({n:R,t:H,s:L,e:X,ss:U,se:F,d:D,a:G})}for(;o.re();){let L=o.es(),X=o.ee(),H=o.els(),G=o.ele(),D=A.slice(L,X),U=D[0],F=H<0?void 0:A.slice(H,G),R=F?F[0]:"";E.push({s:L,e:X,ls:H,le:G,n:U==='"'||U==="'"?Y(D):D,ln:R==='"'||R==="'"?Y(F):F})}function Y(L){try{return(0,eval)(L)}catch(X){}}return[K,E,!!o.f(),!!o.ms()]}function lG(A,Q){let B=A.length,C=0;for(;C<B;){let J=A.charCodeAt(C);Q[C++]=(255&J)<<8|J>>>8}}function cG(A,Q){let B=A.length,C=0;for(;C<B;)Q[C]=A.charCodeAt(C++)}var o,dG=()=>{return A="AGFzbQEAAAABKwhgAX8Bf2AEf39/fwBgAAF/YAAAYAF/AGADf39/AX9gAn9/AX9gA39/fwADMTAAAQECAgICAgICAgICAgICAgICAgIAAwMDBAQAAAUAAAAAAAMDAwAGAAAABwAGAgUEBQFwAQEBBQMBAAEGDwJ/AUHA8gALfwBBwPIACwd6FQZtZW1vcnkCAAJzYQAAAWUAAwJpcwAEAmllAAUCc3MABgJzZQAHAml0AAgCYWkACQJpZAAKAmlwAAsCZXMADAJlZQANA2VscwAOA2VsZQAPAnJpABACcmUAEQFmABICbXMAEwVwYXJzZQAUC19faGVhcF9iYXNlAwEKzkQwaAEBf0EAIAA2AoAKQQAoAtwJIgEgAEEBdGoiAEEAOwEAQQAgAEECaiIANgKECkEAIAA2AogKQQBBADYC4AlBAEEANgLwCUEAQQA2AugJQQBBADYC5AlBAEEANgL4CUEAQQA2AuwJIAEL0wEBA39BACgC8AkhBEEAQQAoAogKIgU2AvAJQQAgBDYC9AlBACAFQSRqNgKICiAEQSBqQeAJIAQbIAU2AgBBACgC1AkhBEEAKALQCSEGIAUgATYCACAFIAA2AgggBSACIAJBAmpBACAGIANGIgAbIAQgA0YiBBs2AgwgBSADNgIUIAVBADYCECAFIAI2AgQgBUEANgIgIAVBA0EBQQIgABsgBBs2AhwgBUEAKALQCSADRiICOgAYAkACQCACDQBBACgC1AkgA0cNAQtBAEEBOgCMCgsLXgEBf0EAKAL4CSIEQRBqQeQJIAQbQQAoAogKIgQ2AgBBACAENgL4CUEAIARBFGo2AogKQQBBAToAjAogBEEANgIQIAQgAzYCDCAEIAI2AgggBCABNgIEIAQgADYCAAsIAEEAKAKQCgsVAEEAKALoCSgCAEEAKALcCWtBAXULHgEBf0EAKALoCSgCBCIAQQAoAtwJa0EBdUF/IAAbCxUAQQAoAugJKAIIQQAoAtwJa0EBdQseAQF/QQAoAugJKAIMIgBBACgC3AlrQQF1QX8gABsLCwBBACgC6AkoAhwLHgEBf0EAKALoCSgCECIAQQAoAtwJa0EBdUF/IAAbCzsBAX8CQEEAKALoCSgCFCIAQQAoAtAJRw0AQX8PCwJAIABBACgC1AlHDQBBfg8LIABBACgC3AlrQQF1CwsAQQAoAugJLQAYCxUAQQAoAuwJKAIAQQAoAtwJa0EBdQsVAEEAKALsCSgCBEEAKALcCWtBAXULHgEBf0EAKALsCSgCCCIAQQAoAtwJa0EBdUF/IAAbCx4BAX9BACgC7AkoAgwiAEEAKALcCWtBAXVBfyAAGwslAQF/QQBBACgC6AkiAEEgakHgCSAAGygCACIANgLoCSAAQQBHCyUBAX9BAEEAKALsCSIAQRBqQeQJIAAbKAIAIgA2AuwJIABBAEcLCABBAC0AlAoLCABBAC0AjAoL3Q0BBX8jAEGA0ABrIgAkAEEAQQE6AJQKQQBBACgC2Ak2ApwKQQBBACgC3AlBfmoiATYCsApBACABQQAoAoAKQQF0aiICNgK0CkEAQQA6AIwKQQBBADsBlgpBAEEAOwGYCkEAQQA6AKAKQQBBADYCkApBAEEAOgD8CUEAIABBgBBqNgKkCkEAIAA2AqgKQQBBADoArAoCQAJAAkACQANAQQAgAUECaiIDNgKwCiABIAJPDQECQCADLwEAIgJBd2pBBUkNAAJAAkACQAJAAkAgAkGbf2oOBQEICAgCAAsgAkEgRg0EIAJBL0YNAyACQTtGDQIMBwtBAC8BmAoNASADEBVFDQEgAUEEakGCCEEKEC8NARAWQQAtAJQKDQFBAEEAKAKwCiIBNgKcCgwHCyADEBVFDQAgAUEEakGMCEEKEC8NABAXC0EAQQAoArAKNgKcCgwBCwJAIAEvAQQiA0EqRg0AIANBL0cNBBAYDAELQQEQGQtBACgCtAohAkEAKAKwCiEBDAALC0EAIQIgAyEBQQAtAPwJDQIMAQtBACABNgKwCkEAQQA6AJQKCwNAQQAgAUECaiIDNgKwCgJAAkACQAJAAkACQAJAIAFBACgCtApPDQAgAy8BACICQXdqQQVJDQYCQAJAAkACQAJAAkACQAJAAkACQCACQWBqDgoQDwYPDw8PBQECAAsCQAJAAkACQCACQaB/ag4KCxISAxIBEhISAgALIAJBhX9qDgMFEQYJC0EALwGYCg0QIAMQFUUNECABQQRqQYIIQQoQLw0QEBYMEAsgAxAVRQ0PIAFBBGpBjAhBChAvDQ8QFwwPCyADEBVFDQ4gASkABELsgISDsI7AOVINDiABLwEMIgNBd2oiAUEXSw0MQQEgAXRBn4CABHFFDQwMDQtBAEEALwGYCiIBQQFqOwGYCkEAKAKkCiABQQN0aiIBQQE2AgAgAUEAKAKcCjYCBAwNC0EALwGYCiIDRQ0JQQAgA0F/aiIDOwGYCkEALwGWCiICRQ0MQQAoAqQKIANB//8DcUEDdGooAgBBBUcNDAJAIAJBAnRBACgCqApqQXxqKAIAIgMoAgQNACADQQAoApwKQQJqNgIEC0EAIAJBf2o7AZYKIAMgAUEEajYCDAwMCwJAQQAoApwKIgEvAQBBKUcNAEEAKALwCSIDRQ0AIAMoAgQgAUcNAEEAQQAoAvQJIgM2AvAJAkAgA0UNACADQQA2AiAMAQtBAEEANgLgCQtBAEEALwGYCiIDQQFqOwGYCkEAKAKkCiADQQN0aiIDQQZBAkEALQCsChs2AgAgAyABNgIEQQBBADoArAoMCwtBAC8BmAoiAUUNB0EAIAFBf2oiATsBmApBACgCpAogAUH//wNxQQN0aigCAEEERg0EDAoLQScQGgwJC0EiEBoMCAsgAkEvRw0HAkACQCABLwEEIgFBKkYNACABQS9HDQEQGAwKC0EBEBkMCQsCQAJAAkACQEEAKAKcCiIBLwEAIgMQG0UNAAJAAkAgA0FVag4EAAkBAwkLIAFBfmovAQBBK0YNAwwICyABQX5qLwEAQS1GDQIMBwsgA0EpRw0BQQAoAqQKQQAvAZgKIgJBA3RqKAIEEBxFDQIMBgsgAUF+ai8BAEFQakH//wNxQQpPDQULQQAvAZgKIQILAkACQCACQf//A3EiAkUNACADQeYARw0AQQAoAqQKIAJBf2pBA3RqIgQoAgBBAUcNACABQX5qLwEAQe8ARw0BIAQoAgRBlghBAxAdRQ0BDAULIANB/QBHDQBBACgCpAogAkEDdGoiAigCBBAeDQQgAigCAEEGRg0ECyABEB8NAyADRQ0DIANBL0ZBAC0AoApBAEdxDQMCQEEAKAL4CSICRQ0AIAEgAigCAEkNACABIAIoAgRNDQQLIAFBfmohAUEAKALcCSECAkADQCABQQJqIgQgAk0NAUEAIAE2ApwKIAEvAQAhAyABQX5qIgQhASADECBFDQALIARBAmohBAsCQCADQf//A3EQIUUNACAEQX5qIQECQANAIAFBAmoiAyACTQ0BQQAgATYCnAogAS8BACEDIAFBfmoiBCEBIAMQIQ0ACyAEQQJqIQMLIAMQIg0EC0EAQQE6AKAKDAcLQQAoAqQKQQAvAZgKIgFBA3QiA2pBACgCnAo2AgRBACABQQFqOwGYCkEAKAKkCiADakEDNgIACxAjDAULQQAtAPwJQQAvAZYKQQAvAZgKcnJFIQIMBwsQJEEAQQA6AKAKDAMLECVBACECDAULIANBoAFHDQELQQBBAToArAoLQQBBACgCsAo2ApwKC0EAKAKwCiEBDAALCyAAQYDQAGokACACCxoAAkBBACgC3AkgAEcNAEEBDwsgAEF+ahAmC/4KAQZ/QQBBACgCsAoiAEEMaiIBNgKwCkEAKAL4CSECQQEQKSEDAkACQAJAAkACQAJAAkACQAJAQQAoArAKIgQgAUcNACADEChFDQELAkACQAJAAkACQAJAAkAgA0EqRg0AIANB+wBHDQFBACAEQQJqNgKwCkEBECkhA0EAKAKwCiEEA0ACQAJAIANB//8DcSIDQSJGDQAgA0EnRg0AIAMQLBpBACgCsAohAwwBCyADEBpBAEEAKAKwCkECaiIDNgKwCgtBARApGgJAIAQgAxAtIgNBLEcNAEEAQQAoArAKQQJqNgKwCkEBECkhAwsgA0H9AEYNA0EAKAKwCiIFIARGDQ8gBSEEIAVBACgCtApNDQAMDwsLQQAgBEECajYCsApBARApGkEAKAKwCiIDIAMQLRoMAgtBAEEAOgCUCgJAAkACQAJAAkACQCADQZ9/ag4MAgsEAQsDCwsLCwsFAAsgA0H2AEYNBAwKC0EAIARBDmoiAzYCsAoCQAJAAkBBARApQZ9/ag4GABICEhIBEgtBACgCsAoiBSkAAkLzgOSD4I3AMVINESAFLwEKECFFDRFBACAFQQpqNgKwCkEAECkaC0EAKAKwCiIFQQJqQbIIQQ4QLw0QIAUvARAiAkF3aiIBQRdLDQ1BASABdEGfgIAEcUUNDQwOC0EAKAKwCiIFKQACQuyAhIOwjsA5Ug0PIAUvAQoiAkF3aiIBQRdNDQYMCgtBACAEQQpqNgKwCkEAECkaQQAoArAKIQQLQQAgBEEQajYCsAoCQEEBECkiBEEqRw0AQQBBACgCsApBAmo2ArAKQQEQKSEEC0EAKAKwCiEDIAQQLBogA0EAKAKwCiIEIAMgBBACQQBBACgCsApBfmo2ArAKDwsCQCAEKQACQuyAhIOwjsA5Ug0AIAQvAQoQIEUNAEEAIARBCmo2ArAKQQEQKSEEQQAoArAKIQMgBBAsGiADQQAoArAKIgQgAyAEEAJBAEEAKAKwCkF+ajYCsAoPC0EAIARBBGoiBDYCsAoLQQAgBEEGajYCsApBAEEAOgCUCkEBECkhBEEAKAKwCiEDIAQQLCEEQQAoArAKIQIgBEHf/wNxIgFB2wBHDQNBACACQQJqNgKwCkEBECkhBUEAKAKwCiEDQQAhBAwEC0EAQQE6AIwKQQBBACgCsApBAmo2ArAKC0EBECkhBEEAKAKwCiEDAkAgBEHmAEcNACADQQJqQawIQQYQLw0AQQAgA0EIajYCsAogAEEBEClBABArIAJBEGpB5AkgAhshAwNAIAMoAgAiA0UNBSADQgA3AgggA0EQaiEDDAALC0EAIANBfmo2ArAKDAMLQQEgAXRBn4CABHFFDQMMBAtBASEECwNAAkACQCAEDgIAAQELIAVB//8DcRAsGkEBIQQMAQsCQAJAQQAoArAKIgQgA0YNACADIAQgAyAEEAJBARApIQQCQCABQdsARw0AIARBIHJB/QBGDQQLQQAoArAKIQMCQCAEQSxHDQBBACADQQJqNgKwCkEBECkhBUEAKAKwCiEDIAVBIHJB+wBHDQILQQAgA0F+ajYCsAoLIAFB2wBHDQJBACACQX5qNgKwCg8LQQAhBAwACwsPCyACQaABRg0AIAJB+wBHDQQLQQAgBUEKajYCsApBARApIgVB+wBGDQMMAgsCQCACQVhqDgMBAwEACyACQaABRw0CC0EAIAVBEGo2ArAKAkBBARApIgVBKkcNAEEAQQAoArAKQQJqNgKwCkEBECkhBQsgBUEoRg0BC0EAKAKwCiEBIAUQLBpBACgCsAoiBSABTQ0AIAQgAyABIAUQAkEAQQAoArAKQX5qNgKwCg8LIAQgA0EAQQAQAkEAIARBDGo2ArAKDwsQJQuFDAEKf0EAQQAoArAKIgBBDGoiATYCsApBARApIQJBACgCsAohAwJAAkACQAJAAkACQAJAAkAgAkEuRw0AQQAgA0ECajYCsAoCQEEBECkiAkHkAEYNAAJAIAJB8wBGDQAgAkHtAEcNB0EAKAKwCiICQQJqQZwIQQYQLw0HAkBBACgCnAoiAxAqDQAgAy8BAEEuRg0ICyAAIAAgAkEIakEAKALUCRABDwtBACgCsAoiAkECakGiCEEKEC8NBgJAQQAoApwKIgMQKg0AIAMvAQBBLkYNBwtBACEEQQAgAkEMajYCsApBASEFQQUhBkEBECkhAkEAIQdBASEIDAILQQAoArAKIgIpAAJC5YCYg9CMgDlSDQUCQEEAKAKcCiIDECoNACADLwEAQS5GDQYLQQAhBEEAIAJBCmo2ArAKQQIhCEEHIQZBASEHQQEQKSECQQEhBQwBCwJAAkACQAJAIAJB8wBHDQAgAyABTQ0AIANBAmpBoghBChAvDQACQCADLwEMIgRBd2oiB0EXSw0AQQEgB3RBn4CABHENAgsgBEGgAUYNAQtBACEHQQchBkEBIQQgAkHkAEYNAQwCC0EAIQRBACADQQxqIgI2ArAKQQEhBUEBECkhCQJAQQAoArAKIgYgAkYNAEHmACECAkAgCUHmAEYNAEEFIQZBACEHQQEhCCAJIQIMBAtBACEHQQEhCCAGQQJqQawIQQYQLw0EIAYvAQgQIEUNBAtBACEHQQAgAzYCsApBByEGQQEhBEEAIQVBACEIIAkhAgwCCyADIABBCmpNDQBBACEIQeQAIQICQCADKQACQuWAmIPQjIA5Ug0AAkACQCADLwEKIgRBd2oiB0EXSw0AQQEgB3RBn4CABHENAQtBACEIIARBoAFHDQELQQAhBUEAIANBCmo2ArAKQSohAkEBIQdBAiEIQQEQKSIJQSpGDQRBACADNgKwCkEBIQRBACEHQQAhCCAJIQIMAgsgAyEGQQAhBwwCC0EAIQVBACEICwJAIAJBKEcNAEEAKAKkCkEALwGYCiICQQN0aiIDQQAoArAKNgIEQQAgAkEBajsBmAogA0EFNgIAQQAoApwKLwEAQS5GDQRBAEEAKAKwCiIDQQJqNgKwCkEBECkhAiAAQQAoArAKQQAgAxABAkACQCAFDQBBACgC8AkhAQwBC0EAKALwCSIBIAY2AhwLQQBBAC8BlgoiA0EBajsBlgpBACgCqAogA0ECdGogATYCAAJAIAJBIkYNACACQSdGDQBBAEEAKAKwCkF+ajYCsAoPCyACEBpBAEEAKAKwCkECaiICNgKwCgJAAkACQEEBEClBV2oOBAECAgACC0EAQQAoArAKQQJqNgKwCkEBECkaQQAoAvAJIgMgAjYCBCADQQE6ABggA0EAKAKwCiICNgIQQQAgAkF+ajYCsAoPC0EAKALwCSIDIAI2AgQgA0EBOgAYQQBBAC8BmApBf2o7AZgKIANBACgCsApBAmo2AgxBAEEALwGWCkF/ajsBlgoPC0EAQQAoArAKQX5qNgKwCg8LAkAgBEEBcyACQfsAR3INAEEAKAKwCiECQQAvAZgKDQUDQAJAAkACQCACQQAoArQKTw0AQQEQKSICQSJGDQEgAkEnRg0BIAJB/QBHDQJBAEEAKAKwCkECajYCsAoLQQEQKSEDQQAoArAKIQICQCADQeYARw0AIAJBAmpBrAhBBhAvDQcLQQAgAkEIajYCsAoCQEEBECkiAkEiRg0AIAJBJ0cNBwsgACACQQAQKw8LIAIQGgtBAEEAKAKwCkECaiICNgKwCgwACwsCQAJAIAJBWWoOBAMBAQMACyACQSJGDQILQQAoArAKIQYLIAYgAUcNAEEAIABBCmo2ArAKDwsgAkEqRyAHcQ0DQQAvAZgKQf//A3ENA0EAKAKwCiECQQAoArQKIQEDQCACIAFPDQECQAJAIAIvAQAiA0EnRg0AIANBIkcNAQsgACADIAgQKw8LQQAgAkECaiICNgKwCgwACwsQJQsPC0EAIAJBfmo2ArAKDwtBAEEAKAKwCkF+ajYCsAoLRwEDf0EAKAKwCkECaiEAQQAoArQKIQECQANAIAAiAkF+aiABTw0BIAJBAmohACACLwEAQXZqDgQBAAABAAsLQQAgAjYCsAoLmAEBA39BAEEAKAKwCiIBQQJqNgKwCiABQQZqIQFBACgCtAohAgNAAkACQAJAIAFBfGogAk8NACABQX5qLwEAIQMCQAJAIAANACADQSpGDQEgA0F2ag4EAgQEAgQLIANBKkcNAwsgAS8BAEEvRw0CQQAgAUF+ajYCsAoMAQsgAUF+aiEBC0EAIAE2ArAKDwsgAUECaiEBDAALC4gBAQR/QQAoArAKIQFBACgCtAohAgJAAkADQCABIgNBAmohASADIAJPDQEgAS8BACIEIABGDQICQCAEQdwARg0AIARBdmoOBAIBAQIBCyADQQRqIQEgAy8BBEENRw0AIANBBmogASADLwEGQQpGGyEBDAALC0EAIAE2ArAKECUPC0EAIAE2ArAKC2wBAX8CQAJAIABBX2oiAUEFSw0AQQEgAXRBMXENAQsgAEFGakH//wNxQQZJDQAgAEEpRyAAQVhqQf//A3FBB0lxDQACQCAAQaV/ag4EAQAAAQALIABB/QBHIABBhX9qQf//A3FBBElxDwtBAQsuAQF/QQEhAQJAIABBpglBBRAdDQAgAEGWCEEDEB0NACAAQbAJQQIQHSEBCyABC0YBA39BACEDAkAgACACQQF0IgJrIgRBAmoiAEEAKALcCSIFSQ0AIAAgASACEC8NAAJAIAAgBUcNAEEBDwsgBBAmIQMLIAMLgwEBAn9BASEBAkACQAJAAkACQAJAIAAvAQAiAkFFag4EBQQEAQALAkAgAkGbf2oOBAMEBAIACyACQSlGDQQgAkH5AEcNAyAAQX5qQbwJQQYQHQ8LIABBfmovAQBBPUYPCyAAQX5qQbQJQQQQHQ8LIABBfmpByAlBAxAdDwtBACEBCyABC7QDAQJ/QQAhAQJAAkACQAJAAkACQAJAAkACQAJAIAAvAQBBnH9qDhQAAQIJCQkJAwkJBAUJCQYJBwkJCAkLAkACQCAAQX5qLwEAQZd/ag4EAAoKAQoLIABBfGpByghBAhAdDwsgAEF8akHOCEEDEB0PCwJAAkACQCAAQX5qLwEAQY1/ag4DAAECCgsCQCAAQXxqLwEAIgJB4QBGDQAgAkHsAEcNCiAAQXpqQeUAECcPCyAAQXpqQeMAECcPCyAAQXxqQdQIQQQQHQ8LIABBfGpB3AhBBhAdDwsgAEF+ai8BAEHvAEcNBiAAQXxqLwEAQeUARw0GAkAgAEF6ai8BACICQfAARg0AIAJB4wBHDQcgAEF4akHoCEEGEB0PCyAAQXhqQfQIQQIQHQ8LIABBfmpB+AhBBBAdDwtBASEBIABBfmoiAEHpABAnDQQgAEGACUEFEB0PCyAAQX5qQeQAECcPCyAAQX5qQYoJQQcQHQ8LIABBfmpBmAlBBBAdDwsCQCAAQX5qLwEAIgJB7wBGDQAgAkHlAEcNASAAQXxqQe4AECcPCyAAQXxqQaAJQQMQHSEBCyABCzQBAX9BASEBAkAgAEF3akH//wNxQQVJDQAgAEGAAXJBoAFGDQAgAEEuRyAAEChxIQELIAELMAEBfwJAAkAgAEF3aiIBQRdLDQBBASABdEGNgIAEcQ0BCyAAQaABRg0AQQAPC0EBC04BAn9BACEBAkACQCAALwEAIgJB5QBGDQAgAkHrAEcNASAAQX5qQfgIQQQQHQ8LIABBfmovAQBB9QBHDQAgAEF8akHcCEEGEB0hAQsgAQveAQEEf0EAKAKwCiEAQQAoArQKIQECQAJAAkADQCAAIgJBAmohACACIAFPDQECQAJAAkAgAC8BACIDQaR/ag4FAgMDAwEACyADQSRHDQIgAi8BBEH7AEcNAkEAIAJBBGoiADYCsApBAEEALwGYCiICQQFqOwGYCkEAKAKkCiACQQN0aiICQQQ2AgAgAiAANgIEDwtBACAANgKwCkEAQQAvAZgKQX9qIgA7AZgKQQAoAqQKIABB//8DcUEDdGooAgBBA0cNAwwECyACQQRqIQAMAAsLQQAgADYCsAoLECULC3ABAn8CQAJAA0BBAEEAKAKwCiIAQQJqIgE2ArAKIABBACgCtApPDQECQAJAAkAgAS8BACIBQaV/ag4CAQIACwJAIAFBdmoOBAQDAwQACyABQS9HDQIMBAsQLhoMAQtBACAAQQRqNgKwCgwACwsQJQsLNQEBf0EAQQE6APwJQQAoArAKIQBBAEEAKAK0CkECajYCsApBACAAQQAoAtwJa0EBdTYCkAoLQwECf0EBIQECQCAALwEAIgJBd2pB//8DcUEFSQ0AIAJBgAFyQaABRg0AQQAhASACEChFDQAgAkEuRyAAECpyDwsgAQs9AQJ/QQAhAgJAQQAoAtwJIgMgAEsNACAALwEAIAFHDQACQCADIABHDQBBAQ8LIABBfmovAQAQICECCyACC2gBAn9BASEBAkACQCAAQV9qIgJBBUsNAEEBIAJ0QTFxDQELIABB+P8DcUEoRg0AIABBRmpB//8DcUEGSQ0AAkAgAEGlf2oiAkEDSw0AIAJBAUcNAQsgAEGFf2pB//8DcUEESSEBCyABC5wBAQN/QQAoArAKIQECQANAAkACQCABLwEAIgJBL0cNAAJAIAEvAQIiAUEqRg0AIAFBL0cNBBAYDAILIAAQGQwBCwJAAkAgAEUNACACQXdqIgFBF0sNAUEBIAF0QZ+AgARxRQ0BDAILIAIQIUUNAwwBCyACQaABRw0CC0EAQQAoArAKIgNBAmoiATYCsAogA0EAKAK0CkkNAAsLIAILMQEBf0EAIQECQCAALwEAQS5HDQAgAEF+ai8BAEEuRw0AIABBfGovAQBBLkYhAQsgAQumBAEBfwJAIAFBIkYNACABQSdGDQAQJQ8LQQAoArAKIQMgARAaIAAgA0ECakEAKAKwCkEAKALQCRABAkAgAkEBSA0AQQAoAvAJQQRBBiACQQFGGzYCHAtBAEEAKAKwCkECajYCsAoCQAJAAkACQEEAECkiAUHhAEYNACABQfcARg0BQQAoArAKIQEMAgtBACgCsAoiAUECakHACEEKEC8NAUEGIQIMAgtBACgCsAoiAS8BAkHpAEcNACABLwEEQfQARw0AQQQhAiABLwEGQegARg0BC0EAIAFBfmo2ArAKDwtBACABIAJBAXRqNgKwCgJAQQEQKUH7AEYNAEEAIAE2ArAKDwtBACgCsAoiACECA0BBACACQQJqNgKwCgJAAkACQEEBECkiAkEiRg0AIAJBJ0cNAUEnEBpBAEEAKAKwCkECajYCsApBARApIQIMAgtBIhAaQQBBACgCsApBAmo2ArAKQQEQKSECDAELIAIQLCECCwJAIAJBOkYNAEEAIAE2ArAKDwtBAEEAKAKwCkECajYCsAoCQEEBECkiAkEiRg0AIAJBJ0YNAEEAIAE2ArAKDwsgAhAaQQBBACgCsApBAmo2ArAKAkACQEEBECkiAkEsRg0AIAJB/QBGDQFBACABNgKwCg8LQQBBACgCsApBAmo2ArAKQQEQKUH9AEYNAEEAKAKwCiECDAELC0EAKALwCSIBIAA2AhAgAUEAKAKwCkECajYCDAttAQJ/AkACQANAAkAgAEH//wNxIgFBd2oiAkEXSw0AQQEgAnRBn4CABHENAgsgAUGgAUYNASAAIQIgARAoDQJBACECQQBBACgCsAoiAEECajYCsAogAC8BAiIADQAMAgsLIAAhAgsgAkH//wNxC6sBAQR/AkACQEEAKAKwCiICLwEAIgNB4QBGDQAgASEEIAAhBQwBC0EAIAJBBGo2ArAKQQEQKSECQQAoArAKIQUCQAJAIAJBIkYNACACQSdGDQAgAhAsGkEAKAKwCiEEDAELIAIQGkEAQQAoArAKQQJqIgQ2ArAKC0EBECkhA0EAKAKwCiECCwJAIAIgBUYNACAFIARBACAAIAAgAUYiAhtBACABIAIbEAILIAMLcgEEf0EAKAKwCiEAQQAoArQKIQECQAJAA0AgAEECaiECIAAgAU8NAQJAAkAgAi8BACIDQaR/ag4CAQQACyACIQAgA0F2ag4EAgEBAgELIABBBGohAAwACwtBACACNgKwChAlQQAPC0EAIAI2ArAKQd0AC0kBA39BACEDAkAgAkUNAAJAA0AgAC0AACIEIAEtAAAiBUcNASABQQFqIQEgAEEBaiEAIAJBf2oiAg0ADAILCyAEIAVrIQMLIAMLC+wBAgBBgAgLzgEAAHgAcABvAHIAdABtAHAAbwByAHQAZgBvAHIAZQB0AGEAbwB1AHIAYwBlAHIAbwBtAHUAbgBjAHQAaQBvAG4AcwBzAGUAcgB0AHYAbwB5AGkAZQBkAGUAbABlAGMAbwBuAHQAaQBuAGkAbgBzAHQAYQBuAHQAeQBiAHIAZQBhAHIAZQB0AHUAcgBkAGUAYgB1AGcAZwBlAGEAdwBhAGkAdABoAHIAdwBoAGkAbABlAGkAZgBjAGEAdABjAGYAaQBuAGEAbABsAGUAbABzAABB0AkLEAEAAAACAAAAAAQAAEA5AAA=",typeof Buffer<"u"?Buffer.from(A,"base64"):Uint8Array.from(atob(A),(Q)=>Q.charCodeAt(0));var A},OK=WebAssembly.compile(dG()).then(WebAssembly.instantiate).then(({exports:A})=>{o=A});var aG=/\.m?js$/i;function L0(A){return/^src\//i.test(A)&&aG.test(A)}function hY(A){return L0(A.entry||"")}function nG(A){let Q=A.lastIndexOf("/");return(Q<0?"":A.slice(0,Q)).split("/").filter(Boolean)}function sG(A,Q){let B=nG(A);for(let C of Q.split("/"))if(C===""||C===".")continue;else if(C==="..")B.pop();else B.push(C);return B.join("/")}async function bY(A){await OK;let Q={};for(let[K,E]of A.files)if(L0(K))Q[K]=new TextDecoder().decode(E);let B=(K)=>Object.prototype.hasOwnProperty.call(Q,K),C=(K,E)=>{let Y=sG(K,E);if(B(Y))return Y;if(B(Y+".js"))return Y+".js";if(B(Y+".mjs"))return Y+".mjs";if(B(Y+"/index.js"))return Y+"/index.js";return Y},J={};for(let[K,E]of Object.entries(Q))J[K]=oG(E,K,C);return{modules:J,entry:A.manifest.entry}}function oG(A,Q,B){let[C]=PK(A),J="",K=0;for(let E of C){if(E.n==null)continue;if(E.n[0]!==".")continue;let Y="trove:/"+B(Q,E.n),L=E.d===-1?Y:JSON.stringify(Y);J+=A.slice(K,E.s)+L,K=E.e}return J+A.slice(K)}var iG=15000;class jK{constructor({media:A,dock:Q}={}){this.media=A,this.dock=Q}async spawn(A,Q,B){let C=document.createElement("iframe");C.style.cssText=rG,C.setAttribute("sandbox","allow-scripts allow-forms"),C.setAttribute("referrerpolicy","no-referrer");let J=B?.entry;if(J)A._entrySrcdoc||={},A._entrySrcdoc[J]||=await vY({...A.manifest,entry:J},A.files),C.srcdoc=A._entrySrcdoc[J];else A._srcdoc||=await vY(A.manifest,A.files),C.srcdoc=A._srcdoc;let K={role:Q,iframe:C,channel:null,record:A,place:null,dock:null,mediaActions:null};document.body.appendChild(C);try{await this.#A(A,K,B)}catch(E){try{K.channel?.dispose()}catch{}throw C.remove(),E}return K}#A(A,Q,{onCall:B,onEvent:C,online:J}){return new Promise((K,E)=>{let{iframe:Y}=Q,L=A.manifest,X=!1,H=0,G=()=>{if(window.removeEventListener("message",U),H)clearTimeout(H)},D=(F)=>{if(X)return;X=!0,G(),E(Error(F))},U=(F)=>{if(F.source!==Y.contentWindow)return;if(F.data?.__trove==="boot-error")return D(F.data.error||"Plugin failed to load its modules");if(F.data?.__trove!=="ready")return;if(!gY(F.data.protocolVersion))return D(`Plugin speaks protocol ${F.data.protocolVersion}, this host speaks ${NK}`);window.removeEventListener("message",U);let R=new MessageChannel;Q.channel=new zK(R.port1,{onCall:(V,w)=>B(A,V,w,Q),onEvent:(V,w)=>C(A,V,w,Q)}),Q.resolveActivated=(V)=>{if(X)return;if(X=!0,H)clearTimeout(H);K(V)},Q.rejectActivated=(V)=>{if(X)return;if(X=!0,H)clearTimeout(H);E(V)},Y.contentWindow.postMessage({__trove:"init",manifest:L,capabilities:A.grants,storage:A.storage,online:J,role:Q.role,protocolVersion:NK},"*",[R.port2])};H=setTimeout(()=>D("Plugin handshake timed out"),iG),window.addEventListener("message",U),Y.addEventListener("error",()=>D("Failed to load plugin iframe"))})}destroy(A){if(!A)return;this.dock?.releaseFrame(A),this.media?.releaseFrame(A);try{A.channel?.emit("deactivate")}catch{}try{A.channel?.dispose()}catch{}A.iframe.remove(),A.record?.frames?.delete(A)}}var rG="position:fixed;left:0;top:0;width:0;height:0;border:0;visibility:hidden;",tG=["default-src 'none'","script-src 'unsafe-inline' 'unsafe-eval' blob:","style-src 'unsafe-inline'","img-src blob: data:","media-src blob: data:","font-src 'none'","connect-src 'none'","base-uri 'none'","form-action 'none'"].join("; "),uY=`<!doctype html><html><head><meta charset="utf-8"><meta http-equiv="Content-Security-Policy" content="${tG}"></head><body>`;async function vY(A,Q){if(hY(A))return eG(await bY({manifest:A,files:Q}));let B=new TextDecoder().decode(Q.get(A.entry)??new Uint8Array);return`${uY}
|
|
478
|
+
<script>${qK}</script>
|
|
479
|
+
<script>${B}</script>
|
|
480
|
+
</body></html>`}function fY(A){return JSON.stringify(A).replace(/</g,"\\u003c").replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029")}function eG(A){let Q=fY("trove:/"+A.entry);return`${uY}
|
|
481
|
+
<script>${qK}</script>
|
|
482
|
+
<script id="__trove_src" type="application/json">${fY(A.modules)}</script>
|
|
483
|
+
<script>
|
|
484
|
+
(function () {
|
|
485
|
+
var src = JSON.parse(document.getElementById('__trove_src').textContent);
|
|
486
|
+
var imports = {};
|
|
487
|
+
for (var p in src) imports['trove:/' + p] = URL.createObjectURL(new Blob([src[p] + '\\n//# sourceURL=trove:/' + p], { type: 'text/javascript' }));
|
|
488
|
+
imports['trove'] = URL.createObjectURL(new Blob(['export const activate = globalThis.trove.activate;\\nexport default globalThis.trove;'], { type: 'text/javascript' }));
|
|
489
|
+
var im = document.createElement('script');
|
|
490
|
+
im.type = 'importmap';
|
|
491
|
+
im.textContent = JSON.stringify({ imports: imports });
|
|
492
|
+
document.head.appendChild(im);
|
|
493
|
+
import(${Q}).catch(function (e) {
|
|
494
|
+
try { parent.postMessage({ __trove: 'boot-error', error: String((e && e.message) || e) }, '*'); } catch (_) {}
|
|
495
|
+
});
|
|
496
|
+
})();
|
|
497
|
+
</script>
|
|
498
|
+
</body></html>`}var A$=/\b(ATTACH|DETACH|VACUUM|PRAGMA)\b/i;function Q$(A){let Q="",B=0;while(B<A.length){let C=A[B];if(C==="-"&&A[B+1]==="-"){let J=A.indexOf(`
|
|
499
|
+
`,B);B=J<0?A.length:J;continue}if(C==="/"&&A[B+1]==="*"){let J=A.indexOf("*/",B+2);B=J<0?A.length:J+2,Q+=" ";continue}if(C==="'"||C==='"'||C==="`"){let J=C;B++;while(B<A.length){if(A[B]===J){if(A[B+1]===J){B+=2;continue}B++;break}B++}Q+=" ";continue}if(C==="["){let J=A.indexOf("]",B);B=J<0?A.length:J+1,Q+=" ";continue}Q+=C,B++}return Q}function SK(A){if(typeof A!=="string"||!A)throw q.invalid("SQL statement is required");if(A$.test(Q$(A)))throw q.invalid("ATTACH, DETACH, VACUUM and PRAGMA are not permitted in plugin storage")}var B$=26214400;async function C$(A,Q){let B=Number(A.headers.get("content-length")||0);if(B&&B>Q)throw Error("Response too large");let C=A.body?.getReader?.();if(!C){let L=await A.arrayBuffer();if(L.byteLength>Q)throw Error("Response too large");return L}let J=[],K=0;for(;;){let{done:L,value:X}=await C.read();if(L)break;if(K+=X.byteLength,K>Q)throw await C.cancel().catch(()=>{}),Error("Response too large");J.push(X)}let E=new Uint8Array(K),Y=0;for(let L of J)E.set(L,Y),Y+=L.byteLength;return E.buffer}class _K{constructor({platform:A,clientDb:Q,media:B,dock:C,onChange:J}={}){this.platform=A,this.clientDb=Q,this.media=B,this.dock=C,this.onChange=J||(()=>{})}async hostCall(A,Q,B,C){let J=(E)=>{if(!A.grants.includes(E))throw Error(`Capability "${E}" not granted`)},K=A.id;switch(Q){case"activated":{let E=C||A.frame;if(clearTimeout(E?._timer),B.ok)E?.resolveActivated?.(E);else E?.rejectActivated?.(Error(B.error||"activate() failed"));return{ok:!0}}case"command:execute":{let E=this.#A(A,B.id);if(!cC(A.manifest,E))throw Error(`Command "${B.id}" is not in this plugin's declared commands`);return{ok:!0,result:await this.platform.commands.execute(E,...B.args||[])??null}}case"ui:status":{J("ui");let E=this.#Q(A,B.name,"statusItem");return this.platform.contributions.update(E.uri,{...B.html!==void 0?{html:String(B.html??"")}:{},...B.tooltip!==void 0?{tooltip:String(B.tooltip??"")}:{},...B.visible!==void 0?{visible:!!B.visible}:{visible:!0}}),{ok:!0}}case"context:setRegister":{let E=this.#Q(A,B.name,"register"),Y=A.registers?.get(E.uri);if(!Y)throw Error(`Register "${B.name}" is not available`);return Y(B.value),{ok:!0}}case"resources:list":return[...A.files.keys()].filter(pY);case"resources:read":{if(!pY(B.path))throw Error(`No such resource ${B.path}`);let E=A.files.get(B.path);if(!E)throw Error(`No such resource ${B.path}`);return{bytes:E.slice().buffer}}case"files:read":return J("files"),{text:await this.platform.api.readText(B.id)};case"files:list":return J("files"),this.platform.api.list(B.collection||B.pathOrId,{sort:B.sort,order:B.order,limit:B.limit,cursor:B.cursor});case"files:stat":return J("files"),this.platform.api.stat(B.id);case"files:bytes":{J("files");let E=await this.platform.fileChunks.read(B.id,{start:B.start,end:B.end});return{bytes:E.bytes.buffer,etag:E.etag,total:E.total}}case"files:offline:start":return J("files"),this.platform.fileChunks.start(B.id);case"files:offline:status":return J("files"),this.platform.fileChunks.status(B.id);case"files:offline:cancel":return J("files"),this.platform.fileChunks.cancel(B.id),{ok:!0};case"files:offline:remove":return J("files"),this.platform.fileChunks.remove(B.id).then(()=>({ok:!0}));case"files:mediaUrl":{J("files");let{url:E,expiresAt:Y}=await this.platform.mediaUrls.url(B.id,{op:B.op||"media"});return{url:E,expiresAt:Y}}case"files:index":{J("indexer");let E=kQ(B.indexerId)?B.indexerId:xQ(A.manifest,B.indexerId||"default");return this.platform.api.pushIndex(E,B.nodeId,{semanticTexts:B.semanticTexts,tags:B.tags,metadata:B.metadata,documents:B.documents,facet:B.facet})}case"net:fetch":return J("network"),this.#C(A,B);case"storage:sql":return J("storage"),this.#J(A,B);case"settings:get":return this.platform.settings.get(`${K}.${B.key}`);case"settings:getSecret":return A.secrets?.[B.key]??null;case"settings:set":return this.platform.settings.set(`${K}.${B.key}`,B.value),{ok:!0};case"ui:showPanel":return J("ui"),A.hasUi=!0,this.platform.dispatch(new CC(K)),this.onChange(),{ok:!0};case"media:metadata":{J("media");let E=(B.artwork||[]).filter((Y)=>this.#B(A,Y?.src));return this.media.apply(C,"metadata",{...B,artwork:E})}case"media:playbackState":return J("media"),this.media.apply(C,"playbackState",B);case"media:position":return J("media"),this.media.apply(C,"position",B);case"media:action":return J("media"),this.media.apply(C,"action",B);case"media:clear":return this.media.apply(C,"clear",B);case"dock:enable":if(J("dock"),C)C.dock={enabled:!0,minSize:B.minSize,maxSize:B.maxSize,dismissed:!1};return{ok:!0};case"dock:disable":if(J("dock"),C?.dock)C.dock.enabled=!1;if(C&&this.dock.docked===C)this.dock.closeDock(C);return{ok:!0};case"dock:close":if(C)this.dock.closeDock(C);return{ok:!0};default:throw Error(`Unknown host method ${Q}`)}}hostEvent(A,Q,B,C){switch(Q){case"manifest":if(C&&C.role!=="primary")break;A.live=B,A.responsive=!0,this.onChange();break;case"ui:toast":this.platform.notifications[B.level||"info"](`${dA(A.manifest)}: ${B.text}`);break;case"ui:badge":A.badge=B.text,this.onChange();break}}#A(A,Q){if(!Q||kQ(Q))return Q;let B=this.platform.contributions.get(xQ(A.manifest,Q));return B?.type==="command"?B.uri:Q}#Q(A,Q,B){let C=Q?this.platform.contributions.get(xQ(A.manifest,Q)):null;if(!C||C.pluginId!==A.id||C.type!==B)throw Error(`"${Q}" is not a ${B} declared by this plugin`);return C}#B(A,Q){if(!Q)return!1;if(/^(blob:|data:image\/)/i.test(Q))return!0;return pC(rQ(A.manifest),Q)}async#C(A,{url:Q,method:B="GET",headers:C,body:J}){let K=rQ(A.manifest);if(mY(Q,this.platform.api?.baseUrl))throw Error("Blocked: a plugin may not call the drive's own API through the network broker");if(!pC(K,Q))throw Error(`Blocked: "${Q}" is not one of this plugin's declared network endpoints`);let E={method:B,credentials:"omit",redirect:"follow",headers:K$(C)};if(J!=null&&B!=="GET"&&B!=="HEAD")E.body=J instanceof ArrayBuffer?new Uint8Array(J):J;let Y=await fetch(Q,E);if(Y.url&&Y.url!==Q){if(mY(Y.url,this.platform.api?.baseUrl))throw Error("Blocked: request redirected onto the drive's own API");if(!pC(K,Y.url))throw Error(`Blocked: request redirected off this plugin's declared endpoints (${Y.url})`)}let L=await C$(Y,B$),X={};return Y.headers.forEach((H,G)=>{X[G]=H}),{ok:Y.ok,status:Y.status,statusText:Y.statusText,url:Y.url,headers:X,bytes:L}}async#J(A,{scope:Q="plugin",side:B="server",op:C,sql:J,params:K=[],statements:E}){if(!A.storage?.[Q])throw Error(`Storage scope "${Q}" not granted${Q==="domain"?" (needs a verified domain)":""}`);if(B==="client"){if(C==="batch")for(let G of Array.isArray(E)?E:[])SK(G?.sql);else SK(J);let X=Q==="domain"?`dom:${A.manifest.domain}`:`plg:${A.id}`,H=await this.clientDb.obtain(X);return E$(H,C,J,K,E)}let Y={scope:Q,op:C,sql:J,params:K,statements:E,domain:Q==="domain"?A.manifest.domain:void 0};return(await this.platform.api.request("POST",`/api/plugins/${encodeURIComponent(A.id)}/sql`,{body:Y})).result}}function mY(A,Q){try{let B=new URL(Q||"",globalThis.location?.href||"http://localhost/");return new URL(A,B).origin===B.origin}catch{return!1}}function pY(A){return A!=="manifest.json"&&!L0(A)}var J$=new Set(["host","cookie","cookie2","set-cookie","origin","referer","content-length","connection"]);function K$(A){let Q={};for(let[B,C]of Object.entries(A||{}))if(!J$.has(String(B).toLowerCase()))Q[B]=C;return Q}function E$(A,Q,B,C=[],J){switch(Q){case"exec":return A.exec(B);case"run":return A.run(B,...C);case"get":return A.get(B,...C);case"all":return A.all(B,...C);case"batch":return A.batch(J);default:throw Error(`Unknown storage op "${Q}"`)}}var lY=["files","storage","ui","commands","indexer","opener","network","media","dock"];class wK{constructor(A,{heartbeatMs:Q=20000}={}){this.platform=A,this.plugins=new Map,this.registry=new e0,this.clientDb=new QJ({onError:(B,C)=>this.platform.notifications.error(`A plugin's on-device data couldn't be saved (${C}): ${B.message}`)}),this.online=typeof navigator<"u"?navigator.onLine:!0,this.heartbeatMs=Q,this._heartbeat=null,this._probing=!1,this.cell=A.reactive.cell([]),this.media=new XJ,this.dock=new HJ({destroyFrame:(B)=>this.frames.destroy(B),openFile:(B,C)=>this.platform.dispatch(new HQ(B,C)),onChange:()=>this.#A()}),this.frames=new jK({media:this.media,dock:this.dock}),this.rpc=new _K({platform:A,clientDb:this.clientDb,media:this.media,dock:this.dock,onChange:()=>this.#A()})}observe(){return this.cell}#A(){this.cell.setValue(this.list())}#Q(A,Q,B){return this.frames.spawn(A,Q,{onCall:(C,J,K,E)=>this.rpc.hostCall(C,J,K,E),onEvent:(C,J,K,E)=>this.rpc.hostEvent(C,J,K,E),online:this.online,entry:B})}#B(A){let Q=A.id,B=this.platform.contributions,C=(K)=>A.disposers.push(K),J=dA(A.manifest);for(let K of FQ(A.manifest)){let E={...K,pluginId:Q};switch(K.type){case"opener":if(A.grants.includes("opener"))C(B.register(K.uri,E));break;case"command":C(this.platform.commands.register({id:K.uri,title:K.title||`${J}: ${K.name}`,category:K.category||J,icon:K.icon,when:K.when,offline:K.offline,palette:K.palette,pluginId:Q,actions:(...Y)=>new IK(Q,K.name,Y)}));break;case"statusItem":{let Y=K.command?this.#J(A,K.command,J,`status item “${K.name}”`):null;C(B.register(K.uri,{...E,command:Y,html:"",visible:!1}));break}case"register":{C(B.register(K.uri,E));let Y=this.platform.context.own(K.uri,K.default);A.registers.set(K.uri,Y.set),C(()=>{A.registers.delete(K.uri),Y.dispose()});break}case"keymap":{let Y=A.files.get(K.path);if(!Y){this.platform.notifications.warn(`Plugin "${J}": keymap file "${K.path}" is not in the package.`);break}try{let L=this.#C(A,J8(new TextDecoder().decode(Y)),J);C(B.register(K.uri,{...E,bindings:L}))}catch(L){this.platform.notifications.warn(`Plugin "${J}": ${L.message}`)}break}case"indexer":break}}}#C(A,Q,B){let C=[];for(let J of Q){let K=this.#J(A,J.command,B,`shortcut ${J.key}`);if(K)C.push({...J,command:K})}return C}#J(A,Q,B,C){let J=xQ(A.manifest,Q);if(FQ(A.manifest).some((E)=>E.uri===J&&E.type==="command"))return J;if(!cC(A.manifest,Q))return this.platform.notifications.warn(`Plugin "${B}": ${C} runs "${Q}", which it isn't allowed to run — ignored.`),null;return Q}list(){return[...this.plugins.values()].map((A)=>({id:A.id,name:dA(A.manifest),version:A.manifest.version,status:A.status,capabilities:A.grants,error:A.error||null,hasUi:A.hasUi,badge:A.badge||null,trust:A.trust||null,settingsSchema:A.manifest.settings||[],endpoints:lC(rQ(A.manifest)),responsive:!!A.responsive,manifest:A.live||null,features:this.#K(A)}))}#K(A){let Q;try{Q=FQ(A.manifest)}catch{return[]}return Q.map((B)=>({kind:B.type,id:B.uri,name:B.name,title:B.title||B.name,offline:!!B.offline,available:this.#E(A,B)}))}#E(A,Q){if(A.status!=="active"||!A.responsive)return!1;return this.online||!!Q.offline}isAvailable(A){if(!A?.pluginId)return!0;let Q=this.plugins.get(A.pluginId);if(!Q)return!1;return this.#E(Q,A)}canGrant(A,Q){return!KJ.has(A)||!!Q}async install(A,{grants:Q,trust:B}={}){let C=JQ(A.manifest),J=EJ(A.manifest),K=(Q||J).filter((X)=>lY.includes(X)&&J.includes(X)),E=X$(A.manifest,K)?"account":"device";if(E==="account"){if(!A.raw)throw Error("Package bytes unavailable for a server install");await this.platform.api.installPlugin(A.raw,K)}let Y=K.includes("storage")?LJ(A.manifest,B):{plugin:!1,domain:!1},L={id:C,manifest:A.manifest,files:Object.fromEntries([...A.files.entries()]),grants:K,storage:Y,trust:B||null,scope:E,settings:{},secrets:{},installedAt:Date.now()};return await this.registry.save(L),this.#L(L),await this.#X(L),this.plugins.get(C)}async restore(){let A=[];try{A=await this.registry.list()}catch{}for(let Q of A)try{this.#L(Q),this.#X(Q).catch((B)=>console.error("restore plugin failed",Q.id,B))}catch(B){console.error("skipping corrupt plugin record",Q?.id,B),this.platform.notifications.warn(`Couldn't restore plugin "${Q?.manifest?dA(Q.manifest):Q?.id||"unknown"}" — its saved data looks corrupt.`)}this.#Y(A).catch(()=>{})}async#Y(A){let Q;try{Q=(await this.platform.api.installedPlugins()).plugins||[]}catch{return}let B=new Set(Q.map((Y)=>Y.pluginId)),C=new Set(A.map((Y)=>Y.id)),J=0,K=0,E=0;for(let Y of A){if(Y.scope!=="account"||B.has(Y.id))continue;try{await this.platform.api.installPlugin(O8(L$(Y.files)),Y.grants||[])}catch(L){console.error("re-upload plugin failed",Y.id,L),J++}}for(let Y of Q){if(C.has(Y.pluginId))continue;try{let L=tQ(await this.platform.api.pluginPackage(Y.pluginId)),X=Y.grants||[],H={id:Y.pluginId,manifest:L.manifest,files:Object.fromEntries([...L.files.entries()]),grants:X,storage:X.includes("storage")?{plugin:!0,domain:!!Y.sharedStorage}:{plugin:!1,domain:!1},trust:null,scope:"account",settings:{},secrets:{},installedAt:Y.createdAt||Date.now()};await this.registry.save(H),this.#L(H),await this.#X(H),K++}catch(L){console.error("sync plugin failed",Y.pluginId,L),E++}}if(K)this.platform.notifications.info(`Synced ${K} account plugin${K>1?"s":""} from the server.`);if(J||E){let Y=[];if(E)Y.push(`${E} couldn't be downloaded`);if(J)Y.push(`${J} couldn't be uploaded`);this.platform.notifications.warn(`Some account plugins didn't sync: ${Y.join(", ")}.`)}}#L(A){let Q=(A.manifest.settings||[]).filter((B)=>!B.secret);if(Q.length)A._settingsDispose=this.platform.settings.scopedFor(A.id).register(Q.map((B)=>({...B,category:dA(A.manifest)})))}async#X(A){if(this.plugins.get(A.id)?.status==="active")return;let Q={...A,iframe:null,status:"loading",error:null,disposers:[],channel:null,registers:new Map,hasUi:!1,responsive:!1,frame:null,frames:new Set,storage:A.storage||(A.grants?.includes("storage")?LJ(A.manifest,A.trust):{plugin:!1,domain:!1}),files:Y$(A.files)};this.plugins.set(A.id,Q);try{this.#B(Q)}catch(B){console.error("registering contributions failed",A.id,B)}this.#A();try{let B=await this.#Q(Q,"primary");if(this.plugins.get(A.id)!==Q)return this.frames.destroy(B),Q;Q.frame=B,Q.iframe=B.iframe,Q.channel=B.channel,Q.status="active",Q.responsive=!0,this.#G(Q).then(()=>this.#A()),this.#H()}catch(B){Q.status="error",Q.error=B?.message||String(B),this.platform.notifications.error(`Plugin "${dA(A.manifest)}" failed to load: ${Q.error}`)}return this.#A(),Q}async setSecret(A,Q,B){let C=await this.registry.get(A);if(!C)return;C.secrets={...C.secrets,[Q]:B},await this.registry.save(C);let J=this.plugins.get(A);if(J)J.secrets=C.secrets;J?.channel?.emit("settings:changed",{key:Q,value:"••••"})}async getSecret(A,Q){return(await this.registry.get(A))?.secrets?.[Q]??""}#H(){if(this._heartbeat||!this.heartbeatMs)return;if(this._heartbeat=setInterval(()=>this.#Z(),this.heartbeatMs),this._heartbeat?.unref)this._heartbeat.unref()}#$(){if(this._heartbeat)clearInterval(this._heartbeat);this._heartbeat=null}async#Z(){if(this._probing)return;this._probing=!0;try{let A=!1;for(let Q of this.plugins.values())if(Q.status==="active")A=await this.#G(Q)||A;if(A)this.#A()}finally{this._probing=!1}}invokeCommand(A,Q,B=[]){return this.plugins.get(A)?.channel?.call("command:execute",{id:Q,args:B})}setHeartbeat(A){if(this.heartbeatMs=A,this.#$(),A&&[...this.plugins.values()].some((Q)=>Q.status==="active"))this.#H()}async#G(A){if(A.status!=="active"||!A.channel)return!1;let Q={responsive:A.responsive,sig:cY(A.live)};try{A.live=await A.channel.call("manifest",{},{timeout:4000}),A.responsive=!0}catch{A.responsive=!1}return Q.responsive!==A.responsive||Q.sig!==cY(A.live)}async setOnline(A){if(this.online===A)return;this.online=A,await Promise.all([...this.plugins.values()].filter((Q)=>Q.status==="active").map(async(Q)=>{try{Q.channel?.emit("connectivity",{online:A})}catch{}for(let B of Q.frames||[])try{B.channel?.emit("connectivity",{online:A})}catch{}await this.#G(Q)})),this.#A()}async refresh(A){let Q=this.plugins.get(A);if(Q)await this.#G(Q),this.#A()}mountPanel(A,Q,{width:B=380,height:C=480}={}){let J=this.plugins.get(A);if(!J?.frame)return null;return Q.style.width=`${B}px`,Q.style.height=`${C}px`,this.dock.place(J.frame,Q,50),J.hasUi=!0,()=>this.dock.hide(J.frame)}mountViewer(A,Q,B,C,J={}){let K=this.plugins.get(A);if(!K)return J.onError?.("Plugin is not available"),null;let E=this.dock.docked;if(E&&E.record===K&&E.node?.id===B.id&&E.openerId===C)return this.dock.undock(E),this.dock.place(E,Q,3),J.onReady?.(),()=>this.#D(E);let Y=this.platform.contributions.get(C),L={cancelled:!1,frame:null};return this.#Q(K,"viewer",Y?.entry).then(async(X)=>{if(L.cancelled){this.frames.destroy(X);return}L.frame=X,X.node=B,X.openerId=C,K.frames.add(X),this.dock.place(X,Q,3);try{if(await X.channel?.call("opener:open",{openerId:C,file:B,context:{}}),!L.cancelled)J.onReady?.()}catch(H){if(!L.cancelled)J.onError?.(H?.message||"Failed to open")}}).catch((X)=>{if(console.error("viewer frame failed to load",X),!L.cancelled)J.onError?.(X?.message||"This viewer failed to load")}),K.hasUi=!0,()=>{if(L.cancelled=!0,L.frame)this.#D(L.frame)}}#D(A){if(A.dock?.enabled&&!A.dock.dismissed)this.dock.dock(A);else this.frames.destroy(A)}async uninstall(A,{wipeData:Q=!0}={}){let B=this.plugins.get(A),C=B?.manifest?dA(B.manifest):A,J=B?.scope==="account"||(await this.registry.get(A).catch(()=>null))?.scope==="account";if(Q&&J)try{await this.platform.api.uninstallPluginServer(A)}catch(Y){this.platform.notifications.error(`Couldn't uninstall "${C}" from the server: ${Y.message}. It's still installed.`);return}if(B){try{B.channel?.emit("deactivate")}catch{}for(let Y of B.disposers)try{Y()}catch{}B._settingsDispose?.();for(let Y of[...B.frames||[]])this.frames.destroy(Y);if(B.frame)this.dock.stopPlace(B.frame),this.media.releaseActions(B.frame);B.channel?.dispose(),B.iframe?.remove(),this.plugins.delete(A)}let K=[];if(Q){if(!J)await this.platform.api.request("DELETE",`/api/plugins/${encodeURIComponent(A)}/data`).catch(()=>K.push("server-side data"));await this.clientDb.drop(`plg:${A}`).catch(()=>K.push("on-device data"))}let E=!1;try{await this.registry.remove(A)}catch(Y){E=!0,console.error("removing the persisted plugin record failed",A,Y)}if(![...this.plugins.values()].some((Y)=>Y.status==="active"))this.#$();if(this.#A(),E)this.platform.notifications.error(`Removed "${C}", but its saved record couldn't be deleted — it may come back when you reload.`);else if(K.length)this.platform.notifications.warn(`Uninstalled "${C}", but couldn't clear its ${K.join(" and ")}.`)}fetchAssetlinks=async(A)=>{return(await this.platform.api.request("GET","/api/plugins/assetlinks",{query:{domain:A}}))?.assetlinks||null};assessTrust(A){return k8(A,this.fetchAssetlinks)}}function Y$(A){let Q=new Map;for(let[B,C]of Object.entries(A))Q.set(B,C instanceof Uint8Array?C:new Uint8Array(C));return Q}function L$(A){let Q={};for(let[B,C]of Object.entries(A||{}))Q[B]=C instanceof Uint8Array?C:new Uint8Array(C);return Q}function X$(A,Q){if(Q.includes("storage"))return!0;return w0(A).length>0}function cY(A){if(!A)return"";return`${A.online?1:0}|${[...A.handlers||[]].sort().join(",")}`}var dY=["auto","desktop","phone","tv"],H$=720,G$=1100,$$=/\b(smart-?tv|smarttv|appletv|googletv|android\s*tv|hbbtv|netcast|web0s|webos|tizen|viera|bravia|aquos|crkey|nettv|dtv|philipstv|roku|aft[a-z]{1,3})\b/i;function D$(A="",Q=0){if(!A)return!1;return $$.test(A)&&Q>=G$}class TK{#A;constructor({window:A=globalThis,settings:Q=null}={}){this.window=A,this.settings=Q,this.urlOverride=U$(A),this.#A=this.#B(),this.cell=c(this.#A),this._onResize=()=>this.refresh()}get(){return this.#A}observe(){return this.cell}install(){if(this.window.addEventListener?.("resize",this._onResize),this.window.addEventListener?.("orientationchange",this._onResize),this.settings)TQ(this.settings.observe(),()=>this.refresh());return this.#Q(this.#A),this}dispose(){this.window.removeEventListener?.("resize",this._onResize),this.window.removeEventListener?.("orientationchange",this._onResize)}refresh(){let A=this.#B();if(A.mode===this.#A.mode&&A.width===this.#A.width&&A.height===this.#A.height&&A.coarse===this.#A.coarse)return;this.#A=A,this.#Q(A),this.cell.setValue(A)}#Q(A){let Q=this.window.document?.documentElement;if(Q)Q.dataset.layout=A.mode}#B(){let A=this.window,Q=A.innerWidth||1280,B=A.innerHeight||800,C=W$(A,"(pointer: coarse)"),J=A.navigator?.userAgent||"",K=this.urlOverride||this.settings?.get?.("workbench.layout")||"auto";return{mode:K!=="auto"&&dY.includes(K)?K:Z$({width:Q,coarse:C,ua:J}),width:Q,height:B,coarse:C,forced:K!=="auto"}}}function Z$({width:A,coarse:Q,ua:B}){if(D$(B,A))return"tv";if(A<=H$)return"phone";return"desktop"}function W$(A,Q){try{return!!A.matchMedia?.(Q)?.matches}catch{return!1}}function U$(A){try{let Q=new URL(A.location.href).searchParams.get("ui");return Q&&dY.includes(Q)?Q:null}catch{return null}}var sY='a[href], button:not([disabled]), input:not([disabled]), select, textarea, [tabindex]:not([tabindex="-1"])',oY=".launch-item, .grid-tile, .sheet-row, .inbox-item, .plugin-card, .act-task, .act-issue, .chapter",I$=`${sY}, ${oY}`,F$=new Set(["BrowserBack","GoBack","Backspace"]),R$=new Set([10009,461]),M$={ArrowLeft:"left",ArrowRight:"right",ArrowUp:"up",ArrowDown:"down"},V$=new Set(["A","BUTTON","INPUT","SELECT","TEXTAREA"]);class xK{constructor({workbench:A,viewport:Q,window:B=globalThis}){this.viewport=Q,this.window=B,this.active=!1,this._onKey=(C)=>this.handleKey(C),this._observer=null,this._pending=0,this._bootstrapped=!1}install(){if(this.viewport)TQ(this.viewport.observe(),(A)=>this.setActive(A.mode==="tv"));return this.setActive(this.viewport?.get().mode==="tv"),this}setActive(A){if(A===this.active)return;if(this.active=A,A)this.window.addEventListener?.("keydown",this._onKey),this.#A(),this.prime(),this.window.setTimeout?.(()=>this.prime(),60);else this.window.removeEventListener?.("keydown",this._onKey),this._observer?.disconnect(),this._observer=null,this._bootstrapped=!1}prime(){this.candidates(),this.focusFirst()}#A(){let A=this.window.MutationObserver;if(!A||this._observer)return;this._observer=new A(()=>{if(this._pending)return;this._pending=this.window.requestAnimationFrame?.(()=>{if(this._pending=0,this.active)this.prime()})||0}),this._observer.observe(this.window.document.body,{childList:!0,subtree:!0})}handleKey(A){if(!this.active||A.defaultPrevented||A.altKey||A.ctrlKey||A.metaKey)return;let Q=this.window.document,B=Q.activeElement;if(F$.has(A.key)||R$.has(A.keyCode)){if(A.key==="Backspace"&&aY(B)&&(B.value??"").length>0)return;A.preventDefault(),this.goBack();return}let C=M$[A.key];if(!C){if(A.key==="Enter"&&B&&!V$.has(B.tagName)&&B.matches(oY))A.preventDefault(),B.click();return}if((C==="left"||C==="right")&&aY(B)&&!z$(B,C))return;let J=B&&B!==Q.body?B:null,K=this.find(C,J);if(!K)return;A.preventDefault(),nY(K)}goBack(){if(this.workbench?.closeOverlays())return;this.window.history?.back?.()}candidates(){let A=this.window.document,Q=[];for(let B of A.querySelectorAll(I$)){if(B.getAttribute?.("aria-hidden")==="true"||B.hasAttribute?.("disabled"))continue;let C=B.getBoundingClientRect();if(C.width<2||C.height<2)continue;if(C.bottom<0||C.top>this.window.innerHeight||C.right<0||C.left>this.window.innerWidth)continue;if(!B.matches(sY)&&!B.hasAttribute("tabindex"))B.setAttribute("tabindex","0");Q.push({el:B,rect:C})}return Q}find(A,Q){let B=this.candidates();if(!B.length)return null;let C=Q&&Q.getBoundingClientRect&&Q.getBoundingClientRect().width?Q.getBoundingClientRect():null;if(!C)return B[0].el;let J=null,K=1/0;for(let{el:E,rect:Y}of B){if(E===Q)continue;let L=q$(C,Y,A);if(L==null||L>=K)continue;K=L,J=E}return J}focusFirst(){if(this._bootstrapped)return;let A=this.window.document;if(A?.activeElement&&A.activeElement!==A.body)return;let Q=this.candidates();if(!Q.length)return;let B=Q.find((C)=>C.el.classList?.contains("launch-input"))||Q[0];nY(B.el),this._bootstrapped=!0}}function z$(A,Q){let{selectionStart:B,selectionEnd:C}=A;if(B==null||C==null)return!0;if(B!==C)return!1;return Q==="left"?B===0:C>=(A.value??"").length}function aY(A){if(!A)return!1;let Q=A.tagName;if(Q==="TEXTAREA")return!0;if(A.isContentEditable)return!0;if(Q!=="INPUT")return!1;return!["checkbox","radio","button","submit","range","file"].includes(A.type)}function nY(A){A.focus?.({preventScroll:!0}),A.scrollIntoView?.({block:"nearest",inline:"nearest"})}function q$(A,Q,B){let C=B==="up"||B==="down",[J,K]=C?B==="down"?[A.bottom,Q.top]:[A.top,Q.bottom]:B==="right"?[A.right,Q.left]:[A.left,Q.right],Y=B==="down"||B==="right"?K-J:J-K;if(Y<-2)return null;let[L,X,H,G]=C?[A.left,A.right,Q.left,Q.right]:[A.top,A.bottom,Q.top,Q.bottom],D=Math.max(0,Math.max(L,H)-Math.min(X,G)),U=Math.abs((L+X)/2-(H+G)/2);return Math.max(0,Y)+D*3+U*0.2}function $C(){if(typeof window>"u")return null;return window.SpeechRecognition||window.webkitSpeechRecognition||null}function X0(){let A=$C();return!!A&&typeof A.available==="function"}var kK=(A)=>({langs:[A],processLocally:!0});async function iY(A=navigator.language||"en-US"){if(!X0())return"unavailable";try{return await $C().available(kK(A))}catch{return"unavailable"}}async function rY(A=navigator.language||"en-US"){if(typeof $C()?.install!=="function")return!1;try{return await $C().install(kK(A))}catch{return!1}}function tY({lang:A=navigator.language||"en-US",onText:Q,onEnd:B,onError:C}={}){if(!X0())throw Error("On-device speech recognition is not available here");let J=new($C());J.lang=A,J.interimResults=!0,J.continuous=!1,J.options=kK(A),J.processLocally=!0;let K=!1;J.onresult=(E)=>{let Y="",L=!1;for(let X=E.resultIndex;X<E.results.length;X++)if(Y+=E.results[X][0].transcript,E.results[X].isFinal)L=!0;Q?.(Y.trim(),{final:L})},J.onerror=(E)=>{if(E.error==="no-speech"||E.error==="aborted")return;C?.(Error(E.error||"Speech recognition failed"))},J.onend=()=>{if(!K)K=!0,B?.()};try{J.start()}catch(E){K=!0,C?.(E),B?.()}return{stop(){if(K)return;K=!0;try{J.stop()}catch{}B?.()}}}class gK{#A;constructor({notifications:A,settings:Q}={}){this.notifications=A,this.settings=Q,this.session=null,this.#A={supported:X0(),status:"unknown",listening:!1},this.cell=c(this.#A)}get(){return this.#A}observe(){return this.cell}#Q(A){this.#A={...this.#A,...A},this.cell.setValue(this.#A)}async refresh(){if(!this.#A.supported)return"unavailable";let A=await iY(this.#B());return this.#Q({status:A}),A}#B(){return this.settings?.get?.("search.voiceLanguage")||navigator.language||"en-US"}canListen(){return this.#A.supported&&(this.#A.status==="available"||this.#A.status==="downloadable")}async run({onText:A}={}){if(this.openSearchSurface(),await this.focusInput(),!this.#A.supported)return{listening:!1,reason:"unsupported"};let Q=this.#A.status==="unknown"?await this.refresh():this.#A.status;if(Q==="downloadable"){this.notifications?.info("Downloading the on-device voice model — this happens once.");let B=await rY(this.#B());if(this.#Q({status:B?"available":"unavailable"}),!B)return{listening:!1,reason:"install-failed"}}else if(Q!=="available")return{listening:!1,reason:Q};return this.toggle({onText:A})}toggle({onText:A}={}){if(this.session)return this.stop(),{listening:!1};try{return this.session=tY({lang:this.#B(),onText:A,onEnd:()=>{this.session=null,this.#Q({listening:!1})},onError:(Q)=>{if(this.session=null,this.#Q({listening:!1}),!/not-allowed|service-not-allowed|denied/i.test(Q.message))this.notifications?.warn(`Couldn't listen: ${Q.message}`)}}),this.#Q({listening:!0}),{listening:!0}}catch(Q){return this.notifications?.warn(`Couldn't listen: ${Q.message}`),{listening:!1,reason:"error"}}}stop(){this.session?.stop(),this.session=null,this.#Q({listening:!1})}openSearchSurface(){let A=this.workbench;if(!A)return;if(A.state.activity==="home"&&!A.nav?.get?.().activeTabId)A.closeSearchModal?.();else A.openSearchModal()}focusInput({tries:A=12}={}){return new Promise((Q)=>{let B=A,C=()=>{let J=document.querySelector(".search-modal .launch-input")||document.querySelector(".launch-input");if(J){J.focus();try{J.setSelectionRange(J.value.length,J.value.length)}catch{}Q(document.activeElement===J);return}if(--B<=0){Q(!1);return}requestAnimationFrame(C)};C()})}}class yK{constructor({api:A,settings:Q=null}){this.api=A,this.settings=Q,this.cache=new Map,this._queue=new Map,this._timer=null}get needed(){let A=this.settings?.get("media.signedUrls");if(A==="always")return!0;if(A==="never")return!1;return!!this.api.token?.()}cacheKey(A){return this.api.downloadUrl(A)}async url(A,{op:Q="media"}={}){if(!this.needed)return{url:this.api.downloadUrl(A,{attachment:Q==="download"}),expiresAt:1/0};let B=`${Q}:${A}`,C=this.cache.get(B);if(C&&this.#A(C))return C;return this.#Q(A,Q)}invalidate(A,Q="media"){if(A==null)this.cache.clear();else this.cache.delete(`${Q}:${A}`)}#A(A){if(A.expiresAt===1/0)return!0;let Q=A.expiresAt-A.mintedAt;return Date.now()<A.mintedAt+Q*0.8}#Q(A,Q){if(!this._queue.has(Q))this._queue.set(Q,new Map);let B=this._queue.get(Q),C=B.get(A);if(C)return C.promise;let J,K,E=new Promise((Y,L)=>{J=Y,K=L});if(B.set(A,{resolve:J,reject:K,promise:E}),B.size>=200)this.#B();else if(!this._timer)this._timer=setTimeout(()=>this.#B(),20);return E}async#B(){clearTimeout(this._timer),this._timer=null;let A=this._queue;this._queue=new Map;for(let[Q,B]of A){let C=[...B.keys()];try{let J=await this.api.mintUrls(C,Q),K=Date.now();for(let[E,Y]of this.cache)if(Y.expiresAt&&Y.expiresAt<K)this.cache.delete(E);for(let[E,Y]of B){let L=J.urls?.[E];if(L){let X={url:L.url,expiresAt:L.expiresAt,mintedAt:K};this.cache.set(`${Q}:${E}`,X),Y.resolve(X)}else Y.reject(Error(J.failed?.[E]==="not_found"?"That file is gone":"You cannot open that file"))}}catch(J){for(let K of B.values())K.reject(J)}}}}var eY=(A)=>Math.floor(A/4194304),N$=(A,Q)=>{let B=new Uint8Array(Q),C=0;for(let J of A)B.set(J,C),C+=J.length;return B};class hK{constructor({api:A,mediaUrls:Q}){this.api=A,this.mediaUrls=Q,this.kept=new Map,this.listeners=new Set}onProgress(A){return this.listeners.add(A),()=>this.listeners.delete(A)}#A(A){let Q=this.status(A);for(let B of[...this.listeners])try{B(A,Q)}catch{}}#Q(A,Q,B){return`${this.mediaUrls.cacheKey(A)}&chunk=${Q||"none"}:4194304:${B}`}async#B(A){if(!("caches"in globalThis))return null;return caches.open(A).catch(()=>null)}async#C(A){let Q=await this.#B("trove-files-v1");if(!Q)return null;return Q.match(this.mediaUrls.cacheKey(A),{ignoreVary:!0}).catch(()=>null)}async read(A,{start:Q=0,end:B,signal:C}={}){let J=await this.#C(A);if(J){let E=await J.blob(),Y=B==null?E.size:Math.min(B,E.size);return{bytes:new Uint8Array(await E.slice(Q,Y).arrayBuffer()),etag:J.headers.get("etag"),total:E.size}}let K=this.kept.get(A);if(!K)return this.api.readRange(A,{start:Q,end:B,signal:C});return this.#J(A,K,Q,B,C)}async#J(A,Q,B,C,J){let K=await this.#B("trove-chunks-v1");if(!K)return this.api.readRange(A,{start:B,end:C,signal:J});if(Q.total==null){let X=await this.api.readRange(A,{start:0,end:1,signal:J});Q.total=X.total,Q.etag=X.etag}let E=Math.min(C==null?Q.total:C,Q.total);if(E<=B)return{bytes:new Uint8Array(0),etag:Q.etag,total:Q.total};let Y=[],L=0;for(let X=eY(B);X<=eY(E-1);X++){let H=await this.#K(A,Q,X,K,J),G=Math.max(0,B-X*4194304),D=Math.min(H.length,E-X*4194304),U=H.subarray(G,D);Y.push(U),L+=U.length}return{bytes:N$(Y,L),etag:Q.etag,total:Q.total}}async#K(A,Q,B,C,J){let K=this.#Q(A,Q.etag,B),E=await C.match(K).catch(()=>null);if(E)return Q.have.add(B),new Uint8Array(await E.arrayBuffer());let Y=B*4194304,L=Math.min(Y+4194304,Q.total),X=await this.api.readRange(A,{start:Y,end:L,signal:J});if(X.etag&&Q.etag&&X.etag!==Q.etag)await this.#Y(A),Q.have.clear(),Q.etag=X.etag,Q.total=X.total??Q.total;return await C.put(K,new Response(X.bytes)).catch(()=>{}),Q.have.add(B),this.#A(A),X.bytes}async start(A){if(this.kept.get(A))return this.status(A);let B=await this.api.readRange(A,{start:0,end:1}),C=new AbortController,J={etag:B.etag,total:B.total,filling:!0,done:!1,failed:null,have:new Set,controller:C};return this.kept.set(A,J),this.#A(A),this.#E(A,J,C.signal).catch((K)=>{J.filling=!1,J.failed=K?.message||String(K),this.#A(A)}),this.status(A)}async#E(A,Q,B){let C=await this.#B("trove-chunks-v1");if(!C)throw Error("This browser has no Cache Storage, so nothing can be kept offline");let J=Math.max(1,Math.ceil((Q.total||0)/4194304));for(let K=0;K<J;K++){if(B.aborted)return;await this.#K(A,Q,K,C,B)}Q.filling=!1,Q.done=!0,this.#A(A)}status(A){let Q=this.kept.get(A);if(!Q)return{kept:!1,loaded:0,total:null,ratio:0,filling:!1,done:!1,error:null};let B=Q.total??null,C=B?Math.ceil(B/4194304)-1:-1,J=0;for(let K of Q.have)J+=K===C?B-C*4194304:4194304;return{kept:!0,total:B,loaded:J,ratio:B?Math.min(1,J/B):0,filling:Q.filling,done:Q.done,error:Q.failed}}cancel(A){let Q=this.kept.get(A);if(!Q)return;Q.controller?.abort(),Q.filling=!1,this.#A(A)}async remove(A){let Q=this.kept.get(A);this.cancel(A),this.kept.delete(A),Q?.have?.clear(),await this.#Y(A),this.#A(A)}async#Y(A){let Q=await this.#B("trove-chunks-v1");if(!Q)return;let B=`${this.mediaUrls.cacheKey(A)}&chunk=`,C=await Q.keys().catch(()=>[]);for(let J of C)if(J.url.startsWith(B))await Q.delete(J).catch(()=>{})}}function P$(){try{return localStorage.getItem("trove.token")||null}catch{return null}}function AL({baseUrl:A=""}={}){let Q=new T0,B=new k0,C=new f0,J=new g0(Q,B,C),K=new v0,E=new UB(Q,J,B,K),Y=new u0({baseUrl:A,token:()=>P$()}),L=new TK({settings:K}),X=new xK({viewport:L}),H=new gK({notifications:C,settings:K}),G={reactive:oE,contributions:Q,context:B,commands:J,keybindings:E,settings:K,notifications:C,api:Y,viewport:L,spatialNav:X,voice:H};return G.mediaUrls=new yK({api:G.api,settings:K}),G.fileChunks=new hK({api:G.api,mediaUrls:G.mediaUrls}),G.plugins=new wK(G),J.availability=(D)=>G.plugins.isAvailable(D),O$(G),L.refresh(),G}function O$(A){A.settings.register([{key:"workbench.theme",type:"enum",enum:["dark","light","midnight"],enumLabels:["Dark","Light","Midnight"],default:"dark",title:"Color theme",category:"Appearance",order:1},{key:"workbench.density",type:"enum",enum:["comfortable","compact"],default:"comfortable",title:"List density",category:"Appearance",order:2},{key:"workbench.layout",type:"enum",enum:["auto","desktop","phone","tv"],enumLabels:["Automatic","Desktop","Phone","TV / remote"],default:"auto",title:"Layout",description:"Automatic follows the screen size. Choose TV for d-pad remote navigation.",category:"Appearance",order:3},{key:"explorer.sort",type:"enum",enum:["name","size","updatedAt"],enumLabels:["Name","Size","Modified"],default:"name",title:"Sort files by",category:"Explorer",order:1},{key:"explorer.sortOrder",type:"enum",enum:["asc","desc"],default:"asc",title:"Sort order",category:"Explorer",order:2},{key:"explorer.confirmDelete",type:"boolean",default:!0,title:"Confirm before deleting",category:"Explorer",order:3},{key:"search.mode",type:"enum",enum:["hybrid","semantic","keyword"],default:"hybrid",title:"Search mode",description:"Hybrid blends semantic meaning with keyword matches.",category:"Search",order:1},{key:"uploads.concurrency",type:"number",minimum:1,maximum:8,default:4,title:"Parallel upload parts",category:"Transfers",order:1},{key:"openers.associations",type:"object",hidden:!0,title:"Default viewers",default:{".md":"core.markdown",".markdown":"core.markdown"}},{key:"explorer.view",type:"string",hidden:!0,title:"Results view"},{key:"media.signedUrls",type:"enum",enum:["auto","always","never"],default:"auto",hidden:!0,title:"Signed media URLs"}]),A.contributions.register("keymap.default",{type:"keymap",bindings:[{key:"mod+shift+p",command:"workbench.showCommandPalette"},{key:"mod+p",command:"workbench.quickOpen"},{key:"mod+shift+f",command:"workbench.view.home"},{key:"mod+shift+e",command:"workbench.view.home"},{key:"mod+,",command:"workbench.openSettings"},{key:"mod+shift+l",command:"explorer.copyLink"},{key:"mod+u",command:"explorer.upload"},{key:"delete",command:"explorer.delete",when:"view.active == 'home' && explorer.hasSelection"},{key:"escape",command:"workbench.closeOverlays"},{key:"f5",command:"explorer.refresh"},{key:"mod+shift+i",command:"workbench.toggleInfoPanel"},{key:"mod+shift+v",command:"search.voice"},{key:"browsersearch",command:"search.voice"}]})}function QL(A,{workbench:Q,overlay:B,navigation:C,explorer:J}){let K=Q.observe(),E=C.observe(),Y=B.observe(),L=J.observe(),X={"view.active":BA([K],(G)=>G.activity),"sidebar.visible":BA([K],(G)=>G.sidebarVisible),"searchModal.open":BA([K],(G)=>!!G.searchModal),"sheet.open":BA([K],(G)=>G.sheet||""),"infoPanel.open":BA([K],(G)=>!!G.infoPanel),"palette.open":BA([Y],(G)=>!!G.palette),"editor.open":BA([E],(G)=>!!G.activeFile),"editor.openerId":BA([E],(G)=>G.stack?.at(-1)?.openerId||""),"editor.contentType":BA([E],(G)=>G.activeFile?.contentType||""),"explorer.collectionId":BA([L],(G)=>G.collectionId??null),"explorer.hasSelection":BA([L],(G)=>(G.selection?.length||0)>0)},H=Object.entries(X).map(([G,D])=>A.register(G,D));return()=>H.forEach((G)=>G())}function BL(A,Q){let B=Q.observe(),C=[A.register("viewport.mode",BA([B],(J)=>J.mode)),A.register("viewport.phone",BA([B],(J)=>J.mode==="phone")),A.register("viewport.tv",BA([B],(J)=>J.mode==="tv"))];return()=>C.forEach((J)=>J())}var CL="trove.recents",j$=12;class vK{#A;constructor(){this.#A={stack:[{kind:"search"}],activeTabId:null,activeFile:null,recents:S$()},this.cell=c(this.#A)}get(){return this.#A}observe(){return this.cell}#Q(A){this.#A={...this.#A,...A},this.cell.setValue(this.#A)}#B(){return this.#A.stack[this.#A.stack.length-1]}activeTab(){let A=this.#B();return A?.kind==="file"?A:null}#C(A,{history:Q=!0}={}){let B=A[A.length-1],C=B&&B.kind==="file"?B:null;if(this.#Q({stack:A,activeTabId:C?C.id:null,activeFile:C?C.node:null}),Q)this.#J()}reset(){this.#C([{kind:"search"}])}openFile(A,Q,{reset:B=!1}={}){let C={kind:"file",id:A.id,node:A,openerId:Q},J;if(B)J=[{kind:"search"},C];else{let K=this.#A.stack.findIndex((E)=>E.kind==="file"&&E.id===A.id);if(K>=0)J=this.#A.stack.slice(0,K+1),J[K]=C;else J=[...this.#A.stack,C]}this.#K(A),this.#C(J)}back(){if(this.#A.stack.length<=1)return;try{history.back()}catch{this.pop()}}pop(){if(this.#A.stack.length>1)this.#C(this.#A.stack.slice(0,-1),{history:!1})}forget(A){let Q=this.#A.recents.filter((C)=>C.id!==A);if(Q.length!==this.#A.recents.length)this.#Q({recents:Q}),bK(Q);let B=this.#A.stack.filter((C)=>!(C.kind==="file"&&C.id===A));this.#C(B.length?B:[{kind:"search"}],{history:!1})}updateTabNode(A){let Q=this.#A.recents.map((C)=>C.id===A.id?{...C,name:A.name,contentType:A.contentType||C.contentType}:C);if(Q.some((C,J)=>C!==this.#A.recents[J]))this.#Q({recents:Q}),bK(Q);let B=this.#A.stack.map((C)=>C.kind==="file"&&C.id===A.id?{...C,node:A}:C);this.#C(B,{history:!1})}#J(A=!1){let Q=this.#B(),B=Q?.node,C={troveDepth:this.#A.stack.length,node:B?{id:B.id,name:B.name,contentType:B.contentType,collectionId:B.collectionId}:null,openerId:Q?.openerId||null};try{(A?history.replaceState:history.pushState).call(history,C,"")}catch{}}onPopState(A){let Q=A?.state||{},B=Q.troveDepth||1;if(B<=this.#A.stack.length)this.#C(this.#A.stack.slice(0,B),{history:!1});else if(Q.node)this.#C([...this.#A.stack,{kind:"file",id:Q.node.id,node:Q.node,openerId:Q.openerId}],{history:!1})}#K(A){if(!A)return;let B=[{id:A.id,name:A.name,contentType:A.contentType||"",collectionId:A.collectionId},...this.#A.recents.filter((C)=>C.id!==A.id)].slice(0,j$);this.#Q({recents:B}),bK(B)}}function S$(){try{return JSON.parse(localStorage.getItem(CL))||[]}catch{return[]}}function bK(A){try{localStorage.setItem(CL,JSON.stringify(A))}catch{}}class fK{#A;constructor(A,Q=null){this.offline=Q,this.platform=A,this.api=A.api,this.#A={me:null,notifications:{items:[],unread:0},inboxOpen:!1,pushSupported:"serviceWorker"in navigator&&"PushManager"in window,pushEnabled:!1,sidecar:null,backlinks:null,posting:!1,replyTo:null},this.cell=c(this.#A),this._pollTimer=null}get(){return this.#A}observe(){return this.cell}#Q(A){this.#A={...this.#A,...A},this.cell.setValue(this.#A)}async init(){try{let A=await this.api.me();this.#Q({me:A.principal,admin:!!A.admin})}catch{}if(await this.refreshNotifications(),this._pollTimer=setInterval(()=>this.refreshNotifications(),45000),this._pollTimer.unref)this._pollTimer.unref();this.#C(),window.addEventListener("focus",()=>this.refreshNotifications()),navigator.serviceWorker?.addEventListener?.("message",(A)=>{if(A.data?.type==="trove-push")this.refreshNotifications()})}async refreshNotifications(){try{let A=await this.api.notifications();this.#Q({notifications:A})}catch{}}toggleInbox(A){let Q=A??!this.#A.inboxOpen;if(this.#Q({inboxOpen:Q}),Q&&this.#A.notifications.unread)this.markAllRead()}async markAllRead(){try{await this.api.markNotificationsRead(),this.#Q({notifications:{...this.#A.notifications,unread:0,items:this.#A.notifications.items.map((A)=>({...A,read:!0}))}})}catch{}}async loadSidecar(A){if(!A)return this.#Q({sidecar:null,backlinks:null});this.#Q({sidecar:{nodeId:A,loading:!0,tags:[],comments:[],subscribers:[]}}),this.loadBacklinks(A);try{let Q=await this.api.sidecar(A);if(this.#A.sidecar?.nodeId!==A)return;this.#Q({sidecar:{...Q,loading:!1}})}catch(Q){if(this.#A.sidecar?.nodeId!==A)return;this.#Q({sidecar:{nodeId:A,loading:!1,error:Q.message,tags:[],comments:[]}})}}async loadBacklinks(A){if(!A)return this.#Q({backlinks:null});this.#Q({backlinks:{nodeId:A,items:[],loading:!0,error:null}});try{let Q=await this.api.backlinks(A);if(this.#A.backlinks?.nodeId!==A)return;this.#Q({backlinks:{nodeId:A,items:Q.items||[],loading:!1,error:null}})}catch(Q){if(this.#A.backlinks?.nodeId!==A)return;this.#Q({backlinks:{nodeId:A,items:[],loading:!1,error:Q.message}})}}async#B(){if(this.#A.sidecar?.nodeId)await this.loadSidecar(this.#A.sidecar.nodeId)}setReplyTo(A){this.#Q({replyTo:A})}async comment(A){let Q=this.#A.sidecar?.nodeId;if(!Q||!A.trim())return;let B=this.#A.replyTo?.id||null;if(this.offline&&!this.offline.get().online){await this.offline.queueOp({method:"POST",path:`/api/items/${encodeURIComponent(Q)}/comments`,body:{body:A,parentId:B}}),this.#Q({replyTo:null}),this.platform.notifications.info("Offline — your comment will post when you reconnect.");return}this.#Q({posting:!0});try{await this.api.addComment(Q,{body:A,parentId:B}),this.#Q({replyTo:null}),await this.#B()}catch(C){this.platform.notifications.error(`Couldn't post comment: ${C.message}`)}finally{this.#Q({posting:!1})}}async deleteComment(A){let Q=this.#A.sidecar?.nodeId;await this.api.deleteComment(Q,A).catch((B)=>this.platform.notifications.error(B.message)),await this.#B()}async react(A,Q){let B=this.#A.sidecar?.nodeId,J=!(JL(this.#A.sidecar?.comments||[],A)?.reactions?.[Q]||[]).includes(this.#A.me?.id);try{await this.api.reactComment(B,A,Q,J)}catch(K){this.platform.notifications.error(`Couldn't react: ${K.message}`)}await this.#B()}async addTag(A,Q){let B=this.#A.sidecar?.nodeId;if(!A.trim())return;if(this.offline&&!this.offline.get().online){await this.offline.queueOp({method:"POST",path:`/api/items/${encodeURIComponent(B)}/tags`,body:{name:A.trim(),value:Q}}),this.platform.notifications.info("Offline — tag will sync when you reconnect.");return}await this.api.setTag(B,A.trim(),Q).catch((C)=>this.platform.notifications.error(C.message)),await this.#B()}async removeTag(A){let Q=this.#A.sidecar?.nodeId;if(this.offline&&!this.offline.get().online){await this.offline.queueOp({method:"DELETE",path:`/api/items/${encodeURIComponent(Q)}/tags/${encodeURIComponent(A)}`}),this.platform.notifications.info("Offline — tag removal will sync when you reconnect.");return}try{await this.api.removeTag(Q,A)}catch(B){this.platform.notifications.error(`Couldn't remove tag: ${B.message}`)}await this.#B()}async#C(){if(!this.#A.pushSupported)return;try{let Q=await(await navigator.serviceWorker.getRegistration())?.pushManager?.getSubscription();this.#Q({pushEnabled:!!Q})}catch{}}async enablePush(){if(!this.#A.pushSupported){this.platform.notifications.warn("Push notifications are not supported in this browser.");return}try{let{publicKey:A}=await this.api.vapidKey();if(!A){this.platform.notifications.warn("This server has no VAPID key configured for web push.");return}let Q=await navigator.serviceWorker.register("/sw.js");if(await navigator.serviceWorker.ready,await Notification.requestPermission()!=="granted")return this.platform.notifications.info("Notifications permission was denied.");let C=await Q.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:_$(A)});await this.api.subscribePush(C.toJSON()),this.#Q({pushEnabled:!0}),this.platform.notifications.success("Notifications enabled — you’ll be pinged when someone @mentions you.")}catch(A){this.platform.notifications.error(`Couldn't enable notifications: ${A.message}`)}}}function JL(A,Q){for(let B of A){if(B.id===Q)return B;let C=JL(B.replies||[],Q);if(C)return C}return null}function _$(A){let Q="=".repeat((4-A.length%4)%4),B=(A+Q).replace(/-/g,"+").replace(/_/g,"/"),C=atob(B),J=new Uint8Array(C.length);for(let K=0;K<C.length;K++)J[K]=C.charCodeAt(K);return J}class uK{get dimensions(){return 0}async embed(A){throw q.unsupported("embed not implemented")}async embedOne(A){return(await this.embed([A]))[0]}}var w$=new Set("a an the of to in on for and or is are be as at by with from this that it".split(" "));function T$(A){return String(A).toLowerCase().replace(/[^a-z0-9\s]/g," ").split(/\s+/).filter((Q)=>Q.length>1&&!w$.has(Q))}function x$(A){let Q=2166136261;for(let B=0;B<A.length;B++)Q^=A.charCodeAt(B),Q=Math.imul(Q,16777619);return Q>>>0}class mK extends uK{constructor({dimensions:A=256}={}){super();this._dim=A}get dimensions(){return this._dim}async embed(A){return A.map((Q)=>this.#A(Q))}#A(A){let Q=new Float64Array(this._dim),B=T$(A),C=[...B];for(let K=0;K<B.length-1;K++)C.push(B[K]+"_"+B[K+1]);for(let K of C){let E=x$(K),Y=E%this._dim,L=E>>31&1?-1:1;Q[Y]+=L}let J=0;for(let K=0;K<Q.length;K++)J+=Q[K]*Q[K];return J=Math.sqrt(J)||1,Array.from(Q,(K)=>K/J)}}class k$ extends uK{constructor(A){super();if(!A?.url||!A?.dimensions)throw q.invalid("HttpEmbedding requires url and dimensions");this.cfg=A}get dimensions(){return this.cfg.dimensions}async embed(A){let Q=this.cfg.batchSize??64,B=[];for(let C=0;C<A.length;C+=Q){let J=A.slice(C,C+Q);B.push(...await this.#A(J))}return B}async#A(A){return IB(async()=>{let Q;try{Q=await fetch(this.cfg.url,{method:"POST",headers:{"content-type":"application/json",...this.cfg.apiKey?{authorization:`Bearer ${this.cfg.apiKey}`}:{}},body:JSON.stringify({model:this.cfg.model,input:A})})}catch(J){throw fB(J)}if(Q.status===429||Q.status>=500)throw q.transient(`Embedding endpoint ${Q.status}`);if(!Q.ok)throw q.internal(`Embedding endpoint failed: ${Q.status}`);let B=await Q.json();return(B.data??B.embeddings??[]).map((J)=>J.embedding??J)})}}function KL(A,Q,B){let C=[],J=0;while(J<A.length){let K=Math.min(J+Q,A.length);if(K<A.length){let E=A.slice(J,K),Y=Math.max(E.lastIndexOf(`
|
|
500
|
+
|
|
501
|
+
`),E.lastIndexOf(". "),E.lastIndexOf(`
|
|
502
|
+
`));if(Y>Q*0.75)K=J+Y+1}if(C.push(A.slice(J,K).trim()),K>=A.length)break;J=K-B}return C.filter(Boolean)}var g$=new Set("a an the of to in on for and or is are be as at by with from this that it".split(" "));function pK(A){return String(A).toLowerCase().replace(/[^a-z0-9\s]/g," ").split(/\s+/).filter((Q)=>Q.length>1&&!g$.has(Q))}var y$="trove-offline",EL="trove-files-v1",lK=new mK({dimensions:256});class aK{#A;constructor(A){this.platform=A,this.api=A.api,this.db=null,this.#A={online:navigator.onLine,pins:[],queued:0,syncing:!1},this.cell=c(this.#A)}get(){return this.#A}observe(){return this.cell}#Q(A){this.#A={...this.#A,...A},this.cell.setValue(this.#A)}async init(){if(this.db=await h$(),await this.#J(),await this.#K(),window.addEventListener("online",()=>this.#B()),window.addEventListener("offline",()=>this.#C()),this.#A.online&&!await this.api.reachable())this.#Q({online:!1});if(this.platform.plugins?.setOnline?.(this.#A.online),this.#A.online)this.flushQueue()}async#B(){if(!await this.api.reachable()){this.#Q({online:!1}),await this.platform.plugins?.setOnline?.(!1);return}this.#Q({online:!0}),await this.platform.plugins?.setOnline?.(!0),await this.flushQueue()}async#C(){this.#Q({online:!1}),await this.platform.plugins?.setOnline?.(!1)}async pin(A){if(!A?.id)return;try{if("caches"in window){let J=await caches.open(EL),K=this.platform.mediaUrls,E=K.cacheKey(A.id),{url:Y}=await K.url(A.id,{op:"download"}),L=await fetch(Y);if(!L.ok)throw Error(`Couldn't fetch the file (${L.status})`);await J.put(new Request(E),L)}let Q=[],B="";if(AY(A))try{B=await this.api.readText(A.id);let J=KL(B,1000,150),K=await lK.embed(J.length?J:[A.name]);Q=(J.length?J:[A.name]).map((E,Y)=>({text:E,vector:K[Y]}))}catch{}let C=(await lK.embed([A.name]))[0];await v$(this.db,"pins",A.id,{node:A,text:B,chunks:Q,nameVec:C,pinnedAt:Date.now()}),await this.#J(),this.platform.notifications.success(`“${A.name}” is available offline`)}catch(Q){this.platform.notifications.error(`Couldn't make available offline: ${Q.message}`)}}async unpin(A){if(this.#A.pins.find((B)=>B.id===A)&&"caches"in window)await(await caches.open(EL)).delete(this.platform.mediaUrls.cacheKey(A),{ignoreVary:!0}).catch(()=>{});await cK(this.db,"pins",A),await this.#J()}async#J(){let A=await dK(this.db,"pins");this.#Q({pins:A.map((Q)=>({id:Q.node.id,name:Q.node.name,contentType:Q.node.contentType,collectionId:Q.node.collectionId,pinnedAt:Q.pinnedAt}))})}async searchOffline(A,{limit:Q=40}={}){let B=await dK(this.db,"pins");if(!B.length)return[];let C=pK(A),J=(await lK.embed([A]))[0],K=[];for(let E of B){let Y=pK(`${E.node.name} ${E.text||""}`),L=m$(C,new Set(Y)),X=YL(J,E.nameVec);for(let G of E.chunks||[])X=Math.max(X,YL(J,G.vector));let H=0.6*X+0.4*L;if(H>0.02)K.push({nodeId:E.node.id,node:E.node,score:H,snippet:p$(E.text,C),indexerId:"offline"})}return K.sort((E,Y)=>Y.score-E.score).slice(0,Q)}async queueOp(A){await f$(this.db,"queue",{...A,at:Date.now()}),await this.#K()}async#K(){let A=await dK(this.db,"queue");this.#Q({queued:A.length})}async flushQueue(){if(!this.#A.online||this.#A.syncing)return;this.#Q({syncing:!0});let A=0,Q=0;try{let B=await u$(this.db,"queue");for(let{key:C,value:J}of B)try{await this.api.request(J.method,J.path,{body:J.body}),await cK(this.db,"queue",C),A++}catch(K){if(["transient","timeout","unauthorized","quota"].includes(K.code))break;await cK(this.db,"queue",C),Q++}}finally{if(await this.#K(),this.#Q({syncing:!1}),Q)this.platform.notifications.warn(`${Q} offline change${Q>1?"s":""} couldn't be applied and ${Q>1?"were":"was"} discarded.`);if(A&&this.#A.queued===0)this.platform.notifications.info(`${A} offline change${A>1?"s":""} synced.`)}}}function h$(){return new Promise((A,Q)=>{let B=indexedDB.open(y$,1);B.onupgradeneeded=()=>{let C=B.result;if(!C.objectStoreNames.contains("pins"))C.createObjectStore("pins");if(!C.objectStoreNames.contains("queue"))C.createObjectStore("queue",{autoIncrement:!0})},B.onsuccess=()=>A(B.result),B.onerror=()=>Q(B.error)})}function DC(A,Q,B,C){return new Promise((J,K)=>{let E=A.transaction(Q,B),Y=E.objectStore(Q),L;Promise.resolve(C(Y)).then((X)=>L=X),E.oncomplete=()=>J(L),E.onerror=()=>K(E.error)})}var b$=(A)=>new Promise((Q,B)=>{A.onsuccess=()=>Q(A.result),A.onerror=()=>B(A.error)}),v$=(A,Q,B,C)=>DC(A,Q,"readwrite",(J)=>J.put(C,B)),f$=(A,Q,B)=>DC(A,Q,"readwrite",(C)=>C.add(B)),cK=(A,Q,B)=>DC(A,Q,"readwrite",(C)=>C.delete(B)),dK=(A,Q)=>DC(A,Q,"readonly",(B)=>b$(B.getAll()));function u$(A,Q){return DC(A,Q,"readonly",(B)=>new Promise((C,J)=>{let K=[],E=B.openCursor();E.onsuccess=()=>{let Y=E.result;if(!Y)return C(K);K.push({key:Y.key,value:Y.value}),Y.continue()},E.onerror=()=>J(E.error)}))}function m$(A,Q){if(!A.length||!Q.size)return 0;let B=0;for(let C of A)if(Q.has(C))B++;return B/A.length}function YL(A,Q){if(!A||!Q)return 0;let B=0;for(let C=0;C<A.length;C++)B+=A[C]*Q[C];return B}function p$(A,Q){if(!A)return null;let B=A.toLowerCase(),C=-1;for(let K of Q){let E=B.indexOf(K);if(E>=0){C=E;break}}if(C<0)return A.slice(0,160).trim();let J=Math.max(0,C-60);return(J>0?"…":"")+A.slice(J,J+200).trim()+"…"}var l$=1000,c$=60000;class nK{#A;constructor(A){this.platform=A,this.api=A.api,this.#A={tasks:[],issues:[],issuesLoading:!1,tasksError:null,issuesError:null},this.cell=c(this.#A),this._local=new Map,this._server=[],this._timer=null,this._pollMs=null}get(){return this.#A}observe(){return this.cell}#Q(A){this.#A={...this.#A,...A},this.cell.setValue(this.#A)}#B(){this.#Q({tasks:[...this._local.values(),...this._server]})}start(A={}){let Q=A.id||`local_${Math.random().toString(36).slice(2,10)}`,B={id:Q,source:"local",kind:A.kind||"general",title:A.title||"Working",detail:A.detail??null,status:"running",done:0,total:A.total??null,unit:A.unit||null,cancellable:!!A.onCancel,startedAt:Date.now(),endedAt:null,error:null};if(this._local.set(Q,B),this._cancels||=new Map,A.onCancel)this._cancels.set(Q,A.onCancel);this.#B(),this.#J();let C=(J)=>{let K=this._local.get(Q);if(!K||K.status!=="running")return;this._local.set(Q,{...K,...J}),this.#B()};return{id:Q,progress:(J={})=>C({done:J.done??this._local.get(Q)?.done??0,total:J.total===void 0?this._local.get(Q)?.total:J.total,unit:J.unit??this._local.get(Q)?.unit,detail:J.detail??this._local.get(Q)?.detail}),succeed:(J)=>{C({status:"done",endedAt:Date.now(),detail:J??this._local.get(Q)?.detail}),this.#C(Q)},fail:(J)=>{C({status:"failed",endedAt:Date.now(),error:J?.message||String(J||"failed")})},cancel:()=>{C({status:"cancelled",endedAt:Date.now()}),this.#C(Q)}}}#C(A,Q=5000){setTimeout(()=>{this._local.delete(A),this._cancels?.delete(A),this.#B()},Q)}async cancel(A){if(this._local.get(A)){this._cancels?.get(A)?.();return}try{await this.api.cancelTask(A),await this.refreshTasks()}catch(B){this.#Q({tasksError:B.message})}}dismiss(A){if(this._local.delete(A)){this.#B();return}this.api.dismissTask(A).catch(()=>{}),this._server=this._server.filter((Q)=>Q.id!==A),this.#B()}async init(){await this.refresh(),this.#J(),window.addEventListener("focus",()=>this.refresh())}async refresh(){await Promise.all([this.refreshTasks(),this.refreshIssues()])}async refreshTasks(){let A=this.running.length>0;try{let{tasks:Q}=await this.api.tasks();this._server=(Q||[]).map((B)=>({...B,source:"server"})),this.#Q({tasksError:null}),this.#B()}catch(Q){this._server=[],this.#Q({tasksError:Q.message}),this.#B()}if(A&&!this.running.length)this.refreshIssues();this.#J()}async refreshIssues(){this.#Q({issuesLoading:!0});try{let{issues:A}=await this.api.issues();this.#Q({issues:A||[],issuesLoading:!1,issuesError:null})}catch(A){this.#Q({issuesLoading:!1,issuesError:A.message})}}async retryIssue(A){try{await this.api.retryIssue(A),await this.refreshTasks(),this.followUp(),this.platform.notifications.info("Retrying — watch its progress in Activity")}catch(Q){this.platform.notifications.error(`Couldn't retry: ${Q.message}`)}}async dismissIssue(A){let Q=this.#A.issues;this.#Q({issues:Q.filter((B)=>B.id!==A)});try{await this.api.dismissIssue(A)}catch(B){this.#Q({issues:Q}),this.platform.notifications.error(`Couldn't dismiss: ${B.message}`)}}followUp(){for(let A of[400,1500])setTimeout(()=>{this.refreshTasks(),this.refreshIssues()},A)?.unref?.()}get running(){return this.#A.tasks.filter((A)=>A.status==="running")}#J(){let A=this.running.length?l$:c$;if(this._timer&&this._pollMs===A)return;clearTimeout(this._timer),this._pollMs=A,this._timer=setTimeout(()=>{this._timer=null,this.refreshTasks().then(()=>{if(!this.running.length)this.refreshIssues()})},A),this._timer?.unref?.()}dispose(){clearTimeout(this._timer),this._timer=null}}var PB="explorer.hasSelection || editor.open";function LL(A){let Q=(B,C,J,K={})=>A.platform.commands.register({id:B,title:C,actions:J,...K});Q("workbench.showCommandPalette","Show All Commands",()=>new J0("commands"),{category:"View",icon:"command"}),Q("workbench.quickOpen","Go to File…",()=>new J0("files"),{category:"File",icon:"search"}),Q("workbench.view.home","Go Home (search & browse)",()=>new vQ,{category:"View",icon:"search"}),Q("workbench.view.plugins","Show Plugins",()=>new GC("plugins"),{category:"View"}),Q("workbench.view.admin","Show Administration",()=>new GC("admin"),{category:"View",icon:"gear"}),Q("workbench.openSettings","Open Settings",()=>new GC("settings"),{category:"Preferences",icon:"gear"}),Q("workbench.closeOverlays","Close",()=>new eJ,{palette:!1}),Q("search.voice","Search by Voice",()=>new AK,{category:"View",icon:"search"}),Q("workbench.showActivity","Show Activity (running work & problems)",()=>new SA(!0),{category:"View",icon:"refresh"}),Q("workbench.rebuildIndex","Rebuild Search Index",()=>new QK,{category:"View",icon:"refresh"}),Q("workbench.scanCollection","Scan Collection for Outside Changes",()=>new BK,{category:"Explorer",icon:"refresh"}),Q("workbench.checkStorage","Check Storage Configuration",()=>new CK,{category:"View",icon:"plug"}),Q("explorer.refresh","Refresh",()=>new rB,{category:"Explorer",icon:"refresh"}),Q("explorer.loadMore","Show More Items",()=>new MJ,{palette:!1}),Q("explorer.upload","Upload Files…",()=>new JK,{category:"Explorer",icon:"upload"}),Q("explorer.copyShareLink","Copy Shareable Link",(B)=>new K0("share",B),{category:"Explorer",icon:"link",when:PB}),Q("explorer.copyLink","Copy Link to Item",(B)=>new K0("trove",B),{category:"Explorer",icon:"link",when:PB}),Q("explorer.rename","Rename",(B)=>new KK(B),{category:"Explorer",when:PB}),Q("explorer.delete","Delete",()=>new EK,{category:"Explorer",icon:"trash",when:PB}),Q("explorer.open","Open",(B)=>new LK(B),{palette:!1}),Q("explorer.download","Download",(B)=>new XK(B),{category:"Explorer",icon:"download",when:PB}),Q("explorer.showTrash","Show Trash",()=>new YK,{category:"Explorer",icon:"trash"}),Q("explorer.hideTrash","Hide Trash",()=>new eQ("hide"),{palette:!1}),Q("explorer.restore","Restore from Trash",(B)=>B?new eQ("restore",B):null,{palette:!1}),Q("explorer.purgeOne","Delete Forever",(B)=>B?new eQ("purge",B):null,{palette:!1}),Q("explorer.emptyTrash","Empty Trash",()=>new sA({kind:"confirm",title:"Empty the trash?",body:"Everything in the trash will be destroyed. This cannot be undone.",danger:!0,confirmLabel:"Delete forever",confirmActions:[new eQ("empty")]}),{category:"Explorer",icon:"trash"}),Q("keys.load","Load API Keys",()=>new eB,{palette:!1}),Q("keys.new","New API Key",()=>new HK,{palette:!1}),Q("keys.cancel","Cancel API Key",()=>new GK,{palette:!1}),Q("keys.dismissMinted","Dismiss API Key",()=>new $K,{palette:!1}),Q("keys.revoke","Revoke API Key",(B)=>B?new zJ(B):null,{palette:!1}),Q("keys.mint","Create API Key",()=>new DK,{palette:!1}),Q("offline.pin","Make Available Offline",(B)=>new E0(B,!0),{category:"Offline",icon:"download",when:PB}),Q("offline.unpin","Remove from Offline",(B)=>new E0(B,!1),{palette:!1}),Q("collections.switch","Switch Collection…",(B)=>new ZK(B),{category:"Collections",icon:"files"}),Q("collections.create","New Collection…",()=>new sA({kind:"collection",title:"New collection"}),{category:"Collections",icon:"files"}),Q("workbench.toggleInfoPanel","Toggle Details & Conversation",()=>new WK,{category:"View",icon:"info"}),Q("notifications.show","Show Notifications",()=>new zQ(!0),{category:"View"}),Q("notifications.enablePush","Enable Push Notifications",()=>new YC,{category:"Notifications"}),Q("plugins.installFromUrl","Install Plugin from URL…",()=>new sA({kind:"prompt",title:"Install plugin from URL",label:"Plugin package (.zip) URL",placeholder:"https://example.com/plugin.zip",confirmLabel:"Fetch",confirmActions:[new iJ]}),{category:"Plugins",icon:"plug"}),Q("plugins.installFromFile","Install Plugin from File…",()=>new UK,{category:"Plugins",icon:"plug"})}function XL(A){let Q=FY(A.settings),B=RY(),C=MY(),J=PY(),K=NY(),E=new nK(A),Y=VY(),L=qY(),X=zY(),H=new vK,G=new WJ(E),D=new aK(A),U=new fK(A,D),F={platform:A,explorer:Q,search:B,transfers:G,social:U,offline:D,activity:E,apiKeys:C,rotation:J,workbench:L,overlay:X,navigation:H,engine:null},R=new nC({providers:{appState:l.fromSingleton(new Map),explorer:l.fromSingleton(Q),search:l.fromSingleton(B),transfers:l.fromSingleton(G),social:l.fromSingleton(U),offline:l.fromSingleton(D),activity:l.fromSingleton(E),apiKeys:l.fromSingleton(C),rotation:l.fromSingleton(J),acl:l.fromSingleton(K),viewState:l.fromSingleton(Y),engine:l.fromLazySingleton(async()=>R,()=>{}),workbench:l.fromSingleton(L),overlay:l.fromSingleton(X),navigation:l.fromSingleton(H),settings:l.fromSingleton(A.settings),notifications:l.fromSingleton(A.notifications),context:l.fromSingleton(A.context),commands:l.fromSingleton(A.commands),keybindings:l.fromSingleton(A.keybindings),contributions:l.fromSingleton(A.contributions),viewport:l.fromSingleton(A.viewport),voice:l.fromSingleton(A.voice),api:l.fromSingleton(A.api),capabilities:l.fromLazySingleton(async()=>{let V=c(null);return A.api.capabilities().then((w)=>V.setValue(w),()=>{}),V},()=>{}),plugins:l.fromSingleton(A.plugins)}});return F.engine=R,A.commands.dispatch=(V)=>R.dispatch(V),A.dispatch=(V)=>R.dispatch(V),LL(F),QL(A.context,{workbench:L,overlay:X,navigation:H,explorer:Q}),BL(A.context,A.viewport),U.init(),D.init(),E.init(),{engine:R,app:F}}var HL=new WeakMap;function s(A,Q){let B=HL.get(A);if(!B)B=new WeakMap,HL.set(A,B);let C=B.get(Q);if(!C)C=_C(A.query(Q),{initial:BQ}),B.set(Q,C);return C}function qA(A,Q,B,C){let J=Object.keys(Q),K=J.map((Y)=>s(A,Q[Y])),E=BA(K,(...Y)=>Object.fromEntries(J.map((L,X)=>[L,Y[X]])));return T.alias(()=>CQ(E,B,C))}var d$=new FinalizationRegistry(({table:A,key:Q})=>{if(A.get(Q)&&!A.get(Q).deref())A.delete(Q)});function sK(A,Q){let B=typeof A;if(A===null||B==="string"||B==="number"||B==="boolean")return;if(B!=="object")throw TypeError(`Query argument ${Q} is a ${B}, which cannot be part of a sharing key. Pass an id and let the query look the thing up, or give queryOf a key function.`);if(Array.isArray(A))return A.forEach((J,K)=>sK(J,`${Q}[${K}]`));let C=Object.getPrototypeOf(A);if(C===Object.prototype||C===null)return Object.entries(A).forEach(([J,K])=>sK(K,`${Q}.${J}`));throw TypeError(`Query argument ${Q} is a ${A.constructor?.name??"non-plain object"}, which cannot be part of a sharing key. Pass an id and let the query look the thing up, or give queryOf a key function.`)}function oK(A){if(A===null||typeof A!=="object")return JSON.stringify(A)??"null";if(Array.isArray(A))return`[${A.map(oK).join(",")}]`;return`{${Object.keys(A).sort().map((Q)=>`${JSON.stringify(Q)}:${oK(A[Q])}`).join(",")}}`}function a$(...A){return A.forEach((Q,B)=>sK(Q,`#${B}`)),A.map(oK).join("|")}function OB(A,Q=a$){let B=new Map;return function(...J){if(this!==void 0&&this!==A)throw TypeError(`${this?.name??"A subclass"}.of() would build a ${A.name}, because \`of\` captures the class it was declared on. Give ${this?.name??"the subclass"} its own \`static of = queryOf(...)\`, or call it on `+A.name+" directly.");let K=Q(...J),E=B.get(K)?.deref();if(E)return E;let Y=new A(...J);return B.set(K,new WeakRef(Y)),d$.register(Y,{table:B,key:K}),Y}}function n$(A,Q){if(!Q)return 1;let B=0,C=0;for(let K of Q){let E=A.indexOf(K,C);if(E<0)return 0;B+=E===C?3:1,C=E+1}let J=A.indexOf(Q);if(J>=0)B+=100-Math.min(50,J);return B}function iK(A,Q,B=60){let C=(Q||"").trim().toLowerCase(),J=A||[];if(!C)return J.slice(0,B);let K=[];for(let E of J){let Y=n$(`${E.category||""} ${E.title}`.toLowerCase(),C);if(Y>0)K.push([Y,E])}return K.sort((E,Y)=>Y[0]-E[0]||String(E[1].title).localeCompare(String(Y[1].title))).slice(0,B).map(([,E])=>E)}function GL({ex:A={},tr:Q={},act:B={},off:C={}}={}){let J=A.items||[],K=B.tasks||[];return{collectionId:A.collectionId??null,collectionLabel:s$(A),totalItems:A.stats?.items??J.length,totalKnown:A.stats?.items!=null,totalBytes:A.stats?.bytes??J.reduce((E,Y)=>E+(Y.size||0),0),shown:J.length,partial:!!A.nextCursor,usage:A.usage??null,usageLevel:o$(A.usage),uploading:(Q.items||[]).filter((E)=>E.status==="active"),running:K.filter((E)=>E.status==="running"),issues:B.issues||[],off:{online:!0,pins:[],queued:0,syncing:!1,...C}}}function s$(A){if(!A?.collectionId)return"no collection";return(A.collections||[]).find((B)=>B.id===A.collectionId)?.name||A.collectionId}function o$(A){if(!A?.total)return"";let Q=A.available/A.total;return Q<0.05?"critical":Q<0.1?"low":""}function $L(A){let Q=A||{};if(!Q.off?.online)return{kind:"offline",label:"Offline"};if(Q.issues?.length)return{kind:"issues",label:`${Q.issues.length} need${Q.issues.length===1?"s":""} attention`,count:Q.issues.length};if(Q.running?.length||Q.uploading?.length||Q.off?.syncing)return{kind:"working",label:"Working…",count:(Q.running?.length||0)+(Q.uploading?.length||0)};if(Q.usageLevel)return{kind:"lowSpace",label:"Low on space"};return{kind:"idle",label:"Status"}}function rK(A){let Q=A||"";return Q.startsWith("!")?"command":Q.includes("#")?"filter":"search"}function i$(A,{pinned:Q=!1,keys:B={}}={}){let C=(J)=>B[J]||void 0;return[{label:"Open",icon:"file-text",actions:[new N("explorer.open",A)]},{label:"Download",icon:"download",actions:[new N("explorer.download",A)]},{label:"Copy shareable link",icon:"link",actions:[new N("explorer.copyShareLink")]},{label:"Copy trove: link",icon:"link",kbd:C("explorer.copyLink"),actions:[new N("explorer.copyLink")]},{sep:!0},{label:"Rename…",actions:[new N("explorer.rename")]},Q?{label:"Remove from offline",icon:"close",actions:[new N("offline.unpin",A)]}:{label:"Make available offline",icon:"download",actions:[new N("offline.pin",A)]},{sep:!0},{label:"Move to trash",icon:"trash",danger:!0,kbd:C("explorer.delete"),actions:[new N("explorer.delete")]}]}function r$(A){return[{label:"Restore",icon:"refresh",actions:[new N("explorer.restore",A.id)]},{sep:!0},{label:"Delete forever",icon:"trash",danger:!0,actions:[new N("explorer.purgeOne",A.id)]}]}function t$(A,{modal:Q,pinnedIds:B,keys:C}){return{icon:MQ(A),title:A.name,detail:A.contentType||"",node:A,actions:[new aA(A,{reset:!!Q}),...Q?[new zB]:[]],menu:()=>i$(A,{pinned:B.has(A.id),keys:C})}}function DL(A,Q=!1){let{ex:B={},se:C={},nav:J={},query:K="",commandMatches:E=[],pinnedIds:Y=new Set,keys:L={}}=A,X=rK(K),H=(O)=>t$(O,{modal:Q,pinnedIds:Y,keys:L}),G=Q?[new zB]:[];if(X==="command")return[{id:"commands",title:"Commands",items:E.map((O)=>({icon:"command",title:O.title,detail:O.category,badge:"command",actions:[new N(O.id),...G]})),empty:"No matching commands."}];let{text:D,filters:U}=nB(K),F=(C.results||[]).map((O)=>O.node),R=C.error,V=(O)=>R?[{icon:"refresh",label:"Retry",title:"Retry",actions:O}]:[];if(U.length){let O=U.map(oC).join(" ")+(D.trim()?` · "${D.trim()}"`:"");return[{id:"filtered",title:C.loading?"Filtering…":R?"Filter failed":"Filtered",verbatim:C.loading||R?null:O,controls:V([new MB(U,D)]),items:F.map(H),empty:C.loading?"Filtering…":R?`Couldn’t filter: ${R}`:"No files match those filters."}]}if(D.trim())return[{id:"results",title:C.loading?"Searching…":R?"Search failed":"Results",controls:V([new VQ(K)]),items:F.map(H),empty:C.loading?"Searching…":R?`Couldn’t search: ${R}`:"No files match."}];let w=[],m=(J.recents||[]).map(H);if(m.length)w.push({id:"recent",title:"Recent",items:m});let b=(B.items||[]).length,z=B.stats?.items??null,p=z??b,k=z!=null?z.toLocaleString():`${b.toLocaleString()}+`,v=(B.items||[]).map(H);if(B.nextCursor)v.push({icon:"refresh",title:B.loadingMore?"Loading…":z!=null?`Show more (${(z-b).toLocaleString()} more)`:"Show more",detail:"or search to jump straight to something",actions:[new N("explorer.loadMore")]});if(B.trash)w.push({id:"trash",title:B.trash.length?`Trash · ${B.trash.length} item${B.trash.length===1?"":"s"}`:"Trash",controls:[...B.trash.length?[{icon:"trash",label:"Empty trash",title:"Destroy everything in the trash",actions:[new N("explorer.emptyTrash")]}]:[],{icon:"close",label:"Close",title:"Hide the trash",actions:[new N("explorer.hideTrash")]}],items:(B.trash||[]).map((O)=>({icon:"trash",title:O.name,detail:`deleted ${new Date(O.deletedAt).toLocaleString()} — restore`,actions:[new N("explorer.restore",O.id)],menu:()=>r$(O)})),empty:"The trash is empty."});return w.push({id:"all",title:B.nextCursor?`All items · showing ${b.toLocaleString()} of ${k}`:"All items",controls:Q?[]:[{icon:"upload",label:"Upload",title:"Upload files to this collection",actions:[new N("explorer.upload")]}],items:v,empty:B.loading?"Loading…":B.error?`Couldn’t load this collection: ${B.error}`:"Nothing here yet — upload a file to get started."}),w}function ZL({eligible:A=!1,caps:Q=null}={}){if(!A)return null;let B=Q?.searchPrompt;if(!B?.hint&&!B?.examples?.length)return null;return{hint:B.hint||null,examples:(B.examples||[]).map((C)=>{let{text:J,filters:K}=nB(C.query);return{query:C.query,label:C.label||null,actions:[new AB(C.query),K.length?new MB(K,J):new VQ(J)]}})}}var WL="explorer.view";function UL({views:A=[],saved:Q=null}={},B=[],C=null){if(!A.length)return null;let J=Q&&A.find((Y)=>Y.id===Q);if(J)return J;let K=C&&A.find((Y)=>Y.id===C);if(K)return K;let E=B.map((Y)=>Y.node).filter(Boolean);if(E.length>=3){let Y=(X)=>X.match&&Object.keys(X.match).length&&E.filter((H)=>e$(X,H)).length/E.length>0.6,L=A.find(Y);if(L)return L}return A[0]}function e$(A,Q){let B=Q.contentType||"",C=(Q.name||"").toLowerCase(),J=C.includes(".")?C.slice(C.lastIndexOf(".")):"";if((A.match.ext||[]).includes(J))return!0;return(A.match.mime||[]).some((K)=>K.endsWith("/*")?B.startsWith(K.slice(0,-1)):B===K)}class EA extends LQ{static deps=[];constructor(A,Q,B,{bootAction:C=null}={}){super();if(this.dep=A,this.cellOf=Q,this.project=B,C)this.bootAction=C}get deps(){return[this.dep,"appState"]}boot(A,{notify:Q}){let B=this.cellOf(A[this.dep]);if(!B){Q(null);return}let C=A[this.dep],J=()=>this.project?this.project(B.getValue(),C):B.getValue();Q(J()),H0(A,this,B.onDirty(()=>Q(J())))}kill(A){G0(A,this)}}function H0(A,Q,B){A.appState.set(Q,B)}function G0(A,Q){let B=A.appState?.get(Q);if(Array.isArray(B))B.forEach((C)=>C());else B?.();A.appState?.delete(Q)}var ZC=new EA("explorer",(A)=>A.observe(),(A)=>({...A,selectedNodes:iB(A),collectionMenu:tC(A,(Q)=>new N("collections.switch",Q),()=>new N("collections.create")),collectionAdmin:DY(A,{open:(Q)=>new N("collections.switch",Q),scan:()=>new N("workbench.scanCollection"),rotate:()=>new N("workbench.openSettings"),create:()=>new N("collections.create"),access:(Q)=>new SJ(Q)})})),tK=new EA("search",(A)=>A.observe()),eK=new EA("transfers",(A)=>A.observe()),$0=new EA("activity",(A)=>A.observe()),WC=new EA("social",(A)=>A.observe()),D0=new EA("offline",(A)=>A.observe(),(A)=>({...A,pinnedIds:new Set((A?.pins||[]).map((Q)=>Q.id))})),IL=(A)=>AE.of(A);class AE extends LQ{static deps=["rotation","appState","engine"];static of=OB(AE);constructor(A){super();this.collectionId=A,this.bootAction=new NB(A)}boot(A,{notify:Q}){let B=A.rotation.observe();Q(B.getValue());let C=B.onDirty(()=>Q(B.getValue())),J=setInterval(()=>{if(A.rotation.get().rotation?.status==="running")A.engine.dispatch(new NB(this.collectionId))},2500);H0(A,this,[C,()=>clearInterval(J)])}kill(A){G0(A,this)}}var FL=(A)=>QE.of(A);class QE extends LQ{static deps=["acl","appState"];static of=OB(QE);constructor(A){super();this.collectionId=A,this.bootAction=new Y0(A)}boot(A,{notify:Q}){let B=A.acl.observe();Q(B.getValue()),H0(A,this,B.onDirty(()=>Q(B.getValue())))}kill(A){G0(A,this)}}var RL=new EA("apiKeys",(A)=>A.observe(),(A)=>({...A,draftScopes:rC(A)}),{bootAction:new eB}),UC=new EA("workbench",(A)=>A.observe()),BE=new EA("navigation",(A)=>A.observe()),IC=new EA("overlay",(A)=>A.observe()),ML=new EA("notifications",(A)=>A.observe()),Z0=new EA("settings",(A)=>A.observe()),VL=new EA("settings",(A)=>A.observe(),(A,Q)=>Q.grouped()),zL=new EA("context",(A)=>A.observe()),qL=new EA("viewport",(A)=>A.observe()),NL=new EA("voice",(A)=>A.observe(),(A,Q)=>({...A,canListen:!!Q.canListen?.()})),FC=new EA("plugins",(A)=>A?.observe?.()),CE=new EA("viewState",(A)=>A.observe());class DQ extends LQ{static deps=[];constructor(A,Q,B){super();this.deps=[...A,"appState"],this.sources=Q,this.project=B}boot(A,{notify:Q}){let B=()=>Q(this.project(A));B(),H0(A,this,this.sources(A).filter(Boolean).map((C)=>C.onDirty(B)))}kill(A){G0(A,this)}}var fQ=["contributions","context","plugins","settings","commands","keybindings"],uQ=(A)=>[A.contributions.observe(),A.context.observe(),A.plugins?.observe?.(),A.settings.observe()];function PL(A){return A.commands.paletteCommands().map((Q)=>({id:Q.id,title:Q.title??Q.id,category:Q.category??null,icon:Q.icon??null,keybinding:A.keybindings.labelFor(Q.id),available:A.commands.isAvailable(Q)}))}var AD=[...fQ,"overlay","workbench"],QD=(A)=>[...uQ(A),A.workbench.observe(),A.overlay.observe()],OL=new DQ(AD,QD,(A)=>iK(PL(A),A.overlay.get().palette?.query||"")),jL=new DQ(fQ,uQ,(A)=>{return A.contributions.ofType("statusItem").filter((Q)=>Q.visible!==!1&&Q.html).filter((Q)=>!Q.when||A.context.evaluate(Q.when)).filter((Q)=>A.plugins?.isAvailable?.(Q)??!0).sort((Q,B)=>(Q.order??0)-(B.order??0)||String(Q.name).localeCompare(String(B.name))).map((Q)=>({id:Q.id,slot:Q.slot==="left"?"left":"right",html:Q.html,tooltip:Q.tooltip??null,command:Q.command??null}))}),SL=new DQ(fQ,uQ,(A)=>{let Q=A.keybindings.resolved(),B=A.keybindings.overrides(),C=new Map;for(let J of Q)C.set(J.key,(C.get(J.key)||0)+1);return Q.map((J)=>({bindingId:J.bindingId,command:J.command,title:A.contributions.get(J.command)?.title??J.command,key:J.key,label:b0(J.key),custom:!!B[J.bindingId],clash:C.get(J.key)>1}))}),JE=(A=!1)=>KE.of(!!A),BD=[...fQ,"explorer","search","workbench","navigation","offline","capabilities"];class KE extends DQ{static of=OB(KE);constructor(A){super(BD,(Q)=>[...uQ(Q),Q.explorer.observe(),Q.search.observe(),Q.workbench.observe(),Q.navigation.observe(),Q.offline.observe(),Q.capabilities],(Q)=>{let B=Q.workbench.get(),C=Q.offline.observe().getValue()||{},J={ex:Q.explorer.observe().getValue()||{},se:Q.search.observe().getValue()||{},nav:Q.navigation.observe().getValue()||{},query:B.launch.query||"",commandMatches:iK(PL(Q),(B.launch.query||"").slice(1)),pinnedIds:new Set((C.pins||[]).map((Y)=>Y.id)),keys:hL(Q)},K=DL(J,this.modal),E=rK(J.query);return{groups:K,mode:E,view:UL(xL(Q),K.flatMap((Y)=>Y.items),E==="search"?J.se.resolved?.view??null:null),help:ZL({eligible:E!=="command"&&!!J.se.ran&&!J.se.loading&&!J.se.error&&!(J.se.results||[]).length,caps:Q.capabilities.getValue()})}});this.modal=A}}var _L=new DQ(["explorer","transfers","activity","offline"],(A)=>[A.explorer.observe(),A.transfers.observe(),A.activity.observe(),A.offline.observe()],(A)=>{let Q=GL({ex:A.explorer.observe().getValue(),tr:A.transfers.observe().getValue(),act:A.activity.observe().getValue(),off:A.offline.observe().getValue()});return{...Q,condition:$L(Q)}}),wL=new DQ(fQ,uQ,(A)=>A.contributions.ofType("opener").filter((Q)=>!Q.when||A.context.evaluate(Q.when)).filter((Q)=>A.plugins?.isAvailable?.(Q)??!0).sort((Q,B)=>(B.priority??0)-(Q.priority??0)).map((Q)=>ZJ(Q,A.plugins))),TL=new DQ(fQ,uQ,xL);function xL(A){return{views:A.contributions.ofType("view").filter((Q)=>!Q.when||A.context.evaluate(Q.when)).sort((Q,B)=>(B.priority??0)-(Q.priority??0)).map((Q)=>({id:Q.id,title:Q.title??Q.name??Q.id,icon:Q.icon??null,match:Q.match??null,render:Q.render,move:Q.move})),saved:A.settings.get("explorer.view")||null}}var kL=new DQ(fQ,uQ,(A)=>{let Q=A.settings.get(RB)||{};return Object.entries(Q).map(([B,C])=>{let J=A.contributions.get(C);return{typeKey:B,openerId:C,openerTitle:J?.title||C,missing:!J}})}),gL=(A)=>EE.of(A);class EE extends EA{static of=OB(EE);constructor(A){super("social",(Q)=>Q.observe(),(Q)=>Q?.sidecar??null);this.nodeId=A,this.bootAction=new LC(A),this.killAction=new FK(A)}}class jB extends LQ{static deps=["api"];static of=OB(jB);constructor(A,Q,B){super();this.nodeId=A,this.maxBytes=Q,this.size=B}async boot({api:A},{notify:Q}){Q(await A.readTextCapped(this.nodeId,{maxBytes:this.maxBytes,size:this.size}))}kill(){}}var yL=new DQ(fQ,uQ,hL);function hL(A){return Object.fromEntries(A.keybindings.resolved().map((Q)=>[Q.command,A.keybindings.labelFor(Q.command)]).filter(([,Q])=>Q))}var RC=new EA("capabilities",(A)=>A);var{svg:JD,h:KD}=T,YE={link:[{d:"M10 13a5 5 0 0 0 7.07 0l3-3A5 5 0 0 0 13 3l-1.5 1.5"},{d:"M14 11a5 5 0 0 0-7.07 0l-3 3A5 5 0 0 0 11 21l1.5-1.5"}],file:[{d:"M6 3h8l5 5v13a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1z"},{d:"M14 3v5h5"}],"file-text":[{d:"M6 3h8l5 5v13a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1z"},{d:"M14 3v5h5M9 13h6M9 17h6M9 9h2"}],"file-image":[{d:"M6 3h8l5 5v13a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1z"},{d:"M14 3v5h5"},{d:"M8.5 15l2-2 3 3 2-1.5"},{d:"M10 12a1 1 0 1 0 0-.01"}],"file-audio":[{d:"M6 3h8l5 5v13a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1z"},{d:"M14 3v5h5M10 12v5M13 10v9"}],"file-video":[{d:"M6 3h8l5 5v13a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1z"},{d:"M14 3v5h5M10 12l4 2.5-4 2.5z"}],book:[{d:"M4 5a2 2 0 0 1 2-2h13v16H6a2 2 0 0 0-2 2z"},{d:"M4 19a2 2 0 0 1 2-2h13"}],search:[{d:"M11 4a7 7 0 1 0 0 14 7 7 0 0 0 0-14zM20 20l-3.5-3.5"}],mic:[{d:"M12 3a3 3 0 0 0-3 3v6a3 3 0 0 0 6 0V6a3 3 0 0 0-3-3z"},{d:"M5 11a7 7 0 0 0 14 0M12 18v3M9 21h6"}],command:[{d:"M8 6a2 2 0 1 0-2 2h12a2 2 0 1 0-2-2v12a2 2 0 1 0 2-2H6a2 2 0 1 0 2 2z"}],gear:[{d:"M12 9a3 3 0 1 0 0 6 3 3 0 0 0 0-6z"},{d:"M19 12a7 7 0 0 0-.1-1.2l2-1.6-2-3.4-2.4 1a7 7 0 0 0-2-1.2L14 2h-4l-.5 2.6a7 7 0 0 0-2 1.2l-2.4-1-2 3.4 2 1.6A7 7 0 0 0 5 12a7 7 0 0 0 .1 1.2l-2 1.6 2 3.4 2.4-1a7 7 0 0 0 2 1.2L10 22h4l.5-2.6a7 7 0 0 0 2-1.2l2.4 1 2-3.4-2-1.6A7 7 0 0 0 19 12z"}],upload:[{d:"M12 16V4M7 9l5-5 5 5M4 20h16"}],download:[{d:"M12 4v12M7 11l5 5 5-5M4 20h16"}],trash:[{d:"M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13M10 11v6M14 11v6"}],refresh:[{d:"M20 11a8 8 0 1 0-.5 4M20 5v6h-6"}],"chevron-right":[{d:"M9 6l6 6-6 6"}],"chevron-left":[{d:"M15 6l-6 6 6 6"}],"chevron-down":[{d:"M6 9l6 6 6-6"}],close:[{d:"M6 6l12 12M18 6L6 18"}],tag:[{d:"M4 4h6.5a1 1 0 0 1 .7.3l8.5 8.5a1 1 0 0 1 0 1.4l-5.5 5.5a1 1 0 0 1-1.4 0L4.3 11.2a1 1 0 0 1-.3-.7V4z"},{d:"M8 8a0.6 0.6 0 1 0 0-.01"}],play:[{d:"M8 5v14l11-7z",fill:"currentColor",stroke:"none"}],pause:[{d:"M8 5h3v14H8zM13 5h3v14h-3z",fill:"currentColor",stroke:"none"}],"skip-back":[{d:"M11 6v12L3 12zM13 6l8 6-8 6zM21 6v12",fill:"none"}],"skip-forward":[{d:"M13 6v12l8-6zM3 6l8 6-8 6zM3 6v12"}],"back-30":[{d:"M11 8a7 7 0 1 0 7 7"},{d:"M11 4l-3 4 4 1"}],"fwd-30":[{d:"M13 8a7 7 0 1 1-7 7"},{d:"M13 4l3 4-4 1"}],plug:[{d:"M9 3v6M15 3v6M6 9h12v3a6 6 0 0 1-12 0zM12 18v3"}],bell:[{d:"M18 8a6 6 0 1 0-12 0c0 7-3 9-3 9h18s-3-2-3-9z"},{d:"M13.73 21a2 2 0 0 1-3.46 0"}],files:[{d:"M4 4h9l3 3v3M8 8h8a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2v-9a2 2 0 0 1 2-2z"}],dots:[{d:"M5 12h.01M12 12h.01M19 12h.01"}],check:[{d:"M5 12l5 5L20 6"}],plus:[{d:"M12 5v14M5 12h14"}],"arrow-up":[{d:"M12 19V5M6 11l6-6 6 6"}],star:[{d:"M12 3l2.7 5.6 6.1.9-4.4 4.3 1 6.1L12 17l-5.4 2.9 1-6.1L3.2 9.5l6.1-.9z"}],info:[{d:"M12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18zM12 11v5M12 8h.01"}],warn:[{d:"M12 3l9 16H3zM12 10v4M12 17h.01"}],x:[{d:"M6 6l12 12M18 6L6 18"}],list:[{d:"M8 6h12M8 12h12M8 18h12M4 6h.01M4 12h.01M4 18h.01"}],grid:[{d:"M4 4h7v7H4zM13 4h7v7h-7zM4 13h7v7H4zM13 13h7v7h-7z"}]};function I(A,{size:Q=18,strokeWidth:B=1.6,className:C}={}){let J=Object.hasOwn(YE,A)?YE[A]:YE.file;return JD({$attrs:{viewBox:"0 0 24 24",width:Q,height:Q,fill:"none",stroke:"currentColor","stroke-width":B,"stroke-linecap":"round","stroke-linejoin":"round",...C?{class:C}:{}}},...J.map((K)=>KD("path",{$attrs:ED(K)})))}function ED(A){let Q={d:A.d};if(A.fill)Q.fill=A.fill;if(A.stroke)Q.stroke=A.stroke;return Q}function JA(A){if(A==null||Number.isNaN(A))return"—";let Q=["B","KB","MB","GB","TB"],B=0,C=A;while(C>=1024&&B<Q.length-1)C/=1024,B++;return`${C>=100||B===0?Math.round(C):C.toFixed(1)} ${Q[B]}`}function LE(A){if(!A)return"";let Q=Date.now()-A,B=86400000;if(Q<60000)return"just now";if(Q<3600000)return`${Math.floor(Q/60000)}m ago`;if(Q<B)return`${Math.floor(Q/3600000)}h ago`;if(Q<7*B)return`${Math.floor(Q/B)}d ago`;return new Date(A).toLocaleDateString(void 0,{month:"short",day:"numeric",year:Q>330*B?"numeric":void 0})}var YD=/@\[([^\]]+)\]\(([^)]+)\)|(?:^|\s)@([a-zA-Z0-9._@-]{2,})/g;function bL(A){let Q=A||"",B=[],C=new RegExp(YD.source,"g"),J=0,K;while(K=C.exec(Q)){let E=!!K[3],Y=K.index+(E&&K[0].startsWith(" ")?1:0);if(Y>J)B.push({type:"text",value:Q.slice(J,Y)});B.push({type:"mention",name:K[1]||K[3],id:K[2]||null}),J=C.lastIndex}if(J<Q.length)B.push({type:"text",value:Q.slice(J)});return B}var{div:h,span:GA,button:xA,textarea:LD,input:XD,p:x3}=T,HD=["\uD83D\uDC4D","❤️","\uD83C\uDF89","\uD83D\uDC40","\uD83D\uDE80"];function vL(A){let Q=A.so.me;if(!Q||Q.anonymous)return null;let B=(Q.name||Q.id||"?")[0].toUpperCase();return h({className:"principal",title:Q.email||Q.name||Q.id},Q.picture?T.img({src:Q.picture,alt:"",className:"avatar-img"}):GA({className:"avatar-txt"},B))}function fL(A,Q){let B=A.so.notifications;return h({className:"bell-wrap"},xA({className:"iconbtn bell",title:"Notifications"},I("bell",{size:19}),B.unread?GA({className:"bell-badge"},String(B.unread>9?"9+":B.unread)):null).on({click:()=>Q.engine.dispatch(new zQ)}),A.so.inboxOpen?GD(A,Q):null)}function GD(A,Q){let B=A.so.notifications.items;return h({},h({className:"scrim",$styling:{background:"transparent","z-index":"54"}}).on({click:()=>Q.engine.dispatch(new zQ(!1))}),h({className:"inbox"},h({className:"inbox-head"},GA("Notifications"),A.so.pushSupported&&!A.so.pushEnabled?xA({className:"link"},"Enable push").on({click:()=>Q.engine.dispatch(new YC)}):A.so.pushEnabled?GA({className:"muted"},I("check",{size:13})):null),B.length?h({className:"inbox-items"},...B.slice(0,30).map((C)=>$D(C,Q))):h({className:"inbox-empty"},I("info",{size:24}),GA("You’re all caught up."))))}function $D(A,Q){let B=A.items?.[0];return h({className:`inbox-item ${A.read?"":"unread"}`},h({className:"ii-title"},A.title),B?.excerpt?h({className:"ii-excerpt"},"“"+B.excerpt+"”"):null,h({className:"ii-time"},LE(A.createdAt))).on({click:()=>{if(B?.nodeId)Q.engine.dispatch(new sJ(B.nodeId));Q.engine.dispatch(new zQ(!1))}})}function uL(A,Q){let B=A.nav,C=B.activeFile?{id:B.activeTabId,node:B.activeFile}:null;return h({className:"infopanel"},h({className:"ip-head"},I("info",{size:15}),GA("Details"),xA({className:"iconbtn",title:"Close"},I("close",{size:14})).on({click:()=>Q.engine.dispatch(new BC(!1))})),!C?h({className:"ip-empty"},GA("Open a file to see its tags and conversation.")):Q.watch(s(Q.engine,gL(C.node.id)),(J)=>h({className:"ip-body"},DD(C.node,A,Q),ZD(C.node,A,Q),UD(J,Q),ID(A,J,Q))))}function DD(A,Q,B){let C=Q.off?.pinnedIds?.has(A.id)??!1;return h({className:"ip-file"},h({className:"ip-name"},A.name),h({className:"ip-path"},A.contentType||""),xA({className:`btn small ${C?"on":""}`,$styling:{"margin-top":"10px"}},I(C?"check":"download",{size:14}),C?"Available offline":"Make available offline").on({click:()=>C?B.engine.dispatch(new N("offline.unpin",A)):B.engine.dispatch(new N("offline.pin",A))}))}function ZD(A,Q,B){let C=Q.so.backlinks,J=A.collectionId?oB(A):null,K=C&&C.nodeId===A.id?C:null;return h({className:"ip-section"},h({className:"ip-label"},"Links"),J?xA({className:"ip-uri",title:"Copy this item’s link"},I("link",{size:12}),GA(J)).on({click:()=>WD(B,J)}):null,h({className:"ip-label",$styling:{"margin-top":"10px"}},"Linked from"),K?.loading?h({className:"ip-muted"},"Loading…"):K?.error?h({className:"ip-muted error"},`Couldn’t load links: ${K.error}`):K?.items?.length?h({className:"ip-backlinks"},...K.items.map((E)=>xA({className:"ip-backlink",title:E.name},I("file-text",{size:12}),GA(E.name)).on({click:()=>B.engine.dispatch(new aA(E))}))):h({className:"ip-muted"},"Nothing links here yet."))}function WD(A,Q){A.engine.dispatch(new tA(Q,`Copied ${Q}`))}function UD(A,Q){let B=A?.tags||[];return h({className:"ip-section"},h({className:"ip-label"},"Tags"),h({className:"tags"},...B.map((C)=>GA({className:"tag"},C.value?`${C.name}: ${C.value}`:C.name,xA({className:"tag-x"},I("close",{size:11})).on({click:()=>Q.engine.dispatch(new mJ(C.name))}))),XD({className:"tag-input",placeholder:"+ tag",value:""}).on({keydown:(C)=>{if(C.key==="Enter"&&C.target.value.trim()){let J=C.target.value.trim(),[K,...E]=J.split(":");Q.engine.dispatch(new uJ(K.trim(),E.join(":").trim()||void 0)),C.target.value=""}}})))}function ID(A,Q,B){if(Q?.loading)return h({className:"ip-section"},h({className:"spinner"}));let C=Q?.comments||[],J=Q?.error?h({className:"conv-empty"},GA(`Couldn't load the conversation: ${Q.error}`),xA({className:"btn",$styling:{"margin-top":"8px"}},"Retry").on({click:()=>B.engine.dispatch(new LC(Q.nodeId))})):C.length?h({className:"thread"},...C.map((K)=>mL(K,A,B,0))):h({className:"conv-empty"},"No comments yet. Start the discussion — use @ to mention someone.");return h({className:"ip-section conv"},h({className:"ip-label"},`Conversation${Q?.commentCount?` · ${Q.commentCount}`:""}`),J,Q?.error?null:FD(A,B))}function mL(A,Q,B,C){let J=Q.so.me,K=J&&A.author?.id===J.id;return h({className:"comment",$styling:C?{marginLeft:"18px"}:{}},h({className:"c-head"},GA({className:"c-avatar"},(A.author?.name||"?")[0].toUpperCase()),GA({className:"c-author"},A.author?.name||A.author?.id||"Someone"),GA({className:"c-time"},LE(A.createdAt),A.edited?" · edited":"")),A.deleted?h({className:"c-body deleted"},"comment deleted"):h({className:"c-body"},RD(A.body)),!A.deleted?h({className:"c-actions"},...HD.map((E)=>{let Y=A.reactions?.[E]||[];return xA({className:`react ${Y.includes(J?.id)?"on":""}`},E,Y.length?GA({className:"rc"},String(Y.length)):null).on({click:()=>B.engine.dispatch(new fJ(A.id,E))})}),xA({className:"c-link"},"Reply").on({click:()=>B.engine.dispatch(new B0({id:A.id,author:A.author}))}),K?xA({className:"c-link danger"},"Delete").on({click:()=>B.engine.dispatch(new vJ(A.id))}):null):null,(A.replies||[]).length?h({className:"replies"},...A.replies.map((E)=>mL(E,Q,B,C+1))):null).key(A.id)}function FD(A,Q){let B=A.so.me,C=A.so.replyTo;if(!B){if(!A.off?.online)return h({className:"conv-signin"},"You’re offline. Conversations come back when you reconnect.");return h({className:"conv-signin"},GA("You’re signed out, so you can read this conversation but not add to it."),xA({className:"c-link"},"Reload to sign in").on({click:()=>window.location.reload()}))}return h({className:"composer"},C?h({className:"replying"},`Replying to ${C.author?.name||"comment"}`,xA({className:"c-link"},"cancel").on({click:()=>Q.engine.dispatch(new B0(null))})):null,LD({className:"composer-input",placeholder:"Write a comment… @mention someone",rows:2,value:""}).on({keydown:(J)=>{if(J.key==="Enter"&&(J.metaKey||J.ctrlKey))Q.engine.dispatch(new Q0(J.target.value)),J.target.value=""}}),h({className:"composer-actions"},GA({className:"muted"},"⌘/Ctrl + Enter"),xA({className:"btn primary",disabled:A.so.posting},"Comment").on({click:(J)=>{let K=J.target.closest(".composer").querySelector(".composer-input");Q.engine.dispatch(new Q0(K.value)),K.value=""}})))}function RD(A){return bL(A).map((Q)=>Q.type==="mention"?GA({className:"mention"},`@${Q.name}`):Q.value)}var{div:pL,button:XE,span:MD,img:VD}=T,zD=[{id:"home",icon:"search",title:"Search & files",command:"workbench.view.home"},{id:"plugins",icon:"plug",title:"Plugins",command:"workbench.view.plugins"},{id:"admin",icon:"book",title:"Administration",command:"workbench.view.admin"}];function HE(A,Q){let B=A.wb.activity,C=A.plugins?.filter((J)=>J.status==="active").length||0;return pL({className:"activitybar"},XE({className:"brand-mark",title:"Trove — home"},VD({src:"/icon.svg",alt:"Trove"})).on({click:()=>Q.engine.dispatch(new N("workbench.view.home"))}),...zD.map((J)=>XE({className:`item ${B===J.id?"active":""}`,title:J.title},I(J.icon,{size:22}),J.id==="plugins"&&C?MD({className:"badge"},String(C)):null).on({click:()=>Q.engine.dispatch(new N(J.command))})),pL({className:"spacer"}),fL(A,Q),XE({className:`item ${B==="settings"?"active":""}`,title:"Settings"},I("gear",{size:21})).on({click:()=>Q.engine.dispatch(new N("workbench.openSettings"))}),vL(A))}var qD=new Set(["SPAN","B","STRONG","I","EM","CODE","SMALL","BR","S","U"]),ND=new Set(["class","title"]);function lL(A){let Q=document.createDocumentFragment();if(typeof A!=="string"||!A)return Q;let B=document.createElement("template");B.innerHTML=A.slice(0,4096);let C={nodes:200};for(let J of B.content.childNodes){let K=nL(J,C);if(K)Q.appendChild(K)}return Q}function cL(A){return(lL(A).textContent||"").trim()}function dL(A,Q){return[...lL(A).childNodes].map((B)=>aL(B,Q)).filter((B)=>B!=null)}function aL(A,Q){if(A.nodeType===Node.TEXT_NODE)return A.nodeValue;let B=Q[A.tagName.toLowerCase()];if(!B)return A.textContent;let C={};if(A.className)C.className=A.className;if(A.title)C.title=A.title;return B(C,...[...A.childNodes].map((J)=>aL(J,Q)).filter((J)=>J!=null))}function nL(A,Q){if(Q.nodes--<=0)return null;if(A.nodeType===Node.TEXT_NODE)return document.createTextNode(A.nodeValue);if(A.nodeType!==Node.ELEMENT_NODE)return null;if(!qD.has(A.tagName))return null;let B=document.createElement(A.tagName.toLowerCase());for(let C of A.attributes){let J=C.name.toLowerCase();if(!ND.has(J))continue;B.setAttribute(J,C.value.slice(0,200))}for(let C of A.childNodes){let J=nL(C,Q);if(J)B.appendChild(J)}return B}var{div:BB,button:CB,span:$A}=T;function sL(A,Q){let B=dL(A.html,T);if(!B.length)return null;let C=A.tooltip?cL(A.tooltip):"";return A.command?CB({className:"seg",title:C},...B).on({click:()=>Q.engine.dispatch(new N(A.command))}):$A({className:"seg",title:C},...B)}function PD(A,Q){let B=A.act||{tasks:[],issues:[]},C=B.tasks.filter((E)=>E.status==="running"),J=()=>Q.engine.dispatch(new SA(!0)),K=[];if(C.length){let E=C[0],L=E.total!=null&&E.total>0?Math.round((E.done||0)/E.total*100):null;K.push(CB({className:"seg sb-activity",title:C.map((X)=>X.title).join(`
|
|
503
|
+
`)},BB({className:"spinner",$styling:{width:"11px",height:"11px"}}),$A(C.length>1?`${C.length} running`:`${E.title}${L==null?"":` ${L}%`}`)).on({click:J}))}if(B.issues.length)K.push(CB({className:"seg sb-attention",title:B.issues.map((E)=>E.title).join(`
|
|
504
|
+
`)},I("info",{size:12}),$A(`${B.issues.length} need${B.issues.length===1?"s":""} attention`)).on({click:J}));return K}function GE({usage:A,usageLevel:Q=""}){if(!A?.total)return null;let B=Math.min(100,Math.round(A.used/A.total*100));return $A({className:`seg sb-usage ${Q}`,title:`${JA(A.used)} used of ${JA(A.total)} — ${JA(A.available)} free on this volume`},BB({className:"usage-bar"},BB({className:"usage-fill",$styling:{width:`${B}%`}})),$A(`${JA(A.available)} free`))}function $E(A,Q){let B=A.ex,C=B.items||[],J=A.facts,{totalItems:K,totalBytes:E}=J,Y=A.caps,L=J.uploading,X=A.statusItems||[],H=X.filter((U)=>U.slot==="left").map((U)=>sL(U,Q)),G=X.filter((U)=>U.slot!=="left").map((U)=>sL(U,Q)),D=J.off;return BB({className:"statusbar"},!D.online?$A({className:"seg offline-badge",title:"You are offline — pinned files and cached data are available"},I("info",{size:12}),$A("Offline")):D.syncing?$A({className:"seg",title:"Syncing offline changes"},BB({className:"spinner",$styling:{width:"11px",height:"11px"}}),$A("Syncing…")):null,D.queued?$A({className:"seg",title:"Changes waiting to sync"},`${D.queued} queued`):null,D.pins.length?CB({className:"seg",title:`${D.pins.length} file(s) available offline`},I("download",{size:12}),$A(`${D.pins.length} offline`),I("chevron-down",{size:11})).on({click:(U)=>{let F=D.pins.slice(0,12).flatMap((R)=>[{label:R.name,icon:"file-text",actions:[new N("explorer.open",R)]},{label:`Remove “${R.name}” from offline`,icon:"close",actions:[new N("offline.unpin",R)]},{sep:!0}]);if(D.pins.length>12)F.push({label:`…and ${D.pins.length-12} more`,actions:[]});Q.engine.dispatch(new $Q(F,{rect:U.currentTarget.getBoundingClientRect(),prefer:"up"}))}}):null,CB({className:"seg",title:"Switch collection"},I("files",{size:13}),$A(J.collectionLabel),(B.collections||[]).length>1||B.canCreateCollection?I("chevron-down",{size:11}):null).on({click:(U)=>{let F=B.collectionMenu||[];if(F.length>1||B.canCreateCollection)Q.engine.dispatch(new $Q(F,{rect:U.currentTarget.getBoundingClientRect(),prefer:"up"}));else Q.engine.dispatch(new N("workbench.view.home"))}}),L.length?CB({className:"seg",title:"Active uploads — click to cancel"},BB({className:"spinner",$styling:{width:"11px",height:"11px"}}),$A(`${L.length} uploading`)).on({click:(U)=>Q.engine.dispatch(new $Q(L.map((F)=>({label:`Cancel ${F.name} (${Math.round((F.ratio||0)*100)}%)`,icon:"close",danger:!0,actions:[new EC(F.id)]})),{x:U.clientX,y:U.clientY}))}):$A({className:"seg",title:B.nextCursor?`Showing ${C.length} of ${J.totalKnown?K:"more"}`:""},`${K.toLocaleString()}${J.totalKnown||!J.partial?"":"+"} item${K===1?"":"s"}`),...H,BB({className:"spacer"}),...PD(A,Q),...G,$A({className:"seg",title:J.totalKnown||!J.partial?"Total size of this collection":`Size of the ${J.shown.toLocaleString()} items loaded so far — this server doesn’t report a collection total`},`${JA(E)}${J.totalKnown||!J.partial?"":"+"}`),GE(J),Y?$A({className:"seg",title:"Storage backend capabilities"},I(Y.storage?.presignDownload?"download":"files",{size:12}),$A(Y.storage?.presignDownload?"S3 direct":"proxied")):null,Y?.features?.semanticSearch?CB({className:"seg",title:"Semantic search enabled"},I("star",{size:12}),$A("semantic")).on({click:()=>Q.engine.dispatch(new N("workbench.view.home"))}):null)}async function NA(A,Q){for(let B of Q?.actions||[])if((await lA(A.engine,B))?.type!=="complete")break}var{div:DE,span:oL,button:iL}=T;function W0(A,Q){let B=A.controls||[];return DE({className:"launch-h"},DE({className:"lh-title"},oL(A.title),A.verbatim?oL({className:"lh-verbatim"},A.verbatim):null),B.length?DE({className:"lh-actions"},...B.map((C)=>iL({className:"launch-up",title:C.title||C.label},C.icon?I(C.icon,{size:13}):null,C.label).on({click:()=>NA(Q,C)}))):null)}function U0(A,Q,B){if(!A.menu)return null;return iL({className:"launch-more",title:`Actions for ${A.title}`,$attrs:{"aria-label":`Actions for ${A.title}`}},I("dots",{size:14})).on({click:(C)=>{C.stopPropagation(),JB(C.currentTarget,A,Q,null,B)}})}function JB(A,Q,B,C,J){let K=A?.getBoundingClientRect?.(),E=C?.clientX??(K?K.right-8:0),Y=C?.clientY??(K?K.bottom:0),L=Q.menu();J?.(),B.engine.dispatch(new $Q(L,{x:E,y:Y}))}var{div:MC,span:ZE}=T;function I0({groups:A,index:Q,handlers:B,ui:C}){let J=-1;return MC({className:"launch-view view-list"},...A.map((K)=>MC({className:"launch-group"},W0(K,C),K.items.length?MC({className:"launch-list"},...K.items.map((E)=>{let Y=++J;return OD(E,Y===Q,{hover:()=>B.hover(Y),select:()=>B.select(Y)},C)})):MC({className:"launch-empty"},K.empty||"Nothing here."))))}function OD(A,Q,{hover:B,select:C},J){return MC({className:`launch-item ${Q?"active":""}`},I(A.icon,{size:15}),ZE({className:"name"},A.title),A.detail?ZE({className:"launch-detail"},A.detail):null,A.badge?ZE({className:"launch-kind"},A.badge):null,U0(A,J,C)).on({click:()=>NA(J,A),mouseenter:B,...A.menu?{contextmenu:(K)=>{K.preventDefault(),JB(K.currentTarget,A,J,K,C)}}:{}})}function SB(A,Q,B,{op:C="media",onError:J}={}){let K=B.platform.mediaUrls,E=null,Y=!1,L=!1,X=()=>{clearTimeout(E),E=null},H=(F)=>{if(X(),!Number.isFinite(F))return;let R=Math.max(1000,(F-Date.now())*0.8);E=setTimeout(()=>G({resume:!0}),Math.min(R,2147483647))};async function G({resume:F}){if(Y)return;let R=jD(A),V=R&&F?A.currentTime:0,w=R&&F?!A.paused&&!A.ended:!1,m;try{m=await K.url(Q.id,{op:C})}catch(b){if(!Y)J?.(b.message);return}if(Y)return;if(A.src=m.url,R){if(A.load(),V>0||w){let b=()=>{if(A.removeEventListener("loadedmetadata",b),V>0&&Number.isFinite(A.duration)&&A.duration>V)A.currentTime=V;if(w)A.play().catch(()=>{})};A.addEventListener("loadedmetadata",b)}}H(m.expiresAt)}let D=()=>{L=!1};A.addEventListener("load",D),A.addEventListener("loadeddata",D);let U=()=>{if(Y)return;if(L){J?.(null);return}L=!0,K.invalidate(Q.id,C),G({resume:!0})};return A.addEventListener("error",U),G({resume:!1}),()=>{Y=!0,X(),A.removeEventListener("error",U),A.removeEventListener("load",D),A.removeEventListener("loadeddata",D)}}function jD(A){return typeof A?.play==="function"&&typeof A?.load==="function"}var{div:KB,span:SD,img:_D}=T;function rL({groups:A,index:Q,handlers:B,ui:C}){let J=-1;return KB({className:"launch-view view-grid"},...A.map((K)=>KB({className:"launch-group"},W0(K,C),K.items.length?KB({className:"grid-list"},...K.items.map((E)=>{let Y=++J;return TD(E,Y===Q,{hover:()=>B.hover(Y),select:()=>B.select(Y)},C)})):KB({className:"launch-empty"},K.empty||"Nothing here."))))}function tL({key:A,textual:Q}){if(A==="ArrowLeft")return Q?null:-1;if(A==="ArrowRight")return Q?null:1;let B=wD();if(A==="ArrowUp")return-B;if(A==="ArrowDown")return B;return null}function wD(){let A=document.querySelectorAll(".grid-list .grid-tile");if(A.length<2)return 1;let Q=A[0].offsetTop,B=0;for(let C of A){if(C.offsetTop!==Q)break;B++}return B||1}function TD(A,Q,{hover:B,select:C},J){let K=A.node,E=(K?.contentType||"").startsWith("image/");return KB({className:`grid-tile ${Q?"active":""}`,title:A.detail?`${A.title} — ${A.detail}`:A.title},KB({className:"gt-media"},I(A.icon,{size:26}),E?_D({className:"gt-img",alt:"",loading:"lazy",decoding:"async"}).on({$attach:(Y)=>{Y._detachMedia=SB(Y,K,J,{onError:()=>{Y.style.display="none"}})},$detach:(Y)=>{Y._detachMedia?.(),Y._detachMedia=null}}).opaque():null,A.badge?SD({className:"gt-badge"},A.badge):null,U0(A,J,C)),KB({className:"gt-name"},A.title)).on({click:()=>NA(J,A),mouseenter:B,...A.menu?{contextmenu:(Y)=>{Y.preventDefault(),JB(Y.currentTarget,A,J,Y,C)}}:{}})}var{div:WE,button:xD,span:kD}=T,gD={"core.view.list":{title:"List",icon:"list",priority:50,render:I0},"core.view.grid":{title:"Grid",icon:"grid",priority:40,match:{mime:["image/*","video/*"]},render:rL,move:tL}};function eL(A){for(let[Q,B]of Object.entries(gD))A.contributions.register(Q,{type:"view",...B})}function AX(A,Q,B){let C=A?.views||[];if(C.length<2)return null;return WE({className:"view-switch"},...C.map((J)=>xD({className:`vs-btn ${J.id===Q?.id?"on":""}`,title:`${J.title} view`,"aria-pressed":J.id===Q?.id?"true":"false"},I(J.icon||"list",{size:14})).on({click:()=>B.engine.dispatch(new bQ(WL,J.id))})))}function QX(A,Q,B){try{let C=A?.move?.({key:Q,...B});return Number.isFinite(C)&&C!==0?C:null}catch{return null}}function BX(A,Q){try{if(typeof A?.render==="function")return A.render(Q)}catch(B){return console.error(`view "${A?.id}" failed`,B),WE({},WE({className:"view-error"},I("warn",{size:13}),kD(`The “${A?.title||A?.id}” view could not be drawn — showing the list instead.`)),I0(Q))}return I0(Q)}var{div:mQ,span:_B,input:yD,button:UE}=T,hD=new Set(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight"]);function bD(A,{compact:Q=!1,modal:B=!1}={}){let C=A?.searchPrompt,J=(Q?C?.short||C?.placeholder:C?.placeholder)||(Q?"Search files":"Search files · # filter by tag");return Q||B?J:`${J} · ! run a command`}var IE=new Map,JX=(A,Q,B)=>{clearTimeout(IE.get(A)),IE.set(A,setTimeout(Q,B))};function vD(A,Q,B){JX(Q,()=>A.engine.dispatch(new VQ(B)),240)}function CX(A,Q){clearTimeout(IE.get(Q)),A.engine.dispatch(new AB("")),A.engine.dispatch(new VQ(""))}function fD(A,Q,B,C){JX(Q,()=>A.engine.dispatch(new MB(B,C)),200)}function F0(A,Q,B={}){let C=!!B.modal,J=A.wb.launch.query,K=C?A.modalContent:A.content,{groups:E,mode:Y,view:L}=K,X=E.flatMap((z)=>z.items),H=X.length?Math.min(A.wb.launch.index,X.length-1):0,G=C?"modal":"home",D=(z)=>{let p=z.target.value;if(Q.engine.dispatch(new AB(p)),p.startsWith("!"))return;let{text:k,filters:v}=nB(p);if(v.length)fD(Q,G,v,k);else vD(Q,G,k)},U=(z)=>Q.engine.dispatch(new _J(z)),F=(z)=>Q.engine.dispatch(new cJ(z,X[z]?.node)),R=(z)=>Q.engine.dispatch(new lJ(z,X.map((p)=>p.node))),V=(z)=>{let p=hD.has(z.key)?QX(L,z.key,{index:H,count:X.length,textual:J.length>0}):null;if(p!==null)z.preventDefault(),R(p);else if(z.key==="ArrowDown")z.preventDefault(),R(1);else if(z.key==="ArrowUp")z.preventDefault(),R(-1);else if(z.key==="Enter")z.preventDefault(),NA(Q,X[H]);else if(z.key==="Escape"&&J)z.preventDefault(),CX(Q,G);else if(z.key==="ContextMenu"||z.shiftKey&&z.key==="F10"){let k=X[H];if(k?.menu)z.preventDefault(),JB(document.querySelector(".launch-item.active, .grid-tile.active"),k,Q)}},w=Y==="search"?A.se.resolved:null,m=w&&(w.source==="llm"||w.tagFilters&&w.tagFilters.length||(w.semanticText||"").trim()!==J.trim()),b=mQ({className:"launcher"},mQ({className:"launch-box"},I(Y==="command"?"command":Y==="filter"?"tag":"search",{size:18}),yD({className:"launch-input",value:J,autofocus:!0,spellcheck:!1,placeholder:bD(A.caps,{compact:A.vp?.mode==="phone",modal:C})}).on({input:D,keydown:V}),J?UE({className:"launch-clear",title:"Clear"},I("close",{size:14})).on({click:()=>CX(Q,G)}):null,A.voice?.canListen?UE({className:`launch-mic ${A.voice?.listening?"on":""}`,title:A.voice?.listening?"Stop listening":"Search by voice","aria-pressed":A.voice?.listening?"true":"false"},I("mic",{size:15})).on({click:()=>Q.engine.dispatch(new N("search.voice"))}):null,C?null:AX(A.views,L,Q)),m?uD(w):null,mQ({className:"launch-body"},BX(L,{groups:E,index:H,handlers:{hover:U,select:F},state:A,ui:Q}),mD(K.help,Q)));return C?b:mQ({className:"editor"},b)}function uD(A){return mQ({className:"launch-resolved"},_B({className:"rq-label"},A.source==="llm"?"Interpreted as":"Searching"),(A.semanticText||"").trim()?_B({className:"rq-text"},`“${A.semanticText.trim()}”`):null,...(A.tagFilters||[]).map((Q)=>_B({className:"rq-chip"},I("tag",{size:11}),oC(Q))))}function mD(A,Q){if(!A)return null;return mQ({className:"launch-help"},A.hint?mQ({className:"lh-hint"},I("info",{size:13}),_B(A.hint)):null,A.examples.length?mQ({className:"lh-examples"},...A.examples.map((B)=>UE({className:"lh-example",title:B.label||"Try this search"},_B({className:"lh-q"},B.query),B.label?_B({className:"lh-label"},B.label):null).on({click:()=>NA(Q,B)}))):null)}var{div:M,h2:pD,h3:pQ,p:ZQ,span:KA,select:lD,option:cD,input:wB,label:EX,button:kA,ul:x9,li:k9,code:dD}=T;function FE(A,Q,B){let C=A.settingsGroups||new Map;return M({className:"editor"},M({className:"stage"},M({className:"settings"},pD("Settings"),ZQ({className:"sub"},"Preferences are stored in this browser. Plugins contribute their own settings here too."),...C.map((J)=>aD(J,Q)),oD(Q,A.caps),CZ(A,Q),rD(A,Q),YZ(A.assoc,Q),B.keybindings())))}function aD(A,Q){return M({className:"group"},pQ(A.category),...A.items.map((B)=>nD(B,Q)))}function nD(A,Q){return M({className:"setting"},M({className:"info"},M({className:"t"},A.title||A.key),A.description?M({className:"d"},A.description):null),M({className:"control"},sD(A,Q)))}function sD(A,Q){let B=(C)=>Q.engine.dispatch(new bQ(A.key,C));if(A.type==="boolean")return EX({className:"switch"},wB({type:"checkbox",checked:!!A.value}).on({change:(C)=>B(C.target.checked)}),KA({className:"track"}));if(A.type==="enum")return lD({className:"input"},...A.enum.map((C,J)=>cD({value:C,selected:A.value===C},A.enumLabels&&A.enumLabels[J]||C))).on({change:(C)=>B(C.target.value)});if(A.type==="number"){let C=(J)=>{let K=Number(J.target.value);if(J.target.value===""||Number.isNaN(K)){J.target.value=A.value;return}if(A.minimum!=null)K=Math.max(A.minimum,K);if(A.maximum!=null)K=Math.min(A.maximum,K);J.target.value=K,B(K)};return wB({className:"input",type:"number",value:A.value,$attrs:{min:A.minimum??"",max:A.maximum??""}}).on({change:C})}return wB({className:"input",value:A.value??""}).on({change:(C)=>B(C.target.value)})}function oD(A,Q){if(!Q)return null;let B=Q.mcp,C=Q.auth||{authorizationServers:[],source:"none"};if(!B?.enabled)return M({className:"group"},pQ("AI agents (MCP)"),ZQ({className:"sub"},"MCP is switched off on this server. Set TROVE_MCP=on to enable it."));let J=(Y)=>()=>A.engine.dispatch(new tA(Y)),K=C.authorizationServers||[],E=C.source==="jwt-issuer"?"from TROVE_JWT_ISSUER":C.source==="configured"?"from TROVE_AUTH_SERVER":null;return M({className:"group"},pQ("AI agents (MCP)"),ZQ({className:"sub"},"Point an AI assistant at this drive. It signs in as you and sees exactly the collections you can see."),M({className:"setting"},M({className:"info"},M({className:"t"},"Server URL"),M({className:"d"},"Paste this into your assistant’s MCP settings.")),M({className:"control mcp-url"},KA({className:"mono"},B.endpoint),kA({className:"btn small",title:"Copy"},I("link",{size:13})).on({click:J(B.endpoint)}))),M({className:"setting"},M({className:"info"},M({className:"t"},"Sign-in required"),M({className:"d"},B.requiresAuth?"Agents must present a token, the same one this browser uses.":"This drive is open, so agents connect without a token — exactly like the web app does.")),M({className:"control"},KA({className:"mono"},B.requiresAuth?"Yes":"No"))),B.needsAuthorizationServer?M({className:"mcp-warn"},I("warn",{size:15}),KA("This drive requires a token but no authorization server is set, so an agent has nowhere to sign in. Set TROVE_AUTH_SERVER (or TROVE_JWT_ISSUER) to the issuer URL of your identity provider and restart.")):null,M({className:"setting"},M({className:"info"},M({className:"t"},"Authorization server"),M({className:"d"},"Where clients are sent to sign in — for the whole drive, not just for agents. "+"Set with TROVE_AUTH_SERVER; defaults to TROVE_JWT_ISSUER when that is set.")),M({className:"control"},K.length?KA({className:"mono"},K.join(", ")+(E?` (${E})`:"")):KA({className:"mono muted"},"not set"))),M({className:"setting"},M({className:"info"},M({className:"t"},"Discovery document"),M({className:"d"},"What a client reads to find out how to authenticate (RFC 9728).")),M({className:"control mcp-url"},KA({className:"mono small"},C.metadataUrl))))}var iD=[{id:"read",label:"Read",hint:"list and download"},{id:"write",label:"Write",hint:"upload and rename"},{id:"delete",label:"Delete",hint:"trash and purge"},{id:"admin",label:"Admin",hint:"includes all of the above"}],YX="*";function rD(A,Q){let B=A.keys||{};if(B.forbidden)return null;if(B.error)return M({className:"group"},pQ("API keys"),ZQ({className:"sub"},`Couldn’t load the key list: ${B.error}`),M({className:"keys-actions"},kA({className:"btn"},"Try again").on({click:()=>Q.engine.dispatch(new N("keys.load"))})));if(!B.loaded)return null;let C=A.ex?.collections||[];return M({className:"group"},pQ("API keys"),ZQ({className:"sub"},"Give a script or a service access without giving it an account. A key carries capabilities and no identity, so anything it does is attributed to the key rather "+"than to a person — and it can only reach the collections you scope it to."),B.minted?tD(B.minted,Q):null,B.draft?eD(B,C,Q):null,!B.draft&&!B.minted?M({className:"keys-actions"},kA({className:"btn"},I("plus",{size:14}),"New key").on({click:()=>Q.engine.dispatch(new N("keys.new"))})):null,B.keys?.length?M({className:"keys-list"},...B.keys.map((J)=>AZ(J,B,C,Q))):M({className:"keys-empty"},"No keys yet."))}function tD(A,Q){let B=()=>Q.engine.dispatch(new tA(A.secret,"Key copied"));return M({className:"key-minted"},M({className:"key-minted-head"},I("warn",{size:15}),KA(`“${A.key.name}” is ready — copy it now.`)),ZQ({className:"key-minted-note"},"This is the only time it can be shown. It is stored as a hash, so it cannot be "+"recovered — if it is lost, revoke the key and make another."),M({className:"key-secret"},dD({className:"mono"},A.secret),kA({className:"btn small",title:"Copy"},I("link",{size:13})).on({click:B})),M({className:"keys-actions"},kA({className:"btn"},"Done").on({click:()=>Q.engine.dispatch(new N("keys.dismissMinted"))})))}function eD(A,Q,B){let{draft:C,draftScopes:J}=A,K=!!C.name.trim()&&!!J;return M({className:"key-form"},M({className:"setting"},M({className:"info"},M({className:"t"},"Name"),M({className:"d"},"What it is for. This is what the list shows, so make it recognisable.")),M({className:"control"},wB({className:"input",value:C.name,$attrs:{placeholder:"CI uploader"}}).on({input:(E)=>B.engine.dispatch(new C0({name:E.target.value}))}))),M({className:"setting"},M({className:"info"},M({className:"t"},"Expires after"),M({className:"d"},"Days from now. Leave blank and it never expires.")),M({className:"control"},wB({className:"input",type:"number",value:C.expiresInDays,$attrs:{min:"1",max:"3650",placeholder:"never"}}).on({input:(E)=>B.engine.dispatch(new C0({expiresInDays:E.target.value}))}))),M({className:"key-scopes"},M({className:"key-scopes-head"},M({className:"t"},"What it may do"),M({className:"d"},"Per collection. A key with nothing ticked grants nothing and cannot be created.")),KX({id:YX,name:"All collections",wildcard:!0},C,B),...Q.map((E)=>KX(E,C,B))),M({className:"keys-actions"},kA({className:"btn primary",$attrs:K?{}:{disabled:"true"}},A.busy==="mint"?"Creating…":"Create key").on({click:()=>K&&B.engine.dispatch(new N("keys.mint"))}),kA({className:"btn"},"Cancel").on({click:()=>B.engine.dispatch(new N("keys.cancel"))})))}function KX(A,Q,B){let C=new Set(Q.caps[A.id]||[]);return M({className:`key-scope ${A.wildcard?"wildcard":""}`},M({className:"key-scope-name"},I(A.wildcard?"grid":"files",{size:14}),KA(A.name||A.id)),M({className:"key-scope-caps"},...iD.map((J)=>EX({className:`cap ${C.has(J.id)?"on":""}`,title:J.hint},wB({type:"checkbox",checked:C.has(J.id)}).on({change:()=>B.engine.dispatch(new pJ(A.id,J.id))}),KA(J.label)))))}function AZ(A,Q,B,C){let J=!!A.revokedAt,K=A.expiresAt!=null&&A.expiresAt<=Date.now(),E=J||K;return M({className:`key-row ${E?"dead":""}`},M({className:"key-row-main"},M({className:"key-row-name"},KA({className:"t"},A.name),J?KA({className:"key-tag"},"revoked"):K?KA({className:"key-tag"},"expired"):null),M({className:"key-row-scopes"},...QZ(A,B)),M({className:"key-row-meta"},BZ(A))),!E?kA({className:"btn small danger",$attrs:Q.busy===A.id?{disabled:"true"}:{}},Q.busy===A.id?"…":"Revoke").on({click:()=>C.engine.dispatch(new N("keys.revoke",A.id))}):null)}function QZ(A,Q){let B=(C)=>Q.find((J)=>J.id===C)?.name||C;return(A.scopes||[]).map((C)=>KA({className:"key-chip"},KA({className:"where"},C.collectionId===YX?"all collections":B(C.collectionId)),KA({className:"what"},C.capabilities.join(" · "))))}function BZ(A){let Q=(C)=>new Date(C).toLocaleDateString(void 0,{year:"numeric",month:"short",day:"numeric"}),B=[`created ${Q(A.createdAt)}`];if(A.createdBy)B.push(`by ${A.createdBy}`);if(B.push(A.lastUsedAt?`last used ${Q(A.lastUsedAt)}`:"never used"),A.expiresAt)B.push(`expires ${Q(A.expiresAt)}`);return B.join(" · ")}function CZ(A,Q){let B=A.ex?.collectionId,C=A.ex?.collections?.find((J)=>J.id===B)?.encryption;if(!C?.enabled)return null;return Q.watch(s(Q.engine,IL(B)),(J)=>JZ(C,J||{},Q))}function JZ(A,Q,B){let C=Q.rotation?.status==="running",J=Q.estimate;return M({className:"group"},pQ("Encryption"),ZQ({className:"sub"},"Files in this collection are sealed before they leave your browser. The drive holds the key."),M({className:"setting"},M({className:"info"},M({className:"t"},"Key fingerprint"),M({className:"d"},"Identifies the key this collection is on.")),M({className:"control"},kA({className:"btn small",title:"Copy"},T.h("code",A.fingerprint)).on({click:()=>B.engine.dispatch(new tA(A.fingerprint,"Fingerprint copied"))}))),M({className:"setting"},M({className:"info"},M({className:"t"},C?"Rotating the key":"Rotate the key"),M({className:"d"},C?`${Q.rotation.moved} moved${Q.rotation.failed?`, ${Q.rotation.failed} failed`:""} — this continues in the background.`:KZ(J))),M({className:"control"},C?kA({className:"btn small",disabled:!!Q.busy},"Stop").on({click:()=>B.engine.dispatch(new VK)}):kA({className:"btn small",disabled:!!Q.busy},"Rotate").on({click:()=>B.engine.dispatch(new MK)}))),C?null:M({},EZ(J),ZQ({className:"sub"},"Every file is re-sealed under a new key and the old one is retired once nothing is left on it. Files stay readable throughout.")))}function KZ(A){if(!A)return"Re-seals every file under a fresh key.";return A.summary||"Re-seals every file under a fresh key."}function EZ(A){if(!A?.applicable||!(A.lines||[]).length)return null;return M({className:"rot-bill"},...A.lines.map((Q)=>M({className:"rb-line"},KA(Q.label||Q.name||""),KA({className:"mono"},Q.amount||Q.value||""))),A.total?M({className:"rb-line total"},KA("Estimated total"),KA({className:"mono"},A.total)):null,A.asOf?M({className:"rb-asof"},`Prices as of ${A.asOf}.`):null)}function YZ(A,Q){return M({className:"group"},pQ("Default Openers"),A.length?M({},...A.map((B)=>M({className:"setting"},M({className:"info"},M({className:"t"},B.typeKey),M({className:"d"},B.missing?`${B.openerTitle} (no longer installed)`:`Opens with ${B.openerTitle}`)),M({className:"control"},kA({className:"iconbtn",title:"Forget this default"},I("close",{size:14})).on({click:()=>Q.engine.dispatch(new XC(B.typeKey,null))}))))):ZQ({className:"sub",$styling:{margin:0}},"No default openers set yet. When a file type has more than one viewer, you can pick one and check “Always use this”."))}var RE="keybindingCapture";function LX(A,Q,B){let C=(E)=>Q.engine.dispatch(new QB(RE,E)),J=()=>C(null),K=(E,Y)=>Q.engine.dispatch(new qJ(E,Y));return M({className:"group"},pQ("Keyboard Shortcuts"),ZQ({className:"sub"},"Click a shortcut to record a new one. Esc cancels; Backspace clears it."),...A.map((E)=>{let Y=B===E.bindingId;return M({className:"setting"},M({className:"info"},M({className:"t"},E.title),M({className:"d"},E.command)),M({className:"control"},E.clash&&!Y?KA({className:"kbd-clash",title:"Another command answers to this shortcut too — the one registered last wins"},I("warn",{size:12})):null,kA({className:`kbd-edit ${Y?"listening":""} ${E.clash?"clash":""}`,title:Y?"Press the new shortcut":"Click to rebind"},Y?KA("Press keys…"):T.h("kbd",E.label)).on({click:()=>C(Y?null:E.bindingId),blur:()=>{if(Y)J()},keydown:(L)=>{if(!Y)return;if(L.preventDefault(),L.stopPropagation(),L.key==="Escape")return J();if(L.key==="Backspace")return K(E.bindingId,null),J();if(["Control","Meta","Alt","Shift"].includes(L.key))return;K(E.bindingId,h0(L)),J()},$attach:(L)=>{if(Y)queueMicrotask(()=>L.focus())}}),E.custom?kA({className:"c-link",title:"Back to the default"},"reset").on({click:()=>{K(E.bindingId,null),C(null)}}):null))}))}var{div:eA,h2:XX,p:HX,button:VE,span:ME}=T;function zE(A,Q){let B=A.ex||{};return eA({className:"editor"},eA({className:"stage"},eA({className:"gate"},B.gate==="create"?LZ(Q):XZ(B,Q))))}function LZ(A){return eA({className:"gate-card"},eA({className:"gate-icon"},I("files",{size:26})),XX("Make your first collection"),HX({className:"gate-sub"},"A collection is a backing store you own — a bucket, a directory, a mount. Files "+"live in one, and permissions are granted on one. Nothing can be uploaded until there is somewhere to put it."),eA({className:"gate-actions"},VE({className:"btn primary"},I("plus",{size:14}),"New collection").on({click:()=>A.engine.dispatch(new N("collections.create"))})))}function XZ(A,Q){let B=A.collections||[];return eA({className:"gate-card"},eA({className:"gate-icon"},I("grid",{size:26})),XX(B.length===1?"Open your collection":"Choose a collection"),HX({className:"gate-sub"},B.length===1?"This is the one you have access to. Opening it will be remembered for next time.":"Files, search and uploads all belong to one collection. Your choice is remembered for next time, and you can switch from the status bar whenever you like."),eA({className:"gate-list"},...B.map((C)=>VE({className:"gate-choice"},eA({className:"gate-choice-main"},ME({className:"n"},C.name||C.id),ME({className:"d"},C.driver?`${C.driver}${C.description?` · ${C.description}`:""}`:C.description||"")),ME({className:"gate-caps"},(C.capabilities||[]).join(" · "))).on({click:()=>Q.engine.dispatch(new N("collections.switch",C.id))}))),A.canCreateCollection?eA({className:"gate-actions"},VE({className:"btn"},I("plus",{size:14}),"New collection").on({click:()=>Q.engine.dispatch(new N("collections.create"))})):null)}var{div:i,span:vA,p:HZ,button:VC,h2:GZ,input:qE,label:$Z}=T;function NE(A,Q){let B=A.plugins||[];return i({className:"editor"},i({className:"stage"},i({className:"plugins"},GZ("Plugins"),HZ({className:"sub",$styling:{color:"var(--text-dim)",margin:"0 0 8px"}},"Plugins are sandboxed packages you install from a file or URL. They run in an isolated iframe and reach Trove only through a message channel, using the capabilities you granted."),i({className:"plugin-install"},VC({className:"btn primary"},I("upload",{size:15}),"Install from file…").on({click:()=>Q.engine.dispatch(new N("plugins.installFromFile"))}),VC({className:"btn"},I("plug",{size:15}),"Install from URL…").on({click:()=>Q.engine.dispatch(new N("plugins.installFromUrl"))})),B.length?i({$styling:{display:"flex","flex-direction":"column",gap:"12px","margin-top":"14px"}},...B.map((C)=>DZ(C,A,Q))):i({className:"empty",$styling:{padding:"48px"}},I("plug",{size:30}),vA("No plugins installed yet.")))))}function DZ(A,Q,B){let C=!A.responsive?"not responding":A.manifest?.online===!1?"offline":"connected",J=A.features||[];return i({className:"plugin-card"},i({className:"top"},i({className:"avatar"},(A.name||"?")[0].toUpperCase()),i({$styling:{flex:"1"}},i({className:"name"},A.name,A.version?vA({$styling:{color:"var(--text-faint)","font-weight":"400","margin-left":"6px"}},"v"+A.version):null),i({$styling:{"font-size":"11px",color:"var(--text-faint)"}},A.id)),UZ(A.trust),vA({className:`status ${A.status}`},A.status)),A.error?i({className:"desc",$styling:{color:"var(--danger)"}},A.error):null,i({className:"caps"},...(A.capabilities||[]).map((K)=>vA({className:"cap"},K))),(A.endpoints||[]).length?i({className:"plugin-endpoints",$styling:{"font-size":"11px",color:"var(--text-faint)","margin-top":"2px"}},I("plug",{size:11})," Network: ",(A.endpoints||[]).map((K)=>K.host).join(", ")):null,A.status==="active"?i({className:"plugin-features"},i({className:"pf-head"},vA(`Features · ${C}`),vA({className:"muted"},`${J.filter((K)=>K.available).length}/${J.length} available`)),J.length?i({className:"pf-list"},...J.map(FZ)):i({className:"muted",$styling:{"font-size":"12px"}},A.responsive?"No contributions announced.":"No manifest received — the plugin may not be running.")):null,(A.settingsSchema||[]).length?ZZ(A,B,Q):null,i({className:"actions"},A.hasUi?VC({className:"btn"},I("command",{size:14}),"Open panel").on({click:()=>B.engine.dispatch(new CC(A.id))}):null,VC({className:"btn"},I("refresh",{size:14}),"Refresh").on({click:()=>B.engine.dispatch(new aJ(A.id))}),VC({className:"btn danger"},"Uninstall").on({click:()=>B.engine.dispatch(new sA({kind:"confirm",title:`Uninstall ${A.name}?`,danger:!0,confirmLabel:"Uninstall",body:"The plugin and all data it stored will be removed.",confirmActions:[new RJ(A.id)]}))})))}function ZZ(A,Q,B){return i({className:"plugin-features"},i({className:"pf-head"},vA("Settings")),i({$styling:{display:"flex","flex-direction":"column",gap:"8px"}},...A.settingsSchema.map((C)=>WZ(A,C,Q,B))))}function WZ(A,Q,B,C){let J=`${A.id}.${Q.key}`,K=Q.secret?"":C.settings?.[J]??Q.default??"";return i({className:"setting",$styling:{padding:"6px 0"}},i({className:"info"},i({className:"t"},Q.title||Q.key),Q.description?i({className:"d"},Q.description):null),i({className:"control"},Q.secret?qE({className:"input",type:"password",placeholder:"Set secret…"}).on({change:(E)=>{if(E.target.value)B.engine.dispatch(new nJ(A.id,Q.key,E.target.value)),E.target.value="",E.target.placeholder="Saved ✓"}}):Q.type==="boolean"?$Z({className:"switch"},qE({type:"checkbox",checked:!!K}).on({change:(E)=>B.engine.dispatch(new bQ(J,E.target.checked))}),vA({className:"track"})):qE({className:"input",value:K}).on({change:(E)=>B.engine.dispatch(new bQ(J,E.target.value))})))}function UZ(A){if(!A)return null;let Q=aB(A),B=Q.status==="verified"?Q.domain:Q.status==="invalid"?"invalid signature":Q.status;return vA({className:`trust ${Q.tone}`,title:Q.explanation},I(Q.icon,{size:12}),B)}var IZ={command:"command",opener:"file",indexer:"search",statusItem:"info"};function FZ(A){return i({className:`pf-row ${A.available?"":"off"}`},I(IZ[A.kind]||"command",{size:13}),vA({className:"pf-title"},A.title),vA({className:"pf-kind"},A.kind),A.offline?vA({className:"pf-badge offline-ok",title:"Works offline"},"offline ✓"):null,vA({className:`pf-dot ${A.available?"on":"no"}`,title:A.available?"Available now":"Unavailable now"}))}var{div:y,h2:RZ,h3:zC,p:TB,span:AQ,button:fA,select:MZ,option:PE,input:VZ}=T;function OE(A,Q){let B=A.caps;return y({className:"editor"},y({className:"stage"},y({className:"settings admin"},RZ("Administration"),TB({className:"sub"},"How this drive is configured, and what it can do. Most of it is decided by the deployment rather than here."),zZ(B,A,Q),qZ(A,Q),OZ(B,A,Q),jZ(B,A),SZ(A,Q))))}function PA(A,Q,B){return y({className:"setting"},y({className:"info"},y({className:"t"},A),Q?y({className:"d"},Q):null),y({className:"control"},typeof B==="string"?AQ({className:"mono"},B):B))}function zZ(A,Q,B){let C=A?.auth||{},J=A?.principal||Q.so?.me||{},K=C.authorizationServers||[];return y({className:"group"},zC("Access"),TB({className:"sub"},"Who can reach this drive. Set by the deployment, not here."),PA("Signed in as",J.anonymous?"This drive does not require a sign-in.":J.email||J.id,J.anonymous?"anonymous":J.name||J.id||"—"),PA("Sign-in required","Whether a caller must present a token.",A?.mcp?.requiresAuth?"Yes":"No"),PA("Authorization server","Where clients are sent to sign in.",K.length?K.join(", "):"not set"),PA("API keys","Credentials for scripts and services, scoped per collection.",fA({className:"btn small"},"In Settings").on({click:()=>B.engine.dispatch(new N("workbench.openSettings"))})))}function qZ(A,Q){let B=A.ex?.collectionAdmin,C=B?.rows||[],J=(K)=>()=>NA(Q,{actions:K});return y({className:"group"},zC("Collections"),TB({className:"sub"},"What exists on this drive, where its bytes live, and which key seals it."),...C.length?C.map((K)=>y({className:"setting stacked"},y({className:"info"},y({className:"t"},K.name,K.current?AQ({className:"mono muted"}," · open"):null),y({className:"d"},K.encrypted?`${K.driver} · sealed, key ${String(K.fingerprint).slice(0,12)}…`:`${K.driver} · not encrypted`),y({className:"d"},`You may: ${K.capabilities.join(", ")||"nothing"}`)),y({className:"control admin-actions"},K.current?null:fA({className:"btn small"},"Open").on({click:J(K.actions.open)}),fA({className:"btn small"},"Scan").on({click:J(K.actions.scan)}),K.actions.rotate?fA({className:"btn small"},"Rotate key…").on({click:J(K.actions.rotate)}):null,K.actions.access?fA({className:`btn small ${A.wb?.aclFor===K.id?"on":""}`},"Access…").on({click:J(K.actions.access)}):null),A.wb?.aclFor===K.id?Q.watch(s(Q.engine,FL(K.id)),(E)=>PZ(E,Q,K.id)):null)):[PA("Collections","Nothing has been created yet.","none")],B?.canCreate?y({className:"setting"},y({className:"info"},y({className:"t"},"New collection"),y({className:"d"},"A backing store you own — a bucket, a directory, a mount. Encryption is chosen here, at creation.")),y({className:"control"},fA({className:"btn small"},"Create…").on({click:J(B.create)}))):PA("New collection","You do not have permission to create one on this drive.","not allowed"))}var NZ=["read","write","delete","admin"];function PZ(A,Q,B){if(!A)return y({className:"acl"},AQ({className:"mono muted"},"Loading access…"));if(A.error)return y({className:"acl"},AQ({className:"mono muted"},A.error));let C=A.grants||[],J=(Y)=>Q.engine.dispatch(new RK(B,Y)),K=(Y)=>{let L=new Set(Y.capabilities||[]),X=Y.type==="anyone"?"Everyone":`${Y.type}: ${Y.subject}`;return y({className:"acl-row"},AQ({className:"acl-who"},X),...NZ.map((H)=>fA({className:`btn small ${L.has(H)?"on":""}`,title:H==="admin"?"admin implies every other capability":`toggle ${H}`},H).on({click:()=>J({type:Y.type,subject:Y.subject,capabilities:L.has(H)?(Y.capabilities||[]).filter((G)=>G!==H):[...Y.capabilities||[],H]})})),fA({className:"btn small",title:"remove this grant entirely"},"×").on({click:()=>J({type:Y.type,subject:Y.subject,capabilities:[]})}))},E=(A.admins||[]).map((Y)=>y({className:"acl-row acl-fixed"},AQ({className:"acl-who"},Y),AQ({className:"mono muted"},"admin · set by this deployment")));return y({className:"acl"},...E,...C.length?C.map(K):E.length?[]:[AQ({className:"mono muted"},"Nobody yet.")],y({className:"acl-row acl-add"},MZ({className:"acl-type"},PE({value:"user"},"user"),PE({value:"role"},"role"),PE({value:"anyone"},"anyone")),VZ({className:"acl-subject",placeholder:"email, or a role name"}),fA({className:"btn small"},"Grant read").on({click:(Y)=>{let L=Y.target.closest(".acl-add"),X=L.querySelector(".acl-type").value,H=L.querySelector(".acl-subject").value.trim();if(X!=="anyone"&&!H)return;J({type:X,subject:X==="anyone"?"":H,capabilities:["read"]})}})))}function OZ(A,Q,B){let C=A?.storage||{},J=A?.storageDrivers||[],K=Q.ex?.usage,E=(Y)=>AQ({className:`mono ${Y?"":"muted"}`},Y?"yes":"no");return y({className:"group"},zC("Storage"),TB({className:"sub"},"The backing stores this deployment offers, and what they support."),PA("Drivers offered","What a new collection may be created on.",J.length?J.map((Y)=>Y.label||Y.key).join(", "):"none registered"),PA("Direct downloads","A presigned URL sends bytes from the store, not through the drive.",E(C.presignDownload)),PA("Direct uploads","A presigned PUT sends bytes to the store, not through the drive.",E(C.presignUpload)),PA("Multipart","Large files go up in parts, resumably.",E(C.multipart)),PA("Range requests","Seeking inside a file without fetching the whole thing.",E(C.range)),K?.total?PA("Space","Reported by the backing store.",`${JA(K.available)} free of ${JA(K.total)}`):PA("Space","This store does not report a total, which object stores generally cannot.","not reported"),y({className:"setting"},y({className:"info"},y({className:"t"},"Check the backing stores"),y({className:"d"},"Asks whether each store can actually be reached from here — the failure that makes every file open to a spinner.")),y({className:"control"},fA({className:"btn small"},"Run check").on({click:()=>B.engine.dispatch(new N("workbench.checkStorage"))}))))}function jZ(A,Q){let B=A?.indexers||[],C=Q.plugins||[];return y({className:"group"},zC("Extensions"),TB({className:"sub"},"What reads and adds to this drive."),y({className:"setting"},y({className:"info"},y({className:"t"},"Indexers"),y({className:"d"},"They read file contents to make them searchable — including in an encrypted collection, since indexing happens on the drive’s side of the encryption.")),y({className:"control"},AQ({className:"mono"},B.length?B.map((J)=>J.displayName||J.id).join(", "):"none"))),C.length?y({},...C.map((J)=>y({className:"setting"},y({className:"info"},y({className:"t"},J.manifest?.displayName||J.id),y({className:"d"},(J.grants||[]).length?`May: ${(J.grants||[]).join(", ")}`:"Granted nothing — it runs in its sandbox and can only draw.")),y({className:"control"},AQ({className:`mono ${J.status==="active"?"":"muted"}`},J.status||"idle"))))):PA("Plugins","Installed by an administrator, from a signed package.","none installed"))}function SZ(A,Q){let B=A.act||{tasks:[],issues:[]},C=(B.tasks||[]).filter((J)=>J.status==="running");return y({className:"group"},zC("Work"),TB({className:"sub"},"Background jobs and anything that needs attention."),PA("Running now","Scans, reindexes and rotations happening on the server.",C.length?`${C.length}`:"nothing running"),PA("Needs attention","Standing problems — they persist until fixed, unlike a toast.",B.issues?.length?`${B.issues.length}`:"none"),y({className:"setting stacked"},y({className:"info"},y({className:"t"},"Maintenance"),y({className:"d"},"A scan picks up files changed in the bucket by something other than Trove. A reindex rebuilds search from scratch.")),y({className:"control admin-actions"},fA({className:"btn small"},"Activity panel").on({click:()=>Q.engine.dispatch(new N("workbench.showActivity"))}),fA({className:"btn small"},"Scan").on({click:()=>Q.engine.dispatch(new N("workbench.scanCollection"))}),fA({className:"btn small"},"Reindex").on({click:()=>Q.engine.dispatch(new N("workbench.rebuildIndex"))}))))}class jE extends P{static deps=["api","engine","notifications"];constructor(A,Q=null){super();this.uri=A,this.from=Q}async execute({api:A,engine:Q,notifications:B}){let C=iC(this.uri);if(!C){B.warn(`"${this.uri}" isn’t a valid Trove link.`);return}try{let J=await A.stat(this.uri);if(!J?.node)throw Error("not found");await lA(Q,new aA(J.node))}catch(J){B.warn(_Z(C,J,this.from))}}}function _Z(A,Q,B){let C=B?.name?` (linked from "${B.name}")`:"";if(Q?.status===403||Q?.code==="forbidden")return`You don’t have access to that item in "${A.collection}"${C}.`;if(A.by==="name")return`Nothing named "${A.value}" in "${A.collection}"${C} — it may have been renamed or deleted.`;return`That item no longer exists in "${A.collection}"${C}.`}var{div:EB,span:_E,h1:wZ,h2:TZ,h3:xZ,p:UX,ul:kZ,ol:gZ,li:yZ,pre:hZ,code:IX,a:GX,em:bZ,strong:vZ,blockquote:fZ,hr:uZ,br:mZ}=T;function FX(A,Q){let B=SC(s(Q.engine,jB.of(A.id,SE,A.size)),(C)=>C.text);return T.alias(()=>Q.watch(B,(C)=>{try{return EB({className:"viewer markdown"},EB({className:"md"},...RX(C,A,Q)))}catch(J){return console.error("markdown render failed",J),$X(`This document couldn’t be displayed: ${J.message}`)}},{placeholder:()=>EB({className:"viewer"},EB({className:"loading"},EB({className:"spinner"}),_E("Loading…"))),error:(C)=>$X(C.message)}))()}function $X(A){return EB({className:"viewer"},EB({className:"fallback"},I("warn",{size:40}),_E(A)))}var SE=524288,pZ=5000,lZ=2000;function RX(A,Q,B){let C=String(A??""),J=C.length>SE,K=(J?C.slice(0,SE):C).split(/\r?\n/),E=[],Y=0;while(Y<K.length){if(E.length>=pZ)return[...E,DX()];let L=K[Y],X=/^\s*(```+|~~~+)(.*)$/.exec(L);if(X){let R=X[1][0].repeat(3),V=[];Y++;while(Y<K.length&&!K[Y].trimStart().startsWith(R))V.push(K[Y++]);Y++,E.push(hZ({className:"md-code"},IX(V.join(`
|
|
505
|
+
`))));continue}if(!L.trim()){Y++;continue}let H=/^(#{1,6})\s+(.*)$/.exec(L);if(H){let R=H[1].length,V=R===1?wZ:R===2?TZ:xZ;E.push(V({className:`md-h md-h${R}`},...qC(H[2],Q,B))),Y++;continue}if(/^\s*(-{3,}|\*{3,}|_{3,})\s*$/.test(L)){E.push(uZ({className:"md-hr"})),Y++;continue}if(/^\s*>/.test(L)){let R=[];while(Y<K.length&&/^\s*>/.test(K[Y]))R.push(K[Y++].replace(/^\s*>\s?/,""));E.push(fZ({className:"md-quote"},...RX(R.join(`
|
|
506
|
+
`),Q,B)));continue}let G=/^\s*([-*+]|\d+[.)])\s+/.exec(L);if(G){let R=/\d/.test(G[1]),V=[];while(Y<K.length){let w=/^\s*([-*+]|\d+[.)])\s+(.*)$/.exec(K[Y]);if(!w||/\d/.test(w[1])!==R)break;V.push(yZ({className:"md-li"},...qC(w[2],Q,B))),Y++}E.push((R?gZ:kZ)({className:"md-list"},...V));continue}let D=[];while(Y<K.length&&K[Y].trim()&&!cZ(K[Y]))D.push(K[Y++]);let U=D.join(`
|
|
507
|
+
`),F=[];U.split(`
|
|
508
|
+
`).forEach((R,V)=>{if(V)F.push(mZ());F.push(...qC(R,Q,B))}),E.push(UX({className:"md-p"},...F))}return J?[...E,DX()]:E}function DX(){return UX({className:"md-truncated"},"This document is too large to display in full. Download it to read the rest.")}function cZ(A){return/^(#{1,6}\s|\s*>|\s*([-*+]|\d+[.)])\s|\s*(```|~~~))/.test(A)||/^\s*(-{3,}|\*{3,}|_{3,})\s*$/.test(A)}var dZ=[{re:/`([^`]+)`/,node:(A)=>IX({className:"md-inline-code"},A[1])},{re:/\[([^\]]*)\]\(([^)\s]+)(?:\s+"[^"]*")?\)/,node:(A,Q,B)=>WX(A[2],A[1]||A[2],Q,B)},{re:/(\*\*|__)(.+?)\1/,node:(A,Q,B,C)=>vZ(...qC(A[2],Q,B,C+1))},{re:/(\*|_)(.+?)\1/,node:(A,Q,B,C)=>bZ(...qC(A[2],Q,B,C+1))},{re:/(trove:[^\s<>"'`)\]}]+|https?:\/\/[^\s<>"'`)\]}]+)/,node:(A,Q,B)=>WX(ZX(A[1]),ZX(A[1]),Q,B)}];function qC(A,Q,B,C=0){if(!A)return[];if(C>12)return[A];let J=[],K=A;while(K){if(J.length>=lZ){J.push(K);break}let E=null;for(let X of dZ){let H=X.re.exec(K);if(H&&(E===null||H.index<E.m.index))E={m:H,rule:X}}if(!E){J.push(K);break}let{m:Y,rule:L}=E;if(Y.index)J.push(K.slice(0,Y.index));J.push(L.node(Y,Q,B,C)),K=K.slice(Y.index+Y[0].length)}return J}function ZX(A){return A.replace(/[.,;:!?]+$/,"")}function WX(A,Q,B,C){if(iC(A))return GX({className:"md-link md-trove",href:"#",title:A},Q).on({click:(K)=>{K.preventDefault(),C.engine.dispatch(new jE(A,B))}});if(/^https?:\/\//i.test(A))return GX({className:"md-link",href:A,target:"_blank",rel:"noopener noreferrer",title:A},Q);return _E({className:"md-deadlink",title:`Unsupported link: ${A}`},Q)}var{div:DA,pre:aZ,img:nZ,span:qQ,button:sZ,video:oZ,audio:iZ}=T,rZ={"core.audio":{title:"Audio Player",priority:20,match:{mime:["audio/*"],ext:[".mp3",".flac",".wav",".opus",".ogg",".m4a",".m4b"]},component:B4},"core.video":{title:"Video Player",priority:20,match:{mime:["video/*"],ext:[".mp4",".webm",".mkv",".mov"]},component:C4},"core.image":{title:"Image Viewer",priority:20,match:{mime:["image/*"],ext:[".png",".jpg",".jpeg",".gif",".webp",".svg",".avif"]},component:Q4},"core.markdown":{title:"Markdown",priority:30,match:{ext:[".md",".markdown"],mime:["text/markdown"]},component:FX},"core.text":{title:"Text Viewer",priority:10,match:{mime:["text/*","application/json"],ext:[".txt",".md",".json",".js",".mjs",".ts",".jsx",".tsx",".css",".html",".xml",".yaml",".yml",".toml",".ini",".log",".csv",".py",".rb",".go",".rs",".sh",".c",".h",".cpp",".java"]},component:eZ}};function MX(A){for(let[Q,B]of Object.entries(rZ))A.contributions.register(Q,{type:"opener",...B})}function VX(A,Q,B){let C=B.platform.contributions.get(Q);if(C?.component)try{return C.component(A,B)}catch(J){return qX(J.message)}if(C?.pluginId)return J4(C,A,B);return zX(A,B)}var tZ=524288;function eZ(A,Q){let B=s(Q.engine,jB.of(A.id,tZ,A.size));return T.alias(()=>Q.watch(B,({text:C,truncated:J,total:K})=>DA({className:"viewer text"},aZ(C),J?DA({className:"md-truncated"},`Showing the first ${Math.round(C.length/1024)} KB${K?` of ${(K/1048576).toFixed(1)} MB`:""}. `,qQ("Download the file to read all of it.")):null),{placeholder:()=>DA({className:"viewer"},DA({className:"loading"},DA({className:"spinner"}),qQ("Loading…"))),error:(C)=>qX(C.message)}))()}var A4="This file couldn't be loaded — it may be missing or in an unsupported format.";function wE(A,Q,B){let C=c({error:null}),K=B((E)=>C.setValue({error:E||A4}));return T.alias(()=>CQ(C,(E)=>E.error?zX(A,Q,E.error):K))()}var TE=(A,Q,B,C)=>A.on({$attach:(J)=>{J._detachMedia=SB(J,Q,B,{onError:C})},$detach:(J)=>{J._detachMedia?.(),J._detachMedia=null}}).opaque();function Q4(A,Q){return wE(A,Q,(B)=>DA({className:"viewer image"},TE(nZ({alt:A.name}),A,Q,B)))}function B4(A,Q){return wE(A,Q,(B)=>DA({className:"viewer",$styling:{display:"grid","place-items":"center",gap:"16px",padding:"40px"}},I("file-audio",{size:48}),qQ({$styling:{color:"var(--text-dim)"}},A.name),TE(iZ({controls:!0,$styling:{width:"min(520px, 90%)"}}),A,Q,B)))}function C4(A,Q){return wE(A,Q,(B)=>DA({className:"viewer",$styling:{display:"grid","place-items":"center",background:"#000"}},TE(oZ({controls:!0,$styling:{"max-width":"100%","max-height":"100%"}}),A,Q,B)))}function zX(A,Q,B){return DA({className:"viewer"},DA({className:"fallback"},I(B?"warn":"file",{size:44}),qQ({$styling:{"font-weight":600}},A.name),qQ(`${A.contentType||"Unknown type"} · ${JA(A.size)}`),qQ({$styling:{color:"var(--text-faint)","max-width":"340px"}},B||"No preview available for this file type. Install a plugin that handles it, or download the file."),sZ({className:"btn primary"},I("download",{size:15}),"Download").on({click:()=>Q.engine.dispatch(new N("explorer.download",A))})))}function J4(A,Q,B){let C=c({ready:!1,error:null});return DA({className:"viewer plugin-viewer"},CQ(C,(J)=>{if(J.ready)return null;return DA({className:"pv-status"},J.error?DA({className:"fallback"},I("warn",{size:40}),qQ(J.error)):DA({className:"loading"},DA({className:"spinner"}),qQ("Opening…")))}),DA({className:"pv-host"}).on({$attach:(J)=>{J._detach=B.platform.plugins.mountViewer(A.pluginId,J,Q,A.id,{onReady:()=>C.setValue({ready:!0,error:null}),onError:(K)=>C.setValue({ready:!1,error:K||"This viewer failed to load"})})},$detach:(J)=>{J._detach?.(),J._detach=null}}).opaque())}function qX(A){return DA({className:"viewer"},DA({className:"fallback"},I("warn",{size:40}),qQ(A||"Failed to open")))}var{div:kB,span:NX,button:xB}=T,R0=new Map;function M0(A,Q){let B=A.wb,C=A.nav.stack.filter((K)=>K.kind==="file");L4(C);let J=C[C.length-1];if(!J)return kB({className:"editor"});return kB({className:"editor"},K4(C,J,A,Q),kB({className:"stage"},Y4(J,Q)))}function K4(A,Q,B,C){return kB({className:"viewer-nav"},xB({className:"vn-back",title:"Back (Esc)"},I("chevron-left",{size:16})).on({click:()=>C.engine.dispatch(new dJ)}),kB({className:"vn-trail"},xB({className:"vn-crumb"},I("search",{size:13}),NX("Search")).on({click:()=>C.engine.dispatch(new vQ)}),...A.map((J)=>xB({className:`vn-crumb ${J.id===Q.id?"active":""}`,title:J.node.name},I(MQ(J.node),{size:13}),NX({className:"label"},J.node.name)).on({click:()=>C.engine.dispatch(new HQ(J.node,J.openerId))}))),kB({className:"vn-actions"},E4(Q,B,C),xB({className:"iconbtn",title:"Details & comments"},I("info",{size:15})).on({click:()=>C.engine.dispatch(new BC)}),xB({className:"iconbtn",title:"Close (Esc)"},I("close",{size:15})).on({click:()=>C.engine.dispatch(new vQ)})))}function E4(A,Q,B){let C=QY(Q.openers,A.node);if(C.length<=1)return null;return xB({className:"iconbtn",title:"Open with…"},I("dots",{size:15})).on({click:()=>B.engine.dispatch(new sA({kind:"opener-chooser",node:A.node,openers:C,current:A.openerId}))})}function Y4(A,Q){let B=`${A.id}:${A.openerId}`,C=R0.get(B);if(!C)C=()=>VX(A.node,A.openerId,Q),R0.set(B,C);return T.alias(C)().key(A.id)}function L4(A){let Q=new Set(A.map((B)=>`${B.id}:${B.openerId}`));for(let B of R0.keys())if(!Q.has(B))R0.delete(B)}var{div:oA,input:X4,span:lQ}=T;function xE(A,Q){let B=A.overlay.palette;if(!B)return null;let C=B.mode==="files"?B.query.trim()?A.se.paletteFiles||[]:[]:A.matches||[],J=Math.min(B.index,Math.max(0,C.length-1)),K=(E)=>{if(!E)return;if(Q.engine.dispatch(new QC),B.mode==="files")Q.engine.dispatch(new aA(E.node));else Q.engine.dispatch(new N(E.id))};return oA({},oA({className:"scrim"}).on({click:()=>Q.engine.dispatch(new QC)}),oA({className:"palette"},oA({className:"search"},I(B.mode==="files"?"search":"command",{size:18}),X4({type:"text",value:B.query,autofocus:!0,placeholder:B.mode==="files"?"Search files by name…":"Type a command…"}).on({input:(E)=>Z4(Q,E.target.value),keydown:(E)=>D4(E,Q,C,J,K),$attach:(E)=>{if(queueMicrotask(()=>E.focus()),E.value!==B.query)E.value=B.query}})),oA({className:"results"},C.length?C.map((E,Y)=>{let L=()=>Q.engine.dispatch(new OJ(Y));return B.mode==="files"?$4(E,Y===J,K,L):G4(E,Y===J,Q,K,L)}):H4(B,A))))}function H4(A,Q){if(A.mode!=="files")return oA({className:"none"},"No matching commands");if(Q.se.paletteError)return oA({className:"none error"},I("warn",{size:14}),` ${Q.se.paletteError}`);if(Q.se.paletteLoading)return oA({className:"none"},oA({className:"spinner"})," Searching…");return oA({className:"none"},A.query.trim()?"No files found":"Type to search files by name")}function G4(A,Q,B,C,J){return oA({className:`opt ${Q?"active":""} ${A.available?"":"unavailable"}`},lQ({className:"ico"},I(A.icon||"command",{size:16})),A.category?lQ({className:"cat"},A.category+" ›"):null,lQ({className:"title"},A.title),!A.available?lQ({className:"offline-tag"},"offline"):null,A.keybinding?lQ({className:"kbd"},T.h("kbd",A.keybinding)):null).on({click:()=>C(A),mouseenter:J})}function $4(A,Q,B,C){return oA({className:`opt ${Q?"active":""}`},lQ({className:"ico"},I(MQ(A.node),{size:16})),lQ({className:"title"},A.node.name),lQ({className:"sub"},A.node.contentType||"")).on({click:()=>B(A),mouseenter:C})}function D4(A,Q,B,C,J){if(A.key==="ArrowDown")A.preventDefault(),Q.engine.dispatch(new eC(1,B.length));else if(A.key==="ArrowUp")A.preventDefault(),Q.engine.dispatch(new eC(-1,B.length));else if(A.key==="Enter")A.preventDefault(),J(B[C]);else if(A.key==="Escape")A.preventDefault(),Q.engine.dispatch(new QC)}var PX=null;function Z4(A,Q){A.engine.dispatch(new PJ(Q)),clearTimeout(PX),PX=setTimeout(()=>A.engine.dispatch(new VJ(Q)),200)}var{div:a,span:YA,button:OX,h3:y7,p:W4,label:SX,input:_X}=T;function wX(A,Q,B){let C=A.summary,J=sC(B,dB,A,{grants:C.capabilities.filter((X)=>!X.adminOnly||A.isAdmin).map((X)=>X.id),acknowledged:!1}),K=A.policy||{requiresAcknowledgement:!1},E=K.requiresAcknowledgement&&!J.acknowledged,Y=(X)=>Q.engine.dispatch(new QB(dB,{...J,...X})),L=(X)=>Y({grants:J.grants.includes(X)?J.grants.filter((H)=>H!==X):[...J.grants,X]});return a({},a({className:"scrim"}).on({click:()=>Q.engine.dispatch(new TA)}),a({className:"dialog review",$styling:{width:"min(560px, 96vw)"}},I4(C),a({className:"review-body"},C.description?W4({className:"review-desc"},C.description):null,gB("Capabilities it requests",C.capabilities.length?a({className:"cap-list"},...C.capabilities.map((X)=>R4(X,A.isAdmin,J.grants.includes(X.id),()=>L(X.id)))):P4("None — this plugin only runs in its sandbox.")),(C.network||[]).length?gB("Network access",a({className:"contrib-list"},...C.network.map(z4))):null,(C.commands||[]).length?gB("Commands it can run",a({className:"contrib-list"},...C.commands.map((X)=>V4(X,Q)))):null,C.storage?gB("Storage",q4(C.storage)):null,C.contributions.length?gB("What it adds",a({className:"contrib-list"},...C.contributions.map(M4))):null,C.settings.length?gB("Settings",a({className:"contrib-list"},...C.settings.map(N4))):null,a({className:"review-meta"},`${C.fileCount} files · ${JA(C.sizeBytes)} · id ${C.id}`)),K.headline?U4(K,J,Y):null,a({className:"row-actions"},OX({className:"btn"},"Cancel").on({click:()=>Q.engine.dispatch(new TA)}),OX({className:`btn primary ${E?"disabled":""}`,disabled:E},I("plug",{size:15}),"Install").on({click:()=>!E&&NA(Q,{actions:A.installActions})}))))}function U4(A,Q,B){return a({className:`review-warning ${A.status}`},a({className:"rw-head"},I("warn",{size:15}),YA(A.headline)),a({className:"rw-detail"},A.detail),A.requiresAcknowledgement?SX({className:"rw-ack"},_X({type:"checkbox",checked:!!Q.acknowledged}).on({change:(C)=>B({acknowledged:!!C.target.checked})}),YA("I know this package is unsigned and I trust where it came from")):null)}function I4(A){let Q=A.trust||{status:"unverified"};return a({className:"review-head"},a({className:"avatar"},(A.name||"?")[0].toUpperCase()),a({className:"rh-main"},a({className:"rh-name"},A.name,YA({className:"rh-ver"},"v"+A.version)),a({className:"rh-author"},"by "+A.author)),F4(Q))}function F4(A){let Q=aB(A),B=Q.status==="verified"&&Q.domain?`Verified · ${Q.domain}`:Q.status==="invalid"?"Invalid signature":Q.status==="signed"?"Signed":"Unverified";return YA({className:`trust ${Q.tone}`,title:Q.explanation},I(Q.icon,{size:13}),B)}function R4(A,Q,B,C){let J=A.adminOnly&&!Q;return SX({className:`cap-row ${J?"blocked":""}`},_X({type:"checkbox",checked:B&&!J,disabled:J}).on({change:()=>!J&&C()}),a({className:"cap-info"},a({className:"cap-name"},A.id,A.adminOnly?YA({className:"pf-badge",$styling:{color:"var(--warn)","margin-left":"6px"}},"admin only"):null),a({className:"cap-desc"},A.description+(J?" — requires an administrator":""))))}function M4(A){let Q={command:"command",opener:"file",indexer:"search",statusItem:"info",register:"info",keymap:"command"}[A.kind]||"command";return a({className:"contrib-row"},I(Q,{size:13}),YA({className:"cr-title"},A.title),A.detail?YA({className:"cr-detail"},A.detail):null,A.offline?YA({className:"pf-badge offline-ok"},"offline"):null,YA({className:"pf-kind"},A.kind))}function V4(A,Q){let B=Q?.platform?.contributions?.get?.(A),C=B?.pluginId?"plugin":B?"built-in":"not installed";return a({className:`contrib-row ${B?"":"blocked"}`},I("command",{size:13}),YA({className:"cr-title"},B?.title||A),YA({className:"cr-detail"},A),YA({className:"pf-kind"},C))}function z4(A){return a({className:"contrib-row"},I("plug",{size:13}),YA({className:"cr-title"},A.host),A.path?YA({className:"cr-detail"},A.path):null,YA({className:"pf-kind"},A.scheme))}function q4(A){let Q=[];if(A.plugin)Q.push(jX("Private database","A SQLite store just for this plugin (server + this device).",!1));if(A.domain)Q.push(jX("Shared database","Shared with other plugins from its domain (SQLite).",A.domainBlocked));return a({className:"contrib-list"},...Q)}function jX(A,Q,B){return a({className:`contrib-row ${B?"blocked":""}`},I("plug",{size:13}),YA({className:"cr-title"},A),YA({className:"cr-detail"},B?Q+" — needs a verified domain":Q),B?YA({className:"pf-badge",$styling:{color:"var(--warn)"}},"unavailable"):null)}function N4(A){return a({className:"contrib-row"},I("gear",{size:13}),YA({className:"cr-title"},A.title),A.secret?YA({className:"pf-badge",$styling:{color:"var(--warn)"}},"secret"):YA({className:"pf-kind"},A.type))}function gB(A,Q){return a({className:"review-section"},a({className:"rs-title"},A),Q)}function P4(A){return a({className:"muted",$styling:{"font-size":"12.5px"}},A)}var{div:S,span:uA,button:mA,input:cQ,h3:kE,p:d7,select:kX,option:V0,label:dQ,textarea:a7}=T;function gX(A,Q){let B=A.overlay.dialog;if(!B)return null;if(B.kind==="collection")return j4(B,Q,A.caps,A.view);if(B.kind==="plugin-review")return wX(B,Q,A.view);if(B.kind==="opener-chooser")return O4(B,Q);let C=d8(A.view,B),J=()=>{if(B.kind==="confirm")Q.engine.dispatch(new TA);NA(Q,{actions:B.confirmActions})};return S({},S({className:"scrim"}).on({click:()=>Q.engine.dispatch(new TA)}),S({className:"dialog"},kE(B.title),B.body?S({className:"body"},B.body):null,B.kind==="prompt"?S({className:"field"},B.label?uA({$styling:{"font-size":"12px",color:"var(--text-dim)"}},B.label):null,cQ({className:"input",value:C,placeholder:B.placeholder||"",autofocus:!0}).on({input:(K)=>Q.engine.dispatch(new QB(cB,{ref:B,value:K.target.value})),keydown:(K)=>{if(K.key==="Enter")J();if(K.key==="Escape")Q.engine.dispatch(new TA)},$attach:(K)=>queueMicrotask(()=>{K.focus(),K.select()})})):null,S({className:"row-actions"},mA({className:"btn"},"Cancel").on({click:()=>Q.engine.dispatch(new TA)}),mA({className:`btn ${B.danger?"danger":"primary"}`},B.confirmLabel||"OK").on({click:J}))))}function O4(A,Q){let B=A.openerId||A.current||A.openers[0]?.id,C=!!A.remember,J=()=>{if(C&&B)Q.engine.dispatch(new XC(BY(A.node),B));Q.engine.dispatch(new TA),Q.engine.dispatch(new HQ(A.node,B,{reset:!!A.reset}))};return S({},S({className:"scrim"}).on({click:()=>Q.engine.dispatch(new TA)}),S({className:"dialog opener-chooser"},kE(`Open “${A.node.name}” with…`),S({className:"opener-list"},...A.openers.map((K)=>dQ({className:`opener-opt ${K.id===B?"sel":""}`},cQ({type:"radio",name:"opener-choice",checked:K.id===B}).on({change:()=>Q.engine.dispatch(new AC({openerId:K.id}))}),I(K.icon||MQ(A.node),{size:18}),S({className:"oo-main"},uA({className:"oo-title"},K.title||K.id),uA({className:"oo-src"},K.source))).on({click:()=>Q.engine.dispatch(new AC({openerId:K.id}))}))),dQ({className:"opener-remember"},cQ({type:"checkbox",checked:C}).on({change:(K)=>Q.engine.dispatch(new AC({remember:K.target.checked}))}),uA(`Always use this for ${CY(A.node)}`)),S({className:"row-actions"},mA({className:"btn"},"Cancel").on({click:()=>Q.engine.dispatch(new TA)}),mA({className:"btn primary"},"Open").on({click:J}))))}var TX="collectionDialog";function j4(A,Q,B,C){let J=B?.storageDrivers||[],K={name:"",description:"",driver:J[0]?.key||"",encrypt:!1,encryptWhat:"all",encryptList:""},E=sC(C,TX,A,{form:K}),Y=E.form,L=J.find((F)=>F.key===Y.driver)||J[0],X=(F)=>(R)=>{let V=R.target.type==="checkbox"?R.target.checked:R.target.value;Q.engine.dispatch(new tJ(TX,E.ref,{[F]:V},K))},H=()=>{let F={driver:Y.driver};for(let R of L?.fields||[]){let V=Y[R.name];if(V!==void 0&&V!=="")F[R.name]=R.type==="number"?Number(V):V}Q.engine.dispatch(new rJ({name:Y.name,description:Y.description,store:F,encryption:S4(Y)}))},G=(F,R,V="")=>S({className:"field",$styling:{"margin-bottom":"10px"}},dQ(F),cQ({className:"input",placeholder:V}).on({input:X(R)})),D=Y.encrypt&&Y.encryptWhat!=="all"&&!yX(Y.encryptList).length?Y.encryptWhat==="extensions"?"Name at least one extension, or choose every file.":"Name at least one media type, or choose every file.":null,U=!!Y.name.trim()&&!!Y.driver&&!D&&(L?.fields||[]).every((F)=>!F.required||String(Y[F.name]??"").trim());return S({},S({className:"scrim"}).on({click:()=>Q.engine.dispatch(new TA)}),S({className:"dialog",$styling:{width:"min(480px, 94vw)"}},kE("New collection"),S({className:"body"},"A collection is a backing store you own. Configure where its files live."),G("Name","name","Team Vault"),J.length?S({className:"field",$styling:{"margin-bottom":"10px"}},dQ("Backing store"),kX({className:"input"},...J.map((F)=>V0({value:F.key,selected:Y.driver===F.key},F.label))).on({change:X("driver")})):S({className:"body"},"This server has no storage drivers registered, so a collection cannot be created."),L?w4(L,Y,X):null,_4(Y,X,B,D),S({className:"row-actions"},mA({className:"btn"},"Cancel").on({click:()=>Q.engine.dispatch(new TA)}),mA({className:"btn primary",$attrs:U?{}:{disabled:"true"}},"Create collection").on({click:()=>U&&H()}))))}function S4(A){if(!A.encrypt)return null;let Q=yX(A.encryptList);return{enabled:!0,rules:A.encryptWhat==="all"?{all:!0}:A.encryptWhat==="extensions"?{extensions:Q}:{mimeTypes:Q}}}function yX(A){return String(A||"").split(/[\s,]+/).map((Q)=>Q.trim()).filter(Boolean)}function _4(A,Q,B,C){let J=(B?.indexers||[]).filter((K)=>K.readsContent!==!1);return S({className:"field enc-section",$styling:{"margin-bottom":"10px"}},dQ({className:"enc-toggle"},cQ({type:"checkbox",checked:!!A.encrypt}).on({change:Q("encrypt")}),uA("Encrypt files in this collection")),!A.encrypt?S({className:"enc-hint"},"Files are stored exactly as uploaded."):S({className:"enc-body"},S({className:"field"},dQ("What to encrypt"),kX({className:"input"},V0({value:"all",selected:A.encryptWhat==="all"},"Every file"),V0({value:"extensions",selected:A.encryptWhat==="extensions"},"Only these extensions"),V0({value:"mimeTypes",selected:A.encryptWhat==="mimeTypes"},"Only these media types")).on({change:Q("encryptWhat")})),A.encryptWhat!=="all"?S({className:"field"},cQ({className:"input",value:A.encryptList,placeholder:A.encryptWhat==="extensions"?".pdf, .docx, .key":"image, application/pdf"}).on({input:Q("encryptList")}),S({className:"enc-hint"},A.encryptWhat==="extensions"?"Separated by commas. The leading dot is optional.":"Separated by commas. “image” covers every image type.")):null,C?S({className:"enc-problem"},I("warn",{size:13}),uA(C)):null,S({className:"enc-scope"},S({className:"es-title"},"What this does"),S({className:"es-line"},"Files are sealed in your browser before they are uploaded, so the storage provider only ever holds ciphertext."),S({className:"es-title"},"What it does not do"),S({className:"es-line"},"It is not end-to-end. The drive holds the key and decrypts for anything that reads through it — previews, downloads, and search indexing."),J.length?S({className:"es-line"},`These read file contents in the clear: ${J.map((K)=>K.title||K.id).join(", ")}.`):null,S({className:"es-line note"},"This applies to files uploaded from now on. Turning it off later does not decrypt anything already sealed."))))}function w4(A,Q,B){if(!A.fields.length)return S({className:"body",$styling:{"font-size":"12px"}},A.description||"This store needs no configuration.");return S({},A.description?S({className:"body",$styling:{"font-size":"12px","margin-bottom":"10px"}},A.description):null,...A.fields.map((C)=>C.type==="boolean"?S({className:"field",$styling:{"margin-bottom":"10px"}},dQ({},cQ({type:"checkbox"}).on({change:B(C.name)}),` ${C.label}`),C.help?S({className:"body",$styling:{"font-size":"11.5px"}},C.help):null):S({className:"field",$styling:{"margin-bottom":"10px"}},dQ(C.label+(C.required?"":" (optional)")),cQ({className:"input",placeholder:C.placeholder,autocomplete:"off",type:C.type==="password"||C.secret?"password":C.type==="number"?"number":"text"}).on({input:B(C.name)}),C.help?S({className:"body",$styling:{"font-size":"11.5px"}},C.help):null)))}var xX=220,T4=34,x4=20;function k4(A,Q){let{innerWidth:B,innerHeight:C}=window;if(!A)return{x:Math.round(B/2-xX/2),y:Math.round(C/3)};let J=A.rect?A.rect.left:A.x,K=A.rect?A.prefer==="up"?A.rect.top-8-Q:A.rect.bottom+8:A.y;return{x:Math.max(8,Math.min(J,B-xX)),y:Math.max(8,Math.min(K,C-Q))}}function hX(A,Q){let B=A.overlay.contextMenu;if(!B||!B.items?.length)return null;let C=Math.min(B.items.length*T4+x4,window.innerHeight-24),{x:J,y:K}=k4(B.at,C);return S({},S({className:"scrim",$styling:{background:"transparent"}}).on({click:()=>Q.engine.dispatch(new VB),contextmenu:(E)=>{E.preventDefault(),Q.engine.dispatch(new VB)}}),S({className:"menu",$styling:{left:J+"px",top:K+"px"}},...B.items.map((E,Y)=>E.sep?S({className:"sep"}):mA({className:`mi ${E.danger?"danger":""}`,autofocus:Y===0},E.icon?I(E.icon,{size:15}):null,uA(E.label),E.kbd?uA({className:"kbd"},E.kbd):null).on({click:()=>{Q.engine.dispatch(new VB),NA(Q,E)},keydown:(L)=>{if(L.key==="Escape")L.preventDefault(),Q.engine.dispatch(new VB)},$attach:(L)=>{if(Y===0)queueMicrotask(()=>L.focus())}}))))}function bX(A,Q){let B=A.notif||[];if(!B.length)return null;return S({className:"toasts"},...B.slice(-5).map((C)=>S({className:`toast ${C.level}`},S({className:"bar"}),S({className:"msg"},C.message),mA({className:"x"},I("close",{size:14})).on({click:()=>Q.engine.dispatch(new NJ(C.id))})).key(C.id)))}function vX(A,Q){let B=A.tr.items;if(!B.length)return null;return S({className:"tray"},S({className:"head"},I("upload",{size:14}),uA({$styling:{"margin-left":"6px"}},"Transfers"),S({className:"actions"},mA({className:"iconbtn",title:"Clear finished"},I("check",{size:14})).on({click:()=>Q.engine.dispatch(new bJ)}))),S({className:"items"},...B.map((C)=>S({className:`xfer ${C.status}`},S({className:"top"},I(C.status==="error"?"warn":C.status==="done"?"check":"upload",{size:14}),uA({className:"name"},C.name),C.status==="active"?mA({className:"iconbtn",title:"Cancel"},I("close",{size:13})).on({click:()=>Q.engine.dispatch(new EC(C.id))}):uA({className:"pct"},C.status==="done"?JA(C.total):C.status)),C.status==="active"?S({className:"progress"},S({$styling:{width:`${Math.round(C.ratio*100)}%`}})):C.error?S({$styling:{"font-size":"11px",color:"var(--danger)","margin-top":"4px"}},C.error):null,C.status==="active"?S({className:"pct",$styling:{"margin-top":"4px"}},`${JA(C.loaded)} / ${JA(C.total)}`):null,(C.status==="error"||C.status==="cancelled")&&C.retryable?S({className:"xfer-actions"},mA({className:"btn small"},I("refresh",{size:12}),uA("Retry")).on({click:()=>Q.engine.dispatch(new yJ(C.id))}),mA({className:"btn small ghost"},"Dismiss").on({click:()=>Q.engine.dispatch(new hJ(C.id))})):null).key(C.id))))}function fX(A,Q){let B=A.overlay.pluginPanel;if(!B)return null;let C=(A.plugins||[]).find((J)=>J.id===B);return S({className:"plugin-panel",$styling:{width:"380px"}},S({className:"head"},I("plug",{size:14}),uA(C?.name||B),mA({className:"iconbtn x"},I("close",{size:14})).on({click:()=>Q.engine.dispatch(new wJ)})),S({className:"host"}).on({$attach:(J)=>{J._detach=Q.platform.plugins.mountPanel(B,J,{width:380,height:460})},$detach:(J)=>J._detach?.()}))}var{div:d,button:NQ,span:NC,h3:g4,p:uX,pre:y4}=T,h4={running:"refresh",done:"check",failed:"close",cancelled:"close"};function b4(A,Q){Q.engine.dispatch(new tA(A))}function mX(A){if(A.total==null)return null;return A.unit==="bytes"?`${JA(A.done||0)} of ${JA(A.total)}`:`${A.done||0} of ${A.total}${A.unit?` ${A.unit}`:""}`}function pX(A,Q){let B=A.status==="running",C=B&&A.total!=null&&A.total>0,J=C?Math.min(100,Math.round((A.done||0)/A.total*100)):0;return d({className:`act-task act-${A.status}`,"data-task-id":A.id},d({className:"act-row"},B?d({className:"spinner",$styling:{width:"12px",height:"12px"}}):I(h4[A.status]||"info",{size:13}),d({className:"act-body"},d({className:"act-title"},A.title),A.detail?d({className:"act-detail"},A.detail):null,A.error?d({className:"act-error"},A.error):null),B&&A.cancellable?NQ({className:"act-action",title:"Cancel"},I("close",{size:12})).on({click:()=>Q.engine.dispatch(new TJ(A.id))}):!B?NQ({className:"act-action",title:"Dismiss"},I("close",{size:12})).on({click:()=>Q.engine.dispatch(new xJ(A.id))}):null),B?d({className:`act-bar ${C?"":"indeterminate"}`},d({className:"act-fill",$styling:C?{width:`${J}%`}:{}})):null,B&&mX(A)?d({className:"act-amount"},mX(A)):null)}function v4(A,Q){let B=new Date(A.firstAt||A.lastAt).toLocaleString();return d({className:`act-issue act-sev-${A.severity||"error"}`,"data-issue-id":A.id},d({className:"act-row"},I(A.severity==="warning"?"info":"close",{size:13}),d({className:"act-body"},d({className:"act-title"},A.title),A.detail?d({className:"act-detail"},A.detail):null,A.remedy?y4({className:"act-remedy"},A.remedy):null,d({className:"act-meta"},A.count>1?`${A.count} times, since ${B}`:`since ${B}`))),d({className:"act-actions"},A.remedy?NQ({className:"btn small ghost"},"Copy fix").on({click:()=>b4(A.remedy,Q)}):null,A.retryable?NQ({className:"btn small act-retry"},I("refresh",{size:12}),NC("Retry")).on({click:()=>Q.engine.dispatch(new kJ(A.id))}):null,NQ({className:"btn small ghost act-dismiss"},"Dismiss").on({click:()=>Q.engine.dispatch(new gJ(A.id))})))}function gE(A,Q){let B=A.act||{tasks:[],issues:[]};if(!A.overlay.activityPanel)return null;let C=B.tasks.filter((K)=>K.status==="running"),J=B.tasks.filter((K)=>K.status!=="running");return d({className:"activity-panel"},d({className:"act-head"},g4("Activity"),NQ({className:"act-action",title:"Close"},I("close",{size:13})).on({click:()=>Q.engine.dispatch(new SA(!1))})),B.tasksError||B.issuesError?d({className:"act-offline"},I("info",{size:12}),NC(`Couldn't reach the server — this list may be out of date (${B.issuesError||B.tasksError})`)):null,d({className:"act-section"},d({className:"act-section-title"},"Running"),C.length?d(...C.map((K)=>pX(K,Q))):uX({className:"act-empty"},"Nothing running.")),B.issues.length?d({className:"act-section"},d({className:"act-section-title"},`Needs attention (${B.issues.length})`),d(...B.issues.map((K)=>v4(K,Q)))):d({className:"act-section"},d({className:"act-section-title"},"Needs attention"),uX({className:"act-empty"},B.issuesError?"Could not load the list of problems.":B.issuesLoading?"Checking…":"No standing problems.")),J.length?d({className:"act-section"},d({className:"act-section-title"},"Recently finished"),d(...J.map((K)=>pX(K,Q)))):null,d({className:"act-foot act-actions"},NQ({className:"btn small ghost act-rebuild"},I("refresh",{size:12}),NC("Rebuild search index")).on({click:()=>Q.engine.dispatch(new N("workbench.rebuildIndex"))}),NQ({className:"btn small ghost act-scan"},I("refresh",{size:12}),NC("Scan for outside changes")).on({click:()=>Q.engine.dispatch(new N("workbench.scanCollection"))}),NQ({className:"btn small ghost act-storage"},I("plug",{size:12}),NC("Check storage")).on({click:()=>Q.engine.dispatch(new N("workbench.checkStorage"))})))}var{div:ZA,button:YB,span:WQ,img:dX}=T,lX=[{id:"home",icon:"search",label:"Files",command:"workbench.view.home"},{id:"upload",icon:"upload",label:"Upload",command:"explorer.upload"},{id:"plugins",icon:"plug",label:"Plugins",command:"workbench.view.plugins"}],cX={offline:{icon:"info",tone:"warn"},issues:{icon:"warn",tone:"danger"},working:{spinner:!0,tone:""},lowSpace:{icon:"info",tone:"warn"},idle:{icon:"info",tone:""}};function aX(A,Q){let B=A.facts,C=B.condition,J={...cX[C.kind]||cX.idle,label:C.label,badge:C.kind==="issues"?C.count:0},K=A.wb.activity==="settings"?"Settings":A.wb.activity==="plugins"?"Plugins":B.collectionLabel;return ZA({className:"phonebar top"},YB({className:"pb-brand",title:"Trove — home"},dX({src:"/icon.svg",alt:"Trove"})).on({click:()=>Q.engine.dispatch(new N("workbench.view.home"))}),ZA({className:"pb-title"},K),YB({className:`pb-status ${J.tone}`,title:J.label,$attrs:{"aria-label":J.label}},J.spinner?ZA({className:"spinner",$styling:{width:"15px",height:"15px"}}):I(J.icon,{size:18}),J.badge?WQ({className:"pb-badge"},String(J.badge>9?"9+":J.badge)):null).on({click:()=>Q.engine.dispatch(new A0("status"))}))}function nX(A,Q){let B=A.wb.activity,C=A.wb.sheet,J=A.so.notifications.unread;return ZA({className:"phonebar bottom"},...lX.map((K)=>YB({className:`pb-tab ${!C&&B===K.id?"active":""}`,$attrs:{"aria-label":K.label}},I(K.icon,{size:21}),WQ({className:"pb-label"},K.label)).on({click:()=>{Q.engine.dispatch(new nA),Q.engine.dispatch(new N(K.command))}})),YB({className:`pb-tab ${C==="more"||!C&&!lX.some((K)=>K.id===B)?"active":""}`,$attrs:{"aria-label":"More"}},I("dots",{size:21}),J?WQ({className:"pb-badge"},String(J>9?"9+":J)):null,WQ({className:"pb-label"},"More")).on({click:()=>Q.engine.dispatch(new A0("more"))}))}function _A({icon:A,label:Q,value:B,danger:C,onClick:J}){let K=[I(A,{size:18}),WQ({className:"sr-label"},Q),B!=null?WQ({className:"sr-value"},B):null,J?I("chevron-right",{size:16,className:"sr-go"}):null];return J?YB({className:`sheet-row ${C?"danger":""}`},...K).on({click:J}):ZA({className:"sheet-row static"},...K)}function sX(A,Q){let B=A.wb.sheet;if(!B)return null;return ZA({className:"sheet-wrap"},ZA({className:"scrim"}).on({click:()=>Q.engine.dispatch(new nA)}),ZA({className:"sheet"},ZA({className:"sheet-grip"}).on({click:()=>Q.engine.dispatch(new nA)}),B==="status"?f4(A,Q):u4(A,Q)))}function f4(A,Q){let B=A.facts,C=(J)=>()=>{Q.engine.dispatch(new nA),Q.engine.dispatch(new N(J))};return ZA({className:"sheet-body"},ZA({className:"sheet-title"},B.collectionLabel),B.issues.length?_A({icon:"warn",danger:!0,label:`${B.issues.length} need${B.issues.length===1?"s":""} attention`,onClick:()=>{Q.engine.dispatch(new nA),Q.engine.dispatch(new SA(!0))}}):null,B.running.length||B.uploading.length?_A({icon:"refresh",label:`${B.running.length+B.uploading.length} running`,onClick:()=>{Q.engine.dispatch(new nA),Q.engine.dispatch(new SA(!0))}}):null,!B.off.online?_A({icon:"info",label:"Offline",value:`${B.off.pins.length} pinned`}):null,B.off.queued?_A({icon:"upload",label:"Waiting to sync",value:String(B.off.queued)}):null,_A({icon:"files",label:"Items",value:B.partial?`${B.shown.toLocaleString()} of ${B.totalKnown?B.totalItems.toLocaleString():"more"}`:B.totalItems.toLocaleString()}),_A({icon:"file",label:"Size",value:`${JA(B.totalBytes)}${B.totalKnown||!B.partial?"":"+"}`}),B.usage?.total?ZA({className:"sheet-row static usage"},I("download",{size:18}),WQ({className:"sr-label"},"Free space"),GE(B)):null,A.caps?_A({icon:A.caps.storage?.presignDownload?"download":"files",label:"Transfers",value:A.caps.storage?.presignDownload?"Direct to storage":"Through the server"}):null,A.caps?.features?.semanticSearch?_A({icon:"star",label:"Search",value:"Semantic + keyword"}):null,ZA({className:"sheet-actions"},YB({className:"btn small ghost"},I("refresh",{size:13}),WQ("Scan for changes")).on({click:C("workbench.scanCollection")}),YB({className:"btn small ghost"},I("refresh",{size:13}),WQ("Activity")).on({click:()=>{Q.engine.dispatch(new nA),Q.engine.dispatch(new SA(!0))}})))}function u4(A,Q){let B=(K)=>()=>{Q.engine.dispatch(new nA),Q.engine.dispatch(new N(K))},C=A.so.me,J=A.so.notifications.unread;return ZA({className:"sheet-body"},C&&!C.anonymous?ZA({className:"sheet-me"},C.picture?dX({src:C.picture,alt:"",className:"avatar-img"}):WQ({className:"avatar-txt"},(C.name||C.id||"?")[0].toUpperCase()),ZA({},ZA({className:"sm-name"},C.name||C.id),C.email?ZA({className:"sm-sub"},C.email):null)):null,_A({icon:"bell",label:J?`Notifications (${J})`:"Notifications",onClick:()=>{Q.engine.dispatch(new nA),Q.engine.dispatch(new zQ(!0))}}),_A({icon:"refresh",label:"Activity & problems",onClick:()=>{Q.engine.dispatch(new nA),Q.engine.dispatch(new SA(!0))}}),_A({icon:"info",label:"Details & conversation",onClick:B("workbench.toggleInfoPanel")}),_A({icon:"trash",label:"Trash",onClick:B("explorer.showTrash")}),_A({icon:"refresh",label:"Refresh",onClick:B("explorer.refresh")}),_A({icon:"command",label:"All commands",onClick:B("workbench.showCommandPalette")}),_A({icon:"gear",label:"Settings",onClick:B("workbench.openSettings")}))}var{alias:m4,div:UQ}=T;function yE({engine:A,platform:Q}){let B={engine:A,platform:Q,watch:CQ},C=BA([s(A,UC),s(A,IC),s(A,BE),s(A,ZC),s(A,tK),s(A,zL),s(A,Z0),s(A,D0),s(A,qL),s(A,NL),s(A,CE),s(A,RC),s(A,yL),s(A,JE(!1)),s(A,JE(!0)),s(A,TL),s(A,wL)],(E,Y,L,X,H,G,D,U,F,R,V,w,m,b,z,p,k)=>({wb:E,overlay:Y,nav:L,ex:X,se:H,ctx:G,settings:D,off:U,vp:F,voice:R,view:V,caps:w,commandKeys:m,content:b,modalContent:z,views:p,openers:k})),J={ex:ZC,tr:eK,act:$0,off:D0,so:WC,wb:UC,statusItems:jL,caps:RC,facts:_L},K={statusBar:qA(A,J,(E)=>$E(E,B),{placeholder:()=>UQ({className:"statusbar"})}),phoneTopBar:qA(A,J,(E)=>aX(E,B),{placeholder:()=>UQ({className:"phonebar top"})}),phoneBottomBar:qA(A,J,(E)=>nX(E,B),{placeholder:()=>UQ({className:"phonebar bottom"})}),phoneSheet:qA(A,J,(E)=>sX(E,B)),transferTray:qA(A,{tr:eK},(E)=>vX(E,B)),toasts:qA(A,{notif:ML},(E)=>bX(E,B)),activityPanel:qA(A,{act:$0,overlay:IC},(E)=>gE(E,B)),pluginPanel:qA(A,{overlay:IC,plugins:FC},(E)=>fX(E,B)),settingsView:qA(A,{settings:Z0,settingsGroups:VL,keys:RL,caps:RC,ex:ZC,assoc:kL},(E)=>FE(E,B,K)),keybindings:qA(A,{bindings:SL,view:CE},(E)=>LX(E.bindings||[],B,E.view?.[RE]??null)),pluginsView:qA(A,{plugins:FC,settings:Z0},(E)=>NE(E,B)),adminView:qA(A,{caps:RC,ex:ZC,plugins:FC,act:$0,so:WC,wb:UC},(E)=>OE(E,B)),infoPanel:qA(A,{so:WC,off:D0,nav:BE},(E)=>uL(E,B)),activityBar:qA(A,{wb:UC,plugins:FC,so:WC},(E)=>HE(E,B)),commandPalette:qA(A,{overlay:IC,se:tK,matches:OL},(E)=>xE(E,B))};return m4(()=>CQ(C,(E)=>p4(E,B,K)))}function p4(A,Q,B){let C=A.vp?.mode||"desktop",J=C==="phone";return UQ({className:`shell ${C} ${A.settings["workbench.density"]==="compact"?"compact":""}`},J?B.phoneTopBar():null,UQ({className:"body"},J?null:B.activityBar(),l4(A,Q,B)),J?B.phoneBottomBar():B.statusBar(),J?B.phoneSheet():null,c4(A,Q),B.commandPalette(),gX(A,Q),hX(A,Q),B.pluginPanel(),B.toasts(),B.transferTray(),B.activityPanel())}function l4(A,Q,B){if(A.ex?.gate&&A.wb.activity!=="settings")return zE(A,Q);switch(A.wb.activity){case"settings":return B.settingsView();case"plugins":return B.pluginsView();case"admin":return B.adminView();default:{if(!A.nav.activeTabId)return F0(A,Q);if(!A.wb.infoPanel)return M0(A,Q);return A.vp?.mode==="phone"?B.infoPanel():UQ({className:"editor-split"},M0(A,Q),B.infoPanel())}}}function c4(A,Q){if(!A.wb.searchModal)return UQ();return UQ({className:"search-modal"},UQ({className:"scrim"}).on({click:()=>Q.engine.dispatch(new zB)}),UQ({className:"search-modal-panel"},F0(A,Q,{modal:!0})))}function iX({root:A=document.querySelector(".workbench"),baseUrl:Q="",openers:B=[],views:C=[],settings:J=[],serviceWorker:K=!0,debug:E=globalThis.__troveDebug===!0}={}){let Y=AL({baseUrl:Q}),{engine:L,app:X}=XL(Y);if(MX(Y),eL(Y),oX(Y,"opener",B),oX(Y,"view",C),J.length)Y.settings.register(J);Y.plugins.restore();let H=yE({engine:L,platform:Y});T.reconcile(A,[H()]);let G=()=>{document.documentElement.dataset.theme=Y.settings.get("workbench.theme")||"dark"};if(G(),TQ(Y.settings.observe(),()=>G()),Y.viewport.install(),Y.voice.refresh().catch(()=>{}),Y.spatialNav.install(),Y.keybindings.install(window),window.addEventListener("popstate",(D)=>X.navigation.onPopState(D)),a4(L),K&&"serviceWorker"in navigator)window.addEventListener("load",()=>navigator.serviceWorker.register("/sw.js").catch(()=>{}));if(n4(L),L.dispatch(new FJ),E)d4({platform:Y,engine:L,app:X});return{platform:Y,engine:L,app:X}}function d4({platform:A,engine:Q,app:B}){window.__trove={platform:A,engine:Q,app:B,test:{parsePackage:tQ,assessTrust:(C)=>A.plugins.assessTrust(C),install:(C,J)=>A.plugins.install(C,J),NavigateAction:hA,open:(C,J)=>A.dispatch(new HQ(C,J)),contextMenu:(C,J)=>A.dispatch(new $Q(C,J)),attachMedia:SB}}}function oX(A,Q,B){for(let C of B){if(!C?.id)throw Error(`A ${Q} passed to createWorkbench needs an "id"`);let{id:J,...K}=C;A.contributions.register(J,{type:Q,...K})}}function a4(A){let Q=0;window.addEventListener("keydown",(B)=>{if(B.key==="Shift"&&!B.repeat){let C=Date.now();if(C-Q<400)A.dispatch(new jJ),Q=0;else Q=C}else if(B.key!=="Shift")Q=0})}function n4(A){let Q=0;window.addEventListener("dragenter",(B)=>{if(!B.dataTransfer?.types.includes("Files"))return;Q++,document.body.classList.add("dragging-file")}),window.addEventListener("dragover",(B)=>{if(B.dataTransfer?.types.includes("Files"))B.preventDefault()}),window.addEventListener("dragleave",()=>{if(--Q<=0)Q=0,document.body.classList.remove("dragging-file")}),window.addEventListener("drop",(B)=>{if(!B.dataTransfer?.files?.length)return;B.preventDefault(),Q=0,document.body.classList.remove("dragging-file"),A.dispatch(new tB(B.dataTransfer.files))})}iX();
|
|
509
|
+
|
|
510
|
+
//# debugId=DEA667E228DB128C64756E2164756E21
|
|
511
|
+
//# sourceMappingURL=main-828yzsr7.js.map
|