@forsion/extend 0.7.1 → 0.8.0

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/dist/desktop.mjs CHANGED
@@ -1,7 +1,7 @@
1
- function Dn(n,e){if(typeof e!="string"||!e.startsWith("/"))return null;let t=String(n||"").replace(/\/+$/,"").replace(/\/api$/,"");if(!t)return null;let s,r;try{s=new URL(t),r=new URL(t+"/api"+e)}catch{return null}return s.protocol!=="http:"&&s.protocol!=="https:"||r.origin!==s.origin||!r.pathname.startsWith("/api/")?null:r.toString()}async function de(n,e,t,s,r=6e4){let i=await fetch(n.base+t,{method:e,headers:{"Content-Type":"application/json","X-Project-Source":"connect",...n.token?{Authorization:`Bearer ${n.token}`}:{}},body:s===void 0?void 0:JSON.stringify(s),signal:AbortSignal.timeout(r)}),o=await i.json().catch(()=>({}));return{status:i.status,json:o}}import{readdirSync as ns,lstatSync as rs,readFileSync as jt,writeFileSync as ss,realpathSync as Mn}from"node:fs";import{join as Ht,extname as is,sep as os}from"node:path";var Lt=300,Nn=5*1024*1024,Un=20*1024*1024,as=50*1024*1024,ls=new Set(["node_modules"]),cs=new Set([".ts",".tsx",".jsx",".mts",".cts"]);function Fn(n,e){let t=[],s=0,r=(i,o)=>{for(let a of ns(i)){if(a.startsWith("."))continue;let c=Ht(i,a),h;try{h=rs(c)}catch{continue}if(h.isSymbolicLink())continue;let d=o?`${o}/${a}`:a;if(h.isDirectory()){ls.has(a)||r(c,d);continue}if(!h.isFile()||a.endsWith(".d.ts"))continue;if(t.length>=Lt)throw new Error(`\u6587\u4EF6\u6570\u8D85\u8FC7 ${Lt}\uFF0C\u8BF7\u7CBE\u7B80\u9879\u76EE\uFF08node_modules \u4E0E\u9690\u85CF\u6587\u4EF6\u5DF2\u81EA\u52A8\u8DF3\u8FC7\uFF09`);let f=is(a).toLowerCase(),u,y=e.mimeOf(f)??"application/octet-stream";if(cs.has(f)){let v=e.transpile(jt(c,"utf8"),f,d);u=Buffer.from(v??"","utf8"),y="text/javascript"}else u=jt(c);if(u.length>Nn)throw new Error(`\u5355\u6587\u4EF6\u8D85\u8FC7 5MB\uFF1A${d}`);if(s+=u.length,s>Un)throw new Error("\u9879\u76EE\u603B\u5927\u5C0F\u8D85\u8FC7 20MB\uFF0C\u65E0\u6CD5\u53D1\u5E03");t.push({path:d,content_b64:u.toString("base64"),content_type:y,size:u.length})}};if(r(n,""),!t.length)throw new Error("\u9879\u76EE\u4E3A\u7A7A\uFF0C\u6CA1\u6709\u53EF\u53D1\u5E03\u7684\u6587\u4EF6");return{files:t,totalBytes:s}}var On=".forsion-connect.json";function jn(n){try{return JSON.parse(jt(Ht(n,On),"utf8"))}catch{return{}}}function Ln(n,e){try{ss(Ht(n,On),JSON.stringify(e,null,2)+`
2
- `,"utf8")}catch{}}function Hn(n){let e={"/__forsion/chat":{method:"POST",path:"/api/chat/completions",auth:!0},"/__forsion/images":{method:"POST",path:"/api/images/generations",auth:!0},"/__forsion/user":{method:"GET",path:"/api/brain/users/me",auth:!0},"/__forsion/models":{method:"GET",path:"/api/models",auth:!1},"/__forsion/config":{method:"GET",path:"/api/connect/config",auth:!1},"/__forsion/agent":{method:"POST",path:"/api/agent/runs",auth:!0,agentRun:!0}};function t(s){if(e[s])return e[s];let r="/__forsion/agent-events/";if(s.startsWith(r)){let i=s.slice(r.length);if(/^[A-Za-z0-9-]{1,64}$/.test(i))return{method:"GET",path:`/api/agent/runs/${i}/events`,auth:!0,timeoutMs:9e5}}}return async(s,r)=>{let[i,o]=(s.url||"").split("?"),a=(v,x)=>{r.headersSent||(r.statusCode=v,r.setHeader("Content-Type","application/json")),r.end(JSON.stringify({detail:x}))},c=t(i);if(!c)return a(404,"unknown connect endpoint");if((s.method||"GET")!==c.method)return a(405,"method not allowed");let h="",d="";try{({base:h,token:d}=await n())}catch{}if(!h)return a(502,"\u672A\u914D\u7F6E Forsion \u4E91\u7AEF\u5730\u5740");if(c.auth&&!d)return a(401,"\u8BF7\u5148\u5728 Forsion Desktop \u4E2D\u767B\u5F55 Forsion \u8D26\u53F7");let f;if(c.method==="POST"){let v=[],x=0;try{for await(let E of s){if(x+=E.length,x>as)return s.destroy(),a(413,"\u8BF7\u6C42\u4F53\u8FC7\u5927");v.push(E)}}catch(E){return a(400,`\u8BF7\u6C42\u4F53\u8BFB\u53D6\u5931\u8D25\uFF1A${E?.message||String(E)}`)}f=Buffer.concat(v)}if(c.agentRun){let v;try{v=JSON.parse((f||Buffer.alloc(0)).toString("utf8")||"{}")}catch{return a(400,"agent \u8BF7\u6C42\u4F53\u5FC5\u987B\u662F JSON")}f=Buffer.from(JSON.stringify({session_id:typeof v.session_id=="string"?v.session_id:"",message:typeof v.message=="string"?v.message:"",app_id:"connect",agent_config:{}}))}let u=new AbortController,y=setTimeout(()=>u.abort(new Error("proxy timeout")),c.timeoutMs??3e5);s.on("close",()=>u.abort());try{let v=await fetch(h+c.path+(o?`?${o}`:""),{method:c.method,headers:{"Content-Type":"application/json","X-Project-Source":"connect",...d?{Authorization:`Bearer ${d}`}:{}},body:f&&f.length?new Uint8Array(f):void 0,signal:u.signal});if(r.statusCode=v.status,r.setHeader("Content-Type",v.headers.get("content-type")||"application/json"),r.setHeader("Cache-Control","no-store"),v.body)for await(let x of v.body)r.write(x);r.end()}catch(v){let x=`\u4E91\u7AEF\u8BF7\u6C42\u4E2D\u65AD\uFF1A${v?.message||String(v)}`;if(r.headersSent){try{r.write(`data: ${JSON.stringify({error:x})}
1
+ function Jn(t,e){if(typeof e!="string"||!e.startsWith("/"))return null;let n=String(t||"").replace(/\/+$/,"").replace(/\/api$/,"");if(!n)return null;let r,s;try{r=new URL(n),s=new URL(n+"/api"+e)}catch{return null}return r.protocol!=="http:"&&r.protocol!=="https:"||s.origin!==r.origin||!s.pathname.startsWith("/api/")?null:s.toString()}async function ge(t,e,n,r,s=6e4){let i=await fetch(t.base+n,{method:e,headers:{"Content-Type":"application/json","X-Project-Source":"connect",...t.token?{Authorization:`Bearer ${t.token}`}:{}},body:r===void 0?void 0:JSON.stringify(r),signal:AbortSignal.timeout(s)}),a=await i.json().catch(()=>({}));return{status:i.status,json:a}}import{readdirSync as Os,lstatSync as Us,readFileSync as Kt,writeFileSync as Fs,realpathSync as Kn}from"node:fs";import{join as Zt,extname as js,sep as Ls}from"node:path";var Xt=300,Xn=5*1024*1024,Zn=20*1024*1024,Hs=50*1024*1024,zs=new Set(["node_modules"]),qs=new Set([".ts",".tsx",".jsx",".mts",".cts"]);function Qn(t,e){let n=[],r=0,s=(i,a)=>{for(let o of Os(i)){if(o.startsWith("."))continue;let l=Zt(i,o),h;try{h=Us(l)}catch{continue}if(h.isSymbolicLink())continue;let d=a?`${a}/${o}`:o;if(h.isDirectory()){zs.has(o)||s(l,d);continue}if(!h.isFile()||o.endsWith(".d.ts"))continue;if(n.length>=Xt)throw new Error(`\u6587\u4EF6\u6570\u8D85\u8FC7 ${Xt}\uFF0C\u8BF7\u7CBE\u7B80\u9879\u76EE\uFF08node_modules \u4E0E\u9690\u85CF\u6587\u4EF6\u5DF2\u81EA\u52A8\u8DF3\u8FC7\uFF09`);let f=js(o).toLowerCase(),u,g=e.mimeOf(f)??"application/octet-stream";if(qs.has(f)){let S=e.transpile(Kt(l,"utf8"),f,d);u=Buffer.from(S??"","utf8"),g="text/javascript"}else u=Kt(l);if(u.length>Xn)throw new Error(`\u5355\u6587\u4EF6\u8D85\u8FC7 5MB\uFF1A${d}`);if(r+=u.length,r>Zn)throw new Error("\u9879\u76EE\u603B\u5927\u5C0F\u8D85\u8FC7 20MB\uFF0C\u65E0\u6CD5\u53D1\u5E03");n.push({path:d,content_b64:u.toString("base64"),content_type:g,size:u.length})}};if(s(t,""),!n.length)throw new Error("\u9879\u76EE\u4E3A\u7A7A\uFF0C\u6CA1\u6709\u53EF\u53D1\u5E03\u7684\u6587\u4EF6");return{files:n,totalBytes:r}}var er=".forsion-connect.json";function tr(t){try{return JSON.parse(Kt(Zt(t,er),"utf8"))}catch{return{}}}function nr(t,e){try{Fs(Zt(t,er),JSON.stringify(e,null,2)+`
2
+ `,"utf8")}catch{}}function rr(t){let e={"/__forsion/chat":{method:"POST",path:"/api/chat/completions",auth:!0},"/__forsion/images":{method:"POST",path:"/api/images/generations",auth:!0},"/__forsion/user":{method:"GET",path:"/api/brain/users/me",auth:!0},"/__forsion/models":{method:"GET",path:"/api/models",auth:!1},"/__forsion/config":{method:"GET",path:"/api/connect/config",auth:!1},"/__forsion/agent":{method:"POST",path:"/api/agent/runs",auth:!0,agentRun:!0}};function n(r){if(e[r])return e[r];let s="/__forsion/agent-events/";if(r.startsWith(s)){let i=r.slice(s.length);if(/^[A-Za-z0-9-]{1,64}$/.test(i))return{method:"GET",path:`/api/agent/runs/${i}/events`,auth:!0,timeoutMs:9e5}}}return async(r,s)=>{let[i,a]=(r.url||"").split("?"),o=(S,x)=>{s.headersSent||(s.statusCode=S,s.setHeader("Content-Type","application/json")),s.end(JSON.stringify({detail:x}))},l=n(i);if(!l)return o(404,"unknown connect endpoint");if((r.method||"GET")!==l.method)return o(405,"method not allowed");let h="",d="";try{({base:h,token:d}=await t())}catch{}if(!h)return o(502,"\u672A\u914D\u7F6E Forsion \u4E91\u7AEF\u5730\u5740");if(l.auth&&!d)return o(401,"\u8BF7\u5148\u5728 Forsion Desktop \u4E2D\u767B\u5F55 Forsion \u8D26\u53F7");let f;if(l.method==="POST"){let S=[],x=0;try{for await(let w of r){if(x+=w.length,x>Hs)return r.destroy(),o(413,"\u8BF7\u6C42\u4F53\u8FC7\u5927");S.push(w)}}catch(w){return o(400,`\u8BF7\u6C42\u4F53\u8BFB\u53D6\u5931\u8D25\uFF1A${w?.message||String(w)}`)}f=Buffer.concat(S)}if(l.agentRun){let S;try{S=JSON.parse((f||Buffer.alloc(0)).toString("utf8")||"{}")}catch{return o(400,"agent \u8BF7\u6C42\u4F53\u5FC5\u987B\u662F JSON")}f=Buffer.from(JSON.stringify({session_id:typeof S.session_id=="string"?S.session_id:"",message:typeof S.message=="string"?S.message:"",app_id:"connect",agent_config:{}}))}let u=new AbortController,g=setTimeout(()=>u.abort(new Error("proxy timeout")),l.timeoutMs??3e5);r.on("close",()=>u.abort());try{let S=await fetch(h+l.path+(a?`?${a}`:""),{method:l.method,headers:{"Content-Type":"application/json","X-Project-Source":"connect",...d?{Authorization:`Bearer ${d}`}:{}},body:f&&f.length?new Uint8Array(f):void 0,signal:u.signal});if(s.statusCode=S.status,s.setHeader("Content-Type",S.headers.get("content-type")||"application/json"),s.setHeader("Cache-Control","no-store"),S.body)for await(let x of S.body)s.write(x);s.end()}catch(S){let x=`\u4E91\u7AEF\u8BF7\u6C42\u4E2D\u65AD\uFF1A${S?.message||String(S)}`;if(s.headersSent){try{s.write(`data: ${JSON.stringify({error:x})}
3
3
 
4
- `)}catch{}r.end()}else a(502,x)}finally{clearTimeout(y)}}}var zn=`
4
+ `)}catch{}s.end()}else o(502,x)}finally{clearTimeout(g)}}}var sr=`
5
5
  (function () {
6
6
  'use strict';
7
7
  if (window.forsion) return;
@@ -190,17 +190,24 @@ function Dn(n,e){if(typeof e!="string"||!e.startsWith("/"))return null;let t=Str
190
190
  ai: { chat: chat, agent: agentRun, generateImage: generateImage }
191
191
  };
192
192
  })();
193
- `,us=n=>({transpile:(e,t,s)=>n.transpileForServe(e,t,s),mimeOf:e=>n.mimeOf(e)});function zt(n){let e=n;return typeof e.projectsRoot=="function"&&typeof e.transpileForServe=="function"&&typeof e.mimeOf=="function"&&typeof e.setPreviewHooks=="function"}function Wt(n){n.setPreviewHooks({sdkJs:zn,proxy:Hn(()=>n.getCloud())}),n.handle("connect:meta",(e,t)=>typeof t=="string"&&t?jn(t):{}),n.handle("connect:list",async()=>{let e=await n.getCloud();if(!e.token)return{ok:!1,code:"not_logged_in",detail:"\u8BF7\u5148\u767B\u5F55 Forsion \u8D26\u53F7"};try{let{status:t,json:s}=await de(e,"GET","/api/connect/apps");return t===401||t===403?{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"}:t!==200?{ok:!1,code:"error",detail:s?.detail||`HTTP ${t}`}:{ok:!0,base:e.base,...s}}catch(t){return{ok:!1,code:"error",detail:t?.message||String(t)}}}),n.handle("connect:publish",async(e,t)=>{if(!t||typeof t.dir!="string"||!t.dir||!t.name||!t.slug||!t.entry)return{ok:!1,code:"error",detail:"\u53C2\u6570\u4E0D\u5B8C\u6574"};let s;try{let i=Mn(n.projectsRoot());if(s=Mn(t.dir),s!==i&&!s.startsWith(i+os))return{ok:!1,code:"error",detail:"\u53EA\u80FD\u53D1\u5E03 Coding Space \u9879\u76EE\u76EE\u5F55"}}catch{return{ok:!1,code:"error",detail:"\u9879\u76EE\u76EE\u5F55\u4E0D\u5B58\u5728\u6216\u65E0\u6CD5\u8BBF\u95EE"}}let r=await n.getCloud();if(!r.token)return{ok:!1,code:"not_logged_in",detail:"\u8BF7\u5148\u767B\u5F55 Forsion \u8D26\u53F7"};try{let{files:i,totalBytes:o}=Fn(s,us(n));if(!i.some(h=>h.path===t.entry))return{ok:!1,code:"error",detail:`\u5165\u53E3\u6587\u4EF6\u4E0D\u5B58\u5728:${t.entry}`};let{status:a,json:c}=await de(r,"POST","/api/connect/apps",{slug:t.slug,name:t.name,entry:t.entry,files:i},3e5);return a===401?{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"}:a!==200?{ok:!1,code:c?.code||"error",detail:c?.detail||`HTTP ${a}`,used:c?.used,limit:c?.limit}:(Ln(s,{slug:String(c.slug)}),{ok:!0,slug:c.slug,handle:c.handle,url:`${r.base}${c.url}`,totalBytes:o})}catch(i){return{ok:!1,code:"error",detail:i?.message||String(i)}}}),n.handle("connect:unpublish",async(e,t)=>{if(!t||typeof t!="string")return{ok:!1,code:"error",detail:"\u53C2\u6570\u4E0D\u5B8C\u6574"};let s=await n.getCloud();if(!s.token)return{ok:!1,code:"not_logged_in",detail:"\u8BF7\u5148\u767B\u5F55 Forsion \u8D26\u53F7"};try{let{status:r,json:i}=await de(s,"DELETE",`/api/connect/apps/${encodeURIComponent(t)}`);return r===401||r===403?{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"}:r!==200&&r!==404?{ok:!1,code:"error",detail:i?.detail||`HTTP ${r}`}:{ok:!0}}catch(r){return{ok:!1,code:"error",detail:r?.message||String(r)}}}),n.handle("connect:listingApply",async(e,t)=>{if(!t||typeof t.slug!="string"||!t.slug||typeof t.summary!="string"||!t.summary.trim())return{ok:!1,code:"error",detail:"\u53C2\u6570\u4E0D\u5B8C\u6574"};let s=await n.getCloud();if(!s.token)return{ok:!1,code:"not_logged_in",detail:"\u8BF7\u5148\u767B\u5F55 Forsion \u8D26\u53F7"};try{let{status:r,json:i}=await de(s,"PUT",`/api/connect/apps/${encodeURIComponent(t.slug)}/listing`,{summary:t.summary});return r===401?{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"}:r!==200?{ok:!1,code:i?.code||"error",detail:i?.detail||`HTTP ${r}`}:{ok:!0,status:i.status}}catch(r){return{ok:!1,code:"error",detail:r?.message||String(r)}}}),n.handle("connect:listingWithdraw",async(e,t)=>{if(!t||typeof t!="string")return{ok:!1,code:"error",detail:"\u53C2\u6570\u4E0D\u5B8C\u6574"};let s=await n.getCloud();if(!s.token)return{ok:!1,code:"not_logged_in",detail:"\u8BF7\u5148\u767B\u5F55 Forsion \u8D26\u53F7"};try{let{status:r,json:i}=await de(s,"DELETE",`/api/connect/apps/${encodeURIComponent(t)}/listing`);return r===401?{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"}:r!==200&&r!==404?{ok:!1,code:"error",detail:i?.detail||`HTTP ${r}`}:{ok:!0}}catch(r){return{ok:!1,code:"error",detail:r?.message||String(r)}}}),n.handle("connect:store",async()=>{let e=await n.getCloud();try{let{status:t,json:s}=await de(e,"GET","/api/connect/store");return t!==200?{ok:!1,detail:s?.detail||`HTTP ${t}`}:{ok:!0,base:e.base,items:Array.isArray(s.items)?s.items:[]}}catch(t){return{ok:!1,detail:t?.message||String(t)}}}),n.log("[forsion-extend] connect handlers registered")}import{createHash as ds}from"node:crypto";async function nt(n,e){if(!n||!e)return{status:"offline"};let t=n.replace(/\/+$/,"");try{let s=await fetch(`${t}/api/brain/users/me`,{headers:{Authorization:`Bearer ${e}`},signal:AbortSignal.timeout(5e3)});if(s.status===401||s.status===403)return{status:(s.headers.get("content-type")||"").includes("application/json")?"expired":"offline"};if(!s.ok)return{status:"offline"};let r=await s.json();if(!r)return{status:"offline"};let i=r.avatar||r.avatarUrl||r.avatar_url||void 0;return i&&/^\/(?!\/)/.test(i)&&(i=t+i),{status:"ok",user:{username:r.username||r.nickname||void 0,nickname:r.nickname||void 0,avatar:i,membershipTier:r.membershipTier||r.membership_tier||void 0}}}catch{return{status:"offline"}}}var Wn=n=>`${n.seq}:${n.hash}`,fs=n=>ds("sha256").update(n).digest("hex");function qt(n){if(n===null)return{baseSeq:0,baseHash:null};if(typeof n!="string")return;let e=n.indexOf(":"),t=Number(e===-1?n:n.slice(0,e));if(!Number.isInteger(t)||t<=0)return;let s=e===-1?"":n.slice(e+1);return{baseSeq:t,baseHash:/^[0-9a-f]{64}$/.test(s)?s:null}}function Bn(n){let e=n.baseUrl.replace(/\/+$/,""),t=r=>`${e}/api/remotesync/vaults/${encodeURIComponent(n.vault)}${r}`,s=async(r,i)=>{let o=n.getToken();if(!o)throw new Error("penzor-not-logged-in");let a=await fetch(r,{...i,headers:{...i.headers,Authorization:`Bearer ${o}`}});if(a.status===409){let c=await a.json().catch(()=>({}));throw new Error(`cas-conflict ${String(c.code??"")}: seq=${String(c.seq??"?")}`)}if(!a.ok){let c=await a.text().catch(()=>"");throw new Error(`penzor ${i.method??"GET"} ${a.status}: ${c.slice(0,200)}`)}return a};return{kind:"penzor",async walk(r){let i=await s(t("/manifest"),{method:"GET",signal:r}),{files:o}=await i.json();return o.map(a=>({key:a.path,size:a.size,mtimeMs:a.mtimeMs,id:Wn(a)}))},async readFile(r,i){let a=await(await s(t(`/file?path=${encodeURIComponent(r)}`),{method:"GET",signal:i})).json(),c=await fetch(a.url,{signal:i});if(!c.ok)throw new Error(`penzor blob GET ${c.status}: ${r}`);let h=Buffer.from(await c.arrayBuffer());if(fs(h)!==a.hash)throw new Error(`penzor hash mismatch: ${r}`);return h},async writeFile(r,i,o,a,c){let h=qt(c),d=new URLSearchParams({path:r,mtimeMs:String(Math.floor(o)||0)});h&&(d.set("baseSeq",String(h.baseSeq)),h.baseHash&&d.set("baseHash",h.baseHash));let u=await(await s(t(`/file?${d.toString()}`),{method:"PUT",body:new Uint8Array(i),headers:{"Content-Type":"application/octet-stream"},signal:a})).json();return{key:r,size:u.size,mtimeMs:u.mtimeMs,id:Wn(u)}},async rm(r,i,o){let a=qt(o),c=new URLSearchParams({path:r});a&&a.baseSeq>0&&(c.set("baseSeq",String(a.baseSeq)),a.baseHash&&c.set("baseHash",a.baseHash)),await s(t(`/file?${c.toString()}`),{method:"DELETE",signal:i})},async check(){try{return await s(t("/manifest"),{method:"GET"}),{ok:!0}}catch(r){return{ok:!1,error:String(r?.message||r)}}}}}var Vn=50*1024*1024,qn=new Map;async function hs(n,e){let t=qn.get(e);if(t)return{id:t};let s=await nt(n,e);if(s.status==="offline")return{error:"penzor-offline"};if(s.status!=="ok")return{error:"penzor-not-logged-in"};let r=s.user?.username?.trim();return r?(qn.set(e,r),{id:r}):{error:"penzor-auth-unverified"}}var Bt=n=>typeof n.registerRemoteSyncBackend=="function"&&typeof n.readCreds=="function";function Vt(n){n.registerRemoteSyncBackend("penzor",async e=>{let t=n.readCreds();if(!t.token||!t.cloudUrl)return{error:"penzor-not-logged-in"};let s=e?.vault,r=(typeof s=="string"?s:"default").trim()||"default";if(!/^[A-Za-z0-9_-]{1,64}$/.test(r))return{error:"penzor-bad-vault"};let i=await hs(t.cloudUrl,t.token);if("error"in i)return i;let o=t.token;return{remote:Bn({baseUrl:t.cloudUrl,vault:r,getToken:()=>o}),fingerprint:`penzor:${t.cloudUrl.replace(/\/+$/,"")}|u:${i.id}|${r}`,maxFileBytes:Vn}}),n.log('[forsion-extend] remote-sync backend "penzor" registered')}import{readFileSync as ps,writeFileSync as ms,mkdirSync as gs,chmodSync as ys,renameSync as ws}from"node:fs";import{join as bs}from"node:path";function Se(n,e){try{let t=new URL(n);if(t.protocol!=="https:"&&t.protocol!=="http:")return null;let s=e.split(".")[1];if(!s)return null;let r=s.replace(/-/g,"+").replace(/_/g,"/"),i=Uint8Array.from(atob(r),c=>c.charCodeAt(0)),o=JSON.parse(new TextDecoder().decode(i)),a=o.userId??o.sub;return typeof a!="string"&&typeof a!="number"||!String(a).trim()?null:`${t.origin}${t.pathname.replace(/\/+$/,"")}::${String(a)}`}catch{return null}}function Gt(n){try{let e=n.split(".")[1];if(!e)return null;let t=JSON.parse(Buffer.from(e,"base64url").toString("utf8"));return t&&typeof t=="object"?t:null}catch{return null}}function Yn(n,e=Date.now()){let t=Gt(n)?.iat;return typeof t=="number"?e-t*1e3:1/0}function Ss(n,e=Date.now()){let t=Gt(n)?.exp;return typeof t=="number"?t*1e3-e:1/0}var vs=36e5;function Jn(n,e=Date.now()){return!!n&&Yn(n,e)>=vs}async function Xn(n,e,t=8e3,s){if(!n||!e)return null;let r=n.replace(/\/+$/,"");try{let i=await fetch(`${r}/api/auth/refresh`,{method:"POST",headers:{Authorization:`Bearer ${e}`,...s?{"X-Forsion-Client":s}:{}},signal:AbortSignal.timeout(t)});if(!i.ok)return null;let o=await i.json().catch(()=>null),a=typeof o?.token=="string"?o.token:"";return a&&a!==e?a:null}catch{return null}}var vt=(n,e)=>`${n.replace(/\/+$/,"")}\0${e}`,Es=(n,e)=>new Promise((t,s)=>{let r=()=>{clearTimeout(i),s(new Error("Sign-in cancelled."))},i=setTimeout(()=>{e.removeEventListener("abort",r),t()},n);e.aborted?r():e.addEventListener("abort",r,{once:!0})});function Kn(n){let e=()=>bs(n.homeDir(),"auth-accounts.json"),t=(f,u)=>{gs(n.homeDir(),{recursive:!0});let y=`${f}.tmp`;ms(y,JSON.stringify(u,null,2),{encoding:"utf8",mode:384}),ys(y,384),ws(y,f)},s=()=>{try{let f=JSON.parse(ps(e(),"utf8"));return Array.isArray(f.accounts)?f.accounts.filter(u=>u&&typeof u.token=="string"&&u.id===Se(u.cloudUrl,u.token)):[]}catch{return[]}},r=(f,u)=>{let y=Se(f.cloudUrl||"",f.token||"");if(!y||!f.token||!f.cloudUrl)return;let v=s(),x=v.find(M=>M.id===y),E=Gt(f.token),U={...x,id:y,cloudUrl:f.cloudUrl.replace(/\/+$/,""),token:f.token,username:u?.username||x?.username||E?.username,nickname:u?.nickname||x?.nickname};JSON.stringify(x)!==JSON.stringify(U)&&t(e(),{version:1,accounts:[...v.filter(M=>M.id!==y),U]})},i=()=>{let f=n.readCreds();r(f);let u=Se(f.cloudUrl,f.token);return s().map(({token:y,...v})=>({...v,active:v.id===u}))},o=f=>{let u=s().find(y=>y.id===f);if(!u)throw new Error("Account is no longer signed in. Sign in again.");return{cloudUrl:u.cloudUrl,token:u.token}},a=f=>{let u=Se(f.cloudUrl||"",f.token||"");u&&t(e(),{version:1,accounts:s().filter(y=>y.id!==u)})},c=null;return{rememberForsionAccount:r,forsionAccounts:i,savedForsionAccount:o,forgetForsionAccount:a,cancelForsionLogin:()=>{c?.abort(),c=null},forsionDeviceLogin:async(f,u,y)=>{if(c)throw new Error("A sign-in is already in progress.");if(!f)throw new Error("\u8BF7\u5148\u586B\u5199 Forsion \u4E91\u7AEF\u5730\u5740(\u6216\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF TANGU_CLOUD_URL)");let v=new AbortController;c=v;let x=()=>{if(v.signal.aborted||c!==v)throw new Error("Sign-in cancelled.")};try{let E=f.replace(/\/+$/,""),U;try{U=await fetch(`${E}/api/auth/cli/start`,{method:"POST",headers:{"Content-Type":"application/json"},body:"{}",signal:AbortSignal.any([v.signal,AbortSignal.timeout(15e3)])}).then(J=>J.json())}catch(J){throw new Error(`\u65E0\u6CD5\u8FDE\u63A5 ${E}:${J?.message||J}`)}if(x(),!U?.device_code)throw new Error("\u4E91\u7AEF\u4E0D\u652F\u6301 CLI \u767B\u5F55(/api/auth/cli/start \u8FD4\u56DE\u5F02\u5E38)");let M=U.verification_uri_complete||`${U.verification_uri}?code=${U.user_code}`,Y=new URL(`${E}/auth`);Y.searchParams.set("logout","1"),Y.searchParams.set("app","forsion-desktop"),Y.searchParams.set("redirect",M);let B=Y.toString();u?.({url:B,userCode:String(U.user_code||"")}),n.openExternal(B);let q=Date.now()+(U.expires_in||600)*1e3,Q=(U.interval||2)*1e3;for(;Date.now()<q;){await Es(Q,v.signal),x();let J=null;try{J=await fetch(`${E}/api/auth/cli/poll`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({device_code:U.device_code}),signal:AbortSignal.any([v.signal,AbortSignal.timeout(15e3)])})}catch{x();continue}if(x(),J.status===410)throw new Error("\u767B\u5F55\u7801\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u53D1\u8D77\u767B\u5F55");let ne=await J.json().catch(()=>({status:"pending"}));if(x(),ne.status==="approved"&&ne.token){let ue={cloudUrl:E,token:ne.token};return await y(ue,x),x(),{token:ne.token,cloudUrl:E}}}throw new Error("\u767B\u5F55\u8D85\u65F6,\u8BF7\u91CD\u8BD5")}finally{c===v&&(c=null)}},readAccounts:s}}var Qn=["homeDir","appVersion","broadcast","accountBackendState","accountTransition","accountCommit","accountClear","writeCreds","onExternalCredsChange","setTokenRefresher","readCreds"],Yt=n=>Qn.every(e=>typeof n[e]=="function");function Jt(n){let e={ok:!1,error:"untrusted"},t={loggedIn:!1,error:"untrusted"},s=Kn(n),r=0,i=()=>{let a=n.readCreds();return vt(a.cloudUrl,a.token)},o=null;n.handle("auth:status",async a=>{if(!n.isTrustedSender(a))return t;let c=r,h=i(),{base:d}=await n.getCloud(),f=n.readCreds().token,u=f?await nt(d,f):null,y=await n.accountBackendState(),{base:v}=await n.getCloud(),x=n.readCreds(),E=vt(v,x.token)!==vt(d,f),U=vt(d,f);!E&&u?.status==="ok"&&u.user&&(o={key:U,user:u.user},s.rememberForsionAccount({...x,cloudUrl:d},u.user));let M=E?void 0:u?.status==="ok"?u.user:u?.status==="offline"&&o?.key===U?o.user:void 0;if(E)return{loggedIn:!!x.token,tokenValid:null,cloudUrl:v,accountId:Se(v,x.token),username:null,nickname:null,avatar:null,membershipTier:null,tokenSource:x.token?"tangu-login":null,backendState:y};if(u?.status==="expired"){await n.accountTransition(async()=>{if(c!==r||i()!==h)return;let B=()=>{if(c!==r||i()!==h)throw Gn};try{await n.accountClear(B,()=>{n.log("[auth] token \u5DF2\u5931\u6548(\u670D\u52A1\u7AEF 401/403),\u81EA\u52A8\u767B\u51FA"),++r,s.cancelForsionLogin(),s.forgetForsionAccount(n.readCreds()),o=null})}catch(q){if(q!==Gn)throw q}});let Y=n.readCreds();return{loggedIn:!!Y.token,tokenValid:null,cloudUrl:Y.cloudUrl||d,accountId:Se(Y.cloudUrl||d,Y.token),username:null,nickname:null,avatar:null,membershipTier:null,tokenSource:Y.token?"tangu-login":null,backendState:y}}return{loggedIn:!!f,tokenValid:u&&u.status==="ok"?!0:null,cloudUrl:d,accountId:Se(d,f),username:M?.username||null,nickname:M?.nickname||null,avatar:M?.avatar||null,membershipTier:M?.membershipTier||null,tokenSource:f?"tangu-login":null,backendState:y}}),n.handle("auth:accounts",a=>n.isTrustedSender(a)?s.forsionAccounts():[]),n.handle("auth:switchAccount",async(a,c)=>{if(!n.isTrustedSender(a))return e;if(typeof c!="string")throw new Error("Invalid account.");let h=++r;return s.cancelForsionLogin(),n.accountTransition(async()=>{let d=s.savedForsionAccount(c);return await n.accountCommit(d,()=>{if(h!==r)throw new Error("Account switch cancelled.")},()=>{s.rememberForsionAccount(d),o=null}),{ok:!0,cloudUrl:d.cloudUrl||""}})}),n.handle("auth:forsionLogin",async(a,c)=>{if(!n.isTrustedSender(a))return e;let h=++r;s.cancelForsionLogin();let{base:d}=await n.getCloud();if(h!==r)throw new Error("Sign-in cancelled.");let f=(c||d||"").trim();return{ok:!0,cloudUrl:(await s.forsionDeviceLogin(f,y=>n.broadcast("auth:device",y),(y,v)=>n.accountTransition(()=>n.accountCommit(y,()=>{if(v(),h!==r)throw new Error("Sign-in cancelled.")},()=>{s.rememberForsionAccount(y),o=null})))).cloudUrl}}),n.handle("auth:logout",async a=>n.isTrustedSender(a)?(++r,s.cancelForsionLogin(),n.accountTransition(async()=>{let{base:c}=await n.getCloud(),h=n.readCreds();return await n.accountClear(void 0,()=>{s.forgetForsionAccount(h),o=null,c&&h.token&&fetch(`${c}/api/auth/logout`,{method:"POST",headers:{Authorization:`Bearer ${h.token}`},signal:AbortSignal.timeout(5e3)}).catch(()=>{})}),{ok:!0}})):e),n.onExternalCredsChange(({previous:a,current:c})=>{++r,s.cancelForsionLogin(),a.token&&!c.token&&s.forgetForsionAccount(a),o=null,s.rememberForsionAccount(c)}),n.setTokenRefresher(async a=>{let c=r,h=i(),d=n.readCreds().token;if(!Jn(d))return;let{base:f}=await n.getCloud(),u=await Xn(f,d,a,`desktop/${n.appVersion()}`);if(!u){n.log("[auth] \u6ED1\u52A8\u7EED\u671F\u672A\u6210\u529F(\u79BB\u7EBF/\u8001\u7248\u672C server/\u8FD9\u679A\u5DF2\u5931\u6548),\u7EE7\u7EED\u7528\u65E7 token");return}c!==r||i()!==h||(s.rememberForsionAccount({cloudUrl:f,token:u}),n.writeCreds({cloudUrl:f,token:u}),n.log("[auth] \u767B\u5F55\u6001\u5DF2\u6ED1\u52A8\u7EED\u671F(\u6709\u6548\u671F\u91CD\u65B0\u8BA1\u6EE1 2 \u5468)"))}),n.log("[forsion-extend] account core registered")}var Gn=Symbol("stale-auth-intent");import{promises as Ke}from"node:fs";import je from"node:path";import{createHash as _s}from"node:crypto";var Xt=null;function Zn(n){Xt=n}function fe(){if(!Xt)throw new Error("amadeus sync env not set (registerAmadeus factory has not run)");return Xt}var he=()=>fe().accountId();function rt(n=he()){return n?_s("sha256").update(n).digest("hex"):"signed-out"}var ve=(n=he())=>fe().readConfig(n),Pe=(n,e=he())=>fe().writeConfig(n,e),We=(n,e=he())=>fe().updateConfig(n,e),$e=(n=he())=>fe().cloudVaultDir(n),Et=n=>fe().isManagedCloudVault(n);import{createHash as Ti}from"node:crypto";import{promises as te,existsSync as Ar}from"node:fs";import se from"node:path";import{EventEmitter as Qs}from"node:events";import{stat as Zs}from"node:fs";import{readdir as ei,stat as ti}from"node:fs/promises";import*as z from"node:path";import{lstat as er,readdir as ks,realpath as Cs,stat as xs}from"node:fs/promises";import{join as Ts,resolve as Rs,sep as tr}from"node:path";import{Readable as Is}from"node:stream";var me={FILE_TYPE:"files",DIR_TYPE:"directories",FILE_DIR_TYPE:"files_directories",EVERYTHING_TYPE:"all"},qe={root:".",fileFilter:n=>!0,directoryFilter:n=>!0,type:me.FILE_TYPE,lstat:!1,depth:2147483648,alwaysStat:!1,highWaterMark:256};Object.freeze(qe);var ir="READDIRP_RECURSIVE_ERROR",Ps=new Set(["ENOENT","EPERM","EACCES","ELOOP",ir]),nr=[me.DIR_TYPE,me.EVERYTHING_TYPE,me.FILE_DIR_TYPE,me.FILE_TYPE],As=new Set([me.DIR_TYPE,me.EVERYTHING_TYPE,me.FILE_DIR_TYPE]),$s=new Set([me.EVERYTHING_TYPE,me.FILE_DIR_TYPE,me.FILE_TYPE]),Ds=n=>Ps.has(n.code),Ms=process.platform==="win32",rr=n=>!0,sr=n=>{if(n===void 0)return rr;if(typeof n=="function")return n;if(typeof n=="string"){let e=n.trim();return t=>t.basename===e}if(Array.isArray(n)){let e=n.map(t=>t.trim());return t=>e.some(s=>t.basename===s)}return rr},Kt=class extends Is{parents;reading;parent;_stat;_maxDepth;_wantsDir;_wantsFile;_wantsEverything;_root;_isDirent;_statsProp;_rdOptions;_fileFilter;_directoryFilter;_relStart;constructor(e={}){super({objectMode:!0,autoDestroy:!0,highWaterMark:e.highWaterMark??qe.highWaterMark});let t={...qe,...e},s=t.root??qe.root,r=t.type??qe.type;this._fileFilter=sr(t.fileFilter),this._directoryFilter=sr(t.directoryFilter);let i=t.lstat?er:xs;Ms?this._stat=a=>i(a,{bigint:!0}):this._stat=i,this._maxDepth=t.depth!=null&&Number.isSafeInteger(t.depth)?t.depth:qe.depth,this._wantsDir=As.has(r),this._wantsFile=$s.has(r),this._wantsEverything=r===me.EVERYTHING_TYPE,this._root=Rs(s),this._relStart=this._root.endsWith(tr)?this._root.length:this._root.length+1,this._isDirent=!t.alwaysStat,this._statsProp=this._isDirent?"dirent":"stats",this._rdOptions={encoding:"utf8",withFileTypes:this._isDirent};let o={path:this._root,depth:1};o.pending=this._exploreDir(this._root,1),this.parents=[o],this.reading=!1,this.parent=void 0}async _read(e){if(!this.reading){this.reading=!0;try{for(;!this.destroyed&&e>0;){let t=this.parent,s=t&&t.files;if(s&&s.length>0){let{path:r,depth:i}=t,o=s.splice(0,e).map(c=>this._formatEntry(c,r)),a=this._isDirent?o:await Promise.all(o);for(let c of a){if(!c)continue;if(this.destroyed)return;let h=this._getEntryType(c);typeof h!="string"&&(h=await h),h==="directory"&&this._directoryFilter(c)?(i<=this._maxDepth&&this.parents.push({path:c.fullPath,depth:i+1}),this._wantsDir&&(this.push(c),e--)):(h==="file"||this._includeAsFile(c))&&this._fileFilter(c)&&this._wantsFile&&(this.push(c),e--)}}else{let r=this.parents.pop();if(!r){this.push(null);break}let i=r.pending??this._exploreDir(r.path,r.depth),o=this.parents[this.parents.length-1];if(o&&!o.pending&&(o.pending=this._exploreDir(o.path,o.depth)),this.parent=await i,this.destroyed)return}}}catch(t){this.destroy(t)}finally{this.reading=!1}}}async _exploreDir(e,t){let s;try{s=await ks(e,this._rdOptions)}catch(r){this._onError(r)}return{files:s,depth:t,path:e}}_formatEntry(e,t){let s=this._isDirent?e.name:e,r=Ts(t,s),i={path:r.slice(this._relStart),fullPath:r,basename:s};return this._isDirent?(i.dirent=e,i):this._stat(r).then(o=>(i.stats=o,i),o=>{this._onError(o)})}_onError(e){Ds(e)&&!this.destroyed?this.emit("warn",e):this.destroy(e)}_getEntryType(e){if(!e||!(this._statsProp in e))return"";let t=e[this._statsProp];return t.isFile()?"file":t.isDirectory()?"directory":t.isSymbolicLink()?this._getSymlinkEntryType(e):""}async _getSymlinkEntryType(e){let t=e.fullPath;try{let s=await Cs(t),r=await er(s);if(r.isFile())return"file";if(r.isDirectory()){let i=s.length;if(t.startsWith(s)&&t[i]===tr){let o=new Error(`Circular symlink detected: "${t}" points to "${s}"`);return o.code=ir,this._onError(o),""}return"directory"}}catch(s){this._onError(s)}return""}_includeAsFile(e){let t=e&&e[this._statsProp];return t&&this._wantsEverything&&!t.isDirectory()}};function or(n,e={}){let t=e.entryType||e.type;if(t==="both"&&(t=me.FILE_DIR_TYPE),n){if(typeof n!="string")throw new TypeError("readdirp: root argument must be a string. Usage: readdirp(root, options)");if(t&&!nr.includes(t))throw new Error(`readdirp: Invalid type passed. Use one of ${nr.join(", ")}`)}else throw new Error("readdirp: root argument is required. Usage: readdirp(root, options)");let s={...e,root:n};return t&&(s.type=t),new Kt(s)}import{watch as Ns,unwatchFile as ar,watchFile as Us}from"node:fs";import{realpath as Qt,lstat as Fs,open as Os,stat as cr}from"node:fs/promises";import{type as js}from"node:os";import*as K from"node:path";var Ls="data",tn="end",ur="close",Tt=()=>{};var Rt=process.platform,nn=Rt==="win32",Hs=Rt==="darwin",zs=Rt==="linux",Ws=Rt==="freebsd",dr=js()==="OS400",ee={ALL:"all",READY:"ready",ADD:"add",CHANGE:"change",ADD_DIR:"addDir",UNLINK:"unlink",UNLINK_DIR:"unlinkDir",RAW:"raw",ERROR:"error"},Ee=ee,qs="watch",Bs={lstat:Fs,stat:cr},Oe="listeners",_t="errHandlers",Be="rawEmitters",Vs=[Oe,_t,Be],Gs=new Set(["3dm","3ds","3g2","3gp","7z","a","aac","adp","afdesign","afphoto","afpub","ai","aif","aiff","alz","ape","apk","appimage","ar","arj","asf","au","avi","bak","baml","bh","bin","bk","bmp","btif","bz2","bzip2","cab","caf","cgm","class","cmx","cpio","cr2","cur","dat","dcm","deb","dex","djvu","dll","dmg","dng","doc","docm","docx","dot","dotm","dra","DS_Store","dsk","dts","dtshd","dvb","dwg","dxf","ecelp4800","ecelp7470","ecelp9600","egg","eol","eot","epub","exe","f4v","fbs","fh","fla","flac","flatpak","fli","flv","fpx","fst","fvt","g3","gh","gif","graffle","gz","gzip","h261","h263","h264","icns","ico","ief","img","ipa","iso","jar","jpeg","jpg","jpgv","jpm","jxr","key","ktx","lha","lib","lvp","lz","lzh","lzma","lzo","m3u","m4a","m4v","mar","mdi","mht","mid","midi","mj2","mka","mkv","mmr","mng","mobi","mov","movie","mp3","mp4","mp4a","mpeg","mpg","mpga","mxu","nef","npx","numbers","nupkg","o","odp","ods","odt","oga","ogg","ogv","otf","ott","pages","pbm","pcx","pdb","pdf","pea","pgm","pic","png","pnm","pot","potm","potx","ppa","ppam","ppm","pps","ppsm","ppsx","ppt","pptm","pptx","psd","pya","pyc","pyo","pyv","qt","rar","ras","raw","resources","rgb","rip","rlc","rmf","rmvb","rpm","rtf","rz","s3m","s7z","scpt","sgi","shar","snap","sil","sketch","slk","smv","snk","so","stl","suo","sub","swf","tar","tbz","tbz2","tga","tgz","thmx","tif","tiff","tlz","ttc","ttf","txz","udf","uvh","uvi","uvm","uvp","uvs","uvu","viv","vob","war","wav","wax","wbmp","wdp","weba","webm","webp","whl","wim","wm","wma","wmv","wmx","woff","woff2","wrm","wvx","xbm","xif","xla","xlam","xls","xlsb","xlsm","xlsx","xlt","xltm","xltx","xm","xmind","xpi","xpm","xwd","xz","z","zip","zipx"]),Ys=n=>Gs.has(K.extname(n).slice(1).toLowerCase()),en=(n,e)=>{n instanceof Set?n.forEach(e):e(n)},st=(n,e,t)=>{let s=n[e];s instanceof Set||(n[e]=s=new Set([s])),s.add(t)},Js=n=>e=>{let t=n[e];t instanceof Set?t.clear():delete n[e]},it=(n,e,t)=>{let s=n[e];s instanceof Set?s.delete(t):s===t&&delete n[e]},fr=n=>n instanceof Set?n.size===0:!n,kt=new Map;function lr(n,e,t,s,r){let i=(o,a)=>{t(n),r(o,a,{watchedPath:n}),a&&n!==a&&Ct(K.resolve(n,a),Oe,K.join(n,a))};try{return Ns(n,{persistent:e.persistent},i)}catch(o){s(o);return}}var Ct=(n,e,t,s,r)=>{let i=kt.get(n);i&&en(i[e],o=>{o(t,s,r)})},Xs=(n,e,t,s)=>{let{listener:r,errHandler:i,rawEmitter:o}=s,a=kt.get(e),c;if(!t.persistent)return c=lr(n,t,r,i,o),c?c.close.bind(c):void 0;if(a)st(a,Oe,r),st(a,_t,i),st(a,Be,o);else{if(c=lr(n,t,Ct.bind(null,e,Oe),i,Ct.bind(null,e,Be)),!c)return;c.on(Ee.ERROR,async h=>{let d=Ct.bind(null,e,_t);if(a&&(a.watcherUnusable=!0),nn&&h.code==="EPERM")try{await(await Os(n,"r")).close(),d(h)}catch{}else d(h)}),a={listeners:r,errHandlers:i,rawEmitters:o,watcher:c},kt.set(e,a)}return()=>{it(a,Oe,r),it(a,_t,i),it(a,Be,o),fr(a.listeners)&&(a.watcher.close(),kt.delete(e),Vs.forEach(Js(a)),a.watcher=void 0,Object.freeze(a))}},Zt=new Map,Ks=(n,e,t,s)=>{let{listener:r,rawEmitter:i}=s,o=Zt.get(e),a=o&&o.options;return a&&(a.persistent<t.persistent||a.interval>t.interval)&&(ar(e),o=void 0),o?(st(o,Oe,r),st(o,Be,i)):(o={listeners:r,rawEmitters:i,options:t,watcher:Us(e,t,(c,h)=>{en(o.rawEmitters,f=>{f(Ee.CHANGE,e,{curr:c,prev:h})});let d=c.mtimeMs;(c.size!==h.size||d>h.mtimeMs||d===0)&&en(o.listeners,f=>f(n,c))})},Zt.set(e,o)),()=>{it(o,Oe,r),it(o,Be,i),fr(o.listeners)&&(Zt.delete(e),ar(e),o.options=o.watcher=void 0,Object.freeze(o))}},xt=class{fsw;_boundHandleError;constructor(e){this.fsw=e,this._boundHandleError=t=>e._handleError(t)}_watchWithNodeFs(e,t){let s=this.fsw.options,r=K.dirname(e),i=K.basename(e);this.fsw._getWatchedDir(r).add(i);let a=K.resolve(e),c={persistent:s.persistent};t||(t=Tt);let h;if(s.usePolling){let d=s.interval!==s.binaryInterval;c.interval=d&&Ys(i)?s.binaryInterval:s.interval,h=Ks(e,a,c,{listener:t,rawEmitter:this.fsw._emitRaw})}else h=Xs(e,a,c,{listener:t,errHandler:this._boundHandleError,rawEmitter:this.fsw._emitRaw});return h}_handleFile(e,t,s){if(this.fsw.closed)return;let r=K.dirname(e),i=K.basename(e),o=this.fsw._getWatchedDir(r),a=t;if(o.has(i))return;let c=async(d,f)=>{if(this.fsw._throttle(qs,e,5)){if(!f||f.mtimeMs===0)try{let u=await cr(e);if(this.fsw.closed)return;let y=u.atimeMs,v=u.mtimeMs;if((!y||y<=v||v!==a.mtimeMs)&&this.fsw._emit(Ee.CHANGE,e,u),(Hs||zs||Ws)&&a.ino!==u.ino){this.fsw._closeFile(d),a=u;let x=this._watchWithNodeFs(e,c);x&&this.fsw._addPathCloser(d,x)}else a=u}catch{this.fsw._remove(r,i)}else if(o.has(i)){let u=f.atimeMs,y=f.mtimeMs;(!u||u<=y||y!==a.mtimeMs)&&this.fsw._emit(Ee.CHANGE,e,f),a=f}}},h=this._watchWithNodeFs(e,c);if(!(s&&this.fsw.options.ignoreInitial)&&this.fsw._isntIgnored(e)){if(!this.fsw._throttle(Ee.ADD,e,0))return;this.fsw._emit(Ee.ADD,e,t)}return h}async _handleSymlink(e,t,s,r){if(this.fsw.closed)return;let i=e.fullPath,o=this.fsw._getWatchedDir(t);if(!this.fsw.options.followSymlinks){this.fsw._incrReadyCount();let a;try{a=await Qt(s)}catch{return this.fsw._emitReady(),!0}return this.fsw.closed?void 0:(o.has(r)?this.fsw._symlinkPaths.get(i)!==a&&(this.fsw._symlinkPaths.set(i,a),this.fsw._emit(Ee.CHANGE,s,e.stats)):(o.add(r),this.fsw._symlinkPaths.set(i,a),this.fsw._emit(Ee.ADD,s,e.stats)),this.fsw._emitReady(),!0)}if(this.fsw._symlinkPaths.has(i))return!0;this.fsw._symlinkPaths.set(i,!0)}_handleRead(e,t,s,r,i,o,a){e=K.join(e,"");let c=r?`${e}:${r}`:e;if(a=this.fsw._throttle("readdir",c,1e3),!a)return;let h=this.fsw._getWatchedDir(s.path),d=new Set,f=this.fsw._readdirp(e,{fileFilter:u=>s.filterPath(u),directoryFilter:u=>s.filterDir(u)});if(f)return f.on(Ls,async u=>{if(this.fsw.closed){f=void 0;return}let y=u.path,v=K.join(e,y);if(d.add(y),!(u.stats.isSymbolicLink()&&await this._handleSymlink(u,e,v,y))){if(this.fsw.closed){f=void 0;return}(y===r||!r&&!h.has(y))&&(this.fsw._incrReadyCount(),v=K.join(i,K.relative(i,v)),this._addToNodeFs(v,t,s,o+1))}}).on(Ee.ERROR,this._boundHandleError),new Promise((u,y)=>{if(!f)return y();f.once(tn,()=>{if(this.fsw.closed){f=void 0;return}let v=a?a.clear():!1;u(void 0),h.getChildren().filter(x=>x!==e&&!d.has(x)).forEach(x=>{this.fsw._remove(e,x)}),f=void 0,v&&this._handleRead(e,!1,s,r,i,o,a)})})}async _handleDir(e,t,s,r,i,o,a){let c=this.fsw._getWatchedDir(K.dirname(e)),h=c.has(K.basename(e));!(s&&this.fsw.options.ignoreInitial)&&!i&&!h&&this.fsw._emit(Ee.ADD_DIR,e,t),c.add(K.basename(e)),this.fsw._getWatchedDir(e);let d,f,u=this.fsw.options.depth;if((u==null||r<=u)&&!this.fsw._symlinkPaths.has(a)){if(!i&&(await this._handleRead(e,s,o,i,e,r,d),this.fsw.closed))return;f=this._watchWithNodeFs(e,(y,v)=>{v&&v.mtimeMs===0||this._handleRead(y,!1,o,i,e,r,d)})}return f}async _addToNodeFs(e,t,s,r,i){let o=this.fsw._emitReady;if(this.fsw._isIgnored(e)||this.fsw.closed)return o(),!1;let a=this.fsw._getWatchHelpers(e);s&&(a.filterPath=c=>s.filterPath(c),a.filterDir=c=>s.filterDir(c));try{let c=await Bs[a.statMethod](a.watchPath);if(this.fsw.closed)return;if(this.fsw._isIgnored(a.watchPath,c))return o(),!1;let h=this.fsw.options.followSymlinks,d;if(c.isDirectory()){let f=K.resolve(e),u=h?await Qt(e):e;if(this.fsw.closed||(d=await this._handleDir(a.watchPath,c,t,r,i,a,u),this.fsw.closed))return;f!==u&&u!==void 0&&this.fsw._symlinkPaths.set(f,u)}else if(c.isSymbolicLink()){let f=h?await Qt(e):e;if(this.fsw.closed)return;let u=K.dirname(a.watchPath);if(this.fsw._getWatchedDir(u).add(a.watchPath),this.fsw._emit(Ee.ADD,a.watchPath,c),d=await this._handleDir(u,c,t,r,e,a,f),this.fsw.closed)return;f!==void 0&&this.fsw._symlinkPaths.set(K.resolve(e),f)}else d=this._handleFile(a.watchPath,c,t);return o(),d&&this.fsw._addPathCloser(e,d),!1}catch(c){if(this.fsw._handleError(c))return o(),e}}};var rn="/",ni="//",yr=".",ri="..",si="string",ii=/\\/g,wr=/\/\//g,oi=/\..*\.(sw[px])$|~$|\.subl.*\.tmp/,ai=/^\.[/\\]/;function It(n){return Array.isArray(n)?n:[n]}var sn=n=>typeof n=="object"&&n!==null&&!(n instanceof RegExp);function li(n){return typeof n=="function"?n:typeof n=="string"?e=>n===e:n instanceof RegExp?e=>n.test(e):typeof n=="object"&&n!==null?e=>{if(n.path===e)return!0;if(n.recursive){let t=z.relative(n.path,e);return t?!t.startsWith("..")&&!z.isAbsolute(t):!1}return!1}:()=>!1}function ci(n){if(typeof n!="string")throw new Error("string expected");n=z.normalize(n),n=n.replace(/\\/g,"/");let e=!1;return n.startsWith("//")&&(e=!0),n=n.replace(wr,"/"),e&&(n="/"+n),n}function hr(n,e,t){let s=ci(e);for(let r=0;r<n.length;r++){let i=n[r];if(i(s,t))return!0}return!1}function ui(n,e){if(n==null)throw new TypeError("anymatch: specify first argument");let s=It(n).map(r=>li(r));return e==null?(r,i)=>hr(s,r,i):hr(s,e)}var pr=n=>{let e=It(n).flat();if(!e.every(t=>typeof t===si))throw new TypeError(`Non-string provided as watch path: ${e}`);return e.map(br)},mr=n=>{let e=n.replace(ii,rn),t=!1;return e.startsWith(ni)&&(t=!0),e=e.replace(wr,rn),t&&(e=rn+e),e},br=n=>mr(z.normalize(mr(n))),gr=(n="")=>e=>typeof e=="string"?br(z.isAbsolute(e)?e:z.join(n,e)):e,di=(n,e)=>z.isAbsolute(n)?n:z.join(e,n),fi=Object.freeze(new Set),on=class{path;_removeWatcher;items;constructor(e,t){this.path=e,this._removeWatcher=t,this.items=new Set}add(e){let{items:t}=this;t&&e!==yr&&e!==ri&&t.add(e)}async remove(e){let{items:t}=this;if(!t||(t.delete(e),t.size>0))return;let s=this.path;try{await ei(s)}catch{this._removeWatcher&&this._removeWatcher(z.dirname(s),z.basename(s))}}has(e){let{items:t}=this;if(t)return t.has(e)}getChildren(){let{items:e}=this;return e?[...e.values()]:[]}dispose(){this.items.clear(),this.path="",this._removeWatcher=Tt,this.items=fi,Object.freeze(this)}},hi="stat",pi="lstat",an=class{fsw;path;watchPath;fullWatchPath;dirParts;followSymlinks;statMethod;constructor(e,t,s){this.fsw=s;let r=e;this.path=e=e.replace(ai,""),this.watchPath=r,this.fullWatchPath=z.resolve(r),this.dirParts=[],this.dirParts.forEach(i=>{i.length>1&&i.pop()}),this.followSymlinks=t,this.statMethod=t?hi:pi}entryPath(e){return z.join(this.watchPath,z.relative(this.watchPath,e.fullPath))}filterPath(e){let{stats:t}=e;if(t&&t.isSymbolicLink())return this.filterDir(e);let s=this.entryPath(e);return this.fsw._isntIgnored(s,t)&&this.fsw._hasReadPermissions(t)}filterDir(e){return this.fsw._isntIgnored(this.entryPath(e),e.stats)}},Pt=class extends Qs{closed;options;_closers;_ignoredPaths;_throttled;_streams;_symlinkPaths;_watched;_pendingWrites;_pendingUnlinks;_readyCount;_emitReady;_closePromise;_userIgnored;_readyEmitted;_emitRaw;_boundRemove;_nodeFsHandler;constructor(e={}){super(),this.closed=!1,this._closers=new Map,this._ignoredPaths=new Set,this._throttled=new Map,this._streams=new Set,this._symlinkPaths=new Map,this._watched=new Map,this._pendingWrites=new Map,this._pendingUnlinks=new Map,this._readyCount=0,this._readyEmitted=!1;let t=e.awaitWriteFinish,s={stabilityThreshold:2e3,pollInterval:100},r={persistent:!0,ignoreInitial:!1,ignorePermissionErrors:!1,interval:100,binaryInterval:300,followSymlinks:!0,usePolling:!1,atomic:!0,...e,ignored:e.ignored?It(e.ignored):It([]),awaitWriteFinish:t===!0?s:typeof t=="object"?{...s,...t}:!1};dr&&(r.usePolling=!0),r.atomic===void 0&&(r.atomic=!r.usePolling);let i=process.env.CHOKIDAR_USEPOLLING;if(i!==void 0){let c=i.toLowerCase();c==="false"||c==="0"?r.usePolling=!1:c==="true"||c==="1"?r.usePolling=!0:r.usePolling=!!c}let o=process.env.CHOKIDAR_INTERVAL;o&&(r.interval=Number.parseInt(o,10));let a=0;this._emitReady=()=>{a++,a>=this._readyCount&&(this._emitReady=Tt,this._readyEmitted=!0,process.nextTick(()=>this.emit(ee.READY)))},this._emitRaw=(...c)=>this.emit(ee.RAW,...c),this._boundRemove=this._remove.bind(this),this.options=r,this._nodeFsHandler=new xt(this),Object.freeze(r)}_addIgnoredPath(e){if(sn(e)){for(let t of this._ignoredPaths)if(sn(t)&&t.path===e.path&&t.recursive===e.recursive)return}this._ignoredPaths.add(e)}_removeIgnoredPath(e){if(this._ignoredPaths.delete(e),typeof e=="string")for(let t of this._ignoredPaths)sn(t)&&t.path===e&&this._ignoredPaths.delete(t)}add(e,t,s){let{cwd:r}=this.options;this.closed=!1,this._closePromise=void 0;let i=pr(e);return r&&(i=i.map(o=>di(o,r))),i.forEach(o=>{this._removeIgnoredPath(o)}),this._userIgnored=void 0,this._readyCount||(this._readyCount=0),this._readyCount+=i.length,Promise.all(i.map(async o=>{let a=await this._nodeFsHandler._addToNodeFs(o,!s,void 0,0,t);return a&&this._emitReady(),a})).then(o=>{this.closed||o.forEach(a=>{a&&this.add(z.dirname(a),z.basename(t||a))})}),this}unwatch(e){if(this.closed)return this;let t=pr(e),{cwd:s}=this.options;return t.forEach(r=>{!z.isAbsolute(r)&&!this._closers.has(r)&&(s&&(r=z.join(s,r)),r=z.resolve(r)),this._closePath(r),this._addIgnoredPath(r),this._watched.has(r)&&this._addIgnoredPath({path:r,recursive:!0}),this._userIgnored=void 0}),this}close(){if(this._closePromise)return this._closePromise;this.closed=!0,this.removeAllListeners();let e=[];return this._closers.forEach(t=>t.forEach(s=>{let r=s();r instanceof Promise&&e.push(r)})),this._streams.forEach(t=>t.destroy()),this._userIgnored=void 0,this._readyCount=0,this._readyEmitted=!1,this._watched.forEach(t=>t.dispose()),this._closers.clear(),this._watched.clear(),this._streams.clear(),this._symlinkPaths.clear(),this._throttled.clear(),this._closePromise=e.length?Promise.all(e).then(()=>{}):Promise.resolve(),this._closePromise}getWatched(){let e={};return this._watched.forEach((t,s)=>{let i=(this.options.cwd?z.relative(this.options.cwd,s):s)||yr;e[i]=t.getChildren().sort()}),e}emitWithAll(e,t){this.emit(e,...t),e!==ee.ERROR&&this.emit(ee.ALL,e,...t)}async _emit(e,t,s){if(this.closed)return;let r=this.options;nn&&(t=z.normalize(t)),r.cwd&&(t=z.relative(r.cwd,t));let i=[t];s!=null&&i.push(s);let o=r.awaitWriteFinish,a;if(o&&(a=this._pendingWrites.get(t)))return a.lastChange=new Date,this;if(r.atomic){if(e===ee.UNLINK)return this._pendingUnlinks.set(t,[e,...i]),setTimeout(()=>{this._pendingUnlinks.forEach((c,h)=>{this.emit(...c),this.emit(ee.ALL,...c),this._pendingUnlinks.delete(h)})},typeof r.atomic=="number"?r.atomic:100),this;e===ee.ADD&&this._pendingUnlinks.has(t)&&(e=ee.CHANGE,this._pendingUnlinks.delete(t))}if(o&&(e===ee.ADD||e===ee.CHANGE)&&this._readyEmitted){let c=(h,d)=>{h?(e=ee.ERROR,i[0]=h,this.emitWithAll(e,i)):d&&(i.length>1?i[1]=d:i.push(d),this.emitWithAll(e,i))};return this._awaitWriteFinish(t,o.stabilityThreshold,e,c),this}if(e===ee.CHANGE&&!this._throttle(ee.CHANGE,t,50))return this;if(r.alwaysStat&&s===void 0&&(e===ee.ADD||e===ee.ADD_DIR||e===ee.CHANGE)){let c=r.cwd?z.join(r.cwd,t):t,h;try{h=await ti(c)}catch{}if(!h||this.closed)return;i.push(h)}return this.emitWithAll(e,i),this}_handleError(e){let t=e&&e.code;return e&&t!=="ENOENT"&&t!=="ENOTDIR"&&(!this.options.ignorePermissionErrors||t!=="EPERM"&&t!=="EACCES")&&this.emit(ee.ERROR,e),e||this.closed}_throttle(e,t,s){this._throttled.has(e)||this._throttled.set(e,new Map);let r=this._throttled.get(e);if(!r)throw new Error("invalid throttle");let i=r.get(t);if(i)return i.count++,!1;let o,a=()=>{let h=r.get(t),d=h?h.count:0;return r.delete(t),clearTimeout(o),h&&clearTimeout(h.timeoutObject),d};o=setTimeout(a,s);let c={timeoutObject:o,clear:a,count:0};return r.set(t,c),c}_incrReadyCount(){return this._readyCount++}_awaitWriteFinish(e,t,s,r){let i=this.options.awaitWriteFinish;if(typeof i!="object")return;let o=i.pollInterval,a,c=e;this.options.cwd&&!z.isAbsolute(e)&&(c=z.join(this.options.cwd,e));let h=new Date,d=this._pendingWrites;function f(u){Zs(c,(y,v)=>{if(y||!d.has(e)){y&&y.code!=="ENOENT"&&r(y);return}let x=Number(new Date);u&&v.size!==u.size&&(d.get(e).lastChange=x);let E=d.get(e);x-E.lastChange>=t?(d.delete(e),r(void 0,v)):a=setTimeout(f,o,v)})}d.has(e)||(d.set(e,{lastChange:h,cancelWait:()=>(d.delete(e),clearTimeout(a),s)}),a=setTimeout(f,o))}_isIgnored(e,t){if(this.options.atomic&&oi.test(e))return!0;if(!this._userIgnored){let{cwd:s}=this.options,i=(this.options.ignored||[]).map(gr(s)),a=[...[...this._ignoredPaths].map(gr(s)),...i];this._userIgnored=ui(a,void 0)}return this._userIgnored(e,t)}_isntIgnored(e,t){return!this._isIgnored(e,t)}_getWatchHelpers(e){return new an(e,this.options.followSymlinks,this)}_getWatchedDir(e){let t=z.resolve(e);return this._watched.has(t)||this._watched.set(t,new on(t,this._boundRemove)),this._watched.get(t)}_hasReadPermissions(e){return this.options.ignorePermissionErrors?!0:!!(Number(e.mode)&256)}_remove(e,t,s){let r=z.join(e,t),i=z.resolve(r);if(s=s??(this._watched.has(r)||this._watched.has(i)),!this._throttle("remove",r,100))return;!s&&this._watched.size===1&&this.add(e,t,!0),this._getWatchedDir(r).getChildren().forEach(u=>this._remove(r,u));let c=this._getWatchedDir(e),h=c.has(t);c.remove(t),this._symlinkPaths.has(i)&&this._symlinkPaths.delete(i);let d=r;if(this.options.cwd&&(d=z.relative(this.options.cwd,r)),this.options.awaitWriteFinish&&this._pendingWrites.has(d)&&this._pendingWrites.get(d).cancelWait()===ee.ADD)return;this._watched.delete(r),this._watched.delete(i);let f=s?ee.UNLINK_DIR:ee.UNLINK;h&&!this._isIgnored(r)&&this._emit(f,r),this._closePath(r)}_closePath(e){this._closeFile(e);let t=z.dirname(e);this._getWatchedDir(t).remove(z.basename(e))}_closeFile(e){let t=this._closers.get(e);t&&(t.forEach(s=>s()),this._closers.delete(e))}_addPathCloser(e,t){if(!t)return;let s=this._closers.get(e);s||(s=[],this._closers.set(e,s)),s.push(t)}_readdirp(e,t){if(this.closed)return;let s={type:ee.ALL,alwaysStat:!0,lstat:!0,...t,depth:0},r=or(e,s);return this._streams.add(r),r.once(ur,()=>{r=void 0}),r.once(tn,()=>{r&&(this._streams.delete(r),r=void 0)}),r}};function mi(n,e={}){let t=new Pt(e);return t.add(n),t}var Sr={watch:mi,FSWatcher:Pt};function gi(n,e){let t=Object.create(null);for(let i=0;i<e.length;i++){let o=e[i];t[o]?t[o].push(i):t[o]=[i]}let r=[{buffer1index:-1,buffer2index:-1,chain:null}];for(let i=0;i<n.length;i++){let o=n[i],a=t[o]||[],c=0,h=r[0];for(let d of a){let f;for(f=c;f<r.length&&!(r[f].buffer2index<d&&(f===r.length-1||r[f+1].buffer2index>d));f++);if(f<r.length){let u={buffer1index:i,buffer2index:d,chain:r[f]};if(c===r.length?r.push(h):r[c]=h,c=f+1,h=u,c===r.length)break}}r[c]=h}return r[r.length-1]}function vr(n,e){let t=gi(n,e),s=[],r=n.length,i=e.length;for(let o=t;o!==null;o=o.chain){let a=r-o.buffer1index-1,c=i-o.buffer2index-1;r=o.buffer1index,i=o.buffer2index,(a||c)&&s.push({buffer1:[r+1,a],buffer1Content:n.slice(r+1,r+1+a),buffer2:[i+1,c],buffer2Content:e.slice(i+1,i+1+c)})}return s.reverse(),s}function yi(n,e,t){let s=[];function r(c,h){s.push({ab:h,oStart:c.buffer1[0],oLength:c.buffer1[1],abStart:c.buffer2[0],abLength:c.buffer2[1]})}vr(e,n).forEach(c=>r(c,"a")),vr(e,t).forEach(c=>r(c,"b")),s.sort((c,h)=>c.oStart-h.oStart);let i=[],o=0;function a(c){c>o&&(i.push({stable:!0,buffer:"o",bufferStart:o,bufferLength:c-o,bufferContent:e.slice(o,c)}),o=c)}for(;s.length;){let c=s.shift(),h=c.oStart,d=c.oStart+c.oLength,f=[c];for(a(h);s.length;){let u=s[0],y=u.oStart;if(y>d)break;d=Math.max(d,y+u.oLength),f.push(s.shift())}if(f.length===1){if(c.abLength>0){let u=c.ab==="a"?n:t;i.push({stable:!0,buffer:c.ab,bufferStart:c.abStart,bufferLength:c.abLength,bufferContent:u.slice(c.abStart,c.abStart+c.abLength)})}}else{let u={a:[n.length,-1,e.length,-1],b:[t.length,-1,e.length,-1]};for(;f.length;){c=f.shift();let M=c.oStart,Y=M+c.oLength,B=c.abStart,q=B+c.abLength,Q=u[c.ab];Q[0]=Math.min(B,Q[0]),Q[1]=Math.max(q,Q[1]),Q[2]=Math.min(M,Q[2]),Q[3]=Math.max(Y,Q[3])}let y=u.a[0]+(h-u.a[2]),v=u.a[1]+(d-u.a[3]),x=u.b[0]+(h-u.b[2]),E=u.b[1]+(d-u.b[3]),U={stable:!1,aStart:y,aLength:v-y,aContent:n.slice(y,v),oStart:h,oLength:d-h,oContent:e.slice(h,d),bStart:x,bLength:E-x,bContent:t.slice(x,E)};i.push(U)}o=d}return a(e.length),i}function Er(n,e,t,s){s=Object.assign({excludeFalseConflicts:!0,stringSeparator:/\s+/},s),typeof n=="string"&&(n=n.split(s.stringSeparator)),typeof e=="string"&&(e=e.split(s.stringSeparator)),typeof t=="string"&&(t=t.split(s.stringSeparator));let i=[],o=yi(n,e,t),a=[];function c(){a.length&&i.push({ok:a}),a=[]}function h(d,f){if(d.length!==f.length)return!1;for(let u=0;u<d.length;u++)if(d[u]!==f[u])return!1;return!0}return o.forEach(d=>{d.stable?a.push(...d.bufferContent):s.excludeFalseConflicts&&h(d.aContent,d.bContent)?a.push(...d.aContent):(c(),i.push({conflict:{a:d.aContent,aIndex:d.aStart,o:d.oContent,oIndex:d.oStart,b:d.bContent,bIndex:d.bStart}}))}),c(),i}function At(n,e){let t=n.lastIndexOf("/"),s=t<0?"":n.slice(0,t+1),r=t<0?n:n.slice(t+1),i=r.lastIndexOf("."),o=i>0?r.slice(0,i):r,a=i>0?r.slice(i):"",c=d=>String(d).padStart(2,"0"),h=`${e.getFullYear()}-${c(e.getMonth()+1)}-${c(e.getDate())} ${c(e.getHours())}${c(e.getMinutes())}`;return`${s}${o} (conflict ${h})${a}`}function wi(n,e){if(e<2)return n;let t=n.lastIndexOf("."),s=t>n.lastIndexOf("/")&&t>n.lastIndexOf(")"),r=s?n.slice(0,t):n,i=s?n.slice(t):"";return`${r}-${e}${i}`}function bi(n){let e=3735928559,t=1103547991;for(let r=0;r<n.length;r++){let i=n.charCodeAt(r);e=Math.imul(e^i,2654435761),t=Math.imul(t^i,1597334677)}e=Math.imul(e^e>>>16,2246822507)^Math.imul(t^t>>>13,3266489909),t=Math.imul(t^t>>>16,2246822507)^Math.imul(e^e>>>13,3266489909);let s=4294967296*(2097151&t)+(e>>>0);return`${n.length.toString(36)}-${s.toString(36)}`}function $t(n,e,t){if(n===null&&e===null&&t===null)return{kind:"none"};if(t===null)return n===null?e?{kind:"dropShadow"}:{kind:"none"}:e?n===e.hash?{kind:"deleteLocal"}:{kind:"pushCreate"}:{kind:"pushCreate"};if(n===null)return e?t.seq===e.seq?{kind:"pushDelete"}:{kind:"pull"}:{kind:"pull"};if(!e)return n===t.hash?{kind:"adopt"}:{kind:"conflict"};let s=n!==e.hash,r=t.seq!==e.seq;return!s&&!r?{kind:"none"}:s?r?n===t.hash?{kind:"adopt"}:t.hash===e.hash?{kind:"push",baseSeq:t.seq}:{kind:"conflict"}:{kind:"push",baseSeq:e.seq}:{kind:"pull"}}function _r(n,e,t){let s=Er(n.split(`
193
+ `,Bs=t=>({transpile:(e,n,r)=>t.transpileForServe(e,n,r),mimeOf:e=>t.mimeOf(e)});function Qt(t){let e=t;return typeof e.projectsRoot=="function"&&typeof e.transpileForServe=="function"&&typeof e.mimeOf=="function"&&typeof e.setPreviewHooks=="function"}function en(t){t.setPreviewHooks({sdkJs:sr,proxy:rr(()=>t.getCloud())}),t.handle("connect:meta",(e,n)=>typeof n=="string"&&n?tr(n):{}),t.handle("connect:list",async()=>{let e=await t.getCloud();if(!e.token)return{ok:!1,code:"not_logged_in",detail:"\u8BF7\u5148\u767B\u5F55 Forsion \u8D26\u53F7"};try{let{status:n,json:r}=await ge(e,"GET","/api/connect/apps");return n===401||n===403?{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"}:n!==200?{ok:!1,code:"error",detail:r?.detail||`HTTP ${n}`}:{ok:!0,base:e.base,...r}}catch(n){return{ok:!1,code:"error",detail:n?.message||String(n)}}}),t.handle("connect:publish",async(e,n)=>{if(!n||typeof n.dir!="string"||!n.dir||!n.name||!n.slug||!n.entry)return{ok:!1,code:"error",detail:"\u53C2\u6570\u4E0D\u5B8C\u6574"};let r;try{let i=Kn(t.projectsRoot());if(r=Kn(n.dir),r!==i&&!r.startsWith(i+Ls))return{ok:!1,code:"error",detail:"\u53EA\u80FD\u53D1\u5E03 Coding Space \u9879\u76EE\u76EE\u5F55"}}catch{return{ok:!1,code:"error",detail:"\u9879\u76EE\u76EE\u5F55\u4E0D\u5B58\u5728\u6216\u65E0\u6CD5\u8BBF\u95EE"}}let s=await t.getCloud();if(!s.token)return{ok:!1,code:"not_logged_in",detail:"\u8BF7\u5148\u767B\u5F55 Forsion \u8D26\u53F7"};try{let{files:i,totalBytes:a}=Qn(r,Bs(t));if(!i.some(h=>h.path===n.entry))return{ok:!1,code:"error",detail:`\u5165\u53E3\u6587\u4EF6\u4E0D\u5B58\u5728:${n.entry}`};let{status:o,json:l}=await ge(s,"POST","/api/connect/apps",{slug:n.slug,name:n.name,entry:n.entry,files:i},3e5);return o===401?{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"}:o!==200?{ok:!1,code:l?.code||"error",detail:l?.detail||`HTTP ${o}`,used:l?.used,limit:l?.limit}:(nr(r,{slug:String(l.slug)}),{ok:!0,slug:l.slug,handle:l.handle,url:`${s.base}${l.url}`,totalBytes:a})}catch(i){return{ok:!1,code:"error",detail:i?.message||String(i)}}}),t.handle("connect:unpublish",async(e,n)=>{if(!n||typeof n!="string")return{ok:!1,code:"error",detail:"\u53C2\u6570\u4E0D\u5B8C\u6574"};let r=await t.getCloud();if(!r.token)return{ok:!1,code:"not_logged_in",detail:"\u8BF7\u5148\u767B\u5F55 Forsion \u8D26\u53F7"};try{let{status:s,json:i}=await ge(r,"DELETE",`/api/connect/apps/${encodeURIComponent(n)}`);return s===401||s===403?{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"}:s!==200&&s!==404?{ok:!1,code:"error",detail:i?.detail||`HTTP ${s}`}:{ok:!0}}catch(s){return{ok:!1,code:"error",detail:s?.message||String(s)}}}),t.handle("connect:listingApply",async(e,n)=>{if(!n||typeof n.slug!="string"||!n.slug||typeof n.summary!="string"||!n.summary.trim())return{ok:!1,code:"error",detail:"\u53C2\u6570\u4E0D\u5B8C\u6574"};let r=await t.getCloud();if(!r.token)return{ok:!1,code:"not_logged_in",detail:"\u8BF7\u5148\u767B\u5F55 Forsion \u8D26\u53F7"};try{let{status:s,json:i}=await ge(r,"PUT",`/api/connect/apps/${encodeURIComponent(n.slug)}/listing`,{summary:n.summary});return s===401?{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"}:s!==200?{ok:!1,code:i?.code||"error",detail:i?.detail||`HTTP ${s}`}:{ok:!0,status:i.status}}catch(s){return{ok:!1,code:"error",detail:s?.message||String(s)}}}),t.handle("connect:listingWithdraw",async(e,n)=>{if(!n||typeof n!="string")return{ok:!1,code:"error",detail:"\u53C2\u6570\u4E0D\u5B8C\u6574"};let r=await t.getCloud();if(!r.token)return{ok:!1,code:"not_logged_in",detail:"\u8BF7\u5148\u767B\u5F55 Forsion \u8D26\u53F7"};try{let{status:s,json:i}=await ge(r,"DELETE",`/api/connect/apps/${encodeURIComponent(n)}/listing`);return s===401?{ok:!1,code:"not_logged_in",detail:"\u767B\u5F55\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u767B\u5F55"}:s!==200&&s!==404?{ok:!1,code:"error",detail:i?.detail||`HTTP ${s}`}:{ok:!0}}catch(s){return{ok:!1,code:"error",detail:s?.message||String(s)}}}),t.handle("connect:store",async()=>{let e=await t.getCloud();try{let{status:n,json:r}=await ge(e,"GET","/api/connect/store");return n!==200?{ok:!1,detail:r?.detail||`HTTP ${n}`}:{ok:!0,base:e.base,items:Array.isArray(r.items)?r.items:[]}}catch(n){return{ok:!1,detail:n?.message||String(n)}}}),t.log("[forsion-extend] connect handlers registered")}import{createHash as Ws}from"node:crypto";async function lt(t,e){if(!t||!e)return{status:"offline"};let n=t.replace(/\/+$/,"");try{let r=await fetch(`${n}/api/brain/users/me`,{headers:{Authorization:`Bearer ${e}`},signal:AbortSignal.timeout(5e3)});if(r.status===401||r.status===403)return{status:(r.headers.get("content-type")||"").includes("application/json")?"expired":"offline"};if(!r.ok)return{status:"offline"};let s=await r.json();if(!s)return{status:"offline"};let i=s.avatar||s.avatarUrl||s.avatar_url||void 0;return i&&/^\/(?!\/)/.test(i)&&(i=n+i),{status:"ok",user:{username:s.username||s.nickname||void 0,nickname:s.nickname||void 0,avatar:i,membershipTier:s.membershipTier||s.membership_tier||void 0}}}catch{return{status:"offline"}}}var ir=t=>`${t.seq}:${t.hash}`,Vs=t=>Ws("sha256").update(t).digest("hex");function tn(t){if(t===null)return{baseSeq:0,baseHash:null};if(typeof t!="string")return;let e=t.indexOf(":"),n=Number(e===-1?t:t.slice(0,e));if(!Number.isInteger(n)||n<=0)return;let r=e===-1?"":t.slice(e+1);return{baseSeq:n,baseHash:/^[0-9a-f]{64}$/.test(r)?r:null}}function Tt(t){let e=t.baseUrl.replace(/\/+$/,""),n=s=>`${e}/api/remotesync/vaults/${encodeURIComponent(t.vault)}${s}`,r=async(s,i)=>{let a=t.getToken();if(!a)throw new Error("penzor-not-logged-in");let o=await fetch(s,{...i,headers:{...i.headers,Authorization:`Bearer ${a}`}});if(o.status===409){let l=await o.json().catch(()=>({}));throw new Error(`cas-conflict ${String(l.code??"")}: seq=${String(l.seq??"?")}`)}if(!o.ok){let l=await o.text().catch(()=>"");throw new Error(`penzor ${i.method??"GET"} ${o.status}: ${l.slice(0,200)}`)}return o};return{kind:"penzor",async walk(s){let i=await r(n("/manifest"),{method:"GET",signal:s}),{files:a}=await i.json();return a.map(o=>({key:o.path,size:o.size,mtimeMs:o.mtimeMs,id:ir(o)}))},async readFile(s,i){let o=await(await r(n(`/file?path=${encodeURIComponent(s)}`),{method:"GET",signal:i})).json(),l=await fetch(o.url,{signal:i});if(!l.ok)throw new Error(`penzor blob GET ${l.status}: ${s}`);let h=Buffer.from(await l.arrayBuffer());if(Vs(h)!==o.hash)throw new Error(`penzor hash mismatch: ${s}`);return h},async writeFile(s,i,a,o,l){let h=tn(l),d=new URLSearchParams({path:s,mtimeMs:String(Math.floor(a)||0)});h&&(d.set("baseSeq",String(h.baseSeq)),h.baseHash&&d.set("baseHash",h.baseHash));let u=await(await r(n(`/file?${d.toString()}`),{method:"PUT",body:new Uint8Array(i),headers:{"Content-Type":"application/octet-stream"},signal:o})).json();return{key:s,size:u.size,mtimeMs:u.mtimeMs,id:ir(u)}},async rm(s,i,a){let o=tn(a),l=new URLSearchParams({path:s});o&&o.baseSeq>0&&(l.set("baseSeq",String(o.baseSeq)),o.baseHash&&l.set("baseHash",o.baseHash)),await r(n(`/file?${l.toString()}`),{method:"DELETE",signal:i})},async check(){try{return await r(n("/manifest"),{method:"GET"}),{ok:!0}}catch(s){return{ok:!1,error:String(s?.message||s)}}}}}var xt="forsion-diagnostics",ar=50*1024*1024,or=new Map;async function Ys(t,e){let n=or.get(e);if(n)return{id:n};let r=await lt(t,e);if(r.status==="offline")return{error:"penzor-offline"};if(r.status!=="ok")return{error:"penzor-not-logged-in"};let s=r.user?.username?.trim();return s?(or.set(e,s),{id:s}):{error:"penzor-auth-unverified"}}var nn=t=>typeof t.registerRemoteSyncBackend=="function"&&typeof t.readCreds=="function";function rn(t){t.registerRemoteSyncBackend("penzor",async e=>{let n=t.readCreds();if(!n.token||!n.cloudUrl)return{error:"penzor-not-logged-in"};let r=e?.vault,s=(typeof r=="string"?r:"default").trim()||"default";if(!/^[A-Za-z0-9_-]{1,64}$/.test(s)||s===xt)return{error:"penzor-bad-vault"};let i=await Ys(n.cloudUrl,n.token);if("error"in i)return i;let a=n.token;return{remote:Tt({baseUrl:n.cloudUrl,vault:s,getToken:()=>a}),fingerprint:`penzor:${n.cloudUrl.replace(/\/+$/,"")}|u:${i.id}|${s}`,maxFileBytes:ar}}),t.log('[forsion-extend] remote-sync backend "penzor" registered')}import{readFileSync as Gs,writeFileSync as Js,mkdirSync as Ks,chmodSync as Xs,renameSync as Zs}from"node:fs";import{join as Qs}from"node:path";function Te(t,e){try{let n=new URL(t);if(n.protocol!=="https:"&&n.protocol!=="http:")return null;let r=e.split(".")[1];if(!r)return null;let s=r.replace(/-/g,"+").replace(/_/g,"/"),i=Uint8Array.from(atob(s),l=>l.charCodeAt(0)),a=JSON.parse(new TextDecoder().decode(i)),o=a.userId??a.sub;return typeof o!="string"&&typeof o!="number"||!String(o).trim()?null:`${n.origin}${n.pathname.replace(/\/+$/,"")}::${String(o)}`}catch{return null}}function sn(t){try{let e=t.split(".")[1];if(!e)return null;let n=JSON.parse(Buffer.from(e,"base64url").toString("utf8"));return n&&typeof n=="object"?n:null}catch{return null}}function cr(t,e=Date.now()){let n=sn(t)?.iat;return typeof n=="number"?e-n*1e3:1/0}function ei(t,e=Date.now()){let n=sn(t)?.exp;return typeof n=="number"?n*1e3-e:1/0}var ti=36e5;function ur(t,e=Date.now()){return!!t&&cr(t,e)>=ti}async function dr(t,e,n=8e3,r){if(!t||!e)return null;let s=t.replace(/\/+$/,"");try{let i=await fetch(`${s}/api/auth/refresh`,{method:"POST",headers:{Authorization:`Bearer ${e}`,...r?{"X-Forsion-Client":r}:{}},signal:AbortSignal.timeout(n)});if(!i.ok)return null;let a=await i.json().catch(()=>null),o=typeof a?.token=="string"?a.token:"";return o&&o!==e?o:null}catch{return null}}var At=(t,e)=>`${t.replace(/\/+$/,"")}\0${e}`,ni=(t,e)=>new Promise((n,r)=>{let s=()=>{clearTimeout(i),r(new Error("Sign-in cancelled."))},i=setTimeout(()=>{e.removeEventListener("abort",s),n()},t);e.aborted?s():e.addEventListener("abort",s,{once:!0})});function fr(t){let e=()=>Qs(t.homeDir(),"auth-accounts.json"),n=(f,u)=>{Ks(t.homeDir(),{recursive:!0});let g=`${f}.tmp`;Js(g,JSON.stringify(u,null,2),{encoding:"utf8",mode:384}),Xs(g,384),Zs(g,f)},r=()=>{try{let f=JSON.parse(Gs(e(),"utf8"));return Array.isArray(f.accounts)?f.accounts.filter(u=>u&&typeof u.token=="string"&&u.id===Te(u.cloudUrl,u.token)):[]}catch{return[]}},s=(f,u)=>{let g=Te(f.cloudUrl||"",f.token||"");if(!g||!f.token||!f.cloudUrl)return;let S=r(),x=S.find(k=>k.id===g),w=sn(f.token),F={...x,id:g,cloudUrl:f.cloudUrl.replace(/\/+$/,""),token:f.token,username:u?.username||x?.username||w?.username,nickname:u?.nickname||x?.nickname};JSON.stringify(x)!==JSON.stringify(F)&&n(e(),{version:1,accounts:[...S.filter(k=>k.id!==g),F]})},i=()=>{let f=t.readCreds();s(f);let u=Te(f.cloudUrl,f.token);return r().map(({token:g,...S})=>({...S,active:S.id===u}))},a=f=>{let u=r().find(g=>g.id===f);if(!u)throw new Error("Account is no longer signed in. Sign in again.");return{cloudUrl:u.cloudUrl,token:u.token}},o=f=>{let u=Te(f.cloudUrl||"",f.token||"");u&&n(e(),{version:1,accounts:r().filter(g=>g.id!==u)})},l=null;return{rememberForsionAccount:s,forsionAccounts:i,savedForsionAccount:a,forgetForsionAccount:o,cancelForsionLogin:()=>{l?.abort(),l=null},forsionDeviceLogin:async(f,u,g)=>{if(l)throw new Error("A sign-in is already in progress.");if(!f)throw new Error("\u8BF7\u5148\u586B\u5199 Forsion \u4E91\u7AEF\u5730\u5740(\u6216\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF TANGU_CLOUD_URL)");let S=new AbortController;l=S;let x=()=>{if(S.signal.aborted||l!==S)throw new Error("Sign-in cancelled.")};try{let w=f.replace(/\/+$/,""),F;try{F=await fetch(`${w}/api/auth/cli/start`,{method:"POST",headers:{"Content-Type":"application/json"},body:"{}",signal:AbortSignal.any([S.signal,AbortSignal.timeout(15e3)])}).then(j=>j.json())}catch(j){throw new Error(`\u65E0\u6CD5\u8FDE\u63A5 ${w}:${j?.message||j}`)}if(x(),!F?.device_code)throw new Error("\u4E91\u7AEF\u4E0D\u652F\u6301 CLI \u767B\u5F55(/api/auth/cli/start \u8FD4\u56DE\u5F02\u5E38)");let k=F.verification_uri_complete||`${F.verification_uri}?code=${F.user_code}`,A=new URL(`${w}/auth`);A.searchParams.set("logout","1"),A.searchParams.set("app","forsion-desktop"),A.searchParams.set("redirect",k);let U=A.toString();u?.({url:U,userCode:String(F.user_code||"")}),t.openExternal(U);let M=Date.now()+(F.expires_in||600)*1e3,B=(F.interval||2)*1e3;for(;Date.now()<M;){await ni(B,S.signal),x();let j=null;try{j=await fetch(`${w}/api/auth/cli/poll`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({device_code:F.device_code}),signal:AbortSignal.any([S.signal,AbortSignal.timeout(15e3)])})}catch{x();continue}if(x(),j.status===410)throw new Error("\u767B\u5F55\u7801\u5DF2\u8FC7\u671F,\u8BF7\u91CD\u65B0\u53D1\u8D77\u767B\u5F55");let K=await j.json().catch(()=>({status:"pending"}));if(x(),K.status==="approved"&&K.token){let se={cloudUrl:w,token:K.token};return await g(se,x),x(),{token:K.token,cloudUrl:w}}}throw new Error("\u767B\u5F55\u8D85\u65F6,\u8BF7\u91CD\u8BD5")}finally{l===S&&(l=null)}},readAccounts:r}}var hr=["homeDir","appVersion","broadcast","accountBackendState","accountTransition","accountCommit","accountClear","writeCreds","onExternalCredsChange","setTokenRefresher","readCreds"],on=t=>hr.every(e=>typeof t[e]=="function");function an(t){let e={ok:!1,error:"untrusted"},n={loggedIn:!1,error:"untrusted"},r=fr(t),s=0,i=()=>{let o=t.readCreds();return At(o.cloudUrl,o.token)},a=null;t.handle("auth:status",async o=>{if(!t.isTrustedSender(o))return n;let l=s,h=i(),{base:d}=await t.getCloud(),f=t.readCreds().token,u=f?await lt(d,f):null,g=await t.accountBackendState(),{base:S}=await t.getCloud(),x=t.readCreds(),w=At(S,x.token)!==At(d,f),F=At(d,f);!w&&u?.status==="ok"&&u.user&&(a={key:F,user:u.user},r.rememberForsionAccount({...x,cloudUrl:d},u.user));let k=w?void 0:u?.status==="ok"?u.user:u?.status==="offline"&&a?.key===F?a.user:void 0;if(w)return{loggedIn:!!x.token,tokenValid:null,cloudUrl:S,accountId:Te(S,x.token),username:null,nickname:null,avatar:null,membershipTier:null,tokenSource:x.token?"tangu-login":null,backendState:g};if(u?.status==="expired"){await t.accountTransition(async()=>{if(l!==s||i()!==h)return;let U=()=>{if(l!==s||i()!==h)throw lr};try{await t.accountClear(U,()=>{t.log("[auth] token \u5DF2\u5931\u6548(\u670D\u52A1\u7AEF 401/403),\u81EA\u52A8\u767B\u51FA"),++s,r.cancelForsionLogin(),r.forgetForsionAccount(t.readCreds()),a=null})}catch(M){if(M!==lr)throw M}});let A=t.readCreds();return{loggedIn:!!A.token,tokenValid:null,cloudUrl:A.cloudUrl||d,accountId:Te(A.cloudUrl||d,A.token),username:null,nickname:null,avatar:null,membershipTier:null,tokenSource:A.token?"tangu-login":null,backendState:g}}return{loggedIn:!!f,tokenValid:u&&u.status==="ok"?!0:null,cloudUrl:d,accountId:Te(d,f),username:k?.username||null,nickname:k?.nickname||null,avatar:k?.avatar||null,membershipTier:k?.membershipTier||null,tokenSource:f?"tangu-login":null,backendState:g}}),t.handle("auth:accounts",o=>t.isTrustedSender(o)?r.forsionAccounts():[]),t.handle("auth:switchAccount",async(o,l)=>{if(!t.isTrustedSender(o))return e;if(typeof l!="string")throw new Error("Invalid account.");let h=++s;return r.cancelForsionLogin(),t.accountTransition(async()=>{let d=r.savedForsionAccount(l);return await t.accountCommit(d,()=>{if(h!==s)throw new Error("Account switch cancelled.")},()=>{r.rememberForsionAccount(d),a=null}),{ok:!0,cloudUrl:d.cloudUrl||""}})}),t.handle("auth:forsionLogin",async(o,l)=>{if(!t.isTrustedSender(o))return e;let h=++s;r.cancelForsionLogin();let{base:d}=await t.getCloud();if(h!==s)throw new Error("Sign-in cancelled.");let f=(l||d||"").trim();return{ok:!0,cloudUrl:(await r.forsionDeviceLogin(f,g=>t.broadcast("auth:device",g),(g,S)=>t.accountTransition(()=>t.accountCommit(g,()=>{if(S(),h!==s)throw new Error("Sign-in cancelled.")},()=>{r.rememberForsionAccount(g),a=null})))).cloudUrl}}),t.handle("auth:logout",async o=>t.isTrustedSender(o)?(++s,r.cancelForsionLogin(),t.accountTransition(async()=>{let{base:l}=await t.getCloud(),h=t.readCreds();return await t.accountClear(void 0,()=>{r.forgetForsionAccount(h),a=null,l&&h.token&&fetch(`${l}/api/auth/logout`,{method:"POST",headers:{Authorization:`Bearer ${h.token}`},signal:AbortSignal.timeout(5e3)}).catch(()=>{})}),{ok:!0}})):e),t.onExternalCredsChange(({previous:o,current:l})=>{++s,r.cancelForsionLogin(),o.token&&!l.token&&r.forgetForsionAccount(o),a=null,r.rememberForsionAccount(l)}),t.setTokenRefresher(async o=>{let l=s,h=i(),d=t.readCreds().token;if(!ur(d))return;let{base:f}=await t.getCloud(),u=await dr(f,d,o,`desktop/${t.appVersion()}`);if(!u){t.log("[auth] \u6ED1\u52A8\u7EED\u671F\u672A\u6210\u529F(\u79BB\u7EBF/\u8001\u7248\u672C server/\u8FD9\u679A\u5DF2\u5931\u6548),\u7EE7\u7EED\u7528\u65E7 token");return}l!==s||i()!==h||(r.rememberForsionAccount({cloudUrl:f,token:u}),t.writeCreds({cloudUrl:f,token:u}),t.log("[auth] \u767B\u5F55\u6001\u5DF2\u6ED1\u52A8\u7EED\u671F(\u6709\u6548\u671F\u91CD\u65B0\u8BA1\u6EE1 2 \u5468)"))}),t.log("[forsion-extend] account core registered")}var lr=Symbol("stale-auth-intent");import{promises as nt}from"node:fs";import Be from"node:path";import{createHash as ri}from"node:crypto";var ln=null;function mr(t){ln=t}function pe(){if(!ln)throw new Error("amadeus sync env not set (registerAmadeus factory has not run)");return ln}var ye=()=>pe().accountId();function ct(t=ye()){return t?ri("sha256").update(t).digest("hex"):"signed-out"}var xe=(t=ye())=>pe().readConfig(t),Oe=(t,e=ye())=>pe().writeConfig(t,e),Ge=(t,e=ye())=>pe().updateConfig(t,e),Fe=(t=ye())=>pe().cloudVaultDir(t),It=t=>pe().isManagedCloudVault(t);import{createHash as ao}from"node:crypto";import{promises as ne,existsSync as Vr}from"node:fs";import oe from"node:path";import{EventEmitter as Di}from"node:events";import{stat as $i}from"node:fs";import{readdir as Mi,stat as Ni}from"node:fs/promises";import*as Y from"node:path";import{lstat as gr,readdir as si,realpath as ii,stat as oi}from"node:fs/promises";import{join as ai,resolve as li,sep as pr}from"node:path";import{Readable as ci}from"node:stream";var Se={FILE_TYPE:"files",DIR_TYPE:"directories",FILE_DIR_TYPE:"files_directories",EVERYTHING_TYPE:"all"},Je={root:".",fileFilter:t=>!0,directoryFilter:t=>!0,type:Se.FILE_TYPE,lstat:!1,depth:2147483648,alwaysStat:!1,highWaterMark:256};Object.freeze(Je);var Sr="READDIRP_RECURSIVE_ERROR",ui=new Set(["ENOENT","EPERM","EACCES","ELOOP",Sr]),yr=[Se.DIR_TYPE,Se.EVERYTHING_TYPE,Se.FILE_DIR_TYPE,Se.FILE_TYPE],di=new Set([Se.DIR_TYPE,Se.EVERYTHING_TYPE,Se.FILE_DIR_TYPE]),fi=new Set([Se.EVERYTHING_TYPE,Se.FILE_DIR_TYPE,Se.FILE_TYPE]),hi=t=>ui.has(t.code),mi=process.platform==="win32",wr=t=>!0,br=t=>{if(t===void 0)return wr;if(typeof t=="function")return t;if(typeof t=="string"){let e=t.trim();return n=>n.basename===e}if(Array.isArray(t)){let e=t.map(n=>n.trim());return n=>e.some(r=>n.basename===r)}return wr},cn=class extends ci{parents;reading;parent;_stat;_maxDepth;_wantsDir;_wantsFile;_wantsEverything;_root;_isDirent;_statsProp;_rdOptions;_fileFilter;_directoryFilter;_relStart;constructor(e={}){super({objectMode:!0,autoDestroy:!0,highWaterMark:e.highWaterMark??Je.highWaterMark});let n={...Je,...e},r=n.root??Je.root,s=n.type??Je.type;this._fileFilter=br(n.fileFilter),this._directoryFilter=br(n.directoryFilter);let i=n.lstat?gr:oi;mi?this._stat=o=>i(o,{bigint:!0}):this._stat=i,this._maxDepth=n.depth!=null&&Number.isSafeInteger(n.depth)?n.depth:Je.depth,this._wantsDir=di.has(s),this._wantsFile=fi.has(s),this._wantsEverything=s===Se.EVERYTHING_TYPE,this._root=li(r),this._relStart=this._root.endsWith(pr)?this._root.length:this._root.length+1,this._isDirent=!n.alwaysStat,this._statsProp=this._isDirent?"dirent":"stats",this._rdOptions={encoding:"utf8",withFileTypes:this._isDirent};let a={path:this._root,depth:1};a.pending=this._exploreDir(this._root,1),this.parents=[a],this.reading=!1,this.parent=void 0}async _read(e){if(!this.reading){this.reading=!0;try{for(;!this.destroyed&&e>0;){let n=this.parent,r=n&&n.files;if(r&&r.length>0){let{path:s,depth:i}=n,a=r.splice(0,e).map(l=>this._formatEntry(l,s)),o=this._isDirent?a:await Promise.all(a);for(let l of o){if(!l)continue;if(this.destroyed)return;let h=this._getEntryType(l);typeof h!="string"&&(h=await h),h==="directory"&&this._directoryFilter(l)?(i<=this._maxDepth&&this.parents.push({path:l.fullPath,depth:i+1}),this._wantsDir&&(this.push(l),e--)):(h==="file"||this._includeAsFile(l))&&this._fileFilter(l)&&this._wantsFile&&(this.push(l),e--)}}else{let s=this.parents.pop();if(!s){this.push(null);break}let i=s.pending??this._exploreDir(s.path,s.depth),a=this.parents[this.parents.length-1];if(a&&!a.pending&&(a.pending=this._exploreDir(a.path,a.depth)),this.parent=await i,this.destroyed)return}}}catch(n){this.destroy(n)}finally{this.reading=!1}}}async _exploreDir(e,n){let r;try{r=await si(e,this._rdOptions)}catch(s){this._onError(s)}return{files:r,depth:n,path:e}}_formatEntry(e,n){let r=this._isDirent?e.name:e,s=ai(n,r),i={path:s.slice(this._relStart),fullPath:s,basename:r};return this._isDirent?(i.dirent=e,i):this._stat(s).then(a=>(i.stats=a,i),a=>{this._onError(a)})}_onError(e){hi(e)&&!this.destroyed?this.emit("warn",e):this.destroy(e)}_getEntryType(e){if(!e||!(this._statsProp in e))return"";let n=e[this._statsProp];return n.isFile()?"file":n.isDirectory()?"directory":n.isSymbolicLink()?this._getSymlinkEntryType(e):""}async _getSymlinkEntryType(e){let n=e.fullPath;try{let r=await ii(n),s=await gr(r);if(s.isFile())return"file";if(s.isDirectory()){let i=r.length;if(n.startsWith(r)&&n[i]===pr){let a=new Error(`Circular symlink detected: "${n}" points to "${r}"`);return a.code=Sr,this._onError(a),""}return"directory"}}catch(r){this._onError(r)}return""}_includeAsFile(e){let n=e&&e[this._statsProp];return n&&this._wantsEverything&&!n.isDirectory()}};function vr(t,e={}){let n=e.entryType||e.type;if(n==="both"&&(n=Se.FILE_DIR_TYPE),t){if(typeof t!="string")throw new TypeError("readdirp: root argument must be a string. Usage: readdirp(root, options)");if(n&&!yr.includes(n))throw new Error(`readdirp: Invalid type passed. Use one of ${yr.join(", ")}`)}else throw new Error("readdirp: root argument is required. Usage: readdirp(root, options)");let r={...e,root:t};return n&&(r.type=n),new cn(r)}import{watch as gi,unwatchFile as Er,watchFile as pi}from"node:fs";import{realpath as un,lstat as yi,open as wi,stat as _r}from"node:fs/promises";import{type as bi}from"node:os";import*as Q from"node:path";var Si="data",hn="end",Cr="close",Mt=()=>{};var Nt=process.platform,mn=Nt==="win32",vi=Nt==="darwin",Ei=Nt==="linux",ki=Nt==="freebsd",Tr=bi()==="OS400",te={ALL:"all",READY:"ready",ADD:"add",CHANGE:"change",ADD_DIR:"addDir",UNLINK:"unlink",UNLINK_DIR:"unlinkDir",RAW:"raw",ERROR:"error"},Ae=te,_i="watch",Ci={lstat:yi,stat:_r},qe="listeners",Rt="errHandlers",Ke="rawEmitters",Ti=[qe,Rt,Ke],xi=new Set(["3dm","3ds","3g2","3gp","7z","a","aac","adp","afdesign","afphoto","afpub","ai","aif","aiff","alz","ape","apk","appimage","ar","arj","asf","au","avi","bak","baml","bh","bin","bk","bmp","btif","bz2","bzip2","cab","caf","cgm","class","cmx","cpio","cr2","cur","dat","dcm","deb","dex","djvu","dll","dmg","dng","doc","docm","docx","dot","dotm","dra","DS_Store","dsk","dts","dtshd","dvb","dwg","dxf","ecelp4800","ecelp7470","ecelp9600","egg","eol","eot","epub","exe","f4v","fbs","fh","fla","flac","flatpak","fli","flv","fpx","fst","fvt","g3","gh","gif","graffle","gz","gzip","h261","h263","h264","icns","ico","ief","img","ipa","iso","jar","jpeg","jpg","jpgv","jpm","jxr","key","ktx","lha","lib","lvp","lz","lzh","lzma","lzo","m3u","m4a","m4v","mar","mdi","mht","mid","midi","mj2","mka","mkv","mmr","mng","mobi","mov","movie","mp3","mp4","mp4a","mpeg","mpg","mpga","mxu","nef","npx","numbers","nupkg","o","odp","ods","odt","oga","ogg","ogv","otf","ott","pages","pbm","pcx","pdb","pdf","pea","pgm","pic","png","pnm","pot","potm","potx","ppa","ppam","ppm","pps","ppsm","ppsx","ppt","pptm","pptx","psd","pya","pyc","pyo","pyv","qt","rar","ras","raw","resources","rgb","rip","rlc","rmf","rmvb","rpm","rtf","rz","s3m","s7z","scpt","sgi","shar","snap","sil","sketch","slk","smv","snk","so","stl","suo","sub","swf","tar","tbz","tbz2","tga","tgz","thmx","tif","tiff","tlz","ttc","ttf","txz","udf","uvh","uvi","uvm","uvp","uvs","uvu","viv","vob","war","wav","wax","wbmp","wdp","weba","webm","webp","whl","wim","wm","wma","wmv","wmx","woff","woff2","wrm","wvx","xbm","xif","xla","xlam","xls","xlsb","xlsm","xlsx","xlt","xltm","xltx","xm","xmind","xpi","xpm","xwd","xz","z","zip","zipx"]),Ai=t=>xi.has(Q.extname(t).slice(1).toLowerCase()),fn=(t,e)=>{t instanceof Set?t.forEach(e):e(t)},ut=(t,e,n)=>{let r=t[e];r instanceof Set||(t[e]=r=new Set([r])),r.add(n)},Ii=t=>e=>{let n=t[e];n instanceof Set?n.clear():delete t[e]},dt=(t,e,n)=>{let r=t[e];r instanceof Set?r.delete(n):r===n&&delete t[e]},xr=t=>t instanceof Set?t.size===0:!t,Pt=new Map;function kr(t,e,n,r,s){let i=(a,o)=>{n(t),s(a,o,{watchedPath:t}),o&&t!==o&&Dt(Q.resolve(t,o),qe,Q.join(t,o))};try{return gi(t,{persistent:e.persistent},i)}catch(a){r(a);return}}var Dt=(t,e,n,r,s)=>{let i=Pt.get(t);i&&fn(i[e],a=>{a(n,r,s)})},Ri=(t,e,n,r)=>{let{listener:s,errHandler:i,rawEmitter:a}=r,o=Pt.get(e),l;if(!n.persistent)return l=kr(t,n,s,i,a),l?l.close.bind(l):void 0;if(o)ut(o,qe,s),ut(o,Rt,i),ut(o,Ke,a);else{if(l=kr(t,n,Dt.bind(null,e,qe),i,Dt.bind(null,e,Ke)),!l)return;l.on(Ae.ERROR,async h=>{let d=Dt.bind(null,e,Rt);if(o&&(o.watcherUnusable=!0),mn&&h.code==="EPERM")try{await(await wi(t,"r")).close(),d(h)}catch{}else d(h)}),o={listeners:s,errHandlers:i,rawEmitters:a,watcher:l},Pt.set(e,o)}return()=>{dt(o,qe,s),dt(o,Rt,i),dt(o,Ke,a),xr(o.listeners)&&(o.watcher.close(),Pt.delete(e),Ti.forEach(Ii(o)),o.watcher=void 0,Object.freeze(o))}},dn=new Map,Pi=(t,e,n,r)=>{let{listener:s,rawEmitter:i}=r,a=dn.get(e),o=a&&a.options;return o&&(o.persistent<n.persistent||o.interval>n.interval)&&(Er(e),a=void 0),a?(ut(a,qe,s),ut(a,Ke,i)):(a={listeners:s,rawEmitters:i,options:n,watcher:pi(e,n,(l,h)=>{fn(a.rawEmitters,f=>{f(Ae.CHANGE,e,{curr:l,prev:h})});let d=l.mtimeMs;(l.size!==h.size||d>h.mtimeMs||d===0)&&fn(a.listeners,f=>f(t,l))})},dn.set(e,a)),()=>{dt(a,qe,s),dt(a,Ke,i),xr(a.listeners)&&(dn.delete(e),Er(e),a.options=a.watcher=void 0,Object.freeze(a))}},$t=class{fsw;_boundHandleError;constructor(e){this.fsw=e,this._boundHandleError=n=>e._handleError(n)}_watchWithNodeFs(e,n){let r=this.fsw.options,s=Q.dirname(e),i=Q.basename(e);this.fsw._getWatchedDir(s).add(i);let o=Q.resolve(e),l={persistent:r.persistent};n||(n=Mt);let h;if(r.usePolling){let d=r.interval!==r.binaryInterval;l.interval=d&&Ai(i)?r.binaryInterval:r.interval,h=Pi(e,o,l,{listener:n,rawEmitter:this.fsw._emitRaw})}else h=Ri(e,o,l,{listener:n,errHandler:this._boundHandleError,rawEmitter:this.fsw._emitRaw});return h}_handleFile(e,n,r){if(this.fsw.closed)return;let s=Q.dirname(e),i=Q.basename(e),a=this.fsw._getWatchedDir(s),o=n;if(a.has(i))return;let l=async(d,f)=>{if(this.fsw._throttle(_i,e,5)){if(!f||f.mtimeMs===0)try{let u=await _r(e);if(this.fsw.closed)return;let g=u.atimeMs,S=u.mtimeMs;if((!g||g<=S||S!==o.mtimeMs)&&this.fsw._emit(Ae.CHANGE,e,u),(vi||Ei||ki)&&o.ino!==u.ino){this.fsw._closeFile(d),o=u;let x=this._watchWithNodeFs(e,l);x&&this.fsw._addPathCloser(d,x)}else o=u}catch{this.fsw._remove(s,i)}else if(a.has(i)){let u=f.atimeMs,g=f.mtimeMs;(!u||u<=g||g!==o.mtimeMs)&&this.fsw._emit(Ae.CHANGE,e,f),o=f}}},h=this._watchWithNodeFs(e,l);if(!(r&&this.fsw.options.ignoreInitial)&&this.fsw._isntIgnored(e)){if(!this.fsw._throttle(Ae.ADD,e,0))return;this.fsw._emit(Ae.ADD,e,n)}return h}async _handleSymlink(e,n,r,s){if(this.fsw.closed)return;let i=e.fullPath,a=this.fsw._getWatchedDir(n);if(!this.fsw.options.followSymlinks){this.fsw._incrReadyCount();let o;try{o=await un(r)}catch{return this.fsw._emitReady(),!0}return this.fsw.closed?void 0:(a.has(s)?this.fsw._symlinkPaths.get(i)!==o&&(this.fsw._symlinkPaths.set(i,o),this.fsw._emit(Ae.CHANGE,r,e.stats)):(a.add(s),this.fsw._symlinkPaths.set(i,o),this.fsw._emit(Ae.ADD,r,e.stats)),this.fsw._emitReady(),!0)}if(this.fsw._symlinkPaths.has(i))return!0;this.fsw._symlinkPaths.set(i,!0)}_handleRead(e,n,r,s,i,a,o){e=Q.join(e,"");let l=s?`${e}:${s}`:e;if(o=this.fsw._throttle("readdir",l,1e3),!o)return;let h=this.fsw._getWatchedDir(r.path),d=new Set,f=this.fsw._readdirp(e,{fileFilter:u=>r.filterPath(u),directoryFilter:u=>r.filterDir(u)});if(f)return f.on(Si,async u=>{if(this.fsw.closed){f=void 0;return}let g=u.path,S=Q.join(e,g);if(d.add(g),!(u.stats.isSymbolicLink()&&await this._handleSymlink(u,e,S,g))){if(this.fsw.closed){f=void 0;return}(g===s||!s&&!h.has(g))&&(this.fsw._incrReadyCount(),S=Q.join(i,Q.relative(i,S)),this._addToNodeFs(S,n,r,a+1))}}).on(Ae.ERROR,this._boundHandleError),new Promise((u,g)=>{if(!f)return g();f.once(hn,()=>{if(this.fsw.closed){f=void 0;return}let S=o?o.clear():!1;u(void 0),h.getChildren().filter(x=>x!==e&&!d.has(x)).forEach(x=>{this.fsw._remove(e,x)}),f=void 0,S&&this._handleRead(e,!1,r,s,i,a,o)})})}async _handleDir(e,n,r,s,i,a,o){let l=this.fsw._getWatchedDir(Q.dirname(e)),h=l.has(Q.basename(e));!(r&&this.fsw.options.ignoreInitial)&&!i&&!h&&this.fsw._emit(Ae.ADD_DIR,e,n),l.add(Q.basename(e)),this.fsw._getWatchedDir(e);let d,f,u=this.fsw.options.depth;if((u==null||s<=u)&&!this.fsw._symlinkPaths.has(o)){if(!i&&(await this._handleRead(e,r,a,i,e,s,d),this.fsw.closed))return;f=this._watchWithNodeFs(e,(g,S)=>{S&&S.mtimeMs===0||this._handleRead(g,!1,a,i,e,s,d)})}return f}async _addToNodeFs(e,n,r,s,i){let a=this.fsw._emitReady;if(this.fsw._isIgnored(e)||this.fsw.closed)return a(),!1;let o=this.fsw._getWatchHelpers(e);r&&(o.filterPath=l=>r.filterPath(l),o.filterDir=l=>r.filterDir(l));try{let l=await Ci[o.statMethod](o.watchPath);if(this.fsw.closed)return;if(this.fsw._isIgnored(o.watchPath,l))return a(),!1;let h=this.fsw.options.followSymlinks,d;if(l.isDirectory()){let f=Q.resolve(e),u=h?await un(e):e;if(this.fsw.closed||(d=await this._handleDir(o.watchPath,l,n,s,i,o,u),this.fsw.closed))return;f!==u&&u!==void 0&&this.fsw._symlinkPaths.set(f,u)}else if(l.isSymbolicLink()){let f=h?await un(e):e;if(this.fsw.closed)return;let u=Q.dirname(o.watchPath);if(this.fsw._getWatchedDir(u).add(o.watchPath),this.fsw._emit(Ae.ADD,o.watchPath,l),d=await this._handleDir(u,l,n,s,e,o,f),this.fsw.closed)return;f!==void 0&&this.fsw._symlinkPaths.set(Q.resolve(e),f)}else d=this._handleFile(o.watchPath,l,n);return a(),d&&this.fsw._addPathCloser(e,d),!1}catch(l){if(this.fsw._handleError(l))return a(),e}}};var gn="/",Oi="//",Dr=".",Ui="..",Fi="string",ji=/\\/g,$r=/\/\//g,Li=/\..*\.(sw[px])$|~$|\.subl.*\.tmp/,Hi=/^\.[/\\]/;function Ot(t){return Array.isArray(t)?t:[t]}var pn=t=>typeof t=="object"&&t!==null&&!(t instanceof RegExp);function zi(t){return typeof t=="function"?t:typeof t=="string"?e=>t===e:t instanceof RegExp?e=>t.test(e):typeof t=="object"&&t!==null?e=>{if(t.path===e)return!0;if(t.recursive){let n=Y.relative(t.path,e);return n?!n.startsWith("..")&&!Y.isAbsolute(n):!1}return!1}:()=>!1}function qi(t){if(typeof t!="string")throw new Error("string expected");t=Y.normalize(t),t=t.replace(/\\/g,"/");let e=!1;return t.startsWith("//")&&(e=!0),t=t.replace($r,"/"),e&&(t="/"+t),t}function Ar(t,e,n){let r=qi(e);for(let s=0;s<t.length;s++){let i=t[s];if(i(r,n))return!0}return!1}function Bi(t,e){if(t==null)throw new TypeError("anymatch: specify first argument");let r=Ot(t).map(s=>zi(s));return e==null?(s,i)=>Ar(r,s,i):Ar(r,e)}var Ir=t=>{let e=Ot(t).flat();if(!e.every(n=>typeof n===Fi))throw new TypeError(`Non-string provided as watch path: ${e}`);return e.map(Mr)},Rr=t=>{let e=t.replace(ji,gn),n=!1;return e.startsWith(Oi)&&(n=!0),e=e.replace($r,gn),n&&(e=gn+e),e},Mr=t=>Rr(Y.normalize(Rr(t))),Pr=(t="")=>e=>typeof e=="string"?Mr(Y.isAbsolute(e)?e:Y.join(t,e)):e,Wi=(t,e)=>Y.isAbsolute(t)?t:Y.join(e,t),Vi=Object.freeze(new Set),yn=class{path;_removeWatcher;items;constructor(e,n){this.path=e,this._removeWatcher=n,this.items=new Set}add(e){let{items:n}=this;n&&e!==Dr&&e!==Ui&&n.add(e)}async remove(e){let{items:n}=this;if(!n||(n.delete(e),n.size>0))return;let r=this.path;try{await Mi(r)}catch{this._removeWatcher&&this._removeWatcher(Y.dirname(r),Y.basename(r))}}has(e){let{items:n}=this;if(n)return n.has(e)}getChildren(){let{items:e}=this;return e?[...e.values()]:[]}dispose(){this.items.clear(),this.path="",this._removeWatcher=Mt,this.items=Vi,Object.freeze(this)}},Yi="stat",Gi="lstat",wn=class{fsw;path;watchPath;fullWatchPath;dirParts;followSymlinks;statMethod;constructor(e,n,r){this.fsw=r;let s=e;this.path=e=e.replace(Hi,""),this.watchPath=s,this.fullWatchPath=Y.resolve(s),this.dirParts=[],this.dirParts.forEach(i=>{i.length>1&&i.pop()}),this.followSymlinks=n,this.statMethod=n?Yi:Gi}entryPath(e){return Y.join(this.watchPath,Y.relative(this.watchPath,e.fullPath))}filterPath(e){let{stats:n}=e;if(n&&n.isSymbolicLink())return this.filterDir(e);let r=this.entryPath(e);return this.fsw._isntIgnored(r,n)&&this.fsw._hasReadPermissions(n)}filterDir(e){return this.fsw._isntIgnored(this.entryPath(e),e.stats)}},Ut=class extends Di{closed;options;_closers;_ignoredPaths;_throttled;_streams;_symlinkPaths;_watched;_pendingWrites;_pendingUnlinks;_readyCount;_emitReady;_closePromise;_userIgnored;_readyEmitted;_emitRaw;_boundRemove;_nodeFsHandler;constructor(e={}){super(),this.closed=!1,this._closers=new Map,this._ignoredPaths=new Set,this._throttled=new Map,this._streams=new Set,this._symlinkPaths=new Map,this._watched=new Map,this._pendingWrites=new Map,this._pendingUnlinks=new Map,this._readyCount=0,this._readyEmitted=!1;let n=e.awaitWriteFinish,r={stabilityThreshold:2e3,pollInterval:100},s={persistent:!0,ignoreInitial:!1,ignorePermissionErrors:!1,interval:100,binaryInterval:300,followSymlinks:!0,usePolling:!1,atomic:!0,...e,ignored:e.ignored?Ot(e.ignored):Ot([]),awaitWriteFinish:n===!0?r:typeof n=="object"?{...r,...n}:!1};Tr&&(s.usePolling=!0),s.atomic===void 0&&(s.atomic=!s.usePolling);let i=process.env.CHOKIDAR_USEPOLLING;if(i!==void 0){let l=i.toLowerCase();l==="false"||l==="0"?s.usePolling=!1:l==="true"||l==="1"?s.usePolling=!0:s.usePolling=!!l}let a=process.env.CHOKIDAR_INTERVAL;a&&(s.interval=Number.parseInt(a,10));let o=0;this._emitReady=()=>{o++,o>=this._readyCount&&(this._emitReady=Mt,this._readyEmitted=!0,process.nextTick(()=>this.emit(te.READY)))},this._emitRaw=(...l)=>this.emit(te.RAW,...l),this._boundRemove=this._remove.bind(this),this.options=s,this._nodeFsHandler=new $t(this),Object.freeze(s)}_addIgnoredPath(e){if(pn(e)){for(let n of this._ignoredPaths)if(pn(n)&&n.path===e.path&&n.recursive===e.recursive)return}this._ignoredPaths.add(e)}_removeIgnoredPath(e){if(this._ignoredPaths.delete(e),typeof e=="string")for(let n of this._ignoredPaths)pn(n)&&n.path===e&&this._ignoredPaths.delete(n)}add(e,n,r){let{cwd:s}=this.options;this.closed=!1,this._closePromise=void 0;let i=Ir(e);return s&&(i=i.map(a=>Wi(a,s))),i.forEach(a=>{this._removeIgnoredPath(a)}),this._userIgnored=void 0,this._readyCount||(this._readyCount=0),this._readyCount+=i.length,Promise.all(i.map(async a=>{let o=await this._nodeFsHandler._addToNodeFs(a,!r,void 0,0,n);return o&&this._emitReady(),o})).then(a=>{this.closed||a.forEach(o=>{o&&this.add(Y.dirname(o),Y.basename(n||o))})}),this}unwatch(e){if(this.closed)return this;let n=Ir(e),{cwd:r}=this.options;return n.forEach(s=>{!Y.isAbsolute(s)&&!this._closers.has(s)&&(r&&(s=Y.join(r,s)),s=Y.resolve(s)),this._closePath(s),this._addIgnoredPath(s),this._watched.has(s)&&this._addIgnoredPath({path:s,recursive:!0}),this._userIgnored=void 0}),this}close(){if(this._closePromise)return this._closePromise;this.closed=!0,this.removeAllListeners();let e=[];return this._closers.forEach(n=>n.forEach(r=>{let s=r();s instanceof Promise&&e.push(s)})),this._streams.forEach(n=>n.destroy()),this._userIgnored=void 0,this._readyCount=0,this._readyEmitted=!1,this._watched.forEach(n=>n.dispose()),this._closers.clear(),this._watched.clear(),this._streams.clear(),this._symlinkPaths.clear(),this._throttled.clear(),this._closePromise=e.length?Promise.all(e).then(()=>{}):Promise.resolve(),this._closePromise}getWatched(){let e={};return this._watched.forEach((n,r)=>{let i=(this.options.cwd?Y.relative(this.options.cwd,r):r)||Dr;e[i]=n.getChildren().sort()}),e}emitWithAll(e,n){this.emit(e,...n),e!==te.ERROR&&this.emit(te.ALL,e,...n)}async _emit(e,n,r){if(this.closed)return;let s=this.options;mn&&(n=Y.normalize(n)),s.cwd&&(n=Y.relative(s.cwd,n));let i=[n];r!=null&&i.push(r);let a=s.awaitWriteFinish,o;if(a&&(o=this._pendingWrites.get(n)))return o.lastChange=new Date,this;if(s.atomic){if(e===te.UNLINK)return this._pendingUnlinks.set(n,[e,...i]),setTimeout(()=>{this._pendingUnlinks.forEach((l,h)=>{this.emit(...l),this.emit(te.ALL,...l),this._pendingUnlinks.delete(h)})},typeof s.atomic=="number"?s.atomic:100),this;e===te.ADD&&this._pendingUnlinks.has(n)&&(e=te.CHANGE,this._pendingUnlinks.delete(n))}if(a&&(e===te.ADD||e===te.CHANGE)&&this._readyEmitted){let l=(h,d)=>{h?(e=te.ERROR,i[0]=h,this.emitWithAll(e,i)):d&&(i.length>1?i[1]=d:i.push(d),this.emitWithAll(e,i))};return this._awaitWriteFinish(n,a.stabilityThreshold,e,l),this}if(e===te.CHANGE&&!this._throttle(te.CHANGE,n,50))return this;if(s.alwaysStat&&r===void 0&&(e===te.ADD||e===te.ADD_DIR||e===te.CHANGE)){let l=s.cwd?Y.join(s.cwd,n):n,h;try{h=await Ni(l)}catch{}if(!h||this.closed)return;i.push(h)}return this.emitWithAll(e,i),this}_handleError(e){let n=e&&e.code;return e&&n!=="ENOENT"&&n!=="ENOTDIR"&&(!this.options.ignorePermissionErrors||n!=="EPERM"&&n!=="EACCES")&&this.emit(te.ERROR,e),e||this.closed}_throttle(e,n,r){this._throttled.has(e)||this._throttled.set(e,new Map);let s=this._throttled.get(e);if(!s)throw new Error("invalid throttle");let i=s.get(n);if(i)return i.count++,!1;let a,o=()=>{let h=s.get(n),d=h?h.count:0;return s.delete(n),clearTimeout(a),h&&clearTimeout(h.timeoutObject),d};a=setTimeout(o,r);let l={timeoutObject:a,clear:o,count:0};return s.set(n,l),l}_incrReadyCount(){return this._readyCount++}_awaitWriteFinish(e,n,r,s){let i=this.options.awaitWriteFinish;if(typeof i!="object")return;let a=i.pollInterval,o,l=e;this.options.cwd&&!Y.isAbsolute(e)&&(l=Y.join(this.options.cwd,e));let h=new Date,d=this._pendingWrites;function f(u){$i(l,(g,S)=>{if(g||!d.has(e)){g&&g.code!=="ENOENT"&&s(g);return}let x=Number(new Date);u&&S.size!==u.size&&(d.get(e).lastChange=x);let w=d.get(e);x-w.lastChange>=n?(d.delete(e),s(void 0,S)):o=setTimeout(f,a,S)})}d.has(e)||(d.set(e,{lastChange:h,cancelWait:()=>(d.delete(e),clearTimeout(o),r)}),o=setTimeout(f,a))}_isIgnored(e,n){if(this.options.atomic&&Li.test(e))return!0;if(!this._userIgnored){let{cwd:r}=this.options,i=(this.options.ignored||[]).map(Pr(r)),o=[...[...this._ignoredPaths].map(Pr(r)),...i];this._userIgnored=Bi(o,void 0)}return this._userIgnored(e,n)}_isntIgnored(e,n){return!this._isIgnored(e,n)}_getWatchHelpers(e){return new wn(e,this.options.followSymlinks,this)}_getWatchedDir(e){let n=Y.resolve(e);return this._watched.has(n)||this._watched.set(n,new yn(n,this._boundRemove)),this._watched.get(n)}_hasReadPermissions(e){return this.options.ignorePermissionErrors?!0:!!(Number(e.mode)&256)}_remove(e,n,r){let s=Y.join(e,n),i=Y.resolve(s);if(r=r??(this._watched.has(s)||this._watched.has(i)),!this._throttle("remove",s,100))return;!r&&this._watched.size===1&&this.add(e,n,!0),this._getWatchedDir(s).getChildren().forEach(u=>this._remove(s,u));let l=this._getWatchedDir(e),h=l.has(n);l.remove(n),this._symlinkPaths.has(i)&&this._symlinkPaths.delete(i);let d=s;if(this.options.cwd&&(d=Y.relative(this.options.cwd,s)),this.options.awaitWriteFinish&&this._pendingWrites.has(d)&&this._pendingWrites.get(d).cancelWait()===te.ADD)return;this._watched.delete(s),this._watched.delete(i);let f=r?te.UNLINK_DIR:te.UNLINK;h&&!this._isIgnored(s)&&this._emit(f,s),this._closePath(s)}_closePath(e){this._closeFile(e);let n=Y.dirname(e);this._getWatchedDir(n).remove(Y.basename(e))}_closeFile(e){let n=this._closers.get(e);n&&(n.forEach(r=>r()),this._closers.delete(e))}_addPathCloser(e,n){if(!n)return;let r=this._closers.get(e);r||(r=[],this._closers.set(e,r)),r.push(n)}_readdirp(e,n){if(this.closed)return;let r={type:te.ALL,alwaysStat:!0,lstat:!0,...n,depth:0},s=vr(e,r);return this._streams.add(s),s.once(Cr,()=>{s=void 0}),s.once(hn,()=>{s&&(this._streams.delete(s),s=void 0)}),s}};function Ji(t,e={}){let n=new Ut(e);return n.add(t),n}var Nr={watch:Ji,FSWatcher:Ut};function Ki(t,e){let n=Object.create(null);for(let i=0;i<e.length;i++){let a=e[i];n[a]?n[a].push(i):n[a]=[i]}let s=[{buffer1index:-1,buffer2index:-1,chain:null}];for(let i=0;i<t.length;i++){let a=t[i],o=n[a]||[],l=0,h=s[0];for(let d of o){let f;for(f=l;f<s.length&&!(s[f].buffer2index<d&&(f===s.length-1||s[f+1].buffer2index>d));f++);if(f<s.length){let u={buffer1index:i,buffer2index:d,chain:s[f]};if(l===s.length?s.push(h):s[l]=h,l=f+1,h=u,l===s.length)break}}s[l]=h}return s[s.length-1]}function Or(t,e){let n=Ki(t,e),r=[],s=t.length,i=e.length;for(let a=n;a!==null;a=a.chain){let o=s-a.buffer1index-1,l=i-a.buffer2index-1;s=a.buffer1index,i=a.buffer2index,(o||l)&&r.push({buffer1:[s+1,o],buffer1Content:t.slice(s+1,s+1+o),buffer2:[i+1,l],buffer2Content:e.slice(i+1,i+1+l)})}return r.reverse(),r}function Xi(t,e,n){let r=[];function s(l,h){r.push({ab:h,oStart:l.buffer1[0],oLength:l.buffer1[1],abStart:l.buffer2[0],abLength:l.buffer2[1]})}Or(e,t).forEach(l=>s(l,"a")),Or(e,n).forEach(l=>s(l,"b")),r.sort((l,h)=>l.oStart-h.oStart);let i=[],a=0;function o(l){l>a&&(i.push({stable:!0,buffer:"o",bufferStart:a,bufferLength:l-a,bufferContent:e.slice(a,l)}),a=l)}for(;r.length;){let l=r.shift(),h=l.oStart,d=l.oStart+l.oLength,f=[l];for(o(h);r.length;){let u=r[0],g=u.oStart;if(g>d)break;d=Math.max(d,g+u.oLength),f.push(r.shift())}if(f.length===1){if(l.abLength>0){let u=l.ab==="a"?t:n;i.push({stable:!0,buffer:l.ab,bufferStart:l.abStart,bufferLength:l.abLength,bufferContent:u.slice(l.abStart,l.abStart+l.abLength)})}}else{let u={a:[t.length,-1,e.length,-1],b:[n.length,-1,e.length,-1]};for(;f.length;){l=f.shift();let k=l.oStart,A=k+l.oLength,U=l.abStart,M=U+l.abLength,B=u[l.ab];B[0]=Math.min(U,B[0]),B[1]=Math.max(M,B[1]),B[2]=Math.min(k,B[2]),B[3]=Math.max(A,B[3])}let g=u.a[0]+(h-u.a[2]),S=u.a[1]+(d-u.a[3]),x=u.b[0]+(h-u.b[2]),w=u.b[1]+(d-u.b[3]),F={stable:!1,aStart:g,aLength:S-g,aContent:t.slice(g,S),oStart:h,oLength:d-h,oContent:e.slice(h,d),bStart:x,bLength:w-x,bContent:n.slice(x,w)};i.push(F)}a=d}return o(e.length),i}function Ur(t,e,n,r){r=Object.assign({excludeFalseConflicts:!0,stringSeparator:/\s+/},r),typeof t=="string"&&(t=t.split(r.stringSeparator)),typeof e=="string"&&(e=e.split(r.stringSeparator)),typeof n=="string"&&(n=n.split(r.stringSeparator));let i=[],a=Xi(t,e,n),o=[];function l(){o.length&&i.push({ok:o}),o=[]}function h(d,f){if(d.length!==f.length)return!1;for(let u=0;u<d.length;u++)if(d[u]!==f[u])return!1;return!0}return a.forEach(d=>{d.stable?o.push(...d.bufferContent):r.excludeFalseConflicts&&h(d.aContent,d.bContent)?o.push(...d.aContent):(l(),i.push({conflict:{a:d.aContent,aIndex:d.aStart,o:d.oContent,oIndex:d.oStart,b:d.bContent,bIndex:d.bStart}}))}),l(),i}function Ft(t,e){let n=t.lastIndexOf("/"),r=n<0?"":t.slice(0,n+1),s=n<0?t:t.slice(n+1),i=s.lastIndexOf("."),a=i>0?s.slice(0,i):s,o=i>0?s.slice(i):"",l=d=>String(d).padStart(2,"0"),h=`${e.getFullYear()}-${l(e.getMonth()+1)}-${l(e.getDate())} ${l(e.getHours())}${l(e.getMinutes())}`;return`${r}${a} (conflict ${h})${o}`}function Zi(t,e){if(e<2)return t;let n=t.lastIndexOf("."),r=n>t.lastIndexOf("/")&&n>t.lastIndexOf(")"),s=r?t.slice(0,n):t,i=r?t.slice(n):"";return`${s}-${e}${i}`}function Qi(t){let e=3735928559,n=1103547991;for(let s=0;s<t.length;s++){let i=t.charCodeAt(s);e=Math.imul(e^i,2654435761),n=Math.imul(n^i,1597334677)}e=Math.imul(e^e>>>16,2246822507)^Math.imul(n^n>>>13,3266489909),n=Math.imul(n^n>>>16,2246822507)^Math.imul(e^e>>>13,3266489909);let r=4294967296*(2097151&n)+(e>>>0);return`${t.length.toString(36)}-${r.toString(36)}`}function jt(t,e,n){if(t===null&&e===null&&n===null)return{kind:"none"};if(n===null)return t===null?e?{kind:"dropShadow"}:{kind:"none"}:e?t===e.hash?{kind:"deleteLocal"}:{kind:"pushCreate"}:{kind:"pushCreate"};if(t===null)return e?n.seq===e.seq?{kind:"pushDelete"}:{kind:"pull"}:{kind:"pull"};if(!e)return t===n.hash?{kind:"adopt"}:{kind:"conflict"};let r=t!==e.hash,s=n.seq!==e.seq;return!r&&!s?{kind:"none"}:r?s?t===n.hash?{kind:"adopt"}:n.hash===e.hash?{kind:"push",baseSeq:n.seq}:{kind:"conflict"}:{kind:"push",baseSeq:e.seq}:{kind:"pull"}}function Fr(t,e,n){let r=Ur(t.split(`
194
194
  `),e.split(`
195
- `),t.split(`
196
- `),{excludeFalseConflicts:!0}),r=[];for(let i of s){if(i.conflict)return null;i.ok&&r.push(...i.ok)}return r.join(`
197
- `)}function ln(n,e,t=200){return n>=t||e>=5&&n>=Math.max(5,Math.ceil(e/2))}var Si=/[\u0000-\u001f\u007f]/;function Ve(n){let e=n.replace(/\\/g,"/").normalize("NFC").trim();if(e=e.replace(/\/+$/,""),!e||e.length>512||e.startsWith("/")||Si.test(e))return null;let t=e.split("/");for(let s of t)if(!s||s==="."||s==="..")return null;return t.join("/")}function cn(n,e){let t=n.replace(/\\/g,"/").normalize("NFC");return e===""?Ve(t):t.startsWith(`${e}/`)?Ve(t.slice(e.length+1)):null}function kr(n,e){return e===""?n:`${e}/${n}`}function ot(n){return!!(n===".DS_Store"||n==="Icon\r"||n===".sync-trash"||/\.tmp-\d+-\d+-\d+$/.test(n)||/^\..+\.lock$/.test(n))}function Ce(n){return/\.md$/i.test(n)?"page":/\.db$/i.test(n)?"db":"binary"}var De=n=>n==="page"||n==="db";import{gzip as vi}from"node:zlib";import{promisify as Ei}from"node:util";var _i=Ei(vi),ki=1024,le=class extends Error{status;body;constructor(e,t,s){super(`cloud http ${e} on ${s}`),this.status=e,this.body=t}},Cr=n=>12e4+Math.ceil(n/256);function xr(n){let e=`${n.baseUrl.replace(/\/+$/,"")}/api/amadeus`,t=async(r,i,o)=>{let a={Authorization:`Bearer ${n.token}`,...o?.headers};r!=="GET"&&(a["X-Amadeus-Client"]=n.clientId);let c;o?.json!==void 0?(a["Content-Type"]="application/json",c=JSON.stringify(o.json),c.length>=ki&&(a["Content-Encoding"]="gzip",c=await _i(c))):o?.form&&(c=o.form);let h=await fetch(i,{method:r,headers:a,body:c,signal:AbortSignal.timeout(o?.timeoutMs??3e4)});if(!h.ok){let d=null;try{d=await h.json()}catch{}throw new le(h.status,d,i)}return h.json()},s=r=>new URLSearchParams(r).toString();return{clientId:n.clientId,async listVaults(){return((await t("GET",`${e}/vaults`)).vaults??[]).map(i=>({id:String(i.id),name:String(i.name),lastChangeSeq:Number(i.lastChangeSeq??0)}))},async tree(r){let i=await t("GET",`${e}/vaults/${r}/tree`);if(!Array.isArray(i.entries))throw new Error("server too old: tree has no entries[] (deploy the amadeus microserver update)");return{folders:i.folders??[],seq:Number(i.seq??0),maxFileBytes:Number.isInteger(i.maxFileBytes)&&i.maxFileBytes>0?i.maxFileBytes:void 0,entries:i.entries.map(o=>({path:String(o.path),kind:o.kind,seq:Number(o.seq??0),hash:o.hash??null,size:Number(o.size??0)}))}},async getFile(r,i){let o=await t("GET",`${e}/vaults/${r}/file?${s({path:i})}`);return{content:String(o.content??""),seq:Number(o.seq??0),hash:o.hash??null}},putFile(r,i,o,a,c=!1){return t("PUT",`${e}/vaults/${r}/file`,{json:{path:i,content:o,baseSeq:a,...c?{force:!0}:{}}})},async deleteFile(r,i,o,a){let c={path:i};o!==void 0&&(c.baseSeq=String(o)),await t("DELETE",`${e}/vaults/${r}/file?${s(c)}`,a?.confirmed?{headers:{"X-Amadeus-Delete-Confirmed":"1"}}:void 0)},move(r,i,o){return t("POST",`${e}/vaults/${r}/move`,{json:{from:i,to:o}})},renameFolder(r,i,o){return t("POST",`${e}/vaults/${r}/folders/rename`,{json:{path:i,newName:o}})},moveFolder(r,i,o){return t("POST",`${e}/vaults/${r}/folders/move`,{json:{path:i,dest:o}})},async deleteFolder(r,i){await t("DELETE",`${e}/vaults/${r}/folders?${s({path:i})}`)},putBinary(r,i,o,a){let c=new FormData;return c.set("path",i),a?.ifAbsent&&c.set("ifAbsent","true"),a?.baseSeq!==void 0&&c.set("baseSeq",String(a.baseSeq)),c.set("file",new Blob([new Uint8Array(o)]),i.split("/").pop()||"file"),t("POST",`${e}/vaults/${r}/binary`,{form:c,timeoutMs:Cr(o.length)})},async listVersions(r,i){return((await t("GET",`${e}/vaults/${r}/file/versions?${s({path:i})}`)).versions??[]).map(a=>({id:String(a.id),seq:Number(a.seq??0)}))},async getVersion(r,i){let o=await t("GET",`${e}/vaults/${r}/file/versions/${i}`);return String(o.content??"")},async getAsset(r,i){let o=new AbortController,a=setTimeout(()=>o.abort(),12e4);try{let c=await fetch(`${e}/vaults/${r}/asset?${s({ref:i})}`,{headers:{Authorization:`Bearer ${n.token}`},signal:o.signal});if(!c.ok)throw new le(c.status,null,"asset:"+i);return clearTimeout(a),a=setTimeout(()=>o.abort(),Cr(Number(c.headers.get("content-length"))||0)),Buffer.from(await c.arrayBuffer())}finally{clearTimeout(a)}},async changes(r,i){let o=await t("GET",`${e}/vaults/${r}/changes?${s({since:String(i)})}`);return{changes:o.changes??[],seq:Number(o.seq??0)}}}}function Tr(n,e){let t=!1,s=0,r=null,i=null,o=()=>`${n.baseUrl.replace(/\/+$/,"")}/api/amadeus/vaults/${n.vaultId}/events?since=${e.getSince()}`,a=h=>{if(t)return;e.onDown(h);let d=Math.min(3e4,1e3*2**s)*(.7+Math.random()*.6);s++,i=setTimeout(()=>void c(),d)},c=async()=>{if(t)return;r=new AbortController;let h;try{h=await fetch(o(),{headers:{Authorization:`Bearer ${n.token}`,Accept:"text/event-stream"},signal:r.signal})}catch(E){a(E);return}if(!h.ok||!h.body){a(new Error(`sse http ${h.status}`));return}s=0,e.onOpen();let d=h.body.getReader(),f=new TextDecoder,u="",y="",v=[],x=()=>{if(!v.length&&!y)return;let E=v.join(`
198
- `),U=y||"message";y="",v=[];let M=null;try{M=E?JSON.parse(E):null}catch{return}U==="hello"?e.onHello(Number(M?.seq??0)):U==="change"?e.onChange(M):U==="reset"?e.onReset():U==="presence"?e.onPresence?.(M):U==="presence-roster"&&e.onPresenceRoster?.(M)};try{for(;;){let{done:E,value:U}=await d.read();if(E)break;for(u+=f.decode(U,{stream:!0});;){let M=u.indexOf(`
199
- `);if(M<0)break;let Y=u.slice(0,M).replace(/\r$/,"");if(u=u.slice(M+1),Y==="")x();else{if(Y.startsWith(":"))continue;Y.startsWith("event:")?y=Y.slice(6).trim():Y.startsWith("data:")&&v.push(Y.slice(5).replace(/^ /,""))}}}}catch(E){t||a(E);return}a(new Error("sse stream ended"))};return c(),{stop:()=>{t=!0,i&&clearTimeout(i),r?.abort()}}}import{constants as Ci,promises as Ye}from"node:fs";import xi from"node:path";var Ge=n=>xi.join(fe().userDataDir(),fe().isDevMode()?`${n}.dev.json`:`${n}.json`);async function un(n){try{let e=JSON.parse(await Ye.readFile(Ge(n),"utf8"));return!e||typeof e.vaultRoot!="string"||typeof e.vaultId!="string"?null:(e.files=e.files??{},e.cursor=Number(e.cursor??0),e.lastSyncAt=e.lastSyncAt??null,e)}catch{return null}}function Rr(n){let e=null,t=null,s=Promise.resolve(),r=null,i=()=>{if(!e)return s;let o=e,a=JSON.stringify(e);return e=null,s=s.then(async()=>{try{let c=Ge(n),h=`${c}.tmp-${process.pid}-${Date.now()}-0`;await Ye.writeFile(h,a,"utf8"),await Ye.rename(h,c),r=null}catch(c){e??=o,r=c}}),s};return{save(o){e=o,!t&&(t=setTimeout(()=>{t=null,i()},500))},async flush(o=!1){if(t&&(clearTimeout(t),t=null),await i(),o&&r)throw r}}}async function Ir(n){try{await Ye.unlink(Ge(n))}catch{}}async function Pr(n,e){try{await Ye.copyFile(Ge(n),Ge(e),Ci.COPYFILE_EXCL)}catch(t){let s=t?.code;if(s==="EEXIST"||s==="ENOENT")return!1;throw t}return await Ye.unlink(Ge(n)).catch(()=>{}),!0}var Ri=5*1024*1024,Ii=5*1024*1024,Pi=3e4,Ai=2500,$i=3e3,Di=5,Mi=256*1024,Ni=5,$r=1024*1024,Dr=200,Ui=6e4,Fi=50,Oi=".sync-trash",Je=n=>Ti("sha256").update(n).digest("hex");function at(n,e={localRoot:$e(),shadowName:`amadeus-sync-${rt()}`,vaultId:"first",serverDir:"",excludePrefixes:["\u4E0E\u6211\u5171\u4EAB/"]}){let t=l=>{let p=cn(l,"");if(!p)return null;for(let m of e.excludePrefixes??[])if(p===m.replace(/\/$/,"")||p.startsWith(m))return null;if(e.ignoreNames?.length&&p.split("/").some(m=>e.ignoreNames.includes(m)))return null;let g=e.serverDir?`${e.serverDir}/${p}`:p;return e.inScope&&!e.inScope(g,Ce(g))?null:g},s=l=>{let p;if(e.serverDir){if(!l.startsWith(`${e.serverDir}/`))return null;p=l.slice(e.serverDir.length+1)}else{for(let g of e.excludePrefixes??[])if(l.startsWith(g))return null;p=l}return p.split("/").some(g=>ot(g)||!!e.ignoreNames?.includes(g))?null:p},r=(l,p)=>!e.inScope||e.inScope(l,p),i=e.accountId??he(),o=!1,a=0,c=Promise.resolve(),h=new Set,d="disabled",f=null,u=null,y=null,v=null,x=null,E=null,U=0,M=new Map,Y=null,B=Rr(e.shadowName),q=new Map,Q=!1,J=!1,ne=[],ue=()=>{u&&(u.pending=q.size?Object.fromEntries(q):void 0,B.save(u))},ft=()=>{J=!1,ne.length=0},Qe=()=>{if(J)return!0;let l=Date.now();for(;ne.length&&l-ne[0]>Ui;)ne.shift();return ne.length>=Fi?(J=!0,!0):!1},xe=[],Ne=new Set,Ze=!1,_=null,C=null,w=null,b=()=>{!o||w||(w=setTimeout(()=>{w=null,n.onStatus(Fe())},200))},P=(l,p)=>{d=l,p!==void 0&&(f=p),b()},S=(l,p=!1)=>{if(o){if(l.key){if(Ne.has(l.key))return;Ne.add(l.key)}p?xe.unshift(l):xe.push(l),G()}},T=new Map,$=l=>{if(!o)return;let p=(u?.files[l]?.size??0)>Mi,g=(e.pushQuietMs??$i)*(p?Ni:1),m=Date.now(),k=T.get(l);k&&clearTimeout(k.timer);let I=k?.since??m,D=Math.max(0,Math.min(g,I+g*Di-m)),R=setTimeout(()=>{T.delete(l),S({key:l,run:()=>ae(l,!0)})},D);T.set(l,{timer:R,since:I}),b()},L=()=>{for(let{timer:l}of T.values())clearTimeout(l);T.clear()},F=l=>!(l instanceof le)||l.status>=500||l.status===0,O=l=>l instanceof le&&(l.status===401||l.status===403),G=async()=>{if(!Ze){Ze=!0;try{for(;xe.length;){(d==="idle"||d==="starting")&&P("syncing");let l=xe.shift();l.key&&Ne.delete(l.key);try{await l.run()}catch(p){if(!o)return;if(O(p)){xe.length=0,Ne.clear(),wt(),P("auth-required","login-expired");return}if(F(p)){S(l,!0),wt(),P("offline",p?.message||"network error"),V();return}let g=l.key??"(op)";M.set(g,p?.body?.code||`http ${p?.status}`),b()}}o&&d==="syncing"&&(u&&(u.lastSyncAt=Date.now(),B.save(u)),P("idle",null))}finally{Ze=!1;for(let l of h)l();h.clear()}}},V=()=>{!o||_||(_=setTimeout(()=>{_=null,tt()},Pi))},W=l=>{if(!E||!u)throw new Error("engine not bound");let p=s(l);if(p===null)throw new Error("path outside binding: "+l);let g=se.resolve(E,kr(p,u.folder)),m=se.relative(E,g);if(m.startsWith("..")||se.isAbsolute(m))throw new Error("path escapes vault: "+l);return g},Z=l=>({size:l,mtimeMs:-1}),X=async l=>{try{let p=await te.stat(l);return p.isFile()?{size:p.size,mtimeMs:Math.floor(p.mtimeMs)}:null}catch{return null}},we=0,Ue=async(l,p,g=()=>!0)=>{await te.mkdir(se.dirname(l),{recursive:!0});let m=`${l}.tmp-${process.pid}-${Date.now()}-${we++}`;await te.writeFile(m,p);let k=await X(m)??Z(Buffer.byteLength(p));return g()?(await te.rename(m,l),k):(await te.rm(m,{force:!0}),null)},Le=async l=>{let p;try{p=await te.readdir(l,{withFileTypes:!0})}catch{return}for(let g of p)g.isDirectory()&&await Le(se.join(l,g.name));try{await te.rmdir(l)}catch{}},ie=async l=>{let p=W(l),g=await X(p),m;try{m=await te.readFile(p)}catch{return null}return{hash:De(Ce(l))?Je(m.toString("utf8")):Je(m),size:g?.size??m.length,mtimeMs:g?.mtimeMs??-1,buf:m}},_e=async(l,p,g,m)=>{u&&(u.files[l]={seq:p,hash:g,size:m.size,mtimeMs:m.mtimeMs},B.save(u))},ye=l=>{u&&l in u.files&&(delete u.files[l],B.save(u))},Te=async(l,p)=>{if(!y||!u||be(l))return;let g=re,m=Ce(l),k,I,D;if(De(m)){let j;try{j=await y.getFile(u.vaultId,l)}catch(H){if(H instanceof le&&H.status===404){await Ut(l);return}throw H}k=j.content,I=j.seq,D=j.hash??Je(j.content)}else{let j;try{j=await y.getAsset(u.vaultId,l)}catch(H){if(H instanceof le&&H.status===404){M.set(l,"ASSET_404"),b();return}throw H}k=j,I=p??0,D=Je(j)}let R=await ie(l);if(g!==re||be(l))return;if(R&&R.hash===D){await _e(l,I,D,R);return}let N=u.files[l];if(R&&N&&D===N.hash&&R.hash!==N.hash){await _e(l,I,D,Z(N.size)),S({key:l,run:()=>ae(l)});return}if(R&&(!N||R.hash!==N.hash)){if(N&&m==="page"&&typeof k=="string"&&await Gr(l,N,R,k,I,D,()=>g===re&&!be(l))||g!==re||be(l))return;await Yr(l)}let A=await Ue(W(l),k,()=>g===re&&!be(l));A&&await _e(l,I,D,A)},Gr=async(l,p,g,m,k,I,D)=>{try{if(!y||!u||g.buf.length>$r||m.length>$r)return!1;let N=(await y.listVersions(u.vaultId,l)).find(H=>H.seq===p.seq);if(!N)return!1;let A=await y.getVersion(u.vaultId,N.id);if(Je(A)!==p.hash)return!1;let j=_r(g.buf.toString("utf8"),A,m);return j===null?!1:(await Ue(W(l),j,D)&&(await _e(l,k,I,Z(Buffer.byteLength(j))),S({key:l,run:()=>ae(l)})),!0)}catch{return!1}},Yr=async l=>{let p=Ve(At(l,new Date));if(!p)return;let g=p.lastIndexOf("."),m=g>p.lastIndexOf("/"),k=m?p.slice(0,g):p,I=m?p.slice(g):"",D=p;for(let R=2;Ar(W(D));R++)D=`${k}-${R}${I}`;try{await te.rename(W(l),W(D))}catch(R){if(R?.code==="ENOENT")return;throw R}U++,S({key:D,run:()=>ae(D)}),b()},_n=async l=>{if(!E)return;let p=W(l),g=s(l)??l,m=se.join(E,Oi,new Date().toISOString().slice(0,10),...g.split("/")),k=Ar(m)?`${m}.${Date.now()}`:m;try{await te.mkdir(se.dirname(k),{recursive:!0}),await te.rename(p,k)}catch(I){if(I?.code==="ENOENT")return;throw new Error(`\u8F6F\u5220\u5931\u8D25,\u4FDD\u7559\u672C\u5730\u6587\u4EF6 ${p}: ${I?.message??String(I)}`)}},Ut=async l=>{if(!u)return;let p=await ie(l);if(be(l))return;let g=u.files[l]??null,m=$t(p?.hash??null,g,null);if(m.kind==="deleteLocal"){if(!Q&&Qe()){q.set(l,"local"),ue(),b();return}ne.push(Date.now()),await _n(l),ye(l)}else m.kind==="pushCreate"?(ye(l),S({key:l,run:()=>ae(l)})):ye(l)},kn=(l,p)=>{if(u){for(let g of Object.keys(u.files))if(g===l||g.startsWith(`${l}/`)){let m=p+g.slice(l.length);u.files[m]=u.files[g],delete u.files[g]}B.save(u)}},Cn=async l=>{if(!y||!u||l.seq<=u.cursor||!await mt())return;if(l.origin.client&&y.clientId===l.origin.client){u.cursor=l.seq,B.save(u);return}let p=l.type==="structure"?"folder":l.type,g=k=>s(k)!==null&&r(k,p);if(!g(l.path)&&!(l.newPath&&g(l.newPath))){u.cursor=l.seq,B.save(u);return}let m=l.path;switch(l.op){case"write":await Te(m,l.fileSeq);break;case"delete":await Ut(m);break;case"move":{let k=l.newPath;if(!k)break;let I=u.files[m];if(await ie(m)&&I)try{await te.mkdir(se.dirname(W(k)),{recursive:!0}),await te.rename(W(m),W(k)),u.files[k]={...I,seq:l.fileSeq??I.seq},delete u.files[m],B.save(u)}catch{await Te(k,l.fileSeq)}else ye(m),await Te(k,l.fileSeq);break}case"mkdir":await te.mkdir(W(m),{recursive:!0});break;case"rename-folder":case"move-folder":{let k=l.newPath;if(!k)break;try{await te.mkdir(se.dirname(W(k)),{recursive:!0}),await te.rename(W(m),W(k))}catch{}kn(m,k);break}case"delete-folder":{let k=`${m}/`;for(let I of Object.keys(u.files))(I===m||I.startsWith(k))&&await Ut(I);await Le(W(m));break}}if(u.cursor=l.seq,B.save(u),l.op==="move"||l.op==="rename-folder"||l.op==="move-folder"||l.op==="delete"||l.op==="delete-folder")try{await n.onRemoteApplied?.(l)}catch{}},Jr=async(l,p,g)=>{let m=Number(p?.seq??0),k=p?.content??null;if(k!==null&&Je(k)===g.hash){await _e(l,m,g.hash,g);return}if(k===null&&m===0){if(!u?.files[l]){M.set(l,p?.code||"EXISTS"),b();return}ye(l),S({key:l,run:()=>ae(l)});return}await Te(l,m)},ht=async(l,p)=>{if(!y||!u)return;let g=await ie(l);if(!g){S({key:l,run:()=>ae(l)});return}if(g.size>Ri){M.set(l,"TOO_LARGE"),b();return}let m=g.buf.toString("utf8");try{let k=await y.putFile(u.vaultId,l,m,p);M.delete(l),await _e(l,k.seq,k.hash??g.hash,g)}catch(k){if(k instanceof le&&k.status===409){await Jr(l,k.body,g);return}throw k}},pt=async(l,p)=>{if(!y||!u)return;let g=await ie(l);if(!g){S({key:l,run:()=>ae(l)});return}if(g.size>(Y??Ii)){M.set(l,"TOO_LARGE"),b();return}try{let m=await y.putBinary(u.vaultId,l,g.buf,{baseSeq:p});M.delete(l),await _e(l,m.seq,g.hash,g)}catch(m){if(m instanceof le&&m.status===409){let k=Number(m.body?.seq??0),I=m.body?.hash??null;if(I!==null&&I===g.hash){await _e(l,k,g.hash,g);return}if(k===0){if(!u.files[l]){M.set(l,m.body?.code||"EXISTS"),b();return}ye(l),S({key:l,run:()=>ae(l)});return}await Te(l,k);return}throw m}},xn=async l=>{if(!y||!u||be(l))return;let p=re,g=u.files[l];if(g){if(De(Ce(l)))try{let m=await y.getFile(u.vaultId,l);if(m.seq!==g.seq){await Te(l,m.seq);return}}catch(m){if(m instanceof le&&m.status===404){ye(l);return}throw m}if(!(p!==re||be(l))){try{await y.deleteFile(u.vaultId,l,g.seq,{confirmed:Q})}catch(m){if(m instanceof le&&m.status===409){await Te(l,Number(m.body?.seq??0)||null);return}if(m instanceof le&&m.status===429&&m.body?.code==="MASS_DELETE_BLOCKED"){q.set(l,"remote"),J=!0,ue(),b();return}throw m}ye(l)}}},mt=async()=>E?await te.stat(E).then(p=>p.isDirectory()).catch(()=>!1)||!e.requireRootExists&&!Object.keys(u?.files??{}).length?!0:(P("error",`vault-missing: ${E}`),V(),!1):!1,re=0,gt=new Set,yt=new Map,pe=l=>JSON.stringify([l.from,l.to]),Ae=(l,p)=>l===p||l.startsWith(`${p}/`),be=l=>[...u?.moves??[],...gt].some(p=>Ae(l,p.from)||Ae(l,p.to)),Re=()=>!!(u?.moves?.length||gt.size),Ft=async l=>{if(!y||!u)return;let{from:p,to:g,kind:m}=l;if(s(p)===null||s(g)===null)throw new Error("Invalid queued cloud move");l.hashes??=Object.fromEntries(Object.entries(u.files).filter(([R])=>Ae(R,p)).map(([R,N])=>[R.slice(p.length),N.hash])),B.save(u),await B.flush(!0);let k,I=!1;try{if(m==="folder"){let R=se.posix.dirname(p)==="."?"":se.posix.dirname(p),N=se.posix.dirname(g)==="."?"":se.posix.dirname(g);R===N?await y.renameFolder(u.vaultId,p,se.posix.basename(g)):await y.moveFolder(u.vaultId,p,N)}else{let R=await y.move(u.vaultId,p,g);k=Number(R.seq)}}catch(R){if(!(R instanceof le)||R.status!==404)throw R;let N=await y.tree(u.vaultId);if(N.entries.some(H=>Ae(H.path,p))||N.folders.some(H=>Ae(H,p)))throw R;let j=N.entries.find(H=>H.path===g);if(k=j?.seq,I=!j&&!N.entries.some(H=>Ae(H.path,g))&&!N.folders.some(H=>Ae(H,g)),!I){let H=Object.entries(l.hashes);if(!(H.length>0&&H.every(([ke,He])=>N.entries.some(ze=>ze.path===g+ke&&ze.hash===He))))throw new le(409,{code:"MOVE_DESTINATION_CHANGED"},"local-move")}}if(I)for(let R of Object.keys(u.files))Ae(R,p)&&delete u.files[R];else kn(p,g),k!==void 0&&u.files[g]&&(u.files[g].seq=k);u.moves=(u.moves??[]).filter(R=>pe(R)!==pe(l)),B.save(u);try{await B.flush(!0)}catch(R){throw u.moves.unshift(l),B.save(u),R}let D=yt.get(pe(l));yt.delete(pe(l)),D?.(),be(g)||(m==="folder"?await Ot():await ae(g))},ae=async(l,p=!1)=>{if(!u||be(l))return;if(!r(l,Ce(l))){ye(l);return}if(!await mt())return;let g=await ie(l);if(be(l))return;let m=u.files[l]??null,k=$t(g?.hash??null,m,m?{seq:m.seq,hash:m.hash}:null);switch(k.kind){case"push":De(Ce(l))?await ht(l,k.baseSeq):await pt(l,k.baseSeq);break;case"pushCreate":De(Ce(l))?await ht(l,0):await pt(l,0);break;case"pushDelete":if(p){St();break}if(!Q&&(q.has(l)||Qe())){q.set(l,"remote"),ue(),b();break}ne.push(Date.now()),await xn(l);break;case"dropShadow":ye(l);break;default:g&&m&&g.hash===m.hash&&g.mtimeMs>=0&&(m.size!==g.size||m.mtimeMs!==g.mtimeMs)&&await _e(l,m.seq,m.hash,g);break}},Tn=async()=>{let l=new Map;if(!E||!u)return l;let p=E,g=null,m=async k=>{if(g)return;let I;try{I=await te.readdir(k,{withFileTypes:!0})}catch(D){g=`${k}: ${D?.message??String(D)}`;return}for(let D of I){if(ot(D.name)||D.isDirectory()&&e.ignoreNames?.includes(D.name))continue;let R=se.join(k,D.name);if(D.isDirectory())await m(R);else if(D.isFile()){let N=se.relative(p,R).split(se.sep).join("/"),A=t(N);if(!A)continue;try{let j=await te.stat(R);if(!j.isFile())continue;l.set(A,{size:j.size,mtimeMs:Math.floor(j.mtimeMs)})}catch(j){if(j?.code==="ENOENT")continue;g=`${R}: ${j?.message??String(j)}`;return}}}};return await m(p),g?(P("error",`scan-failed: ${g}`),V(),null):l},Ot=async()=>{let l=re;if(Re()||l!==re||!u||!await mt())return;let p=await Tn();if(!p||Re()||l!==re)return;let g=!1;for(let[I,D]of[...q])(D==="remote"&&p.has(I)||D==="local"&&!p.has(I))&&(q.delete(I),g=!0);q.size||ft();for(let[I,D]of p){let R=u.files[I];R&&R.size===D.size&&R.mtimeMs===D.mtimeMs||S({key:I,run:()=>ae(I)})}let m=Object.keys(u.files),k=m.filter(I=>!p.has(I));if(k.length&&!Q&&(J||ln(k.length,m.length,Dr))){J=!0;for(let I of k)q.set(I,"remote");ue(),b();return}g&&(ue(),b());for(let I of k)q.has(I)||S({key:I,run:()=>ae(I)})},et=async()=>{let l=re;if(Re()||l!==re||!y||!u||!E||!await mt())return;let p=await y.tree(u.vaultId);if(p.maxFileBytes!==void 0&&p.maxFileBytes!==Y&&(Y=p.maxFileBytes,b()),Re()||l!==re)return;let g=new Map;for(let A of p.entries)s(A.path)===null||!r(A.path,A.kind)||g.set(A.path,A);let m=await Tn();if(!m||Re()||l!==re)return;let k=new Set([...g.keys(),...m.keys(),...Object.keys(u.files)]),I=Object.keys(u.files).length,D=[];for(let A of k){if(Re()||l!==re)return;let j=u.files[A]??null,H=g.get(A)??null,ce=m.get(A)??null,ke=null,He=Z(ce?.size??0);if(ce)if(j&&j.size===ce.size&&j.mtimeMs===ce.mtimeMs)ke=j.hash,He=ce;else{let ze=await ie(A);ze&&(ke=ze.hash,He=ze)}D.push({sp:A,d:$t(ke,j,H?{seq:H.seq,hash:H.hash}:null),rSeq:H?.seq??null,localHash:ke,localStat:He})}if(Re()||l!==re)return;let R=D.filter(A=>A.d.kind==="deleteLocal"||A.d.kind==="pushDelete").length,N=!Q&&(J||ln(R,I,Dr));N&&R&&(J=!0),q.clear();for(let{sp:A,d:j,rSeq:H,localHash:ce,localStat:ke}of D){if(Re()||l!==re)return;if(N&&(j.kind==="deleteLocal"||j.kind==="pushDelete")){q.set(A,j.kind==="deleteLocal"?"local":"remote");continue}if((j.kind==="deleteLocal"||j.kind==="pushDelete")&&((await ie(A))?.hash??null)!==ce){S({key:A,run:()=>ae(A)});continue}if(Re()||l!==re)return;switch(j.kind){case"adopt":await _e(A,H,ce,ke);break;case"pull":await Te(A,H);break;case"push":De(Ce(A))?await ht(A,j.baseSeq):await pt(A,j.baseSeq);break;case"pushCreate":De(Ce(A))?await ht(A,0):await pt(A,0);break;case"pushDelete":await xn(A);break;case"deleteLocal":await _n(A),ye(A);break;case"conflict":await Te(A,H);break;case"dropShadow":ye(A);break;case"none":break}}Q&&(Q=!1,ne.length=0),q.size||ft(),ue(),N&&b();for(let A of p.folders)if(!(s(A)===null||!r(A,"folder")))try{await te.mkdir(W(A),{recursive:!0})}catch{}u.cursor=p.seq,u.lastSyncAt=Date.now(),B.save(u)},Xr=async()=>{if(!y||!u)return;let l=u.cursor,p=await y.changes(u.vaultId,l);if(p.changes.length===0&&p.seq>l||p.changes.length>0&&p.changes[0].seq!==l+1){await et();return}for(let m of p.changes)await Cn(m)},Ie=null,Rn=[],In=()=>{Ie&&Rn.push(Ie.close()),Ie=null},Kr=()=>{if(!o||Ie||!E)return;Ie=Sr.watch(E,{ignoreInitial:!0,depth:12,ignored:p=>{let g=se.basename(p);return ot(g)||!!e.ignoreNames?.includes(g)}});let l=p=>{if(!E)return;let g=se.relative(E,p);if(!g||g.startsWith(".."))return;let m=t(g);m&&$(m)};Ie.on("change",l),Ie.on("add",l),Ie.on("unlink",()=>St()),Ie.on("unlinkDir",()=>St())},wt=()=>{v?.stop(),v=null},Qr=()=>{if(!o||!y||!u||v)return;let l=x;l&&(v=Tr({baseUrl:l.cloudUrl,vaultId:u.vaultId,token:l.token},{getSince:()=>u?.cursor??0,onHello:p=>{u&&p>u.cursor&&S({run:Xr})},onChange:p=>{S({run:()=>Cn(p)})},onReset:()=>{S({run:et})},onOpen:()=>{(d==="offline"||d==="starting")&&P("idle",null),S({run:Ot})},onDown:()=>{(d==="idle"||d==="syncing")&&P("offline")},onPresence:p=>n.onPresence?.(u?.vaultId??"",p),onPresenceRoster:p=>n.onPresenceRoster?.(u?.vaultId??"",p)}))},Zr=async()=>{let l=await ve(i);if(l.cloudSync?.deviceId)return l.cloudSync.deviceId;let p=`desk-${Math.random().toString(36).slice(2,10)}${Date.now().toString(36)}`;return await Pe({cloudSync:{...l.cloudSync??{},deviceId:p}},i),p},es=async l=>{wt(),In(),xe.length=0,Ne.clear(),q.clear(),Q=!1,J=!1,ne.length=0;let p=await ve(i);if(l!==a)return;let g=p.cloudSync;if(g?.enabled===!1){E=null,y=null,P("disabled",null);return}if(!i||i!==he()){P("auth-required","not-logged-in");return}if(E=e.localRoot,e.requireRootExists){let D=await te.stat(E).then(R=>R.isDirectory()).catch(()=>!1);if(l!==a)return;if(!D){P("error",`vault-missing: ${E}`),V();return}}if(l!==a)return;let m=n.loadCreds();if(!m.cloudUrl||!m.token){y=null,P("auth-required","not-logged-in");return}P("starting",null);let k=g?.deviceId??await Zr();if(l!==a)return;let I=e.clientIdSuffix?`${k}#${e.clientIdSuffix}`:k;x={cloudUrl:m.cloudUrl,token:m.token},y=xr({baseUrl:m.cloudUrl,token:m.token,clientId:I});try{let D=e.vaultId==="first"?g?.vaultId:e.vaultId;if(!D){let N=await y.listVaults();if(l!==a)return;if(!N.length)throw new Error("\u4E91\u7AEF\u65E0\u53EF\u7528 vault");D=N[0].id,await Pe({cloudSync:{...g??{},vaultId:D}},i)}if(l!==a)return;let R=await un(e.shadowName);if(l!==a||(u=R&&R.vaultRoot===E&&R.vaultId===D&&R.folder===""?R:{vaultRoot:E,folder:"",vaultId:D,cursor:0,lastSyncAt:null,files:{}},l!==a))return;for(let[N,A]of Object.entries(u.pending??{}))q.set(N,A);if(q.size&&(J=!0),!e.requireRootExists){let N=await te.stat(E).then(A=>A.isDirectory()).catch(()=>!1);if(l!==a)return;if(!N){if(Object.keys(u.files).length){P("error",`mirror-missing: ${E}`),V();return}if(await te.mkdir(E,{recursive:!0}),l!==a)return}}Kr();for(let N of u.moves??[])S({key:`move:${pe(N)}`,run:()=>Ft(N)});S({run:et}),S({run:async()=>{Qr()}})}catch(D){if(l!==a)return;O(D)?P("auth-required","login-expired"):(P("offline",D?.message||String(D)),V())}},Pn=()=>{o=!1,wt(),In(),xe.length=0,Ne.clear(),L();for(let l of[_,C,w])l&&clearTimeout(l);_=C=w=null},An=async()=>{Ze&&await new Promise(l=>h.add(l)),await Promise.all(Rn.splice(0)),await B.flush(),u=null,y=null,x=null,E=null,U=0,M.clear(),Y=null,q.clear(),Q=!1,J=!1,ne.length=0,d="disabled",f=null},ts=()=>{$n()},bt=null,tt=()=>{bt?.(),bt=fe().onBeforeQuit(ts);let l=++a;Pn();let p=c.catch(()=>{}).then(async()=>{await An(),l===a&&(o=!0,await es(l))});return c=p,p},$n=()=>{bt?.(),bt=null,++a,Pn();let l=c.catch(()=>{}).then(An);return c=l,l},Fe=()=>({enabled:d!=="disabled",state:d==="idle"&&T.size?"syncing":d,lastSyncAt:u?.lastSyncAt??null,pending:xe.length+T.size,conflicts:U,skipped:[...M].map(([l,p])=>({path:l,reason:p})),error:f,pendingDeletions:q.size,maxFileBytes:Y});return{getStatus:Fe,start(){tt()},notifyLocal(l,p,g){if(!u||d==="disabled"||d==="auth-required")return;let m=t(l),k=g?t(g):null;if(p==="write"&&m){ot(m.split("/").pop()||"")||$(m);return}if(p==="remove"){if(!m)return;let I=`${m}/`,D=!1;for(let R of Object.keys(u.files))(R===m||R.startsWith(I))&&(D=!0,S({key:R,run:()=>ae(R)}));!D&&m&&S({key:m,run:()=>ae(m)})}},holdLocalMove(l,p){let g=k=>e.serverDir?`${e.serverDir}/${k.replace(/\\/g,"/").normalize("NFC")}`:k.replace(/\\/g,"/").normalize("NFC"),m={from:g(l),to:g(p)};return++re,gt.add(m),()=>{gt.delete(m)}},async notifyLocalMove(l,p,g,m){let k=t(l),I=t(p),D=u??await un(e.shadowName),R=cn(l,""),N=R&&(e.serverDir?`${e.serverDir}/${R}`:R);if(!k&&I&&N&&D&&Object.keys(D.files).some(A=>A===N||A.startsWith(`${N}/`))&&(k=N),!k&&!I){g?.();return}if(k&&I){let A=u??D;if(!A){g?.();return}let j=m??(Object.keys(A.files).some(ce=>ce.startsWith(`${k}/`))?"folder":"file"),H={from:k,to:I,kind:j};A.moves??=[],A.moves.some(ce=>pe(ce)===pe(H))||(A.moves.push(H),++re),g&&yt.set(pe(H),g),B.save(A);try{await B.flush(!0)}catch(ce){throw A.moves=A.moves.filter(ke=>pe(ke)!==pe(H)),yt.delete(pe(H)),B.save(A),ce}u===A&&o&&d!=="disabled"&&d!=="auth-required"&&S({key:`move:${pe(H)}`,run:()=>Ft(H)});return}k&&this.notifyLocal(l,"remove"),I&&(S({key:I,run:()=>ae(I)}),St()),g?.()},async setEnabled(l){let p=await ve(i);return await Pe({cloudSync:{...p.cloudSync??{},enabled:l}},i),await tt(),Fe()},async restart(){return await tt(),Fe()},async syncNow(){if(M.clear(),d==="disabled"||d==="auth-required"||!y)await tt();else{for(let l of u?.moves??[])S({key:`move:${pe(l)}`,run:()=>Ft(l)});S({run:et})}return Fe()},confirmMassDeletions(){return q.size&&(Q=!0,J=!1,q.clear(),ne.length=0,ue(),S({run:et})),Fe()},stop:$n};function St(){o&&(C&&clearTimeout(C),C=setTimeout(()=>{C=null,S({run:Ot})},Ai))}}import{createHash as ji}from"node:crypto";function Mr(n){let e=n.replace(/\.md$/i,""),t=n.lastIndexOf("/"),s=t<0?"":n.slice(0,t);return{root:n,fdPrefix:`${e}.fd/`,assetPrefix:s?`${s}/.amadeus/`:".amadeus/"}}function Nr(n,e,t){return!!(e===n.root||e.startsWith(n.fdPrefix)||`${e}/`===n.fdPrefix||t==="binary"&&e.startsWith(n.assetPrefix)||t==="folder"&&(`${e}/`===n.assetPrefix||e.startsWith(n.assetPrefix)))}var Li=n=>ji("sha256").update(n).digest("hex").slice(0,8),Hi=n=>n.replace(/[\\/:*?"<>|]/g," ").trim().slice(0,40)||"shared",Dt="\u4E0E\u6211\u5171\u4EAB";function dn(n){let e=Li(`${n.vaultId}:${n.path}`),t=Mr(n.path),s=n.path.includes("/")?n.path.slice(0,n.path.lastIndexOf("/")):"";return{key:e,vaultId:n.vaultId,rootPath:n.path,title:n.title,localRelDir:`${Dt}/${Hi(n.title)}-${e}`,serverDir:s,inScope:(r,i)=>Nr(t,r,i)}}function fn(){let n=fe().readCreds(),e=Se(n.cloudUrl??"",n.token??""),t=new AbortController,s=()=>{let f=fe().readCreds();if(t.signal.aborted||!e||Se(f.cloudUrl??"",f.token??"")!==e)throw Object.assign(new Error("Cloud account changed; retry from the current account"),{status:401});return f},r=()=>{let f=s();if(!f.cloudUrl||!f.token)throw Object.assign(new Error("\u672A\u767B\u5F55 Forsion \u8D26\u53F7"),{status:401});return f.cloudUrl.replace(/\/+$/,"")},i=async(f,u,y)=>{let v=s();if(!v.cloudUrl||!v.token)throw Object.assign(new Error("\u672A\u767B\u5F55 Forsion \u8D26\u53F7"),{status:401});let x=await fetch(`${v.cloudUrl.replace(/\/+$/,"")}/api/amadeus${u}`,{method:f,headers:{Authorization:`Bearer ${v.token}`,...y!==void 0?{"Content-Type":"application/json"}:{}},body:y!==void 0?JSON.stringify(y):void 0,signal:AbortSignal.any([t.signal,AbortSignal.timeout(2e4)])});if(!x.ok){let U=null;try{U=await x.json()}catch{}throw Object.assign(new Error(U?.detail||`http ${x.status}`),{status:x.status,code:U?.code})}let E=await x.json();return s(),E},o=null,a=async()=>(s(),o||(o=(await i("GET","/vaults")).vaults[0]?.id??"default",o)),c=()=>{try{let f=(s().token??"").split(".")[1],u=JSON.parse(Buffer.from(f.replace(/-/g,"+").replace(/_/g,"/"),"base64").toString());return typeof u.userId=="string"?u.userId:null}catch{return null}},h=async()=>(await i("GET","/shared-with-me")).items.map(u=>{let y=dn(u),v=u.path.split("/").pop()??u.path;return{...u,localPath:`${y.localRelDir}/${v}`}}),d=null;return{stop:()=>t.abort(),call:i,ensureOwnVault:a,myUserId:c,sharedWithMe:h,linkBase:async()=>{if(s(),d)return d;try{d=((await i("GET","/collab/link-base")).webOrigin??"").trim().replace(/\/+$/,"")||r()}catch{d=r()}return d},async heartbeat(f,u){let y=(f??"").replace(/\\/g,"/"),v,x=null,E=u.find(U=>y.startsWith(`${U.localRelDir}/`));E?(v=E.vaultId,x=E.serverDir?`${E.serverDir}/${y.slice(E.localRelDir.length+1)}`:y.slice(E.localRelDir.length+1)):(v=await a(),x=y||null),await i("POST",`/vaults/${encodeURIComponent(v)}/presence`,{page:x})}}}import{promises as Ur}from"node:fs";import zi from"node:path";var hn=".forsion-vault.md",pn=n=>`${n}/${hn}`;var ge=n=>n.replace(/\\/g,"/").normalize("NFC");function mn(n){let e=ge(n.path);return e?n.kind==="folder"?`${e}/`:n.kind==="page"?`${e.replace(/\.md$/i,"")}.fd/`:null:null}function Xe(n,e,t){let s=ge(t);if(!s)return!1;if(n.some(r=>ge(r.path)===s))return!0;for(let r of e??[]){let i=ge(r);if(!i)continue;let o=`${i.replace(/\.md$/i,"")}.fd`;if(s===i||s.startsWith(`${i}/`)||s===o||s.startsWith(`${o}/`))return!1}return n.some(r=>{let i=mn(r);return!!i&&s.startsWith(i)})}function gn(n,e,t){let s=ge(n),r=ge(e);return s===r?ge(t):s.startsWith(`${r}/`)?ge(t)+s.slice(r.length):null}function lt(n,e,t){let s=!1,r=n.map(i=>{let o=gn(i,e,t);return o===null?i:(s=!0,o)});return{changed:s,next:r}}async function Fr(n){let e=await Ur.readdir(n,{withFileTypes:!0}).catch(()=>[]),t=[];for(let s of e)!s.isDirectory()||s.name.startsWith(".")||await Ur.access(zi.join(n,s.name,hn)).then(()=>!0,()=>!1)&&t.push(s.name);return t.sort()}var oe={get:"amadeus:sync:get",setEnabled:"amadeus:sync:set-enabled",syncNow:"amadeus:sync:now",confirmDeletions:"amadeus:sync:confirm-deletions",status:"amadeus:sync:status",switchSide:"amadeus:sync:switch-side",collabCall:"amadeus:collab:call",presence:"amadeus:collab:presence",entryGet:"amadeus:entry-sync:get",entryEnable:"amadeus:entry-sync:enable",entryDisable:"amadeus:entry-sync:disable",entryClosure:"amadeus:entry-sync:closure",entryChange:"amadeus:entry-sync:change",otherSideDbs:"amadeus:entry-sync:other-side-dbs"};import{createHash as Wi}from"node:crypto";var Mt=n=>Wi("sha256").update(n).digest("hex").slice(0,8);function Or(n){return n.replace(/ \(conflict \d{4}-\d{2}-\d{2} \d{4}\)(?=(?:\.[^./]+)?$)/,"")}function Me(n,e=[]){let t=[],s=[];for(let r of n){let i=ge(r.path);if(!i)continue;s.push(i);let o=mn(r);o&&t.push(o)}return{entries:n,exclude:e,prefixes:t,paths:s}}function jr(n,e){let t=Or(ge(e));if(!t)return!1;if(Xe(n.entries,n.exclude,t))return!0;let s=`${t}/`;for(let r of n.paths)if(r.startsWith(s))return!0;for(let r of n.prefixes)if(r.startsWith(s))return!0;return!1}function ct(n,e,t){let s=!1,r=n.map(i=>{let o=gn(i.path,e,t);return o===null?i:(s=!0,{...i,path:o})});return{changed:s,next:r}}function Lr(n,e,t,s){if(e==="delete"||e==="delete-folder"){let r=ge(t),i=n.filter(o=>{let a=ge(o.path);return!(a===r||e==="delete-folder"&&a.startsWith(`${r}/`))});return{changed:i.length!==n.length,next:i}}return s?ct(n,t,s):{changed:!1,next:n}}function yn(n,e){let t=Ve(n);return!t||t!==n.normalize("NFC").trim()?"\u540D\u79F0\u4E0D\u5408\u6CD5":t.includes("/")?"\u540D\u79F0\u4E0D\u80FD\u5305\u542B /":t===Dt?`\u300C${Dt}\u300D\u662F\u4FDD\u7559\u540D\u79F0`:e.includes(t)?"\u8BE5\u540D\u79F0\u5DF2\u88AB\u5176\u4ED6\u667A\u5E93\u7684\u4E91\u540C\u6B65\u5360\u7528":null}var Hr=["setAmadeusSyncFactory","readCreds","accountId","homeDir"],wn=n=>Hr.every(e=>typeof n[e]=="function"),qi=()=>({enabled:!1,state:"disabled",lastSyncAt:null,pending:0,conflicts:0,skipped:[],error:null,pendingDeletions:0,maxFileBytes:null,side:"local"});function bn(n){let e=null,t=()=>{if(!e)throw new Error("Cloud sync is not ready");return e};n.handle(oe.get,()=>e?e.get():qi()),n.handle(oe.setEnabled,(s,r)=>t().setEnabled(r)),n.handle(oe.syncNow,()=>t().syncNow()),n.handle(oe.confirmDeletions,()=>t().confirmDeletions()),n.handle(oe.entryGet,()=>t().entryGet()),n.handle(oe.otherSideDbs,()=>t().otherSideDbs()),n.handle(oe.entryEnable,(s,r)=>t().entryEnable(r)),n.handle(oe.entryDisable,(s,r)=>t().entryDisable(r)),n.handle(oe.entryClosure,(s,r,i)=>t().entryClosure(r,i)),n.handle(oe.collabCall,(s,r,i)=>t().collabCall(r,i)),n.handle(oe.switchSide,(s,r)=>t().switchSide(s.sender.id,r)),n.setAmadeusSyncFactory(s=>{Zn(s);let r=zr(s);return e=r.handlers,r.instance}),n.log("[forsion-extend] amadeus cloud sync registered")}function zr(n){let e=n.notifyAll,t=()=>n.vaultRoot(),s=0,r=!1,i=fn(),o=new Map,a=()=>{let _=Date.now();for(let[C,w]of o)_-w.at>7e4&&o.delete(C);e(oe.presence,[...o.values()])},c={loadCreds:()=>n.readCreds(),onStatus:_=>e(oe.status,{..._,pendingDeletions:ne(),side:v()?"cloud":"local"}),onPresence:(_,C)=>{let w=C;w?.userId&&(o.set(w.userId,{userId:w.userId,username:String(w.username??"user"),page:w.page??null,at:Number(w.at)||Date.now()}),a())},onPresenceRoster:(_,C)=>{if(Array.isArray(C)){for(let w of C){let b=w;b?.userId&&o.set(b.userId,{userId:b.userId,username:String(b.username??"user"),page:b.page??null,at:Number(b.at)||Date.now()})}a()}}},h=()=>{let _=s;return{...c,onStatus:C=>{_===s&&c.onStatus(C)},onPresence:(C,w)=>{_===s&&c.onPresence(C,w)},onPresenceRoster:(C,w)=>{_===s&&c.onPresenceRoster(C,w)}}},d=at(h()),f=new Map,u=[],y=async()=>{if(!r||!he())return;let _=s,C=i,w;try{w=await C.sharedWithMe()}catch{return}if(_!==s||!r)return;let b=w.map(S=>dn(S));u=b;let P=new Set(b.map(S=>S.key));for(let[S,T]of f)if(!P.has(S)){if(await T.engine.stop(),_!==s)return;f.delete(S)}for(let S of b){if(f.has(S.key))continue;let T=at(h(),{localRoot:je.join($e(),...S.localRelDir.split("/")),shadowName:`amadeus-sync-${rt()}-share-${S.key}`,vaultId:S.vaultId,serverDir:S.serverDir,inScope:S.inScope});f.set(S.key,{engine:T,plan:S}),T.start()}},v=()=>t()===$e(),x=(_,C=_.base)=>{_.base=C;let w=[C,..._.pendingMoves];_.scope.current=Me(w.flatMap(b=>b.entries),w.flatMap(b=>b.exclude))},E=new Map,U=new Set,M=()=>{e(oe.entryChange)},Y=async(_,C)=>{let w=E.get(_);if(!w)return;let b=T=>T&&T.startsWith(`${w.cloudName}/`)?T.slice(w.cloudName.length+1):null,P=b(C.path);if(!P)return;let S=!1;await We(T=>{if(E.get(_)!==w)return!1;let $=(T.entrySync??[]).find(V=>V.vaultRoot===_);if(!$)return!1;let L=C.op,F=b(C.newPath),O=Lr($.entries,L,P,F),G=F?lt($.exclude??[],P,F):{changed:!1,next:$.exclude??[]};if(!O.changed&&!G.changed)return!1;S=!0,$.entries=O.next,G.changed&&($.exclude=G.next),x(w,Me($.entries,$.exclude??[]))}),S&&E.get(_)===w&&M()},B=_=>{let C=s;return{...h(),onStatus:w=>{C===s&&e(oe.status,{...w,pendingDeletions:ne(),side:"local",binding:_})},onRemoteApplied:async w=>{C===s&&await Y(_,w)}}},q=async()=>{let _=he();if(!r||!_)return;let C=s,w=i,b=rt(_);await n.adoptLegacyCloudState(_,Pr);let P=await ve(_),S=P.entrySync??[];if(C!==s||!r||_!==he())return;let T=new Map(S.map($=>[$.vaultRoot,$]));for(let[$,L]of E){let F=T.get($);if(!(F&&F.cloudName===L.cloudName)&&(await L.engine.stop(),C!==s||(E.delete($),F&&await Ir(`amadeus-sync-${b}-entry-${Mt($)}`),C!==s)))return}for(let $ of S){let L=E.get($.vaultRoot);if(L){x(L,Me($.entries,$.exclude??[]));continue}let F={current:Me($.entries,$.exclude??[])},O=$.cloudName,G=at(B($.vaultRoot),{accountId:_,localRoot:$.vaultRoot,shadowName:`amadeus-sync-${b}-entry-${Mt($.vaultRoot)}`,vaultId:"first",serverDir:O,clientIdSuffix:`entry-${Mt($.vaultRoot)}`,requireRootExists:!0,ignoreNames:[".git","node_modules",".trash"],inScope:V=>V===O?!0:V.startsWith(`${O}/`)?jr(F.current,V.slice(O.length+1)):!1});E.set($.vaultRoot,{engine:G,scope:F,cloudName:O,base:F.current,pendingMoves:new Set}),G.start()}if(P.cloudSync?.enabled!==!1)for(let $ of S)U.has($.cloudName)||(async()=>{try{let L=await w.ensureOwnVault();await w.call("PUT",`/vaults/${encodeURIComponent(L)}/file`,{path:pn($.cloudName),content:"",baseSeq:0}),C===s&&U.add($.cloudName)}catch(L){L?.status===409&&C===s&&U.add($.cloudName)}})()},Q=async(_,C,w,b,P)=>{let S=C.replace(/\\/g,"/").normalize("NFC"),T=w.replace(/\\/g,"/").normalize("NFC"),$=!1,L,F,O,G=P??"file";try{await We(async V=>{if(E.get(_)!==b)return!1;let W=(V.entrySync??[]).find(ie=>ie.vaultRoot===_);if(!W)return!1;let Z=ct(W.entries,S,T),X=lt(W.exclude??[],S,T),we=Xe(W.entries,W.exclude,S);!P&&await Ke.stat(je.join(_,...T.split("/"))).then(ie=>ie.isDirectory(),()=>!1)&&(G="folder");let Ue=G==="folder"?"folder":/\.md$/i.test(T)?"page":"asset";we&&!Xe(Z.next,X.next,T)&&(Z.next.push({path:T,kind:Ue}),Z.changed=!0),$=Z.changed||X.changed;let Le=W.entries.filter(ie=>ct([ie],S,T).changed);return we&&!Le.some(ie=>ie.path===S)&&Le.push({path:S,kind:Ue}),L=Me(Le,(W.exclude??[]).filter(ie=>lt([ie],S,T).changed)),F=b.base,b.pendingMoves.add(L),W.entries=Z.next,W.exclude=X.next,O=Me(W.entries,W.exclude),x(b,O),$})}catch(V){throw L&&b.pendingMoves.delete(L),x(b,b.base===O&&F?F:b.base),V}try{L&&await b.engine.notifyLocalMove(S,T,()=>{b.pendingMoves.delete(L),x(b)},G)}catch(V){throw L&&b.pendingMoves.delete(L),await We(W=>{let Z=W.entrySync?.find(X=>X.vaultRoot===_);if(!Z)return!1;Z.entries=ct(Z.entries,T,S).next,Z.exclude=lt(Z.exclude??[],T,S).next,x(b,Me(Z.entries,Z.exclude))}),V}$&&E.get(_)===b&&M()},J=_=>{let C=_.replace(/\\/g,"/");for(let{engine:w,plan:b}of f.values())if(C.startsWith(`${b.localRelDir}/`))return{engine:w,rel:C.slice(b.localRelDir.length+1)};return{engine:d,rel:C}};n.setMutationHooks((_,C)=>{if(v()){let w=J(_);w.engine.notifyLocal(w.rel,C);return}E.get(t()??"")?.engine.notifyLocal(_,C)},(_,C,w)=>{if(v()){let S=J(_),T=J(C);if(S.engine===T.engine)return S.engine.notifyLocalMove(S.rel,T.rel,void 0,w);S.engine.notifyLocal(S.rel,"remove"),T.engine.notifyLocal(T.rel,"write");return}let b=t()??"",P=E.get(b);if(P)return Q(b,_,C,P,w)},(_,C)=>{if(v()){let w=J(_),b=J(C),P=[w.engine.holdLocalMove(w.rel,b.rel)];return w.engine!==b.engine&&P.push(b.engine.holdLocalMove(w.rel,b.rel)),()=>{for(let S of P)S()}}return E.get(t()??"")?.engine.holdLocalMove(_,C)});let ne=()=>{let _=d.getStatus().pendingDeletions;for(let{engine:C}of f.values())_+=C.getStatus().pendingDeletions;for(let{engine:C}of E.values())_+=C.getStatus().pendingDeletions;return _},ue=_=>({..._,pendingDeletions:ne(),side:v()?"cloud":"local"}),ft=()=>{if(!r)return Promise.resolve(d.getStatus());y();for(let{engine:_}of f.values())_.syncNow();for(let{engine:_}of E.values())_.syncNow();return d.syncNow()},Qe=async()=>{++s,r=!1,i.stop();let _=[d.stop(),...[...f.values()].map(({engine:w})=>w.stop()),...[...E.values()].map(({engine:w})=>w.stop())];f.clear(),E.clear(),u=[],U.clear(),o.clear(),a(),await Promise.all(_),await n.awaitPendingVaultWrites();let C=t();if(C&&Et(C)){let w=await ve(),b=w.localVault&&!Et(w.localVault)?w.localVault:je.join(n.workspaceDir(),"Amadeus");await Ke.mkdir(b,{recursive:!0}),await Pe({lastVault:b,localVault:b,lastPage:void 0}),await n.activateRoot(b,!1)}M()};return{handlers:{get:()=>ue(d.getStatus()),setEnabled:async _=>{if(!r)throw new Error("Cloud account is changing");let C=s;return await d.setEnabled(_),C!==s?d.getStatus():(await Promise.all([...f.values(),...E.values()].map(({engine:w})=>w.restart())),ue(d.getStatus()))},syncNow:()=>ft(),confirmDeletions:()=>{for(let{engine:_}of f.values())_.confirmMassDeletions();for(let{engine:_}of E.values())_.confirmMassDeletions();return ue(d.confirmMassDeletions())},entryGet:async()=>{let _=await ve(),C=$e();return{vaults:_.entrySync??[],activeRoot:t(),cloudRoot:C,mirrorVaults:await Fr(C)}},otherSideDbs:async()=>{let _=t();if(!_)return null;let C=$e(),w=await ve(),b=_===C?w.localVault&&w.localVault!==C?w.localVault:null:C;if(!b)return null;let P=[],S=500,T=async($,L)=>{if(P.length>=S)return;let F;try{F=await Ke.readdir($,{withFileTypes:!0})}catch{return}for(let O of F){if(P.length>=S)break;if(O.name.startsWith(".")||O.isSymbolicLink())continue;let G=L?`${L}/${O.name}`:O.name;if(O.isDirectory())await T(je.join($,O.name),G);else if(O.isFile()&&/\.db$/i.test(O.name))try{P.push({rel:G,source:await Ke.readFile(je.join($,O.name),"utf8")})}catch{}}};return await T(b,""),{root:b,vaultName:b===C?"\u4E91\u7AEF":je.basename(b),dbs:P}},entryEnable:async _=>{let C=s,w=i;if(!r||!he())return{error:"Sign in to enable cloud sync"};let b=t();if(!b||v())return{error:"\u4EC5\u672C\u5730 vault \u53EF\u5F00\u542F\u4E91\u540C\u6B65"};let P=await ve(),S=P.entrySync??[],T=S.find($=>$.vaultRoot===b);if(!T){let $=(_.cloudName??je.basename(b)).normalize("NFC").trim(),L=yn($,S.map(F=>F.cloudName));if(L)return{error:L};if(!_.merge)try{let F=await w.ensureOwnVault(),O=await w.call("GET",`/vaults/${encodeURIComponent(F)}/tree`);if((O.folders??[]).some(V=>V===$||V.startsWith(`${$}/`))||(O.entries??[]).some(V=>V.path===$||V.path.startsWith(`${$}/`)))return{conflict:$}}catch(F){return{error:F?.message||"\u65E0\u6CD5\u8FDE\u63A5\u4E91\u7AEF(\u9996\u6B21\u5F00\u542F\u9700\u8981\u5728\u7EBF)"}}T={vaultRoot:b,cloudName:$,entries:[]},S.push(T),(async()=>{try{let F=await w.ensureOwnVault();await w.call("PUT",`/vaults/${encodeURIComponent(F)}/file`,{path:pn(T.cloudName),content:"",baseSeq:0})}catch{}})()}return C!==s||!r?{error:"Cloud account changed; retry from the current account"}:(await We($=>{if(C!==s||!r)return!1;let L=$.entrySync??[],F=L.find(X=>X.vaultRoot===b);if(!F){let X=yn(T.cloudName,L.map(we=>we.cloudName));if(X)throw new Error(X);F={vaultRoot:b,cloudName:T.cloudName,entries:[]},L.push(F)}let O=X=>String(X??"").replace(/\\/g,"/").normalize("NFC"),G=new Set;for(let X of _.entries??[]){let we=O(X.path);we&&(G.add(we),!F.entries.some(Ue=>Ue.path===we)&&F.entries.push({path:we,kind:X.kind==="folder"||X.kind==="asset"?X.kind:"page"}))}let V=(_.exclude??[]).map(O).filter(Boolean),W=new Set([...G,...(_.include??[]).map(O).filter(Boolean)]);F.exclude=[...new Set([...(F.exclude??[]).filter(X=>!W.has(X)),...V])];let Z=new Set(V);F.entries=F.entries.filter(X=>!Z.has(X.path)),$.entrySync=L,T=F},P.cloudAccountId),C!==s?{error:"Cloud account changed; retry from the current account"}:(await q(),E.get(b)?.engine.syncNow(),M(),{ok:!0,cloudName:T.cloudName}))},entryDisable:async _=>{let C=t(),w=!1,b=s;return await We(P=>{if(b!==s||!r)return!1;let S=(P.entrySync??[]).find(L=>L.vaultRoot===C);if(!C||!S)return!1;let T=String(_??"").replace(/\\/g,"/").normalize("NFC"),$=S.entries.length;if(S.entries=S.entries.filter(L=>L.path!==T),Xe(S.entries,S.exclude,T))S.exclude=[...new Set([...S.exclude??[],T])];else if(S.entries.length===$)return!1;w=!0}),!w||b!==s?{ok:!1}:(await q(),M(),{ok:!0})},entryClosure:(_,C)=>n.relatedClosure(String(_??""),C==="folder"?"folder":"page"),collabCall:async(_,C)=>{let w=i,b=async()=>w.ensureOwnVault(),P=T=>String((C??[])[T]??""),S=T=>(C??[])[T]??{};switch(_){case"listVaults":return(await w.call("GET","/vaults")).vaults;case"activeVaultId":return b();case"pageShare":return w.call("GET",`/vaults/${encodeURIComponent(await b())}/page-shares?path=${encodeURIComponent(P(0))}`);case"createPageShare":return w.call("POST",`/vaults/${encodeURIComponent(await b())}/page-shares`,{path:P(0),...S(1)});case"updatePageShare":return w.call("PATCH",`/vaults/${encodeURIComponent(await b())}/page-shares/${encodeURIComponent(P(0))}`,S(1));case"revokePageShare":return w.call("DELETE",`/vaults/${encodeURIComponent(await b())}/page-shares/${encodeURIComponent(P(0))}`);case"setParticipantRole":return w.call("PATCH",`/vaults/${encodeURIComponent(await b())}/page-shares/${encodeURIComponent(P(0))}/members/${encodeURIComponent(P(1))}`,{role:P(2)});case"removeParticipant":return w.call("DELETE",`/vaults/${encodeURIComponent(await b())}/page-shares/${encodeURIComponent(P(0))}/members/${encodeURIComponent(P(1))}`);case"sharedWithMe":{let T=await w.sharedWithMe();return y(),T}case"leaveShare":{let T=w.myUserId();if(!T)throw new Error("\u672A\u767B\u5F55");return w.call("DELETE",`/vaults/${encodeURIComponent(await b())}/page-shares/${encodeURIComponent(P(0))}/members/${encodeURIComponent(T)}`)}case"publishes":return w.call("GET",`/vaults/${encodeURIComponent(await b())}/shares`);case"listAllShares":{let T=(await w.call("GET","/vaults")).vaults||[],$=w.myUserId(),L=[],F=[];for(let O of T){try{let G=await w.call("GET",`/vaults/${encodeURIComponent(O.id)}/shares`);for(let V of G.shares||[])L.push({...V,vaultId:O.id,vaultName:O.name||""})}catch(G){n.log(`[connect] listAllShares publishes vault ${O.id} failed: ${G?.message}`)}try{let G=await w.call("GET",`/vaults/${encodeURIComponent(O.id)}/page-shares`),V=G?.shares||G?.pageShares||(Array.isArray(G)?G:[]);for(let W of V){let Z=W.created_by??W.createdBy;(!$||!Z||Z===$)&&F.push({...W,vaultId:O.id,vaultName:O.name||""})}}catch(G){n.log(`[connect] listAllShares pageShares vault ${O.id} failed: ${G?.message}`)}}return{publishes:L,pageShares:F,linkBase:await w.linkBase()}}case"createPublish":{let T=await w.call("POST",`/vaults/${encodeURIComponent(await b())}/shares`,{mode:P(0),path:P(1)});return{...T,url:`${await w.linkBase()}/share/${T.token}`}}case"revokePublish":return w.call("DELETE",`/vaults/${encodeURIComponent(await b())}/shares/${encodeURIComponent(P(0))}`);case"revokePublishIn":return w.call("DELETE",`/vaults/${encodeURIComponent(P(0))}/shares/${encodeURIComponent(P(1))}`);case"revokePageShareIn":return w.call("DELETE",`/vaults/${encodeURIComponent(P(0))}/page-shares/${encodeURIComponent(P(1))}`);case"myUserId":return w.myUserId();case"linkBase":return w.linkBase();case"heartbeat":return w.heartbeat((C??[])[0]??null,u);default:throw new Error(`unknown collab fn: ${_}`)}},switchSide:async(_,C)=>{let w=await ve();if(C==="cloud"){if(!r||!he())throw new Error("Sign in to open cloud notes");let S=$e();await Ke.mkdir(S,{recursive:!0}),w.lastVault&&!Et(w.lastVault)&&await Pe({localVault:w.lastVault}),await Pe({lastVault:S});let T=await n.activateRoot(S,!1);return n.bindRenderer(_,S),{...T,side:"cloud"}}let b=w.localVault&&await Ke.stat(w.localVault).then(S=>S.isDirectory()).catch(()=>!1)?w.localVault:null;if(!b){let S=await n.ensureDefaultVault();return n.bindRenderer(_,S.root),{...S,side:"local"}}await Pe({lastVault:b});let P=await n.activateRoot(b,!1);return n.bindRenderer(_,b),{...P,side:"local"}}},instance:{start:()=>{r=!0,d.start(),y(),q()},stopAllSync:Qe,restartAllSync:async()=>{await Qe(),i=fn(),d=at(h()),r=!0,await Promise.all([d.restart(),y(),q()]),M(),e(oe.status,ue(d.getStatus()))}}}}import{hostname as Bi}from"node:os";var Vi=256*1024;function Wr(n,e,t){if(t?.hasSecHeaders&&!t.gatewayStreamsSecHeaders)return!1;if(n.includes("text/event-stream"))return!0;let s=Number(e||NaN);return!Number.isFinite(s)||s>Vi}var Sn=45e3,Gi=3e3,Yi=16*1024,Ji=6e4,Nt=n=>`${n.replace(/\/+$/,"")}/api`,ut=class{deps;ctrl=null;conn=null;wake=null;redialNow=!1;inflight=new Map;connected=!1;lastError=null;hubCaps=new Set;constructor(e){this.deps=e}hubFetch(e,t){return(this.deps.hubFetch??fetch)(e,t)}get requestTimeoutMs(){return this.deps.requestTimeoutMs??Ji}status(){return{running:!!this.ctrl,connected:this.connected,unitId:this.deps.getPairing()?.unitId??null,lastError:this.lastError}}start(){if(this.ctrl)return;let e=new AbortController;this.ctrl=e,this.loop(e)}stop(){this.ctrl?.abort(),this.ctrl=null,this.markDown(),this.abortEnvelopes(),this.wake?.()}reconnect(e){this.ctrl&&(this.deps.log(`[unit-host] \u7ACB\u5373\u91CD\u8FDE\u901A\u9053(${e})`),this.redialNow=!0,this.conn?.abort(),this.wake?.())}markDown(){this.connected=!1,this.hook(this.deps.onChannelDown)}hook(e){try{e?.()}catch(t){this.deps.log(`[unit-host] \u901A\u9053\u56DE\u8C03\u51FA\u9519(\u5DF2\u5FFD\u7565): ${t?.message||t}`)}}abortEnvelope(e){let t=this.inflight.get(e);return t?(this.inflight.delete(e),t.ctrl.abort(),!0):!1}abortEnvelopes(e){for(let[t,s]of[...this.inflight])e&&s.conn!==e||(this.inflight.delete(t),s.ctrl.abort())}sleep(e){return new Promise(t=>{let s=setTimeout(r,e);function r(){clearTimeout(s),t()}this.wake=()=>{this.wake=null,r()}})}async loop(e){let t=1e3;for(;!e.signal.aborted;){let s=new AbortController,r=()=>s.abort();e.signal.addEventListener("abort",r,{once:!0}),this.conn=s;try{let{cloudUrl:i,token:o}=this.deps.getCreds();if(!o)throw new Error("\u672A\u767B\u5F55 Forsion \u8D26\u53F7");let a=this.deps.getPairing();if(!a){if(a=await this.register(i,o,s),s.signal.aborted)throw new Error("\u5165\u518C\u671F\u95F4\u901A\u9053\u5DF2\u88AB\u505C\u7528");await this.deps.savePairing(a),this.deps.log(`[unit-host] \u5DF2\u5165\u518C\u4E3A\u8BBE\u5907 ${a.unitId}`)}let c=this.deps.getLanUrl();this.hubCaps=new Set;let h=this.deps.readIdleMs??Sn,d=h?setTimeout(()=>{this.deps.log(`[unit-host] \u901A\u9053 ${Math.round(h/1e3)}s \u672A\u6536\u5230\u54CD\u5E94\u5934,\u5224\u5B9A\u5DF2\u65AD,\u91CD\u8FDE`),s.abort()},h):null,f;try{f=await this.hubFetch(`${Nt(i)}/units/${a.unitId}/channel`,{headers:{Authorization:`Bearer ${o}`,"X-Unit-Secret":a.secret,...c?{"X-Unit-Lan-Url":c}:{}},signal:s.signal})}finally{d&&clearTimeout(d)}if(f.status===403||f.status===404){let u=Number(f.headers.get("content-length"))>Yi,y=setTimeout(()=>s.abort(),u?0:Gi),v=await f.json().then(x=>x?.code,()=>null);throw clearTimeout(y),v==="UNIT_NOT_FOUND"||v==="UNIT_SECRET_MISMATCH"?(await this.deps.clearPairing(),new Error(`\u901A\u9053\u88AB\u62D2(${f.status} ${v}),\u5DF2\u6E05\u9664\u914D\u5BF9\u5F85\u91CD\u65B0\u5165\u518C`)):new Error(`channel HTTP ${f.status} (not a hub verdict; keeping pairing and retrying)`)}if(!f.ok||!f.body)throw new Error(`channel HTTP ${f.status}`);this.connected=!0,this.lastError=null,t=1e3,this.deps.log("[unit-host] \u901A\u9053\u5DF2\u8FDE\u63A5"),await this.consume(f.body,s),this.markDown(),this.deps.log("[unit-host] \u901A\u9053\u65AD\u5F00,\u51C6\u5907\u91CD\u8FDE")}catch(i){if(this.markDown(),e.signal.aborted)return;this.lastError=s.signal.aborted?"\u901A\u9053\u88AB\u672C\u673A\u65AD\u5F00(\u770B\u95E8\u72D7 / \u91CD\u8FDE)":String(i?.message||i),this.deps.log(`[unit-host] ${this.lastError};${this.redialNow?"\u7ACB\u5373":`${Math.round(t/1e3)}s \u540E`}\u91CD\u8BD5`)}finally{e.signal.removeEventListener("abort",r),this.conn===s&&(this.conn=null),s.abort(),this.abortEnvelopes(s)}if(e.signal.aborted)return;if(this.redialNow){this.redialNow=!1,t=1e3;continue}if(await this.sleep(t),this.redialNow){this.redialNow=!1,t=1e3;continue}t=Math.min(t*2,3e4)}}async register(e,t,s){let r=this.deps.readIdleMs??Sn,i=r?setTimeout(()=>{this.deps.log(`[unit-host] \u8BBE\u5907\u5165\u518C ${Math.round(r/1e3)}s \u672A\u8FD4\u56DE,\u4E2D\u6B62\u91CD\u8BD5`),s.abort()},r):null;try{let o=await this.hubFetch(`${Nt(e)}/units/register`,{method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:JSON.stringify({name:Bi(),platform:process.platform}),signal:s.signal});if(!o.ok)throw new Error(`\u8BBE\u5907\u5165\u518C\u5931\u8D25 HTTP ${o.status}`);let a=await o.json();if(!a.unitId||!a.secret)throw new Error("\u8BBE\u5907\u5165\u518C\u54CD\u5E94\u7F3A\u5B57\u6BB5");return{unitId:a.unitId,secret:a.secret}}finally{i&&clearTimeout(i)}}async consume(e,t){let s=e.getReader(),r=new TextDecoder,i="",o=this.deps.readIdleMs??Sn,a=null,c=()=>{o&&(a&&clearTimeout(a),a=setTimeout(()=>{this.deps.log(`[unit-host] \u901A\u9053 ${Math.round(o/1e3)}s \u65E0\u4EFB\u4F55\u5B57\u8282(\u7F51\u5173 15s \u4E00\u6B21\u5FC3\u8DF3),\u5224\u5B9A\u5DF2\u65AD,\u91CD\u8FDE`),t.abort(),s.cancel().catch(()=>{})},o))};c();try{for(;;){let{done:h,value:d}=await s.read();if(h||t.signal.aborted)return;c(),i=this.parseFrames(i+r.decode(d,{stream:!0}),t)}}finally{a&&clearTimeout(a)}}parseFrames(e,t){let s=e,r;for(;(r=s.indexOf(`
195
+ `),n.split(`
196
+ `),{excludeFalseConflicts:!0}),s=[];for(let i of r){if(i.conflict)return null;i.ok&&s.push(...i.ok)}return s.join(`
197
+ `)}function bn(t,e,n=200){return t>=n||e>=5&&t>=Math.max(5,Math.ceil(e/2))}var eo=/[\u0000-\u001f\u007f]/;function Xe(t){let e=t.replace(/\\/g,"/").normalize("NFC").trim();if(e=e.replace(/\/+$/,""),!e||e.length>512||e.startsWith("/")||eo.test(e))return null;let n=e.split("/");for(let r of n)if(!r||r==="."||r==="..")return null;return n.join("/")}function Sn(t,e){let n=t.replace(/\\/g,"/").normalize("NFC");return e===""?Xe(n):n.startsWith(`${e}/`)?Xe(n.slice(e.length+1)):null}function jr(t,e){return e===""?t:`${e}/${t}`}function ft(t){return!!(t===".DS_Store"||t==="Icon\r"||t===".sync-trash"||/\.tmp-\d+-\d+-\d+$/.test(t)||/^\..+\.lock$/.test(t))}function Pe(t){return/\.md$/i.test(t)?"page":/\.db$/i.test(t)?"db":"binary"}var je=t=>t==="page"||t==="db";import{gzip as to}from"node:zlib";import{promisify as no}from"node:util";var ro=no(to),so=1024,fe=class extends Error{status;body;constructor(e,n,r){super(`cloud http ${e} on ${r}`),this.status=e,this.body=n}},Lr=t=>12e4+Math.ceil(t/256);function Hr(t){let e=`${t.baseUrl.replace(/\/+$/,"")}/api/amadeus`,n=async(s,i,a)=>{let o={Authorization:`Bearer ${t.token}`,...a?.headers};s!=="GET"&&(o["X-Amadeus-Client"]=t.clientId);let l;a?.json!==void 0?(o["Content-Type"]="application/json",l=JSON.stringify(a.json),l.length>=so&&(o["Content-Encoding"]="gzip",l=await ro(l))):a?.form&&(l=a.form);let h=await fetch(i,{method:s,headers:o,body:l,signal:AbortSignal.timeout(a?.timeoutMs??3e4)});if(!h.ok){let d=null;try{d=await h.json()}catch{}throw new fe(h.status,d,i)}return h.json()},r=s=>new URLSearchParams(s).toString();return{clientId:t.clientId,async listVaults(){return((await n("GET",`${e}/vaults`)).vaults??[]).map(i=>({id:String(i.id),name:String(i.name),lastChangeSeq:Number(i.lastChangeSeq??0)}))},async tree(s){let i=await n("GET",`${e}/vaults/${s}/tree`);if(!Array.isArray(i.entries))throw new Error("server too old: tree has no entries[] (deploy the amadeus microserver update)");return{folders:i.folders??[],seq:Number(i.seq??0),maxFileBytes:Number.isInteger(i.maxFileBytes)&&i.maxFileBytes>0?i.maxFileBytes:void 0,entries:i.entries.map(a=>({path:String(a.path),kind:a.kind,seq:Number(a.seq??0),hash:a.hash??null,size:Number(a.size??0)}))}},async getFile(s,i){let a=await n("GET",`${e}/vaults/${s}/file?${r({path:i})}`);return{content:String(a.content??""),seq:Number(a.seq??0),hash:a.hash??null}},putFile(s,i,a,o,l=!1){return n("PUT",`${e}/vaults/${s}/file`,{json:{path:i,content:a,baseSeq:o,...l?{force:!0}:{}}})},async deleteFile(s,i,a,o){let l={path:i};a!==void 0&&(l.baseSeq=String(a)),await n("DELETE",`${e}/vaults/${s}/file?${r(l)}`,o?.confirmed?{headers:{"X-Amadeus-Delete-Confirmed":"1"}}:void 0)},move(s,i,a){return n("POST",`${e}/vaults/${s}/move`,{json:{from:i,to:a}})},renameFolder(s,i,a){return n("POST",`${e}/vaults/${s}/folders/rename`,{json:{path:i,newName:a}})},moveFolder(s,i,a){return n("POST",`${e}/vaults/${s}/folders/move`,{json:{path:i,dest:a}})},async deleteFolder(s,i){await n("DELETE",`${e}/vaults/${s}/folders?${r({path:i})}`)},putBinary(s,i,a,o){let l=new FormData;return l.set("path",i),o?.ifAbsent&&l.set("ifAbsent","true"),o?.baseSeq!==void 0&&l.set("baseSeq",String(o.baseSeq)),l.set("file",new Blob([new Uint8Array(a)]),i.split("/").pop()||"file"),n("POST",`${e}/vaults/${s}/binary`,{form:l,timeoutMs:Lr(a.length)})},async listVersions(s,i){return((await n("GET",`${e}/vaults/${s}/file/versions?${r({path:i})}`)).versions??[]).map(o=>({id:String(o.id),seq:Number(o.seq??0)}))},async getVersion(s,i){let a=await n("GET",`${e}/vaults/${s}/file/versions/${i}`);return String(a.content??"")},async getAsset(s,i){let a=new AbortController,o=setTimeout(()=>a.abort(),12e4);try{let l=await fetch(`${e}/vaults/${s}/asset?${r({ref:i})}`,{headers:{Authorization:`Bearer ${t.token}`},signal:a.signal});if(!l.ok)throw new fe(l.status,null,"asset:"+i);return clearTimeout(o),o=setTimeout(()=>a.abort(),Lr(Number(l.headers.get("content-length"))||0)),Buffer.from(await l.arrayBuffer())}finally{clearTimeout(o)}},async changes(s,i){let a=await n("GET",`${e}/vaults/${s}/changes?${r({since:String(i)})}`);return{changes:a.changes??[],seq:Number(a.seq??0)}}}}function zr(t,e){let n=!1,r=0,s=null,i=null,a=()=>`${t.baseUrl.replace(/\/+$/,"")}/api/amadeus/vaults/${t.vaultId}/events?since=${e.getSince()}`,o=h=>{if(n)return;e.onDown(h);let d=Math.min(3e4,1e3*2**r)*(.7+Math.random()*.6);r++,i=setTimeout(()=>void l(),d)},l=async()=>{if(n)return;s=new AbortController;let h;try{h=await fetch(a(),{headers:{Authorization:`Bearer ${t.token}`,Accept:"text/event-stream"},signal:s.signal})}catch(w){o(w);return}if(!h.ok||!h.body){o(new Error(`sse http ${h.status}`));return}r=0,e.onOpen();let d=h.body.getReader(),f=new TextDecoder,u="",g="",S=[],x=()=>{if(!S.length&&!g)return;let w=S.join(`
198
+ `),F=g||"message";g="",S=[];let k=null;try{k=w?JSON.parse(w):null}catch{return}F==="hello"?e.onHello(Number(k?.seq??0)):F==="change"?e.onChange(k):F==="reset"?e.onReset():F==="presence"?e.onPresence?.(k):F==="presence-roster"&&e.onPresenceRoster?.(k)};try{for(;;){let{done:w,value:F}=await d.read();if(w)break;for(u+=f.decode(F,{stream:!0});;){let k=u.indexOf(`
199
+ `);if(k<0)break;let A=u.slice(0,k).replace(/\r$/,"");if(u=u.slice(k+1),A==="")x();else{if(A.startsWith(":"))continue;A.startsWith("event:")?g=A.slice(6).trim():A.startsWith("data:")&&S.push(A.slice(5).replace(/^ /,""))}}}}catch(w){n||o(w);return}o(new Error("sse stream ended"))};return l(),{stop:()=>{n=!0,i&&clearTimeout(i),s?.abort()}}}import{constants as io,promises as Qe}from"node:fs";import oo from"node:path";var Ze=t=>oo.join(pe().userDataDir(),pe().isDevMode()?`${t}.dev.json`:`${t}.json`);async function vn(t){try{let e=JSON.parse(await Qe.readFile(Ze(t),"utf8"));return!e||typeof e.vaultRoot!="string"||typeof e.vaultId!="string"?null:(e.files=e.files??{},e.cursor=Number(e.cursor??0),e.lastSyncAt=e.lastSyncAt??null,e)}catch{return null}}function qr(t){let e=null,n=null,r=Promise.resolve(),s=null,i=()=>{if(!e)return r;let a=e,o=JSON.stringify(e);return e=null,r=r.then(async()=>{try{let l=Ze(t),h=`${l}.tmp-${process.pid}-${Date.now()}-0`;await Qe.writeFile(h,o,"utf8"),await Qe.rename(h,l),s=null}catch(l){e??=a,s=l}}),r};return{save(a){e=a,!n&&(n=setTimeout(()=>{n=null,i()},500))},async flush(a=!1){if(n&&(clearTimeout(n),n=null),await i(),a&&s)throw s}}}async function Br(t){try{await Qe.unlink(Ze(t))}catch{}}async function Wr(t,e){try{await Qe.copyFile(Ze(t),Ze(e),io.COPYFILE_EXCL)}catch(n){let r=n?.code;if(r==="EEXIST"||r==="ENOENT")return!1;throw n}return await Qe.unlink(Ze(t)).catch(()=>{}),!0}var lo=5*1024*1024,co=5*1024*1024,uo=3e4,fo=2500,ho=3e3,mo=5,go=256*1024,po=5,Yr=1024*1024,Gr=200,yo=6e4,wo=50,bo=".sync-trash",et=t=>ao("sha256").update(t).digest("hex");function ht(t,e={localRoot:Fe(),shadowName:`amadeus-sync-${ct()}`,vaultId:"first",serverDir:"",excludePrefixes:["\u4E0E\u6211\u5171\u4EAB/"]}){let n=c=>{let m=Sn(c,"");if(!m)return null;for(let p of e.excludePrefixes??[])if(m===p.replace(/\/$/,"")||m.startsWith(p))return null;if(e.ignoreNames?.length&&m.split("/").some(p=>e.ignoreNames.includes(p)))return null;let y=e.serverDir?`${e.serverDir}/${m}`:m;return e.inScope&&!e.inScope(y,Pe(y))?null:y},r=c=>{let m;if(e.serverDir){if(!c.startsWith(`${e.serverDir}/`))return null;m=c.slice(e.serverDir.length+1)}else{for(let y of e.excludePrefixes??[])if(c.startsWith(y))return null;m=c}return m.split("/").some(y=>ft(y)||!!e.ignoreNames?.includes(y))?null:m},s=(c,m)=>!e.inScope||e.inScope(c,m),i=e.accountId??ye(),a=!1,o=0,l=Promise.resolve(),h=new Set,d="disabled",f=null,u=null,g=null,S=null,x=null,w=null,F=0,k=new Map,A=null,U=qr(e.shadowName),M=new Map,B=!1,j=!1,K=[],se=()=>{u&&(u.pending=M.size?Object.fromEntries(M):void 0,U.save(u))},he=()=>{j=!1,K.length=0},we=()=>{if(j)return!0;let c=Date.now();for(;K.length&&c-K[0]>yo;)K.shift();return K.length>=wo?(j=!0,!0):!1},ae=[],Ee=new Set,De=!1,_=null,C=null,b=null,v=()=>{!a||b||(b=setTimeout(()=>{b=null,t.onStatus(ze())},200))},D=(c,m)=>{d=c,m!==void 0&&(f=m),v()},E=(c,m=!1)=>{if(a){if(c.key){if(Ee.has(c.key))return;Ee.add(c.key)}m?ae.unshift(c):ae.push(c),X()}},I=new Map,N=c=>{if(!a)return;let m=(u?.files[c]?.size??0)>go,y=(e.pushQuietMs??ho)*(m?po:1),p=Date.now(),T=I.get(c);T&&clearTimeout(T.timer);let P=T?.since??p,O=Math.max(0,Math.min(y,P+y*mo-p)),R=setTimeout(()=>{I.delete(c),E({key:c,run:()=>de(c,!0)})},O);I.set(c,{timer:R,since:P}),v()},W=()=>{for(let{timer:c}of I.values())clearTimeout(c);I.clear()},H=c=>!(c instanceof fe)||c.status>=500||c.status===0,z=c=>c instanceof fe&&(c.status===401||c.status===403),X=async()=>{if(!De){De=!0;try{for(;ae.length;){(d==="idle"||d==="starting")&&D("syncing");let c=ae.shift();c.key&&Ee.delete(c.key);try{await c.run()}catch(m){if(!a)return;if(z(m)){ae.length=0,Ee.clear(),kt(),D("auth-required","login-expired");return}if(H(m)){E(c,!0),kt(),D("offline",m?.message||"network error"),J();return}let y=c.key??"(op)";k.set(y,m?.body?.code||`http ${m?.status}`),v()}}a&&d==="syncing"&&(u&&(u.lastSyncAt=Date.now(),U.save(u)),D("idle",null))}finally{De=!1;for(let c of h)c();h.clear()}}},J=()=>{!a||_||(_=setTimeout(()=>{_=null,at()},uo))},G=c=>{if(!w||!u)throw new Error("engine not bound");let m=r(c);if(m===null)throw new Error("path outside binding: "+c);let y=oe.resolve(w,jr(m,u.folder)),p=oe.relative(w,y);if(p.startsWith("..")||oe.isAbsolute(p))throw new Error("path escapes vault: "+c);return y},ee=c=>({size:c,mtimeMs:-1}),Z=async c=>{try{let m=await ne.stat(c);return m.isFile()?{size:m.size,mtimeMs:Math.floor(m.mtimeMs)}:null}catch{return null}},_e=0,He=async(c,m,y=()=>!0)=>{await ne.mkdir(oe.dirname(c),{recursive:!0});let p=`${c}.tmp-${process.pid}-${Date.now()}-${_e++}`;await ne.writeFile(p,m);let T=await Z(p)??ee(Buffer.byteLength(m));return y()?(await ne.rename(p,c),T):(await ne.rm(p,{force:!0}),null)},We=async c=>{let m;try{m=await ne.readdir(c,{withFileTypes:!0})}catch{return}for(let y of m)y.isDirectory()&&await We(oe.join(c,y.name));try{await ne.rmdir(c)}catch{}},le=async c=>{let m=G(c),y=await Z(m),p;try{p=await ne.readFile(m)}catch{return null}return{hash:je(Pe(c))?et(p.toString("utf8")):et(p),size:y?.size??p.length,mtimeMs:y?.mtimeMs??-1,buf:p}},Ie=async(c,m,y,p)=>{u&&(u.files[c]={seq:m,hash:y,size:p.size,mtimeMs:p.mtimeMs},U.save(u))},ke=c=>{u&&c in u.files&&(delete u.files[c],U.save(u))},$e=async(c,m)=>{if(!g||!u||Ce(c))return;let y=ie,p=Pe(c),T,P,O;if(je(p)){let q;try{q=await g.getFile(u.vaultId,c)}catch(V){if(V instanceof fe&&V.status===404){await Yt(c);return}throw V}T=q.content,P=q.seq,O=q.hash??et(q.content)}else{let q;try{q=await g.getAsset(u.vaultId,c)}catch(V){if(V instanceof fe&&V.status===404){k.set(c,"ASSET_404"),v();return}throw V}T=q,P=m??0,O=et(q)}let R=await le(c);if(y!==ie||Ce(c))return;if(R&&R.hash===O){await Ie(c,P,O,R);return}let L=u.files[c];if(R&&L&&O===L.hash&&R.hash!==L.hash){await Ie(c,P,O,ee(L.size)),E({key:c,run:()=>de(c)});return}if(R&&(!L||R.hash!==L.hash)){if(L&&p==="page"&&typeof T=="string"&&await xs(c,L,R,T,P,O,()=>y===ie&&!Ce(c))||y!==ie||Ce(c))return;await As(c)}let $=await He(G(c),T,()=>y===ie&&!Ce(c));$&&await Ie(c,P,O,$)},xs=async(c,m,y,p,T,P,O)=>{try{if(!g||!u||y.buf.length>Yr||p.length>Yr)return!1;let L=(await g.listVersions(u.vaultId,c)).find(V=>V.seq===m.seq);if(!L)return!1;let $=await g.getVersion(u.vaultId,L.id);if(et($)!==m.hash)return!1;let q=Fr(y.buf.toString("utf8"),$,p);return q===null?!1:(await He(G(c),q,O)&&(await Ie(c,T,P,ee(Buffer.byteLength(q))),E({key:c,run:()=>de(c)})),!0)}catch{return!1}},As=async c=>{let m=Xe(Ft(c,new Date));if(!m)return;let y=m.lastIndexOf("."),p=y>m.lastIndexOf("/"),T=p?m.slice(0,y):m,P=p?m.slice(y):"",O=m;for(let R=2;Vr(G(O));R++)O=`${T}-${R}${P}`;try{await ne.rename(G(c),G(O))}catch(R){if(R?.code==="ENOENT")return;throw R}F++,E({key:O,run:()=>de(O)}),v()},jn=async c=>{if(!w)return;let m=G(c),y=r(c)??c,p=oe.join(w,bo,new Date().toISOString().slice(0,10),...y.split("/")),T=Vr(p)?`${p}.${Date.now()}`:p;try{await ne.mkdir(oe.dirname(T),{recursive:!0}),await ne.rename(m,T)}catch(P){if(P?.code==="ENOENT")return;throw new Error(`\u8F6F\u5220\u5931\u8D25,\u4FDD\u7559\u672C\u5730\u6587\u4EF6 ${m}: ${P?.message??String(P)}`)}},Yt=async c=>{if(!u)return;let m=await le(c);if(Ce(c))return;let y=u.files[c]??null,p=jt(m?.hash??null,y,null);if(p.kind==="deleteLocal"){if(!B&&we()){M.set(c,"local"),se(),v();return}K.push(Date.now()),await jn(c),ke(c)}else p.kind==="pushCreate"?(ke(c),E({key:c,run:()=>de(c)})):ke(c)},Ln=(c,m)=>{if(u){for(let y of Object.keys(u.files))if(y===c||y.startsWith(`${c}/`)){let p=m+y.slice(c.length);u.files[p]=u.files[y],delete u.files[y]}U.save(u)}},Hn=async c=>{if(!g||!u||c.seq<=u.cursor||!await St())return;if(c.origin.client&&g.clientId===c.origin.client){u.cursor=c.seq,U.save(u);return}let m=c.type==="structure"?"folder":c.type,y=T=>r(T)!==null&&s(T,m);if(!y(c.path)&&!(c.newPath&&y(c.newPath))){u.cursor=c.seq,U.save(u);return}let p=c.path;switch(c.op){case"write":await $e(p,c.fileSeq);break;case"delete":await Yt(p);break;case"move":{let T=c.newPath;if(!T)break;let P=u.files[p];if(await le(p)&&P)try{await ne.mkdir(oe.dirname(G(T)),{recursive:!0}),await ne.rename(G(p),G(T)),u.files[T]={...P,seq:c.fileSeq??P.seq},delete u.files[p],U.save(u)}catch{await $e(T,c.fileSeq)}else ke(p),await $e(T,c.fileSeq);break}case"mkdir":await ne.mkdir(G(p),{recursive:!0});break;case"rename-folder":case"move-folder":{let T=c.newPath;if(!T)break;try{await ne.mkdir(oe.dirname(G(T)),{recursive:!0}),await ne.rename(G(p),G(T))}catch{}Ln(p,T);break}case"delete-folder":{let T=`${p}/`;for(let P of Object.keys(u.files))(P===p||P.startsWith(T))&&await Yt(P);await We(G(p));break}}if(u.cursor=c.seq,U.save(u),c.op==="move"||c.op==="rename-folder"||c.op==="move-folder"||c.op==="delete"||c.op==="delete-folder")try{await t.onRemoteApplied?.(c)}catch{}},Is=async(c,m,y)=>{let p=Number(m?.seq??0),T=m?.content??null;if(T!==null&&et(T)===y.hash){await Ie(c,p,y.hash,y);return}if(T===null&&p===0){if(!u?.files[c]){k.set(c,m?.code||"EXISTS"),v();return}ke(c),E({key:c,run:()=>de(c)});return}await $e(c,p)},wt=async(c,m)=>{if(!g||!u)return;let y=await le(c);if(!y){E({key:c,run:()=>de(c)});return}if(y.size>lo){k.set(c,"TOO_LARGE"),v();return}let p=y.buf.toString("utf8");try{let T=await g.putFile(u.vaultId,c,p,m);k.delete(c),await Ie(c,T.seq,T.hash??y.hash,y)}catch(T){if(T instanceof fe&&T.status===409){await Is(c,T.body,y);return}throw T}},bt=async(c,m)=>{if(!g||!u)return;let y=await le(c);if(!y){E({key:c,run:()=>de(c)});return}if(y.size>(A??co)){k.set(c,"TOO_LARGE"),v();return}try{let p=await g.putBinary(u.vaultId,c,y.buf,{baseSeq:m});k.delete(c),await Ie(c,p.seq,y.hash,y)}catch(p){if(p instanceof fe&&p.status===409){let T=Number(p.body?.seq??0),P=p.body?.hash??null;if(P!==null&&P===y.hash){await Ie(c,T,y.hash,y);return}if(T===0){if(!u.files[c]){k.set(c,p.body?.code||"EXISTS"),v();return}ke(c),E({key:c,run:()=>de(c)});return}await $e(c,T);return}throw p}},zn=async c=>{if(!g||!u||Ce(c))return;let m=ie,y=u.files[c];if(y){if(je(Pe(c)))try{let p=await g.getFile(u.vaultId,c);if(p.seq!==y.seq){await $e(c,p.seq);return}}catch(p){if(p instanceof fe&&p.status===404){ke(c);return}throw p}if(!(m!==ie||Ce(c))){try{await g.deleteFile(u.vaultId,c,y.seq,{confirmed:B})}catch(p){if(p instanceof fe&&p.status===409){await $e(c,Number(p.body?.seq??0)||null);return}if(p instanceof fe&&p.status===429&&p.body?.code==="MASS_DELETE_BLOCKED"){M.set(c,"remote"),j=!0,se(),v();return}throw p}ke(c)}}},St=async()=>w?await ne.stat(w).then(m=>m.isDirectory()).catch(()=>!1)||!e.requireRootExists&&!Object.keys(u?.files??{}).length?!0:(D("error",`vault-missing: ${w}`),J(),!1):!1,ie=0,vt=new Set,Et=new Map,be=c=>JSON.stringify([c.from,c.to]),Ue=(c,m)=>c===m||c.startsWith(`${m}/`),Ce=c=>[...u?.moves??[],...vt].some(m=>Ue(c,m.from)||Ue(c,m.to)),Me=()=>!!(u?.moves?.length||vt.size),Gt=async c=>{if(!g||!u)return;let{from:m,to:y,kind:p}=c;if(r(m)===null||r(y)===null)throw new Error("Invalid queued cloud move");c.hashes??=Object.fromEntries(Object.entries(u.files).filter(([R])=>Ue(R,m)).map(([R,L])=>[R.slice(m.length),L.hash])),U.save(u),await U.flush(!0);let T,P=!1;try{if(p==="folder"){let R=oe.posix.dirname(m)==="."?"":oe.posix.dirname(m),L=oe.posix.dirname(y)==="."?"":oe.posix.dirname(y);R===L?await g.renameFolder(u.vaultId,m,oe.posix.basename(y)):await g.moveFolder(u.vaultId,m,L)}else{let R=await g.move(u.vaultId,m,y);T=Number(R.seq)}}catch(R){if(!(R instanceof fe)||R.status!==404)throw R;let L=await g.tree(u.vaultId);if(L.entries.some(V=>Ue(V.path,m))||L.folders.some(V=>Ue(V,m)))throw R;let q=L.entries.find(V=>V.path===y);if(T=q?.seq,P=!q&&!L.entries.some(V=>Ue(V.path,y))&&!L.folders.some(V=>Ue(V,y)),!P){let V=Object.entries(c.hashes);if(!(V.length>0&&V.every(([Re,Ve])=>L.entries.some(Ye=>Ye.path===y+Re&&Ye.hash===Ve))))throw new fe(409,{code:"MOVE_DESTINATION_CHANGED"},"local-move")}}if(P)for(let R of Object.keys(u.files))Ue(R,m)&&delete u.files[R];else Ln(m,y),T!==void 0&&u.files[y]&&(u.files[y].seq=T);u.moves=(u.moves??[]).filter(R=>be(R)!==be(c)),U.save(u);try{await U.flush(!0)}catch(R){throw u.moves.unshift(c),U.save(u),R}let O=Et.get(be(c));Et.delete(be(c)),O?.(),Ce(y)||(p==="folder"?await Jt():await de(y))},de=async(c,m=!1)=>{if(!u||Ce(c))return;if(!s(c,Pe(c))){ke(c);return}if(!await St())return;let y=await le(c);if(Ce(c))return;let p=u.files[c]??null,T=jt(y?.hash??null,p,p?{seq:p.seq,hash:p.hash}:null);switch(T.kind){case"push":je(Pe(c))?await wt(c,T.baseSeq):await bt(c,T.baseSeq);break;case"pushCreate":je(Pe(c))?await wt(c,0):await bt(c,0);break;case"pushDelete":if(m){Ct();break}if(!B&&(M.has(c)||we())){M.set(c,"remote"),se(),v();break}K.push(Date.now()),await zn(c);break;case"dropShadow":ke(c);break;default:y&&p&&y.hash===p.hash&&y.mtimeMs>=0&&(p.size!==y.size||p.mtimeMs!==y.mtimeMs)&&await Ie(c,p.seq,p.hash,y);break}},qn=async()=>{let c=new Map;if(!w||!u)return c;let m=w,y=null,p=async T=>{if(y)return;let P;try{P=await ne.readdir(T,{withFileTypes:!0})}catch(O){y=`${T}: ${O?.message??String(O)}`;return}for(let O of P){if(ft(O.name)||O.isDirectory()&&e.ignoreNames?.includes(O.name))continue;let R=oe.join(T,O.name);if(O.isDirectory())await p(R);else if(O.isFile()){let L=oe.relative(m,R).split(oe.sep).join("/"),$=n(L);if(!$)continue;try{let q=await ne.stat(R);if(!q.isFile())continue;c.set($,{size:q.size,mtimeMs:Math.floor(q.mtimeMs)})}catch(q){if(q?.code==="ENOENT")continue;y=`${R}: ${q?.message??String(q)}`;return}}}};return await p(m),y?(D("error",`scan-failed: ${y}`),J(),null):c},Jt=async()=>{let c=ie;if(Me()||c!==ie||!u||!await St())return;let m=await qn();if(!m||Me()||c!==ie)return;let y=!1;for(let[P,O]of[...M])(O==="remote"&&m.has(P)||O==="local"&&!m.has(P))&&(M.delete(P),y=!0);M.size||he();for(let[P,O]of m){let R=u.files[P];R&&R.size===O.size&&R.mtimeMs===O.mtimeMs||E({key:P,run:()=>de(P)})}let p=Object.keys(u.files),T=p.filter(P=>!m.has(P));if(T.length&&!B&&(j||bn(T.length,p.length,Gr))){j=!0;for(let P of T)M.set(P,"remote");se(),v();return}y&&(se(),v());for(let P of T)M.has(P)||E({key:P,run:()=>de(P)})},ot=async()=>{let c=ie;if(Me()||c!==ie||!g||!u||!w||!await St())return;let m=await g.tree(u.vaultId);if(m.maxFileBytes!==void 0&&m.maxFileBytes!==A&&(A=m.maxFileBytes,v()),Me()||c!==ie)return;let y=new Map;for(let $ of m.entries)r($.path)===null||!s($.path,$.kind)||y.set($.path,$);let p=await qn();if(!p||Me()||c!==ie)return;let T=new Set([...y.keys(),...p.keys(),...Object.keys(u.files)]),P=Object.keys(u.files).length,O=[];for(let $ of T){if(Me()||c!==ie)return;let q=u.files[$]??null,V=y.get($)??null,me=p.get($)??null,Re=null,Ve=ee(me?.size??0);if(me)if(q&&q.size===me.size&&q.mtimeMs===me.mtimeMs)Re=q.hash,Ve=me;else{let Ye=await le($);Ye&&(Re=Ye.hash,Ve=Ye)}O.push({sp:$,d:jt(Re,q,V?{seq:V.seq,hash:V.hash}:null),rSeq:V?.seq??null,localHash:Re,localStat:Ve})}if(Me()||c!==ie)return;let R=O.filter($=>$.d.kind==="deleteLocal"||$.d.kind==="pushDelete").length,L=!B&&(j||bn(R,P,Gr));L&&R&&(j=!0),M.clear();for(let{sp:$,d:q,rSeq:V,localHash:me,localStat:Re}of O){if(Me()||c!==ie)return;if(L&&(q.kind==="deleteLocal"||q.kind==="pushDelete")){M.set($,q.kind==="deleteLocal"?"local":"remote");continue}if((q.kind==="deleteLocal"||q.kind==="pushDelete")&&((await le($))?.hash??null)!==me){E({key:$,run:()=>de($)});continue}if(Me()||c!==ie)return;switch(q.kind){case"adopt":await Ie($,V,me,Re);break;case"pull":await $e($,V);break;case"push":je(Pe($))?await wt($,q.baseSeq):await bt($,q.baseSeq);break;case"pushCreate":je(Pe($))?await wt($,0):await bt($,0);break;case"pushDelete":await zn($);break;case"deleteLocal":await jn($),ke($);break;case"conflict":await $e($,V);break;case"dropShadow":ke($);break;case"none":break}}B&&(B=!1,K.length=0),M.size||he(),se(),L&&v();for(let $ of m.folders)if(!(r($)===null||!s($,"folder")))try{await ne.mkdir(G($),{recursive:!0})}catch{}u.cursor=m.seq,u.lastSyncAt=Date.now(),U.save(u)},Rs=async()=>{if(!g||!u)return;let c=u.cursor,m=await g.changes(u.vaultId,c);if(m.changes.length===0&&m.seq>c||m.changes.length>0&&m.changes[0].seq!==c+1){await ot();return}for(let p of m.changes)await Hn(p)},Ne=null,Bn=[],Wn=()=>{Ne&&Bn.push(Ne.close()),Ne=null},Ps=()=>{if(!a||Ne||!w)return;Ne=Nr.watch(w,{ignoreInitial:!0,depth:12,ignored:m=>{let y=oe.basename(m);return ft(y)||!!e.ignoreNames?.includes(y)}});let c=m=>{if(!w)return;let y=oe.relative(w,m);if(!y||y.startsWith(".."))return;let p=n(y);p&&N(p)};Ne.on("change",c),Ne.on("add",c),Ne.on("unlink",()=>Ct()),Ne.on("unlinkDir",()=>Ct())},kt=()=>{S?.stop(),S=null},Ds=()=>{if(!a||!g||!u||S)return;let c=x;c&&(S=zr({baseUrl:c.cloudUrl,vaultId:u.vaultId,token:c.token},{getSince:()=>u?.cursor??0,onHello:m=>{u&&m>u.cursor&&E({run:Rs})},onChange:m=>{E({run:()=>Hn(m)})},onReset:()=>{E({run:ot})},onOpen:()=>{(d==="offline"||d==="starting")&&D("idle",null),E({run:Jt})},onDown:()=>{(d==="idle"||d==="syncing")&&D("offline")},onPresence:m=>t.onPresence?.(u?.vaultId??"",m),onPresenceRoster:m=>t.onPresenceRoster?.(u?.vaultId??"",m)}))},$s=async()=>{let c=await xe(i);if(c.cloudSync?.deviceId)return c.cloudSync.deviceId;let m=`desk-${Math.random().toString(36).slice(2,10)}${Date.now().toString(36)}`;return await Oe({cloudSync:{...c.cloudSync??{},deviceId:m}},i),m},Ms=async c=>{kt(),Wn(),ae.length=0,Ee.clear(),M.clear(),B=!1,j=!1,K.length=0;let m=await xe(i);if(c!==o)return;let y=m.cloudSync;if(y?.enabled===!1){w=null,g=null,D("disabled",null);return}if(!i||i!==ye()){D("auth-required","not-logged-in");return}if(w=e.localRoot,e.requireRootExists){let O=await ne.stat(w).then(R=>R.isDirectory()).catch(()=>!1);if(c!==o)return;if(!O){D("error",`vault-missing: ${w}`),J();return}}if(c!==o)return;let p=t.loadCreds();if(!p.cloudUrl||!p.token){g=null,D("auth-required","not-logged-in");return}D("starting",null);let T=y?.deviceId??await $s();if(c!==o)return;let P=e.clientIdSuffix?`${T}#${e.clientIdSuffix}`:T;x={cloudUrl:p.cloudUrl,token:p.token},g=Hr({baseUrl:p.cloudUrl,token:p.token,clientId:P});try{let O=e.vaultId==="first"?y?.vaultId:e.vaultId;if(!O){let L=await g.listVaults();if(c!==o)return;if(!L.length)throw new Error("\u4E91\u7AEF\u65E0\u53EF\u7528 vault");O=L[0].id,await Oe({cloudSync:{...y??{},vaultId:O}},i)}if(c!==o)return;let R=await vn(e.shadowName);if(c!==o||(u=R&&R.vaultRoot===w&&R.vaultId===O&&R.folder===""?R:{vaultRoot:w,folder:"",vaultId:O,cursor:0,lastSyncAt:null,files:{}},c!==o))return;for(let[L,$]of Object.entries(u.pending??{}))M.set(L,$);if(M.size&&(j=!0),!e.requireRootExists){let L=await ne.stat(w).then($=>$.isDirectory()).catch(()=>!1);if(c!==o)return;if(!L){if(Object.keys(u.files).length){D("error",`mirror-missing: ${w}`),J();return}if(await ne.mkdir(w,{recursive:!0}),c!==o)return}}Ps();for(let L of u.moves??[])E({key:`move:${be(L)}`,run:()=>Gt(L)});E({run:ot}),E({run:async()=>{Ds()}})}catch(O){if(c!==o)return;z(O)?D("auth-required","login-expired"):(D("offline",O?.message||String(O)),J())}},Vn=()=>{a=!1,kt(),Wn(),ae.length=0,Ee.clear(),W();for(let c of[_,C,b])c&&clearTimeout(c);_=C=b=null},Yn=async()=>{De&&await new Promise(c=>h.add(c)),await Promise.all(Bn.splice(0)),await U.flush(),u=null,g=null,x=null,w=null,F=0,k.clear(),A=null,M.clear(),B=!1,j=!1,K.length=0,d="disabled",f=null},Ns=()=>{Gn()},_t=null,at=()=>{_t?.(),_t=pe().onBeforeQuit(Ns);let c=++o;Vn();let m=l.catch(()=>{}).then(async()=>{await Yn(),c===o&&(a=!0,await Ms(c))});return l=m,m},Gn=()=>{_t?.(),_t=null,++o,Vn();let c=l.catch(()=>{}).then(Yn);return l=c,c},ze=()=>({enabled:d!=="disabled",state:d==="idle"&&I.size?"syncing":d,lastSyncAt:u?.lastSyncAt??null,pending:ae.length+I.size,conflicts:F,skipped:[...k].map(([c,m])=>({path:c,reason:m})),error:f,pendingDeletions:M.size,maxFileBytes:A});return{getStatus:ze,start(){at()},notifyLocal(c,m,y){if(!u||d==="disabled"||d==="auth-required")return;let p=n(c),T=y?n(y):null;if(m==="write"&&p){ft(p.split("/").pop()||"")||N(p);return}if(m==="remove"){if(!p)return;let P=`${p}/`,O=!1;for(let R of Object.keys(u.files))(R===p||R.startsWith(P))&&(O=!0,E({key:R,run:()=>de(R)}));!O&&p&&E({key:p,run:()=>de(p)})}},holdLocalMove(c,m){let y=T=>e.serverDir?`${e.serverDir}/${T.replace(/\\/g,"/").normalize("NFC")}`:T.replace(/\\/g,"/").normalize("NFC"),p={from:y(c),to:y(m)};return++ie,vt.add(p),()=>{vt.delete(p)}},async notifyLocalMove(c,m,y,p){let T=n(c),P=n(m),O=u??await vn(e.shadowName),R=Sn(c,""),L=R&&(e.serverDir?`${e.serverDir}/${R}`:R);if(!T&&P&&L&&O&&Object.keys(O.files).some($=>$===L||$.startsWith(`${L}/`))&&(T=L),!T&&!P){y?.();return}if(T&&P){let $=u??O;if(!$){y?.();return}let q=p??(Object.keys($.files).some(me=>me.startsWith(`${T}/`))?"folder":"file"),V={from:T,to:P,kind:q};$.moves??=[],$.moves.some(me=>be(me)===be(V))||($.moves.push(V),++ie),y&&Et.set(be(V),y),U.save($);try{await U.flush(!0)}catch(me){throw $.moves=$.moves.filter(Re=>be(Re)!==be(V)),Et.delete(be(V)),U.save($),me}u===$&&a&&d!=="disabled"&&d!=="auth-required"&&E({key:`move:${be(V)}`,run:()=>Gt(V)});return}T&&this.notifyLocal(c,"remove"),P&&(E({key:P,run:()=>de(P)}),Ct()),y?.()},async setEnabled(c){let m=await xe(i);return await Oe({cloudSync:{...m.cloudSync??{},enabled:c}},i),await at(),ze()},async restart(){return await at(),ze()},async syncNow(){if(k.clear(),d==="disabled"||d==="auth-required"||!g)await at();else{for(let c of u?.moves??[])E({key:`move:${be(c)}`,run:()=>Gt(c)});E({run:ot})}return ze()},confirmMassDeletions(){return M.size&&(B=!0,j=!1,M.clear(),K.length=0,se(),E({run:ot})),ze()},stop:Gn};function Ct(){a&&(C&&clearTimeout(C),C=setTimeout(()=>{C=null,E({run:Jt})},fo))}}import{createHash as So}from"node:crypto";function Jr(t){let e=t.replace(/\.md$/i,""),n=t.lastIndexOf("/"),r=n<0?"":t.slice(0,n);return{root:t,fdPrefix:`${e}.fd/`,assetPrefix:r?`${r}/.amadeus/`:".amadeus/"}}function Kr(t,e,n){return!!(e===t.root||e.startsWith(t.fdPrefix)||`${e}/`===t.fdPrefix||n==="binary"&&e.startsWith(t.assetPrefix)||n==="folder"&&(`${e}/`===t.assetPrefix||e.startsWith(t.assetPrefix)))}var vo=t=>So("sha256").update(t).digest("hex").slice(0,8),Eo=t=>t.replace(/[\\/:*?"<>|]/g," ").trim().slice(0,40)||"shared",Lt="\u4E0E\u6211\u5171\u4EAB";function En(t){let e=vo(`${t.vaultId}:${t.path}`),n=Jr(t.path),r=t.path.includes("/")?t.path.slice(0,t.path.lastIndexOf("/")):"";return{key:e,vaultId:t.vaultId,rootPath:t.path,title:t.title,localRelDir:`${Lt}/${Eo(t.title)}-${e}`,serverDir:r,inScope:(s,i)=>Kr(n,s,i)}}function kn(){let t=pe().readCreds(),e=Te(t.cloudUrl??"",t.token??""),n=new AbortController,r=()=>{let f=pe().readCreds();if(n.signal.aborted||!e||Te(f.cloudUrl??"",f.token??"")!==e)throw Object.assign(new Error("Cloud account changed; retry from the current account"),{status:401});return f},s=()=>{let f=r();if(!f.cloudUrl||!f.token)throw Object.assign(new Error("\u672A\u767B\u5F55 Forsion \u8D26\u53F7"),{status:401});return f.cloudUrl.replace(/\/+$/,"")},i=async(f,u,g)=>{let S=r();if(!S.cloudUrl||!S.token)throw Object.assign(new Error("\u672A\u767B\u5F55 Forsion \u8D26\u53F7"),{status:401});let x=await fetch(`${S.cloudUrl.replace(/\/+$/,"")}/api/amadeus${u}`,{method:f,headers:{Authorization:`Bearer ${S.token}`,...g!==void 0?{"Content-Type":"application/json"}:{}},body:g!==void 0?JSON.stringify(g):void 0,signal:AbortSignal.any([n.signal,AbortSignal.timeout(2e4)])});if(!x.ok){let F=null;try{F=await x.json()}catch{}throw Object.assign(new Error(F?.detail||`http ${x.status}`),{status:x.status,code:F?.code})}let w=await x.json();return r(),w},a=null,o=async()=>(r(),a||(a=(await i("GET","/vaults")).vaults[0]?.id??"default",a)),l=()=>{try{let f=(r().token??"").split(".")[1],u=JSON.parse(Buffer.from(f.replace(/-/g,"+").replace(/_/g,"/"),"base64").toString());return typeof u.userId=="string"?u.userId:null}catch{return null}},h=async()=>(await i("GET","/shared-with-me")).items.map(u=>{let g=En(u),S=u.path.split("/").pop()??u.path;return{...u,localPath:`${g.localRelDir}/${S}`}}),d=null;return{stop:()=>n.abort(),call:i,ensureOwnVault:o,myUserId:l,sharedWithMe:h,linkBase:async()=>{if(r(),d)return d;try{d=((await i("GET","/collab/link-base")).webOrigin??"").trim().replace(/\/+$/,"")||s()}catch{d=s()}return d},async heartbeat(f,u){let g=(f??"").replace(/\\/g,"/"),S,x=null,w=u.find(F=>g.startsWith(`${F.localRelDir}/`));w?(S=w.vaultId,x=w.serverDir?`${w.serverDir}/${g.slice(w.localRelDir.length+1)}`:g.slice(w.localRelDir.length+1)):(S=await o(),x=g||null),await i("POST",`/vaults/${encodeURIComponent(S)}/presence`,{page:x})}}}import{promises as Xr}from"node:fs";import ko from"node:path";var _n=".forsion-vault.md",Cn=t=>`${t}/${_n}`;var ve=t=>t.replace(/\\/g,"/").normalize("NFC");function Tn(t){let e=ve(t.path);return e?t.kind==="folder"?`${e}/`:t.kind==="page"?`${e.replace(/\.md$/i,"")}.fd/`:null:null}function tt(t,e,n){let r=ve(n);if(!r)return!1;if(t.some(s=>ve(s.path)===r))return!0;for(let s of e??[]){let i=ve(s);if(!i)continue;let a=`${i.replace(/\.md$/i,"")}.fd`;if(r===i||r.startsWith(`${i}/`)||r===a||r.startsWith(`${a}/`))return!1}return t.some(s=>{let i=Tn(s);return!!i&&r.startsWith(i)})}function xn(t,e,n){let r=ve(t),s=ve(e);return r===s?ve(n):r.startsWith(`${s}/`)?ve(n)+r.slice(s.length):null}function mt(t,e,n){let r=!1,s=t.map(i=>{let a=xn(i,e,n);return a===null?i:(r=!0,a)});return{changed:r,next:s}}async function Zr(t){let e=await Xr.readdir(t,{withFileTypes:!0}).catch(()=>[]),n=[];for(let r of e)!r.isDirectory()||r.name.startsWith(".")||await Xr.access(ko.join(t,r.name,_n)).then(()=>!0,()=>!1)&&n.push(r.name);return n.sort()}var ce={get:"amadeus:sync:get",setEnabled:"amadeus:sync:set-enabled",syncNow:"amadeus:sync:now",confirmDeletions:"amadeus:sync:confirm-deletions",status:"amadeus:sync:status",switchSide:"amadeus:sync:switch-side",collabCall:"amadeus:collab:call",presence:"amadeus:collab:presence",entryGet:"amadeus:entry-sync:get",entryEnable:"amadeus:entry-sync:enable",entryDisable:"amadeus:entry-sync:disable",entryClosure:"amadeus:entry-sync:closure",entryChange:"amadeus:entry-sync:change",otherSideDbs:"amadeus:entry-sync:other-side-dbs"};import{createHash as _o}from"node:crypto";var Ht=t=>_o("sha256").update(t).digest("hex").slice(0,8);function Qr(t){return t.replace(/ \(conflict \d{4}-\d{2}-\d{2} \d{4}\)(?=(?:\.[^./]+)?$)/,"")}function Le(t,e=[]){let n=[],r=[];for(let s of t){let i=ve(s.path);if(!i)continue;r.push(i);let a=Tn(s);a&&n.push(a)}return{entries:t,exclude:e,prefixes:n,paths:r}}function es(t,e){let n=Qr(ve(e));if(!n)return!1;if(tt(t.entries,t.exclude,n))return!0;let r=`${n}/`;for(let s of t.paths)if(s.startsWith(r))return!0;for(let s of t.prefixes)if(s.startsWith(r))return!0;return!1}function gt(t,e,n){let r=!1,s=t.map(i=>{let a=xn(i.path,e,n);return a===null?i:(r=!0,{...i,path:a})});return{changed:r,next:s}}function ts(t,e,n,r){if(e==="delete"||e==="delete-folder"){let s=ve(n),i=t.filter(a=>{let o=ve(a.path);return!(o===s||e==="delete-folder"&&o.startsWith(`${s}/`))});return{changed:i.length!==t.length,next:i}}return r?gt(t,n,r):{changed:!1,next:t}}function An(t,e){let n=Xe(t);return!n||n!==t.normalize("NFC").trim()?"\u540D\u79F0\u4E0D\u5408\u6CD5":n.includes("/")?"\u540D\u79F0\u4E0D\u80FD\u5305\u542B /":n===Lt?`\u300C${Lt}\u300D\u662F\u4FDD\u7559\u540D\u79F0`:e.includes(n)?"\u8BE5\u540D\u79F0\u5DF2\u88AB\u5176\u4ED6\u667A\u5E93\u7684\u4E91\u540C\u6B65\u5360\u7528":null}var ns=["setAmadeusSyncFactory","readCreds","accountId","homeDir"],In=t=>ns.every(e=>typeof t[e]=="function"),Co=()=>({enabled:!1,state:"disabled",lastSyncAt:null,pending:0,conflicts:0,skipped:[],error:null,pendingDeletions:0,maxFileBytes:null,side:"local"});function Rn(t){let e=null,n=()=>{if(!e)throw new Error("Cloud sync is not ready");return e};t.handle(ce.get,()=>e?e.get():Co()),t.handle(ce.setEnabled,(r,s)=>n().setEnabled(s)),t.handle(ce.syncNow,()=>n().syncNow()),t.handle(ce.confirmDeletions,()=>n().confirmDeletions()),t.handle(ce.entryGet,()=>n().entryGet()),t.handle(ce.otherSideDbs,()=>n().otherSideDbs()),t.handle(ce.entryEnable,(r,s)=>n().entryEnable(s)),t.handle(ce.entryDisable,(r,s)=>n().entryDisable(s)),t.handle(ce.entryClosure,(r,s,i)=>n().entryClosure(s,i)),t.handle(ce.collabCall,(r,s,i)=>n().collabCall(s,i)),t.handle(ce.switchSide,(r,s)=>n().switchSide(r.sender.id,s)),t.setAmadeusSyncFactory(r=>{mr(r);let s=rs(r);return e=s.handlers,s.instance}),t.log("[forsion-extend] amadeus cloud sync registered")}function rs(t){let e=t.notifyAll,n=()=>t.vaultRoot(),r=0,s=!1,i=kn(),a=new Map,o=()=>{let _=Date.now();for(let[C,b]of a)_-b.at>7e4&&a.delete(C);e(ce.presence,[...a.values()])},l={loadCreds:()=>t.readCreds(),onStatus:_=>e(ce.status,{..._,pendingDeletions:K(),side:S()?"cloud":"local"}),onPresence:(_,C)=>{let b=C;b?.userId&&(a.set(b.userId,{userId:b.userId,username:String(b.username??"user"),page:b.page??null,at:Number(b.at)||Date.now()}),o())},onPresenceRoster:(_,C)=>{if(Array.isArray(C)){for(let b of C){let v=b;v?.userId&&a.set(v.userId,{userId:v.userId,username:String(v.username??"user"),page:v.page??null,at:Number(v.at)||Date.now()})}o()}}},h=()=>{let _=r;return{...l,onStatus:C=>{_===r&&l.onStatus(C)},onPresence:(C,b)=>{_===r&&l.onPresence(C,b)},onPresenceRoster:(C,b)=>{_===r&&l.onPresenceRoster(C,b)}}},d=ht(h()),f=new Map,u=[],g=async()=>{if(!s||!ye())return;let _=r,C=i,b;try{b=await C.sharedWithMe()}catch{return}if(_!==r||!s)return;let v=b.map(E=>En(E));u=v;let D=new Set(v.map(E=>E.key));for(let[E,I]of f)if(!D.has(E)){if(await I.engine.stop(),_!==r)return;f.delete(E)}for(let E of v){if(f.has(E.key))continue;let I=ht(h(),{localRoot:Be.join(Fe(),...E.localRelDir.split("/")),shadowName:`amadeus-sync-${ct()}-share-${E.key}`,vaultId:E.vaultId,serverDir:E.serverDir,inScope:E.inScope});f.set(E.key,{engine:I,plan:E}),I.start()}},S=()=>n()===Fe(),x=(_,C=_.base)=>{_.base=C;let b=[C,..._.pendingMoves];_.scope.current=Le(b.flatMap(v=>v.entries),b.flatMap(v=>v.exclude))},w=new Map,F=new Set,k=()=>{e(ce.entryChange)},A=async(_,C)=>{let b=w.get(_);if(!b)return;let v=I=>I&&I.startsWith(`${b.cloudName}/`)?I.slice(b.cloudName.length+1):null,D=v(C.path);if(!D)return;let E=!1;await Ge(I=>{if(w.get(_)!==b)return!1;let N=(I.entrySync??[]).find(J=>J.vaultRoot===_);if(!N)return!1;let W=C.op,H=v(C.newPath),z=ts(N.entries,W,D,H),X=H?mt(N.exclude??[],D,H):{changed:!1,next:N.exclude??[]};if(!z.changed&&!X.changed)return!1;E=!0,N.entries=z.next,X.changed&&(N.exclude=X.next),x(b,Le(N.entries,N.exclude??[]))}),E&&w.get(_)===b&&k()},U=_=>{let C=r;return{...h(),onStatus:b=>{C===r&&e(ce.status,{...b,pendingDeletions:K(),side:"local",binding:_})},onRemoteApplied:async b=>{C===r&&await A(_,b)}}},M=async()=>{let _=ye();if(!s||!_)return;let C=r,b=i,v=ct(_);await t.adoptLegacyCloudState(_,Wr);let D=await xe(_),E=D.entrySync??[];if(C!==r||!s||_!==ye())return;let I=new Map(E.map(N=>[N.vaultRoot,N]));for(let[N,W]of w){let H=I.get(N);if(!(H&&H.cloudName===W.cloudName)&&(await W.engine.stop(),C!==r||(w.delete(N),H&&await Br(`amadeus-sync-${v}-entry-${Ht(N)}`),C!==r)))return}for(let N of E){let W=w.get(N.vaultRoot);if(W){x(W,Le(N.entries,N.exclude??[]));continue}let H={current:Le(N.entries,N.exclude??[])},z=N.cloudName,X=ht(U(N.vaultRoot),{accountId:_,localRoot:N.vaultRoot,shadowName:`amadeus-sync-${v}-entry-${Ht(N.vaultRoot)}`,vaultId:"first",serverDir:z,clientIdSuffix:`entry-${Ht(N.vaultRoot)}`,requireRootExists:!0,ignoreNames:[".git","node_modules",".trash"],inScope:J=>J===z?!0:J.startsWith(`${z}/`)?es(H.current,J.slice(z.length+1)):!1});w.set(N.vaultRoot,{engine:X,scope:H,cloudName:z,base:H.current,pendingMoves:new Set}),X.start()}if(D.cloudSync?.enabled!==!1)for(let N of E)F.has(N.cloudName)||(async()=>{try{let W=await b.ensureOwnVault();await b.call("PUT",`/vaults/${encodeURIComponent(W)}/file`,{path:Cn(N.cloudName),content:"",baseSeq:0}),C===r&&F.add(N.cloudName)}catch(W){W?.status===409&&C===r&&F.add(N.cloudName)}})()},B=async(_,C,b,v,D)=>{let E=C.replace(/\\/g,"/").normalize("NFC"),I=b.replace(/\\/g,"/").normalize("NFC"),N=!1,W,H,z,X=D??"file";try{await Ge(async J=>{if(w.get(_)!==v)return!1;let G=(J.entrySync??[]).find(le=>le.vaultRoot===_);if(!G)return!1;let ee=gt(G.entries,E,I),Z=mt(G.exclude??[],E,I),_e=tt(G.entries,G.exclude,E);!D&&await nt.stat(Be.join(_,...I.split("/"))).then(le=>le.isDirectory(),()=>!1)&&(X="folder");let He=X==="folder"?"folder":/\.md$/i.test(I)?"page":"asset";_e&&!tt(ee.next,Z.next,I)&&(ee.next.push({path:I,kind:He}),ee.changed=!0),N=ee.changed||Z.changed;let We=G.entries.filter(le=>gt([le],E,I).changed);return _e&&!We.some(le=>le.path===E)&&We.push({path:E,kind:He}),W=Le(We,(G.exclude??[]).filter(le=>mt([le],E,I).changed)),H=v.base,v.pendingMoves.add(W),G.entries=ee.next,G.exclude=Z.next,z=Le(G.entries,G.exclude),x(v,z),N})}catch(J){throw W&&v.pendingMoves.delete(W),x(v,v.base===z&&H?H:v.base),J}try{W&&await v.engine.notifyLocalMove(E,I,()=>{v.pendingMoves.delete(W),x(v)},X)}catch(J){throw W&&v.pendingMoves.delete(W),await Ge(G=>{let ee=G.entrySync?.find(Z=>Z.vaultRoot===_);if(!ee)return!1;ee.entries=gt(ee.entries,I,E).next,ee.exclude=mt(ee.exclude??[],I,E).next,x(v,Le(ee.entries,ee.exclude))}),J}N&&w.get(_)===v&&k()},j=_=>{let C=_.replace(/\\/g,"/");for(let{engine:b,plan:v}of f.values())if(C.startsWith(`${v.localRelDir}/`))return{engine:b,rel:C.slice(v.localRelDir.length+1)};return{engine:d,rel:C}};t.setMutationHooks((_,C)=>{if(S()){let b=j(_);b.engine.notifyLocal(b.rel,C);return}w.get(n()??"")?.engine.notifyLocal(_,C)},(_,C,b)=>{if(S()){let E=j(_),I=j(C);if(E.engine===I.engine)return E.engine.notifyLocalMove(E.rel,I.rel,void 0,b);E.engine.notifyLocal(E.rel,"remove"),I.engine.notifyLocal(I.rel,"write");return}let v=n()??"",D=w.get(v);if(D)return B(v,_,C,D,b)},(_,C)=>{if(S()){let b=j(_),v=j(C),D=[b.engine.holdLocalMove(b.rel,v.rel)];return b.engine!==v.engine&&D.push(v.engine.holdLocalMove(b.rel,v.rel)),()=>{for(let E of D)E()}}return w.get(n()??"")?.engine.holdLocalMove(_,C)});let K=()=>{let _=d.getStatus().pendingDeletions;for(let{engine:C}of f.values())_+=C.getStatus().pendingDeletions;for(let{engine:C}of w.values())_+=C.getStatus().pendingDeletions;return _},se=_=>({..._,pendingDeletions:K(),side:S()?"cloud":"local"}),he=()=>{if(!s)return Promise.resolve(d.getStatus());g();for(let{engine:_}of f.values())_.syncNow();for(let{engine:_}of w.values())_.syncNow();return d.syncNow()},we=async()=>{++r,s=!1,i.stop();let _=[d.stop(),...[...f.values()].map(({engine:b})=>b.stop()),...[...w.values()].map(({engine:b})=>b.stop())];f.clear(),w.clear(),u=[],F.clear(),a.clear(),o(),await Promise.all(_),await t.awaitPendingVaultWrites();let C=n();if(C&&It(C)){let b=await xe(),v=b.localVault&&!It(b.localVault)?b.localVault:Be.join(t.workspaceDir(),"Amadeus");await nt.mkdir(v,{recursive:!0}),await Oe({lastVault:v,localVault:v,lastPage:void 0}),await t.activateRoot(v,!1)}k()};return{handlers:{get:()=>se(d.getStatus()),setEnabled:async _=>{if(!s)throw new Error("Cloud account is changing");let C=r;return await d.setEnabled(_),C!==r?d.getStatus():(await Promise.all([...f.values(),...w.values()].map(({engine:b})=>b.restart())),se(d.getStatus()))},syncNow:()=>he(),confirmDeletions:()=>{for(let{engine:_}of f.values())_.confirmMassDeletions();for(let{engine:_}of w.values())_.confirmMassDeletions();return se(d.confirmMassDeletions())},entryGet:async()=>{let _=await xe(),C=Fe();return{vaults:_.entrySync??[],activeRoot:n(),cloudRoot:C,mirrorVaults:await Zr(C)}},otherSideDbs:async()=>{let _=n();if(!_)return null;let C=Fe(),b=await xe(),v=_===C?b.localVault&&b.localVault!==C?b.localVault:null:C;if(!v)return null;let D=[],E=500,I=async(N,W)=>{if(D.length>=E)return;let H;try{H=await nt.readdir(N,{withFileTypes:!0})}catch{return}for(let z of H){if(D.length>=E)break;if(z.name.startsWith(".")||z.isSymbolicLink())continue;let X=W?`${W}/${z.name}`:z.name;if(z.isDirectory())await I(Be.join(N,z.name),X);else if(z.isFile()&&/\.db$/i.test(z.name))try{D.push({rel:X,source:await nt.readFile(Be.join(N,z.name),"utf8")})}catch{}}};return await I(v,""),{root:v,vaultName:v===C?"\u4E91\u7AEF":Be.basename(v),dbs:D}},entryEnable:async _=>{let C=r,b=i;if(!s||!ye())return{error:"Sign in to enable cloud sync"};let v=n();if(!v||S())return{error:"\u4EC5\u672C\u5730 vault \u53EF\u5F00\u542F\u4E91\u540C\u6B65"};let D=await xe(),E=D.entrySync??[],I=E.find(N=>N.vaultRoot===v);if(!I){let N=(_.cloudName??Be.basename(v)).normalize("NFC").trim(),W=An(N,E.map(H=>H.cloudName));if(W)return{error:W};if(!_.merge)try{let H=await b.ensureOwnVault(),z=await b.call("GET",`/vaults/${encodeURIComponent(H)}/tree`);if((z.folders??[]).some(J=>J===N||J.startsWith(`${N}/`))||(z.entries??[]).some(J=>J.path===N||J.path.startsWith(`${N}/`)))return{conflict:N}}catch(H){return{error:H?.message||"\u65E0\u6CD5\u8FDE\u63A5\u4E91\u7AEF(\u9996\u6B21\u5F00\u542F\u9700\u8981\u5728\u7EBF)"}}I={vaultRoot:v,cloudName:N,entries:[]},E.push(I),(async()=>{try{let H=await b.ensureOwnVault();await b.call("PUT",`/vaults/${encodeURIComponent(H)}/file`,{path:Cn(I.cloudName),content:"",baseSeq:0})}catch{}})()}return C!==r||!s?{error:"Cloud account changed; retry from the current account"}:(await Ge(N=>{if(C!==r||!s)return!1;let W=N.entrySync??[],H=W.find(Z=>Z.vaultRoot===v);if(!H){let Z=An(I.cloudName,W.map(_e=>_e.cloudName));if(Z)throw new Error(Z);H={vaultRoot:v,cloudName:I.cloudName,entries:[]},W.push(H)}let z=Z=>String(Z??"").replace(/\\/g,"/").normalize("NFC"),X=new Set;for(let Z of _.entries??[]){let _e=z(Z.path);_e&&(X.add(_e),!H.entries.some(He=>He.path===_e)&&H.entries.push({path:_e,kind:Z.kind==="folder"||Z.kind==="asset"?Z.kind:"page"}))}let J=(_.exclude??[]).map(z).filter(Boolean),G=new Set([...X,...(_.include??[]).map(z).filter(Boolean)]);H.exclude=[...new Set([...(H.exclude??[]).filter(Z=>!G.has(Z)),...J])];let ee=new Set(J);H.entries=H.entries.filter(Z=>!ee.has(Z.path)),N.entrySync=W,I=H},D.cloudAccountId),C!==r?{error:"Cloud account changed; retry from the current account"}:(await M(),w.get(v)?.engine.syncNow(),k(),{ok:!0,cloudName:I.cloudName}))},entryDisable:async _=>{let C=n(),b=!1,v=r;return await Ge(D=>{if(v!==r||!s)return!1;let E=(D.entrySync??[]).find(W=>W.vaultRoot===C);if(!C||!E)return!1;let I=String(_??"").replace(/\\/g,"/").normalize("NFC"),N=E.entries.length;if(E.entries=E.entries.filter(W=>W.path!==I),tt(E.entries,E.exclude,I))E.exclude=[...new Set([...E.exclude??[],I])];else if(E.entries.length===N)return!1;b=!0}),!b||v!==r?{ok:!1}:(await M(),k(),{ok:!0})},entryClosure:(_,C)=>t.relatedClosure(String(_??""),C==="folder"?"folder":"page"),collabCall:async(_,C)=>{let b=i,v=async()=>b.ensureOwnVault(),D=I=>String((C??[])[I]??""),E=I=>(C??[])[I]??{};switch(_){case"listVaults":return(await b.call("GET","/vaults")).vaults;case"activeVaultId":return v();case"pageShare":return b.call("GET",`/vaults/${encodeURIComponent(await v())}/page-shares?path=${encodeURIComponent(D(0))}`);case"createPageShare":return b.call("POST",`/vaults/${encodeURIComponent(await v())}/page-shares`,{path:D(0),...E(1)});case"updatePageShare":return b.call("PATCH",`/vaults/${encodeURIComponent(await v())}/page-shares/${encodeURIComponent(D(0))}`,E(1));case"revokePageShare":return b.call("DELETE",`/vaults/${encodeURIComponent(await v())}/page-shares/${encodeURIComponent(D(0))}`);case"setParticipantRole":return b.call("PATCH",`/vaults/${encodeURIComponent(await v())}/page-shares/${encodeURIComponent(D(0))}/members/${encodeURIComponent(D(1))}`,{role:D(2)});case"removeParticipant":return b.call("DELETE",`/vaults/${encodeURIComponent(await v())}/page-shares/${encodeURIComponent(D(0))}/members/${encodeURIComponent(D(1))}`);case"sharedWithMe":{let I=await b.sharedWithMe();return g(),I}case"leaveShare":{let I=b.myUserId();if(!I)throw new Error("\u672A\u767B\u5F55");return b.call("DELETE",`/vaults/${encodeURIComponent(await v())}/page-shares/${encodeURIComponent(D(0))}/members/${encodeURIComponent(I)}`)}case"publishes":return b.call("GET",`/vaults/${encodeURIComponent(await v())}/shares`);case"listAllShares":{let I=(await b.call("GET","/vaults")).vaults||[],N=b.myUserId(),W=[],H=[];for(let z of I){try{let X=await b.call("GET",`/vaults/${encodeURIComponent(z.id)}/shares`);for(let J of X.shares||[])W.push({...J,vaultId:z.id,vaultName:z.name||""})}catch(X){t.log(`[connect] listAllShares publishes vault ${z.id} failed: ${X?.message}`)}try{let X=await b.call("GET",`/vaults/${encodeURIComponent(z.id)}/page-shares`),J=X?.shares||X?.pageShares||(Array.isArray(X)?X:[]);for(let G of J){let ee=G.created_by??G.createdBy;(!N||!ee||ee===N)&&H.push({...G,vaultId:z.id,vaultName:z.name||""})}}catch(X){t.log(`[connect] listAllShares pageShares vault ${z.id} failed: ${X?.message}`)}}return{publishes:W,pageShares:H,linkBase:await b.linkBase()}}case"createPublish":{let I=await b.call("POST",`/vaults/${encodeURIComponent(await v())}/shares`,{mode:D(0),path:D(1)});return{...I,url:`${await b.linkBase()}/share/${I.token}`}}case"revokePublish":return b.call("DELETE",`/vaults/${encodeURIComponent(await v())}/shares/${encodeURIComponent(D(0))}`);case"revokePublishIn":return b.call("DELETE",`/vaults/${encodeURIComponent(D(0))}/shares/${encodeURIComponent(D(1))}`);case"revokePageShareIn":return b.call("DELETE",`/vaults/${encodeURIComponent(D(0))}/page-shares/${encodeURIComponent(D(1))}`);case"myUserId":return b.myUserId();case"linkBase":return b.linkBase();case"heartbeat":return b.heartbeat((C??[])[0]??null,u);default:throw new Error(`unknown collab fn: ${_}`)}},switchSide:async(_,C)=>{let b=await xe();if(C==="cloud"){if(!s||!ye())throw new Error("Sign in to open cloud notes");let E=Fe();await nt.mkdir(E,{recursive:!0}),b.lastVault&&!It(b.lastVault)&&await Oe({localVault:b.lastVault}),await Oe({lastVault:E});let I=await t.activateRoot(E,!1);return t.bindRenderer(_,E),{...I,side:"cloud"}}let v=b.localVault&&await nt.stat(b.localVault).then(E=>E.isDirectory()).catch(()=>!1)?b.localVault:null;if(!v){let E=await t.ensureDefaultVault();return t.bindRenderer(_,E.root),{...E,side:"local"}}await Oe({lastVault:v});let D=await t.activateRoot(v,!1);return t.bindRenderer(_,v),{...D,side:"local"}}},instance:{start:()=>{s=!0,d.start(),g(),M()},stopAllSync:we,restartAllSync:async()=>{await we(),i=kn(),d=ht(h()),s=!0,await Promise.all([d.restart(),g(),M()]),k(),e(ce.status,se(d.getStatus()))}}}}import{hostname as To}from"node:os";var xo=256*1024;function ss(t,e,n){if(n?.hasSecHeaders&&!n.gatewayStreamsSecHeaders)return!1;if(t.includes("text/event-stream"))return!0;let r=Number(e||NaN);return!Number.isFinite(r)||r>xo}var Pn=45e3,Ao=3e3,Io=16*1024,Ro=6e4,zt=t=>`${t.replace(/\/+$/,"")}/api`,pt=class{deps;ctrl=null;conn=null;wake=null;redialNow=!1;inflight=new Map;connected=!1;lastError=null;hubCaps=new Set;constructor(e){this.deps=e}hubFetch(e,n){return(this.deps.hubFetch??fetch)(e,n)}get requestTimeoutMs(){return this.deps.requestTimeoutMs??Ro}status(){return{running:!!this.ctrl,connected:this.connected,unitId:this.deps.getPairing()?.unitId??null,lastError:this.lastError}}start(){if(this.ctrl)return;let e=new AbortController;this.ctrl=e,this.loop(e)}stop(){this.ctrl?.abort(),this.ctrl=null,this.markDown(),this.abortEnvelopes(),this.wake?.()}reconnect(e){this.ctrl&&(this.deps.log(`[unit-host] \u7ACB\u5373\u91CD\u8FDE\u901A\u9053(${e})`),this.redialNow=!0,this.conn?.abort(),this.wake?.())}markDown(){this.connected=!1,this.hook(this.deps.onChannelDown)}hook(e){try{e?.()}catch(n){this.deps.log(`[unit-host] \u901A\u9053\u56DE\u8C03\u51FA\u9519(\u5DF2\u5FFD\u7565): ${n?.message||n}`)}}abortEnvelope(e){let n=this.inflight.get(e);return n?(this.inflight.delete(e),n.ctrl.abort(),!0):!1}abortEnvelopes(e){for(let[n,r]of[...this.inflight])e&&r.conn!==e||(this.inflight.delete(n),r.ctrl.abort())}sleep(e){return new Promise(n=>{let r=setTimeout(s,e);function s(){clearTimeout(r),n()}this.wake=()=>{this.wake=null,s()}})}async loop(e){let n=1e3;for(;!e.signal.aborted;){let r=new AbortController,s=()=>r.abort();e.signal.addEventListener("abort",s,{once:!0}),this.conn=r;try{let{cloudUrl:i,token:a}=this.deps.getCreds();if(!a)throw new Error("\u672A\u767B\u5F55 Forsion \u8D26\u53F7");let o=this.deps.getPairing();if(!o){if(o=await this.register(i,a,r),r.signal.aborted)throw new Error("\u5165\u518C\u671F\u95F4\u901A\u9053\u5DF2\u88AB\u505C\u7528");await this.deps.savePairing(o),this.deps.log(`[unit-host] \u5DF2\u5165\u518C\u4E3A\u8BBE\u5907 ${o.unitId}`)}let l=this.deps.getLanUrl();this.hubCaps=new Set;let h=this.deps.readIdleMs??Pn,d=h?setTimeout(()=>{this.deps.log(`[unit-host] \u901A\u9053 ${Math.round(h/1e3)}s \u672A\u6536\u5230\u54CD\u5E94\u5934,\u5224\u5B9A\u5DF2\u65AD,\u91CD\u8FDE`),r.abort()},h):null,f;try{f=await this.hubFetch(`${zt(i)}/units/${o.unitId}/channel`,{headers:{Authorization:`Bearer ${a}`,"X-Unit-Secret":o.secret,...l?{"X-Unit-Lan-Url":l}:{}},signal:r.signal})}finally{d&&clearTimeout(d)}if(f.status===403||f.status===404){let u=Number(f.headers.get("content-length"))>Io,g=setTimeout(()=>r.abort(),u?0:Ao),S=await f.json().then(x=>x?.code,()=>null);throw clearTimeout(g),S==="UNIT_NOT_FOUND"||S==="UNIT_SECRET_MISMATCH"?(await this.deps.clearPairing(),new Error(`\u901A\u9053\u88AB\u62D2(${f.status} ${S}),\u5DF2\u6E05\u9664\u914D\u5BF9\u5F85\u91CD\u65B0\u5165\u518C`)):new Error(`channel HTTP ${f.status} (not a hub verdict; keeping pairing and retrying)`)}if(!f.ok||!f.body)throw new Error(`channel HTTP ${f.status}`);this.connected=!0,this.lastError=null,n=1e3,this.deps.log("[unit-host] \u901A\u9053\u5DF2\u8FDE\u63A5"),await this.consume(f.body,r),this.markDown(),this.deps.log("[unit-host] \u901A\u9053\u65AD\u5F00,\u51C6\u5907\u91CD\u8FDE")}catch(i){if(this.markDown(),e.signal.aborted)return;this.lastError=r.signal.aborted?"\u901A\u9053\u88AB\u672C\u673A\u65AD\u5F00(\u770B\u95E8\u72D7 / \u91CD\u8FDE)":String(i?.message||i),this.deps.log(`[unit-host] ${this.lastError};${this.redialNow?"\u7ACB\u5373":`${Math.round(n/1e3)}s \u540E`}\u91CD\u8BD5`)}finally{e.signal.removeEventListener("abort",s),this.conn===r&&(this.conn=null),r.abort(),this.abortEnvelopes(r)}if(e.signal.aborted)return;if(this.redialNow){this.redialNow=!1,n=1e3;continue}if(await this.sleep(n),this.redialNow){this.redialNow=!1,n=1e3;continue}n=Math.min(n*2,3e4)}}async register(e,n,r){let s=this.deps.readIdleMs??Pn,i=s?setTimeout(()=>{this.deps.log(`[unit-host] \u8BBE\u5907\u5165\u518C ${Math.round(s/1e3)}s \u672A\u8FD4\u56DE,\u4E2D\u6B62\u91CD\u8BD5`),r.abort()},s):null;try{let a=await this.hubFetch(`${zt(e)}/units/register`,{method:"POST",headers:{Authorization:`Bearer ${n}`,"Content-Type":"application/json"},body:JSON.stringify({name:To(),platform:process.platform}),signal:r.signal});if(!a.ok)throw new Error(`\u8BBE\u5907\u5165\u518C\u5931\u8D25 HTTP ${a.status}`);let o=await a.json();if(!o.unitId||!o.secret)throw new Error("\u8BBE\u5907\u5165\u518C\u54CD\u5E94\u7F3A\u5B57\u6BB5");return{unitId:o.unitId,secret:o.secret}}finally{i&&clearTimeout(i)}}async consume(e,n){let r=e.getReader(),s=new TextDecoder,i="",a=this.deps.readIdleMs??Pn,o=null,l=()=>{a&&(o&&clearTimeout(o),o=setTimeout(()=>{this.deps.log(`[unit-host] \u901A\u9053 ${Math.round(a/1e3)}s \u65E0\u4EFB\u4F55\u5B57\u8282(\u7F51\u5173 15s \u4E00\u6B21\u5FC3\u8DF3),\u5224\u5B9A\u5DF2\u65AD,\u91CD\u8FDE`),n.abort(),r.cancel().catch(()=>{})},a))};l();try{for(;;){let{done:h,value:d}=await r.read();if(h||n.signal.aborted)return;l(),i=this.parseFrames(i+s.decode(d,{stream:!0}),n)}}finally{o&&clearTimeout(o)}}parseFrames(e,n){let r=e,s;for(;(s=r.indexOf(`
200
200
 
201
- `))>=0;){let i=s.slice(0,r);if(s=s.slice(r+2),i.includes("event: ready")){let a=i.split(`
202
- `).find(c=>c.startsWith("data: "))?.slice(6);try{let c=JSON.parse(a||"{}").caps;this.hubCaps=new Set(Array.isArray(c)?c.map(String):[])}catch{this.hubCaps=new Set}t.signal.aborted||this.hook(this.deps.onChannelReady);continue}if(!i.includes("event: dispatch"))continue;let o=i.split(`
203
- `).find(a=>a.startsWith("data: "))?.slice(6);if(o)try{let a=JSON.parse(o);this.dispatch(a,t).catch(c=>this.deps.log(`[unit-host] \u6D3E\u53D1\u5904\u7406\u5931\u8D25: ${c?.message||c}`))}catch{}}return s}async dispatch(e,t){let s=new AbortController;if(t.signal.aborted)return;this.inflight.get(e.id)?.ctrl.abort();let r={ctrl:s,conn:t};this.inflight.set(e.id,r);try{await this.handle(e,s)}finally{this.inflight.get(e.id)===r&&this.inflight.delete(e.id)}}async handle(e,t){let s=this.deps.getUnitWeb();if(!s.url){await this.respond(e.id,503,"application/json",Buffer.from(JSON.stringify({detail:"\u672C\u673A\u4E92\u8054\u670D\u52A1\u672A\u5C31\u7EEA",code:"UNIT_WEB_NOT_READY"})),void 0,t.signal);return}let r={"x-unit-internal":s.internalSecret};e.ct&&(r["Content-Type"]=e.ct),e.accept&&(r.Accept=e.accept);let i;try{let d=new URL(`${s.url}${e.path}`);Object.assign(r,this.deps.callerHeaders({dispatchId:e.id,method:e.method,target:d,proxyCaller:e.proxyCaller})),i=await fetch(d,{method:e.method,headers:r,body:e.body??void 0,signal:t.signal})}catch(d){if(t.signal.aborted)return;await this.respond(e.id,502,"application/json",Buffer.from(JSON.stringify({detail:`\u672C\u673A\u4E92\u8054\u670D\u52A1\u4E0D\u53EF\u8FBE: ${d?.message||d}`})),void 0,t.signal);return}let o=i.headers.get("content-type")||"",a={};for(let d of["content-security-policy","x-content-type-options"]){let f=i.headers.get(d);f&&(a[d]=f)}let c=o||"application/octet-stream";i.body&&Wr(o,i.headers.get("content-length"),{hasSecHeaders:Object.keys(a).length>0,gatewayStreamsSecHeaders:this.hubCaps.has("stream-sec-headers")})?await this.streamBack(e.id,i,t,c,a):await this.respond(e.id,i.status,c,Buffer.from(await i.arrayBuffer()),a,t.signal)}async respond(e,t,s,r,i,o){if(o?.aborted)return;let{cloudUrl:a,token:c}=this.deps.getCreds(),h=this.deps.getPairing();if(!h)return;let d=this.requestTimeoutMs*2,f=[...d?[AbortSignal.timeout(d)]:[],...o?[o]:[]],u=f.length>1?AbortSignal.any(f):f[0];await this.hubFetch(`${Nt(a)}/units/${h.unitId}/resp/${e}`,{method:"POST",headers:{Authorization:`Bearer ${c}`,"X-Unit-Secret":h.secret,"Content-Type":"application/json"},body:JSON.stringify({status:t,headers:{"content-type":s,...i},bodyB64:r.toString("base64")}),...u?{signal:u}:{}}).then(y=>{y.body?.cancel().catch(()=>{})}).catch(y=>{o?.aborted||this.deps.log(`[unit-host] \u56DE\u5305\u5931\u8D25: ${y?.name==="TimeoutError"?`${Math.round(d/1e3)}s \u672A\u5B8C\u6210`:y?.message||y}`)})}async streamBack(e,t,s,r,i){let{cloudUrl:o,token:a}=this.deps.getCreds(),c=this.deps.getPairing();if(!c)return;let h=i?.["content-security-policy"],d=i?.["x-content-type-options"],f=`${Nt(o)}/units/${c.unitId}/stream/${e}?status=${t.status}&ct=${encodeURIComponent(r)}`+(h?`&csp=${encodeURIComponent(h)}`:"")+(d?`&xcto=${encodeURIComponent(d)}`:""),u=t.body;if(!u)return;let y=u.getReader(),v=0,x=this.requestTimeoutMs,E=x?setTimeout(()=>{v>=2||(this.deps.log(`[unit-host] \u6D41\u5F0F\u56DE\u4F20 ${Math.round(x/1e3)}s \u672A\u628A\u9996\u5757\u5199\u7ED9\u7F51\u5173,\u4E2D\u6B62\u672C\u6B21\u6D3E\u53D1`),s.abort())},x):null,U=new ReadableStream({async pull(M){++v===2&&E&&clearTimeout(E);let{done:Y,value:B}=await y.read();Y?M.close():M.enqueue(B)},cancel(M){return y.cancel(M)}},{highWaterMark:0});try{await this.hubFetch(f,{method:"POST",headers:{Authorization:`Bearer ${a}`,"X-Unit-Secret":c.secret,"Content-Type":"application/octet-stream"},body:U,signal:s.signal,duplex:"half"})}catch(M){this.deps.log(`[unit-host] \u6D41\u5F0F\u56DE\u4F20\u4E2D\u65AD: ${M?.message||M}`);try{await y.cancel()}catch{}}finally{E&&clearTimeout(E)}}};var dt=class{d;up=!1;gen=0;lastSent=null;disabled=!1;inflight=!1;again=!1;timer=null;warned=new Set;constructor(e){this.d=e}channelReady(){this.gen++,this.up=!0,this.lastSent=null,this.disabled=!1,this.clearTimer(),this.again=!1,this.flush()}channelDown(){this.gen++,this.up=!1,this.lastSent=null,this.again=!1,this.clearTimer()}engineChanged(){!this.up||this.disabled||(this.clearTimer(),this.timer=setTimeout(()=>{this.timer=null,this.flush()},this.d.debounceMs??500))}clearTimer(){this.timer&&(clearTimeout(this.timer),this.timer=null)}async flush(){if(!this.up||this.disabled)return;if(this.inflight){this.again=!0;return}let e;try{e=this.d.current()}catch(a){this.d.log(`[unit-caps] \u8BFB\u5F15\u64CE\u6001\u5931\u8D25:${a?.message||a}`);return}if(e===this.lastSent)return;let t=this.d.getPairing(),s;try{s=this.d.getCreds()}catch{return}if(!t||!s.token||!s.cloudUrl)return;let r=this.gen;this.inflight=!0;let i=new AbortController,o=setTimeout(()=>i.abort(),this.d.timeoutMs??1e4);try{let a=`${s.cloudUrl.replace(/\/+$/,"")}/api/units/${encodeURIComponent(t.unitId)}/caps`,c=await(this.d.hubFetch??fetch)(a,{method:"POST",headers:{Authorization:`Bearer ${s.token}`,"X-Unit-Secret":t.secret,"Content-Type":"application/json"},body:JSON.stringify({engine:e,tools:[]}),signal:i.signal});try{await c.text()}catch{}if(r!==this.gen)return;c.ok?(this.lastSent=e,this.d.log(`[unit-caps] \u5DF2\u4E0A\u62A5\u5F15\u64CE\u6001 ${e}`)):c.status===404||c.status===405?(this.disabled=!0,this.d.log(`[unit-caps] \u7F51\u5173\u4E0D\u6536 caps(HTTP ${c.status},\u8001\u7248\u672C),\u672C\u8FDE\u63A5\u5185\u4E0D\u518D\u4E0A\u62A5`)):c.status===400||c.status===401||c.status===403?this.warned.has(c.status)||(this.warned.add(c.status),this.d.log(`[unit-caps] \u4E0A\u62A5\u88AB\u62D2 HTTP ${c.status}`)):this.d.log(`[unit-caps] \u4E0A\u62A5\u5931\u8D25 HTTP ${c.status},\u7B49\u4E0B\u6B21\u53D8\u5316 / \u91CD\u8FDE\u518D\u62A5`)}catch(a){r===this.gen&&this.d.log(`[unit-caps] \u4E0A\u62A5\u5931\u8D25:${i.signal.aborted?"\u8D85\u65F6":a?.message||a}`)}finally{clearTimeout(o),this.inflight=!1,this.again&&this.up&&!this.disabled&&(this.again=!1,this.flush())}}};var qr=["setUnitHubFactory"],vn=n=>qr.every(e=>typeof n[e]=="function");function Br(n){let e=new dt({getCreds:()=>n.getCreds(),getPairing:()=>n.getPairing(),current:()=>n.engineCaps(),log:s=>n.log(s)}),t=new ut({onChannelReady:()=>e.channelReady(),onChannelDown:()=>e.channelDown(),getCreds:()=>n.getCreds(),getUnitWeb:()=>n.getUnitWeb(),callerHeaders:s=>n.callerHeaders(s),getLanUrl:()=>n.getLanUrl(),getPairing:()=>n.getPairing(),savePairing:s=>n.savePairing(s),clearPairing:()=>n.clearPairing(),log:s=>n.log(s)});return{start:()=>t.start(),stop:()=>t.stop(),reconnect:s=>t.reconnect(s),status:()=>t.status(),engineChanged:()=>e.engineChanged()}}function En(n){let e=async(t,s,r)=>{let{base:i,token:o}=await n.getCloud();if(!o)return{status:401,json:{detail:"\u672A\u767B\u5F55 Forsion \u8D26\u53F7"}};try{let a=await fetch(`${i}/api${s}`,{method:t,headers:{Authorization:`Bearer ${o}`,...r!==void 0?{"Content-Type":"application/json"}:{}},body:r!==void 0?JSON.stringify(r):void 0});return{status:a.status,json:await a.json().catch(()=>null)}}catch(a){return{status:0,json:{detail:String(a?.message||a)}}}};n.handle("units:list",()=>e("GET","/units")),n.handle("units:update",(t,s,r)=>e("PATCH",`/units/${encodeURIComponent(String(s))}`,{name:r?.name,icon:r?.icon})),n.handle("units:remove",(t,s)=>e("DELETE",`/units/${encodeURIComponent(String(s))}`)),n.handle("units:openInBrowser",async(t,s)=>{if(typeof s!="string"||!/^[0-9a-zA-Z-]{8,64}$/.test(s))throw new Error("\u53C2\u6570\u4E0D\u5B8C\u6574");let{base:r,token:i}=await n.getCloud();await n.openExternal(`${r}/api/units/${s}/open${i?`#token=${encodeURIComponent(i)}`:""}`)}),n.setUnitHubFactory(Br),n.log("[forsion-extend] unit hub registered")}async function Vr(n,e){if(!e)return"";try{let t=await de({base:n,token:e},"POST","/api/auth/handoff",{},5e3);if(t.status===200&&typeof t.json?.code=="string"&&t.json.code)return`code=${encodeURIComponent(t.json.code)}`;if(t.status===404||t.status===405)return`token=${encodeURIComponent(e)}`}catch{}return""}var Xi=["membership","credits"];function qa(n){let e={status:0,error:"untrusted"},t={ok:!1,error:"untrusted"};n.handle("auth:openAccountCenter",async(r,i)=>{if(!n.isTrustedSender(r))return t;let{base:o,token:a}=await n.getCloud();if(!o)return{ok:!1};let c=i&&/^[a-z0-9-]+$/i.test(i)?`#${i}`:"",h=await Vr(o,a),d=`${o}/account${h?`?${h}`:""}${c}`;return await n.openExternal(d),{ok:!0}}),n.handle("auth:openPayCenter",async(r,i)=>{if(!n.isTrustedSender(r))return t;if(i!==void 0&&!Xi.includes(i))return{ok:!1,error:"invalid_tab"};let{base:o,token:a}=await n.getCloud();if(!o)return{ok:!1};let c=await Vr(o,a),h=`${o}/pay?tab=${i??"membership"}${c?`&${c}`:""}&redirect=${encodeURIComponent(`${o}/account`)}`;return await n.openExternal(h),{ok:!0}});let s=()=>n.getCloud();n.handle("account:quota",async r=>{if(!n.isTrustedSender(r))return e;let i=await s();if(!i.token)return{status:401,json:null};try{return await de(i,"GET","/api/token-quota/my",void 0,15e3)}catch(o){return{status:0,json:{detail:String(o?.message||o)}}}}),n.handle("account:useResetCard",async(r,i)=>{if(!n.isTrustedSender(r))return e;let o=await s();if(!o.token)return{status:401,json:null};if(i!==void 0&&i!=="both")return{status:400,json:{error:"invalid_type",detail:`invalid reset card type: ${i}`}};let a=i??"both";try{return await de(o,"POST","/api/token-quota/reset-card/use",{type:a},15e3)}catch(c){return{status:0,json:{detail:String(c?.message||c)}}}}),n.handle("account:bgConvert",async(r,i)=>{if(!n.isTrustedSender(r))return e;let o=await s();if(!o.token)return{status:401,json:null};if(!Number.isInteger(i)||i<1||i>100)return{status:400,json:{error:"invalid_percent"}};try{return await de(o,"POST","/api/token-quota/background/convert",{percent:i},15e3)}catch(a){return{status:0,json:{detail:String(a?.message||a)}}}}),n.handle("account:bgAutoMain",async(r,i)=>{if(!n.isTrustedSender(r))return e;let o=await s();if(!o.token)return{status:401,json:null};if(typeof i!="boolean")return{status:400,json:{error:"invalid_request"}};try{return await de(o,"POST","/api/token-quota/background/auto-main",{enabled:i},15e3)}catch(a){return{status:0,json:{detail:String(a?.message||a)}}}}),n.handle("feedback:submit",async(r,i)=>{if(!n.isTrustedSender(r))return t;let{base:o,token:a}=await n.getCloud();if(!o||!a)return{ok:!1,error:"not-logged-in"};let c=(i?.description||"").trim();if(!c)return{ok:!1,error:"empty"};if(c.length>1e4)return{ok:!1,error:"description-too-long"};let h=[],d=!1;if(i?.sessionLogJson){let f=Buffer.from(i.sessionLogJson,"utf8");if(f.length>5*1024*1024)return{ok:!1,error:"attachment-too-large"};h.push({filename:i.sessionLogName||"tangu-session.json",mime_type:"application/json",size:f.length,data_base64:f.toString("base64")})}try{let f=await fetch(`${o}/api/feedback`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${a}`},body:JSON.stringify({description:c,attachments:h}),signal:AbortSignal.timeout(2e4)});if(!f.ok){let y=`HTTP ${f.status}`;try{y=(await f.json())?.detail||y}catch{}return{ok:!1,error:y}}return{ok:!0,id:(await f.json().catch(()=>({})))?.id??null,attachmentSkipped:d}}catch(f){return{ok:!1,error:f?.message||String(f)}}}),n.handle("cloud:fetch",async(r,i)=>{if(!n.isTrustedSender(r))return{status:0,error:"untrusted"};let o=i??{},a=typeof o.path=="string"?o.path:"",c=Math.min(12e4,Math.max(1e3,Number(o.timeoutMs)||15e3)),h=typeof o.method=="string"?o.method.toUpperCase():"GET";if(!/^(GET|POST|PUT|PATCH|DELETE)$/.test(h))return{status:0,error:"bad_method"};if(!a.startsWith("/"))return{status:0,error:"bad_path"};let{base:d,token:f}=await n.getCloud();if(!String(d||""))return{status:0,error:"no_cloud_url"};let u=Dn(d,a);if(!u)return{status:0,error:"bad_path"};if(!f)return{status:401,error:"not_signed_in"};let y=o.body!==void 0&&h!=="GET"&&h!=="DELETE",v=new AbortController,x=setTimeout(()=>v.abort(),c);try{let E=await fetch(u,{method:h,headers:{Authorization:`Bearer ${f}`,...y?{"Content-Type":"application/json"}:{}},body:y?JSON.stringify(o.body):void 0,signal:v.signal});return{status:E.status,json:await E.json().catch(()=>null)}}catch(E){return{status:0,error:String(E?.message||E)}}finally{clearTimeout(x)}}),n.log("[forsion-extend] cloud account handlers registered"),zt(n)?Wt(n):n.log("[forsion-extend] host has no Connect seam (projectsRoot / transpileForServe / mimeOf / setPreviewHooks); Connect stays with the host"),Bt(n)?Vt(n):n.log("[forsion-extend] host has no remote-sync seam (registerRemoteSyncBackend / readCreds); penzor stays with the host"),Yt(n)?Jt(n):n.log("[forsion-extend] host has no account seam (accountCommit / accountClear / \u2026); account core stays with the host"),wn(n)?bn(n):n.log("[forsion-extend] host has no amadeus seam (setAmadeusSyncFactory); cloud sync stays with the host"),vn(n)?En(n):n.log("[forsion-extend] host has no unit seam (setUnitHubFactory); the device channel stays with the host")}export{Qn as ACCOUNT_SEAM,Hr as AMADEUS_SEAM,Lt as CONNECT_MAX_FILES,Nn as CONNECT_MAX_FILE_BYTES,Un as CONNECT_MAX_TOTAL_BYTES,zn as FORSION_CONNECT_LOCAL_SDK,Xi as PAY_TABS,Vn as PENZOR_MAX_FILE,oe as SYNC_IPC,qr as UNIT_SEAM,dt as UnitCapsReporter,ut as UnitHost,de as cloudJson,Fn as collectProjectFiles,At as conflictCopyPath,wi as conflictCopyVariant,Kn as createAccountCloud,zr as createAmadeusCloud,Bn as createPenzorRemote,Br as createUnitHub,qt as expectedPartsOf,Se as forsionAccountId,Xn as forsionRefreshToken,nt as forsionWhoami,Yt as hasAccountHost,wn as hasAmadeusHost,zt as hasConnectHost,Bt as hasRemoteSyncHost,vn as hasUnitHost,Hn as makePreviewProxy,jn as readConnectMeta,Jt as registerAccount,bn as registerAmadeus,qa as registerCloud,Wt as registerConnect,Vt as registerPenzor,En as registerUnit,Jn as shouldRefreshToken,Wr as streamWorthy,Or as stripConflictSuffix,bi as textFingerprint,Yn as tokenAgeMs,Ss as tokenRemainingMs,Ln as writeConnectMeta};
201
+ `))>=0;){let i=r.slice(0,s);if(r=r.slice(s+2),i.includes("event: ready")){let o=i.split(`
202
+ `).find(l=>l.startsWith("data: "))?.slice(6);try{let l=JSON.parse(o||"{}").caps;this.hubCaps=new Set(Array.isArray(l)?l.map(String):[])}catch{this.hubCaps=new Set}n.signal.aborted||this.hook(this.deps.onChannelReady);continue}if(!i.includes("event: dispatch"))continue;let a=i.split(`
203
+ `).find(o=>o.startsWith("data: "))?.slice(6);if(a)try{let o=JSON.parse(a);this.dispatch(o,n).catch(l=>this.deps.log(`[unit-host] \u6D3E\u53D1\u5904\u7406\u5931\u8D25: ${l?.message||l}`))}catch{}}return r}async dispatch(e,n){let r=new AbortController;if(n.signal.aborted)return;this.inflight.get(e.id)?.ctrl.abort();let s={ctrl:r,conn:n};this.inflight.set(e.id,s);try{await this.handle(e,r)}finally{this.inflight.get(e.id)===s&&this.inflight.delete(e.id)}}async handle(e,n){let r=this.deps.getUnitWeb();if(!r.url){await this.respond(e.id,503,"application/json",Buffer.from(JSON.stringify({detail:"\u672C\u673A\u4E92\u8054\u670D\u52A1\u672A\u5C31\u7EEA",code:"UNIT_WEB_NOT_READY"})),void 0,n.signal);return}let s={"x-unit-internal":r.internalSecret};e.ct&&(s["Content-Type"]=e.ct),e.accept&&(s.Accept=e.accept);let i;try{let d=new URL(`${r.url}${e.path}`);Object.assign(s,this.deps.callerHeaders({dispatchId:e.id,method:e.method,target:d,proxyCaller:e.proxyCaller})),i=await fetch(d,{method:e.method,headers:s,body:e.body??void 0,signal:n.signal})}catch(d){if(n.signal.aborted)return;await this.respond(e.id,502,"application/json",Buffer.from(JSON.stringify({detail:`\u672C\u673A\u4E92\u8054\u670D\u52A1\u4E0D\u53EF\u8FBE: ${d?.message||d}`})),void 0,n.signal);return}let a=i.headers.get("content-type")||"",o={};for(let d of["content-security-policy","x-content-type-options"]){let f=i.headers.get(d);f&&(o[d]=f)}let l=a||"application/octet-stream";i.body&&ss(a,i.headers.get("content-length"),{hasSecHeaders:Object.keys(o).length>0,gatewayStreamsSecHeaders:this.hubCaps.has("stream-sec-headers")})?await this.streamBack(e.id,i,n,l,o):await this.respond(e.id,i.status,l,Buffer.from(await i.arrayBuffer()),o,n.signal)}async respond(e,n,r,s,i,a){if(a?.aborted)return;let{cloudUrl:o,token:l}=this.deps.getCreds(),h=this.deps.getPairing();if(!h)return;let d=this.requestTimeoutMs*2,f=[...d?[AbortSignal.timeout(d)]:[],...a?[a]:[]],u=f.length>1?AbortSignal.any(f):f[0];await this.hubFetch(`${zt(o)}/units/${h.unitId}/resp/${e}`,{method:"POST",headers:{Authorization:`Bearer ${l}`,"X-Unit-Secret":h.secret,"Content-Type":"application/json"},body:JSON.stringify({status:n,headers:{"content-type":r,...i},bodyB64:s.toString("base64")}),...u?{signal:u}:{}}).then(g=>{g.body?.cancel().catch(()=>{})}).catch(g=>{a?.aborted||this.deps.log(`[unit-host] \u56DE\u5305\u5931\u8D25: ${g?.name==="TimeoutError"?`${Math.round(d/1e3)}s \u672A\u5B8C\u6210`:g?.message||g}`)})}async streamBack(e,n,r,s,i){let{cloudUrl:a,token:o}=this.deps.getCreds(),l=this.deps.getPairing();if(!l)return;let h=i?.["content-security-policy"],d=i?.["x-content-type-options"],f=`${zt(a)}/units/${l.unitId}/stream/${e}?status=${n.status}&ct=${encodeURIComponent(s)}`+(h?`&csp=${encodeURIComponent(h)}`:"")+(d?`&xcto=${encodeURIComponent(d)}`:""),u=n.body;if(!u)return;let g=u.getReader(),S=0,x=this.requestTimeoutMs,w=x?setTimeout(()=>{S>=2||(this.deps.log(`[unit-host] \u6D41\u5F0F\u56DE\u4F20 ${Math.round(x/1e3)}s \u672A\u628A\u9996\u5757\u5199\u7ED9\u7F51\u5173,\u4E2D\u6B62\u672C\u6B21\u6D3E\u53D1`),r.abort())},x):null,F=new ReadableStream({async pull(k){++S===2&&w&&clearTimeout(w);let{done:A,value:U}=await g.read();A?k.close():k.enqueue(U)},cancel(k){return g.cancel(k)}},{highWaterMark:0});try{await this.hubFetch(f,{method:"POST",headers:{Authorization:`Bearer ${o}`,"X-Unit-Secret":l.secret,"Content-Type":"application/octet-stream"},body:F,signal:r.signal,duplex:"half"})}catch(k){this.deps.log(`[unit-host] \u6D41\u5F0F\u56DE\u4F20\u4E2D\u65AD: ${k?.message||k}`);try{await g.cancel()}catch{}}finally{w&&clearTimeout(w)}}};var yt=class{d;up=!1;gen=0;lastSent=null;disabled=!1;inflight=!1;again=!1;timer=null;warned=new Set;constructor(e){this.d=e}channelReady(){this.gen++,this.up=!0,this.lastSent=null,this.disabled=!1,this.clearTimer(),this.again=!1,this.flush()}channelDown(){this.gen++,this.up=!1,this.lastSent=null,this.again=!1,this.clearTimer()}engineChanged(){!this.up||this.disabled||(this.clearTimer(),this.timer=setTimeout(()=>{this.timer=null,this.flush()},this.d.debounceMs??500))}clearTimer(){this.timer&&(clearTimeout(this.timer),this.timer=null)}async flush(){if(!this.up||this.disabled)return;if(this.inflight){this.again=!0;return}let e;try{e=this.d.current()}catch(o){this.d.log(`[unit-caps] \u8BFB\u5F15\u64CE\u6001\u5931\u8D25:${o?.message||o}`);return}if(e===this.lastSent)return;let n=this.d.getPairing(),r;try{r=this.d.getCreds()}catch{return}if(!n||!r.token||!r.cloudUrl)return;let s=this.gen;this.inflight=!0;let i=new AbortController,a=setTimeout(()=>i.abort(),this.d.timeoutMs??1e4);try{let o=`${r.cloudUrl.replace(/\/+$/,"")}/api/units/${encodeURIComponent(n.unitId)}/caps`,l=await(this.d.hubFetch??fetch)(o,{method:"POST",headers:{Authorization:`Bearer ${r.token}`,"X-Unit-Secret":n.secret,"Content-Type":"application/json"},body:JSON.stringify({engine:e,tools:[]}),signal:i.signal});try{await l.text()}catch{}if(s!==this.gen)return;l.ok?(this.lastSent=e,this.d.log(`[unit-caps] \u5DF2\u4E0A\u62A5\u5F15\u64CE\u6001 ${e}`)):l.status===404||l.status===405?(this.disabled=!0,this.d.log(`[unit-caps] \u7F51\u5173\u4E0D\u6536 caps(HTTP ${l.status},\u8001\u7248\u672C),\u672C\u8FDE\u63A5\u5185\u4E0D\u518D\u4E0A\u62A5`)):l.status===400||l.status===401||l.status===403?this.warned.has(l.status)||(this.warned.add(l.status),this.d.log(`[unit-caps] \u4E0A\u62A5\u88AB\u62D2 HTTP ${l.status}`)):this.d.log(`[unit-caps] \u4E0A\u62A5\u5931\u8D25 HTTP ${l.status},\u7B49\u4E0B\u6B21\u53D8\u5316 / \u91CD\u8FDE\u518D\u62A5`)}catch(o){s===this.gen&&this.d.log(`[unit-caps] \u4E0A\u62A5\u5931\u8D25:${i.signal.aborted?"\u8D85\u65F6":o?.message||o}`)}finally{clearTimeout(a),this.inflight=!1,this.again&&this.up&&!this.disabled&&(this.again=!1,this.flush())}}};var is=["setUnitHubFactory"],Dn=t=>is.every(e=>typeof t[e]=="function");function os(t){let e=new yt({getCreds:()=>t.getCreds(),getPairing:()=>t.getPairing(),current:()=>t.engineCaps(),log:r=>t.log(r)}),n=new pt({onChannelReady:()=>e.channelReady(),onChannelDown:()=>e.channelDown(),getCreds:()=>t.getCreds(),getUnitWeb:()=>t.getUnitWeb(),callerHeaders:r=>t.callerHeaders(r),getLanUrl:()=>t.getLanUrl(),getPairing:()=>t.getPairing(),savePairing:r=>t.savePairing(r),clearPairing:()=>t.clearPairing(),log:r=>t.log(r)});return{start:()=>n.start(),stop:()=>n.stop(),reconnect:r=>n.reconnect(r),status:()=>n.status(),engineChanged:()=>e.engineChanged()}}function $n(t){let e=async(n,r,s)=>{let{base:i,token:a}=await t.getCloud();if(!a)return{status:401,json:{detail:"\u672A\u767B\u5F55 Forsion \u8D26\u53F7"}};try{let o=await fetch(`${i}/api${r}`,{method:n,headers:{Authorization:`Bearer ${a}`,...s!==void 0?{"Content-Type":"application/json"}:{}},body:s!==void 0?JSON.stringify(s):void 0});return{status:o.status,json:await o.json().catch(()=>null)}}catch(o){return{status:0,json:{detail:String(o?.message||o)}}}};t.handle("units:list",()=>e("GET","/units")),t.handle("units:update",(n,r,s)=>e("PATCH",`/units/${encodeURIComponent(String(r))}`,{name:s?.name,icon:s?.icon})),t.handle("units:remove",(n,r)=>e("DELETE",`/units/${encodeURIComponent(String(r))}`)),t.handle("units:openInBrowser",async(n,r)=>{if(typeof r!="string"||!/^[0-9a-zA-Z-]{8,64}$/.test(r))throw new Error("\u53C2\u6570\u4E0D\u5B8C\u6574");let{base:s,token:i}=await t.getCloud();await t.openExternal(`${s}/api/units/${r}/open${i?`#token=${encodeURIComponent(i)}`:""}`)}),t.setUnitHubFactory(os),t.log("[forsion-extend] unit hub registered")}import{createHash as Po}from"node:crypto";import{mkdirSync as Do,readFileSync as $o,renameSync as Mo,writeFileSync as No}from"node:fs";import{lstat as Vt,open as Oo,readFile as Uo,readdir as ps}from"node:fs/promises";import{homedir as as,hostname as ys,release as Fo}from"node:os";import{basename as jo,join as ue}from"node:path";var ws=14,Un=60*6e4,Lo=24*Un,Ho=2*6e4,zo=12e4,qo=10*6e4,ls=Un,Bo=15e3,cs=1792*1024,Wo=7,Vo=4*1024*1024,Yo=256*1024,it=t=>t.toISOString().slice(0,10),Bt=t=>Date.parse(it(t))-(Wo-1)*Lo,us=["user","teamwork","discussion","delegate"],Go=/^(?:New remarks in the team chat:|You are activated now \()/,bs={totalBytes:1024*1024,sessionBytes:256*1024,textChars:8e3,sessions:300,messages:400},Jo=["homeDir","readCreds","accountId","appVersion"],Ss=t=>Jo.every(e=>typeof t[e]=="function"),ds=as().length>3?as():null;function Mn(t){return typeof t=="string"?(ds?t.split(ds).join("~"):t).replace(/\bBearer\s+[A-Za-z0-9._~+\/-]+=*/gi,"Bearer [redacted]").replace(/\b(sk-[a-zA-Z0-9_-]{12,})\b/g,"[redacted]").replace(/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}/g,"[redacted]").replace(/\b(?:gh[pousr]_[A-Za-z0-9]{20,}|github_pat_[A-Za-z0-9_]{20,}|AKIA[0-9A-Z]{16}|LTAI[0-9A-Za-z]{12,}|xox[abeprs]-[A-Za-z0-9-]{10,}|AIza[0-9A-Za-z_-]{30,})/g,"[redacted]").replace(/-{5}BEGIN [A-Z ]*PRIVATE KEY-{5}[\s\S]*?(?:-{5}END [A-Z ]*PRIVATE KEY-{5}|$)/g,"[redacted]").replace(/\b[a-fA-F0-9]{32,}\b/g,e=>`[hex:${e.length}]`).replace(/((?:["']?)(?:api[_-]?key|access[_-]?token|refresh[_-]?token|token|password|secret|authorization|cookie)(?:["']?)\s*[:=]\s*)("[^"\n]*"|'[^'\n]*'|\[[^\]\n]*\]|[^\s,"';&}]+)/gi,"$1[redacted]"):Array.isArray(t)?t.map(Mn):t&&typeof t=="object"?Object.fromEntries(Object.entries(t).map(([e,n])=>[e,/^(?:token|.*api[_-]?key|access[_-]?token|refresh[_-]?token|password|secret|authorization|cookie|set-cookie)$/i.test(e)?"[redacted]":Mn(n)])):t}var Ko=/^(?:model|modelId|voice|mode|backend|notify|escalateTo|realtimeModel|realtimeVoice|vision|background)$/,re=(t,e=120)=>typeof t=="string"&&t.length<=e?t:void 0,Xo=(t,e)=>/^[A-Za-z_][\w.-]{0,63}$/.test(t)?t:`[key:${e}]`;function rt(t,e=0){if(typeof t=="boolean"||typeof t=="number"||t===null||t===void 0)return t??null;if(typeof t=="string")return`[string:${t.length}]`;if(Array.isArray(t))return`[array:${t.length}]`;if(typeof t!="object"||e>=4)return"[object]";let n={};for(let[r,[s,i]]of Object.entries(t).slice(0,100).entries())n[Xo(s,r)]=Ko.test(s)&&re(i,80)!==void 0?i:rt(i,e+1);return n}var Zo=/^(?:name|version|model|model_reasoning_effort|approval_mode|created_by|created_at|avatar|lead|slug)$/,Qo=/^(?:apps|enabled_skill_ids)$/;function ea(t){let e=[],n=t.split(/\r?\n/);for(let r=0;r<n.length;r++){let s=n[r].trim();if(/^\[\[?[\w.-]{1,80}\]\]?$/.test(s)){e.push(s);continue}let i=/^([\w.-]+)\s*=\s*(.*)$/.exec(s);if(!i)continue;let[,a,o]=i,l=/^('''|""")/.exec(o)?.[1],h=o.length;if(l&&!o.slice(3).includes(l))for(;++r<n.length&&!n[r].includes(l);)h+=n[r].length+1;let d=/^(?:true|false|[+-]?\d[\d._]*)$/.test(o)||Zo.test(a)&&h<=120&&/^(?:"[^"]*"|'[^']*'|\d{4}-\d{2}-\d{2}[\dT:.+Z -]*)$/.test(o)||Qo.test(a)&&h<=2e3&&/^\[[^\[\]{}]*\]$/.test(o);e.push(d?`${a} = ${o}`:`${a} = "[text:${h}]"`)}return e.join(`
204
+ `)}var vs=async t=>{try{return(await Vt(t)).isFile()?await Uo(t,"utf8"):null}catch{return null}},ta=t=>Vt(t).then(e=>e.isDirectory(),()=>!1),Fn=async t=>{try{return JSON.parse(await vs(t)??"null")}catch{return null}},st=async(t,e=200)=>{try{return(await ps(t)).filter(n=>!n.startsWith(".")&&n.length<=120).sort().slice(0,e)}catch{return[]}};async function na(t,e){if(!(await Vt(t)).isFile())return"";let n=await Oo(t,"r");try{let{size:r}=await n.stat(),s=Math.max(0,r-e),i=Buffer.alloc(r-s);await n.read(i,0,i.length,s);let a=i.toString("utf8");return s>0?a.slice(a.indexOf(`
205
+ `)+1):a}finally{await n.close()}}function ra(t){if(!t||typeof t!="object")return{};let e=n=>n&&typeof n=="object"?Object.entries(n).slice(0,100):[];return{defaultModel:re(t.cloud?.defaultModel)??null,models:rt(t.models),tts:rt(t.tts),asr:rt(t.asr),specialAgents:rt(t.specialAgents),pluginSettings:rt(t.plugins?.global),providers:(Array.isArray(t.providers)?t.providers:[]).slice(0,50).map(n=>({providerId:re(n?.providerId)??null,models:(Array.isArray(n?.modelIds)?n.modelIds:[]).filter(r=>re(r)!==void 0).slice(0,100)})),mcpServers:e(t.mcp?.mcpServers).map(([n,r])=>({name:re(n,64)??"[name]",enabled:r?.enabled!==!1})),channels:e(t.channels).map(([n,r])=>({name:re(n,64)??"[name]",enabled:r?.enabled===!0}))}}var sa=new Set(["config.toml","SOUL.md","MEMORY.md","HARNESS.md","HUMAN.md","Library","LOG","skills","plugins","Space","SCHEDULE.db","triggers.json"]);async function fs(t){let e=[];for(let n of await st(t,100)){let r=ue(t,n);if(!await ta(r))continue;let s=await vs(ue(r,"config.toml"));e.push({id:n,config:s===null?null:ea(s).slice(0,4096),files:(await st(r,400)).filter(i=>sa.has(i))})}return e}async function hs(t){let e=[];for(let n of await st(t,300)){let r=await Fn(ue(t,n,"manifest.json"));r&&e.push({id:re(r.id)??n,version:re(r.version,40)??null,name:re(r.nameEn)??re(r.name)??null})}return e}var Nn=t=>String(t?.code||t?.message||t).slice(0,120);async function ia(t,e,n,r=Yo){let s=u=>String(u).padStart(2,"0"),i=u=>{let g=new Date(u);return`${g.getFullYear()}${s(g.getMonth()+1)}${s(g.getDate())}${s(g.getHours())}${s(g.getMinutes())}`},a=u=>`${u.slice(0,4)}-${u.slice(4,6)}-${u.slice(6,8)}.log`,o=i(n),l=i(e.getTime()),h=[],d=r,f=!1;try{let u=(await ps(t)).filter(g=>/^\d{4}-\d{2}-\d{2}\.log$/.test(g)&&g>=a(o)&&g<=a(l)).sort().reverse();for(let g of u){if(f)break;let x=(await na(ue(t,g),Vo).catch(F=>{if(F?.code==="ENOENT")return"";throw F})).split(`
206
+ `).filter(F=>/^\d{12} /.test(F)&&F.slice(0,12)>=o&&F.slice(0,12)<l),w=x.length;for(;w>0&&Buffer.byteLength(x[w-1])+1<=d;)d-=Buffer.byteLength(x[--w])+1;w>0&&(f=!0),w<x.length&&h.push({date:g.slice(0,10),log:x.slice(w).join(`
207
+ `)})}}catch(u){return u?.code==="ENOENT"?{activity:[]}:{activity:[],activityError:Nn(u)}}return{activity:h.reverse(),...f?{activityTruncated:!0}:{}}}var qt=(t,e)=>{if(!(typeof t!="string"||!t))return t.length>e?`${t.slice(0,e)}\u2026[+${t.length-e}]`:t},ms=t=>{try{let e=typeof t=="string"?JSON.parse(t):t;return Array.isArray(e)?e:[]}catch{return[]}},gs=t=>new Date(t).toISOString().slice(0,19).replace("T"," ");async function oa(t,e,n=bs,r=Bt(e)){let s=ue(t,"tangu","state.db"),i=await Vt(s).then(o=>o.isFile(),o=>o?.code==="ENOENT"?!1:Nn(o));if(i!==!0)return i===!1?{sessions:[]}:{sessions:[],sessionsError:i};let a;try{let{DatabaseSync:o}=await import("node:sqlite");a=new o(s,{readOnly:!0}),a.exec("PRAGMA busy_timeout = 1500");let h="m.updated_at >= ? AND m.updated_at < ? AND m.timestamp >= ?",d=[gs(r),gs(e.getTime()),Bt(e)],f=a.prepare(`SELECT s.id, s.kind, s.parent_session_id, s.app_id, s.title, s.model_id, s.project_name, s.archived, s.created_at, s.updated_at, MAX(m.updated_at) AS changed_at
208
+ FROM chat_messages m JOIN chat_sessions s ON s.id = m.session_id
209
+ WHERE s.kind IN (${us.map(()=>"?").join(", ")}) AND ${h} GROUP BY s.id ORDER BY changed_at DESC, s.id LIMIT ?`).all(...us,...d,n.sessions+1),u=a.prepare(`SELECT m.role, m.content, m.reasoning, m.timestamp, m.model_id, m.is_error, m.tool_calls, length(m.tool_results) AS tool_result_chars, m.attachments, m.agent_slug
210
+ FROM chat_messages m WHERE m.session_id = ? AND ${h} ORDER BY m.timestamp DESC, m.created_at DESC LIMIT ?`),g=[],S=0,x=f.length>n.sessions;for(let w of f.slice(0,n.sessions)){let F=u.all(w.id,...d,n.messages+1),k=F.length>n.messages,A=[],U=0;for(let j of F.slice(0,n.messages)){let K=ms(j.tool_calls),se=w.kind==="teamwork"&&j.role==="user"&&Go.test(String(j.content??"")),he={role:re(j.role,16)??null,at:Number(j.timestamp)||null,agent:re(j.agent_slug,64),model:re(j.model_id,128),error:j.is_error?!0:void 0,text:se?void 0:qt(j.content,n.textChars),relayChars:se?String(j.content??"").length:void 0,reasoning:qt(j.reasoning,n.textChars),tools:K.length?K.map(ae=>re(ae?.function?.name??ae?.name,80)??"?"):void 0,toolArgChars:K.length?K.reduce((ae,Ee)=>ae+String(Ee?.function?.arguments??"").length,0):void 0,toolResultChars:Number(j.tool_result_chars)||void 0,attachments:ms(j.attachments).length||void 0},we=Buffer.byteLength(JSON.stringify(he));if(U+we>n.sessionBytes){k=!0;break}U+=we,A.push(he)}let M={id:re(w.id,64)??null,kind:re(w.kind,16)??null,parent:re(w.parent_session_id,64),app:re(w.app_id,50)??null,title:qt(w.title,200)??null,model:re(w.model_id,128)??null,project:qt(w.project_name,120),archived:w.archived?!0:void 0,createdAt:re(w.created_at,40)??null,updatedAt:re(w.updated_at,40)??null,messages:A.reverse(),...k?{olderMessagesDropped:!0}:{}},B=Buffer.byteLength(JSON.stringify(M));if(S+B>n.totalBytes){x=!0;break}S+=B,g.push(M)}return{sessions:g,...x?{sessionsTruncated:!0}:{}}}catch(o){return{sessions:[],sessionsError:Nn(o)}}finally{try{a?.close()}catch{}}}async function Es(t){let e=(await Fn(ue(t,"tangu","device.json")))?.deviceId;return typeof e=="string"&&/^[A-Za-z0-9_-]{1,64}$/.test(e)?e:`h${Po("sha256").update(ys()).digest("hex").slice(0,8)}`}var ks=["sessions","activity"],Wt=t=>typeof t=="number"&&Number.isFinite(t)?t:void 0;function aa(t,e,n){let r=t?.day===it(n)?t:void 0;return Object.fromEntries(ks.map(s=>[s,Wt(r?.[s])??Math.min(Math.max(Wt(e[s])??0,Bt(n)),n.getTime())]))}function la(t,e,n,r,s,i){let a=e?.day===it(r)?e:void 0,o={sent:{...t},file:{day:it(r)}};for(let l of ks){let h=l in s&&!i.includes(l)&&!(`${l}Error`in s),d=Wt(a?.[l]);h?(o.file[l]=n[l],o.sent[l]=r.getTime()):d!==void 0&&(o.sent[l]=Math.min(Wt(t[l])??d,d))}return o}async function ca(t){let{home:e}=t,n=ue(e,"tangu"),r=t.now??new Date,s=i=>t.since?.[i]??Bt(r);return Mn({schema:2,collectedAt:r.toISOString(),app:{version:t.appVersion,platform:process.platform,arch:process.arch,os:Fo(),electron:process.versions.electron??null,node:process.versions.node,locale:Intl.DateTimeFormat().resolvedOptions().locale,timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,home:jo(e),cloudUrl:t.cloudUrl},device:{id:await Es(e),name:ys()},config:ra(await Fn(ue(e,"config.json"))),agents:await fs(ue(n,"agents")),teams:await fs(ue(n,"teams")),plugins:{desktop:await hs(ue(e,"plugins")),engine:await hs(ue(n,"plugins"))},inventory:{skills:await st(ue(n,"skills")),spaces:await st(ue(e,"spaces")),themes:await st(ue(e,"themes"))},...t.activity?{...await ia(ue(e,"activity"),r,s("activity")),activitySince:new Date(s("activity")).toISOString()}:{},...t.sessions?{...await oa(e,r,bs,s("sessions")),sessionsSince:new Date(s("sessions")).toISOString()}:{}})}function ua(t,e=[]){let n={...t},r=Buffer.from(JSON.stringify(n),"utf8");for(let s of["activity","sessions"]){if(r.length<=cs)break;s in n&&(delete n[s],e.push(s),r=Buffer.from(JSON.stringify({...n,truncated:e}),"utf8"))}return r.length>cs?null:r}async function da(t,e,n,r=new Date){let s=AbortSignal.timeout(zo);await t.writeFile(`${e}/${it(r)}.json`,n,r.getTime(),s);try{let i=it(new Date(r.getTime()-ws*24*60*6e4));for(let a of await t.walk(s)){let o=/^([^/]+)\/(\d{4}-\d{2}-\d{2})\.json$/.exec(a.key);o&&o[1]===e&&o[2]<i&&await t.rm(a.key,s)}}catch{}}var _s={mode:"scheduled",intervalHours:24,requestedAt:0};function On(t){let e=t&&typeof t=="object"?t:{},n=Number(e.intervalHours),r=Number(e.requestedAt);return{mode:e.mode==="manual"?"manual":"scheduled",intervalHours:Number.isInteger(n)&&n>=1&&n<=720?n:_s.intervalHours,requestedAt:Number.isFinite(r)&&r>0?r:0}}async function fa(t){try{let e=await fetch(`${t.cloudUrl.replace(/\/+$/,"")}/api/remotesync/diagnostics/policy`,{headers:{Authorization:`Bearer ${t.token}`},signal:AbortSignal.timeout(Bo)});return e.status===404?{..._s}:e.ok?On(await e.json()):null}catch{return null}}function Cs(t,e={}){let n=e.now??(()=>new Date),r=e.remoteFor??(k=>Tt({baseUrl:k.cloudUrl,vault:xt,getToken:()=>k.token})),s=e.policyFor??fa,i=()=>ue(t.homeDir(),"extend-diagnostics.json"),a=()=>{let k=A=>A&&typeof A=="object"?A:{};try{let A=JSON.parse($o(i(),"utf8"));return{accounts:k(A?.accounts),sent:k(A?.sent)}}catch{return{accounts:{},sent:{}}}},o=()=>a().accounts,l=(k,A,U)=>{let M=a();M.accounts[k]={...M.accounts[k],...A},Object.assign(M.sent,U),Do(t.homeDir(),{recursive:!0});let B=`${i()}.${process.pid}.tmp`;No(B,JSON.stringify(M,null,2),{encoding:"utf8",mode:384}),Mo(B,i())},h=()=>{let k=t.readCreds();return k.token&&k.cloudUrl?t.accountId():null},d=()=>{let k=h(),A=k?o()[k]??{}:{},U=On(A.policy);return{signedIn:!!k,enabled:A.enabled===!0,activity:A.activity!==!1,sessions:A.sessions??A.enabled!==!0,lastUploadAt:A.lastUploadAt??null,lastError:A.lastError??null,retainDays:ws,mode:U.mode,intervalHours:U.intervalHours}},f=null,u=new Map,g=async()=>{let k=h();if(!k)return!1;if(f)return f.id===k?f.done:(await f.done,g());let A={...t.readCreds()},U=n(),M=a(),B=M.accounts[k],j=A.cloudUrl.replace(/\/+$/,""),K=aa(B?.file,M.sent[j]??{},U),se=(async()=>{try{let he=await ca({home:t.homeDir(),appVersion:t.appVersion(),cloudUrl:A.cloudUrl,activity:B?.activity!==!1,sessions:B?.sessions===!0,now:U,since:K}),we=await Es(t.homeDir()),ae=o()[k];if(h()!==k||ae?.enabled!==!0)return!1;if(ae.activity===!1)for(let C of["activity","activityTruncated","activityError","activitySince"])delete he[C];if(ae.sessions!==!0)for(let C of["sessions","sessionsTruncated","sessionsError","sessionsSince"])delete he[C];let Ee=[],De=ua(he,Ee);if(!De)throw new Error("snapshot too large");await da(r(A),we,De,U),u.delete(k);let _=la(a().sent[j]??{},B?.file,K,U,he,Ee);return l(k,{lastUploadAt:n().getTime(),lastError:void 0,file:_.file},{[j]:_.sent}),t.log(`[forsion-extend] diagnostics uploaded (${De.length} bytes)`),!0}catch(he){u.set(k,n().getTime());let we=String(he?.message||he).slice(0,300);try{l(k,{lastError:we})}catch{}return t.log(`[forsion-extend] diagnostics upload failed: ${we}`),!1}finally{f=null}})();return f={id:k,done:se},se},S=async()=>{try{let k=h();if(!k||o()[k]?.enabled!==!0)return;let A=await s({...t.readCreds()}),U=h()===k?o()[k]:void 0;if(U?.enabled!==!0)return;A&&(A.mode!==U.policy?.mode||A.intervalHours!==U.policy?.intervalHours)&&l(k,{policy:{mode:A.mode,intervalHours:A.intervalHours}}),A&&U.requestSeen===void 0&&l(k,{requestSeen:A.requestedAt});let M=A??{...On(U.policy),requestedAt:0},B=M.requestedAt>(U.requestSeen??M.requestedAt),j=U.lastUploadAt??0,K=!j||M.mode==="scheduled"&&n().getTime()-j>=M.intervalHours*Un;if(!B&&!K||n().getTime()-(u.get(k)??-ls)<ls)return;await g()&&B&&l(k,{requestSeen:M.requestedAt})}catch(k){t.log(`[forsion-extend] diagnostics tick failed: ${String(k?.message||k)}`)}},x={ok:!1,error:"untrusted"};t.handle("diagnostics:get",k=>t.isTrustedSender(k)?d():x),t.handle("diagnostics:set",(k,A)=>{if(!t.isTrustedSender(k))return x;let U=h();if(!U)return d();let M={};typeof A?.enabled=="boolean"&&(M.enabled=A.enabled),M.enabled&&(M.requestSeen=void 0),typeof A?.activity=="boolean"&&(M.activity=A.activity),typeof A?.sessions=="boolean"&&(M.sessions=A.sessions);let B=o()[U];return M.sessions===void 0&&B?.sessions===void 0&&(B?.enabled===!0?M.sessions=!1:M.enabled&&(M.sessions=!0)),l(U,M),M.enabled&&(u.delete(U),S()),d()}),t.handle("diagnostics:uploadNow",async k=>t.isTrustedSender(k)?(d().enabled&&await g(),d()):x);let w=setTimeout(()=>void S(),Ho),F=setInterval(()=>void S(),qo);return w.unref?.(),F.unref?.(),t.log("[forsion-extend] diagnostics registered"),Object.assign(()=>{clearTimeout(w),clearInterval(F)},{tick:S})}async function Ts(t,e){if(!e)return"";try{let n=await ge({base:t,token:e},"POST","/api/auth/handoff",{},5e3);if(n.status===200&&typeof n.json?.code=="string"&&n.json.code)return`code=${encodeURIComponent(n.json.code)}`;if(n.status===404||n.status===405)return`token=${encodeURIComponent(e)}`}catch{}return""}var ha=["membership","credits"];function mc(t){let e={status:0,error:"untrusted"},n={ok:!1,error:"untrusted"};t.handle("auth:openAccountCenter",async(s,i)=>{if(!t.isTrustedSender(s))return n;let{base:a,token:o}=await t.getCloud();if(!a)return{ok:!1};let l=i&&/^[a-z0-9-]+$/i.test(i)?`#${i}`:"",h=await Ts(a,o),d=`${a}/account${h?`?${h}`:""}${l}`;return await t.openExternal(d),{ok:!0}}),t.handle("auth:openPayCenter",async(s,i)=>{if(!t.isTrustedSender(s))return n;if(i!==void 0&&!ha.includes(i))return{ok:!1,error:"invalid_tab"};let{base:a,token:o}=await t.getCloud();if(!a)return{ok:!1};let l=await Ts(a,o),h=`${a}/pay?tab=${i??"membership"}${l?`&${l}`:""}&redirect=${encodeURIComponent(`${a}/account`)}`;return await t.openExternal(h),{ok:!0}});let r=()=>t.getCloud();t.handle("account:quota",async s=>{if(!t.isTrustedSender(s))return e;let i=await r();if(!i.token)return{status:401,json:null};try{return await ge(i,"GET","/api/token-quota/my",void 0,15e3)}catch(a){return{status:0,json:{detail:String(a?.message||a)}}}}),t.handle("account:useResetCard",async(s,i)=>{if(!t.isTrustedSender(s))return e;let a=await r();if(!a.token)return{status:401,json:null};if(i!==void 0&&i!=="both")return{status:400,json:{error:"invalid_type",detail:`invalid reset card type: ${i}`}};let o=i??"both";try{return await ge(a,"POST","/api/token-quota/reset-card/use",{type:o},15e3)}catch(l){return{status:0,json:{detail:String(l?.message||l)}}}}),t.handle("account:bgConvert",async(s,i)=>{if(!t.isTrustedSender(s))return e;let a=await r();if(!a.token)return{status:401,json:null};if(!Number.isInteger(i)||i<1||i>100)return{status:400,json:{error:"invalid_percent"}};try{return await ge(a,"POST","/api/token-quota/background/convert",{percent:i},15e3)}catch(o){return{status:0,json:{detail:String(o?.message||o)}}}}),t.handle("account:bgAutoMain",async(s,i)=>{if(!t.isTrustedSender(s))return e;let a=await r();if(!a.token)return{status:401,json:null};if(typeof i!="boolean")return{status:400,json:{error:"invalid_request"}};try{return await ge(a,"POST","/api/token-quota/background/auto-main",{enabled:i},15e3)}catch(o){return{status:0,json:{detail:String(o?.message||o)}}}}),t.handle("feedback:submit",async(s,i)=>{if(!t.isTrustedSender(s))return n;let{base:a,token:o}=await t.getCloud();if(!a||!o)return{ok:!1,error:"not-logged-in"};let l=(i?.description||"").trim();if(!l)return{ok:!1,error:"empty"};if(l.length>1e4)return{ok:!1,error:"description-too-long"};let h=[],d=!1;if(i?.sessionLogJson){let f=Buffer.from(i.sessionLogJson,"utf8");if(f.length>5*1024*1024)return{ok:!1,error:"attachment-too-large"};h.push({filename:i.sessionLogName||"tangu-session.json",mime_type:"application/json",size:f.length,data_base64:f.toString("base64")})}try{let f=await fetch(`${a}/api/feedback`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o}`},body:JSON.stringify({description:l,attachments:h}),signal:AbortSignal.timeout(2e4)});if(!f.ok){let g=`HTTP ${f.status}`;try{g=(await f.json())?.detail||g}catch{}return{ok:!1,error:g}}return{ok:!0,id:(await f.json().catch(()=>({})))?.id??null,attachmentSkipped:d}}catch(f){return{ok:!1,error:f?.message||String(f)}}}),t.handle("cloud:fetch",async(s,i)=>{if(!t.isTrustedSender(s))return{status:0,error:"untrusted"};let a=i??{},o=typeof a.path=="string"?a.path:"",l=Math.min(12e4,Math.max(1e3,Number(a.timeoutMs)||15e3)),h=typeof a.method=="string"?a.method.toUpperCase():"GET";if(!/^(GET|POST|PUT|PATCH|DELETE)$/.test(h))return{status:0,error:"bad_method"};if(!o.startsWith("/"))return{status:0,error:"bad_path"};let{base:d,token:f}=await t.getCloud();if(!String(d||""))return{status:0,error:"no_cloud_url"};let u=Jn(d,o);if(!u)return{status:0,error:"bad_path"};if(!f)return{status:401,error:"not_signed_in"};let g=a.body!==void 0&&h!=="GET"&&h!=="DELETE",S=new AbortController,x=setTimeout(()=>S.abort(),l);try{let w=await fetch(u,{method:h,headers:{Authorization:`Bearer ${f}`,...g?{"Content-Type":"application/json"}:{}},body:g?JSON.stringify(a.body):void 0,signal:S.signal});return{status:w.status,json:await w.json().catch(()=>null)}}catch(w){return{status:0,error:String(w?.message||w)}}finally{clearTimeout(x)}}),t.log("[forsion-extend] cloud account handlers registered"),Qt(t)?en(t):t.log("[forsion-extend] host has no Connect seam (projectsRoot / transpileForServe / mimeOf / setPreviewHooks); Connect stays with the host"),nn(t)?rn(t):t.log("[forsion-extend] host has no remote-sync seam (registerRemoteSyncBackend / readCreds); penzor stays with the host"),on(t)?an(t):t.log("[forsion-extend] host has no account seam (accountCommit / accountClear / \u2026); account core stays with the host"),In(t)?Rn(t):t.log("[forsion-extend] host has no amadeus seam (setAmadeusSyncFactory); cloud sync stays with the host"),Dn(t)?$n(t):t.log("[forsion-extend] host has no unit seam (setUnitHubFactory); the device channel stays with the host"),Ss(t)?Cs(t):t.log("[forsion-extend] host has no diagnostics seam (homeDir / readCreds / accountId / appVersion); diagnostics upload is off")}export{hr as ACCOUNT_SEAM,ns as AMADEUS_SEAM,Xt as CONNECT_MAX_FILES,Xn as CONNECT_MAX_FILE_BYTES,Zn as CONNECT_MAX_TOTAL_BYTES,xt as DIAGNOSTICS_VAULT,sr as FORSION_CONNECT_LOCAL_SDK,ha as PAY_TABS,ar as PENZOR_MAX_FILE,ce as SYNC_IPC,is as UNIT_SEAM,yt as UnitCapsReporter,pt as UnitHost,ge as cloudJson,Qn as collectProjectFiles,Ft as conflictCopyPath,Zi as conflictCopyVariant,fr as createAccountCloud,rs as createAmadeusCloud,Tt as createPenzorRemote,os as createUnitHub,tn as expectedPartsOf,Te as forsionAccountId,dr as forsionRefreshToken,lt as forsionWhoami,on as hasAccountHost,In as hasAmadeusHost,Qt as hasConnectHost,nn as hasRemoteSyncHost,Dn as hasUnitHost,rr as makePreviewProxy,tr as readConnectMeta,an as registerAccount,Rn as registerAmadeus,mc as registerCloud,en as registerConnect,rn as registerPenzor,$n as registerUnit,ur as shouldRefreshToken,ss as streamWorthy,Qr as stripConflictSuffix,Qi as textFingerprint,cr as tokenAgeMs,ei as tokenRemainingMs,nr as writeConnectMeta};
204
211
  /*! Bundled license information:
205
212
 
206
213
  chokidar/index.js: