@preventive/triage 1.0.0-alpha.5 → 1.0.0-alpha.7

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/api/reap.ts ADDED
@@ -0,0 +1,79 @@
1
+ // Vercel Cron entry point for the objstore orphan reaper.
2
+ //
3
+ // The relay's in-process reaper (server/objstore/init.ts) is a boot sweep plus
4
+ // a periodic setInterval — both need a long-lived process. For a serverless
5
+ // deployment (no persistent event loop to host the periodic sweep), or any
6
+ // deployment that sets OBJSTORE_REAP_DISABLED to take GC out-of-band, this
7
+ // endpoint runs ONE reapOrphans sweep per invocation. Vercel Cron hits it on a
8
+ // schedule (see vercel.json). reapOrphans is stateless, lock-free, and safe to
9
+ // run concurrently with live traffic and across replicas, so a one-shot
10
+ // function is a clean GC driver.
11
+ //
12
+ // Neon (DATABASE_URL) + Vercel Blob (BLOB_READ_WRITE_TOKEN) only — the local-FS
13
+ // / SQLite backend is single-process and reaps in-process. Opens its own
14
+ // objstore handle (the Neon HTTP callable is stateless — nothing to close, see
15
+ // server/objstore/store.ts) rather than booting the WS/SSE relay.
16
+
17
+ import type { IncomingMessage, ServerResponse } from 'node:http'
18
+ import { env } from 'node:process'
19
+ import { createHmac, randomBytes, timingSafeEqual } from 'node:crypto'
20
+ import { reapOrphans } from '../server/objstore/reaper.ts'
21
+ import { openNeonObjstore } from '../server/objstore/store-neon.ts'
22
+ import { openVercelBlobBackend } from '../server/objstore/blob-vercel.ts'
23
+
24
+ // Config read once at module load. Vercel sets env at cold start and it's
25
+ // fixed for the function instance's lifetime, so there's nothing to re-read
26
+ // per request. CRON_SECRET gates the endpoint; DATABASE_URL +
27
+ // BLOB_READ_WRITE_TOKEN select the Neon + Vercel Blob backend.
28
+ const { CRON_SECRET, DATABASE_URL, BLOB_READ_WRITE_TOKEN } = env
29
+
30
+ // Constant-time bearer check, mirroring server/auth.ts's password gate: HMAC
31
+ // both the expected `Bearer ${CRON_SECRET}` and the received Authorization
32
+ // header under a per-process random key, then timingSafeEqual the fixed-length
33
+ // digests. Hashing to a fixed length sidesteps timingSafeEqual's
34
+ // throw-on-length-mismatch AND avoids leaking the secret's length through the
35
+ // comparison. Null when CRON_SECRET is unset → the endpoint fails closed.
36
+ const BEARER_HMAC_KEY = new Uint8Array(randomBytes(32))
37
+ const bearerHmac = (s: string): Uint8Array =>
38
+ new Uint8Array(createHmac('sha256', BEARER_HMAC_KEY).update(s, 'utf8').digest())
39
+ const EXPECTED_BEARER_HMAC = CRON_SECRET ? bearerHmac(`Bearer ${CRON_SECRET}`) : null
40
+
41
+ function authorized(req: IncomingMessage): boolean {
42
+ if (EXPECTED_BEARER_HMAC == null) return false // CRON_SECRET unset → fail closed
43
+ const header = req.headers['authorization']
44
+ if (typeof header !== 'string') return false
45
+ return timingSafeEqual(bearerHmac(header), EXPECTED_BEARER_HMAC)
46
+ }
47
+
48
+ function send(res: ServerResponse, status: number, body: object): void {
49
+ res.writeHead(status, { 'content-type': 'application/json' })
50
+ res.end(JSON.stringify(body))
51
+ }
52
+
53
+ export default async function handler(req: IncomingMessage, res: ServerResponse): Promise<void> {
54
+ // Require the Vercel-Cron bearer — Vercel sends `Authorization: Bearer
55
+ // ${CRON_SECRET}` on cron invocations. Constant-time + fail-closed via
56
+ // `authorized` above, so this DB- and blob-touching GC endpoint can't be
57
+ // probed by arbitrary callers (reapOrphans is idempotent/safe, but the
58
+ // endpoint still shouldn't be open). A 401 in the cron logs is the signal
59
+ // that CRON_SECRET wasn't set on the deployment.
60
+ if (!authorized(req)) {
61
+ send(res, 401, { error: 'unauthorized' })
62
+ return
63
+ }
64
+ if (!DATABASE_URL || !BLOB_READ_WRITE_TOKEN) {
65
+ send(res, 500, { error: 'not-configured', detail: 'requires DATABASE_URL + BLOB_READ_WRITE_TOKEN (Neon + Vercel Blob)' })
66
+ return
67
+ }
68
+ const startedAt = Date.now()
69
+ try {
70
+ const blob = await openVercelBlobBackend({ token: BLOB_READ_WRITE_TOKEN })
71
+ const handle = await openNeonObjstore(DATABASE_URL, blob)
72
+ // Handle is stateless (HTTP `neon()` callable) — nothing to close.
73
+ await reapOrphans(handle)
74
+ send(res, 200, { ok: true, ms: Date.now() - startedAt })
75
+ } catch (err) {
76
+ console.error('cron reap failed:', err instanceof Error ? (err.stack ?? err.message) : String(err))
77
+ send(res, 500, { error: 'reap-failed' })
78
+ }
79
+ }
@@ -1,20 +1,20 @@
1
- function Gr(e){return e instanceof Uint8Array||ArrayBuffer.isView(e)&&e.constructor.name==="Uint8Array"&&"BYTES_PER_ELEMENT"in e&&e.BYTES_PER_ELEMENT===1}function tt(e){if(typeof e!="boolean")throw new TypeError(`boolean expected, not ${e}`)}function Be(e){if(typeof e!="number")throw new TypeError("number expected, got "+typeof e);if(!Number.isSafeInteger(e)||e<0)throw new RangeError("positive integer expected, got "+e)}function ee(e,t,n=""){let r=Gr(e),o=e?.length,s=t!==void 0;if(!r||s&&o!==t){let i=n&&`"${n}" `,a=s?` of length ${t}`:"",f=r?`length=${o}`:`type=${typeof e}`,c=i+"expected Uint8Array"+a+", got "+f;throw r?new RangeError(c):new TypeError(c)}return e}function At(e,t=!0){if(e.destroyed)throw new Error("Hash instance has been destroyed");if(t&&e.finished)throw new Error("Hash#digest() has already been called")}function Tn(e,t,n=!1){ee(e,void 0,"output");let r=t.outputLen;if(e.length<r)throw new RangeError("digestInto() expects output buffer of length at least "+r);if(n&&!Re(e))throw new Error("invalid output, must be aligned")}function pe(e){return new Uint32Array(e.buffer,e.byteOffset,Math.floor(e.byteLength/4))}function ue(...e){for(let t=0;t<e.length;t++)e[t].fill(0)}function Jr(e){return new DataView(e.buffer,e.byteOffset,e.byteLength)}var Se=new Uint8Array(new Uint32Array([287454020]).buffer)[0]===68,Yr=e=>e<<24&4278190080|e<<8&16711680|e>>>8&65280|e>>>24&255;var Xr=e=>{for(let t=0;t<e.length;t++)e[t]=Yr(e[t]);return e},be=Se?e=>e:Xr;function xn(e,t){if(t==null||typeof t!="object")throw new Error("options must be defined");return Object.assign(e,t)}function En(e,t){if(e.length!==t.length)return!1;let n=0;for(let r=0;r<e.length;r++)n|=e[r]^t[r];return n===0}function An(e,t,n){let r=t,o=n||(()=>[]),s=(a,f)=>r(f,...o(a)).update(a).digest(),i=r(new Uint8Array(e),...o(new Uint8Array(0)));return s.outputLen=i.outputLen,s.blockLen=i.blockLen,s.create=(a,...f)=>r(a,...f),s}var Pn=(e,t)=>{function n(r,...o){if(ee(r,void 0,"key"),e.nonceLength!==void 0){let p=o[0];ee(p,e.varSizeNonce?void 0:e.nonceLength,"nonce")}let s=e.tagLength;s&&o[1]!==void 0&&ee(o[1],void 0,"AAD");let i=t(r,...o),a=(p,w)=>{if(w!==void 0){if(p!==2)throw new Error("cipher output not supported");ee(w,void 0,"output")}},f=!1;return{encrypt(p,w){if(f)throw new Error("cannot encrypt() twice with same key + nonce");return f=!0,ee(p),a(i.encrypt.length,w),i.encrypt(p,w)},decrypt(p,w){if(ee(p),s&&p.length<s)throw new Error('"ciphertext" expected length bigger than tagLength='+s);return a(i.decrypt.length,w),i.decrypt(p,w)}}}return Object.assign(n,e),n};function De(e,t,n=!0){if(t===void 0)return new Uint8Array(e);if(ee(t,void 0,"output"),t.length!==e)throw new Error('"output" expected Uint8Array of length '+e+", got: "+t.length);if(n&&!Re(t))throw new Error("invalid output, must be aligned");return t}function Bn(e,t,n){Be(e),Be(t),tt(n);let r=new Uint8Array(16),o=Jr(r);return o.setBigUint64(0,BigInt(t),n),o.setBigUint64(8,BigInt(e),n),r}function Re(e){return e.byteOffset%4===0}function je(e){return Uint8Array.from(ee(e))}var jn=e=>Uint8Array.from(e.split(""),t=>t.charCodeAt(0)),Qr=be(pe(jn("expand 16-byte k"))),Zr=be(pe(jn("expand 32-byte k")));function C(e,t){return e<<t|e>>>32-t}var $e=64,eo=16,Pt=2**32-1,Rn=Uint32Array.of();function to(e,t,n,r,o,s,i,a){let f=o.length,c=new Uint8Array($e),p=pe(c),w=Se&&Re(o)&&Re(s),x=w?pe(o):Rn,A=w?pe(s):Rn;if(!Se){for(let y=0;y<f;i++){if(e(t,n,r,p,i,a),be(p),i>=Pt)throw new Error("arx: counter overflow");let T=Math.min($e,f-y);for(let E=0,j;E<T;E++)j=y+E,s[j]=o[j]^c[E];y+=T}return}for(let y=0;y<f;i++){if(e(t,n,r,p,i,a),i>=Pt)throw new Error("arx: counter overflow");let T=Math.min($e,f-y);if(w&&T===$e){let E=y/4;if(y%4!==0)throw new Error("arx: invalid block position");for(let j=0,V;j<eo;j++)V=E+j,A[V]=x[V]^p[j];y+=$e;continue}for(let E=0,j;E<T;E++)j=y+E,s[j]=o[j]^c[E];y+=T}}function On(e,t){let{allowShortKeys:n,extendNonceFn:r,counterLength:o,counterRight:s,rounds:i}=xn({allowShortKeys:!1,counterLength:8,counterRight:!1,rounds:20},t);if(typeof e!="function")throw new Error("core must be a function");return Be(o),Be(i),tt(s),tt(n),(a,f,c,p,w=0)=>{ee(a,void 0,"key"),ee(f,void 0,"nonce"),ee(c,void 0,"data");let x=c.length;if(p=De(x,p,!1),Be(w),w<0||w>=Pt)throw new Error("arx: counter overflow");let A=[],y=a.length,T,E;if(y===32)A.push(T=je(a)),E=Zr;else if(y===16&&n)T=new Uint8Array(32),T.set(a),T.set(a,16),E=Qr,A.push(T);else throw ee(a,32,"arx key"),new Error("invalid key size");(!Se||!Re(f))&&A.push(f=je(f));let j=pe(T);if(r){if(f.length!==24)throw new Error("arx: extended nonce must be 24 bytes");let ne=f.subarray(0,16);if(Se)r(E,j,pe(ne),j);else{let oe=be(Uint32Array.from(E));r(oe,j,pe(ne),j),ue(oe),be(j)}f=f.subarray(16)}else Se||be(j);let V=16-o;if(V!==f.length)throw new Error(`arx: nonce must be ${V} or 16 bytes`);if(V!==12){let ne=new Uint8Array(12);ne.set(f,s?0:12-f.length),f=ne,A.push(f)}let ie=be(pe(f));try{return to(e,E,j,ie,c,p,w,i),p}finally{ue(...A)}}}function re(e,t){return e[t++]&255|(e[t++]&255)<<8}var Bt=class{blockLen=16;outputLen=16;buffer=new Uint8Array(16);r=new Uint16Array(10);h=new Uint16Array(10);pad=new Uint16Array(8);pos=0;finished=!1;destroyed=!1;constructor(t){t=je(ee(t,32,"key"));let n=re(t,0),r=re(t,2),o=re(t,4),s=re(t,6),i=re(t,8),a=re(t,10),f=re(t,12),c=re(t,14);this.r[0]=n&8191,this.r[1]=(n>>>13|r<<3)&8191,this.r[2]=(r>>>10|o<<6)&7939,this.r[3]=(o>>>7|s<<9)&8191,this.r[4]=(s>>>4|i<<12)&255,this.r[5]=i>>>1&8190,this.r[6]=(i>>>14|a<<2)&8191,this.r[7]=(a>>>11|f<<5)&8065,this.r[8]=(f>>>8|c<<8)&8191,this.r[9]=c>>>5&127;for(let p=0;p<8;p++)this.pad[p]=re(t,16+2*p)}process(t,n,r=!1){let o=r?0:2048,{h:s,r:i}=this,a=i[0],f=i[1],c=i[2],p=i[3],w=i[4],x=i[5],A=i[6],y=i[7],T=i[8],E=i[9],j=re(t,n+0),V=re(t,n+2),ie=re(t,n+4),ne=re(t,n+6),oe=re(t,n+8),Z=re(t,n+10),Y=re(t,n+12),Q=re(t,n+14),U=s[0]+(j&8191),K=s[1]+((j>>>13|V<<3)&8191),L=s[2]+((V>>>10|ie<<6)&8191),$=s[3]+((ie>>>7|ne<<9)&8191),M=s[4]+((ne>>>4|oe<<12)&8191),N=s[5]+(oe>>>1&8191),I=s[6]+((oe>>>14|Z<<2)&8191),F=s[7]+((Z>>>11|Y<<5)&8191),H=s[8]+((Y>>>8|Q<<8)&8191),D=s[9]+(Q>>>5|o),k=0,z=k+U*a+K*(5*E)+L*(5*T)+$*(5*y)+M*(5*A);k=z>>>13,z&=8191,z+=N*(5*x)+I*(5*w)+F*(5*p)+H*(5*c)+D*(5*f),k+=z>>>13,z&=8191;let G=k+U*f+K*a+L*(5*E)+$*(5*T)+M*(5*y);k=G>>>13,G&=8191,G+=N*(5*A)+I*(5*x)+F*(5*w)+H*(5*p)+D*(5*c),k+=G>>>13,G&=8191;let b=k+U*c+K*f+L*a+$*(5*E)+M*(5*T);k=b>>>13,b&=8191,b+=N*(5*y)+I*(5*A)+F*(5*x)+H*(5*w)+D*(5*p),k+=b>>>13,b&=8191;let v=k+U*p+K*c+L*f+$*a+M*(5*E);k=v>>>13,v&=8191,v+=N*(5*T)+I*(5*y)+F*(5*A)+H*(5*x)+D*(5*w),k+=v>>>13,v&=8191;let _=k+U*w+K*p+L*c+$*f+M*a;k=_>>>13,_&=8191,_+=N*(5*E)+I*(5*T)+F*(5*y)+H*(5*A)+D*(5*x),k+=_>>>13,_&=8191;let l=k+U*x+K*w+L*p+$*c+M*f;k=l>>>13,l&=8191,l+=N*a+I*(5*E)+F*(5*T)+H*(5*y)+D*(5*A),k+=l>>>13,l&=8191;let g=k+U*A+K*x+L*w+$*p+M*c;k=g>>>13,g&=8191,g+=N*f+I*a+F*(5*E)+H*(5*T)+D*(5*y),k+=g>>>13,g&=8191;let d=k+U*y+K*A+L*x+$*w+M*p;k=d>>>13,d&=8191,d+=N*c+I*f+F*a+H*(5*E)+D*(5*T),k+=d>>>13,d&=8191;let m=k+U*T+K*y+L*A+$*x+M*w;k=m>>>13,m&=8191,m+=N*p+I*c+F*f+H*a+D*(5*E),k+=m>>>13,m&=8191;let u=k+U*E+K*T+L*y+$*A+M*x;k=u>>>13,u&=8191,u+=N*w+I*p+F*c+H*f+D*a,k+=u>>>13,u&=8191,k=(k<<2)+k|0,k=k+z|0,z=k&8191,k=k>>>13,G+=k,s[0]=z,s[1]=G,s[2]=b,s[3]=v,s[4]=_,s[5]=l,s[6]=g,s[7]=d,s[8]=m,s[9]=u}finalize(){let{h:t,pad:n}=this,r=new Uint16Array(10),o=t[1]>>>13;t[1]&=8191;for(let a=2;a<10;a++)t[a]+=o,o=t[a]>>>13,t[a]&=8191;t[0]+=o*5,o=t[0]>>>13,t[0]&=8191,t[1]+=o,o=t[1]>>>13,t[1]&=8191,t[2]+=o,r[0]=t[0]+5,o=r[0]>>>13,r[0]&=8191;for(let a=1;a<10;a++)r[a]=t[a]+o,o=r[a]>>>13,r[a]&=8191;r[9]-=8192;let s=(o^1)-1;for(let a=0;a<10;a++)r[a]&=s;s=~s;for(let a=0;a<10;a++)t[a]=t[a]&s|r[a];t[0]=(t[0]|t[1]<<13)&65535,t[1]=(t[1]>>>3|t[2]<<10)&65535,t[2]=(t[2]>>>6|t[3]<<7)&65535,t[3]=(t[3]>>>9|t[4]<<4)&65535,t[4]=(t[4]>>>12|t[5]<<1|t[6]<<14)&65535,t[5]=(t[6]>>>2|t[7]<<11)&65535,t[6]=(t[7]>>>5|t[8]<<8)&65535,t[7]=(t[8]>>>8|t[9]<<5)&65535;let i=t[0]+n[0];t[0]=i&65535;for(let a=1;a<8;a++)i=(t[a]+n[a]|0)+(i>>>16)|0,t[a]=i&65535;ue(r)}update(t){At(this),ee(t),t=je(t);let{buffer:n,blockLen:r}=this,o=t.length;for(let s=0;s<o;){let i=Math.min(r-this.pos,o-s);if(i===r){for(;r<=o-s;s+=r)this.process(t,s);continue}n.set(t.subarray(s,s+i),this.pos),this.pos+=i,s+=i,this.pos===r&&(this.process(n,0,!1),this.pos=0)}return this}destroy(){this.destroyed=!0,ue(this.h,this.r,this.buffer,this.pad)}digestInto(t){At(this),Tn(t,this),this.finished=!0;let{buffer:n,h:r}=this,{pos:o}=this;if(o){for(n[o++]=1;o<16;o++)n[o]=0;this.process(n,0,!0)}this.finalize();let s=0;for(let i=0;i<8;i++)t[s++]=r[i]>>>0,t[s++]=r[i]>>>8}digest(){let{buffer:t,outputLen:n}=this;this.digestInto(t);let r=t.slice(0,n);return this.destroy(),r}},Cn=An(32,e=>new Bt(e));function no(e,t,n,r,o,s=20){let i=e[0],a=e[1],f=e[2],c=e[3],p=t[0],w=t[1],x=t[2],A=t[3],y=t[4],T=t[5],E=t[6],j=t[7],V=o,ie=n[0],ne=n[1],oe=n[2],Z=i,Y=a,Q=f,U=c,K=p,L=w,$=x,M=A,N=y,I=T,F=E,H=j,D=V,k=ie,z=ne,G=oe;for(let v=0;v<s;v+=2)Z=Z+K|0,D=C(D^Z,16),N=N+D|0,K=C(K^N,12),Z=Z+K|0,D=C(D^Z,8),N=N+D|0,K=C(K^N,7),Y=Y+L|0,k=C(k^Y,16),I=I+k|0,L=C(L^I,12),Y=Y+L|0,k=C(k^Y,8),I=I+k|0,L=C(L^I,7),Q=Q+$|0,z=C(z^Q,16),F=F+z|0,$=C($^F,12),Q=Q+$|0,z=C(z^Q,8),F=F+z|0,$=C($^F,7),U=U+M|0,G=C(G^U,16),H=H+G|0,M=C(M^H,12),U=U+M|0,G=C(G^U,8),H=H+G|0,M=C(M^H,7),Z=Z+L|0,G=C(G^Z,16),F=F+G|0,L=C(L^F,12),Z=Z+L|0,G=C(G^Z,8),F=F+G|0,L=C(L^F,7),Y=Y+$|0,D=C(D^Y,16),H=H+D|0,$=C($^H,12),Y=Y+$|0,D=C(D^Y,8),H=H+D|0,$=C($^H,7),Q=Q+M|0,k=C(k^Q,16),N=N+k|0,M=C(M^N,12),Q=Q+M|0,k=C(k^Q,8),N=N+k|0,M=C(M^N,7),U=U+K|0,z=C(z^U,16),I=I+z|0,K=C(K^I,12),U=U+K|0,z=C(z^U,8),I=I+z|0,K=C(K^I,7);let b=0;r[b++]=i+Z|0,r[b++]=a+Y|0,r[b++]=f+Q|0,r[b++]=c+U|0,r[b++]=p+K|0,r[b++]=w+L|0,r[b++]=x+$|0,r[b++]=A+M|0,r[b++]=y+N|0,r[b++]=T+I|0,r[b++]=E+F|0,r[b++]=j+H|0,r[b++]=V+D|0,r[b++]=ie+k|0,r[b++]=ne+z|0,r[b++]=oe+G|0}var ro=On(no,{counterRight:!1,counterLength:4,allowShortKeys:!1});var oo=new Uint8Array(16),Un=(e,t)=>{e.update(t);let n=t.length%16;n&&e.update(oo.subarray(n))},so=new Uint8Array(32);function Ln(e,t,n,r,o){o!==void 0&&ee(o,void 0,"AAD");let s=e(t,n,so),i=Bn(r.length,o?o.length:0,!0),a=Cn.create(s);o&&Un(a,o),Un(a,r),a.update(i);let f=a.digest();return ue(s,i),f}var io=e=>(t,n,r)=>({encrypt(s,i){let a=s.length;i=De(a+16,i,!1),i.set(s);let f=i.subarray(0,-16);e(t,n,f,f,1);let c=Ln(e,t,n,f,r);return i.set(c,a),ue(c),i},decrypt(s,i){i=De(s.length-16,i,!1);let a=s.subarray(0,-16),f=s.subarray(-16),c=Ln(e,t,n,a,r);if(!En(f,c))throw ue(c),new Error("invalid tag");return i.set(s.subarray(0,-16)),e(t,n,i,i,1),ue(c),i}}),Oe=Pn({blockSize:64,nonceLength:12,tagLength:16},io(ro));var ao=new TextEncoder,co=new TextDecoder("utf-8",{fatal:!0,ignoreBOM:!0});function X(e){if(typeof e!="string")throw new TypeError(`encodeUtf8 expects a string, got ${typeof e}`);if(!e.isWellFormed())throw new TypeError("encodeUtf8: input contains lone surrogates");return ao.encode(e)}function Ce(e){if(!ArrayBuffer.isView(e)&&!(e instanceof ArrayBuffer))throw new TypeError(`decodeUtf8 expects a BufferSource, got ${e===null?"null":typeof e}`);return co.decode(e)}async function Nn(e){let t=new Blob([e]).stream().pipeThrough(new CompressionStream("gzip"));return new Uint8Array(await new Response(t).arrayBuffer())}async function Kn(e){let t=new Blob([e]).stream().pipeThrough(new DecompressionStream("gzip"));return new Uint8Array(await new Response(t).arrayBuffer())}var lo="deepview-triage-sync.v1.content-key",uo="deepview-triage-sync.v1.sign-key",fo="deepview-triage-sync.v1.save",go="deepview-triage-sync.v1.subscribe",po=12,Rt=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]),nt=null;function Mn(){return nt||(nt=(async()=>{try{return await crypto.subtle.importKey("raw",new Uint8Array(32),{name:"ChaCha20-Poly1305"},!1,["encrypt","decrypt"]),!0}catch{return!1}})(),nt)}async function In(e,t){let n=Uint8Array.fromBase64(e);if(n.length!==32)throw new Error(`workspace private key must be 32 bytes (got ${n.length})`);let r=await crypto.subtle.importKey("raw",n,"HKDF",!1,["deriveBits"]),o=await crypto.subtle.deriveBits({name:"HKDF",hash:"SHA-256",salt:new Uint8Array,info:X(t)},r,256);return new Uint8Array(o)}async function Fn(e){return await In(e,lo)}async function rt(e,t){let n=await In(e,`${uo}|${t}`),r=new Uint8Array(Rt.length+32);r.set(Rt,0),r.set(n,Rt.length);let o=await crypto.subtle.importKey("pkcs8",r,{name:"Ed25519"},!0,["sign"]),s=await crypto.subtle.exportKey("jwk",o),i=s.x;if(delete s.d,i==null)throw new Error("Ed25519 JWK export returned no public key");let a=Uint8Array.fromBase64(i,{alphabet:"base64url"}),f=await crypto.subtle.importKey("pkcs8",r,{name:"Ed25519"},!1,["sign"]);return n.fill(0),r.fill(0),{privateKey:f,publicKey:a,publicKeyB64:i}}function jt({publicKeyB64:e,base:t,keyframe:n,nonceB64:r,ciphertextB64:o}){return X([fo,e,t==null?"":String(t),n===!0?"1":"",r,o].join(`
2
- `))}async function Dn(e,t){let n=await crypto.subtle.sign({name:"Ed25519"},e,t);return new Uint8Array(n).toBase64({alphabet:"base64url",omitPadding:!0})}async function $n(e,t){return await Dn(e,jt(t))}async function Ot(e){let t=jt(e),n=await crypto.subtle.digest("SHA-256",t);return new Uint8Array(n).toBase64({alphabet:"base64url",omitPadding:!0})}function yo(e,t,n){let r=t==null?"":String(t);return X([go,e,r,n].join(`
3
- `))}async function Hn(e,t,n,r){return await Dn(e,yo(t,n,r))}async function _n(e,t,n){try{let r=await crypto.subtle.importKey("raw",e,{name:"Ed25519"},!1,["verify"]),o=Uint8Array.fromBase64(n,{alphabet:"base64url"}),s=jt(t);return await crypto.subtle.verify({name:"Ed25519"},r,o,s)}catch{return!1}}function ho(){let e=new Uint8Array(po);return crypto.getRandomValues(e),e}function Ct(e,t){let n=t==null?"":String(t);return X(`${e}|${n}`)}async function mo(e,t,n){let r=ho();if(await Mn()){let s=await crypto.subtle.importKey("raw",e,{name:"ChaCha20-Poly1305"},!1,["encrypt"]),i=new Uint8Array(await crypto.subtle.encrypt({name:"ChaCha20-Poly1305",iv:r,additionalData:n},s,t));return{nonce:r,ciphertext:i}}let o=Oe(e,r,n);return{nonce:r,ciphertext:o.encrypt(t)}}async function bo(e,t,n,r){if(await Mn()){let s=await crypto.subtle.importKey("raw",e,{name:"ChaCha20-Poly1305"},!1,["decrypt"]);return new Uint8Array(await crypto.subtle.decrypt({name:"ChaCha20-Poly1305",iv:t,additionalData:r},s,n))}return Oe(e,t,r).decrypt(n)}var wo=64;function vo(e,t){return e<=t?t:2**(32-Math.clz32(e-1))}async function So(e){let t=X(JSON.stringify(e)),n=await Nn(t);if(n.length>1073741820)throw new Error("payload too large");let r=vo(4+n.length,wo),o=new Uint8Array(r);return new DataView(o.buffer,o.byteOffset,o.byteLength).setUint32(0,n.length,!1),o.set(n,4),o}async function ko(e){if(e.length<4)throw new Error("plaintext too short");let n=new DataView(e.buffer,e.byteOffset,e.byteLength).getUint32(0,!1);if(n+4>e.length)throw new Error("length prefix exceeds buffer");let r=e.subarray(4,4+n),o=await Kn(r);return JSON.parse(Ce(o))}async function Wn(e,t,n){let r=await So(t),{nonce:o,ciphertext:s}=await mo(e,r,n);return{nonce:o.toBase64(),ciphertext:s.toBase64()}}async function Vn(e,t,n,r){let o=Uint8Array.fromBase64(t),s=Uint8Array.fromBase64(n),i=await bo(e,o,s,r);return ko(i)}var To="deepview-objstore.v1.content",xo="deepview-objstore.v1.tag",Eo=`objstore-tag
1
+ function Gr(e){return e instanceof Uint8Array||ArrayBuffer.isView(e)&&e.constructor.name==="Uint8Array"&&"BYTES_PER_ELEMENT"in e&&e.BYTES_PER_ELEMENT===1}function tt(e){if(typeof e!="boolean")throw new TypeError(`boolean expected, not ${e}`)}function Be(e){if(typeof e!="number")throw new TypeError("number expected, got "+typeof e);if(!Number.isSafeInteger(e)||e<0)throw new RangeError("positive integer expected, got "+e)}function ee(e,t,n=""){let r=Gr(e),o=e?.length,s=t!==void 0;if(!r||s&&o!==t){let i=n&&`"${n}" `,a=s?` of length ${t}`:"",f=r?`length=${o}`:`type=${typeof e}`,c=i+"expected Uint8Array"+a+", got "+f;throw r?new RangeError(c):new TypeError(c)}return e}function At(e,t=!0){if(e.destroyed)throw new Error("Hash instance has been destroyed");if(t&&e.finished)throw new Error("Hash#digest() has already been called")}function Tn(e,t,n=!1){ee(e,void 0,"output");let r=t.outputLen;if(e.length<r)throw new RangeError("digestInto() expects output buffer of length at least "+r);if(n&&!Re(e))throw new Error("invalid output, must be aligned")}function pe(e){return new Uint32Array(e.buffer,e.byteOffset,Math.floor(e.byteLength/4))}function fe(...e){for(let t=0;t<e.length;t++)e[t].fill(0)}function Jr(e){return new DataView(e.buffer,e.byteOffset,e.byteLength)}var Se=new Uint8Array(new Uint32Array([287454020]).buffer)[0]===68,Yr=e=>e<<24&4278190080|e<<8&16711680|e>>>8&65280|e>>>24&255;var Xr=e=>{for(let t=0;t<e.length;t++)e[t]=Yr(e[t]);return e},we=Se?e=>e:Xr;function xn(e,t){if(t==null||typeof t!="object")throw new Error("options must be defined");return Object.assign(e,t)}function En(e,t){if(e.length!==t.length)return!1;let n=0;for(let r=0;r<e.length;r++)n|=e[r]^t[r];return n===0}function An(e,t,n){let r=t,o=n||(()=>[]),s=(a,f)=>r(f,...o(a)).update(a).digest(),i=r(new Uint8Array(e),...o(new Uint8Array(0)));return s.outputLen=i.outputLen,s.blockLen=i.blockLen,s.create=(a,...f)=>r(a,...f),s}var Pn=(e,t)=>{function n(r,...o){if(ee(r,void 0,"key"),e.nonceLength!==void 0){let p=o[0];ee(p,e.varSizeNonce?void 0:e.nonceLength,"nonce")}let s=e.tagLength;s&&o[1]!==void 0&&ee(o[1],void 0,"AAD");let i=t(r,...o),a=(p,b)=>{if(b!==void 0){if(p!==2)throw new Error("cipher output not supported");ee(b,void 0,"output")}},f=!1;return{encrypt(p,b){if(f)throw new Error("cannot encrypt() twice with same key + nonce");return f=!0,ee(p),a(i.encrypt.length,b),i.encrypt(p,b)},decrypt(p,b){if(ee(p),s&&p.length<s)throw new Error('"ciphertext" expected length bigger than tagLength='+s);return a(i.decrypt.length,b),i.decrypt(p,b)}}}return Object.assign(n,e),n};function De(e,t,n=!0){if(t===void 0)return new Uint8Array(e);if(ee(t,void 0,"output"),t.length!==e)throw new Error('"output" expected Uint8Array of length '+e+", got: "+t.length);if(n&&!Re(t))throw new Error("invalid output, must be aligned");return t}function Bn(e,t,n){Be(e),Be(t),tt(n);let r=new Uint8Array(16),o=Jr(r);return o.setBigUint64(0,BigInt(t),n),o.setBigUint64(8,BigInt(e),n),r}function Re(e){return e.byteOffset%4===0}function Oe(e){return Uint8Array.from(ee(e))}var On=e=>Uint8Array.from(e.split(""),t=>t.charCodeAt(0)),Qr=we(pe(On("expand 16-byte k"))),Zr=we(pe(On("expand 32-byte k")));function C(e,t){return e<<t|e>>>32-t}var $e=64,eo=16,Pt=2**32-1,Rn=Uint32Array.of();function to(e,t,n,r,o,s,i,a){let f=o.length,c=new Uint8Array($e),p=pe(c),b=Se&&Re(o)&&Re(s),x=b?pe(o):Rn,A=b?pe(s):Rn;if(!Se){for(let y=0;y<f;i++){if(e(t,n,r,p,i,a),we(p),i>=Pt)throw new Error("arx: counter overflow");let T=Math.min($e,f-y);for(let E=0,O;E<T;E++)O=y+E,s[O]=o[O]^c[E];y+=T}return}for(let y=0;y<f;i++){if(e(t,n,r,p,i,a),i>=Pt)throw new Error("arx: counter overflow");let T=Math.min($e,f-y);if(b&&T===$e){let E=y/4;if(y%4!==0)throw new Error("arx: invalid block position");for(let O=0,V;O<eo;O++)V=E+O,A[V]=x[V]^p[O];y+=$e;continue}for(let E=0,O;E<T;E++)O=y+E,s[O]=o[O]^c[E];y+=T}}function jn(e,t){let{allowShortKeys:n,extendNonceFn:r,counterLength:o,counterRight:s,rounds:i}=xn({allowShortKeys:!1,counterLength:8,counterRight:!1,rounds:20},t);if(typeof e!="function")throw new Error("core must be a function");return Be(o),Be(i),tt(s),tt(n),(a,f,c,p,b=0)=>{ee(a,void 0,"key"),ee(f,void 0,"nonce"),ee(c,void 0,"data");let x=c.length;if(p=De(x,p,!1),Be(b),b<0||b>=Pt)throw new Error("arx: counter overflow");let A=[],y=a.length,T,E;if(y===32)A.push(T=Oe(a)),E=Zr;else if(y===16&&n)T=new Uint8Array(32),T.set(a),T.set(a,16),E=Qr,A.push(T);else throw ee(a,32,"arx key"),new Error("invalid key size");(!Se||!Re(f))&&A.push(f=Oe(f));let O=pe(T);if(r){if(f.length!==24)throw new Error("arx: extended nonce must be 24 bytes");let ne=f.subarray(0,16);if(Se)r(E,O,pe(ne),O);else{let oe=we(Uint32Array.from(E));r(oe,O,pe(ne),O),fe(oe),we(O)}f=f.subarray(16)}else Se||we(O);let V=16-o;if(V!==f.length)throw new Error(`arx: nonce must be ${V} or 16 bytes`);if(V!==12){let ne=new Uint8Array(12);ne.set(f,s?0:12-f.length),f=ne,A.push(f)}let ie=we(pe(f));try{return to(e,E,O,ie,c,p,b,i),p}finally{fe(...A)}}}function re(e,t){return e[t++]&255|(e[t++]&255)<<8}var Bt=class{blockLen=16;outputLen=16;buffer=new Uint8Array(16);r=new Uint16Array(10);h=new Uint16Array(10);pad=new Uint16Array(8);pos=0;finished=!1;destroyed=!1;constructor(t){t=Oe(ee(t,32,"key"));let n=re(t,0),r=re(t,2),o=re(t,4),s=re(t,6),i=re(t,8),a=re(t,10),f=re(t,12),c=re(t,14);this.r[0]=n&8191,this.r[1]=(n>>>13|r<<3)&8191,this.r[2]=(r>>>10|o<<6)&7939,this.r[3]=(o>>>7|s<<9)&8191,this.r[4]=(s>>>4|i<<12)&255,this.r[5]=i>>>1&8190,this.r[6]=(i>>>14|a<<2)&8191,this.r[7]=(a>>>11|f<<5)&8065,this.r[8]=(f>>>8|c<<8)&8191,this.r[9]=c>>>5&127;for(let p=0;p<8;p++)this.pad[p]=re(t,16+2*p)}process(t,n,r=!1){let o=r?0:2048,{h:s,r:i}=this,a=i[0],f=i[1],c=i[2],p=i[3],b=i[4],x=i[5],A=i[6],y=i[7],T=i[8],E=i[9],O=re(t,n+0),V=re(t,n+2),ie=re(t,n+4),ne=re(t,n+6),oe=re(t,n+8),Z=re(t,n+10),Y=re(t,n+12),Q=re(t,n+14),U=s[0]+(O&8191),K=s[1]+((O>>>13|V<<3)&8191),L=s[2]+((V>>>10|ie<<6)&8191),$=s[3]+((ie>>>7|ne<<9)&8191),M=s[4]+((ne>>>4|oe<<12)&8191),N=s[5]+(oe>>>1&8191),I=s[6]+((oe>>>14|Z<<2)&8191),F=s[7]+((Z>>>11|Y<<5)&8191),W=s[8]+((Y>>>8|Q<<8)&8191),D=s[9]+(Q>>>5|o),k=0,z=k+U*a+K*(5*E)+L*(5*T)+$*(5*y)+M*(5*A);k=z>>>13,z&=8191,z+=N*(5*x)+I*(5*b)+F*(5*p)+W*(5*c)+D*(5*f),k+=z>>>13,z&=8191;let G=k+U*f+K*a+L*(5*E)+$*(5*T)+M*(5*y);k=G>>>13,G&=8191,G+=N*(5*A)+I*(5*x)+F*(5*b)+W*(5*p)+D*(5*c),k+=G>>>13,G&=8191;let w=k+U*c+K*f+L*a+$*(5*E)+M*(5*T);k=w>>>13,w&=8191,w+=N*(5*y)+I*(5*A)+F*(5*x)+W*(5*b)+D*(5*p),k+=w>>>13,w&=8191;let v=k+U*p+K*c+L*f+$*a+M*(5*E);k=v>>>13,v&=8191,v+=N*(5*T)+I*(5*y)+F*(5*A)+W*(5*x)+D*(5*b),k+=v>>>13,v&=8191;let H=k+U*b+K*p+L*c+$*f+M*a;k=H>>>13,H&=8191,H+=N*(5*E)+I*(5*T)+F*(5*y)+W*(5*A)+D*(5*x),k+=H>>>13,H&=8191;let l=k+U*x+K*b+L*p+$*c+M*f;k=l>>>13,l&=8191,l+=N*a+I*(5*E)+F*(5*T)+W*(5*y)+D*(5*A),k+=l>>>13,l&=8191;let g=k+U*A+K*x+L*b+$*p+M*c;k=g>>>13,g&=8191,g+=N*f+I*a+F*(5*E)+W*(5*T)+D*(5*y),k+=g>>>13,g&=8191;let d=k+U*y+K*A+L*x+$*b+M*p;k=d>>>13,d&=8191,d+=N*c+I*f+F*a+W*(5*E)+D*(5*T),k+=d>>>13,d&=8191;let m=k+U*T+K*y+L*A+$*x+M*b;k=m>>>13,m&=8191,m+=N*p+I*c+F*f+W*a+D*(5*E),k+=m>>>13,m&=8191;let u=k+U*E+K*T+L*y+$*A+M*x;k=u>>>13,u&=8191,u+=N*b+I*p+F*c+W*f+D*a,k+=u>>>13,u&=8191,k=(k<<2)+k|0,k=k+z|0,z=k&8191,k=k>>>13,G+=k,s[0]=z,s[1]=G,s[2]=w,s[3]=v,s[4]=H,s[5]=l,s[6]=g,s[7]=d,s[8]=m,s[9]=u}finalize(){let{h:t,pad:n}=this,r=new Uint16Array(10),o=t[1]>>>13;t[1]&=8191;for(let a=2;a<10;a++)t[a]+=o,o=t[a]>>>13,t[a]&=8191;t[0]+=o*5,o=t[0]>>>13,t[0]&=8191,t[1]+=o,o=t[1]>>>13,t[1]&=8191,t[2]+=o,r[0]=t[0]+5,o=r[0]>>>13,r[0]&=8191;for(let a=1;a<10;a++)r[a]=t[a]+o,o=r[a]>>>13,r[a]&=8191;r[9]-=8192;let s=(o^1)-1;for(let a=0;a<10;a++)r[a]&=s;s=~s;for(let a=0;a<10;a++)t[a]=t[a]&s|r[a];t[0]=(t[0]|t[1]<<13)&65535,t[1]=(t[1]>>>3|t[2]<<10)&65535,t[2]=(t[2]>>>6|t[3]<<7)&65535,t[3]=(t[3]>>>9|t[4]<<4)&65535,t[4]=(t[4]>>>12|t[5]<<1|t[6]<<14)&65535,t[5]=(t[6]>>>2|t[7]<<11)&65535,t[6]=(t[7]>>>5|t[8]<<8)&65535,t[7]=(t[8]>>>8|t[9]<<5)&65535;let i=t[0]+n[0];t[0]=i&65535;for(let a=1;a<8;a++)i=(t[a]+n[a]|0)+(i>>>16)|0,t[a]=i&65535;fe(r)}update(t){At(this),ee(t),t=Oe(t);let{buffer:n,blockLen:r}=this,o=t.length;for(let s=0;s<o;){let i=Math.min(r-this.pos,o-s);if(i===r){for(;r<=o-s;s+=r)this.process(t,s);continue}n.set(t.subarray(s,s+i),this.pos),this.pos+=i,s+=i,this.pos===r&&(this.process(n,0,!1),this.pos=0)}return this}destroy(){this.destroyed=!0,fe(this.h,this.r,this.buffer,this.pad)}digestInto(t){At(this),Tn(t,this),this.finished=!0;let{buffer:n,h:r}=this,{pos:o}=this;if(o){for(n[o++]=1;o<16;o++)n[o]=0;this.process(n,0,!0)}this.finalize();let s=0;for(let i=0;i<8;i++)t[s++]=r[i]>>>0,t[s++]=r[i]>>>8}digest(){let{buffer:t,outputLen:n}=this;this.digestInto(t);let r=t.slice(0,n);return this.destroy(),r}},Cn=An(32,e=>new Bt(e));function no(e,t,n,r,o,s=20){let i=e[0],a=e[1],f=e[2],c=e[3],p=t[0],b=t[1],x=t[2],A=t[3],y=t[4],T=t[5],E=t[6],O=t[7],V=o,ie=n[0],ne=n[1],oe=n[2],Z=i,Y=a,Q=f,U=c,K=p,L=b,$=x,M=A,N=y,I=T,F=E,W=O,D=V,k=ie,z=ne,G=oe;for(let v=0;v<s;v+=2)Z=Z+K|0,D=C(D^Z,16),N=N+D|0,K=C(K^N,12),Z=Z+K|0,D=C(D^Z,8),N=N+D|0,K=C(K^N,7),Y=Y+L|0,k=C(k^Y,16),I=I+k|0,L=C(L^I,12),Y=Y+L|0,k=C(k^Y,8),I=I+k|0,L=C(L^I,7),Q=Q+$|0,z=C(z^Q,16),F=F+z|0,$=C($^F,12),Q=Q+$|0,z=C(z^Q,8),F=F+z|0,$=C($^F,7),U=U+M|0,G=C(G^U,16),W=W+G|0,M=C(M^W,12),U=U+M|0,G=C(G^U,8),W=W+G|0,M=C(M^W,7),Z=Z+L|0,G=C(G^Z,16),F=F+G|0,L=C(L^F,12),Z=Z+L|0,G=C(G^Z,8),F=F+G|0,L=C(L^F,7),Y=Y+$|0,D=C(D^Y,16),W=W+D|0,$=C($^W,12),Y=Y+$|0,D=C(D^Y,8),W=W+D|0,$=C($^W,7),Q=Q+M|0,k=C(k^Q,16),N=N+k|0,M=C(M^N,12),Q=Q+M|0,k=C(k^Q,8),N=N+k|0,M=C(M^N,7),U=U+K|0,z=C(z^U,16),I=I+z|0,K=C(K^I,12),U=U+K|0,z=C(z^U,8),I=I+z|0,K=C(K^I,7);let w=0;r[w++]=i+Z|0,r[w++]=a+Y|0,r[w++]=f+Q|0,r[w++]=c+U|0,r[w++]=p+K|0,r[w++]=b+L|0,r[w++]=x+$|0,r[w++]=A+M|0,r[w++]=y+N|0,r[w++]=T+I|0,r[w++]=E+F|0,r[w++]=O+W|0,r[w++]=V+D|0,r[w++]=ie+k|0,r[w++]=ne+z|0,r[w++]=oe+G|0}var ro=jn(no,{counterRight:!1,counterLength:4,allowShortKeys:!1});var oo=new Uint8Array(16),Un=(e,t)=>{e.update(t);let n=t.length%16;n&&e.update(oo.subarray(n))},so=new Uint8Array(32);function Ln(e,t,n,r,o){o!==void 0&&ee(o,void 0,"AAD");let s=e(t,n,so),i=Bn(r.length,o?o.length:0,!0),a=Cn.create(s);o&&Un(a,o),Un(a,r),a.update(i);let f=a.digest();return fe(s,i),f}var io=e=>(t,n,r)=>({encrypt(s,i){let a=s.length;i=De(a+16,i,!1),i.set(s);let f=i.subarray(0,-16);e(t,n,f,f,1);let c=Ln(e,t,n,f,r);return i.set(c,a),fe(c),i},decrypt(s,i){i=De(s.length-16,i,!1);let a=s.subarray(0,-16),f=s.subarray(-16),c=Ln(e,t,n,a,r);if(!En(f,c))throw fe(c),new Error("invalid tag");return i.set(s.subarray(0,-16)),e(t,n,i,i,1),fe(c),i}}),je=Pn({blockSize:64,nonceLength:12,tagLength:16},io(ro));var ao=new TextEncoder,co=new TextDecoder("utf-8",{fatal:!0,ignoreBOM:!0});function X(e){if(typeof e!="string")throw new TypeError(`encodeUtf8 expects a string, got ${typeof e}`);if(!e.isWellFormed())throw new TypeError("encodeUtf8: input contains lone surrogates");return ao.encode(e)}function Ce(e){if(!ArrayBuffer.isView(e)&&!(e instanceof ArrayBuffer))throw new TypeError(`decodeUtf8 expects a BufferSource, got ${e===null?"null":typeof e}`);return co.decode(e)}async function Nn(e){let t=new Blob([e]).stream().pipeThrough(new CompressionStream("gzip"));return new Uint8Array(await new Response(t).arrayBuffer())}async function Kn(e){let t=new Blob([e]).stream().pipeThrough(new DecompressionStream("gzip"));return new Uint8Array(await new Response(t).arrayBuffer())}var lo="deepview-triage-sync.v1.content-key",uo="deepview-triage-sync.v1.sign-key",fo="deepview-triage-sync.v1.save",go="deepview-triage-sync.v1.subscribe",po=12,Rt=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]),nt=null;function Mn(){return nt||(nt=(async()=>{try{return await crypto.subtle.importKey("raw",new Uint8Array(32),{name:"ChaCha20-Poly1305"},!1,["encrypt","decrypt"]),!0}catch{return!1}})(),nt)}async function In(e,t){let n=Uint8Array.fromBase64(e);if(n.length!==32)throw new Error(`workspace private key must be 32 bytes (got ${n.length})`);let r=await crypto.subtle.importKey("raw",n,"HKDF",!1,["deriveBits"]),o=await crypto.subtle.deriveBits({name:"HKDF",hash:"SHA-256",salt:new Uint8Array,info:X(t)},r,256);return new Uint8Array(o)}async function Fn(e){return await In(e,lo)}async function rt(e,t){let n=await In(e,`${uo}|${t}`),r=new Uint8Array(Rt.length+32);r.set(Rt,0),r.set(n,Rt.length);let o=await crypto.subtle.importKey("pkcs8",r,{name:"Ed25519"},!0,["sign"]),s=await crypto.subtle.exportKey("jwk",o),i=s.x;if(delete s.d,i==null)throw new Error("Ed25519 JWK export returned no public key");let a=Uint8Array.fromBase64(i,{alphabet:"base64url"}),f=await crypto.subtle.importKey("pkcs8",r,{name:"Ed25519"},!1,["sign"]);return n.fill(0),r.fill(0),{privateKey:f,publicKey:a,publicKeyB64:i}}function Ot({publicKeyB64:e,base:t,keyframe:n,nonceB64:r,ciphertextB64:o}){return X([fo,e,t==null?"":String(t),n===!0?"1":"",r,o].join(`
2
+ `))}async function Dn(e,t){let n=await crypto.subtle.sign({name:"Ed25519"},e,t);return new Uint8Array(n).toBase64({alphabet:"base64url",omitPadding:!0})}async function $n(e,t){return await Dn(e,Ot(t))}async function jt(e){let t=Ot(e),n=await crypto.subtle.digest("SHA-256",t);return new Uint8Array(n).toBase64({alphabet:"base64url",omitPadding:!0})}function yo(e,t,n){let r=t==null?"":String(t);return X([go,e,r,n].join(`
3
+ `))}async function Wn(e,t,n,r){return await Dn(e,yo(t,n,r))}async function Hn(e,t,n){try{let r=await crypto.subtle.importKey("raw",e,{name:"Ed25519"},!1,["verify"]),o=Uint8Array.fromBase64(n,{alphabet:"base64url"}),s=Ot(t);return await crypto.subtle.verify({name:"Ed25519"},r,o,s)}catch{return!1}}function ho(){let e=new Uint8Array(po);return crypto.getRandomValues(e),e}function Ct(e,t){let n=t==null?"":String(t);return X(`${e}|${n}`)}async function mo(e,t,n){let r=ho();if(await Mn()){let s=await crypto.subtle.importKey("raw",e,{name:"ChaCha20-Poly1305"},!1,["encrypt"]),i=new Uint8Array(await crypto.subtle.encrypt({name:"ChaCha20-Poly1305",iv:r,additionalData:n},s,t));return{nonce:r,ciphertext:i}}let o=je(e,r,n);return{nonce:r,ciphertext:o.encrypt(t)}}async function wo(e,t,n,r){if(await Mn()){let s=await crypto.subtle.importKey("raw",e,{name:"ChaCha20-Poly1305"},!1,["decrypt"]);return new Uint8Array(await crypto.subtle.decrypt({name:"ChaCha20-Poly1305",iv:t,additionalData:r},s,n))}return je(e,t,r).decrypt(n)}var bo=64;function vo(e,t){return e<=t?t:2**(32-Math.clz32(e-1))}async function So(e){let t=X(JSON.stringify(e)),n=await Nn(t);if(n.length>1073741820)throw new Error("payload too large");let r=vo(4+n.length,bo),o=new Uint8Array(r);return new DataView(o.buffer,o.byteOffset,o.byteLength).setUint32(0,n.length,!1),o.set(n,4),o}async function ko(e){if(e.length<4)throw new Error("plaintext too short");let n=new DataView(e.buffer,e.byteOffset,e.byteLength).getUint32(0,!1);if(n+4>e.length)throw new Error("length prefix exceeds buffer");let r=e.subarray(4,4+n),o=await Kn(r);return JSON.parse(Ce(o))}async function _n(e,t,n){let r=await So(t),{nonce:o,ciphertext:s}=await mo(e,r,n);return{nonce:o.toBase64(),ciphertext:s.toBase64()}}async function Vn(e,t,n,r){let o=Uint8Array.fromBase64(t),s=Uint8Array.fromBase64(n),i=await wo(e,o,s,r);return ko(i)}var To="deepview-objstore.v1.content",xo="deepview-objstore.v1.tag",Eo=`objstore-tag
4
4
  `,Ao=`objstore-bundle-tag
