1"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[4902],{74902:function(e,t,r){r.d(t,{e2eeWorker:function(){return s}});function s(){let e=(e,t)=>{for(let r=t;r<e.length-2;++r)if(0===e[r]&&0===e[r+1]){if(1===e[r+2])return{pos:r,len:3};if(0===e[r+2]&&r+3<e.length&&1===e[r+3])return{pos:r,len:4}}return null},t=e=>{let t=e.length,r=0;for(;r<2&&r<t&&0===e[t-1-r];)r++;return r},r=(e,t)=>{let r=0,s=t;for(let t of e){r+=t.length;for(let e=0;e<t.length;++e){let a=t[e];s>=2&&a<=3&&(r++,s=0),s=0===a?s+1:0}}return r},s=(e,t,r,s)=>{let a=t,n=s;for(let t of r)for(let r=0;r<t.length;++r){let s=t[r];n>=2&&s<=3&&(e[a++]=3,n=0),e[a++]=s,n=0===s?n+1:0}},a=(e,t)=>{let r=(t,r)=>r>=2&&3===e[t]&&t+1<e.length&&e[t+1]<=3,s=0,a=t;for(let t=0;t<e.length;++t){if(r(t,a)){s++,a=0;continue}a=0===e[t]?a+1:0}if(0===s)return e;let n=new Uint8Array(e.length-s),i=0;a=t;for(let t=0;t<e.length;++t){if(r(t,a)){a=0;continue}n[i++]=e[t],a=0===e[t]?a+1:0}return n},n=e=>void 0===e?1:0,i=(e,t)=>{let r="key"===e?10:3;return r>t.length?t.length:r},l={opus:{rbsp:!1,audioOnly:!0,clearBytes:n},vp8:{rbsp:!1,audioOnly:!1,clearBytes:i},vp9:{rbsp:!1,audioOnly:!1,clearBytes:i},h264:{rbsp:!0,audioOnly:!1,clearBytes:(t,r)=>{let s=e(r,0);for(;s;){let t=s.pos+s.len;if(t>=r.length)break;let a=31&r[t];if(1===a||5===a){let e=s.pos+s.len+2;return e>r.length?r.length:e}s=e(r,t)}return 0}}},h={rbsp:!1,audioOnly:!0,clearBytes:n},y=e=>void 0!==e&&Object.hasOwn(l,e)?l[e]:h,o=e=>void 0===e||Object.hasOwn(l,e),u=Promise.resolve(),c=e=>{let t=u.then(e);return u=t.catch(()=>{}),t},d=new Uint8Array(0);class p{intervalMs;lastFiredAt=new Map;constructor(e){this.intervalMs=e}tryFire=e=>{let t=Date.now();return t-(this.lastFiredAt.get(e)??0)>this.intervalMs&&(this.lastFiredAt.set(e,t),!0)}}let f=e=>{self.postMessage({type:"e2ee.error",message:e})},g=new p(1e3),m=e=>{g.tryFire(e)&&self.postMessage({type:"e2ee.missing_key",userId:e})};class w{userId;trackType;latched=!1;constructor(e,t){this.userId=e,this.trackType=t}failed=e=>{this.latched||(this.latched=!0,self.postMessage({type:"e2ee.encryption_failed",userId:this.userId,trackType:this.trackType,reason:e}))};recovered=()=>{this.latched=!1}}class k{userId;trackType;failureThrottle=new p(1e3);missingKeyThrottle=new p(1e3);cleartextThrottle=new p(1e3);versionThrottle=new p(1e3);failureReported=!1;constructor(e,t){this.userId=e,this.trackType=t}failed=()=>{this.failureThrottle.tryFire(this.userId)&&(this.failureReported=!0,self.postMessage({type:"e2ee.decryption_failed",userId:this.userId,trackType:this.trackType}))};resumed=()=>{this.failureReported&&(this.failureReported=!1,self.postMessage({type:"e2ee.decryption_resumed",userId:this.userId,trackType:this.trackType}))};missingKey=e=>{this.missingKeyThrottle.tryFire(String(e))&&self.postMessage({type:"e2ee.missing_key",userId:this.userId,trackType:this.trackType,keyIndex:e})};unsupportedVersion=e=>{this.versionThrottle.tryFire(this.userId)&&self.postMessage({type:"e2ee.unsupported_version",userId:this.userId,trackType:this.trackType,version:e})};unencrypted=()=>{this.cleartextThrottle.tryFire(this.userId)&&self.postMessage({type:"e2ee.unencrypted_frame",userId:this.userId,trackType:this.trackType})};stalled=e=>{self.postMessage({type:"e2ee.decryption_stalled",userId:this.userId,trackType:this.trackType,keyIndex:e})}}let b=(e,t)=>{let r=e.get(t);return r||(r=new Map,e.set(t,r)),r},v=e=>{let t=new Uint8Array(e);return crypto.getRandomValues(t),t},K=async e=>new Uint8Array(await crypto.subtle.digest("SHA-256",e),0,8),I=e=>({name:"AES-GCM",length:8*e.byteLength}),x=async e=>{let[t,r]=await Promise.all([crypto.subtle.importKey("raw",e,I(e),!1,["encrypt","decrypt"]),K(e)]);return{key:t,ivPrefix:v(8),fingerprint:r}},U=e=>Array.from(e).map(e=>e.toString(16).padStart(2,"0")).join("");class T{perUserKeys=new Map;latestKeyIndex=new Map;sharedKeys=new Map;activeSharedKeyIndex;getKey=(e,t)=>{let r=this.perUserKeys.get(e)?.get(t);return r?r.key:this.sharedKeys.get(t)?.key};getLatestKey=e=>{let t=this.latestKeyIndex.get(e);if(void 0!==t){let r=this.perUserKeys.get(e)?.get(t);if(r)return{key:r.key,keyIndex:t,ivPrefix:r.ivPrefix}}if(void 0===this.activeSharedKeyIndex)return null;let r=this.sharedKeys.get(this.activeSharedKeyIndex);return r?{key:r.key,keyIndex:this.activeSharedKeyIndex,ivPrefix:r.ivPrefix}:null};importKey=async(e,t,r)=>{try{b(this.perUserKeys,e).set(t,await x(r)),this.latestKeyIndex.set(e,t)}catch(t){f(`Failed to import key for user ${e}: ${t?.message||t}`)}};importSharedKey=async(e,t)=>{try{let r=await x(t);this.sharedKeys.set(e,r),this.activeSharedKeyIndex=e}catch(e){f(`Failed to import shared key: ${e?.message||e}`)}};removeKey=(e,t)=>{let r=this.perUserKeys.get(e);
1r?.delete(t)&&(0===r.size&&this.perUserKeys.delete(e),this.latestKeyIndex.get(e)===t&&this.latestKeyIndex.delete(e))};removeAllKeys=e=>{this.perUserKeys.delete(e),this.latestKeyIndex.delete(e)};removeSharedKey=e=>{this.sharedKeys.delete(e),this.activeSharedKeyIndex===e&&(this.activeSharedKeyIndex=void 0)};keyState=()=>({perUserKeys:Array.from(this.perUserKeys).flatMap(([e,t])=>Array.from(t,([t,r])=>({userId:e,keyIndex:t,fingerprint:U(r.fingerprint)}))),sharedKeys:Array.from(this.sharedKeys,([e,t])=>({keyIndex:e,fingerprint:U(t.fingerprint),isActive:e===this.activeSharedKeyIndex}))});clear=()=>{this.perUserKeys.clear(),this.latestKeyIndex.clear(),this.sharedKeys.clear(),this.activeSharedKeyIndex=void 0}}let M=new T,A=!1,S=null,_=0;class C{stats;key;labels;constructor(e,t,r){this.stats=e,this.key=t,this.labels=r}entry=()=>{if(!A)return;let e=this.stats.get(this.key);return e||(e={...this.labels,count:0,maxCryptoMs:0},this.stats.set(this.key,e)),e};bump=()=>{let e=this.entry();e&&e.count++};startCrypto=()=>A?performance.now():0;endCrypto=e=>{let t=this.entry();t&&(t.maxCryptoMs=Math.max(t.maxCryptoMs,performance.now()-e))}}class ${stats=new Map;track=(e,t)=>new C(this.stats,e,t);flush=e=>{let t=Array.from(this.stats.values(),({count:t,maxCryptoMs:r,...s})=>({...s,fps:t/e,maxCryptoMs:r}));return this.stats.clear(),t};clear=()=>this.stats.clear();removeUser=e=>{for(let[t,r]of this.stats)r.userId===e&&this.stats.delete(t)}}let E=new $,O=new $,F=()=>{S||(A=!0,_=performance.now(),S=setInterval(()=>{let e=performance.now(),t=Math.max(.001,(e-_)/1e3);_=e,self.postMessage({type:"e2ee.perf_report",encode:E.flush(t),decode:O.flush(t)})},1e3))},L=()=>{A=!1,S&&(clearInterval(S),S=null),E.clear(),O.clear()},P=(e,t,r,s)=>{e.set(r,0),t.setUint32(8,s)},D=(e,t,r,s,a,n,i)=>{if(n>32767)throw Error(`clearBytes ${n} exceeds 15-bit max 32767`);
1if(8!==s.length)throw Error(`ivPrefix must be 8 bytes, got ${s.length}`);let l=new DataView(e.buffer,e.byteOffset,e.byteLength);l.setUint32(t,r),e.set(s,t+4),e[t+12]=a,l.setUint16(t+13,i?32768|n:n),e[t+15]=1,l.setUint32(t+16,3807313645)},V=e=>{let t=new DataView(e.buffer,e.byteOffset,e.byteLength),r=e.length-20;return{frameCounter:t.getUint32(r),ivPrefix:e.subarray(r+4,r+12),keyIndex:e[r+12]}},B=(e,t)=>{if(e.length<5)return null;let r=t??new DataView(e.buffer,e.byteOffset,e.byteLength),s=e.length-5;return 3807313645!==r.getUint32(s+1)?null:e[s]},q=e=>{if(e.length<20)return null;let t=new DataView(e.buffer,e.byteOffset,e.byteLength);if(1!==B(e,t))return null;let r=e.length-20,s=t.getUint16(r+13),a=32767&s;return a>e.length-20?null:{frameCounter:t.getUint32(r),ivPrefix:e.subarray(r+4,r+12),keyIndex:e[r+12],clearBytes:a,isRbsp:(32768&s)!=0}},R=0,j=()=>{let e=R+1;if(e>4294967295)throw Error("frame counter exhausted, create a new EncryptionManager");return R=e,e},G=(e,a,n)=>{let i=y(a),l=i.rbsp,h=n??a??"unknown",o=a??"unknown",u=E.track(h,{userId:e,trackType:h,codec:o}),c=new w(e,n),p=new Uint8Array(12),f=new DataView(p.buffer),g=async(e,t,r)=>{try{let s=u.startCrypto(),a=await r();if(u.endCrypto(s),!a)return;e.data=a.buffer,t.enqueue(e),c.recovered(),u.bump()}catch(e){c.failed(e?.message||String(e))}};return new TransformStream({async transform(a,n){if(0===a.data.byteLength){n.enqueue(a),u.bump();return}let h=M.getLatestKey(e);if(!h){m(e);return}let{key:y,keyIndex:w,ivPrefix:k}=h;return g(a,n,async()=>{if(i.audioOnly&&void 0!==a.type)return c.failed(`no clear-byte rule for video on codec ${o}`),null;let e=new Uint8Array(a.data),n=i.clearBytes(a.type,e);if(n>32767)return c.failed("clearBytes exceeds trailer capacity"),null;let h=j();P(p,f,k,h);let u=n>0?e.subarray(0,n):d,g=n>0?e.subarray(n):e,m=new Uint8Array(await crypto.subtle.encrypt({name:"AES-GCM",iv:p,additionalData:u},y,g));if(l&&n>0){let e=new Uint8Array(20);D(e,0,h,k,w,n,!0);let a=[m,e],i=t(u),l=new Uint8Array(n+r(a,i));return l.set(u,0),s(l,n,a,i),l}let b=new Uint8Array(n+m.length+20);return n>0&&b.set(u,0),b.set(m,n),D(b,n+m.length,h,k,w,n,!1),b})}})};class N{counts=new Map;recordFailure=e=>{let t=(this.counts.get(e)??0)+1;return this.counts.set(e,t),11===t};recordSuccess=e=>this.counts.delete(e)}let z=(e,t)=>{if(e.length!==t.length)return!1;for(let r=0;r<e.length;r++)if(e[r]!==t[r])return!1;return!0};class H{prefix;highest;bitmap=new Uint32Array(32);constructor(e,t){this.prefix=e.slice(),this.highest=t,this.mark(t)}accepts=e=>e>this.highest||!(e<=this.highest-1024)&&!this.isMarked(e);record=e=>{if(e>this.highest){if(e-this.highest>=1024)this.bitmap.fill(0);else for(let t=this.highest+1;t<e;t++)this.clear(t);this.highest=e}this.mark(e)};slot=e=>{let t=e%1024;return{word:t>>>5,mask:1<<(31&t)}};isMarked=e=>{let{word:t,mask:r}=this.slot(e);return(this.bitmap[t]&r)!=0};mark=e=>{let{word:t,mask:r}=this.slot(e);this.bitmap[t]|=r};clear=e=>{let{word:t,mask:r}=this.slot(e);this.bitmap[t]&=~r}}class W{epochs=[];find=e=>this.epochs.find(t=>z(t.prefix,e));peek=(e,t)=>this.find(t)?.accepts(e)??!0;commit=(e,t)=>{let r=this.find(t);if(r){r.record(e);return}this.epochs.unshift(new H(t,e)),this.epochs.length>3&&this.epochs.pop()}}let J=(e,r)=>{let s=r??"unknown",n=O.track(`${e}/${s}`,{userId:e,trackType:s}),i=new k(e,r),l=new Uint8Array(12),h=new DataView(l.buffer),y=new W,o=new N,u=async(t,r,s,a,l,h)=>{let u=M.getKey(e,s);if(!u){i.missingKey(s);return}if(y.peek(l,a))try{let e=n.startCrypto(),c=await h(u);n.endCrypto(e),y.commit(l,a),o.recordSuccess(s),i.resumed(),t.data=c,r.enqueue(t),n.bump()}catch{let e=o.recordFailure(s);i.failed(),e&&i.stalled(s)}};return new TransformStream({async transform(e,r){let s;if(0===e.data.byteLength){r.enqueue(e),n.bump();return}let y=new Uint8Array(e.data),o=q(y);if(!o){let t=B(y);if(null!==t&&1!==t){i.unsupportedVersion(t);return}i.unencrypted(),r.enqueue(e),n.bump();return}let{clearBytes:c,isRbsp:p}=o,{frameCounter:f,ivPrefix:g,keyIndex:m}=o;if(p){let e=t(y.subarray(0,c)),r=a(y.subarray(c),e);if(r.length<20)return;({frameCounter:f,ivPrefix:g,keyIndex:m}=V(r)),s=r.subarray(0,r.length-20)}else s=y.subarray(c,y.length-20);return u(e,r,m,g,f,async e=>{P(l,h,g,f);let t=c>
10?y.subarray(0,c):d,r=await crypto.subtle.decrypt({name:"AES-GCM",iv:l,additionalData:t},e,s);if(0===c)return r;let a=new Uint8Array(r),n=new Uint8Array(c+a.length);return n.set(y.subarray(0,c),0),n.set(a,c),n.buffer})}})},Q=(e,t,r,s)=>"encode"!==e?J(t,s):o(r)?G(t,r,s):(new w(t,s).failed(`unsupported codec for E2EE: ${r}`),new TransformStream({transform(){}})),X=({readable:e,writable:t,operation:r,userId:s,codec:a,trackType:n})=>{let i=Q(r,s,a,n);e.pipeThrough(i).pipeTo(t).catch(e=>{f(`Transform pipeline error (${r}, ${s}): ${e?.message||e}`)})};addEventListener("rtctransform",e=>{let{readable:t,writable:r,options:s}=e.transformer;c(async()=>{X({readable:t,writable:r,...s})}).catch(e=>{f(`Transform setup failed: ${e?.message||e}`)})}),addEventListener("message",({data:e})=>{c(async()=>{switch(e.type){case"cmd.set_key":await M.importKey(e.userId,e.keyIndex,e.rawKey);break;case"cmd.set_shared_key":await M.importSharedKey(e.keyIndex,e.rawKey);break;case"cmd.remove_shared_key":M.removeSharedKey(e.keyIndex);break;case"cmd.remove_key":M.removeKey(e.userId,e.keyIndex);break;case"cmd.remove_all_keys":M.removeAllKeys(e.userId),O.removeUser(e.userId);break;case"cmd.enable_performance_reporting":e.enabled?F():L();break;case"cmd.request_key_state":self.postMessage({type:"e2ee.key_state",...M.keyState()});break;case"cmd.setup_transform":X(e);break;default:f(`Unknown command type: ${e.type}`)}}).catch(e=>{f(`Message handler error: ${e?.message||e}`)})})}}}]); 2//# sourceMappingURL=4902.810caf0d4f6f9592.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.