5
- `,ke=12,Po=16;async function Ut(e,t){let n=Uint8Array.fromBase64(e);if(n.length!==32)throw new Error(`workspace private key must be 32 bytes (got ${n.length})`);let r=await zn(n,To,32),o=await zn(n,xo,32);n.fill(0);let{privateKey:s,publicKeyB64:i}=await rt(e,t);return{signingKey:s,contentKey:r,tagKey:o,workspaceTag:i}}async function zn(e,t,n){let r=await crypto.subtle.importKey("raw",e,"HKDF",!1,["deriveBits"]),o=await crypto.subtle.deriveBits({name:"HKDF",hash:"SHA-256",salt:new Uint8Array,info:X(t)},r,n*8);return new Uint8Array(o)}async function fe(e,t){let n=await crypto.subtle.importKey("raw",e,{name:"HMAC",hash:"SHA-256"},!1,["sign"]);return new Uint8Array(await crypto.subtle.sign("HMAC",n,X(Eo+t))).toBase64({alphabet:"base64url",omitPadding:!0})}async function ye(e,t){let n=await crypto.subtle.importKey("raw",e,{name:"HMAC",hash:"SHA-256"},!1,["sign"]);return new Uint8Array(await crypto.subtle.sign("HMAC",n,X(Ao+t))).toBase64({alphabet:"base64url",omitPadding:!0})}function Lt(e,t,n,r,o){let s=X(t);if(s.length>65535)throw new Error(`fileName too long: ${s.length} bytes (max 65535)`);let i=new Uint8Array(2+s.length+n.length);new DataView(i.buffer).setUint16(0,s.length,!1),i.set(s,2),i.set(n,2+s.length);let f=new Uint8Array(ke);crypto.getRandomValues(f);let c=X(`${r}
6
- ${o}`),p=Oe(e,f,c).encrypt(i),w=new Uint8Array(ke+p.length);return w.set(f,0),w.set(p,ke),w}function qn(e,t){return ke+2+X(e).length+t+Po}function Gn(e,t){let n=X(e);if(n.length>65535)throw new Error(`bundle name too long: ${n.length} bytes (max 65535)`);let r=new Uint8Array(2+n.length+t.length);return new DataView(r.buffer).setUint16(0,n.length,!1),r.set(n,2),r.set(t,2+n.length),r}function Nt(e){if(e.length<2)throw new Error(`bundle wrapped content truncated: ${e.length} bytes`);let n=new DataView(e.buffer,e.byteOffset,e.byteLength).getUint16(0,!1);if(2+n>e.length)throw new Error(`bundle wrapped nameLen ${n} overflows ${e.length}`);let r=new TextDecoder("utf-8",{fatal:!0}).decode(e.subarray(2,2+n)),o=new Uint8Array(e.subarray(2+n));return{name:r,content:o}}function ot(e,t,n,r){if(t.length<ke+16)throw new Error(`objstore payload too short: ${t.length} bytes`);let o=t.subarray(0,ke),s=t.subarray(ke),i=X(`${n}
7
- ${r}`),a=Oe(e,o,i).decrypt(s);if(a.length<2)throw new Error(`objstore plaintext truncated: ${a.length} bytes`);let c=new DataView(a.buffer,a.byteOffset,a.byteLength).getUint16(0,!1);if(2+c>a.length)throw new Error(`objstore plaintext nameLen ${c} overflows ${a.length}`);let p=new TextDecoder("utf-8",{fatal:!0}).decode(a.subarray(2,2+c)),w=a.subarray(2+c);return{fileName:p,content:new Uint8Array(w)}}var Bo="deepview-objstore.v1.put",Ro="deepview-objstore.v1.delete",jo="deepview-objstore.v1.fetch",Oo="deepview-objstore.v1.fetch-rest",Co="deepview-objstore.v1.put-rest",Uo="deepview-objstore.v1.delete-rest";function st(e){return e==null?"":String(e)}function it(e){return e??""}function Lo(e,t){return X([Bo,e.workspaceTag,e.resourceTag,st(e.prevVersion),it(e.prevIncarnation),e.contentHash,String(e.expectedLength),t].join(`
5
+ `,ke=12,Po=16;async function Ut(e,t){let n=Uint8Array.fromBase64(e);if(n.length!==32)throw new Error(`workspace private key must be 32 bytes (got ${n.length})`);let r=await zn(n,To,32),o=await zn(n,xo,32);n.fill(0);let{privateKey:s,publicKeyB64:i}=await rt(e,t);return{signingKey:s,contentKey:r,tagKey:o,workspaceTag:i}}async function zn(e,t,n){let r=await crypto.subtle.importKey("raw",e,"HKDF",!1,["deriveBits"]),o=await crypto.subtle.deriveBits({name:"HKDF",hash:"SHA-256",salt:new Uint8Array,info:X(t)},r,n*8);return new Uint8Array(o)}async function de(e,t){let n=await crypto.subtle.importKey("raw",e,{name:"HMAC",hash:"SHA-256"},!1,["sign"]);return new Uint8Array(await crypto.subtle.sign("HMAC",n,X(Eo+t))).toBase64({alphabet:"base64url",omitPadding:!0})}async function ye(e,t){let n=await crypto.subtle.importKey("raw",e,{name:"HMAC",hash:"SHA-256"},!1,["sign"]);return new Uint8Array(await crypto.subtle.sign("HMAC",n,X(Ao+t))).toBase64({alphabet:"base64url",omitPadding:!0})}function Lt(e,t,n,r,o){let s=X(t);if(s.length>65535)throw new Error(`fileName too long: ${s.length} bytes (max 65535)`);let i=new Uint8Array(2+s.length+n.length);new DataView(i.buffer).setUint16(0,s.length,!1),i.set(s,2),i.set(n,2+s.length);let f=new Uint8Array(ke);crypto.getRandomValues(f);let c=X(`${r}
6
+ ${o}`),p=je(e,f,c).encrypt(i),b=new Uint8Array(ke+p.length);return b.set(f,0),b.set(p,ke),b}function qn(e,t){return ke+2+X(e).length+t+Po}function Gn(e,t){let n=X(e);if(n.length>65535)throw new Error(`bundle name too long: ${n.length} bytes (max 65535)`);let r=new Uint8Array(2+n.length+t.length);return new DataView(r.buffer).setUint16(0,n.length,!1),r.set(n,2),r.set(t,2+n.length),r}function Nt(e){if(e.length<2)throw new Error(`bundle wrapped content truncated: ${e.length} bytes`);let n=new DataView(e.buffer,e.byteOffset,e.byteLength).getUint16(0,!1);if(2+n>e.length)throw new Error(`bundle wrapped nameLen ${n} overflows ${e.length}`);let r=new TextDecoder("utf-8",{fatal:!0}).decode(e.subarray(2,2+n)),o=new Uint8Array(e.subarray(2+n));return{name:r,content:o}}function ot(e,t,n,r){if(t.length<ke+16)throw new Error(`objstore payload too short: ${t.length} bytes`);let o=t.subarray(0,ke),s=t.subarray(ke),i=X(`${n}
7
+ ${r}`),a=je(e,o,i).decrypt(s);if(a.length<2)throw new Error(`objstore plaintext truncated: ${a.length} bytes`);let c=new DataView(a.buffer,a.byteOffset,a.byteLength).getUint16(0,!1);if(2+c>a.length)throw new Error(`objstore plaintext nameLen ${c} overflows ${a.length}`);let p=new TextDecoder("utf-8",{fatal:!0}).decode(a.subarray(2,2+c)),b=a.subarray(2+c);return{fileName:p,content:new Uint8Array(b)}}var Bo="deepview-objstore.v1.put",Ro="deepview-objstore.v1.delete",Oo="deepview-objstore.v1.fetch",jo="deepview-objstore.v1.fetch-rest",Co="deepview-objstore.v1.put-rest",Uo="deepview-objstore.v1.delete-rest";function st(e){return e==null?"":String(e)}function it(e){return e??""}function Lo(e,t){return X([Bo,e.workspaceTag,e.resourceTag,st(e.prevVersion),it(e.prevIncarnation),e.contentHash,String(e.expectedLength),t].join(`
8
8
  `))}function No(e,t){return X([Ro,e.workspaceTag,e.resourceTag,st(e.prevVersion),it(e.prevIncarnation),t].join(`
9
- `))}function Ko(e,t,n){return X([jo,e,t,n].join(`
10
- `))}async function Ue(e,t){return new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},e,t)).toBase64({alphabet:"base64url",omitPadding:!0})}function Jn(e,t,n){return Ue(e,Lo(t,n))}function Yn(e,t,n){return Ue(e,No(t,n))}function Xn(e,t,n,r){return Ue(e,Ko(t,n,r))}function Mo(e,t,n){return X([Oo,e,t,String(n)].join(`
9
+ `))}function Ko(e,t,n){return X([Oo,e,t,n].join(`
10
+ `))}async function Ue(e,t){return new Uint8Array(await crypto.subtle.sign({name:"Ed25519"},e,t)).toBase64({alphabet:"base64url",omitPadding:!0})}function Jn(e,t,n){return Ue(e,Lo(t,n))}function Yn(e,t,n){return Ue(e,No(t,n))}function Xn(e,t,n,r){return Ue(e,Ko(t,n,r))}function Mo(e,t,n){return X([jo,e,t,String(n)].join(`
11
11
  `))}function Qn(e,t,n,r){return Ue(e,Mo(t,n,r))}function Io(e,t){return X([Co,e.workspaceTag,e.resourceTag,st(e.prevVersion),it(e.prevIncarnation),e.contentHash,String(e.expectedLength),String(t)].join(`
12
12
  `))}function Zn(e,t,n){return Ue(e,Io(t,n))}function Fo(e,t){return X([Uo,e.workspaceTag,e.resourceTag,st(e.prevVersion),it(e.prevIncarnation),String(t)].join(`
13
- `))}function er(e,t,n){return Ue(e,Fo(t,n))}async function Kt(e){let t=await crypto.subtle.digest("SHA-256",e);return new Uint8Array(t).toBase64({alphabet:"base64url",omitPadding:!0})}var Te=null,tr=[];function Do(e){if(Te===e)return;if(Te!==null)throw new Error("SyncHost: a different host is already installed");Te=e;let t=tr.splice(0);for(let n of t)try{n(e)}catch(r){console.warn("SyncHost install listener:",r)}}function ce(){if(Te===null)throw new Error("SyncHost: not installed \u2014 call installSyncHost(host) during app boot");return Te}function at(e){if(Te!==null){try{e(Te)}catch(t){console.warn("SyncHost install listener:",t)}return}tr.push(e)}var Mt="deepview.sync.password",It=null;function nr(){return It}function rr(){let e=ce().getSecureItem(Mt);It=typeof e=="string"&&e.length>0?e:null}async function He(e){It=e;let t=ce();e==null?await t.removeSecureItem(Mt):await t.setSecureItem(Mt,e)}function or(e){let t,n;if(e.startsWith("wss://"))t="https://",n=e.slice(6);else if(e.startsWith("ws://"))t="http://",n=e.slice(5);else if(e.startsWith("https://"))t="https://",n=e.slice(8);else if(e.startsWith("http://"))t="http://",n=e.slice(7);else throw new Error(`sse-transport: unsupported URL scheme: ${e}`);let r=n.indexOf("?");return r>=0&&(n=n.slice(0,r)),`${t}${n}`}function $o(e){return`${or(e)}/sse`}function sr(e){return`${or(e)}/save`}var Ho=100,_o=5e3,Ft=class{buf="";parse(t){this.buf+=t;let n=[],r;for(;(r=this.buf.indexOf(`
13
+ `))}function er(e,t,n){return Ue(e,Fo(t,n))}async function Kt(e){let t=await crypto.subtle.digest("SHA-256",e);return new Uint8Array(t).toBase64({alphabet:"base64url",omitPadding:!0})}var Te=null,tr=[];function Do(e){if(Te===e)return;if(Te!==null)throw new Error("SyncHost: a different host is already installed");Te=e;let t=tr.splice(0);for(let n of t)try{n(e)}catch(r){console.warn("SyncHost install listener:",r)}}function ce(){if(Te===null)throw new Error("SyncHost: not installed \u2014 call installSyncHost(host) during app boot");return Te}function at(e){if(Te!==null){try{e(Te)}catch(t){console.warn("SyncHost install listener:",t)}return}tr.push(e)}var Mt="deepview.sync.password",It=null;function nr(){return It}function rr(){let e=ce().getSecureItem(Mt);It=typeof e=="string"&&e.length>0?e:null}async function We(e){It=e;let t=ce();e==null?await t.removeSecureItem(Mt):await t.setSecureItem(Mt,e)}function or(e){let t,n;if(e.startsWith("wss://"))t="https://",n=e.slice(6);else if(e.startsWith("ws://"))t="http://",n=e.slice(5);else if(e.startsWith("https://"))t="https://",n=e.slice(8);else if(e.startsWith("http://"))t="http://",n=e.slice(7);else throw new Error(`sse-transport: unsupported URL scheme: ${e}`);let r=n.indexOf("?");return r>=0&&(n=n.slice(0,r)),`${t}${n}`}function $o(e){return`${or(e)}/sse`}function sr(e){return`${or(e)}/save`}var Wo=100,Ho=5e3,_o=75e3;var Ft=class{buf="";parse(t){this.buf+=t;let n=[],r;for(;(r=this.buf.indexOf(`
14
14
 
15
15
  `))>=0;){let o=this.buf.slice(0,r);this.buf=this.buf.slice(r+2);let s="",i=[];for(let a of o.split(`
16
16
  `))if(!a.startsWith(":")){if(a.startsWith("event:")){s=a.slice(6).trim();continue}if(a.startsWith("data:")){i.push(a.slice(5).replace(/^ /u,""));continue}}i.length!==0&&n.push({event:s,data:i.join(`
17
- `)})}return n}},ct=class e extends EventTarget{static CONNECTING=0;static OPEN=1;static CLOSING=2;static CLOSED=3;CONNECTING=e.CONNECTING;OPEN=e.OPEN;CLOSING=e.CLOSING;CLOSED=e.CLOSED;readyState=e.CONNECTING;baseUrl;sessionId=null;cachedPassword=null;outbound=[];flushTimer=null;inFlightPost=null;activeReaders=new Set;fetchAbort=new AbortController;constructor(t){super(),this.baseUrl=$o(t),this.scheduleFlush(!0)}send(t){if(this.readyState===e.CLOSED)throw new Error("sse-transport: send on closed transport");let n;try{n=JSON.parse(t)}catch(r){throw new Error(`sse-transport: send received non-JSON payload: ${r.message}`,{cause:r})}if(n.type==="authenticate"&&typeof n.password=="string"){this.cachedPassword=n.password,this.scheduleFlush();return}this.outbound.push(n),this.scheduleFlush()}close(){this.shutdown()}scheduleFlush(t=!1){if(this.readyState===e.CLOSED)return;if(this.flushTimer!=null)if(t)clearTimeout(this.flushTimer),this.flushTimer=null;else return;let n=t?0:Ho;this.flushTimer=setTimeout(()=>{this.flushTimer=null,this.flush()},n)}async flush(){if(this.readyState===e.CLOSED)return;if(this.inFlightPost){let s=new Promise(i=>{setTimeout(i,_o)});await Promise.race([this.inFlightPost.catch(()=>{}),s])}if(this.readyState===e.CLOSED)return;let t=this.outbound;this.outbound=[];let n={};this.cachedPassword!=null&&(n.password=this.cachedPassword),t.length>0&&(n.frames=t);let r=this.sessionId==null?this.baseUrl:`${this.baseUrl}?id=${encodeURIComponent(this.sessionId)}`,o=(async()=>{let s;try{s=await fetch(r,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(n),credentials:"same-origin",signal:this.fetchAbort.signal})}catch(a){this.readyState!==e.CLOSED&&console.warn("sse-transport: POST failed:",a),this.shutdown();return}if(!s.ok){this.readyState!==e.CLOSED&&console.warn(`sse-transport: POST ${s.status} ${s.statusText}; closing`),this.shutdown();return}let i=s.body;if(!i){this.shutdown();return}this.consumeStream(i)})();this.inFlightPost=o,o.finally(()=>{this.inFlightPost===o&&(this.inFlightPost=null)})}async consumeStream(t){let n=t.getReader();this.activeReaders.add(n);let r=new Ft,o=new TextDecoder;try{for(;;){let{value:s,done:i}=await n.read();if(i)break;if(this.readyState===e.CLOSED)return;let a=r.parse(o.decode(s,{stream:!0}));for(let f of a)this.dispatchEvent_(f)}if(this.readyState!==e.CLOSED){let s=o.decode();if(s.length>0)for(let i of r.parse(s))this.dispatchEvent_(i)}}catch(s){this.readyState!==e.CLOSED&&(console.warn("sse-transport: stream read failed:",s),this.shutdown())}finally{this.activeReaders.delete(n);try{n.releaseLock()}catch{}}}dispatchEvent_(t){if(t.event==="session"){if(this.readyState===e.CLOSED)return;this.sessionId=t.data,this.readyState===e.CONNECTING&&(this.readyState=e.OPEN,this.dispatchEvent(new Event("open")));return}if(t.event==="close"){let n,r;try{let o=JSON.parse(t.data);typeof o.code=="number"&&(n=o.code),typeof o.reason=="string"&&(r=o.reason)}catch{}this.shutdown(n,r);return}if(t.event===""||t.event==="message"){if(this.readyState!==e.OPEN)return;this.dispatchEvent(new MessageEvent("message",{data:t.data}))}}shutdown(t,n){if(this.readyState===e.CLOSED)return;this.readyState=e.CLOSING,this.flushTimer!=null&&(clearTimeout(this.flushTimer),this.flushTimer=null);try{this.fetchAbort.abort()}catch{}for(let o of this.activeReaders)try{o.cancel().catch(()=>{})}catch{}this.activeReaders.clear(),this.readyState=e.CLOSED;let r=new Event("close");t!=null&&(r.code=t),n!=null&&(r.reason=n),this.dispatchEvent(r)}};var lt=1e3,Wo=3e4,Dt="session restarted";function ut(e){let t=e.serverUrl,n=e.pingIntervalMs??15e3,r=e.pongTimeoutMs??5e3,o=null,s=!1,i=null,a=0,f=!1,c=null,p=lt,w=null,x=null,A=null,y=!1,T=null,E=new Set;function j(){c&&(clearTimeout(c),c=null)}function V(){j(),!f&&a!==0&&t&&(c=setTimeout(()=>{c=null,N()},p),p=Math.min(p*2,Wo))}function ie(){ne(),!(n<=0)&&(s||(w=setInterval(()=>{!o||o.readyState!==o.OPEN||x||(K({type:"ping"}),x=setTimeout(()=>{x=null,console.warn("socket-transport: heartbeat timeout; closing socket");try{o?.close()}catch{}},r))},n)))}function ne(){w&&(clearInterval(w),w=null),x&&(clearTimeout(x),x=null)}function oe(b){for(let v of E)try{v.onDisconnected(b)}catch(_){console.warn("socket-transport: consumer.onDisconnected threw:",_)}}function Z(b){for(let v of E)try{v.onConnected(b)}catch(_){console.warn("socket-transport: consumer.onConnected threw:",_)}}function Y(b){for(let v of E)try{v.onMessage(b)}catch(_){console.warn("socket-transport: consumer.onMessage threw:",_)}}function Q(b){let v;try{let _=typeof b.data=="string"?b.data:new TextDecoder().decode(b.data);v=JSON.parse(_)}catch(_){console.warn("socket-transport: dropping malformed wire frame:",_);return}if(!(!v||typeof v!="object")){if(v.type==="pong"){x&&(clearTimeout(x),x=null);return}if(v.type==="challenge"){if(typeof v.nonce!="string")return;i!=null&&i!==v.nonce&&oe(Dt),i=v.nonce,Z(i);return}if(v.type==="authenticated"){U(!0),Y(v);return}if(v.type==="unauthorized"&&v.kind==="auth-failed"){U(!1);return}Y(v)}}function U(b){if(!T)return;let v=T;T=null,v(b)}function K(b){if(!o||o.readyState!==o.OPEN)return!1;try{return o.send(JSON.stringify(b)),!0}catch(v){return console.warn("socket-transport: send failed:",v),!1}}function L(b){return new Promise(v=>{T=v,K({type:"authenticate",password:b})||(T=null,v(!1))})}function $(){if(A)return A;if(!o||o.readyState!==o.OPEN)return Promise.resolve(!1);let b=o,v=(async()=>{await Promise.resolve();try{let _=nr();if(_!=null&&!y){y=!0;let g=await L(_);if(o!==b)return!1;if(g)return!0;try{await He(null)}catch(d){console.warn("socket-transport: failed to clear cached auth password:",d)}}let l=!0;for(;;){if(o!==b||!o||o.readyState!==o.OPEN||!e.authResolver)return!1;let g;try{g=await e.authResolver({retry:!l})}catch(m){return console.warn("socket-transport: authentication resolver threw:",m),!1}if(o!==b||(l=!1,g==null||g===""))return!1;let d=await L(g);if(o!==b)return!1;if(d){try{await He(g)}catch(m){console.warn("socket-transport: failed to cache auth password:",m)}return!0}}}finally{A=null}})();return A=v,v}function M(b){if(!o)return;let v=o;o=null,i=null,y=!1,U(!1),ne(),oe(b);try{v.close()}catch{}}function N(){f||o||a!==0&&t&&I(!1)}function I(b){if(f||a===0||!t)return;let v;try{v=b?new ct(t):new WebSocket(t)}catch(l){if(!b){console.warn("socket-transport: WebSocket constructor failed; trying SSE fallback:",l),I(!0);return}console.warn("socket-transport: SSE constructor failed:",l),V();return}o=v,s=b,i=null,y=!1;let _=!1;v.addEventListener("open",()=>{o===v&&(_=!0,p=lt,ie())}),v.addEventListener("message",l=>{o===v&&Q(l)}),v.addEventListener("close",l=>{if(o!==v)return;if(o=null,i=null,y=!1,U(!1),ne(),!_&&!b&&!f&&a>0){if(typeof fetch>"u"){oe("socket closed"),V();return}console.warn("socket-transport: WebSocket failed to open; falling back to SSE"),I(!0);return}l?.code===1001&&(p=lt),oe("socket closed"),!f&&a>0&&V()}),v.addEventListener("error",()=>{})}function F(){if(f)return{release(){}};a+=1,a===1&&!o&&N();let b=!1;return{release(){b||(b=!0,!f&&(a-=1,a===0&&(j(),p=lt,M("released"))))}}}function H(b){b!==t&&(t=b,o&&M("serverUrl changed"),a>0&&t&&N())}function D(b){E.add(b);let v=!1;return{remove(){v||(v=!0,E.delete(b))}}}function k(){f||(f=!0,j(),M("transport closed"),E.clear(),a=0)}function z(b){let{pingMs:v,pongMs:_}=b;typeof v=="number"&&v>=0&&(n=v),typeof _=="number"&&_>0&&(r=_),w&&ie()}function G(){y=!1}return{acquire:F,setServerUrl:H,addConsumer:D,send:K,getNonce:()=>i,getSocket:()=>o,isSse:()=>o!=null&&s,runAuthFlow:$,close:k,setHeartbeatTimings:z,resetCachedReplayGuard:G}}var $t=64,Vo=5,ir=6,zo=25,qo=500;function Go(e,t){if(!/^\/api\/objstore\/[\w-]+\/[\w-]+$/u.test(e))throw new TypeError(`objstore: urlPath rejected (unexpected shape): ${JSON.stringify(e)}`);let n=new URL(t).origin,r=new URL(e,n);if(r.origin!==n)throw new TypeError(`objstore: urlPath origin mismatch \u2014 expected ${n}, got ${r.origin}`);return r.href}function ar(e){let t=e.requestTimeoutMs??1e4,n=new URL(e.httpOrigin).origin,r=e.transport===void 0,o=e.transport??ut(e.authResolver===void 0?{serverUrl:e.serverUrl}:{serverUrl:e.serverUrl,authResolver:e.authResolver}),s=!1,i=new Map,a=new Map,f=[],c=[];function p(l,g,d,m){let u=l.seenVersions.get(g);(!u||u.incarnation!==d||m>u.version)&&l.seenVersions.set(g,{incarnation:d,version:m})}function w(l){l.connectedPromise=new Promise((g,d)=>{l.resolveConnected=g,l.rejectConnected=d}),l.connectedPromise.catch(()=>{})}function x(l){l.listedPromise=new Promise((g,d)=>{l.resolveListed=g,l.rejectListed=d}),l.listedPromise.catch(()=>{})}function A(l,g){l.inventory.clear();for(let d of g)l.inventory.set(d.resourceTag,{version:d.version,incarnation:d.incarnation,contentLength:d.contentLength}),p(l,d.resourceTag,d.incarnation,d.version);l.resolveListed()}function y(l){if(!Array.isArray(l))return[];let g=[];for(let d of l)Le(d)&&g.push(Ne(d));return g}function T(l){let g;return new Promise((d,m)=>{g=setTimeout(()=>m(new Error(`objstore: inventory not seeded (no subscribe ack) after ${t}ms`)),t),l.listedPromise.then(d,m)}).finally(()=>clearTimeout(g))}function E(l){for(let g=0;g<f.length;g++)if(l(f[g]))return Promise.resolve(f.splice(g,1)[0]);return new Promise((g,d)=>{let m={predicate:l,resolve:()=>{},reject:h=>{clearTimeout(u);let R=c.indexOf(m);R>=0&&c.splice(R,1),d(h)}},u=setTimeout(()=>m.reject(new Error(`objstore: response timeout after ${t}ms`)),t);m.resolve=h=>{clearTimeout(u),g(h)},c.push(m)})}function j(l){if(!o.send(l))throw new Error("objstore: socket not open")}function V(l){for(let g of c.splice(0))try{g.reject(new Error(`objstore: ${l}`))}catch{}}function ie(l){if(l.type==="objstore-put"&&typeof l.workspaceTag=="string"&&Le(l)){let g=i.get(l.workspaceTag);if(!g)return;let d=Ne(l);p(g,d.resourceTag,d.incarnation,d.version),g.inventory.set(d.resourceTag,{version:d.version,incarnation:d.incarnation,contentLength:d.contentLength});let m={resourceTag:d.resourceTag,version:d.version,contentLength:d.contentLength};for(let u of g.putHandlers)try{u(m)}catch{}return}if(l.type==="objstore-deleted"&&typeof l.workspaceTag=="string"&&typeof l.resourceTag=="string"&&typeof l.version=="number"){let g=i.get(l.workspaceTag);if(!g)return;let d=l.resourceTag,m=l.version;g.seenVersions.delete(d),g.inventory.delete(d);let u={resourceTag:d,version:m};for(let h of g.deletedHandlers)try{h(u)}catch{}return}if(!(l.type==="workspace-state"||l.type==="workspace-save-ack"||l.type==="workspace-save-error"||l.type==="workspace-subscribed"||l.type==="authenticated")){for(let g=0;g<c.length;g++)if(c[g].predicate(l)){let d=c[g];c.splice(g,1),d.resolve(l);return}if(f.push(l),f.length>$t){let g=f.splice(0,f.length-$t),d=[...new Set(g.map(m=>m.type??"<no-type>"))].slice(0,4);console.warn(`objstore: dropping ${g.length} unmatched frame(s) over MAX_QUEUE_SIZE=${$t} (types: ${d.join(", ")})`)}}}function ne(){for(let l of i.values())l.closed||l.connected||(l.connected=!0,l.resolveConnected())}function oe(l){V(l);for(let g of i.values())g.closed||g.connected&&(g.connected=!1,w(g))}let Z=o.addConsumer({onMessage:ie,onConnected:ne,onDisconnected:oe}),Y=l=>Go(l,n),Q=(l,g)=>Y(`/api/objstore/${l}/${g}`);async function U(l,g,d){let m=o.getNonce();if(!m)throw new Error("objstore: socket not open");let u=await Jn(l.signingKey,d,m),h,R=!1;for(;j({type:"objstore-put-begin",...d,signature:u}),h=await E(ae=>ae.workspaceTag===l.workspaceTag&&ae.resourceTag===g&&(ae.type==="objstore-put-token"||ae.type==="objstore-put-error"||ae.type==="objstore-conflict"||ae.type==="unauthorized"&&ae.kind==="gated")),!(h.type!=="unauthorized"||R||(R=!0,!await o.runAuthFlow())););if(h.type==="unauthorized")return{kind:"unauthorized"};if(h.type==="objstore-put-error"){if(h.reason==="workspace-full")return{kind:"workspace-full"};throw new Error(`objstore: put-error reason='${String(h.reason)}'`)}if(h.type==="objstore-conflict")return{kind:"conflict",current:Le(h.current)?Ne(h.current):null};if(typeof h.urlPath!="string"||typeof h.token!="string")throw new TypeError("objstore: malformed put-token (missing urlPath/token)");return{kind:"token",urlPath:h.urlPath,token:h.token}}async function K(l,g,d,m){let u=Date.now(),h=await Zn(l.signingKey,d,u),R=await globalThis.fetch(Q(l.workspaceTag,g),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({op:"put",ts:u,signature:h,prevVersion:d.prevVersion,prevIncarnation:d.prevIncarnation,expectedLength:d.expectedLength,contentHash:m})});if(R.status===401)return{kind:"unauthorized"};if(R.status===403)return{kind:"workspace-full"};if(R.status===409)return{kind:"conflict",current:await Ht(R)};if(!R.ok){let ae="";try{ae=await R.text()}catch{}throw new Error(`objstore: REST put-begin failed ${R.status} ${ae.slice(0,200)}`)}let J;try{J=await R.json()}catch{throw new TypeError("objstore: put-mint JSON parse failed")}if(!J||typeof J!="object"||typeof J.urlPath!="string"||typeof J.token!="string")throw new TypeError("objstore: malformed put-mint (missing urlPath/token)");return{kind:"token",urlPath:J.urlPath,token:J.token}}async function L(l,g){let d=`objstore: ${Dt}`;for(let m=0;;m++)try{return await g()}catch(u){if(m<Vo&&!l.closed&&u instanceof Error&&u.message===d)continue;throw u}}function $(l,g){return L(l,()=>M(l,g))}async function M(l,g){if(await l.connectedPromise,l.closed)throw new Error("objstore: session closed");let d=await Kt(g.bytes),m={workspaceTag:l.workspaceTag,resourceTag:g.resourceTag,prevVersion:g.prev?.version??null,prevIncarnation:g.prev?.incarnation??null,expectedLength:g.bytes.byteLength,contentHash:d},u;if(o.isSse()?(u=await K(l,g.resourceTag,m,d),u.kind==="unauthorized"&&(u=await U(l,g.resourceTag,m))):u=await U(l,g.resourceTag,m),u.kind==="unauthorized")return{ok:!1,reason:"unauthorized"};if(u.kind==="workspace-full")return{ok:!1,reason:"workspace-full"};if(u.kind==="conflict")return{ok:!1,reason:"conflict",current:u.current};let h=await globalThis.fetch(Y(u.urlPath),{method:"PUT",headers:{authorization:`Bearer ${u.token}`,"content-type":"application/octet-stream"},body:g.bytes});if(!h.ok){if(h.status===409||h.status===410)return{ok:!1,reason:"conflict",current:h.status===409?await Ht(h):null};let ae="";try{ae=await h.text()}catch{}throw new Error(`objstore: REST PUT failed ${h.status} ${ae.slice(0,200)}`)}let R;try{R=await h.json()}catch{throw new TypeError("objstore: PUT ack JSON parse failed")}if(!R||typeof R!="object"||!_e(R.version)||typeof R.incarnation!="string"||typeof R.contentHash!="string"||!_e(R.contentLength))throw new TypeError("objstore: PUT ack malformed (missing/invalid version/incarnation/contentHash/contentLength)");let J=R;if(J.contentHash!==d||J.contentLength!==g.bytes.byteLength)throw new Error(`objstore: PUT ack mismatch \u2014 server returned contentHash=${J.contentHash.slice(0,16)}\u2026 length=${J.contentLength}, client signed ${d.slice(0,16)}\u2026 length=${g.bytes.byteLength}`);return{ok:!0,meta:J}}async function N(l,g){let d=o.getNonce();if(!d)throw new Error("objstore: socket not open");let m=await Xn(l.signingKey,l.workspaceTag,g,d);j({type:"objstore-fetch",workspaceTag:l.workspaceTag,resourceTag:g,signature:m});let u=await E(h=>h.workspaceTag===l.workspaceTag&&h.resourceTag===g&&(h.type==="objstore-fetch-token"||h.type==="objstore-fetch-not-found"));if(u.type==="objstore-fetch-not-found")return{kind:"not-found"};if(typeof u.urlPath!="string"||typeof u.token!="string"||!Le(u))throw new TypeError("objstore: malformed fetch-token (missing urlPath / token / metadata)");return{kind:"token",urlPath:u.urlPath,token:u.token,meta:Ne(u)}}async function I(l,g){let d=Date.now(),m=await Qn(l.signingKey,l.workspaceTag,g,d),u=await globalThis.fetch(Q(l.workspaceTag,g),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({op:"fetch",ts:d,signature:m})});if(u.status===404)return{kind:"not-found"};if(u.status===401)return{kind:"unauthorized"};if(!u.ok){let R="";try{R=await u.text()}catch{}throw new Error(`objstore: REST fetch-mint failed ${u.status} ${R.slice(0,200)}`)}let h;try{h=await u.json()}catch{throw new TypeError("objstore: fetch-mint JSON parse failed")}if(!h||typeof h!="object"||typeof h.urlPath!="string"||typeof h.token!="string"||!Le(h))throw new TypeError("objstore: malformed fetch-mint (missing urlPath / token / metadata)");return{kind:"token",urlPath:h.urlPath,token:h.token,meta:Ne(h)}}async function F(l,g){for(let d=0;d<ir;d++){let m=await L(l,()=>H(l,g));if(m.kind==="ok")return m.value;if(m.kind==="not-found")return null;if(d+1<ir){let u=Math.min(qo,zo*2**d);await new Promise(h=>{setTimeout(h,u)})}}return null}async function H(l,g){if(await l.connectedPromise,l.closed)throw new Error("objstore: session closed");let d;if(o.isSse()?(d=await I(l,g),d.kind==="unauthorized"&&(d=await N(l,g))):d=await N(l,g),d.kind==="not-found")return{kind:"not-found"};if(d.kind==="unauthorized")throw new Error("objstore: fetch-mint unauthorized");let m=d.meta,u=await globalThis.fetch(Y(d.urlPath),{method:"GET",headers:{authorization:`Bearer ${d.token}`}});if(!u.ok){if(u.status===404||u.status===503)return{kind:"retry"};let J="";try{J=await u.text()}catch{}throw new Error(`objstore: REST GET failed ${u.status} ${J.slice(0,200)}`)}let h=new Uint8Array(await u.arrayBuffer()),R=await Kt(h);if(R!==m.contentHash)throw new Error(`objstore: contentHash mismatch \u2014 expected ${m.contentHash.slice(0,16)}\u2026, got ${R.slice(0,16)}\u2026`);return{kind:"ok",value:{bytes:h,meta:m}}}async function D(l,g){let d=o.getNonce();if(!d)throw new Error("objstore: socket not open");let m=await Yn(l.signingKey,g,d);j({type:"objstore-delete",...g,signature:m});let u=await E(h=>h.workspaceTag===l.workspaceTag&&h.resourceTag===g.resourceTag&&(h.type==="objstore-deleted-ack"||h.type==="objstore-delete-error"||h.type==="objstore-conflict"));if(u.type==="objstore-deleted-ack"){if(typeof u.deletedVersion!="number")throw new TypeError("objstore: malformed deleted-ack (deletedVersion not a number)");return{kind:"ok",deletedVersion:u.deletedVersion}}if(u.type==="objstore-conflict")return{kind:"conflict",current:Le(u.current)?Ne(u.current):null};if(u.reason==="not-found")return{kind:"not-found"};throw new Error(`objstore: delete-error reason='${String(u.reason)}'`)}async function k(l,g,d){let m=Date.now(),u=await er(l.signingKey,d,m),h=await globalThis.fetch(Q(l.workspaceTag,g),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({op:"delete",ts:m,signature:u,prevVersion:d.prevVersion,prevIncarnation:d.prevIncarnation})});if(h.status===401)return{kind:"unauthorized"};if(h.status===404)return{kind:"not-found"};if(h.status===409)return{kind:"conflict",current:await Ht(h)};if(!h.ok){let J="";try{J=await h.text()}catch{}throw new Error(`objstore: REST delete failed ${h.status} ${J.slice(0,200)}`)}let R;try{R=await h.json()}catch{throw new TypeError("objstore: delete-ack JSON parse failed")}if(!R||typeof R!="object"||typeof R.deletedVersion!="number")throw new TypeError("objstore: malformed delete-ack (deletedVersion not a number)");return{kind:"ok",deletedVersion:R.deletedVersion}}function z(l,g,d){return L(l,()=>G(l,g,d))}async function G(l,g,d){if(await l.connectedPromise,l.closed)throw new Error("objstore: session closed");let m={workspaceTag:l.workspaceTag,resourceTag:g,prevVersion:d?.version??null,prevIncarnation:d?.incarnation??null},u;if(o.isSse()?(u=await k(l,g,m),u.kind==="unauthorized"&&(u=await D(l,m))):u=await D(l,m),u.kind==="ok")return{ok:!0,deletedVersion:u.deletedVersion};if(u.kind==="conflict")return{ok:!1,reason:"conflict",current:u.current};if(u.kind==="not-found")return{ok:!1,reason:"not-found"};throw new Error("objstore: delete unauthorized")}function b(l,g,d,m){let u=l.seenVersions.get(g);if(u&&u.incarnation===d&&m<u.version)throw new Error(`objstore: version-rollback rejected \u2014 fetched v${m} for an incarnation we've already seen at v${u.version}`)}async function v(l,g){if(s)throw new Error("objstore: client closed");if(!g||typeof g.workspaceId!="string")throw new Error("objstore: openWorkspace requires a WorkspaceSubscription (triageSync.ensureSubscription) \u2014 the client must not open a session for a tag with no backing sync subscribe");let d=l.workspaceTag;if(g.workspaceTag!=null&&g.workspaceTag!==d)throw new Error("objstore: openWorkspace \u2014 WorkspaceSubscription is for a different workspace than these keys");if(i.has(d))throw new Error(`objstore: workspace ${d.slice(0,8)}\u2026 is already open on this client`);let m={workspaceTag:d,signingKey:l.signingKey,contentKey:new Uint8Array(l.contentKey),tagKey:new Uint8Array(l.tagKey),putHandlers:new Set,deletedHandlers:new Set,seenVersions:new Map,inventory:new Map,connected:!1,closed:!1};w(m),x(m),i.set(d,m);let u=m;(async()=>{let S;try{S=await g.resources}catch{return}u.closed||A(u,y(S))})();let h=o.acquire();a.set(d,h),o.getNonce()&&(u.connected=!0,u.resolveConnected());let R=null;try{await new Promise((S,P)=>{R=setTimeout(()=>{P(new Error(`objstore: connect timeout after ${t}ms`))},t),u.connectedPromise.then(()=>S(),B=>P(B))})}catch(S){R&&clearTimeout(R),i.delete(d),a.delete(d),u.closed=!0;try{u.contentKey.fill(0)}catch{}try{u.tagKey.fill(0)}catch{}throw h.release(),S}R&&clearTimeout(R);async function J(S,P,B){let q=await $(u,{resourceTag:S,bytes:P,prev:B});return q.ok?(B==null&&u.seenVersions.delete(S),p(u,S,q.meta.incarnation,q.meta.version),u.inventory.set(S,{version:q.meta.version,incarnation:q.meta.incarnation,contentLength:q.meta.contentLength}),{ok:!0,meta:{version:q.meta.version,incarnation:q.meta.incarnation,contentLength:q.meta.contentLength}}):q.reason==="workspace-full"?{ok:!1,reason:"workspace-full"}:q.reason==="unauthorized"?{ok:!1,reason:"unauthorized"}:(q.current&&p(u,S,q.current.incarnation,q.current.version),{ok:!1,reason:"conflict",current:q.current})}async function ae(S){let P=await fe(u.tagKey,S.fileName),B=Lt(u.contentKey,S.fileName,S.content,d,P);return await J(P,B,S.prev)}async function vn(S){let P=await fe(u.tagKey,S),B=await F(u,P);if(!B)return null;b(u,P,B.meta.incarnation,B.meta.version);let{fileName:q,content:et}=ot(u.contentKey,B.bytes,d,P);if(q!==S)throw new Error(`objstore: fileName-binding mismatch \u2014 requested '${S}', payload encoded '${q}'`);return p(u,P,B.meta.incarnation,B.meta.version),{content:et,version:B.meta.version,incarnation:B.meta.incarnation}}async function $r(S){let P=await F(u,S);if(!P)return null;b(u,S,P.meta.incarnation,P.meta.version);let{fileName:B,content:q}=ot(u.contentKey,P.bytes,d,S);if(await fe(u.tagKey,B)===S)return p(u,S,P.meta.incarnation,P.meta.version),{kind:"report",fileName:B,content:q,version:P.meta.version,incarnation:P.meta.incarnation};if(await ye(u.tagKey,B)===S){let{name:Et,content:qr}=Nt(q);return p(u,S,P.meta.incarnation,P.meta.version),{kind:"bundle",integrity:B,name:Et,content:qr,version:P.meta.version,incarnation:P.meta.incarnation}}throw new Error("objstore: fetchByTag \u2014 decrypted name does not derive back to the requested resourceTag under either the report or bundle tag scheme (relay or workspace member produced a non-round-trippable tag-name pair)")}async function Sn(S,P){let B=await z(u,S,P);return B.ok?(u.seenVersions.delete(S),u.inventory.delete(S),B):B.reason==="not-found"?{ok:!1,reason:"not-found"}:(B.current&&p(u,S,B.current.incarnation,B.current.version),{ok:!1,reason:"conflict",current:B.current})}async function Hr(S,P){let B=await fe(u.tagKey,S);return await Sn(B,P)}async function _r(){if(await T(u),u.closed)throw new Error("objstore: session closed");return[...u.inventory.entries()].map(([S,P])=>({resourceTag:S,version:P.version,incarnation:P.incarnation,contentLength:P.contentLength}))}async function Wr(S){let P=await ye(u.tagKey,S.integrity),B=Gn(S.name,S.content),q=Lt(u.contentKey,S.integrity,B,d,P);return await J(P,q,S.prev)}async function Vr(S){let P=await ye(u.tagKey,S),B=await F(u,P);if(!B)return null;b(u,P,B.meta.incarnation,B.meta.version);let{fileName:q,content:et}=ot(u.contentKey,B.bytes,d,P);if(q!==S)throw new Error(`objstore: bundle-integrity binding mismatch \u2014 requested '${S}', payload encoded '${q}'`);let{name:kn,content:Et}=Nt(et);return p(u,P,B.meta.incarnation,B.meta.version),{name:kn,content:Et,version:B.meta.version,incarnation:B.meta.incarnation}}async function zr(S,P){let B=await ye(u.tagKey,S);return await Sn(B,P)}return{put:ae,fetch:vn,fetchByTag:$r,delete:Hr,list:_r,putBundle:Wr,fetchBundle:Vr,deleteBundle:zr,onPut(S){return u.putHandlers.add(S),()=>{u.putHandlers.delete(S)}},onDeleted(S){return u.deletedHandlers.add(S),()=>{u.deletedHandlers.delete(S)}},close(){if(u.closed)return;u.closed=!0,i.delete(d);try{u.contentKey.fill(0)}catch{}try{u.tagKey.fill(0)}catch{}try{u.rejectConnected(new Error("objstore: session closed"))}catch{}try{u.rejectListed(new Error("objstore: session closed"))}catch{}let S=a.get(d);a.delete(d),S&&S.release()}}}function _(){if(!s){s=!0;for(let l of i.values()){l.closed=!0;try{l.contentKey.fill(0)}catch{}try{l.tagKey.fill(0)}catch{}try{l.rejectConnected(new Error("objstore: client closed"))}catch{}try{l.rejectListed(new Error("objstore: client closed"))}catch{}}i.clear();for(let l of a.values())l.release();a.clear(),Z.remove(),r&&o.close()}}return{openWorkspace:v,close:_}}async function Ht(e){try{let t=await e.json();if(_e(t.currentVersion)&&typeof t.currentIncarnation=="string")return{version:t.currentVersion,incarnation:t.currentIncarnation}}catch{}return null}function _e(e){return typeof e=="number"&&Number.isSafeInteger(e)&&e>=0}function Le(e){return!e||typeof e!="object"?!1:typeof e.resourceTag=="string"&&_e(e.version)&&typeof e.incarnation=="string"&&typeof e.contentHash=="string"&&_e(e.contentLength)&&typeof e.signature=="string"}function Ne(e){return{resourceTag:e.resourceTag,version:e.version,incarnation:e.incarnation,contentHash:e.contentHash,contentLength:e.contentLength,signature:e.signature}}var _t=null;function cr(e){_t=typeof e=="function"?e:null}var Jo=ut({serverUrl:"",authResolver:e=>_t==null?Promise.resolve(null):_t(e)});function ft(){return Jo}var lr=new Set(["busy"]);function Yo(e){return typeof e?.color=="string"?e.color:""}function Xo(e){return e?.triage==="fixed"||e?.triage==="invalid"||e?.triage==="deleted"?e.triage:e?.deleted?"deleted":""}function Qo(e){return typeof e?.comment=="string"?e.comment:""}function Zo(e){return typeof e?.fix=="string"?e.fix:""}function ur(e,t,n){let r=[];for(let o of Object.keys(e)){let s=e[o],i=t[o],a=n[o],f=s??null,c=[{name:"color",norm:Yo},{name:"triage",norm:Xo},{name:"comment",norm:Qo},{name:"fix",norm:Zo}];for(let{name:p,norm:w}of c){let x=w(i),A=w(f),y=w(a);A!==x&&y!==x&&A!==y&&r.push({id:o,property:p,local:A,imported:y})}}return r}function es(e,t){let n=Array.isArray(e)?e:[],r=Array.isArray(t)?t:[];if(n.length!==r.length)return!1;if(n.length===0)return!0;let o=new Set(n);for(let s of r)if(!o.has(s))return!1;return!0}function fr(e,t){let n=e.triage??(e.deleted?"deleted":""),r=t.triage??(t.deleted?"deleted":"");return e.color===t.color&&n===r&&(e.comment??"")===(t.comment??"")&&(e.fix??"")===(t.fix??"")&&es(e.ignoredReports,t.ignoredReports)}function Wt(e,t){let n=new Set([...Object.keys(e),...Object.keys(t)]);for(let r of n)if(!fr(e[r]??{},t[r]??{}))return!1;return!0}function dt(e,t){let n=Object.assign(Object.create(null),e);for(let[r,o]of Object.entries(t))o===null?delete n[r]:o!==void 0&&(n[r]=o);return n}function Vt(e,t){let n=Object.create(null),r=new Set([...Object.keys(e),...Object.keys(t)]);for(let o of r){let s=e[o]??{},i=t[o]??{};fr(s,i)||(n[o]=t[o]??null)}return n}function dr(e){for(let t in e)return!1;return!0}function gr(e){return e==="fixed"||e==="invalid"||e==="deleted"?e:void 0}function we(e){if(e)return gr(e.triage)??(e.deleted?"deleted":void 0)}function ts(e){return e?!e.color&&!we(e)&&!e.comment&&!e.fix&&!(e.ignoredReports&&e.ignoredReports.length>0):!0}function gt(e){if(!e||typeof e!="object")return;let t=e,n={};typeof t.color=="string"&&t.color&&(n.color=t.color);let r=gr(t.triage)??(t.deleted?"deleted":void 0);if(r&&(n.triage=r),typeof t.comment=="string"&&t.comment&&(n.comment=t.comment),typeof t.fix=="string"&&t.fix&&(n.fix=t.fix),Array.isArray(t.ignoredReports)){let o=t.ignoredReports.filter(s=>typeof s=="string"&&s.length>0);o.length>0&&(n.ignoredReports=o)}return ts(n)?void 0:n}function ns(e,t){let n=e??[],r=t??[];if(n.length!==r.length)return!1;if(n.length===0)return!0;let o=new Set(n);for(let s of r)if(!o.has(s))return!1;return!0}function pr(e,t){let n=e??{},r=t??{};return(n.color??"")===(r.color??"")&&(we(n)??"")===(we(r)??"")&&(n.comment??"")===(r.comment??"")&&(n.fix??"")===(r.fix??"")&&ns(n.ignoredReports,r.ignoredReports)}function de(e,t,n){let r=e.get(t),o=gt({...r,...n});return o===void 0?e.delete(t):pr(r,o)?!1:(e.set(t,o),!0)}function yr(e,t,n){let r=gt(n),o=e.get(t);return r===void 0?e.delete(t):pr(o,r)?!1:(e.set(t,r),!0)}function hr(e,t,n,r){let o=new Set(e.get(t)?.ignoredReports??[]);return r?o.add(n):o.delete(n),de(e,t,{ignoredReports:o.size>0?[...o]:void 0})}function Ke(e,t){let n=Object.assign(Object.create(null),e),r=ce().state,o=t instanceof Set?t:new Set(t);for(let s of o){let i=gt(r.triage.get(s));i?n[s]=i:delete n[s]}return n}function zt(e,t){let n=ce().state,r=[];for(let o of t){let s=e[o];if(!s||typeof s!="object")continue;let i=n.triage.get(o);if(s.color){let c=i?.color;c===void 0?de(n.triage,o,{color:s.color}):c!==s.color&&r.push({id:o,property:"color",local:c,imported:s.color})}let a=we(s);if(a){let c=we(i);c===void 0?de(n.triage,o,{triage:a}):c!==a&&r.push({id:o,property:"triage",local:c,imported:a})}if(s.comment){let c=i?.comment;c===void 0?de(n.triage,o,{comment:s.comment}):c!==s.comment&&r.push({id:o,property:"comment",local:c,imported:s.comment})}if(s.fix){let c=i?.fix;c===void 0?de(n.triage,o,{fix:s.fix}):c!==s.fix&&r.push({id:o,property:"fix",local:c,imported:s.fix})}if(!(a!=null||we(i)!=null||!Array.isArray(s.ignoredReports))&&!((i?.ignoredReports?.length??0)>0))for(let c of s.ignoredReports)typeof c=="string"&&hr(n.triage,o,c,!0)}return r}function qt(e,t){let n=ce().state;for(let r of e){let o=`${r.id}:${r.property}`;t[o]==="imported"&&rs(r.id,r.property)===r.local&&(r.property==="color"?de(n.triage,r.id,{color:r.imported}):r.property==="comment"?de(n.triage,r.id,{comment:r.imported}):r.property==="fix"?de(n.triage,r.id,{fix:r.imported}):r.property==="triage"&&(r.imported==="fixed"||r.imported==="invalid"||r.imported==="deleted"?de(n.triage,r.id,{triage:r.imported,ignoredReports:void 0}):de(n.triage,r.id,{triage:void 0})))}}function rs(e,t){let n=ce().state.triage.get(e);return t==="color"?n?.color??"":t==="triage"?we(n)??"":t==="comment"?n?.comment??"":t==="fix"?n?.fix??"":""}function mr(e,t){let n=ce().state,r=t instanceof Set?t:new Set(t);for(let o of r){let s=e[o],i=we(s)?void 0:s?.ignoredReports;yr(n.triage,o,{...s,ignoredReports:i})}}var Jt="deepview.sync.sessions",os=Jt,Gt=1,yt=!1,pt=new Set;function br(){return yt}function We(e){if(yt!==e){yt=e,console.warn(e?"triage-sync: can't persist the sessions blob \u2014 either it's an unrecognised future version (writes skipped to avoid clobbering a newer build's data) or the write itself failed (storage full / vault locked). Your in-memory triage state still works this session but will not persist across reload. Free up storage and/or clear localStorage[deepview.sync.sessions]; the badge clears on the next successful save.":"triage-sync: persistence recovered; persisted-sessions blob is now writable.");for(let t of pt)try{t(e)}catch(n){console.warn("persistenceDegraded listener:",n)}}}function wr(e){let t=n=>e(n);return pt.add(t),queueMicrotask(()=>{if(pt.has(t))try{t(yt)}catch(n){console.warn("persistenceDegraded listener:",n)}}),()=>pt.delete(t)}function ht(){try{let e=ce().getSecureItem(Jt);if(!e)return{kind:"empty"};let t=JSON.parse(e);if(!t||typeof t!="object")return{kind:"empty"};let n=t;return n.version===Gt&&n.sessions&&typeof n.sessions=="object"&&!Array.isArray(n.sessions)?{kind:"v1",map:n.sessions}:n.version===Gt?{kind:"empty"}:"version"in n?{kind:"unknown-version"}:{kind:"legacy",map:n}}catch{return{kind:"empty"}}}function ss(){let e=ht();return e.kind==="v1"||e.kind==="legacy"?e.map:{}}async function is(e){try{return await ce().setSecureItem(Jt,JSON.stringify({version:Gt,sessions:e})),!0}catch(t){return console.warn("Triage sync: could not persist session state:",t),!1}}function Yt(e,t){if(!t)return null;let r=ss()[e];return!r||r.serverUrl!==t?null:{baseRevision:typeof r.baseRevision=="string"?r.baseRevision:null,baseState:r.baseState&&typeof r.baseState=="object"?Object.assign(Object.create(null),r.baseState):Object.create(null),savesSinceKeyframe:typeof r.savesSinceKeyframe=="number"?r.savesSinceKeyframe:0}}async function mt(e){await navigator.locks.request(os,async()=>{let t=ht();if(t.kind==="unknown-version"){We(!0);return}let n=t.kind==="v1"||t.kind==="legacy"?t.map:{};if(await e(n)===!1)return;let o=await is(n);We(!o)})}function Xt(e=null){mt(t=>{let n=Object.keys(t);if(n.length===0)return!1;let r=new Set(ce().listWorkspaces().map(s=>s.id)),o=!1;for(let s of n){let i=t[s];(!r.has(s)||e!=null&&i?.serverUrl!==e)&&(delete t[s],o=!0)}return o?void 0:!1}).catch(t=>{console.warn("Triage sync: prunePersistedSessions lock failed:",t)})}function bt(e){return mt(t=>{if(!(e in t))return!1;delete t[e]})}var Er,Je,vt,vr,Ar,as="deepview.triageSyncUrl",Pr="deepview.sync.userEnabled",cs=/^\d+$/u,on=()=>{},Ge=null,he="",qe=!0,en=!1,se=ft(),Ve=null,xe=100,ls=5;function St(){return qe&&!en&&!!he&&us()}function us(){try{return Je().length>0}catch{return!1}}var tn=new Set;function Br(){if(!St())return"off";for(let t of O.values())if(t.error)return"error";let e=se.getSocket();if(!e||e.readyState!==WebSocket.OPEN)return"offline";for(let t of O.values())if(t.subscribed&&!t.subscribeAcked)return"connecting";return"online"}var Sr="off";function te(){let e=Br();if(e!==Sr){Sr=e;for(let t of tn)try{t(e)}catch(n){console.warn("Triage sync status listener:",n)}}}var nn=0,O=new Map;function kr(e){for(let t of O.values())if(t.workspaceTag===e)return t;return null}function ge(e){return O.get(e.workspaceId)===e}function Tr(e){if(e.key){try{e.key.fill(0)}catch{}e.key=null}if(e.signingKey=null,e.verifyingKey=null,e.objstoreResourceWaiters.length>0){let t=e.objstoreResourceWaiters.splice(0);for(let n of t)try{n([])}catch{}}}function Rr(e){let t=new Set,n=Je().find(o=>o.id===e);if(!n)return t;let r=new Set(n.reports??[]);for(let o of Er.reports)if(r.has(o.fileName))for(let s of o.groups)for(let i of s){let a=i.id??String(i._id);cs.test(a)||t.add(a)}return t}function sn(e){let t=Rr(e.workspaceId),n=[];for(let o of t)e.ids.has(o)||n.push(o);let r=[];return n.length>0&&(r=zt(e.baseState,n)),e.ids=t,{conflicts:r,hydrated:n.length>0}}function fs(){let e=ht();e.kind==="unknown-version"?We(!0):(e.kind==="v1"||e.kind==="legacy")&&We(!1),rr(),se.resetCachedReplayGuard()}function jr(e){if(!e||!he)return;let t=he;mt(n=>{n[e.workspaceId]={serverUrl:t,baseRevision:e.baseRevision,savesSinceKeyframe:e.savesSinceKeyframe??0,baseState:e.baseState}}).catch(n=>{console.warn("Triage sync: persistSession lock failed:",n)})}function rn(e){let t=Je().find(r=>r.id===e.workspaceId);if(!t){e.error="workspace no longer exists",te();return}let n=(e.keyDerivationGen??0)+1;e.keyDerivationGen=n,(async()=>{try{let[r,o]=await Promise.all([Fn(t.privateKey),rt(t.privateKey,e.workspaceId)]);if(O.get(e.workspaceId)!==e||e.keyDerivationGen!==n)return;if(e.key=r,e.signingKey=o.privateKey,e.verifyingKey=o.publicKey,e.workspaceTag=o.publicKeyB64,se.getSocket()?.readyState!==WebSocket.OPEN){Ee();return}Me(e),le(e),te()}catch(r){console.warn("Triage sync: key derivation failed:",r),O.get(e.workspaceId)===e&&e.keyDerivationGen===n&&(e.error=`key derivation failed: ${r instanceof Error?r.message:String(r)}`,te())}})()}function wt(e){return se.send(e)}function ds(e){if(!se.isSse()){wt(e);return}gs(e).then(t=>(t&&wt(e),null)).catch(()=>{wt(e)})}async function gs(e){if(!he)return!0;let t;try{t=sr(he)}catch{return!0}let n;try{n=await globalThis.fetch(t,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}catch{return!0}let r=e.workspaceTag,o=e.base??null;if(n.status===401)return!0;if(n.ok){let s=null;try{s=await n.json()}catch{return!0}return!s||typeof s.id!="string"?!0:(ze({type:"workspace-save-ack",workspaceTag:r,base:o,id:s.id}),!1)}if(n.status===409){let s=null;try{s=await n.json()}catch{return!0}let i=s&&Array.isArray(s.revisions)?s.revisions:[];return ze({type:"workspace-state",workspaceTag:r,revisions:i}),ze({type:"workspace-save-error",workspaceTag:r,base:o,reason:"stale-base"}),!1}return n.status===413?(ze({type:"workspace-save-error",workspaceTag:r,base:o,reason:"too-large"}),!1):!0}function Me(e,t=!1){if(!e)return;let n=se.getSocket();if(!n||n.readyState!==WebSocket.OPEN||!t&&e.subscribed||!e.signingKey||!e.workspaceTag)return;let r=se.getNonce();if(r==null)return;let o=e.baseRevision,s=n,i=e.signingKey,a=e.workspaceTag;(async()=>{try{let f=await Hn(i,a,o,r);if(O.get(e.workspaceId)!==e||e.workspaceTag!==a||se.getSocket()!==s||se.getNonce()!==r)return;e.subscribed=!0,wt({type:"workspace-subscribe",workspaceTag:a,from:o,signature:f})}catch(f){console.warn("Triage sync: subscribe sign failed:",f)}})()}function le(e){if(!e||e.error)return;if(e.pending||e.encrypting){e.pendingSave=!0;return}if(!e.key||!e.signingKey||!e.workspaceTag){e.pendingSave=!0;return}sn(e),e.localState=Ke(e.baseState,e.ids);let t=se.getSocket();if(!t||t.readyState!==WebSocket.OPEN)return;let n=(e.savesSinceKeyframe??0)>=xe,r=n?Object.create(null):e.baseState,o=Vt(r,e.localState);if(dr(o)&&!n)return;let s=e.baseRevision,i=e.key,a=e.signingKey,f=e.workspaceTag;e.encrypting=!0,(async()=>{try{let c=Ct(f,s),{nonce:p,ciphertext:w}=await Wn(i,o,c),x={publicKeyB64:f,base:s,keyframe:n,nonceB64:p,ciphertextB64:w},A=await $n(a,x),y=await Ot(x);if(O.get(e.workspaceId)!==e||e.workspaceTag!==f)return;if(e.baseRevision!==s){e.pendingSave=!0;return}e.pending={base:s,id:y,changeset:o,keyframe:n},e.pendingSave=!1;let T={type:"workspace-save",workspaceTag:f,base:s,nonce:p,ciphertext:w,signature:A};n&&(T.keyframe=!0),ds(T),e.consecutiveFailures=0,e.error&&(e.error=null,te())}catch(c){console.warn("Triage sync: encrypt/sign failed:",c),O.get(e.workspaceId)===e&&(e.consecutiveFailures=(e.consecutiveFailures??0)+1,e.consecutiveFailures>=ls&&(e.error=`encrypt/sign failed: ${c instanceof Error?c.message:String(c)}`,te()))}finally{O.get(e.workspaceId)===e&&(e.encrypting=!1,!e.error&&e.pendingSave&&!e.pending&&(e.pendingSave=!1,le(e)))}})()}async function ps(e,t){for(let n of t){if(!n||typeof n!="object"||typeof n.id=="string"&&n.id===e.baseRevision)continue;let r=e.baseRevision,o=!!n.keyframe;if(!(r==null?n.base==null||o:n.base===r))return console.warn(`Triage sync: chain base mismatch (expected ${r}, got ${n.base})`),!1;if(typeof n.signature!="string"||typeof n.nonce!="string"||typeof n.ciphertext!="string"||typeof n.id!="string")return console.warn("Triage sync: revision missing signature/nonce/ciphertext/id; resyncing"),e.savesSinceKeyframe=xe,!1;if(!e.workspaceTag||!e.verifyingKey||!e.key)return!1;let i=typeof n.base=="string"?n.base:null,a={publicKeyB64:e.workspaceTag,base:i,keyframe:o,nonceB64:n.nonce,ciphertextB64:n.ciphertext},f=await _n(e.verifyingKey,a,n.signature);if(!ge(e))return!1;if(!f)return console.warn("Triage sync: revision signature did not verify; resyncing"),e.savesSinceKeyframe=xe,!1;let c=await Ot(a);if(!ge(e))return!1;if(n.id!==c)return console.warn("Triage sync: revision id does not match content hash; resyncing"),e.savesSinceKeyframe=xe,!1;let p;try{let x=Ct(e.workspaceTag,i);p=await Vn(e.key,n.nonce,n.ciphertext,x)}catch(x){return console.warn("Triage sync: decrypt failed; resyncing",x),e.savesSinceKeyframe=xe,!1}if(!ge(e))return!1;let w=o?Object.create(null):e.baseState;e.baseState=dt(w,p??{}),e.baseRevision=n.id,o?e.savesSinceKeyframe=0:e.savesSinceKeyframe=Math.min((e.savesSinceKeyframe??0)+1,xe)}return!0}async function Or(e,t,n=[],r=null){if(ge(e)){e.localState=dt(e.baseState,t),nn++;try{mr(e.localState,e.ids),r&&n.length>0&&(qt(n,r),e.localState=Ke(e.baseState,e.ids)),jr(e),await vt()}finally{nn--}if(ge(e)){on();for(let o of O.values())o!==e&&le(o)}}}function Cr(e){return sn(e),e.localState=Ke(e.baseState,e.ids),Vt(e.baseState,e.localState)}async function ys(e,t){if(e.pending&&t.base===e.pending.base&&typeof t.id=="string"&&t.id===e.pending.id){let n=Cr(e),r=e.pending.keyframe?Object.create(null):e.baseState;if(e.baseState=dt(r,e.pending.changeset),e.baseRevision=t.id,e.savesSinceKeyframe=e.pending.keyframe?0:Math.min((e.savesSinceKeyframe??0)+1,xe),e.pending=null,await Or(e,n),!ge(e))return;(e.pendingSave||!Wt(e.localState,e.baseState))&&(e.pendingSave=!1,le(e));return}if(e.pending){let n=typeof t.id=="string"?t.id.slice(0,8):String(t.id);console.warn(`Triage sync: ack mismatch (pending ${e.pending.base}/${e.pending.id.slice(0,8)}, ack ${t.base}/${n})`);return}if(t.id!==e.baseRevision){let n=typeof t.id=="string"?t.id.slice(0,8):String(t.id);console.warn(`Triage sync: late ack for base=${t.base} id=${n}\u2026; pending was already cleared`),e.pendingSave=!0,le(e)}}async function hs(e,t){if(!Array.isArray(t)||t.length===0||!e.key)return;let n=Cr(e),r=e.baseRevision,o=e.baseState,s=await ps(e,t);if(!ge(e))return;if(!s){if(!e.resyncAttempted){e.resyncAttempted=!0,console.warn("Triage sync: requesting catch-up from last known baseRevision"),Me(e,!0);return}console.warn("Triage sync: catch-up also broke continuity; full state push"),e.baseRevision=null,e.baseState=Object.create(null),e.pending=null,e.pendingSave=!1,e.resyncAttempted=!1,jr(e),on(),le(e);return}if(e.resyncAttempted=!1,e.pending&&(e.pending=null,e.pendingSave=!0),e.baseRevision===r){if(!ge(e))return;e.pendingSave&&(e.pendingSave=!1,le(e));return}let i=ur(n,o,e.baseState),a=null;if(i.length>0&&Ge){try{a=await Ge(i,e.baseState,"chain")??null}catch(f){console.warn("Triage sync: chain-conflict resolver failed:",f)}if(!ge(e))return}await Or(e,n,i,a),ge(e)&&(e.pendingSave||!Wt(e.localState,e.baseState))&&(e.pendingSave=!1,le(e))}async function ms(e){if(e.type==="authenticated"){for(let n of O.values())Me(n),le(n);return}if(e.type==="unauthorized"){if(e.kind==="gated"){if(typeof e.workspaceTag=="string"){let n=kr(e.workspaceTag);n&&typeof e.resourceTag!="string"&&bs(n,e)}se.runAuthFlow().catch(n=>{console.warn("Triage sync: auth flow failed:",n)})}return}if(typeof e.workspaceTag!="string")return;let t=kr(e.workspaceTag);if(t){if(e.type==="workspace-save-ack")await ys(t,e);else if(e.type==="workspace-state")await hs(t,e.revisions);else if(e.type==="workspace-save-error")vs(t,e);else if(e.type==="workspace-subscribed"){t.subscribeAcked=!0;let n=Array.isArray(e.resources)?e.resources:[],r=t.objstoreResourceWaiters.splice(0);for(let o of r)try{o(n)}catch{}te()}}}function bs(e,t){e.pending&&(typeof t.base!="string"&&t.base!==null||t.base===e.pending.base&&(e.pending=null,e.pendingSave=!0))}var ws=/^[\w-]+$/u;function vs(e,t){if(!e.pending||typeof t.base!="string"&&t.base!==null||t.base!==e.pending.base)return;let n=t.reason,r=typeof n=="string"&&n.length>0&&n.length<=64&&ws.test(n)?n:"rejected";if(e.pending=null,lr.has(r)){e.pendingSave=!0;return}e.consecutiveFailures=(e.consecutiveFailures??0)+1,e.error=`server rejected save: ${r}`,te()}var xr=Promise.resolve();function ze(e){xr=xr.then(()=>ms(e)).catch(t=>{console.warn("Triage sync handler error:",t)})}function Ss(e){for(let t of O.values())t.pending=null,t.pendingSave=!1,Me(t),le(t);te()}function ks(e){for(let t of O.values())t.pending=null,t.subscribed=!1,t.subscribeAcked=!1,t.resyncAttempted=!1,t.pendingSave=!0;te()}se.addConsumer({onMessage:ze,onConnected:Ss,onDisconnected:ks});function Ee(){St()?Ve||(Ve=se.acquire()):Ve&&(Ve.release(),Ve=null)}function Ts(e){on=typeof e=="function"?e:()=>{}}function xs(e){Ge=typeof e=="function"?e:null}function Es(e){cr(e)}function Qt(e){let t=e.error!=null;e.error=null,e.consecutiveFailures=0,t&&(!e.key||!e.signingKey)&&rn(e)}function Zt(e){e.pending=null,e.pendingSave=!1,e.encrypting=!1,e.subscribed=!1,e.subscribeAcked=!1,e.resyncAttempted=!1}var ve={setServerUrl(e){let t=(e??"").trim();if(t===he)return;let n=he;he=t,t&&Xt(t),n&&t&&n!==t&&He(null).catch(r=>{console.warn("Triage sync: failed to drop cached auth password on server change:",r)}),se.setServerUrl(t);for(let r of O.values()){Zt(r);let o=t?Yt(r.workspaceId,t):null;r.baseRevision=o?.baseRevision??null,r.baseState=o?.baseState??Object.create(null),r.savesSinceKeyframe=o?.savesSinceKeyframe??0,r.localState=Ke(r.baseState,r.ids),Qt(r)}Ee(),te()},setEnabled(e){let t=!!e;if(t!==qe){if(qe=t,Ar(Pr,t?"1":"0").catch(n=>{console.warn("Triage sync: could not persist user-enabled:",n)}),St())for(let n of O.values())Qt(n);else for(let n of O.values())Zt(n);Ee(),te()}},isEnabled(){return qe},setForcedOff(e){let t=!!e;if(t!==en){if(en=t,St())for(let n of O.values())Qt(n);else for(let n of O.values())Zt(n);Ee(),te()}},getServerUrl(){return he},get connected(){return se.getSocket()?.readyState===WebSocket.OPEN},get status(){return Br()},onStatusChange(e){return tn.add(e),()=>tn.delete(e)},notify(){if(!(nn>0))for(let e of O.values())le(e)},ensureSubscription(e){let t=O.has(e);ve.openSession(e);let n=O.get(e);if(!n)return null;let r=new Promise(o=>{n.objstoreResourceWaiters.push(o)});return t&&Me(n,!0),{workspaceId:e,workspaceTag:n.workspaceTag,resources:r}},openSession(e){if(!e||O.has(e)||!Je().find(i=>i.id===e))return;let n=Rr(e),r=Yt(e,he),o=r?.baseState??Object.create(null);zt(o,n);let s={workspaceId:e,workspaceTag:null,signingKey:null,verifyingKey:null,ids:n,baseRevision:r?.baseRevision??null,baseState:o,savesSinceKeyframe:r?.savesSinceKeyframe??0,localState:Ke(o,n),pending:null,pendingSave:!1,key:null,encrypting:!1,subscribed:!1,subscribeAcked:!1,resyncAttempted:!1,consecutiveFailures:0,error:null,objstoreResourceWaiters:[]};O.set(e,s),rn(s),Ee(),te()},closeSession(e){if(e==null){for(let t of O.values())Tr(t);O.clear()}else{let t=O.get(e);t&&Tr(t),O.delete(e)}te()},refreshSession(e){let t=O.get(e);if(!t){console.debug("triage-sync: refreshSession bail \u2014 no session for",e,"(caller must openSession first)");return}Ur(t)},sessionInfo(e){let t=O.get(e);return t?{workspaceId:t.workspaceId,workspaceTag:t.workspaceTag,baseRevision:t.baseRevision,pending:t.pending&&{base:t.pending.base,keyframe:t.pending.keyframe},pendingSave:t.pendingSave,keyReady:t.key!==null,encrypting:t.encrypting,tracked:t.ids.size,savesSinceKeyframe:t.savesSinceKeyframe??0,error:t.error??null}:null},get openSessions(){return[...O.keys()].map(e=>this.sessionInfo(e)).filter(e=>e!==null)},dismissError(e){let t=e==null?[...O.keys()]:[e],n=!1;for(let r of t){let o=O.get(r);!o||!o.error||(o.error=null,o.consecutiveFailures=0,n=!0,!o.key||!o.signingKey?rn(o):se.getSocket()?.readyState===WebSocket.OPEN&&(Me(o),le(o)))}n&&te()},get persistenceDegraded(){return br()},onPersistenceDegraded(e){return wr(e)}};at(e=>{Er=e.state,Je=e.listWorkspaces,vt=e.saveTriage,vr=e.getSecureItem,Ar=e.setSecureItem,e.onSecureStorageHydrated(fs);try{localStorage.removeItem(as),vr(Pr)==="0"&&(qe=!1),Ee()}catch{}e.onWorkspaceDeleted(t=>{let n=O.delete(t);bt(t).catch(r=>{console.warn("Triage sync: dropPersistedSession lock failed:",r)}),Ee(),n&&te()}),e.onWorkspacePrivateKeyChanged(t=>{let n=O.get(t);if(!n){bt(t).catch(r=>{console.warn("Triage sync: dropPersistedSession lock failed:",r)});return}n.signingKey=null,n.key=null,n.verifyingKey=null,n.workspaceTag=null,n.keyDerivationGen=(n.keyDerivationGen??0)+1,(async()=>{await bt(t),O.delete(t),ve.openSession(t),te()})().catch(r=>{console.warn("Triage sync: privateKey rotation IIFE failed:",r),O.delete(t),te()})}),e.onReportMembershipChanged(t=>{ve.openSession(t);let n=O.get(t);n&&Ur(n)}),Xt()});function Ur(e){let{conflicts:t,hydrated:n}=sn(e);(async()=>{if(t.length===0){n?await vt():le(e);return}let r=null;if(Ge)try{r=await Ge(t,e.baseState,"attach")}catch(o){console.warn("Triage sync: hydration conflict resolver failed:",o)}ge(e)&&(r&&qt(t,r),await vt())})().catch(r=>{console.warn("Triage sync: refreshAndPropagate failed:",r)})}async function an(e){let t=await crypto.subtle.digest("SHA-512",e);return`sha512-${new Uint8Array(t).toBase64()}`}var Ae,un,fn,gn,pn,yn,Ze,Tt,hn,Mr,mn,bn,W=new Map,dn=new Set,As="deepview.objstore-presence.";function wn(e){return As+e}function Ps(e){try{let t=localStorage.getItem(wn(e));if(!t)return null;let n=JSON.parse(t);return!n||typeof n!="object"?null:{names:n.names&&typeof n.names=="object"?n.names:{},bundles:n.bundles&&typeof n.bundles=="object"?n.bundles:{},bundleNames:n.bundleNames&&typeof n.bundleNames=="object"?n.bundleNames:{},localVersions:n.localVersions&&typeof n.localVersions=="object"?n.localVersions:{}}}catch{return null}}function Fe(e,t){try{let n={names:Object.fromEntries(t.remoteNameByTag),bundles:Object.fromEntries(t.remoteBundleByTag),bundleNames:Object.fromEntries(t.remoteBundleNameByIntegrity),localVersions:Object.fromEntries(t.localVersions)};localStorage.setItem(wn(e),JSON.stringify(n))}catch(n){console.warn(`objstore-presence: cache persist failed for ${e}:`,n)}}function Lr(e){try{localStorage.removeItem(wn(e))}catch{}}var cn=null;function Bs(e){return cn||(cn=ar({serverUrl:"",httpOrigin:e,transport:ft()})),cn}var Ye=new Set,Xe=new Set;function me(){for(let e of dn)try{e()}catch{}}function Rs(e){if(e==null)return"";if(e instanceof Error&&e.message)return`: ${e.message}`;if(typeof e=="string"&&e)return`: ${e}`;if(typeof e=="object"&&typeof e.message=="string"&&e.message)return`: ${e.message}`;try{return`: ${String(e)}`}catch{return""}}var Nr=256;function Ir(e){return typeof e!="string"?"":e.length<=Nr?e:e.slice(0,Nr)}function js(e){try{let t=new URL(e);return t.protocol=t.protocol==="wss:"?"https:":"http:",t.pathname="/",t.search="",t.hash="",t.origin}catch{return null}}function Ie(e){if(W.has(e))return;let t=Ae().find(s=>s.id===e);if(!t)return;let n=ve.ensureSubscription(e);if(!n)return;let r={workspaceId:e,session:null,keys:null,remoteTags:new Set,fileTags:new Map,bundleTags:new Map,remoteNameByTag:new Map,remoteBundleByTag:new Map,remoteBundleNameByIntegrity:new Map,remoteVersions:new Map,localVersions:new Map,inFlight:new Map,err:null,disposed:!1,ready:null};W.set(e,r),r.ready=(async()=>{if(r.keys=await Ut(t.privateKey,t.id),r.disposed)return;let s=new Map;for(let c of t.reports??[]){let p=await fe(r.keys.tagKey,c);r.fileTags.set(c,p),s.set(p,c)}if(r.disposed)return;let i=new Map;for(let c of t.bundles??[]){let p=await ye(r.keys.tagKey,c);r.bundleTags.set(c,p),i.set(p,c)}if(r.disposed)return;try{let c=await Ze();if(r.disposed)return;for(let p of c)r.bundleTags.has(p.integrity)&&r.remoteBundleNameByIntegrity.set(p.integrity,p.name)}catch(c){console.warn(`objstore-presence: listBundles failed during ${e} open:`,c)}me();let a=ve.getServerUrl();if(!a)return;let f=js(a);if(f)try{let p=await Bs(f).openWorkspace(r.keys,n);if(r.disposed){try{p.close()}catch{}return}r.session=p,o();let w=await p.list();if(r.disposed)return;for(let y of w){r.remoteTags.add(y.resourceTag);let T=r.remoteVersions.get(y.resourceTag);(T===void 0||y.version>T)&&r.remoteVersions.set(y.resourceTag,y.version)}let x=Ps(e),A=!1;if(x&&x.localVersions)for(let y of r.remoteTags){let T=x.localVersions[y];typeof T=="number"&&r.localVersions.set(y,T)}for(let y of r.remoteTags){let T=s.get(y);T!==void 0&&!r.remoteNameByTag.has(y)&&(r.remoteNameByTag.set(y,T),A=!0);let E=i.get(y);if(E!==void 0&&!r.remoteBundleByTag.has(y)&&(r.remoteBundleByTag.set(y,E),A=!0),x){let j=x.names[y];typeof j=="string"&&!r.remoteNameByTag.has(y)&&!r.remoteBundleByTag.has(y)&&(r.remoteNameByTag.set(y,j),r.fileTags.set(j,y),A=!0);let V=x.bundles[y];if(typeof V=="string"&&!r.remoteBundleByTag.has(y)&&!r.remoteNameByTag.has(y)){r.remoteBundleByTag.set(y,V),r.bundleTags.set(V,y);let ie=x.bundleNames[V];typeof ie=="string"&&!r.remoteBundleNameByIntegrity.has(V)&&r.remoteBundleNameByIntegrity.set(V,ie),A=!0}}}(A||x)&&Fe(e,r),me(),kt(r);for(let y of r.remoteTags){let T=r.localVersions.get(y),E=r.remoteVersions.get(y);typeof T!="number"||typeof E!="number"||E>T&&Kr(r,y).catch(()=>{})}}catch(c){r.err=c}})();function o(){let s=r.session;s.onPut(({resourceTag:i,version:a})=>{let f=r.remoteVersions.get(i),c=r.remoteTags.has(i)&&typeof f=="number"&&a>f;if(r.remoteTags.add(i),(f===void 0||a>f)&&r.remoteVersions.set(i,a),me(),c){Kr(r,i).catch(()=>{});return}kt(r)}),s.onDeleted(({resourceTag:i})=>{r.remoteTags.delete(i),r.remoteVersions.delete(i),r.localVersions.delete(i);let a=r.remoteNameByTag.get(i);r.remoteNameByTag.delete(i);let f=Ae().find(x=>x.id===e),c=f?.reports??[],p=f?.bundles??[];a&&!c.includes(a)&&r.fileTags.delete(a);let w=r.remoteBundleByTag.get(i);r.remoteBundleByTag.delete(i),w&&(r.remoteBundleNameByIntegrity.delete(w),p.includes(w)||r.bundleTags.delete(w)),Fe(e,r),me()})}r.ready.catch(()=>{})}function Qe(e){let t=W.get(e);if(t){t.disposed=!0;try{t.session?.close()}catch{}if(t.keys){try{t.keys.contentKey.fill(0)}catch{}try{t.keys.tagKey.fill(0)}catch{}t.keys=null}W.delete(e),me()}}at(e=>{Ae=e.listWorkspaces,un=e.addReportToWorkspace,fn=e.addBundleToWorkspace,gn=e.analyzeContent,pn=e.setCount,yn=e.gunzipBytes,Ze=e.listBundles,Tt=e.listFiles,hn=e.readBundle,Mr=e.readFileBytes,mn=e.saveBundle,bn=e.saveFileBytes,e.onReportMembershipChanged(t=>{W.has(t)||Ie(t);let n=W.get(t);if(!n)return;let r=Ae().find(o=>o.id===t);if(r)for(let o of r.reports??[])n.fileTags.has(o)||Us(t,o).catch(()=>{})}),e.onBundleMembershipChanged(t=>{W.has(t)||Ie(t);let n=W.get(t);if(!n)return;let r=Ae().find(o=>o.id===t);if(r)for(let o of r.bundles??[])n.bundleTags.has(o)||Ns(t,o).catch(()=>{})}),e.onWorkspaceDeleted(t=>{Qe(t),Lr(t)}),e.onWorkspacePrivateKeyChanged(t=>{W.has(t)&&(Qe(t),Lr(t),Ie(t))})});function Os(){return Array.from(W.keys())}function Cs(e,t){let n=W.get(e);if(!n)return!1;let r=n.fileTags.get(t);return r?n.remoteTags.has(r):!1}async function Us(e,t){let n=W.get(e);!n||n.fileTags.has(t)||(n.ready&&!n.keys&&await n.ready,n.keys&&(n.fileTags.set(t,await fe(n.keys.tagKey,t)),n.disposed||me()))}function Ls(e,t){let n=W.get(e);if(!n)return!1;let r=n.bundleTags.get(t);return r?n.remoteTags.has(r):!1}async function Ns(e,t){let n=W.get(e);!n||n.bundleTags.has(t)||(n.ready&&!n.keys&&await n.ready,n.keys&&(n.bundleTags.set(t,await ye(n.keys.tagKey,t)),n.disposed||me()))}function Ks(e){return dn.add(e),()=>dn.delete(e)}function Ms(e){return Ye.add(e),()=>Ye.delete(e)}function Is(e){return Xe.add(e),()=>Xe.delete(e)}function Fs(e){let t=W.get(e);return t?t.remoteTags.size:0}async function Ds(e){let t=W.get(e);return t?(t.ready&&!t.session&&await t.ready,t.session?(await kt(t),Array.from(t.remoteNameByTag.values())):[]):[]}async function $s(e){let t=W.get(e);return t?(t.ready&&!t.session&&await t.ready,t.session?(await kt(t),Array.from(t.remoteBundleByTag.values())):[]):[]}function Hs(e,t){let n=W.get(e);if(n)return n.remoteBundleNameByIntegrity.get(t)}async function kt(e){if(!e.session||e.disposed)return;let t=Ae().find(i=>i.id===e.workspaceId),n=new Set(t?.reports??[]),r=new Set(t?.bundles??[]),o=new Set;try{o=new Set(await Tt())}catch(i){console.warn(`objstore-presence: listFiles failed during discovery for "${e.workspaceId}":`,i)}if(e.disposed||!e.session)return;let s=[];for(let i of e.remoteTags){let a=e.remoteNameByTag.get(i);if(a!==void 0&&n.has(a)&&o.has(a))continue;if(e.remoteBundleByTag.has(i)){let c=e.remoteBundleByTag.get(i);if(e.remoteBundleNameByIntegrity.has(c)&&r.has(c))continue}let f=e.inFlight.get(i);f||(f=e.session.fetchByTag(i).then(async c=>(e.inFlight.delete(i),!c||e.disposed||!e.remoteTags.has(i)?null:c.kind==="bundle"?(e.remoteBundleByTag.set(i,c.integrity),e.bundleTags.set(c.integrity,i),c.name&&e.remoteBundleNameByIntegrity.set(c.integrity,c.name),await Ws(e,i,c.integrity,c.name,c.content),null):(e.remoteNameByTag.set(i,c.fileName),e.fileTags.set(c.fileName,i),await _s(e,i,c.fileName,c.content),null)),()=>(e.inFlight.delete(i),null)),e.inFlight.set(i,f)),s.push(f)}s.length!==0&&(await Promise.all(s),!e.disposed&&(Fe(e.workspaceId,e),me()))}async function _s(e,t,n,r){if(e.disposed||!e.remoteTags.has(t))return;let o=Ae().find(c=>c.id===e.workspaceId),s=!!(o&&Array.isArray(o.reports)&&o.reports.includes(n)),i;try{let c=await Tt();if(e.disposed||!e.remoteTags.has(t))return;i=c.includes(n)}catch(c){console.warn(`auto-download: listFiles failed before saving "${n}":`,c);return}if(i){if(s||e.disposed||!e.remoteTags.has(t))return;try{await un(n,e.workspaceId)}catch(c){console.warn(`auto-download: attaching local "${n}" to workspace "${e.workspaceId}" failed:`,c);return}if(e.disposed)return;for(let c of Ye)try{c(e.workspaceId,n)}catch{}return}let a;try{a=Ce(await yn(r))}catch(c){console.warn(`auto-download: gunzip/decode of "${n}" failed (likely forged peer payload):`,c);return}if(e.disposed||!e.remoteTags.has(t))return;let f=gn(a);if(f.recognized){try{if(await bn(n,r),e.disposed||!e.remoteTags.has(t))return;pn(n,f.count,f.source);let c=e.remoteVersions.get(t);if(typeof c=="number"&&e.localVersions.set(t,c),!e.remoteTags.has(t))return;await un(n,e.workspaceId),Fe(e.workspaceId,e)}catch(c){console.warn(`auto-download: persisting "${n}" to workspace "${e.workspaceId}" failed:`,c);return}if(!e.disposed)for(let c of Ye)try{c(e.workspaceId,n)}catch{}}}async function Kr(e,t){if(e.disposed||!e.remoteTags.has(t))return;let n;try{n=await e.session.fetchByTag(t)}catch(a){console.warn(`replace-refetch: fetchByTag failed for tag in workspace "${e.workspaceId}":`,a);return}if(!n||e.disposed||!e.remoteTags.has(t)||n.kind==="bundle")return;let r=n.fileName,o=n.content,s;try{s=Ce(await yn(o))}catch(a){console.warn(`replace-refetch: gunzip/decode of "${r}" failed (likely forged peer payload):`,a);return}if(e.disposed||!e.remoteTags.has(t))return;let i=gn(s);if(!i.recognized){console.warn(`replace-refetch: peer-uploaded replacement for "${r}" did not analyze as a recognized report \u2014 refusing to overwrite local copy`);return}try{if(await bn(r,o),e.disposed)return;pn(r,i.count,i.source),typeof n.version=="number"&&e.localVersions.set(t,n.version),Fe(e.workspaceId,e)}catch(a){console.warn(`replace-refetch: saveFileBytes failed for "${r}":`,a);return}if(!e.disposed)for(let a of Ye)try{a(e.workspaceId,r)}catch{}}async function Ws(e,t,n,r,o){if(e.disposed||!e.remoteTags.has(t))return;let s;try{s=await Ze()}catch(c){console.warn(`auto-download: listBundles failed before saving bundle "${n}":`,c);return}if(e.disposed||!e.remoteTags.has(t))return;if(s.some(c=>c.integrity===n)){try{await fn(n,e.workspaceId)}catch(p){console.warn("auto-download: attach pre-existing bundle failed:",p);return}if(e.disposed)return;let c=s.find(p=>p.integrity===n)?.name??"";for(let p of Xe)try{p(e.workspaceId,n,c)}catch{}return}let i=await an(o);if(e.disposed||!e.remoteTags.has(t))return;if(i!==n){console.warn(`auto-download: bundle integrity mismatch (claimed ${n}, got ${i}) \u2014 refusing to save`);return}let a=r&&r.length>0?r:`bundle-${n.slice(7,15)}`,f=Ir(a);try{if(await mn(f,o),e.disposed||!e.remoteTags.has(t))return;await fn(n,e.workspaceId)}catch(c){console.warn(`auto-download: persisting bundle "${n}" to workspace "${e.workspaceId}" failed:`,c);return}if(!e.disposed)for(let c of Xe)try{c(e.workspaceId,n,f)}catch{}}async function Pe(e){if(e.ready&&!e.session&&await e.ready,!e.session)throw new Error(`Objstore session is not connected${Rs(e.err)}`)}async function xt(e){let t=await e(null);return!t.ok&&t.reason==="conflict"&&t.current&&(t=await e(t.current)),t}async function Vs(e,t){let n=W.get(e);if(!n)throw new Error(`Workspace ${e} is not open`);return await Pe(n),n.session.fetch(t)}async function Fr(e,t,n){let r=W.get(e);if(!r)throw new Error(`Workspace ${e} is not open`);await Pe(r);let o=await xt(s=>r.session.put({fileName:t,content:n,prev:s}));if(o.ok&&r.keys&&!r.disposed)try{let s=r.fileTags.get(t)??await fe(r.keys.tagKey,t);r.fileTags.set(t,s),r.remoteVersions.set(s,o.meta.version),r.localVersions.set(s,o.meta.version),Fe(r.workspaceId,r)}catch{}return o}async function zs(e,t){let n=!1;W.has(e)||(Ie(e),n=!0);try{let r=W.get(e);if(!r)throw new Error(`Workspace ${e} could not be opened \u2014 not in listWorkspaces()?`);if(await Pe(r),!r.keys)throw new Error("Objstore session keys missing \u2014 derivation failed during open");r.fileTags.has(t)||r.fileTags.set(t,await fe(r.keys.tagKey,t));let o=r.fileTags.get(t),s=await xt(i=>r.session.delete(t,i));return s.ok&&(r.remoteTags.delete(o),r.remoteNameByTag.delete(o),r.remoteVersions.delete(o),r.localVersions.delete(o),me()),s}finally{n&&Qe(e)}}async function Dr(e,t){let n=W.get(e);if(!n)throw new Error(`Workspace ${e} is not open`);await Pe(n);let r=await hn(t),i=(await Ze()).find(a=>a.integrity===t)?.name??`bundle-${t.slice(7,15)}`;return await xt(a=>n.session.putBundle({integrity:t,name:i,content:r,prev:a}))}async function qs(e,t){let n=W.get(e);if(!n)throw new Error(`Workspace ${e} is not open`);await Pe(n);let r=await n.session.fetchBundle(t);if(!r)return{ok:!1,reason:"not-found"};if(await an(r.content)!==t)return{ok:!1,reason:"integrity-mismatch"};let s=r.name&&r.name.length>0?r.name:`bundle-${t.slice(7,15)}`,i=Ir(s);await mn(i,r.content);for(let a of Xe)try{a(e,t,i)}catch{}return{ok:!0,integrity:t,name:i}}async function Gs(e,t){let n=!1;W.has(e)||(Ie(e),n=!0);try{let r=W.get(e);if(!r)throw new Error(`Workspace ${e} could not be opened \u2014 not in listWorkspaces()?`);if(await Pe(r),!r.keys)throw new Error("Objstore session keys missing \u2014 derivation failed during open");r.bundleTags.has(t)||r.bundleTags.set(t,await ye(r.keys.tagKey,t));let o=r.bundleTags.get(t),s=await xt(i=>r.session.deleteBundle(t,i));return s.ok&&(r.remoteTags.delete(o),r.remoteBundleByTag.delete(o),me()),s}finally{n&&Qe(e)}}async function Js(e,{onList:t,onItem:n}={}){let r=W.get(e);if(!r)throw new Error(`Workspace ${e} is not open`);if(await Pe(r),!r.keys)throw new Error("Objstore session keys missing \u2014 derivation failed during open");let o=r.keys.tagKey,s=new Set,i=r.session.onDeleted(a=>{s.add(a.resourceTag)});try{let a=await Ys(r,e),f=await oi(),c=await si(),p=new Map;for(let y of f)p.set(await fe(o,y),y);let w=new Map;for(let y of c)w.set(await ye(o,y.integrity),y.integrity);let x=a.map(y=>{let T=p.get(y.resourceTag),E=w.get(y.resourceTag);return{resourceTag:y.resourceTag,kind:ti(r,y.resourceTag,T,E),label:ni(r,y.resourceTag,T,E),contentLength:y.contentLength,reportName:T,bundleIntegrity:E,identifier:T??E,status:"checking"}});if(typeof t=="function")try{t(x.map(ln))}catch{}let A={good:0,reuploaded:0,failed:0,"check-failed":0,missing:0};for(let y of x)if(y.status=await Qs(r,e,y,s),A[y.status]+=1,typeof n=="function")try{n(ln(y))}catch{}return{items:x.map(ln),counts:A}}finally{i()}}async function Ys(e,t){try{let n=ve.ensureSubscription(t);if(n){let r=await ri(n.resources,1e4);if(Array.isArray(r))return Xs(r)}}catch(n){console.warn(`objstore-recovery: fresh DB listing for ${t} failed; using cached inventory:`,n)}try{return(await e.session.list()).map(n=>({resourceTag:n.resourceTag,contentLength:n.contentLength}))}catch{return[]}}function Xs(e){let t=[];for(let n of e)!n||typeof n!="object"||typeof n.resourceTag=="string"&&t.push({resourceTag:n.resourceTag,contentLength:Number.isSafeInteger(n.contentLength)?n.contentLength:null});return t}async function Qs(e,t,n,r){let o;try{o=await e.session.fetchByTag(n.resourceTag)}catch(s){return n.detail=`verification fetch failed: ${s?.message??String(s)}`,"check-failed"}return o?(o.kind==="report"?(n.kind="report",n.label=o.fileName,n.identifier=o.fileName):(n.kind="bundle",n.label=o.name??n.label,n.bundleIntegrity=o.integrity,n.identifier=o.integrity),"good"):r.has(n.resourceTag)?"missing":n.reportName!==void 0?await Zs(t,n,r):n.bundleIntegrity!==void 0?await ei(t,n,r):"missing"}async function Zs(e,t,n){let r;try{r=await Mr(t.reportName)}catch{return"missing"}if(t.contentLength==null||qn(t.reportName,r.length)!==t.contentLength||n.has(t.resourceTag))return"missing";try{let o=await Fr(e,t.reportName,r);return o&&o.ok?"reuploaded":(t.detail=`re-upload rejected: ${o?.reason??"unknown"}`,"failed")}catch(o){return t.detail=`re-upload error: ${o?.message??String(o)}`,console.warn(`objstore-recovery: re-upload of "${t.reportName}" failed:`,o),"failed"}}async function ei(e,t,n){try{await hn(t.bundleIntegrity)}catch{return"missing"}if(n.has(t.resourceTag))return"missing";try{let r=await Dr(e,t.bundleIntegrity);return r&&r.ok?"reuploaded":(t.detail=`re-upload rejected: ${r?.reason??"unknown"}`,"failed")}catch(r){return t.detail=`re-upload error: ${r?.message??String(r)}`,console.warn(`objstore-recovery: bundle re-upload of "${t.bundleIntegrity}" failed:`,r),"failed"}}function ti(e,t,n,r){return n!==void 0?"report":r!==void 0||e.remoteBundleByTag.has(t)?"bundle":e.remoteNameByTag.has(t)?"report":"unknown"}function ni(e,t,n,r){if(n!==void 0)return n;if(r!==void 0)return e.remoteBundleNameByIntegrity.get(r)??r;let o=e.remoteNameByTag.get(t);if(o!==void 0)return o;let s=e.remoteBundleByTag.get(t);return s!==void 0?e.remoteBundleNameByIntegrity.get(s)??s:`${t.slice(0,10)}\u2026`}function ln(e){return{resourceTag:e.resourceTag,kind:e.kind,label:e.label,status:e.status,identifier:e.identifier,detail:e.detail}}function ri(e,t){let n,r=Promise.resolve(e);r.catch(()=>{});let o=new Promise((s,i)=>{n=setTimeout(()=>i(new Error(`objstore-recovery: timed out after ${t}ms`)),t)});return Promise.race([r,o]).finally(()=>clearTimeout(n))}async function oi(){try{return await Tt()}catch(e){return console.warn("objstore-recovery: listFiles failed; treating as no local reports:",e),[]}}async function si(){try{return await Ze()}catch(e){return console.warn("objstore-recovery: listBundles failed; treating as no local bundles:",e),[]}}export{Qe as closeWorkspace,Gs as deleteBundleFromRemote,zs as deleteFromRemote,$s as discoverRemoteBundleIntegrities,Ds as discoverRemoteFileNames,qs as fetchBundleFromRemote,Vs as fetchFile,Do as installSyncHost,Ls as isBundleInRemote,Cs as isInRemote,Ms as onAutoDownloaded,Is as onBundleAutoDownloaded,Ks as onChange,Ie as openWorkspace,Os as openWorkspaceIds,Dr as putBundleToRemote,Fr as putFile,Js as recheckRemoteStorage,Hs as remoteBundleName,Fs as remoteCount,Es as setAuthenticationResolver,xs as setHydrationConflictResolver,Ts as setRedraw,ve as triageSync};
17
+ `)})}return n}},ct=class e extends EventTarget{static CONNECTING=0;static OPEN=1;static CLOSING=2;static CLOSED=3;CONNECTING=e.CONNECTING;OPEN=e.OPEN;CLOSING=e.CLOSING;CLOSED=e.CLOSED;readyState=e.CONNECTING;baseUrl;sessionId=null;cachedPassword=null;outbound=[];flushTimer=null;inFlightPost=null;activeReaders=new Set;fetchAbort=new AbortController;postSeq=0;downstreamWatchdog=null;constructor(t){super(),this.baseUrl=$o(t),this.scheduleFlush(!0)}send(t){if(this.readyState===e.CLOSED)throw new Error("sse-transport: send on closed transport");let n;try{n=JSON.parse(t)}catch(r){throw new Error(`sse-transport: send received non-JSON payload: ${r.message}`,{cause:r})}if(n.type==="authenticate"&&typeof n.password=="string"){this.cachedPassword=n.password,this.scheduleFlush();return}this.outbound.push(n),this.scheduleFlush()}close(){this.shutdown()}scheduleFlush(t=!1){if(this.readyState===e.CLOSED)return;if(this.flushTimer!=null)if(t)clearTimeout(this.flushTimer),this.flushTimer=null;else return;let n=t?0:Wo;this.flushTimer=setTimeout(()=>{this.flushTimer=null,this.flush()},n)}armDownstreamWatchdog(){this.readyState!==e.CLOSED&&(this.downstreamWatchdog!=null&&clearTimeout(this.downstreamWatchdog),this.downstreamWatchdog=setTimeout(()=>{this.downstreamWatchdog=null,this.readyState!==e.CLOSED&&(console.warn("sse-transport: no downstream activity within the liveness window; reconnecting"),this.shutdown())},_o),this.downstreamWatchdog.unref?.())}async flush(){if(this.readyState===e.CLOSED)return;if(this.inFlightPost){let i=new Promise(a=>{setTimeout(a,Ho)});await Promise.race([this.inFlightPost.catch(()=>{}),i])}if(this.readyState===e.CLOSED)return;let t=this.outbound;this.outbound=[];let n={};this.cachedPassword!=null&&(n.password=this.cachedPassword),t.length>0&&(n.frames=t);let r=this.sessionId==null?this.baseUrl:`${this.baseUrl}?id=${encodeURIComponent(this.sessionId)}`,o=++this.postSeq;this.armDownstreamWatchdog();let s=(async()=>{let i;try{i=await fetch(r,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(n),credentials:"same-origin",signal:this.fetchAbort.signal})}catch(f){this.readyState!==e.CLOSED&&console.warn("sse-transport: POST failed:",f),this.shutdown();return}if(!i.ok){this.readyState!==e.CLOSED&&console.warn(`sse-transport: POST ${i.status} ${i.statusText}; closing`),this.shutdown();return}let a=i.body;if(!a){this.shutdown();return}this.consumeStream(a,o)})();this.inFlightPost=s,s.finally(()=>{this.inFlightPost===s&&(this.inFlightPost=null)})}async consumeStream(t,n){let r=t.getReader();this.activeReaders.add(r);let o=new Ft,s=new TextDecoder,i=!1;try{for(;;){let{value:a,done:f}=await r.read();if(f){i=!0;break}if(this.readyState===e.CLOSED)return;n===this.postSeq&&this.armDownstreamWatchdog();let c=o.parse(s.decode(a,{stream:!0}));for(let p of c)this.dispatchEvent_(p)}if(this.readyState!==e.CLOSED){let a=s.decode();if(a.length>0)for(let f of o.parse(a))this.dispatchEvent_(f)}i&&this.readyState!==e.CLOSED&&n===this.postSeq&&(console.warn("sse-transport: live downstream closed without a close frame; reconnecting"),this.shutdown())}catch(a){this.readyState!==e.CLOSED&&n===this.postSeq&&(console.warn("sse-transport: stream read failed:",a),this.shutdown())}finally{this.activeReaders.delete(r);try{r.releaseLock()}catch{}}}dispatchEvent_(t){if(t.event==="session"){if(this.readyState===e.CLOSED)return;this.sessionId=t.data,this.readyState===e.CONNECTING&&(this.readyState=e.OPEN,this.dispatchEvent(new Event("open")));return}if(t.event==="close"){let n,r;try{let o=JSON.parse(t.data);typeof o.code=="number"&&(n=o.code),typeof o.reason=="string"&&(r=o.reason)}catch{}this.shutdown(n,r);return}if(t.event===""||t.event==="message"){if(this.readyState!==e.OPEN)return;this.dispatchEvent(new MessageEvent("message",{data:t.data}))}}shutdown(t,n){if(this.readyState===e.CLOSED)return;this.readyState=e.CLOSING,this.flushTimer!=null&&(clearTimeout(this.flushTimer),this.flushTimer=null),this.downstreamWatchdog!=null&&(clearTimeout(this.downstreamWatchdog),this.downstreamWatchdog=null);try{this.fetchAbort.abort()}catch{}for(let o of this.activeReaders)try{o.cancel().catch(()=>{})}catch{}this.activeReaders.clear(),this.readyState=e.CLOSED;let r=new Event("close");t!=null&&(r.code=t),n!=null&&(r.reason=n),this.dispatchEvent(r)}};var lt=1e3,Vo=3e4,Dt="session restarted";function ut(e){let t=e.serverUrl,n=e.pingIntervalMs??15e3,r=e.pongTimeoutMs??5e3,o=null,s=!1,i=null,a=0,f=!1,c=null,p=lt,b=null,x=null,A=null,y=!1,T=null,E=new Set;function O(){c&&(clearTimeout(c),c=null)}function V(){O(),!f&&a!==0&&t&&(c=setTimeout(()=>{c=null,N()},p),p=Math.min(p*2,Vo))}function ie(){ne(),!(n<=0)&&(s||(b=setInterval(()=>{!o||o.readyState!==o.OPEN||x||(K({type:"ping"}),x=setTimeout(()=>{x=null,console.warn("socket-transport: heartbeat timeout; closing socket");try{o?.close()}catch{}},r))},n)))}function ne(){b&&(clearInterval(b),b=null),x&&(clearTimeout(x),x=null)}function oe(w){for(let v of E)try{v.onDisconnected(w)}catch(H){console.warn("socket-transport: consumer.onDisconnected threw:",H)}}function Z(w){for(let v of E)try{v.onConnected(w)}catch(H){console.warn("socket-transport: consumer.onConnected threw:",H)}}function Y(w){for(let v of E)try{v.onMessage(w)}catch(H){console.warn("socket-transport: consumer.onMessage threw:",H)}}function Q(w){let v;try{let H=typeof w.data=="string"?w.data:new TextDecoder().decode(w.data);v=JSON.parse(H)}catch(H){console.warn("socket-transport: dropping malformed wire frame:",H);return}if(!(!v||typeof v!="object")){if(v.type==="pong"){x&&(clearTimeout(x),x=null);return}if(v.type==="challenge"){if(typeof v.nonce!="string")return;i!=null&&i!==v.nonce&&oe(Dt),i=v.nonce,Z(i);return}if(v.type==="authenticated"){U(!0),Y(v);return}if(v.type==="unauthorized"&&v.kind==="auth-failed"){U(!1);return}Y(v)}}function U(w){if(!T)return;let v=T;T=null,v(w)}function K(w){if(!o||o.readyState!==o.OPEN)return!1;try{return o.send(JSON.stringify(w)),!0}catch(v){return console.warn("socket-transport: send failed:",v),!1}}function L(w){return new Promise(v=>{T=v,K({type:"authenticate",password:w})||(T=null,v(!1))})}function $(){if(A)return A;if(!o||o.readyState!==o.OPEN)return Promise.resolve(!1);let w=o,v=(async()=>{await Promise.resolve();try{let H=nr();if(H!=null&&!y){y=!0;let g=await L(H);if(o!==w)return!1;if(g)return!0;try{await We(null)}catch(d){console.warn("socket-transport: failed to clear cached auth password:",d)}}let l=!0;for(;;){if(o!==w||!o||o.readyState!==o.OPEN||!e.authResolver)return!1;let g;try{g=await e.authResolver({retry:!l})}catch(m){return console.warn("socket-transport: authentication resolver threw:",m),!1}if(o!==w||(l=!1,g==null||g===""))return!1;let d=await L(g);if(o!==w)return!1;if(d){try{await We(g)}catch(m){console.warn("socket-transport: failed to cache auth password:",m)}return!0}}}finally{A=null}})();return A=v,v}function M(w){if(!o)return;let v=o;o=null,i=null,y=!1,U(!1),ne(),oe(w);try{v.close()}catch{}}function N(){f||o||a!==0&&t&&I(!1)}function I(w){if(f||a===0||!t)return;let v;try{v=w?new ct(t):new WebSocket(t)}catch(l){if(!w){console.warn("socket-transport: WebSocket constructor failed; trying SSE fallback:",l),I(!0);return}console.warn("socket-transport: SSE constructor failed:",l),V();return}o=v,s=w,i=null,y=!1;let H=!1;v.addEventListener("open",()=>{o===v&&(H=!0,p=lt,ie())}),v.addEventListener("message",l=>{o===v&&Q(l)}),v.addEventListener("close",l=>{if(o!==v)return;if(o=null,i=null,y=!1,U(!1),ne(),!H&&!w&&!f&&a>0){if(typeof fetch>"u"){oe("socket closed"),V();return}console.warn("socket-transport: WebSocket failed to open; falling back to SSE"),I(!0);return}l?.code===1001&&(p=lt),oe("socket closed"),!f&&a>0&&V()}),v.addEventListener("error",()=>{})}function F(){if(f)return{release(){}};a+=1,a===1&&!o&&N();let w=!1;return{release(){w||(w=!0,!f&&(a-=1,a===0&&(O(),p=lt,M("released"))))}}}function W(w){w!==t&&(t=w,o&&M("serverUrl changed"),a>0&&t&&N())}function D(w){E.add(w);let v=!1;return{remove(){v||(v=!0,E.delete(w))}}}function k(){f||(f=!0,O(),M("transport closed"),E.clear(),a=0)}function z(w){let{pingMs:v,pongMs:H}=w;typeof v=="number"&&v>=0&&(n=v),typeof H=="number"&&H>0&&(r=H),b&&ie()}function G(){y=!1}return{acquire:F,setServerUrl:W,addConsumer:D,send:K,getNonce:()=>i,getSocket:()=>o,isSse:()=>o!=null&&s,runAuthFlow:$,close:k,setHeartbeatTimings:z,resetCachedReplayGuard:G}}var $t=64,zo=5,ir=6,qo=25,Go=500;function Jo(e,t){if(!/^\/api\/objstore\/[\w-]+\/[\w-]+$/u.test(e))throw new TypeError(`objstore: urlPath rejected (unexpected shape): ${JSON.stringify(e)}`);let n=new URL(t).origin,r=new URL(e,n);if(r.origin!==n)throw new TypeError(`objstore: urlPath origin mismatch \u2014 expected ${n}, got ${r.origin}`);return r.href}function ar(e){let t=e.requestTimeoutMs??1e4,n=new URL(e.httpOrigin).origin,r=e.transport===void 0,o=e.transport??ut(e.authResolver===void 0?{serverUrl:e.serverUrl}:{serverUrl:e.serverUrl,authResolver:e.authResolver}),s=!1,i=new Map,a=new Map,f=[],c=[];function p(l,g,d,m){let u=l.seenVersions.get(g);(!u||u.incarnation!==d||m>u.version)&&l.seenVersions.set(g,{incarnation:d,version:m})}function b(l){l.connectedPromise=new Promise((g,d)=>{l.resolveConnected=g,l.rejectConnected=d}),l.connectedPromise.catch(()=>{})}function x(l){l.listedPromise=new Promise((g,d)=>{l.resolveListed=g,l.rejectListed=d}),l.listedPromise.catch(()=>{})}function A(l,g){l.inventory.clear();for(let d of g)l.inventory.set(d.resourceTag,{version:d.version,incarnation:d.incarnation,contentLength:d.contentLength}),p(l,d.resourceTag,d.incarnation,d.version);l.resolveListed()}function y(l){if(!Array.isArray(l))return[];let g=[];for(let d of l)Le(d)&&g.push(Ne(d));return g}function T(l){let g;return new Promise((d,m)=>{g=setTimeout(()=>m(new Error(`objstore: inventory not seeded (no subscribe ack) after ${t}ms`)),t),l.listedPromise.then(d,m)}).finally(()=>clearTimeout(g))}function E(l){for(let g=0;g<f.length;g++)if(l(f[g]))return Promise.resolve(f.splice(g,1)[0]);return new Promise((g,d)=>{let m={predicate:l,resolve:()=>{},reject:h=>{clearTimeout(u);let R=c.indexOf(m);R>=0&&c.splice(R,1),d(h)}},u=setTimeout(()=>m.reject(new Error(`objstore: response timeout after ${t}ms`)),t);m.resolve=h=>{clearTimeout(u),g(h)},c.push(m)})}function O(l){if(!o.send(l))throw new Error("objstore: socket not open")}function V(l){for(let g of c.splice(0))try{g.reject(new Error(`objstore: ${l}`))}catch{}}function ie(l){if(l.type==="objstore-put"&&typeof l.workspaceTag=="string"&&Le(l)){let g=i.get(l.workspaceTag);if(!g)return;let d=Ne(l);p(g,d.resourceTag,d.incarnation,d.version),g.inventory.set(d.resourceTag,{version:d.version,incarnation:d.incarnation,contentLength:d.contentLength});let m={resourceTag:d.resourceTag,version:d.version,contentLength:d.contentLength};for(let u of g.putHandlers)try{u(m)}catch{}return}if(l.type==="objstore-deleted"&&typeof l.workspaceTag=="string"&&typeof l.resourceTag=="string"&&typeof l.version=="number"){let g=i.get(l.workspaceTag);if(!g)return;let d=l.resourceTag,m=l.version;g.seenVersions.delete(d),g.inventory.delete(d);let u={resourceTag:d,version:m};for(let h of g.deletedHandlers)try{h(u)}catch{}return}if(!(l.type==="workspace-state"||l.type==="workspace-save-ack"||l.type==="workspace-save-error"||l.type==="workspace-subscribed"||l.type==="authenticated")){for(let g=0;g<c.length;g++)if(c[g].predicate(l)){let d=c[g];c.splice(g,1),d.resolve(l);return}if(f.push(l),f.length>$t){let g=f.splice(0,f.length-$t),d=[...new Set(g.map(m=>m.type??"<no-type>"))].slice(0,4);console.warn(`objstore: dropping ${g.length} unmatched frame(s) over MAX_QUEUE_SIZE=${$t} (types: ${d.join(", ")})`)}}}function ne(){for(let l of i.values())l.closed||l.connected||(l.connected=!0,l.resolveConnected())}function oe(l){V(l);for(let g of i.values())g.closed||g.connected&&(g.connected=!1,b(g))}let Z=o.addConsumer({onMessage:ie,onConnected:ne,onDisconnected:oe}),Y=l=>Jo(l,n),Q=(l,g)=>Y(`/api/objstore/${l}/${g}`);async function U(l,g,d){let m=o.getNonce();if(!m)throw new Error("objstore: socket not open");let u=await Jn(l.signingKey,d,m),h,R=!1;for(;O({type:"objstore-put-begin",...d,signature:u}),h=await E(ae=>ae.workspaceTag===l.workspaceTag&&ae.resourceTag===g&&(ae.type==="objstore-put-token"||ae.type==="objstore-put-error"||ae.type==="objstore-conflict"||ae.type==="unauthorized"&&ae.kind==="gated")),!(h.type!=="unauthorized"||R||(R=!0,!await o.runAuthFlow())););if(h.type==="unauthorized")return{kind:"unauthorized"};if(h.type==="objstore-put-error"){if(h.reason==="workspace-full")return{kind:"workspace-full"};throw new Error(`objstore: put-error reason='${String(h.reason)}'`)}if(h.type==="objstore-conflict")return{kind:"conflict",current:Le(h.current)?Ne(h.current):null};if(typeof h.urlPath!="string"||typeof h.token!="string")throw new TypeError("objstore: malformed put-token (missing urlPath/token)");return{kind:"token",urlPath:h.urlPath,token:h.token}}async function K(l,g,d,m){let u=Date.now(),h=await Zn(l.signingKey,d,u),R=await globalThis.fetch(Q(l.workspaceTag,g),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({op:"put",ts:u,signature:h,prevVersion:d.prevVersion,prevIncarnation:d.prevIncarnation,expectedLength:d.expectedLength,contentHash:m})});if(R.status===401)return{kind:"unauthorized"};if(R.status===403)return{kind:"workspace-full"};if(R.status===409)return{kind:"conflict",current:await Wt(R)};if(!R.ok){let ae="";try{ae=await R.text()}catch{}throw new Error(`objstore: REST put-begin failed ${R.status} ${ae.slice(0,200)}`)}let J;try{J=await R.json()}catch{throw new TypeError("objstore: put-mint JSON parse failed")}if(!J||typeof J!="object"||typeof J.urlPath!="string"||typeof J.token!="string")throw new TypeError("objstore: malformed put-mint (missing urlPath/token)");return{kind:"token",urlPath:J.urlPath,token:J.token}}async function L(l,g){let d=`objstore: ${Dt}`;for(let m=0;;m++)try{return await g()}catch(u){if(m<zo&&!l.closed&&u instanceof Error&&u.message===d)continue;throw u}}function $(l,g){return L(l,()=>M(l,g))}async function M(l,g){if(await l.connectedPromise,l.closed)throw new Error("objstore: session closed");let d=await Kt(g.bytes),m={workspaceTag:l.workspaceTag,resourceTag:g.resourceTag,prevVersion:g.prev?.version??null,prevIncarnation:g.prev?.incarnation??null,expectedLength:g.bytes.byteLength,contentHash:d},u;if(o.isSse()?(u=await K(l,g.resourceTag,m,d),u.kind==="unauthorized"&&(u=await U(l,g.resourceTag,m))):u=await U(l,g.resourceTag,m),u.kind==="unauthorized")return{ok:!1,reason:"unauthorized"};if(u.kind==="workspace-full")return{ok:!1,reason:"workspace-full"};if(u.kind==="conflict")return{ok:!1,reason:"conflict",current:u.current};let h=await globalThis.fetch(Y(u.urlPath),{method:"PUT",headers:{authorization:`Bearer ${u.token}`,"content-type":"application/octet-stream"},body:g.bytes});if(!h.ok){if(h.status===409||h.status===410)return{ok:!1,reason:"conflict",current:h.status===409?await Wt(h):null};let ae="";try{ae=await h.text()}catch{}throw new Error(`objstore: REST PUT failed ${h.status} ${ae.slice(0,200)}`)}let R;try{R=await h.json()}catch{throw new TypeError("objstore: PUT ack JSON parse failed")}if(!R||typeof R!="object"||!He(R.version)||typeof R.incarnation!="string"||typeof R.contentHash!="string"||!He(R.contentLength))throw new TypeError("objstore: PUT ack malformed (missing/invalid version/incarnation/contentHash/contentLength)");let J=R;if(J.contentHash!==d||J.contentLength!==g.bytes.byteLength)throw new Error(`objstore: PUT ack mismatch \u2014 server returned contentHash=${J.contentHash.slice(0,16)}\u2026 length=${J.contentLength}, client signed ${d.slice(0,16)}\u2026 length=${g.bytes.byteLength}`);return{ok:!0,meta:J}}async function N(l,g){let d=o.getNonce();if(!d)throw new Error("objstore: socket not open");let m=await Xn(l.signingKey,l.workspaceTag,g,d);O({type:"objstore-fetch",workspaceTag:l.workspaceTag,resourceTag:g,signature:m});let u=await E(h=>h.workspaceTag===l.workspaceTag&&h.resourceTag===g&&(h.type==="objstore-fetch-token"||h.type==="objstore-fetch-not-found"));if(u.type==="objstore-fetch-not-found")return{kind:"not-found"};if(typeof u.urlPath!="string"||typeof u.token!="string"||!Le(u))throw new TypeError("objstore: malformed fetch-token (missing urlPath / token / metadata)");return{kind:"token",urlPath:u.urlPath,token:u.token,meta:Ne(u)}}async function I(l,g){let d=Date.now(),m=await Qn(l.signingKey,l.workspaceTag,g,d),u=await globalThis.fetch(Q(l.workspaceTag,g),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({op:"fetch",ts:d,signature:m})});if(u.status===404)return{kind:"not-found"};if(u.status===401)return{kind:"unauthorized"};if(!u.ok){let R="";try{R=await u.text()}catch{}throw new Error(`objstore: REST fetch-mint failed ${u.status} ${R.slice(0,200)}`)}let h;try{h=await u.json()}catch{throw new TypeError("objstore: fetch-mint JSON parse failed")}if(!h||typeof h!="object"||typeof h.urlPath!="string"||typeof h.token!="string"||!Le(h))throw new TypeError("objstore: malformed fetch-mint (missing urlPath / token / metadata)");return{kind:"token",urlPath:h.urlPath,token:h.token,meta:Ne(h)}}async function F(l,g){for(let d=0;d<ir;d++){let m=await L(l,()=>W(l,g));if(m.kind==="ok")return m.value;if(m.kind==="not-found")return null;if(d+1<ir){let u=Math.min(Go,qo*2**d);await new Promise(h=>{setTimeout(h,u)})}}return null}async function W(l,g){if(await l.connectedPromise,l.closed)throw new Error("objstore: session closed");let d;if(o.isSse()?(d=await I(l,g),d.kind==="unauthorized"&&(d=await N(l,g))):d=await N(l,g),d.kind==="not-found")return{kind:"not-found"};if(d.kind==="unauthorized")throw new Error("objstore: fetch-mint unauthorized");let m=d.meta,u=await globalThis.fetch(Y(d.urlPath),{method:"GET",headers:{authorization:`Bearer ${d.token}`}});if(!u.ok){if(u.status===404||u.status===503)return{kind:"retry"};let J="";try{J=await u.text()}catch{}throw new Error(`objstore: REST GET failed ${u.status} ${J.slice(0,200)}`)}let h=new Uint8Array(await u.arrayBuffer()),R=await Kt(h);if(R!==m.contentHash)throw new Error(`objstore: contentHash mismatch \u2014 expected ${m.contentHash.slice(0,16)}\u2026, got ${R.slice(0,16)}\u2026`);return{kind:"ok",value:{bytes:h,meta:m}}}async function D(l,g){let d=o.getNonce();if(!d)throw new Error("objstore: socket not open");let m=await Yn(l.signingKey,g,d);O({type:"objstore-delete",...g,signature:m});let u=await E(h=>h.workspaceTag===l.workspaceTag&&h.resourceTag===g.resourceTag&&(h.type==="objstore-deleted-ack"||h.type==="objstore-delete-error"||h.type==="objstore-conflict"));if(u.type==="objstore-deleted-ack"){if(typeof u.deletedVersion!="number")throw new TypeError("objstore: malformed deleted-ack (deletedVersion not a number)");return{kind:"ok",deletedVersion:u.deletedVersion}}if(u.type==="objstore-conflict")return{kind:"conflict",current:Le(u.current)?Ne(u.current):null};if(u.reason==="not-found")return{kind:"not-found"};throw new Error(`objstore: delete-error reason='${String(u.reason)}'`)}async function k(l,g,d){let m=Date.now(),u=await er(l.signingKey,d,m),h=await globalThis.fetch(Q(l.workspaceTag,g),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({op:"delete",ts:m,signature:u,prevVersion:d.prevVersion,prevIncarnation:d.prevIncarnation})});if(h.status===401)return{kind:"unauthorized"};if(h.status===404)return{kind:"not-found"};if(h.status===409)return{kind:"conflict",current:await Wt(h)};if(!h.ok){let J="";try{J=await h.text()}catch{}throw new Error(`objstore: REST delete failed ${h.status} ${J.slice(0,200)}`)}let R;try{R=await h.json()}catch{throw new TypeError("objstore: delete-ack JSON parse failed")}if(!R||typeof R!="object"||typeof R.deletedVersion!="number")throw new TypeError("objstore: malformed delete-ack (deletedVersion not a number)");return{kind:"ok",deletedVersion:R.deletedVersion}}function z(l,g,d){return L(l,()=>G(l,g,d))}async function G(l,g,d){if(await l.connectedPromise,l.closed)throw new Error("objstore: session closed");let m={workspaceTag:l.workspaceTag,resourceTag:g,prevVersion:d?.version??null,prevIncarnation:d?.incarnation??null},u;if(o.isSse()?(u=await k(l,g,m),u.kind==="unauthorized"&&(u=await D(l,m))):u=await D(l,m),u.kind==="ok")return{ok:!0,deletedVersion:u.deletedVersion};if(u.kind==="conflict")return{ok:!1,reason:"conflict",current:u.current};if(u.kind==="not-found")return{ok:!1,reason:"not-found"};throw new Error("objstore: delete unauthorized")}function w(l,g,d,m){let u=l.seenVersions.get(g);if(u&&u.incarnation===d&&m<u.version)throw new Error(`objstore: version-rollback rejected \u2014 fetched v${m} for an incarnation we've already seen at v${u.version}`)}async function v(l,g){if(s)throw new Error("objstore: client closed");if(!g||typeof g.workspaceId!="string")throw new Error("objstore: openWorkspace requires a WorkspaceSubscription (triageSync.ensureSubscription) \u2014 the client must not open a session for a tag with no backing sync subscribe");let d=l.workspaceTag;if(g.workspaceTag!=null&&g.workspaceTag!==d)throw new Error("objstore: openWorkspace \u2014 WorkspaceSubscription is for a different workspace than these keys");if(i.has(d))throw new Error(`objstore: workspace ${d.slice(0,8)}\u2026 is already open on this client`);let m={workspaceTag:d,signingKey:l.signingKey,contentKey:new Uint8Array(l.contentKey),tagKey:new Uint8Array(l.tagKey),putHandlers:new Set,deletedHandlers:new Set,seenVersions:new Map,inventory:new Map,connected:!1,closed:!1};b(m),x(m),i.set(d,m);let u=m;(async()=>{let S;try{S=await g.resources}catch{return}u.closed||A(u,y(S))})();let h=o.acquire();a.set(d,h),o.getNonce()&&(u.connected=!0,u.resolveConnected());let R=null;try{await new Promise((S,P)=>{R=setTimeout(()=>{P(new Error(`objstore: connect timeout after ${t}ms`))},t),u.connectedPromise.then(()=>S(),B=>P(B))})}catch(S){R&&clearTimeout(R),i.delete(d),a.delete(d),u.closed=!0;try{u.contentKey.fill(0)}catch{}try{u.tagKey.fill(0)}catch{}throw h.release(),S}R&&clearTimeout(R);async function J(S,P,B){let q=await $(u,{resourceTag:S,bytes:P,prev:B});return q.ok?(B==null&&u.seenVersions.delete(S),p(u,S,q.meta.incarnation,q.meta.version),u.inventory.set(S,{version:q.meta.version,incarnation:q.meta.incarnation,contentLength:q.meta.contentLength}),{ok:!0,meta:{version:q.meta.version,incarnation:q.meta.incarnation,contentLength:q.meta.contentLength}}):q.reason==="workspace-full"?{ok:!1,reason:"workspace-full"}:q.reason==="unauthorized"?{ok:!1,reason:"unauthorized"}:(q.current&&p(u,S,q.current.incarnation,q.current.version),{ok:!1,reason:"conflict",current:q.current})}async function ae(S){let P=await de(u.tagKey,S.fileName),B=Lt(u.contentKey,S.fileName,S.content,d,P);return await J(P,B,S.prev)}async function vn(S){let P=await de(u.tagKey,S),B=await F(u,P);if(!B)return null;w(u,P,B.meta.incarnation,B.meta.version);let{fileName:q,content:et}=ot(u.contentKey,B.bytes,d,P);if(q!==S)throw new Error(`objstore: fileName-binding mismatch \u2014 requested '${S}', payload encoded '${q}'`);return p(u,P,B.meta.incarnation,B.meta.version),{content:et,version:B.meta.version,incarnation:B.meta.incarnation}}async function $r(S){let P=await F(u,S);if(!P)return null;w(u,S,P.meta.incarnation,P.meta.version);let{fileName:B,content:q}=ot(u.contentKey,P.bytes,d,S);if(await de(u.tagKey,B)===S)return p(u,S,P.meta.incarnation,P.meta.version),{kind:"report",fileName:B,content:q,version:P.meta.version,incarnation:P.meta.incarnation};if(await ye(u.tagKey,B)===S){let{name:Et,content:qr}=Nt(q);return p(u,S,P.meta.incarnation,P.meta.version),{kind:"bundle",integrity:B,name:Et,content:qr,version:P.meta.version,incarnation:P.meta.incarnation}}throw new Error("objstore: fetchByTag \u2014 decrypted name does not derive back to the requested resourceTag under either the report or bundle tag scheme (relay or workspace member produced a non-round-trippable tag-name pair)")}async function Sn(S,P){let B=await z(u,S,P);return B.ok?(u.seenVersions.delete(S),u.inventory.delete(S),B):B.reason==="not-found"?{ok:!1,reason:"not-found"}:(B.current&&p(u,S,B.current.incarnation,B.current.version),{ok:!1,reason:"conflict",current:B.current})}async function Wr(S,P){let B=await de(u.tagKey,S);return await Sn(B,P)}async function Hr(){if(await T(u),u.closed)throw new Error("objstore: session closed");return[...u.inventory.entries()].map(([S,P])=>({resourceTag:S,version:P.version,incarnation:P.incarnation,contentLength:P.contentLength}))}async function _r(S){let P=await ye(u.tagKey,S.integrity),B=Gn(S.name,S.content),q=Lt(u.contentKey,S.integrity,B,d,P);return await J(P,q,S.prev)}async function Vr(S){let P=await ye(u.tagKey,S),B=await F(u,P);if(!B)return null;w(u,P,B.meta.incarnation,B.meta.version);let{fileName:q,content:et}=ot(u.contentKey,B.bytes,d,P);if(q!==S)throw new Error(`objstore: bundle-integrity binding mismatch \u2014 requested '${S}', payload encoded '${q}'`);let{name:kn,content:Et}=Nt(et);return p(u,P,B.meta.incarnation,B.meta.version),{name:kn,content:Et,version:B.meta.version,incarnation:B.meta.incarnation}}async function zr(S,P){let B=await ye(u.tagKey,S);return await Sn(B,P)}return{put:ae,fetch:vn,fetchByTag:$r,delete:Wr,list:Hr,putBundle:_r,fetchBundle:Vr,deleteBundle:zr,onPut(S){return u.putHandlers.add(S),()=>{u.putHandlers.delete(S)}},onDeleted(S){return u.deletedHandlers.add(S),()=>{u.deletedHandlers.delete(S)}},close(){if(u.closed)return;u.closed=!0,i.delete(d);try{u.contentKey.fill(0)}catch{}try{u.tagKey.fill(0)}catch{}try{u.rejectConnected(new Error("objstore: session closed"))}catch{}try{u.rejectListed(new Error("objstore: session closed"))}catch{}let S=a.get(d);a.delete(d),S&&S.release()}}}function H(){if(!s){s=!0;for(let l of i.values()){l.closed=!0;try{l.contentKey.fill(0)}catch{}try{l.tagKey.fill(0)}catch{}try{l.rejectConnected(new Error("objstore: client closed"))}catch{}try{l.rejectListed(new Error("objstore: client closed"))}catch{}}i.clear();for(let l of a.values())l.release();a.clear(),Z.remove(),r&&o.close()}}return{openWorkspace:v,close:H}}async function Wt(e){try{let t=await e.json();if(He(t.currentVersion)&&typeof t.currentIncarnation=="string")return{version:t.currentVersion,incarnation:t.currentIncarnation}}catch{}return null}function He(e){return typeof e=="number"&&Number.isSafeInteger(e)&&e>=0}function Le(e){return!e||typeof e!="object"?!1:typeof e.resourceTag=="string"&&He(e.version)&&typeof e.incarnation=="string"&&typeof e.contentHash=="string"&&He(e.contentLength)&&typeof e.signature=="string"}function Ne(e){return{resourceTag:e.resourceTag,version:e.version,incarnation:e.incarnation,contentHash:e.contentHash,contentLength:e.contentLength,signature:e.signature}}var Ht=null;function cr(e){Ht=typeof e=="function"?e:null}var Yo=ut({serverUrl:"",authResolver:e=>Ht==null?Promise.resolve(null):Ht(e)});function ft(){return Yo}var lr=new Set(["busy"]);function Xo(e){return typeof e?.color=="string"?e.color:""}function Qo(e){return e?.triage==="inprogress"||e?.triage==="fixed"||e?.triage==="invalid"||e?.triage==="deleted"?e.triage:e?.deleted?"deleted":""}function Zo(e){return typeof e?.comment=="string"?e.comment:""}function es(e){return typeof e?.fix=="string"?e.fix:""}function ts(e){return e?.flagged===!0?"flagged":e?.flagged===!1?"not flagged":""}function ur(e,t,n){let r=[];for(let o of Object.keys(e)){let s=e[o],i=t[o],a=n[o],f=s??null,c=[{name:"color",norm:Xo},{name:"triage",norm:Qo},{name:"comment",norm:Zo},{name:"fix",norm:es},{name:"flagged",norm:ts}];for(let{name:p,norm:b}of c){let x=b(i),A=b(f),y=b(a);A!==x&&y!==x&&A!==y&&r.push({id:o,property:p,local:A,imported:y})}}return r}function ns(e,t){let n=Array.isArray(e)?e:[],r=Array.isArray(t)?t:[];if(n.length!==r.length)return!1;if(n.length===0)return!0;let o=new Set(n);for(let s of r)if(!o.has(s))return!1;return!0}function fr(e,t){let n=e.triage??(e.deleted?"deleted":""),r=t.triage??(t.deleted?"deleted":"");return e.color===t.color&&n===r&&(e.comment??"")===(t.comment??"")&&(e.fix??"")===(t.fix??"")&&e.flagged===t.flagged&&ns(e.ignoredReports,t.ignoredReports)}function _t(e,t){let n=new Set([...Object.keys(e),...Object.keys(t)]);for(let r of n)if(!fr(e[r]??{},t[r]??{}))return!1;return!0}function dt(e,t){let n=Object.assign(Object.create(null),e);for(let[r,o]of Object.entries(t))o===null?delete n[r]:o!==void 0&&(n[r]=o);return n}function Vt(e,t){let n=Object.create(null),r=new Set([...Object.keys(e),...Object.keys(t)]);for(let o of r){let s=e[o]??{},i=t[o]??{};fr(s,i)||(n[o]=t[o]??null)}return n}function dr(e){for(let t in e)return!1;return!0}function gr(e){return e==="inprogress"||e==="fixed"||e==="invalid"||e==="deleted"?e:void 0}function be(e){if(e)return gr(e.triage)??(e.deleted?"deleted":void 0)}function rs(e){return e?!e.color&&!be(e)&&!e.comment&&!e.fix&&!(e.ignoredReports&&e.ignoredReports.length>0)&&e.flagged===void 0:!0}function gt(e){if(!e||typeof e!="object")return;let t=e,n={};typeof t.color=="string"&&t.color&&(n.color=t.color);let r=gr(t.triage)??(t.deleted?"deleted":void 0);if(r&&(n.triage=r),typeof t.comment=="string"&&t.comment&&(n.comment=t.comment),typeof t.fix=="string"&&t.fix&&(n.fix=t.fix),typeof t.flagged=="boolean"&&(n.flagged=t.flagged),Array.isArray(t.ignoredReports)){let o=t.ignoredReports.filter(s=>typeof s=="string"&&s.length>0);o.length>0&&(n.ignoredReports=o)}return rs(n)?void 0:n}function os(e,t){let n=e??[],r=t??[];if(n.length!==r.length)return!1;if(n.length===0)return!0;let o=new Set(n);for(let s of r)if(!o.has(s))return!1;return!0}function pr(e,t){let n=e??{},r=t??{};return(n.color??"")===(r.color??"")&&(be(n)??"")===(be(r)??"")&&(n.comment??"")===(r.comment??"")&&(n.fix??"")===(r.fix??"")&&n.flagged===r.flagged&&os(n.ignoredReports,r.ignoredReports)}function le(e,t,n){let r=e.get(t),o=gt({...r,...n});return o===void 0?e.delete(t):pr(r,o)?!1:(e.set(t,o),!0)}function yr(e,t,n){let r=gt(n),o=e.get(t);return r===void 0?e.delete(t):pr(o,r)?!1:(e.set(t,r),!0)}function hr(e,t,n,r){let o=new Set(e.get(t)?.ignoredReports??[]);return r?o.add(n):o.delete(n),le(e,t,{ignoredReports:o.size>0?[...o]:void 0})}function Ke(e,t){let n=Object.assign(Object.create(null),e),r=ce().state,o=t instanceof Set?t:new Set(t);for(let s of o){let i=gt(r.triage.get(s));i?n[s]=i:delete n[s]}return n}function zt(e,t){let n=ce().state,r=[];for(let o of t){let s=e[o];if(!s||typeof s!="object")continue;let i=n.triage.get(o);if(s.color){let c=i?.color;c===void 0?le(n.triage,o,{color:s.color}):c!==s.color&&r.push({id:o,property:"color",local:c,imported:s.color})}let a=be(s);if(a){let c=be(i);c===void 0?le(n.triage,o,{triage:a}):c!==a&&r.push({id:o,property:"triage",local:c,imported:a})}if(s.comment){let c=i?.comment;c===void 0?le(n.triage,o,{comment:s.comment}):c!==s.comment&&r.push({id:o,property:"comment",local:c,imported:s.comment})}if(s.fix){let c=i?.fix;c===void 0?le(n.triage,o,{fix:s.fix}):c!==s.fix&&r.push({id:o,property:"fix",local:c,imported:s.fix})}if(typeof s.flagged=="boolean"){let c=i?.flagged;c===void 0?le(n.triage,o,{flagged:s.flagged}):c!==s.flagged&&r.push({id:o,property:"flagged",local:c?"flagged":"not flagged",imported:s.flagged?"flagged":"not flagged"})}if(!(a!=null||be(i)!=null||!Array.isArray(s.ignoredReports))&&!((i?.ignoredReports?.length??0)>0))for(let c of s.ignoredReports)typeof c=="string"&&hr(n.triage,o,c,!0)}return r}function qt(e,t){let n=ce().state;for(let r of e){let o=`${r.id}:${r.property}`;t[o]==="imported"&&ss(r.id,r.property)===r.local&&(r.property==="color"?le(n.triage,r.id,{color:r.imported}):r.property==="comment"?le(n.triage,r.id,{comment:r.imported}):r.property==="fix"?le(n.triage,r.id,{fix:r.imported}):r.property==="triage"?r.imported==="inprogress"||r.imported==="fixed"||r.imported==="invalid"||r.imported==="deleted"?le(n.triage,r.id,{triage:r.imported,ignoredReports:void 0}):le(n.triage,r.id,{triage:void 0}):r.property==="flagged"&&le(n.triage,r.id,{flagged:r.imported==="flagged"?!0:r.imported==="not flagged"?!1:void 0}))}}function ss(e,t){let n=ce().state.triage.get(e);return t==="color"?n?.color??"":t==="triage"?be(n)??"":t==="comment"?n?.comment??"":t==="fix"?n?.fix??"":t==="flagged"?n?.flagged===!0?"flagged":n?.flagged===!1?"not flagged":"":""}function mr(e,t){let n=ce().state,r=t instanceof Set?t:new Set(t);for(let o of r){let s=e[o],i=be(s)?void 0:s?.ignoredReports;yr(n.triage,o,{...s,ignoredReports:i})}}var Jt="deepview.sync.sessions",is=Jt,Gt=1,yt=!1,pt=new Set;function wr(){return yt}function _e(e){if(yt!==e){yt=e,console.warn(e?"triage-sync: can't persist the sessions blob \u2014 either it's an unrecognised future version (writes skipped to avoid clobbering a newer build's data) or the write itself failed (storage full / vault locked). Your in-memory triage state still works this session but will not persist across reload. Free up storage and/or clear localStorage[deepview.sync.sessions]; the badge clears on the next successful save.":"triage-sync: persistence recovered; persisted-sessions blob is now writable.");for(let t of pt)try{t(e)}catch(n){console.warn("persistenceDegraded listener:",n)}}}function br(e){let t=n=>e(n);return pt.add(t),queueMicrotask(()=>{if(pt.has(t))try{t(yt)}catch(n){console.warn("persistenceDegraded listener:",n)}}),()=>pt.delete(t)}function ht(){try{let e=ce().getSecureItem(Jt);if(!e)return{kind:"empty"};let t=JSON.parse(e);if(!t||typeof t!="object")return{kind:"empty"};let n=t;return n.version===Gt&&n.sessions&&typeof n.sessions=="object"&&!Array.isArray(n.sessions)?{kind:"v1",map:n.sessions}:n.version===Gt?{kind:"empty"}:"version"in n?{kind:"unknown-version"}:{kind:"legacy",map:n}}catch{return{kind:"empty"}}}function as(){let e=ht();return e.kind==="v1"||e.kind==="legacy"?e.map:{}}async function cs(e){try{return await ce().setSecureItem(Jt,JSON.stringify({version:Gt,sessions:e})),!0}catch(t){return console.warn("Triage sync: could not persist session state:",t),!1}}function Yt(e,t){if(!t)return null;let r=as()[e];return!r||r.serverUrl!==t?null:{baseRevision:typeof r.baseRevision=="string"?r.baseRevision:null,baseState:r.baseState&&typeof r.baseState=="object"?Object.assign(Object.create(null),r.baseState):Object.create(null),savesSinceKeyframe:typeof r.savesSinceKeyframe=="number"?r.savesSinceKeyframe:0}}async function mt(e){await navigator.locks.request(is,async()=>{let t=ht();if(t.kind==="unknown-version"){_e(!0);return}let n=t.kind==="v1"||t.kind==="legacy"?t.map:{};if(await e(n)===!1)return;let o=await cs(n);_e(!o)})}function Xt(e=null){mt(t=>{let n=Object.keys(t);if(n.length===0)return!1;let r=new Set(ce().listWorkspaces().map(s=>s.id)),o=!1;for(let s of n){let i=t[s];(!r.has(s)||e!=null&&i?.serverUrl!==e)&&(delete t[s],o=!0)}return o?void 0:!1}).catch(t=>{console.warn("Triage sync: prunePersistedSessions lock failed:",t)})}function wt(e){return mt(t=>{if(!(e in t))return!1;delete t[e]})}var Er,Je,vt,vr,Ar,ls="deepview.triageSyncUrl",Pr="deepview.sync.userEnabled",us=/^\d+$/u,on=()=>{},Ge=null,he="",qe=!0,en=!1,se=ft(),Ve=null,xe=100,fs=5;function St(){return qe&&!en&&!!he&&ds()}function ds(){try{return Je().length>0}catch{return!1}}var tn=new Set;function Br(){if(!St())return"off";for(let t of j.values())if(t.error)return"error";let e=se.getSocket();if(!e||e.readyState!==WebSocket.OPEN)return"offline";for(let t of j.values())if(!t.subscribeAcked)return"connecting";return"online"}var Sr="off";function te(){let e=Br();if(e!==Sr){Sr=e;for(let t of tn)try{t(e)}catch(n){console.warn("Triage sync status listener:",n)}}}var nn=0,j=new Map;function kr(e){for(let t of j.values())if(t.workspaceTag===e)return t;return null}function ge(e){return j.get(e.workspaceId)===e}function Tr(e){if(e.key){try{e.key.fill(0)}catch{}e.key=null}if(e.signingKey=null,e.verifyingKey=null,e.objstoreResourceWaiters.length>0){let t=e.objstoreResourceWaiters.splice(0);for(let n of t)try{n([])}catch{}}}function Rr(e){let t=new Set,n=Je().find(o=>o.id===e);if(!n)return t;let r=new Set(n.reports??[]);for(let o of Er.reports)if(r.has(o.fileName))for(let s of o.groups)for(let i of s){let a=i.id??String(i._id);us.test(a)||t.add(a)}return t}function sn(e){let t=Rr(e.workspaceId),n=[];for(let o of t)e.ids.has(o)||n.push(o);let r=[];return n.length>0&&(r=zt(e.baseState,n)),e.ids=t,{conflicts:r,hydrated:n.length>0}}function gs(){let e=ht();e.kind==="unknown-version"?_e(!0):(e.kind==="v1"||e.kind==="legacy")&&_e(!1),rr(),se.resetCachedReplayGuard()}function Or(e){if(!e||!he)return;let t=he;mt(n=>{n[e.workspaceId]={serverUrl:t,baseRevision:e.baseRevision,savesSinceKeyframe:e.savesSinceKeyframe??0,baseState:e.baseState}}).catch(n=>{console.warn("Triage sync: persistSession lock failed:",n)})}function rn(e){let t=Je().find(r=>r.id===e.workspaceId);if(!t){e.error="workspace no longer exists",te();return}let n=(e.keyDerivationGen??0)+1;e.keyDerivationGen=n,(async()=>{try{let[r,o]=await Promise.all([Fn(t.privateKey),rt(t.privateKey,e.workspaceId)]);if(j.get(e.workspaceId)!==e||e.keyDerivationGen!==n)return;if(e.key=r,e.signingKey=o.privateKey,e.verifyingKey=o.publicKey,e.workspaceTag=o.publicKeyB64,se.getSocket()?.readyState!==WebSocket.OPEN){Ee();return}Me(e),ue(e),te()}catch(r){console.warn("Triage sync: key derivation failed:",r),j.get(e.workspaceId)===e&&e.keyDerivationGen===n&&(e.error=`key derivation failed: ${r instanceof Error?r.message:String(r)}`,te())}})()}function bt(e){return se.send(e)}function ps(e){if(!se.isSse()){bt(e);return}ys(e).then(t=>(t&&bt(e),null)).catch(()=>{bt(e)})}async function ys(e){if(!he)return!0;let t;try{t=sr(he)}catch{return!0}let n;try{n=await globalThis.fetch(t,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})}catch{return!0}let r=e.workspaceTag,o=e.base??null;if(n.status===401)return!0;if(n.ok){let s=null;try{s=await n.json()}catch{return!0}return!s||typeof s.id!="string"?!0:(ze({type:"workspace-save-ack",workspaceTag:r,base:o,id:s.id}),!1)}if(n.status===409){let s=null;try{s=await n.json()}catch{return!0}let i=s&&Array.isArray(s.revisions)?s.revisions:[];return ze({type:"workspace-state",workspaceTag:r,revisions:i}),ze({type:"workspace-save-error",workspaceTag:r,base:o,reason:"stale-base"}),!1}return n.status===413?(ze({type:"workspace-save-error",workspaceTag:r,base:o,reason:"too-large"}),!1):!0}function Me(e,t=!1){if(!e)return;let n=se.getSocket();if(!n||n.readyState!==WebSocket.OPEN||!t&&e.subscribed||!e.signingKey||!e.workspaceTag)return;let r=se.getNonce();if(r==null)return;let o=e.baseRevision,s=n,i=e.signingKey,a=e.workspaceTag;(async()=>{try{let f=await Wn(i,a,o,r);if(j.get(e.workspaceId)!==e||e.workspaceTag!==a||se.getSocket()!==s||se.getNonce()!==r)return;e.subscribed=!0,bt({type:"workspace-subscribe",workspaceTag:a,from:o,signature:f})}catch(f){console.warn("Triage sync: subscribe sign failed:",f)}})()}function ue(e){if(!e||e.error)return;if(e.pending||e.encrypting){e.pendingSave=!0;return}if(!e.key||!e.signingKey||!e.workspaceTag){e.pendingSave=!0;return}sn(e),e.localState=Ke(e.baseState,e.ids);let t=se.getSocket();if(!t||t.readyState!==WebSocket.OPEN)return;let n=(e.savesSinceKeyframe??0)>=xe,r=n?Object.create(null):e.baseState,o=Vt(r,e.localState);if(dr(o)&&!n)return;let s=e.baseRevision,i=e.key,a=e.signingKey,f=e.workspaceTag;e.encrypting=!0,(async()=>{try{let c=Ct(f,s),{nonce:p,ciphertext:b}=await _n(i,o,c),x={publicKeyB64:f,base:s,keyframe:n,nonceB64:p,ciphertextB64:b},A=await $n(a,x),y=await jt(x);if(j.get(e.workspaceId)!==e||e.workspaceTag!==f)return;if(e.baseRevision!==s){e.pendingSave=!0;return}e.pending={base:s,id:y,changeset:o,keyframe:n},e.pendingSave=!1;let T={type:"workspace-save",workspaceTag:f,base:s,nonce:p,ciphertext:b,signature:A};n&&(T.keyframe=!0),ps(T),e.consecutiveFailures=0,e.error&&(e.error=null,te())}catch(c){console.warn("Triage sync: encrypt/sign failed:",c),j.get(e.workspaceId)===e&&(e.consecutiveFailures=(e.consecutiveFailures??0)+1,e.consecutiveFailures>=fs&&(e.error=`encrypt/sign failed: ${c instanceof Error?c.message:String(c)}`,te()))}finally{j.get(e.workspaceId)===e&&(e.encrypting=!1,!e.error&&e.pendingSave&&!e.pending&&(e.pendingSave=!1,ue(e)))}})()}async function hs(e,t){for(let n of t){if(!n||typeof n!="object"||typeof n.id=="string"&&n.id===e.baseRevision)continue;let r=e.baseRevision,o=!!n.keyframe;if(!(r==null?n.base==null||o:n.base===r))return console.warn(`Triage sync: chain base mismatch (expected ${r}, got ${n.base})`),!1;if(typeof n.signature!="string"||typeof n.nonce!="string"||typeof n.ciphertext!="string"||typeof n.id!="string")return console.warn("Triage sync: revision missing signature/nonce/ciphertext/id; resyncing"),e.savesSinceKeyframe=xe,!1;if(!e.workspaceTag||!e.verifyingKey||!e.key)return!1;let i=typeof n.base=="string"?n.base:null,a={publicKeyB64:e.workspaceTag,base:i,keyframe:o,nonceB64:n.nonce,ciphertextB64:n.ciphertext},f=await Hn(e.verifyingKey,a,n.signature);if(!ge(e))return!1;if(!f)return console.warn("Triage sync: revision signature did not verify; resyncing"),e.savesSinceKeyframe=xe,!1;let c=await jt(a);if(!ge(e))return!1;if(n.id!==c)return console.warn("Triage sync: revision id does not match content hash; resyncing"),e.savesSinceKeyframe=xe,!1;let p;try{let x=Ct(e.workspaceTag,i);p=await Vn(e.key,n.nonce,n.ciphertext,x)}catch(x){return console.warn("Triage sync: decrypt failed; resyncing",x),e.savesSinceKeyframe=xe,!1}if(!ge(e))return!1;let b=o?Object.create(null):e.baseState;e.baseState=dt(b,p??{}),e.baseRevision=n.id,o?e.savesSinceKeyframe=0:e.savesSinceKeyframe=Math.min((e.savesSinceKeyframe??0)+1,xe)}return!0}async function jr(e,t,n=[],r=null){if(ge(e)){e.localState=dt(e.baseState,t),nn++;try{mr(e.localState,e.ids),r&&n.length>0&&(qt(n,r),e.localState=Ke(e.baseState,e.ids)),Or(e),await vt()}finally{nn--}if(ge(e)){on();for(let o of j.values())o!==e&&ue(o)}}}function Cr(e){return sn(e),e.localState=Ke(e.baseState,e.ids),Vt(e.baseState,e.localState)}async function ms(e,t){if(e.pending&&t.base===e.pending.base&&typeof t.id=="string"&&t.id===e.pending.id){let n=Cr(e),r=e.pending.keyframe?Object.create(null):e.baseState;if(e.baseState=dt(r,e.pending.changeset),e.baseRevision=t.id,e.savesSinceKeyframe=e.pending.keyframe?0:Math.min((e.savesSinceKeyframe??0)+1,xe),e.pending=null,await jr(e,n),!ge(e))return;(e.pendingSave||!_t(e.localState,e.baseState))&&(e.pendingSave=!1,ue(e));return}if(e.pending){let n=typeof t.id=="string"?t.id.slice(0,8):String(t.id);console.warn(`Triage sync: ack mismatch (pending ${e.pending.base}/${e.pending.id.slice(0,8)}, ack ${t.base}/${n})`);return}if(t.id!==e.baseRevision){let n=typeof t.id=="string"?t.id.slice(0,8):String(t.id);console.warn(`Triage sync: late ack for base=${t.base} id=${n}\u2026; pending was already cleared`),e.pendingSave=!0,ue(e)}}async function ws(e,t){if(!Array.isArray(t)||t.length===0||!e.key)return;let n=Cr(e),r=e.baseRevision,o=e.baseState,s=await hs(e,t);if(!ge(e))return;if(!s){if(!e.resyncAttempted){e.resyncAttempted=!0,console.warn("Triage sync: requesting catch-up from last known baseRevision"),Me(e,!0);return}console.warn("Triage sync: catch-up also broke continuity; full state push"),e.baseRevision=null,e.baseState=Object.create(null),e.pending=null,e.pendingSave=!1,e.resyncAttempted=!1,Or(e),on(),ue(e);return}if(e.resyncAttempted=!1,e.pending&&(e.pending=null,e.pendingSave=!0),e.baseRevision===r){if(!ge(e))return;e.pendingSave&&(e.pendingSave=!1,ue(e));return}let i=ur(n,o,e.baseState),a=null;if(i.length>0&&Ge){try{a=await Ge(i,e.baseState,"chain")??null}catch(f){console.warn("Triage sync: chain-conflict resolver failed:",f)}if(!ge(e))return}await jr(e,n,i,a),ge(e)&&(e.pendingSave||!_t(e.localState,e.baseState))&&(e.pendingSave=!1,ue(e))}async function bs(e){if(e.type==="authenticated"){for(let n of j.values())Me(n),ue(n);return}if(e.type==="unauthorized"){if(e.kind==="gated"){if(typeof e.workspaceTag=="string"){let n=kr(e.workspaceTag);n&&typeof e.resourceTag!="string"&&vs(n,e)}se.runAuthFlow().catch(n=>{console.warn("Triage sync: auth flow failed:",n)})}return}if(typeof e.workspaceTag!="string")return;let t=kr(e.workspaceTag);if(t){if(e.type==="workspace-save-ack")await ms(t,e);else if(e.type==="workspace-state")await ws(t,e.revisions);else if(e.type==="workspace-save-error")ks(t,e);else if(e.type==="workspace-subscribed"){t.subscribeAcked=!0;let n=Array.isArray(e.resources)?e.resources:[],r=t.objstoreResourceWaiters.splice(0);for(let o of r)try{o(n)}catch{}te()}}}function vs(e,t){e.pending&&(typeof t.base!="string"&&t.base!==null||t.base===e.pending.base&&(e.pending=null,e.pendingSave=!0))}var Ss=/^[\w-]+$/u;function ks(e,t){if(!e.pending||typeof t.base!="string"&&t.base!==null||t.base!==e.pending.base)return;let n=t.reason,r=typeof n=="string"&&n.length>0&&n.length<=64&&Ss.test(n)?n:"rejected";if(e.pending=null,lr.has(r)){e.pendingSave=!0;return}e.consecutiveFailures=(e.consecutiveFailures??0)+1,e.error=`server rejected save: ${r}`,te()}var xr=Promise.resolve();function ze(e){xr=xr.then(()=>bs(e)).catch(t=>{console.warn("Triage sync handler error:",t)})}function Ts(e){for(let t of j.values())t.pending=null,t.pendingSave=!1,Me(t),ue(t);te()}function xs(e){for(let t of j.values())t.pending=null,t.subscribed=!1,t.subscribeAcked=!1,t.resyncAttempted=!1,t.pendingSave=!0;te()}se.addConsumer({onMessage:ze,onConnected:Ts,onDisconnected:xs});function Ee(){St()?Ve||(Ve=se.acquire()):Ve&&(Ve.release(),Ve=null)}function Es(e){on=typeof e=="function"?e:()=>{}}function As(e){Ge=typeof e=="function"?e:null}function Ps(e){cr(e)}function Qt(e){let t=e.error!=null;e.error=null,e.consecutiveFailures=0,t&&(!e.key||!e.signingKey)&&rn(e)}function Zt(e){e.pending=null,e.pendingSave=!1,e.encrypting=!1,e.subscribed=!1,e.subscribeAcked=!1,e.resyncAttempted=!1}var ve={setServerUrl(e){let t=(e??"").trim();if(t===he)return;let n=he;he=t,t&&Xt(t),n&&t&&n!==t&&We(null).catch(r=>{console.warn("Triage sync: failed to drop cached auth password on server change:",r)}),se.setServerUrl(t);for(let r of j.values()){Zt(r);let o=t?Yt(r.workspaceId,t):null;r.baseRevision=o?.baseRevision??null,r.baseState=o?.baseState??Object.create(null),r.savesSinceKeyframe=o?.savesSinceKeyframe??0,r.localState=Ke(r.baseState,r.ids),Qt(r)}Ee(),te()},setEnabled(e){let t=!!e;if(t!==qe){if(qe=t,Ar(Pr,t?"1":"0").catch(n=>{console.warn("Triage sync: could not persist user-enabled:",n)}),St())for(let n of j.values())Qt(n);else for(let n of j.values())Zt(n);Ee(),te()}},isEnabled(){return qe},setForcedOff(e){let t=!!e;if(t!==en){if(en=t,St())for(let n of j.values())Qt(n);else for(let n of j.values())Zt(n);Ee(),te()}},getServerUrl(){return he},get connected(){return se.getSocket()?.readyState===WebSocket.OPEN},get status(){return Br()},onStatusChange(e){return tn.add(e),()=>tn.delete(e)},notify(){if(!(nn>0))for(let e of j.values())ue(e)},ensureSubscription(e){let t=j.has(e);ve.openSession(e);let n=j.get(e);if(!n)return null;let r=new Promise(o=>{n.objstoreResourceWaiters.push(o)});return t&&Me(n,!0),{workspaceId:e,workspaceTag:n.workspaceTag,resources:r}},openSession(e){if(!e||j.has(e)||!Je().find(i=>i.id===e))return;let n=Rr(e),r=Yt(e,he),o=r?.baseState??Object.create(null);zt(o,n);let s={workspaceId:e,workspaceTag:null,signingKey:null,verifyingKey:null,ids:n,baseRevision:r?.baseRevision??null,baseState:o,savesSinceKeyframe:r?.savesSinceKeyframe??0,localState:Ke(o,n),pending:null,pendingSave:!1,key:null,encrypting:!1,subscribed:!1,subscribeAcked:!1,resyncAttempted:!1,consecutiveFailures:0,error:null,objstoreResourceWaiters:[]};j.set(e,s),rn(s),Ee(),te()},closeSession(e){if(e==null){for(let t of j.values())Tr(t);j.clear()}else{let t=j.get(e);t&&Tr(t),j.delete(e)}te()},refreshSession(e){let t=j.get(e);if(!t){console.debug("triage-sync: refreshSession bail \u2014 no session for",e,"(caller must openSession first)");return}Ur(t)},sessionInfo(e){let t=j.get(e);return t?{workspaceId:t.workspaceId,workspaceTag:t.workspaceTag,baseRevision:t.baseRevision,pending:t.pending&&{base:t.pending.base,keyframe:t.pending.keyframe},pendingSave:t.pendingSave,keyReady:t.key!==null,encrypting:t.encrypting,tracked:t.ids.size,savesSinceKeyframe:t.savesSinceKeyframe??0,error:t.error??null}:null},get openSessions(){return[...j.keys()].map(e=>this.sessionInfo(e)).filter(e=>e!==null)},dismissError(e){let t=e==null?[...j.keys()]:[e],n=!1;for(let r of t){let o=j.get(r);!o||!o.error||(o.error=null,o.consecutiveFailures=0,n=!0,!o.key||!o.signingKey?rn(o):se.getSocket()?.readyState===WebSocket.OPEN&&(Me(o),ue(o)))}n&&te()},get persistenceDegraded(){return wr()},onPersistenceDegraded(e){return br(e)}};at(e=>{Er=e.state,Je=e.listWorkspaces,vt=e.saveTriage,vr=e.getSecureItem,Ar=e.setSecureItem,e.onSecureStorageHydrated(gs);try{localStorage.removeItem(ls),vr(Pr)==="0"&&(qe=!1),Ee()}catch{}e.onWorkspaceDeleted(t=>{let n=j.delete(t);wt(t).catch(r=>{console.warn("Triage sync: dropPersistedSession lock failed:",r)}),Ee(),n&&te()}),e.onWorkspacePrivateKeyChanged(t=>{let n=j.get(t);if(!n){wt(t).catch(r=>{console.warn("Triage sync: dropPersistedSession lock failed:",r)});return}n.signingKey=null,n.key=null,n.verifyingKey=null,n.workspaceTag=null,n.keyDerivationGen=(n.keyDerivationGen??0)+1,(async()=>{await wt(t),j.delete(t),ve.openSession(t),te()})().catch(r=>{console.warn("Triage sync: privateKey rotation IIFE failed:",r),j.delete(t),te()})}),e.onReportMembershipChanged(t=>{ve.openSession(t);let n=j.get(t);n&&Ur(n)}),Xt()});function Ur(e){let{conflicts:t,hydrated:n}=sn(e);(async()=>{if(t.length===0){n?await vt():ue(e);return}let r=null;if(Ge)try{r=await Ge(t,e.baseState,"attach")}catch(o){console.warn("Triage sync: hydration conflict resolver failed:",o)}ge(e)&&(r&&qt(t,r),await vt())})().catch(r=>{console.warn("Triage sync: refreshAndPropagate failed:",r)})}async function an(e){let t=await crypto.subtle.digest("SHA-512",e);return`sha512-${new Uint8Array(t).toBase64()}`}var Ae,un,fn,gn,pn,yn,Ze,Tt,hn,Mr,mn,wn,_=new Map,dn=new Set,Bs="deepview.objstore-presence.";function bn(e){return Bs+e}function Rs(e){try{let t=localStorage.getItem(bn(e));if(!t)return null;let n=JSON.parse(t);return!n||typeof n!="object"?null:{names:n.names&&typeof n.names=="object"?n.names:{},bundles:n.bundles&&typeof n.bundles=="object"?n.bundles:{},bundleNames:n.bundleNames&&typeof n.bundleNames=="object"?n.bundleNames:{},localVersions:n.localVersions&&typeof n.localVersions=="object"?n.localVersions:{}}}catch{return null}}function Fe(e,t){try{let n={names:Object.fromEntries(t.remoteNameByTag),bundles:Object.fromEntries(t.remoteBundleByTag),bundleNames:Object.fromEntries(t.remoteBundleNameByIntegrity),localVersions:Object.fromEntries(t.localVersions)};localStorage.setItem(bn(e),JSON.stringify(n))}catch(n){console.warn(`objstore-presence: cache persist failed for ${e}:`,n)}}function Lr(e){try{localStorage.removeItem(bn(e))}catch{}}var cn=null;function Os(e){return cn||(cn=ar({serverUrl:"",httpOrigin:e,transport:ft()})),cn}var Ye=new Set,Xe=new Set;function me(){for(let e of dn)try{e()}catch{}}function js(e){if(e==null)return"";if(e instanceof Error&&e.message)return`: ${e.message}`;if(typeof e=="string"&&e)return`: ${e}`;if(typeof e=="object"&&typeof e.message=="string"&&e.message)return`: ${e.message}`;try{return`: ${String(e)}`}catch{return""}}var Nr=256;function Ir(e){return typeof e!="string"?"":e.length<=Nr?e:e.slice(0,Nr)}function Cs(e){try{let t=new URL(e);return t.protocol=t.protocol==="wss:"?"https:":"http:",t.pathname="/",t.search="",t.hash="",t.origin}catch{return null}}function Ie(e){if(_.has(e))return;let t=Ae().find(s=>s.id===e);if(!t)return;let n=ve.ensureSubscription(e);if(!n)return;let r={workspaceId:e,session:null,keys:null,remoteTags:new Set,fileTags:new Map,bundleTags:new Map,remoteNameByTag:new Map,remoteBundleByTag:new Map,remoteBundleNameByIntegrity:new Map,remoteVersions:new Map,localVersions:new Map,inFlight:new Map,err:null,disposed:!1,ready:null};_.set(e,r),r.ready=(async()=>{if(r.keys=await Ut(t.privateKey,t.id),r.disposed)return;let s=new Map;for(let c of t.reports??[]){let p=await de(r.keys.tagKey,c);r.fileTags.set(c,p),s.set(p,c)}if(r.disposed)return;let i=new Map;for(let c of t.bundles??[]){let p=await ye(r.keys.tagKey,c);r.bundleTags.set(c,p),i.set(p,c)}if(r.disposed)return;try{let c=await Ze();if(r.disposed)return;for(let p of c)r.bundleTags.has(p.integrity)&&r.remoteBundleNameByIntegrity.set(p.integrity,p.name)}catch(c){console.warn(`objstore-presence: listBundles failed during ${e} open:`,c)}me();let a=ve.getServerUrl();if(!a)return;let f=Cs(a);if(f)try{let p=await Os(f).openWorkspace(r.keys,n);if(r.disposed){try{p.close()}catch{}return}r.session=p,o();let b=await p.list();if(r.disposed)return;for(let y of b){r.remoteTags.add(y.resourceTag);let T=r.remoteVersions.get(y.resourceTag);(T===void 0||y.version>T)&&r.remoteVersions.set(y.resourceTag,y.version)}let x=Rs(e),A=!1;if(x&&x.localVersions)for(let y of r.remoteTags){let T=x.localVersions[y];typeof T=="number"&&r.localVersions.set(y,T)}for(let y of r.remoteTags){let T=s.get(y);T!==void 0&&!r.remoteNameByTag.has(y)&&(r.remoteNameByTag.set(y,T),A=!0);let E=i.get(y);if(E!==void 0&&!r.remoteBundleByTag.has(y)&&(r.remoteBundleByTag.set(y,E),A=!0),x){let O=x.names[y];typeof O=="string"&&!r.remoteNameByTag.has(y)&&!r.remoteBundleByTag.has(y)&&(r.remoteNameByTag.set(y,O),r.fileTags.set(O,y),A=!0);let V=x.bundles[y];if(typeof V=="string"&&!r.remoteBundleByTag.has(y)&&!r.remoteNameByTag.has(y)){r.remoteBundleByTag.set(y,V),r.bundleTags.set(V,y);let ie=x.bundleNames[V];typeof ie=="string"&&!r.remoteBundleNameByIntegrity.has(V)&&r.remoteBundleNameByIntegrity.set(V,ie),A=!0}}}(A||x)&&Fe(e,r),me(),kt(r);for(let y of r.remoteTags){let T=r.localVersions.get(y),E=r.remoteVersions.get(y);typeof T!="number"||typeof E!="number"||E>T&&Kr(r,y).catch(()=>{})}}catch(c){r.err=c}})();function o(){let s=r.session;s.onPut(({resourceTag:i,version:a})=>{let f=r.remoteVersions.get(i),c=r.remoteTags.has(i)&&typeof f=="number"&&a>f;if(r.remoteTags.add(i),(f===void 0||a>f)&&r.remoteVersions.set(i,a),me(),c){Kr(r,i).catch(()=>{});return}kt(r)}),s.onDeleted(({resourceTag:i})=>{r.remoteTags.delete(i),r.remoteVersions.delete(i),r.localVersions.delete(i);let a=r.remoteNameByTag.get(i);r.remoteNameByTag.delete(i);let f=Ae().find(x=>x.id===e),c=f?.reports??[],p=f?.bundles??[];a&&!c.includes(a)&&r.fileTags.delete(a);let b=r.remoteBundleByTag.get(i);r.remoteBundleByTag.delete(i),b&&(r.remoteBundleNameByIntegrity.delete(b),p.includes(b)||r.bundleTags.delete(b)),Fe(e,r),me()})}r.ready.catch(()=>{})}function Qe(e){let t=_.get(e);if(t){t.disposed=!0;try{t.session?.close()}catch{}if(t.keys){try{t.keys.contentKey.fill(0)}catch{}try{t.keys.tagKey.fill(0)}catch{}t.keys=null}_.delete(e),me()}}at(e=>{Ae=e.listWorkspaces,un=e.addReportToWorkspace,fn=e.addBundleToWorkspace,gn=e.analyzeContent,pn=e.setCount,yn=e.gunzipBytes,Ze=e.listBundles,Tt=e.listFiles,hn=e.readBundle,Mr=e.readFileBytes,mn=e.saveBundle,wn=e.saveFileBytes,e.onReportMembershipChanged(t=>{_.has(t)||Ie(t);let n=_.get(t);if(!n)return;let r=Ae().find(o=>o.id===t);if(r)for(let o of r.reports??[])n.fileTags.has(o)||Ns(t,o).catch(()=>{})}),e.onBundleMembershipChanged(t=>{_.has(t)||Ie(t);let n=_.get(t);if(!n)return;let r=Ae().find(o=>o.id===t);if(r)for(let o of r.bundles??[])n.bundleTags.has(o)||Ms(t,o).catch(()=>{})}),e.onWorkspaceDeleted(t=>{Qe(t),Lr(t)}),e.onWorkspacePrivateKeyChanged(t=>{_.has(t)&&(Qe(t),Lr(t),Ie(t))})});function Us(){return Array.from(_.keys())}function Ls(e,t){let n=_.get(e);if(!n)return!1;let r=n.fileTags.get(t);return r?n.remoteTags.has(r):!1}async function Ns(e,t){let n=_.get(e);!n||n.fileTags.has(t)||(n.ready&&!n.keys&&await n.ready,n.keys&&(n.fileTags.set(t,await de(n.keys.tagKey,t)),n.disposed||me()))}function Ks(e,t){let n=_.get(e);if(!n)return!1;let r=n.bundleTags.get(t);return r?n.remoteTags.has(r):!1}async function Ms(e,t){let n=_.get(e);!n||n.bundleTags.has(t)||(n.ready&&!n.keys&&await n.ready,n.keys&&(n.bundleTags.set(t,await ye(n.keys.tagKey,t)),n.disposed||me()))}function Is(e){return dn.add(e),()=>dn.delete(e)}function Fs(e){return Ye.add(e),()=>Ye.delete(e)}function Ds(e){return Xe.add(e),()=>Xe.delete(e)}function $s(e){let t=_.get(e);return t?t.remoteTags.size:0}async function Ws(e){let t=_.get(e);return t?(t.ready&&!t.session&&await t.ready,t.session?(await kt(t),Array.from(t.remoteNameByTag.values())):[]):[]}async function Hs(e){let t=_.get(e);return t?(t.ready&&!t.session&&await t.ready,t.session?(await kt(t),Array.from(t.remoteBundleByTag.values())):[]):[]}function _s(e,t){let n=_.get(e);if(n)return n.remoteBundleNameByIntegrity.get(t)}async function kt(e){if(!e.session||e.disposed)return;let t=Ae().find(i=>i.id===e.workspaceId),n=new Set(t?.reports??[]),r=new Set(t?.bundles??[]),o=new Set;try{o=new Set(await Tt())}catch(i){console.warn(`objstore-presence: listFiles failed during discovery for "${e.workspaceId}":`,i)}if(e.disposed||!e.session)return;let s=[];for(let i of e.remoteTags){let a=e.remoteNameByTag.get(i);if(a!==void 0&&n.has(a)&&o.has(a))continue;if(e.remoteBundleByTag.has(i)){let c=e.remoteBundleByTag.get(i);if(e.remoteBundleNameByIntegrity.has(c)&&r.has(c))continue}let f=e.inFlight.get(i);f||(f=e.session.fetchByTag(i).then(async c=>(e.inFlight.delete(i),!c||e.disposed||!e.remoteTags.has(i)?null:c.kind==="bundle"?(e.remoteBundleByTag.set(i,c.integrity),e.bundleTags.set(c.integrity,i),c.name&&e.remoteBundleNameByIntegrity.set(c.integrity,c.name),await zs(e,i,c.integrity,c.name,c.content),null):(e.remoteNameByTag.set(i,c.fileName),e.fileTags.set(c.fileName,i),await Vs(e,i,c.fileName,c.content),null)),()=>(e.inFlight.delete(i),null)),e.inFlight.set(i,f)),s.push(f)}s.length!==0&&(await Promise.all(s),!e.disposed&&(Fe(e.workspaceId,e),me()))}async function Vs(e,t,n,r){if(e.disposed||!e.remoteTags.has(t))return;let o=Ae().find(c=>c.id===e.workspaceId),s=!!(o&&Array.isArray(o.reports)&&o.reports.includes(n)),i;try{let c=await Tt();if(e.disposed||!e.remoteTags.has(t))return;i=c.includes(n)}catch(c){console.warn(`auto-download: listFiles failed before saving "${n}":`,c);return}if(i){if(s||e.disposed||!e.remoteTags.has(t))return;try{await un(n,e.workspaceId)}catch(c){console.warn(`auto-download: attaching local "${n}" to workspace "${e.workspaceId}" failed:`,c);return}if(e.disposed)return;for(let c of Ye)try{c(e.workspaceId,n)}catch{}return}let a;try{a=Ce(await yn(r))}catch(c){console.warn(`auto-download: gunzip/decode of "${n}" failed (likely forged peer payload):`,c);return}if(e.disposed||!e.remoteTags.has(t))return;let f=gn(a);if(f.recognized){try{if(await wn(n,r),e.disposed||!e.remoteTags.has(t))return;pn(n,f.count,f.source);let c=e.remoteVersions.get(t);if(typeof c=="number"&&e.localVersions.set(t,c),!e.remoteTags.has(t))return;await un(n,e.workspaceId),Fe(e.workspaceId,e)}catch(c){console.warn(`auto-download: persisting "${n}" to workspace "${e.workspaceId}" failed:`,c);return}if(!e.disposed)for(let c of Ye)try{c(e.workspaceId,n)}catch{}}}async function Kr(e,t){if(e.disposed||!e.remoteTags.has(t))return;let n;try{n=await e.session.fetchByTag(t)}catch(a){console.warn(`replace-refetch: fetchByTag failed for tag in workspace "${e.workspaceId}":`,a);return}if(!n||e.disposed||!e.remoteTags.has(t)||n.kind==="bundle")return;let r=n.fileName,o=n.content,s;try{s=Ce(await yn(o))}catch(a){console.warn(`replace-refetch: gunzip/decode of "${r}" failed (likely forged peer payload):`,a);return}if(e.disposed||!e.remoteTags.has(t))return;let i=gn(s);if(!i.recognized){console.warn(`replace-refetch: peer-uploaded replacement for "${r}" did not analyze as a recognized report \u2014 refusing to overwrite local copy`);return}try{if(await wn(r,o),e.disposed)return;pn(r,i.count,i.source),typeof n.version=="number"&&e.localVersions.set(t,n.version),Fe(e.workspaceId,e)}catch(a){console.warn(`replace-refetch: saveFileBytes failed for "${r}":`,a);return}if(!e.disposed)for(let a of Ye)try{a(e.workspaceId,r)}catch{}}async function zs(e,t,n,r,o){if(e.disposed||!e.remoteTags.has(t))return;let s;try{s=await Ze()}catch(c){console.warn(`auto-download: listBundles failed before saving bundle "${n}":`,c);return}if(e.disposed||!e.remoteTags.has(t))return;if(s.some(c=>c.integrity===n)){try{await fn(n,e.workspaceId)}catch(p){console.warn("auto-download: attach pre-existing bundle failed:",p);return}if(e.disposed)return;let c=s.find(p=>p.integrity===n)?.name??"";for(let p of Xe)try{p(e.workspaceId,n,c)}catch{}return}let i=await an(o);if(e.disposed||!e.remoteTags.has(t))return;if(i!==n){console.warn(`auto-download: bundle integrity mismatch (claimed ${n}, got ${i}) \u2014 refusing to save`);return}let a=r&&r.length>0?r:`bundle-${n.slice(7,15)}`,f=Ir(a);try{if(await mn(f,o),e.disposed||!e.remoteTags.has(t))return;await fn(n,e.workspaceId)}catch(c){console.warn(`auto-download: persisting bundle "${n}" to workspace "${e.workspaceId}" failed:`,c);return}if(!e.disposed)for(let c of Xe)try{c(e.workspaceId,n,f)}catch{}}async function Pe(e){if(e.ready&&!e.session&&await e.ready,!e.session)throw new Error(`Objstore session is not connected${js(e.err)}`)}async function xt(e){let t=await e(null);return!t.ok&&t.reason==="conflict"&&t.current&&(t=await e(t.current)),t}async function qs(e,t){let n=_.get(e);if(!n)throw new Error(`Workspace ${e} is not open`);return await Pe(n),n.session.fetch(t)}async function Fr(e,t,n){let r=_.get(e);if(!r)throw new Error(`Workspace ${e} is not open`);await Pe(r);let o=await xt(s=>r.session.put({fileName:t,content:n,prev:s}));if(o.ok&&r.keys&&!r.disposed)try{let s=r.fileTags.get(t)??await de(r.keys.tagKey,t);r.fileTags.set(t,s),r.remoteVersions.set(s,o.meta.version),r.localVersions.set(s,o.meta.version),Fe(r.workspaceId,r)}catch{}return o}async function Gs(e,t){let n=!1;_.has(e)||(Ie(e),n=!0);try{let r=_.get(e);if(!r)throw new Error(`Workspace ${e} could not be opened \u2014 not in listWorkspaces()?`);if(await Pe(r),!r.keys)throw new Error("Objstore session keys missing \u2014 derivation failed during open");r.fileTags.has(t)||r.fileTags.set(t,await de(r.keys.tagKey,t));let o=r.fileTags.get(t),s=await xt(i=>r.session.delete(t,i));return s.ok&&(r.remoteTags.delete(o),r.remoteNameByTag.delete(o),r.remoteVersions.delete(o),r.localVersions.delete(o),me()),s}finally{n&&Qe(e)}}async function Dr(e,t){let n=_.get(e);if(!n)throw new Error(`Workspace ${e} is not open`);await Pe(n);let r=await hn(t),i=(await Ze()).find(a=>a.integrity===t)?.name??`bundle-${t.slice(7,15)}`;return await xt(a=>n.session.putBundle({integrity:t,name:i,content:r,prev:a}))}async function Js(e,t){let n=_.get(e);if(!n)throw new Error(`Workspace ${e} is not open`);await Pe(n);let r=await n.session.fetchBundle(t);if(!r)return{ok:!1,reason:"not-found"};if(await an(r.content)!==t)return{ok:!1,reason:"integrity-mismatch"};let s=r.name&&r.name.length>0?r.name:`bundle-${t.slice(7,15)}`,i=Ir(s);await mn(i,r.content);for(let a of Xe)try{a(e,t,i)}catch{}return{ok:!0,integrity:t,name:i}}async function Ys(e,t){let n=!1;_.has(e)||(Ie(e),n=!0);try{let r=_.get(e);if(!r)throw new Error(`Workspace ${e} could not be opened \u2014 not in listWorkspaces()?`);if(await Pe(r),!r.keys)throw new Error("Objstore session keys missing \u2014 derivation failed during open");r.bundleTags.has(t)||r.bundleTags.set(t,await ye(r.keys.tagKey,t));let o=r.bundleTags.get(t),s=await xt(i=>r.session.deleteBundle(t,i));return s.ok&&(r.remoteTags.delete(o),r.remoteBundleByTag.delete(o),me()),s}finally{n&&Qe(e)}}async function Xs(e,{onList:t,onItem:n}={}){let r=_.get(e);if(!r)throw new Error(`Workspace ${e} is not open`);if(await Pe(r),!r.keys)throw new Error("Objstore session keys missing \u2014 derivation failed during open");let o=r.keys.tagKey,s=new Set,i=r.session.onDeleted(a=>{s.add(a.resourceTag)});try{let a=await Qs(r,e),f=await ii(),c=await ai(),p=new Map;for(let y of f)p.set(await de(o,y),y);let b=new Map;for(let y of c)b.set(await ye(o,y.integrity),y.integrity);let x=a.map(y=>{let T=p.get(y.resourceTag),E=b.get(y.resourceTag);return{resourceTag:y.resourceTag,kind:ri(r,y.resourceTag,T,E),label:oi(r,y.resourceTag,T,E),contentLength:y.contentLength,reportName:T,bundleIntegrity:E,identifier:T??E,status:"checking"}});if(typeof t=="function")try{t(x.map(ln))}catch{}let A={good:0,reuploaded:0,failed:0,"check-failed":0,missing:0};for(let y of x)if(y.status=await ei(r,e,y,s),A[y.status]+=1,typeof n=="function")try{n(ln(y))}catch{}return{items:x.map(ln),counts:A}}finally{i()}}async function Qs(e,t){try{let n=ve.ensureSubscription(t);if(n){let r=await si(n.resources,1e4);if(Array.isArray(r))return Zs(r)}}catch(n){console.warn(`objstore-recovery: fresh DB listing for ${t} failed; using cached inventory:`,n)}try{return(await e.session.list()).map(n=>({resourceTag:n.resourceTag,contentLength:n.contentLength}))}catch{return[]}}function Zs(e){let t=[];for(let n of e)!n||typeof n!="object"||typeof n.resourceTag=="string"&&t.push({resourceTag:n.resourceTag,contentLength:Number.isSafeInteger(n.contentLength)?n.contentLength:null});return t}async function ei(e,t,n,r){let o;try{o=await e.session.fetchByTag(n.resourceTag)}catch(s){return n.detail=`verification fetch failed: ${s?.message??String(s)}`,"check-failed"}return o?(o.kind==="report"?(n.kind="report",n.label=o.fileName,n.identifier=o.fileName):(n.kind="bundle",n.label=o.name??n.label,n.bundleIntegrity=o.integrity,n.identifier=o.integrity),"good"):r.has(n.resourceTag)?"missing":n.reportName!==void 0?await ti(t,n,r):n.bundleIntegrity!==void 0?await ni(t,n,r):"missing"}async function ti(e,t,n){let r;try{r=await Mr(t.reportName)}catch{return"missing"}if(t.contentLength==null||qn(t.reportName,r.length)!==t.contentLength||n.has(t.resourceTag))return"missing";try{let o=await Fr(e,t.reportName,r);return o&&o.ok?"reuploaded":(t.detail=`re-upload rejected: ${o?.reason??"unknown"}`,"failed")}catch(o){return t.detail=`re-upload error: ${o?.message??String(o)}`,console.warn(`objstore-recovery: re-upload of "${t.reportName}" failed:`,o),"failed"}}async function ni(e,t,n){try{await hn(t.bundleIntegrity)}catch{return"missing"}if(n.has(t.resourceTag))return"missing";try{let r=await Dr(e,t.bundleIntegrity);return r&&r.ok?"reuploaded":(t.detail=`re-upload rejected: ${r?.reason??"unknown"}`,"failed")}catch(r){return t.detail=`re-upload error: ${r?.message??String(r)}`,console.warn(`objstore-recovery: bundle re-upload of "${t.bundleIntegrity}" failed:`,r),"failed"}}function ri(e,t,n,r){return n!==void 0?"report":r!==void 0||e.remoteBundleByTag.has(t)?"bundle":e.remoteNameByTag.has(t)?"report":"unknown"}function oi(e,t,n,r){if(n!==void 0)return n;if(r!==void 0)return e.remoteBundleNameByIntegrity.get(r)??r;let o=e.remoteNameByTag.get(t);if(o!==void 0)return o;let s=e.remoteBundleByTag.get(t);return s!==void 0?e.remoteBundleNameByIntegrity.get(s)??s:`${t.slice(0,10)}\u2026`}function ln(e){return{resourceTag:e.resourceTag,kind:e.kind,label:e.label,status:e.status,identifier:e.identifier,detail:e.detail}}function si(e,t){let n,r=Promise.resolve(e);r.catch(()=>{});let o=new Promise((s,i)=>{n=setTimeout(()=>i(new Error(`objstore-recovery: timed out after ${t}ms`)),t)});return Promise.race([r,o]).finally(()=>clearTimeout(n))}async function ii(){try{return await Tt()}catch(e){return console.warn("objstore-recovery: listFiles failed; treating as no local reports:",e),[]}}async function ai(){try{return await Ze()}catch(e){return console.warn("objstore-recovery: listBundles failed; treating as no local bundles:",e),[]}}export{Qe as closeWorkspace,Ys as deleteBundleFromRemote,Gs as deleteFromRemote,Hs as discoverRemoteBundleIntegrities,Ws as discoverRemoteFileNames,Js as fetchBundleFromRemote,qs as fetchFile,Do as installSyncHost,Ks as isBundleInRemote,Ls as isInRemote,Fs as onAutoDownloaded,Ds as onBundleAutoDownloaded,Is as onChange,Ie as openWorkspace,Us as openWorkspaceIds,Dr as putBundleToRemote,Fr as putFile,Xs as recheckRemoteStorage,_s as remoteBundleName,$s as remoteCount,Ps as setAuthenticationResolver,As as setHydrationConflictResolver,Es as setRedraw,ve as triageSync};
18
18
  /*! Bundled license information:
19
19
 
20
20
  @noble/ciphers/utils.js: