@vidtreo/recorder-wc 1.6.2 → 1.6.3

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.
@@ -123,7 +123,7 @@ The @mediabunny/ac3 extension package provides support for encoding and decoding
123
123
  The @mediabunny/flac-encoder extension package provides support for encoding FLAC.`)}else e.push(`
124
124
  Check the discardedTracks field for more info.`)}return e}async execute(){if(!this.isValid)throw Error(`Cannot execute this conversion because its output configuration is invalid. Make sure to always check the isValid field before executing a conversion.
125
125
  `+this._getInvalidityExplanation().join(``));if(this._executed)throw Error(`Conversion cannot be executed twice.`);this._executed=!0;for(let e of this._outputTrackIds)this._synchronizer.declareTrack(e);if(this.onProgress){let e=[...new Set(this.utilizedTracks)].map(async e=>await e.isLive()?1/0:await e.getDurationFromMetadata()??await e.computeDuration()),t=Math.max(0,...await Promise.all(e));this._computeProgress=!0,this._totalDuration=Math.min(t-this._startTimestamp,this._endTimestamp-this._startTimestamp);for(let e of this._outputTrackIds)this._maxTimestamps.set(e,0);this.onProgress?.(0,0)}await this.output.start(),this._start();try{await Promise.all(this._trackPromises)}catch(e){throw this._canceled||this.cancel(),e}if(this._canceled)throw new gv;if(await this.output.finalize(),this._computeProgress){let e=Math.min(...this._maxTimestamps.values());this.onProgress?.(1,e)}}async cancel(){if(!(this.output.state===`finalizing`||this.output.state===`finalized`)){if(this._canceled){console.warn(`Conversion already canceled.`);return}this._canceled=!0,await this.output.cancel()}}async _processVideoTrack(e,t,n){let r=await e.getCodec();if(!r){this.discardedTracks.push({track:e,reason:`unknown_source_codec`,trackOptions:t});return}let i,a=await e.getRotation(),o=Bn(a+(t.rotate??0)),s=o,c=this.output.format.supportsVideoRotationMetadata&&(t.allowRotationMetadata??!0),l=await e.getSquarePixelWidth(),u=await e.getSquarePixelHeight(),[d,f]=o%180==0?[l,u]:[u,l],p=t.crop;p&&=jd(p,d,f);let[m,h]=p?[p.width,p.height]:[d,f],g=m,_=h,v=g/_;t.width!==void 0&&t.height===void 0?(g=_i(t.width),_=_i(Math.round(g/v))):t.width===void 0&&t.height!==void 0?(_=_i(t.height),g=_i(Math.round(_*v))):t.width!==void 0&&t.height!==void 0&&(g=_i(t.width),_=_i(t.height));let y=await e.getFirstTimestamp(),b=this.output.format.getSupportedVideoCodecs(),x=!!t.forceTranscode||y<this._startTimestamp||!!t.frameRate||t.keyFrameInterval!==void 0||t.process!==void 0||t.bitrate!==void 0||!b.includes(r)||t.codec&&t.codec!==r||g!==m||_!==h||o!==0&&!c||!!p,S=t.alpha??`discard`;if(x){if(!await e.canDecode()){this.discardedTracks.push({track:e,reason:`undecodable_source_codec`,trackOptions:t});return}t.codec&&(b=b.filter(e=>e===t.codec));let r=t.bitrate??df,d=await xf(b,{width:t.process&&t.processedWidth?t.processedWidth:g,height:t.process&&t.processedHeight?t.processedHeight:_,bitrate:r});if(!d){this.discardedTracks.push({track:e,reason:`no_encodable_target_codec`,trackOptions:t});return}let f={codec:d,bitrate:r,keyFrameInterval:t.keyFrameInterval,sizeChangeBehavior:t.fit??`passThrough`,alpha:S,hardwareAcceleration:t.hardwareAcceleration,transform:{}};D(f.transform);let v=g!==m||_!==h||o!==0&&(!c||t.process!==void 0)||!!p||l!==await e.getCodedWidth()||u!==await e.getCodedHeight();if(!v){let t=new lv({format:new U_,target:new vg}),n=new g_(f);t.addVideoTrack(n),await t.start();let r=await new Qf(e).getSample(y);if(r)try{await n.add(r),r.close(),await t.finalize()}catch(e){console.info(`Error when probing encoder support. Falling back to rerender path.`,e),v=!0,t.cancel()}else await t.cancel()}t.frameRate&&(f.transform.frameRate=t.frameRate),v&&(s=0,f.transform.width=g,f.transform.height=_,f.transform.fit=t.fit??`fill`,f.transform.rotate=Bn(o-a),f.transform.crop=p,f.transform.alpha=S);let x=new g_(f);i=x,this._trackPromises.push((async()=>{await this._started;let r=new Qf(e);for await(let e of r.samples(this._startTimestamp,this._endTimestamp)){if(this._canceled){e.close();return}let r=Math.max(e.timestamp-this._startTimestamp,0);e.setTimestamp(r),await this._registerVideoSample(t,n,x,e),e.close()}x.close(),this._synchronizer.closeTrack(n)})())}else{let t=new d_(r);i=t,this._trackPromises.push((async()=>{await this._started;let r=new Wf(e),i={decoderConfig:await e.getDecoderConfig()??void 0};for await(let e of r.packets(void 0,void 0,{verifyKeyPackets:!0})){if(this._canceled)return;if(e.timestamp>=this._endTimestamp)break;let r=e.clone({timestamp:e.timestamp-this._startTimestamp,sideData:S===`discard`?{}:e.sideData});D(r.timestamp>=0),this._reportProgress(n,r.timestamp+r.duration),await t.add(r,i),this._synchronizer.shouldWait(n,r.timestamp)&&await this._synchronizer.wait(r.timestamp)}t.close(),this._synchronizer.closeTrack(n)})())}let C=null;t.group||(C=new sv);let ee=await e.getLanguageCode();this.output.addVideoTrack(i,{frameRate:t.frameRate,languageCode:kr(ee)?ee:void 0,name:await e.getName()??void 0,disposition:await e.getDisposition(),rotation:s,group:C??t.group}),this._addedCounts.video++,this._totalTrackCount++,this.utilizedTracks.push(e),this._outputTrackIds.push(n),this._outputOwnTrackGroups.push(C)}async _registerVideoSample(e,t,n,r){if(this._canceled)return;this._reportProgress(t,r.timestamp+r.duration);let i;if(!e.process)i=[r];else{let t=e.process(r);t instanceof Promise&&(t=await t),Array.isArray(t)||(t=t===null?[]:[t]),i=t.map(e=>e instanceof Cd?e:typeof VideoFrame<`u`&&e instanceof VideoFrame?new Cd(e):new Cd(e,{timestamp:r.timestamp,duration:r.duration}))}try{for(let e of i){if(this._canceled)break;await n.add(e),this._synchronizer.shouldWait(t,e.timestamp)&&await this._synchronizer.wait(e.timestamp)}}finally{for(let e of i)e!==r&&e.close()}}async _processAudioTrack(e,t,n){let r=await e.getCodec();if(!r){this.discardedTracks.push({track:e,reason:`unknown_source_codec`,trackOptions:t});return}let i,a=await e.getNumberOfChannels(),o=await e.getSampleRate(),s=await e.getFirstTimestamp(),c=t.numberOfChannels??a,l=t.sampleRate??o,u=c!==a||l!==o||s<this._startTimestamp||s>this._startTimestamp&&!this.output.format.supportsTimestampedMediaData,d=this.output.format.getSupportedAudioCodecs();if(!t.forceTranscode&&!t.bitrate&&!u&&d.includes(r)&&(!t.codec||t.codec===r)&&!t.process&&t.sampleFormat===void 0){let t=new b_(r);i=t,this._trackPromises.push((async()=>{await this._started;let r=new Wf(e),i={decoderConfig:await e.getDecoderConfig()??void 0};for await(let e of r.packets()){if(this._canceled)return;if(e.timestamp>=this._endTimestamp)break;let r=e.clone({timestamp:e.timestamp-this._startTimestamp});D(r.timestamp>=0),this._reportProgress(n,r.timestamp+r.duration),await t.add(r,i),this._synchronizer.shouldWait(n,r.timestamp)&&await this._synchronizer.wait(r.timestamp)}t.close(),this._synchronizer.closeTrack(n)})())}else{if(!await e.canDecode()){this.discardedTracks.push({track:e,reason:`undecodable_source_codec`,trackOptions:t});return}let r=null;t.codec&&(d=d.filter(e=>e===t.codec));let a=t.bitrate??df,o=await yf(d,{numberOfChannels:t.process&&t.processedNumberOfChannels?t.processedNumberOfChannels:c,sampleRate:t.process&&t.processedSampleRate?t.processedSampleRate:l,bitrate:a});if(!o.some(e=>Li.includes(e))&&d.some(e=>Li.includes(e))&&(c!==pv||l!==mv)){let e=(await yf(d,{numberOfChannels:pv,sampleRate:mv,bitrate:a})).find(e=>Li.includes(e));e&&(u=!0,r=e,c=pv,l=mv)}else r=o[0]??null;if(r===null){this.discardedTracks.push({track:e,reason:`no_encodable_target_codec`,trackOptions:t});return}if(u)i=this._resampleAudio(e,t,n,r,c,l,a);else{let o=new S_({codec:r,bitrate:a});i=o,this._trackPromises.push((async()=>{await this._started;let r=new np(e);for await(let e of r.samples(void 0,this._endTimestamp)){if(this._canceled){e.close();return}e.setTimestamp(e.timestamp-this._startTimestamp),await this._registerAudioSample(t,n,o,e),e.close()}o.close(),this._synchronizer.closeTrack(n)})())}}let f=null;t.group||(f=new sv);let p=await e.getLanguageCode();this.output.addAudioTrack(i,{languageCode:kr(p)?p:void 0,name:await e.getName()??void 0,disposition:await e.getDisposition(),group:f??t.group}),this._addedCounts.audio++,this._totalTrackCount++,this.utilizedTracks.push(e),this._outputTrackIds.push(n),this._outputOwnTrackGroups.push(f)}async _registerAudioSample(e,t,n,r){if(this._canceled)return;let i=r;e.sampleFormat!==void 0&&Jd(i.format)!==e.sampleFormat&&(i=Xd(i,e.sampleFormat)),this._reportProgress(t,i.timestamp+i.duration);let a;if(!e.process)a=[i];else{let t=e.process(i);if(t instanceof Promise&&(t=await t),Array.isArray(t)||(t=t===null?[]:[t]),!t.every(e=>e instanceof Hd))throw TypeError(`The audio process function must return an AudioSample, null, or an array of AudioSamples.`);a=t}try{for(let e of a){if(this._canceled)break;await n.add(e),this._synchronizer.shouldWait(t,e.timestamp)&&await this._synchronizer.wait(e.timestamp)}}finally{i!==r&&i.close();for(let e of a)e!==r&&e.close()}}_resampleAudio(e,t,n,r,i,a,o){let s=new S_({codec:r,bitrate:o});return this._trackPromises.push((async()=>{await this._started;let r=new o_({targetNumberOfChannels:i,targetSampleRate:a,startTime:this._startTimestamp,endTime:this._endTimestamp,onSample:async e=>{D(e.timestamp>=this._startTimestamp),e.setTimestamp(e.timestamp-this._startTimestamp),await this._registerAudioSample(t,n,s,e),e.close()}}),o=new np(e).samples(this._startTimestamp,this._endTimestamp);for await(let e of o){if(this._canceled){e.close();return}await r.add(e),e.close()}await r.finalize(),s.close(),this._synchronizer.closeTrack(n)})()),s}_reportProgress(e,t){if(!this._computeProgress)return;D(this._totalDuration!==null),this._maxTimestamps.set(e,Math.max(t,this._maxTimestamps.get(e)));let n=Math.min(...this._maxTimestamps.values()),r=br(n/this._totalDuration,0,1);r!==this._lastProgress&&(this._lastProgress=r,this.onProgress?.(r,n))}},gv=class extends Error{constructor(e=`Conversion has been canceled.`){super(e),this.name=`ConversionCanceledError`}},_v=1,vv=class{constructor(){this.maxTimestamps=new Map,this.resolvers=[]}declareTrack(e){this.maxTimestamps.set(e,0)}shouldWait(e,t){let n=this.maxTimestamps.get(e);return D(n!==void 0),this.maxTimestamps.set(e,Math.max(t,n)),t-this.computeMinAndMaybeResolve()>_v}wait(e){let{promise:t,resolve:n}=P();return this.resolvers.push({timestamp:e,resolve:n}),t}closeTrack(e){this.maxTimestamps.delete(e),this.computeMinAndMaybeResolve()}computeMinAndMaybeResolve(){let e=1/0;for(let[,t]of this.maxTimestamps)e=Math.min(e,t);for(let t=0;t<this.resolvers.length;t++){let n=this.resolvers[t];n.timestamp-e<_v&&(n.resolve(),this.resolvers.splice(t,1),t--)}return e}}})),bv=r({ADTS:()=>Xu,ALL_FORMATS:()=>ed,ALL_TRACK_TYPES:()=>nv,AUDIO_CODECS:()=>Ri,AdtsInputFormat:()=>Bu,AdtsOutputFormat:()=>Z_,AppendOnlyStreamTarget:()=>gg,AttachedFile:()=>xi,AudioBufferSink:()=>rp,AudioBufferSource:()=>C_,AudioSample:()=>Hd,AudioSampleResource:()=>Vd,AudioSampleSink:()=>np,AudioSampleSource:()=>S_,AudioSource:()=>y_,BaseMediaSampleSink:()=>Kf,BlobSource:()=>iu,BufferSource:()=>ru,BufferTarget:()=>fg,CanvasSink:()=>$f,CanvasSource:()=>__,CmafOutputFormat:()=>W_,ConcurrentRunner:()=>vi,Conversion:()=>hv,ConversionCanceledError:()=>gv,CustomAudioDecoder:()=>Ef,CustomAudioEncoder:()=>Of,CustomPathedSource:()=>nu,CustomVideoDecoder:()=>Tf,CustomVideoEncoder:()=>Df,EncodedAudioPacketSource:()=>b_,EncodedPacket:()=>L,EncodedPacketSink:()=>Wf,EncodedVideoPacketSource:()=>d_,EventEmitter:()=>gi,FLAC:()=>Zu,FilePathSource:()=>lu,FilePathTarget:()=>_g,FlacInputFormat:()=>zu,FlacOutputFormat:()=>Q_,HLS:()=>$u,HLS_FORMATS:()=>td,HlsInputFormat:()=>Hu,HlsOutputFormat:()=>ev,Input:()=>yp,InputAudioTrack:()=>cp,InputDisposedError:()=>xp,InputFormat:()=>Au,InputTrack:()=>ap,InputVideoTrack:()=>sp,IsobmffInputFormat:()=>ju,IsobmffOutputFormat:()=>H_,MATROSKA:()=>Gu,MP3:()=>qu,MP4:()=>Uu,MPEG_TS:()=>Qu,MatroskaInputFormat:()=>Pu,MediaSource:()=>c_,MediaStreamAudioTrackSource:()=>w_,MediaStreamVideoTrackSource:()=>v_,MkvOutputFormat:()=>K_,MovOutputFormat:()=>G_,Mp3InputFormat:()=>Iu,Mp3OutputFormat:()=>J_,Mp4InputFormat:()=>Mu,Mp4OutputFormat:()=>U_,MpegTsInputFormat:()=>Vu,MpegTsOutputFormat:()=>$_,NON_PCM_AUDIO_CODECS:()=>Li,NullTarget:()=>vg,OGG:()=>Yu,OggInputFormat:()=>Ru,OggOutputFormat:()=>X_,Output:()=>lv,OutputAudioTrack:()=>av,OutputFormat:()=>V_,OutputSubtitleTrack:()=>ov,OutputTrack:()=>rv,OutputTrackGroup:()=>sv,OutputVideoTrack:()=>iv,PCM_AUDIO_CODECS:()=>Ii,PathedSource:()=>eu,PathedTarget:()=>bg,QTFF:()=>Wu,QUALITY_HIGH:()=>df,QUALITY_LOW:()=>lf,QUALITY_MEDIUM:()=>uf,QUALITY_VERY_HIGH:()=>ff,QUALITY_VERY_LOW:()=>cf,Quality:()=>sf,QuickTimeInputFormat:()=>Nu,RangedSource:()=>mu,RangedTarget:()=>yg,ReadableStreamSource:()=>du,RichImageData:()=>bi,SUBTITLE_CODECS:()=>zi,Source:()=>Ql,SourceRef:()=>$l,StreamSource:()=>uu,StreamTarget:()=>hg,SubtitleSource:()=>M_,Target:()=>lg,TextSubtitleSource:()=>N_,UnsupportedInputFormatError:()=>bp,UrlSource:()=>cu,VIDEO_CODECS:()=>Fi,VIDEO_SAMPLE_PIXEL_FORMATS:()=>xd,VideoSample:()=>Cd,VideoSampleColorSpace:()=>kd,VideoSampleResource:()=>bd,VideoSampleSink:()=>Qf,VideoSampleSource:()=>g_,VideoSource:()=>l_,WAVE:()=>Ju,WEBM:()=>Ku,WavOutputFormat:()=>Y_,WaveInputFormat:()=>Lu,WebMInputFormat:()=>Fu,WebMOutputFormat:()=>q_,asc:()=>lp,canDecode:()=>cd,canDecodeAudio:()=>ud,canDecodeVideo:()=>ld,canEncode:()=>pf,canEncodeAudio:()=>hf,canEncodeSubtitles:()=>gf,canEncodeVideo:()=>mf,desc:()=>up,getDecodableAudioCodecs:()=>pd,getDecodableCodecs:()=>dd,getDecodableVideoCodecs:()=>fd,getEncodableAudioCodecs:()=>yf,getEncodableCodecs:()=>_f,getEncodableSubtitleCodecs:()=>bf,getEncodableVideoCodecs:()=>vf,getFirstEncodableAudioCodec:()=>Sf,getFirstEncodableSubtitleCodec:()=>Cf,getFirstEncodableVideoCodec:()=>xf,prefer:()=>dp,registerDecoder:()=>Nf,registerEncoder:()=>Pf,registerVideoSampleTransformer:()=>Td}),xv,Sv=n((()=>{uv(),tv(),P_(),ha(),md(),wf(),xg(),F(),hu(),rd(),Sp(),hp(),Ro(),Zd(),ip(),yv(),Ff(),Ei(),xv=Symbol.for(`mediabunny loaded`),globalThis[xv]&&console.error(`[WARNING]
126
- Mediabunny was loaded twice. This will likely cause Mediabunny not to work correctly. Check if multiple dependencies are importing different versions of Mediabunny, or if something is being bundled incorrectly.`),globalThis[xv]=!0}));Sv();async function Cv(e){try{let t=new iu(e),n=new yp({formats:[Uu],source:t});if(typeof n.computeDuration!=`function`)throw Error(`computeDuration method is not available`);let r=await n.computeDuration();if(!r)throw Error(`Duration is missing from computeDuration`);if(r<=0)throw Error(`Invalid duration: must be greater than 0`);return r}catch{return wv(e)}}function wv(e){return new Promise((t,n)=>{let r=document.createElement(`video`),i=URL.createObjectURL(e),a=()=>{URL.revokeObjectURL(i)};r.addEventListener(`loadedmetadata`,()=>{a();let e=r.duration;if(!Number.isFinite(e)||e<=0){n(Error(`Invalid video duration`));return}t(e)}),r.addEventListener(`error`,()=>{a(),n(Error(`Failed to load video metadata`))}),r.src=i,r.load()})}let Tv=[`video/mp4`,`video/quicktime`,`video/webm`];async function Ev(e,t={}){let n=t.maxFileSize===void 0?524288e3:t.maxFileSize;if(e.size>n)return{valid:!1,error:`File too large. Maximum size is ${Math.round(n/1024/1024)}MB`};let r=t.allowedFormats===void 0?Tv:t.allowedFormats;if(!r.includes(e.type))return{valid:!1,error:`Unsupported format. Please use: ${r.join(`, `)}`};let a=await Cv(e).then(e=>({success:!0,duration:e})).catch(e=>({success:!1,error:i(e)}));if(a.success===!1)return{valid:!1,error:`Failed to read video file: ${a.error}`};let o=a.duration;return t.maxRecordingTime!==null&&t.maxRecordingTime!==void 0&&o>t.maxRecordingTime?{valid:!1,error:`Video too long. Maximum duration is ${t.maxRecordingTime} seconds`}:{valid:!0}}let Dv=`unknown`;function Ov(){if(typeof navigator>`u`)return null;let e=navigator;return{userAgent:e.userAgent,platform:e.platform,hardwareConcurrency:e.hardwareConcurrency,deviceMemory:e.deviceMemory,onLine:e.onLine,connection:e.connection}}function kv(){return globalThis.isSecureContext===!0}function Av(){return globalThis.MediaRecorder!==void 0}function jv(){return globalThis.VideoEncoder!==void 0}function Mv(e){return globalThis.VideoEncoder===void 0?Promise.resolve({config:e,supported:!1}):globalThis.VideoEncoder.isConfigSupported(e)}function Nv(e){return{navigatorProvider:e?.navigatorProvider??Ov(),secureContextProvider:e?.secureContextProvider??kv,mediaRecorderAvailabilityProvider:e?.mediaRecorderAvailabilityProvider??Av,videoEncoderAvailabilityProvider:e?.videoEncoderAvailabilityProvider??jv,codecSupportProbe:e?.codecSupportProbe??Mv}}function Pv(e){let t=new wt(e??``).getResult(),n=t.browser.name??Dv;return{browser:{name:n,version:t.browser.version??``,normalizedName:n.toLowerCase()},os:{name:t.os.name??Dv,version:t.os.version??``}}}function Fv(e){return e instanceof Error?e.message:String(e)}async function Iv(e,t){try{let n=await t(e.config);return{id:e.id,config:e.config,supported:n.supported===!0}}catch(t){return{id:e.id,config:e.config,supported:!1,errorCode:`codec-probe-error`,errorMessage:Fv(t)}}}async function Lv(e={}){let t=Nv(e.dependencies),{browser:n,os:r}=Pv(t.navigatorProvider?.userAgent),i=await Promise.all((e.codecCandidates??[]).map(e=>Iv(e,t.codecSupportProbe)));return{browser:n,os:r,resources:{deviceMemory:t.navigatorProvider?.deviceMemory,hardwareConcurrency:t.navigatorProvider?.hardwareConcurrency},network:{online:t.navigatorProvider?.onLine,effectiveType:t.navigatorProvider?.connection?.effectiveType},features:{isSecureContext:t.secureContextProvider(),hasMediaRecorder:t.mediaRecorderAvailabilityProvider(),hasVideoEncoder:t.videoEncoderAvailabilityProvider()},codecProbeResults:i}}function Rv(e,t){let n=e.resources.deviceMemory;return n===void 0||n>=t}function zv(e,t){let n=e.resources.hardwareConcurrency;return n===void 0||n>=t}function Bv(e,t){let n=new Set(t);return e.codecProbeResults.find(e=>n.has(e.id)&&e.supported)?.id}function Vv(e,t){return e.features.isSecureContext&&e.features.hasMediaRecorder&&e.features.hasVideoEncoder&&t&&e.network.online!==!1}function Hv(e){return e.os.name.toLowerCase()===`android`}function Uv(e,t,n,r){let i=[];return e.features.isSecureContext||i.push(`insecure-context`),e.features.hasVideoEncoder||i.push(`webcodecs-unavailable`),t||i.push(`target-codec-unsupported`),n||i.push(`insufficient-device-memory`),r||i.push(`insufficient-hardware-concurrency`),Hv(e)&&i.push(`android-post-recording-transcode`),i}function Wv(e){let t=[];return e.features.hasMediaRecorder||t.push(`mediarecorder-unavailable`),e.network.online===!1&&t.push(`offline`),t}function Gv(e){let t=e.resourceThresholds?.minDeviceMemory??4,n=e.resourceThresholds?.minHardwareConcurrency??4,r=Bv(e.profile,e.targetCodecIds),i=r!==void 0,a=Rv(e.profile,t),o=zv(e.profile,n),s=Uv(e.profile,i,a,o);return e.profile.features.isSecureContext&&e.profile.features.hasVideoEncoder&&i&&e.profile.network.online!==!1&&!Hv(e.profile)&&a&&o?{route:`local-webcodecs`,reasonCodes:[`webcodecs-supported`,`target-codec-supported`],selectedCodecId:r}:Vv(e.profile,i)?{route:`safe-capture-post-recording-transcode`,reasonCodes:[...s,`mediarecorder-supported`],selectedCodecId:r}:{route:`unsupported-with-guidance`,reasonCodes:[...s,...Wv(e.profile)],guidance:{canRetry:!0,message:`Recording is not supported in this browser context. Use a secure connection, go online, and try a current Chrome or Edge browser.`}}}let Kv=[`prefer-hardware`,`no-preference`,`prefer-software`];async function qv(){let e=(await Promise.allSettled([Promise.resolve().then(()=>(Sv(),bv))]))[0];return e.status===`fulfilled`?e.value:null}let Jv={loadMediabunnyModule:qv};function Yv(e){let t=e?.loadMediabunnyModule,n;return n=t===void 0?Jv.loadMediabunnyModule:t,{loadMediabunnyModule:n}}function Xv(e,t){return t===void 0||e.includes(t)?e:[...e,t]}function Zv(e,t){let n=[];e!==void 0&&t.videoCodecFallbackOrder.includes(e)&&(n=Xv(n,e)),n=Xv(n,t.preferredVideoCodec);for(let e of t.videoCodecFallbackOrder)n=Xv(n,e);return n}function Qv(e,t){let n=[];e!==void 0&&t.audioCodecFallbackOrder.includes(e)&&(n=Xv(n,e)),n=Xv(n,t.preferredAudioCodec);for(let e of t.audioCodecFallbackOrder)n=Xv(n,e);return n}function $v(e,t,n){let r=Error(`No encodable video codec available for format: ${e}`);return r.code=`recording.video-codec-unavailable`,r.details={candidates:t,format:e,probeErrors:n},r}async function ey(e,t,n){try{return await e(t,n)?{kind:`supported`,codec:t}:{kind:`unsupported`,codec:t}}catch(e){return{kind:`error`,codec:t,error:e}}}async function ty(e){let t=await Yv(e.dependencies).loadMediabunnyModule();if(t===null)return e.policy.preferredVideoCodec;let n=t.canEncodeVideo;if(typeof n!=`function`)return e.policy.preferredVideoCodec;let r=Zv(e.overrideCodec,e.policy),a={};e.width!==void 0&&(a.width=e.width),e.height!==void 0&&(a.height=e.height),e.bitrate!==void 0&&(a.bitrate=e.bitrate);let o=[];for(let e of Kv){let t={...a,hardwareAcceleration:e},i=await Promise.all(r.map(e=>ey(n,e,t)));o.push(...i);for(let e of i)if(e.kind===`supported`)return e.codec}let s=o.filter(e=>e.kind===`error`).map(e=>`${e.codec}: ${i(e.error)}`);if(e.dependencies?.loadMediabunnyModule===void 0&&s.length===0&&typeof VideoEncoder>`u`)return e.policy.preferredVideoCodec;throw $v(e.format,r,s)}async function ny(e){let t=await Yv(e.dependencies).loadMediabunnyModule();if(t===null)return e.policy.preferredAudioCodec;let n=t.getFirstEncodableAudioCodec;if(typeof n!=`function`)return e.policy.preferredAudioCodec;let r=Qv(e.overrideCodec,e.policy),i={};e.bitrate!==void 0&&(i.bitrate=e.bitrate);let a=(await Promise.allSettled([n(r,i)]))[0];if(a.status===`rejected`)return e.policy.preferredAudioCodec;let o=a.value;if(o===null){if(e.shouldThrowIfNoCodecAvailable)throw Error(`No encodable audio codec available for format: ${e.format}`);return e.policy.preferredAudioCodec}if(r.includes(o))return o;if(e.shouldThrowIfNoCodecAvailable)throw Error(`No encodable audio codec available for format: ${e.format}`);return e.policy.preferredAudioCodec}Sv();function ry(e){if(typeof e==`string`)return new lu(e);if(e instanceof Blob)return new iu(e);throw Error(`Invalid input type. Expected Blob, File, or file path string.`)}function iy(e){switch(e){case`mp4`:return new U_;case`webm`:return new q_;case`mkv`:return new K_;case`mov`:return new G_;default:throw Error(`Unsupported output format: ${e}`)}}function ay(e){switch(e){case`mp4`:return`video/mp4`;case`webm`:return`video/webm`;case`mkv`:return`video/x-matroska`;case`mov`:return`video/quicktime`;default:throw Error(`Unsupported output format: ${e}`)}}function oy(e,t=!1){let n={fit:`contain`,forceTranscode:!0,allowRotationMetadata:!1};return e.width!==void 0&&(n.width=e.width),e.height!==void 0&&(n.height=e.height),e.fps!==void 0&&(n.frameRate=e.fps),e.bitrate!==void 0&&(n.bitrate=e.bitrate),e.codec!==void 0&&(n.codec=e.codec),t&&(n.bitrateMode=`variable`,n.latencyMode=`realtime`,n.hardwareAcceleration=`prefer-hardware`,n.keyFrameInterval=2),{video:n,audio:{codec:e.audioCodec,forceTranscode:!0,...t&&{bitrateMode:`variable`}}}}function sy(e){if(!e.isValid){let t=e.discardedTracks.map(e=>e.reason).join(`, `);throw Error(`Conversion is invalid. Discarded tracks: ${t}`)}}async function cy(e,t={},n){let r=t.format;r===void 0&&(r=Xt.format);let i={...Xt,...t,format:r},a=ry(e),o=Ht(i.format,{isLinuxPlatform:on()});i.audioBitrate===void 0&&(i.audioBitrate=Kt(i.format)),i.audioCodec=await ny({format:i.format,overrideCodec:i.audioCodec,policy:o,bitrate:i.audioBitrate}),i.codec=await ty({format:i.format,overrideCodec:i.codec,policy:o,width:i.width,height:i.height,bitrate:i.bitrate});let s=new yp({formats:ed,source:a}),c=new lv({format:iy(i.format),target:new fg}),l=await hv.init({input:s,output:c,...oy(i)});sy(l),n&&(l.onProgress=n),await l.execute();let u=c.target.buffer;if(!u)throw Error(`Transcoding completed but no output buffer was generated`);let d=ay(i.format);return{buffer:u,blob:new Blob([u],{type:d})}}async function ly(e,t={},n){let r=t.format;r===void 0&&(r=Xt.format);let i={...Xt,...t,format:r},a=Ht(i.format,{isLinuxPlatform:on()});i.audioBitrate===void 0&&(i.audioBitrate=Kt(i.format)),i.audioCodec=await ny({format:i.format,overrideCodec:i.audioCodec,policy:a,bitrate:i.audioBitrate}),i.codec=await ty({format:i.format,overrideCodec:i.codec,policy:a,width:i.width,height:i.height,bitrate:i.bitrate});let o=new yp({formats:ed,source:new iu(e)}),s=new lv({format:iy(i.format),target:new fg}),c=await hv.init({input:o,output:s,video:{codec:i.codec,width:i.width,height:i.height,frameRate:i.fps,bitrate:i.bitrate,fit:`contain`,allowRotationMetadata:!1},audio:{codec:i.audioCodec}});sy(c),n&&(c.onProgress=n),await c.execute();let l=s.target.buffer;if(!l)throw Error(`Transcoding completed but no output buffer was generated`);let u=ay(i.format);return{buffer:l,blob:new Blob([l],{type:u})}}function uy(e,t=1e4){return new Promise((n,r)=>{let i=document.createElement(`video`);i.preload=`metadata`,i.muted=!0;let a=setTimeout(()=>{o(),r(Error(`Preview extraction timeout`))},t),o=()=>{clearTimeout(a),URL.revokeObjectURL(i.src)};i.addEventListener(`loadedmetadata`,()=>{i.currentTime=Math.max(0,i.duration-.1)}),i.addEventListener(`seeked`,()=>{let e=document.createElement(`canvas`);e.width=i.videoWidth,e.height=i.videoHeight;let t=e.getContext(`2d`);if(!t){o(),r(Error(`Canvas context unavailable`));return}if(i.videoWidth===0||i.videoHeight===0){o(),r(Error(`Invalid video dimensions`));return}if(!(Number.isFinite(i.videoWidth)&&Number.isFinite(i.videoHeight))){o(),r(Error(`Invalid video dimensions`));return}t.drawImage(i,0,0,e.width,e.height),e.toBlob(e=>{o(),e?n(e):r(Error(`Failed to create preview blob`))},`image/jpeg`,.8)}),i.addEventListener(`error`,()=>{o(),r(Error(`Failed to load video for preview extraction`))}),i.src=URL.createObjectURL(e)})}var dy=class{constructor(e,t,n){this.pendingFile=null,this.configService=null,this.config=e,this.configService=t,this.uploadService=n}async handleFileSelection(e){let t=await Ev(e,{maxFileSize:this.config.maxFileSize===void 0?2*1024*1024*1024:this.config.maxFileSize,maxRecordingTime:this.config.maxRecordingTime,allowedFormats:[`video/mp4`,`video/quicktime`,`video/webm`]});if(!t.valid)throw Error(t.error);let n=await uy(e),r=URL.createObjectURL(n),a=await Cv(e).then(e=>({success:!0,duration:e})).catch(e=>({success:!1,error:i(e)}));if(a.success===!1)throw Error(`Failed to extract video duration: ${a.error}`);let o=a.duration;return this.pendingFile=e,{file:e,previewUrl:r,duration:o,validated:!0}}async processAndUpload(e,t){if(!this.pendingFile)throw Error(`No file selected`);let n=this.configService?await this.configService.fetchConfig():Xt,r=await this.resolveNativeCameraRouteDecision(n);if(r.route===`unsupported-with-guidance`)throw Error(r.guidance?.message??`This browser or device cannot safely process this video. Try another browser or upload from a different device.`);let i=(await ly(this.pendingFile,n,e)).blob;if(!(this.config.apiKey&&this.config.backendUrl))throw Error(`Upload requires API key and backend URL`);let a=await this.uploadService.uploadVideo(i,{apiKey:this.config.apiKey,backendUrl:this.config.backendUrl,filename:this.resolveUploadFilename(i),userMetadata:this.config.userMetadata,onProgress:t});return this.pendingFile=null,{blob:i,recordingId:a.id,uploadUrl:a.uploadUrl||``}}async resolveNativeCameraRouteDecision(e){let t=this.buildCodecProbeCandidates(e);return Gv({profile:await Lv({codecCandidates:t}),targetCodecIds:t.map(e=>e.id)})}buildCodecProbeCandidates(e){let t=e.width??1280,n=e.height??720,r=typeof e.bitrate==`number`?e.bitrate:25e5,i=e.fps??30;return this.resolveTargetCodecIds(e.codec).map(e=>({id:`${e}-${t}x${n}`,config:{codec:e,width:t,height:n,bitrate:r,framerate:i}}))}resolveTargetCodecIds(e){switch(e){case`avc`:return[`avc1.640028`,`avc1.42001f`];case`vp9`:return[`vp09.00.10.08`];case`vp8`:return[`vp8`];case`av1`:return[`av01.0.08M.08`];case`hevc`:return[`hvc1.1.6.L123.B0`];default:return[`avc1.640028`,`avc1.42001f`,`vp09.00.10.08`,`vp8`]}}resolveUploadFilename(e){let t=this.resolveUploadExtension(e.type);return`${Date.now()}.${t}`}resolveUploadExtension(e){switch(e){case`video/webm`:return`webm`;case`video/quicktime`:return`mov`;default:return`mp4`}}cancel(){this.pendingFile=null}async preloadConfig(){this.configService&&await this.configService.fetchConfig()}};let fy={isLinuxPlatform:on()};Ht(`mp4`,fy).preferredAudioCodec,Ht(`mov`,fy).preferredAudioCodec,Ht(`mkv`,fy).preferredAudioCodec,Ht(`webm`,fy).preferredAudioCodec;let py=`recording.invalid-container-layout`,my=`recording.no-video-track`,hy=`recording.no-audio-track`,gy=`moov`,_y=`trak`,vy=`stsz`,yy=`soun`;function by(e){return e>=6e3&&e<=384e3}function xy(e){let t=Error(py);return t.code=py,t.detectedBoxTypes=e,t}function Sy(e){let t=Error(e);return t.code=e,t}function Cy(e){return e instanceof Uint8Array?e:new Uint8Array(e)}function wy(e,t){let n=e.getUint8(t),r=e.getUint8(t+1),i=e.getUint8(t+2),a=e.getUint8(t+3);return String.fromCharCode(n,r,i,a)}function Ty(e,t){let n=e.getUint32(t,!1),r=e.getUint32(t+4,!1);return n*4294967296+r}function Ey(e){let t=new Set;for(let n of e)t.add(n);return[...t]}function Dy(e,t,n){let r=new DataView(e.buffer,e.byteOffset,e.byteLength),i=[],a=t;for(;a<n;){if(!(a+8<=n))throw xy(i.map(e=>e.type));let e=r.getUint32(a,!1),t=wy(r,a+4),o=e,s=8;if(e===1){let e=a+8;if(!(e+8<=n))throw xy(i.map(e=>e.type));o=Ty(r,e),s=16}if(e===0&&(o=n-a),!(o>=s))throw xy(i.map(e=>e.type));let c=a+o;if(!(c<=n))throw xy(i.map(e=>e.type));let l=a+s;i.push({type:t,size:o,startOffset:a,endOffset:c,payloadStartOffset:l}),a=c}return i}function Oy(e,t){for(let n of e)if(n.type===t)return n;return null}function ky(e,t,n){if(!(t+4<=n))throw xy([]);return wy(e,t)}function Ay(e,t){let n=Oy(t,`mdhd`);if(n===null||n.endOffset-n.payloadStartOffset<16||e.getUint8(n.payloadStartOffset)!==0)return 0;let r=n.payloadStartOffset+8,i=n.payloadStartOffset+12,a=e.getUint32(r,!1),o=e.getUint32(i,!1);return a===0?0:o/a}function jy(e,t){let n=Oy(t,`stsd`);if(n===null)return{channelCount:0,sampleRate:0};let r=n.payloadStartOffset+4+4+8;if(r+28>n.endOffset)return{channelCount:0,sampleRate:0};let i=e.getUint16(r+16,!1),a=e.getUint32(r+24,!1);return{channelCount:i,sampleRate:Math.floor(a/65536)}}function My(e,t,n){let r=new DataView(e.buffer,e.byteOffset,e.byteLength),i=Oy(Dy(e,t.payloadStartOffset,t.endOffset),`mdia`);if(i===null)return{isMatchingTrack:!1,sampleCount:0,channelCount:0,sampleRate:0,durationSeconds:0};let a=Dy(e,i.payloadStartOffset,i.endOffset),o=Oy(a,`hdlr`);if(o===null||ky(r,o.payloadStartOffset+8,o.endOffset)!==n)return{isMatchingTrack:!1,sampleCount:0,channelCount:0,sampleRate:0,durationSeconds:0};let s=Ay(r,a),c=Oy(a,`minf`);if(c===null)return{isMatchingTrack:!0,sampleCount:0,channelCount:0,sampleRate:0,durationSeconds:s};let l=Oy(Dy(e,c.payloadStartOffset,c.endOffset),`stbl`);if(l===null)return{isMatchingTrack:!0,sampleCount:0,channelCount:0,sampleRate:0,durationSeconds:s};let u=Dy(e,l.payloadStartOffset,l.endOffset),d=Oy(u,vy);if(d===null)return{isMatchingTrack:!0,sampleCount:0,channelCount:0,sampleRate:0,durationSeconds:s};let f=d.payloadStartOffset+8;if(!(f+4<=d.endOffset))throw xy([vy]);return{isMatchingTrack:!0,sampleCount:r.getUint32(f,!1),...n===yy?jy(r,u):{channelCount:0,sampleRate:0},durationSeconds:s}}function Ny(e){let t=Cy(e),n=t.byteLength,r=new DataView(t.buffer,t.byteOffset,t.byteLength),i=[],a=0;for(;a<n;){if(!(a+8<=n))throw xy(i.map(e=>e.type));let e=r.getUint32(a,!1),t=wy(r,a+4),o=e,s=8;if(e===1){let e=a+8;if(!(e+8<=n))throw xy(i.map(e=>e.type));o=Ty(r,e),s=16}if(e===0&&(o=n-a),!(o>=s))throw xy(i.map(e=>e.type));let c=a+o;if(!(c<=n))throw xy(i.map(e=>e.type));i.push({type:t,size:o,startOffset:a,endOffset:c}),a=c}return i}function Py(e){let t=Ny(e).filter(e=>e.type===`moof`||e.type===`mfra`).map(e=>e.type);if(t.length>0)throw xy(Ey(t))}function Fy(e){let t=Cy(e),n=Oy(Dy(t,0,t.byteLength),gy);if(n===null)throw Sy(my);let r=Dy(t,n.payloadStartOffset,n.endOffset).filter(e=>e.type===_y);if(r.length===0)throw Sy(my);let i=!1;for(let e of r){let n=My(t,e,`vide`);if(n.isMatchingTrack&&(i=!0,n.sampleCount>0))return}throw Sy(i?`recording.no-video-frames`:my)}function Iy(e){let t=Cy(e),n=Oy(Dy(t,0,t.byteLength),gy);if(n===null)throw Sy(hy);let r=Dy(t,n.payloadStartOffset,n.endOffset).filter(e=>e.type===_y);if(r.length===0)throw Sy(hy);let i=!1;for(let e of r){let n=My(t,e,yy);if(n.isMatchingTrack&&(i=!0,n.sampleCount!==0)){if(n.channelCount===0)throw Sy(`recording.audio-zero-channels`);if(!by(n.sampleRate))throw Sy(`recording.audio-invalid-sample-rate`);return}}throw Sy(i?`recording.no-audio-frames`:hy)}function Ly(){return new Blob([`"use strict";
126
+ Mediabunny was loaded twice. This will likely cause Mediabunny not to work correctly. Check if multiple dependencies are importing different versions of Mediabunny, or if something is being bundled incorrectly.`),globalThis[xv]=!0}));Sv();async function Cv(e){try{let t=new iu(e),n=new yp({formats:[Uu],source:t});if(typeof n.computeDuration!=`function`)throw Error(`computeDuration method is not available`);let r=await n.computeDuration();if(!r)throw Error(`Duration is missing from computeDuration`);if(r<=0)throw Error(`Invalid duration: must be greater than 0`);return r}catch{return wv(e)}}function wv(e){return new Promise((t,n)=>{let r=document.createElement(`video`),i=URL.createObjectURL(e),a=()=>{URL.revokeObjectURL(i)};r.addEventListener(`loadedmetadata`,()=>{a();let e=r.duration;if(!Number.isFinite(e)||e<=0){n(Error(`Invalid video duration`));return}t(e)}),r.addEventListener(`error`,()=>{a(),n(Error(`Failed to load video metadata`))}),r.src=i,r.load()})}let Tv=[`video/mp4`,`video/quicktime`,`video/webm`];async function Ev(e,t={}){let n=t.maxFileSize===void 0?524288e3:t.maxFileSize;if(e.size>n)return{valid:!1,error:`File too large. Maximum size is ${Math.round(n/1024/1024)}MB`};let r=t.allowedFormats===void 0?Tv:t.allowedFormats;if(!r.includes(e.type))return{valid:!1,error:`Unsupported format. Please use: ${r.join(`, `)}`};let a=await Cv(e).then(e=>({success:!0,duration:e})).catch(e=>({success:!1,error:i(e)}));if(a.success===!1)return{valid:!1,error:`Failed to read video file: ${a.error}`};let o=a.duration;return t.maxRecordingTime!==null&&t.maxRecordingTime!==void 0&&o>t.maxRecordingTime?{valid:!1,error:`Video too long. Maximum duration is ${t.maxRecordingTime} seconds`}:{valid:!0}}let Dv=`unknown`;function Ov(){if(typeof navigator>`u`)return null;let e=navigator;return{userAgent:e.userAgent,platform:e.platform,hardwareConcurrency:e.hardwareConcurrency,deviceMemory:e.deviceMemory,onLine:e.onLine,connection:e.connection}}function kv(){return globalThis.isSecureContext===!0}function Av(){return globalThis.MediaRecorder!==void 0}function jv(){return globalThis.VideoEncoder!==void 0}function Mv(e){return globalThis.VideoEncoder===void 0?Promise.resolve({config:e,supported:!1}):globalThis.VideoEncoder.isConfigSupported(e)}function Nv(e){return{navigatorProvider:e?.navigatorProvider??Ov(),secureContextProvider:e?.secureContextProvider??kv,mediaRecorderAvailabilityProvider:e?.mediaRecorderAvailabilityProvider??Av,videoEncoderAvailabilityProvider:e?.videoEncoderAvailabilityProvider??jv,codecSupportProbe:e?.codecSupportProbe??Mv}}function Pv(e){let t=new wt(e??``).getResult(),n=t.browser.name??Dv;return{browser:{name:n,version:t.browser.version??``,normalizedName:n.toLowerCase()},os:{name:t.os.name??Dv,version:t.os.version??``}}}function Fv(e){return e instanceof Error?e.message:String(e)}async function Iv(e,t){try{let n=await t(e.config);return{id:e.id,config:e.config,supported:n.supported===!0}}catch(t){return{id:e.id,config:e.config,supported:!1,errorCode:`codec-probe-error`,errorMessage:Fv(t)}}}async function Lv(e={}){let t=Nv(e.dependencies),{browser:n,os:r}=Pv(t.navigatorProvider?.userAgent),i=await Promise.all((e.codecCandidates??[]).map(e=>Iv(e,t.codecSupportProbe)));return{browser:n,os:r,resources:{deviceMemory:t.navigatorProvider?.deviceMemory,hardwareConcurrency:t.navigatorProvider?.hardwareConcurrency},network:{online:t.navigatorProvider?.onLine,effectiveType:t.navigatorProvider?.connection?.effectiveType},features:{isSecureContext:t.secureContextProvider(),hasMediaRecorder:t.mediaRecorderAvailabilityProvider(),hasVideoEncoder:t.videoEncoderAvailabilityProvider()},codecProbeResults:i}}function Rv(e,t){let n=e.resources.deviceMemory;return n===void 0||n>=t}function zv(e,t){let n=e.resources.hardwareConcurrency;return n===void 0||n>=t}function Bv(e,t){let n=new Set(t);return e.codecProbeResults.find(e=>n.has(e.id)&&e.supported)?.id}function Vv(e,t){return e.features.isSecureContext&&e.features.hasMediaRecorder&&e.features.hasVideoEncoder&&t&&e.network.online!==!1}function Hv(e){return e.os.name.toLowerCase()===`android`}function Uv(e,t,n,r){let i=[];return e.features.isSecureContext||i.push(`insecure-context`),e.features.hasVideoEncoder||i.push(`webcodecs-unavailable`),t||i.push(`target-codec-unsupported`),n||i.push(`insufficient-device-memory`),r||i.push(`insufficient-hardware-concurrency`),Hv(e)&&i.push(`android-post-recording-transcode`),i}function Wv(e){let t=[];return e.features.hasMediaRecorder||t.push(`mediarecorder-unavailable`),e.network.online===!1&&t.push(`offline`),t}function Gv(e){let t=e.resourceThresholds?.minDeviceMemory??4,n=e.resourceThresholds?.minHardwareConcurrency??4,r=Bv(e.profile,e.targetCodecIds),i=r!==void 0,a=Rv(e.profile,t),o=zv(e.profile,n),s=Uv(e.profile,i,a,o);return e.profile.features.isSecureContext&&e.profile.features.hasVideoEncoder&&i&&e.profile.network.online!==!1&&!Hv(e.profile)&&a&&o?{route:`local-webcodecs`,reasonCodes:[`webcodecs-supported`,`target-codec-supported`],selectedCodecId:r}:Vv(e.profile,i)?{route:`safe-capture-post-recording-transcode`,reasonCodes:[...s,`mediarecorder-supported`],selectedCodecId:r}:{route:`unsupported-with-guidance`,reasonCodes:[...s,...Wv(e.profile)],guidance:{canRetry:!0,message:`Recording is not supported in this browser context. Use a secure connection, go online, and try a current Chrome or Edge browser.`}}}let Kv=[`prefer-hardware`,`no-preference`,`prefer-software`];async function qv(){let e=(await Promise.allSettled([Promise.resolve().then(()=>(Sv(),bv))]))[0];return e.status===`fulfilled`?e.value:null}let Jv={loadMediabunnyModule:qv};function Yv(e){let t=e?.loadMediabunnyModule,n;return n=t===void 0?Jv.loadMediabunnyModule:t,{loadMediabunnyModule:n}}function Xv(e,t){return t===void 0||e.includes(t)?e:[...e,t]}function Zv(e,t){let n=[];e!==void 0&&t.videoCodecFallbackOrder.includes(e)&&(n=Xv(n,e)),n=Xv(n,t.preferredVideoCodec);for(let e of t.videoCodecFallbackOrder)n=Xv(n,e);return n}function Qv(e,t){let n=[];e!==void 0&&t.audioCodecFallbackOrder.includes(e)&&(n=Xv(n,e)),n=Xv(n,t.preferredAudioCodec);for(let e of t.audioCodecFallbackOrder)n=Xv(n,e);return n}function $v(e,t,n){let r=Error(`No encodable video codec available for format: ${e}`);return r.code=`recording.video-codec-unavailable`,r.details={candidates:t,format:e,probeErrors:n},r}async function ey(e,t,n){try{return await e(t,n)?{kind:`supported`,codec:t}:{kind:`unsupported`,codec:t}}catch(e){return{kind:`error`,codec:t,error:e}}}async function ty(e){let t=await Yv(e.dependencies).loadMediabunnyModule();if(t===null)return e.policy.preferredVideoCodec;let n=t.canEncodeVideo;if(typeof n!=`function`)return e.policy.preferredVideoCodec;let r=Zv(e.overrideCodec,e.policy),a={};e.width!==void 0&&(a.width=e.width),e.height!==void 0&&(a.height=e.height),e.bitrate!==void 0&&(a.bitrate=e.bitrate);let o=[];for(let e of Kv){let t={...a,hardwareAcceleration:e},i=await Promise.all(r.map(e=>ey(n,e,t)));o.push(...i);for(let e of i)if(e.kind===`supported`)return e.codec}let s=o.filter(e=>e.kind===`error`).map(e=>`${e.codec}: ${i(e.error)}`);if(e.dependencies?.loadMediabunnyModule===void 0&&s.length===0&&typeof VideoEncoder>`u`)return e.policy.preferredVideoCodec;throw $v(e.format,r,s)}async function ny(e){let t=await Yv(e.dependencies).loadMediabunnyModule();if(t===null)return e.policy.preferredAudioCodec;let n=t.getFirstEncodableAudioCodec;if(typeof n!=`function`)return e.policy.preferredAudioCodec;let r=Qv(e.overrideCodec,e.policy),i={};e.bitrate!==void 0&&(i.bitrate=e.bitrate);let a=(await Promise.allSettled([n(r,i)]))[0];if(a.status===`rejected`)return e.policy.preferredAudioCodec;let o=a.value;if(o===null){if(e.shouldThrowIfNoCodecAvailable)throw Error(`No encodable audio codec available for format: ${e.format}`);return e.policy.preferredAudioCodec}if(r.includes(o))return o;if(e.shouldThrowIfNoCodecAvailable)throw Error(`No encodable audio codec available for format: ${e.format}`);return e.policy.preferredAudioCodec}function ry(e){switch(e){case`mp4`:return`video/mp4`;case`webm`:return`video/webm`;case`mkv`:return`video/x-matroska`;case`mov`:return`video/quicktime`;default:throw Error(`Unsupported output format: ${e}`)}}function iy(e){switch(e){case`mp4`:return`mp4`;case`webm`:return`webm`;case`mkv`:return`mkv`;case`mov`:return`mov`;default:throw Error(`Unsupported output format: ${e}`)}}Sv();function ay(e){if(typeof e==`string`)return new lu(e);if(e instanceof Blob)return new iu(e);throw Error(`Invalid input type. Expected Blob, File, or file path string.`)}function oy(e){switch(e){case`mp4`:return new U_;case`webm`:return new q_;case`mkv`:return new K_;case`mov`:return new G_;default:throw Error(`Unsupported output format: ${e}`)}}function sy(e,t=!1){let n={fit:`contain`,forceTranscode:!0,allowRotationMetadata:!1};return e.width!==void 0&&(n.width=e.width),e.height!==void 0&&(n.height=e.height),e.fps!==void 0&&(n.frameRate=e.fps),e.bitrate!==void 0&&(n.bitrate=e.bitrate),e.codec!==void 0&&(n.codec=e.codec),t&&(n.bitrateMode=`variable`,n.latencyMode=`realtime`,n.hardwareAcceleration=`prefer-hardware`,n.keyFrameInterval=2),{video:n,audio:{codec:e.audioCodec,forceTranscode:!0,...t&&{bitrateMode:`variable`}}}}function cy(e){if(!e.isValid){let t=e.discardedTracks.map(e=>e.reason).join(`, `);throw Error(`Conversion is invalid. Discarded tracks: ${t}`)}}async function ly(e,t={},n){let r=t.format;r===void 0&&(r=Xt.format);let i={...Xt,...t,format:r},a=ay(e),o=Ht(i.format,{isLinuxPlatform:on()});i.audioBitrate===void 0&&(i.audioBitrate=Kt(i.format)),i.audioCodec=await ny({format:i.format,overrideCodec:i.audioCodec,policy:o,bitrate:i.audioBitrate}),i.codec=await ty({format:i.format,overrideCodec:i.codec,policy:o,width:i.width,height:i.height,bitrate:i.bitrate});let s=new yp({formats:ed,source:a}),c=new lv({format:oy(i.format),target:new fg}),l=await hv.init({input:s,output:c,...sy(i)});cy(l),n&&(l.onProgress=n),await l.execute();let u=c.target.buffer;if(!u)throw Error(`Transcoding completed but no output buffer was generated`);let d=ry(i.format);return{buffer:u,blob:new Blob([u],{type:d})}}async function uy(e,t={},n){let r=t.format;r===void 0&&(r=Xt.format);let i={...Xt,...t,format:r},a=Ht(i.format,{isLinuxPlatform:on()});i.audioBitrate===void 0&&(i.audioBitrate=Kt(i.format)),i.audioCodec=await ny({format:i.format,overrideCodec:i.audioCodec,policy:a,bitrate:i.audioBitrate}),i.codec=await ty({format:i.format,overrideCodec:i.codec,policy:a,width:i.width,height:i.height,bitrate:i.bitrate});let o=new yp({formats:ed,source:new iu(e)}),s=new lv({format:oy(i.format),target:new fg}),c=await hv.init({input:o,output:s,video:{codec:i.codec,width:i.width,height:i.height,frameRate:i.fps,bitrate:i.bitrate,fit:`contain`,allowRotationMetadata:!1},audio:{codec:i.audioCodec}});cy(c),n&&(c.onProgress=n),await c.execute();let l=s.target.buffer;if(!l)throw Error(`Transcoding completed but no output buffer was generated`);let u=ry(i.format);return{buffer:l,blob:new Blob([l],{type:u})}}function dy(e,t=1e4){return new Promise((n,r)=>{let i=document.createElement(`video`);i.preload=`metadata`,i.muted=!0;let a=setTimeout(()=>{o(),r(Error(`Preview extraction timeout`))},t),o=()=>{clearTimeout(a),URL.revokeObjectURL(i.src)};i.addEventListener(`loadedmetadata`,()=>{i.currentTime=Math.max(0,i.duration-.1)}),i.addEventListener(`seeked`,()=>{let e=document.createElement(`canvas`);e.width=i.videoWidth,e.height=i.videoHeight;let t=e.getContext(`2d`);if(!t){o(),r(Error(`Canvas context unavailable`));return}if(i.videoWidth===0||i.videoHeight===0){o(),r(Error(`Invalid video dimensions`));return}if(!(Number.isFinite(i.videoWidth)&&Number.isFinite(i.videoHeight))){o(),r(Error(`Invalid video dimensions`));return}t.drawImage(i,0,0,e.width,e.height),e.toBlob(e=>{o(),e?n(e):r(Error(`Failed to create preview blob`))},`image/jpeg`,.8)}),i.addEventListener(`error`,()=>{o(),r(Error(`Failed to load video for preview extraction`))}),i.src=URL.createObjectURL(e)})}var fy=class{constructor(e,t,n){this.pendingFile=null,this.configService=null,this.config=e,this.configService=t,this.uploadService=n}async handleFileSelection(e){let t=await Ev(e,{maxFileSize:this.config.maxFileSize===void 0?2*1024*1024*1024:this.config.maxFileSize,maxRecordingTime:this.config.maxRecordingTime,allowedFormats:[`video/mp4`,`video/quicktime`,`video/webm`]});if(!t.valid)throw Error(t.error);let n=await dy(e),r=URL.createObjectURL(n),a=await Cv(e).then(e=>({success:!0,duration:e})).catch(e=>({success:!1,error:i(e)}));if(a.success===!1)throw Error(`Failed to extract video duration: ${a.error}`);let o=a.duration;return this.pendingFile=e,{file:e,previewUrl:r,duration:o,validated:!0}}async processAndUpload(e,t){if(!this.pendingFile)throw Error(`No file selected`);let n=this.configService?await this.configService.fetchConfig():Xt,r=await this.resolveNativeCameraRouteDecision(n);if(r.route===`unsupported-with-guidance`)throw Error(r.guidance?.message??`This browser or device cannot safely process this video. Try another browser or upload from a different device.`);let i=(await uy(this.pendingFile,n,e)).blob;if(!(this.config.apiKey&&this.config.backendUrl))throw Error(`Upload requires API key and backend URL`);let a=await this.uploadService.uploadVideo(i,{apiKey:this.config.apiKey,backendUrl:this.config.backendUrl,filename:this.resolveUploadFilename(i),userMetadata:this.config.userMetadata,onProgress:t});return this.pendingFile=null,{blob:i,recordingId:a.id,uploadUrl:a.uploadUrl||``}}async resolveNativeCameraRouteDecision(e){let t=this.buildCodecProbeCandidates(e);return Gv({profile:await Lv({codecCandidates:t}),targetCodecIds:t.map(e=>e.id)})}buildCodecProbeCandidates(e){let t=e.width??1280,n=e.height??720,r=typeof e.bitrate==`number`?e.bitrate:25e5,i=e.fps??30;return this.resolveTargetCodecIds(e.codec).map(e=>({id:`${e}-${t}x${n}`,config:{codec:e,width:t,height:n,bitrate:r,framerate:i}}))}resolveTargetCodecIds(e){switch(e){case`avc`:return[`avc1.640028`,`avc1.42001f`];case`vp9`:return[`vp09.00.10.08`];case`vp8`:return[`vp8`];case`av1`:return[`av01.0.08M.08`];case`hevc`:return[`hvc1.1.6.L123.B0`];default:return[`avc1.640028`,`avc1.42001f`,`vp09.00.10.08`,`vp8`]}}resolveUploadFilename(e){let t=this.resolveUploadExtension(e.type);return`${Date.now()}.${t}`}resolveUploadExtension(e){switch(e){case`video/webm`:return`webm`;case`video/quicktime`:return`mov`;default:return`mp4`}}cancel(){this.pendingFile=null}async preloadConfig(){this.configService&&await this.configService.fetchConfig()}};let py={isLinuxPlatform:on()};Ht(`mp4`,py).preferredAudioCodec,Ht(`mov`,py).preferredAudioCodec,Ht(`mkv`,py).preferredAudioCodec,Ht(`webm`,py).preferredAudioCodec;let my=`recording.invalid-container-layout`,hy=`recording.no-video-track`,gy=`recording.no-audio-track`,_y=`moov`,vy=`trak`,yy=`stsz`,by=`soun`;function xy(e){return e>=6e3&&e<=384e3}function Sy(e){let t=Error(my);return t.code=my,t.detectedBoxTypes=e,t}function Cy(e){let t=Error(e);return t.code=e,t}function wy(e){return e instanceof Uint8Array?e:new Uint8Array(e)}function Ty(e,t){let n=e.getUint8(t),r=e.getUint8(t+1),i=e.getUint8(t+2),a=e.getUint8(t+3);return String.fromCharCode(n,r,i,a)}function Ey(e,t){let n=e.getUint32(t,!1),r=e.getUint32(t+4,!1);return n*4294967296+r}function Dy(e){let t=new Set;for(let n of e)t.add(n);return[...t]}function Oy(e,t,n){let r=new DataView(e.buffer,e.byteOffset,e.byteLength),i=[],a=t;for(;a<n;){if(!(a+8<=n))throw Sy(i.map(e=>e.type));let e=r.getUint32(a,!1),t=Ty(r,a+4),o=e,s=8;if(e===1){let e=a+8;if(!(e+8<=n))throw Sy(i.map(e=>e.type));o=Ey(r,e),s=16}if(e===0&&(o=n-a),!(o>=s))throw Sy(i.map(e=>e.type));let c=a+o;if(!(c<=n))throw Sy(i.map(e=>e.type));let l=a+s;i.push({type:t,size:o,startOffset:a,endOffset:c,payloadStartOffset:l}),a=c}return i}function ky(e,t){for(let n of e)if(n.type===t)return n;return null}function Ay(e,t,n){if(!(t+4<=n))throw Sy([]);return Ty(e,t)}function jy(e,t){let n=ky(t,`mdhd`);if(n===null||n.endOffset-n.payloadStartOffset<16||e.getUint8(n.payloadStartOffset)!==0)return 0;let r=n.payloadStartOffset+8,i=n.payloadStartOffset+12,a=e.getUint32(r,!1),o=e.getUint32(i,!1);return a===0?0:o/a}function My(e,t){let n=ky(t,`stsd`);if(n===null)return{channelCount:0,sampleRate:0};let r=n.payloadStartOffset+4+4+8;if(r+28>n.endOffset)return{channelCount:0,sampleRate:0};let i=e.getUint16(r+16,!1),a=e.getUint32(r+24,!1);return{channelCount:i,sampleRate:Math.floor(a/65536)}}function Ny(e,t,n){let r=new DataView(e.buffer,e.byteOffset,e.byteLength),i=ky(Oy(e,t.payloadStartOffset,t.endOffset),`mdia`);if(i===null)return{isMatchingTrack:!1,sampleCount:0,channelCount:0,sampleRate:0,durationSeconds:0};let a=Oy(e,i.payloadStartOffset,i.endOffset),o=ky(a,`hdlr`);if(o===null||Ay(r,o.payloadStartOffset+8,o.endOffset)!==n)return{isMatchingTrack:!1,sampleCount:0,channelCount:0,sampleRate:0,durationSeconds:0};let s=jy(r,a),c=ky(a,`minf`);if(c===null)return{isMatchingTrack:!0,sampleCount:0,channelCount:0,sampleRate:0,durationSeconds:s};let l=ky(Oy(e,c.payloadStartOffset,c.endOffset),`stbl`);if(l===null)return{isMatchingTrack:!0,sampleCount:0,channelCount:0,sampleRate:0,durationSeconds:s};let u=Oy(e,l.payloadStartOffset,l.endOffset),d=ky(u,yy);if(d===null)return{isMatchingTrack:!0,sampleCount:0,channelCount:0,sampleRate:0,durationSeconds:s};let f=d.payloadStartOffset+8;if(!(f+4<=d.endOffset))throw Sy([yy]);return{isMatchingTrack:!0,sampleCount:r.getUint32(f,!1),...n===by?My(r,u):{channelCount:0,sampleRate:0},durationSeconds:s}}function Py(e){let t=wy(e),n=t.byteLength,r=new DataView(t.buffer,t.byteOffset,t.byteLength),i=[],a=0;for(;a<n;){if(!(a+8<=n))throw Sy(i.map(e=>e.type));let e=r.getUint32(a,!1),t=Ty(r,a+4),o=e,s=8;if(e===1){let e=a+8;if(!(e+8<=n))throw Sy(i.map(e=>e.type));o=Ey(r,e),s=16}if(e===0&&(o=n-a),!(o>=s))throw Sy(i.map(e=>e.type));let c=a+o;if(!(c<=n))throw Sy(i.map(e=>e.type));i.push({type:t,size:o,startOffset:a,endOffset:c}),a=c}return i}function Fy(e){let t=Py(e).filter(e=>e.type===`moof`||e.type===`mfra`).map(e=>e.type);if(t.length>0)throw Sy(Dy(t))}function Iy(e){let t=wy(e),n=ky(Oy(t,0,t.byteLength),_y);if(n===null)throw Cy(hy);let r=Oy(t,n.payloadStartOffset,n.endOffset).filter(e=>e.type===vy);if(r.length===0)throw Cy(hy);let i=!1;for(let e of r){let n=Ny(t,e,`vide`);if(n.isMatchingTrack&&(i=!0,n.sampleCount>0))return}throw Cy(i?`recording.no-video-frames`:hy)}function Ly(e){let t=wy(e),n=ky(Oy(t,0,t.byteLength),_y);if(n===null)throw Cy(gy);let r=Oy(t,n.payloadStartOffset,n.endOffset).filter(e=>e.type===vy);if(r.length===0)throw Cy(gy);let i=!1;for(let e of r){let n=Ny(t,e,by);if(n.isMatchingTrack&&(i=!0,n.sampleCount!==0)){if(n.channelCount===0)throw Cy(`recording.audio-zero-channels`);if(!xy(n.sampleRate))throw Cy(`recording.audio-invalid-sample-rate`);return}}throw Cy(i?`recording.no-audio-frames`:gy)}function Ry(){return new Blob([`"use strict";
127
127
  var PROBE_MESSAGE_TYPE="probe";
128
128
  var PROBE_RESULT_TYPE="probeResult";
129
129
  self.onmessage=function(e){
@@ -137,11 +137,11 @@ hasOffscreenCanvas:typeof OffscreenCanvas!=="undefined",
137
137
  hasCreateImageBitmap:typeof createImageBitmap!=="undefined",
138
138
  hasReadableStream:typeof ReadableStream!=="undefined"
139
139
  });
140
- };`],{type:`application/javascript`})}function Ry(){let e=Ly();return URL.createObjectURL(e)}function zy(e){URL.revokeObjectURL(e)}let By=`probe`,Vy=`probeResult`,Hy=`mediaStreamTrackProcessor`,Uy=`unavailable`,Wy=`unavailable`,Gy=new Map,Ky=new Map;function qy(e,t){return typeof e==`boolean`?e:t}function Jy(e){return e?`1`:`0`}function Yy(e,t){return[`audio`,Jy(e),`watermark`,Jy(t)].join(`|`)}function Xy(){return typeof process>`u`||process.env,!0}function Zy(e){return e.probeResult.hasMediaStreamTrackProcessor?`worker-track`:e.hasMainThreadMediaStreamTrackProcessor?`main-thread-stream`:Uy}function Qy(e){return e.requiresAudio?e.hasMainThreadMediaStreamTrackProcessor&&e.probeResult.hasAudioData?`main-thread-audio-stream`:e.hasAudioContext&&e.hasAudioWorklet?`audio-worklet-chunks`:Wy:`none-required`}function $y(e,t){return e.includes(t)?e:[...e,t]}function eb(e,t){let n=e;return t.hasWorker||(n=$y(n,`worker`)),t.probeResult.hasVideoFrame||(n=$y(n,`videoFrame`)),t.probeResult.hasOffscreenCanvas||(n=$y(n,`offscreenCanvas`)),t.probeResult.hasReadableStream||(n=$y(n,`readableStream`)),n}function tb(e,t){let n=e;return t.requiresWatermark&&!t.probeResult.hasCreateImageBitmap&&(n=$y(n,`createImageBitmap`)),n}function nb(e,t){let n=e;return t.videoPath===Uy&&(n=$y(n,Hy)),n}function rb(e,t){let n=e;return t.hasMainThreadMediaStreamTrackProcessor&&t.probeResult.hasAudioData?n:(t.hasMainThreadMediaStreamTrackProcessor||(n=$y(n,Hy)),t.hasMainThreadMediaStreamTrackProcessor&&!t.probeResult.hasAudioData&&(n=$y(n,`audioData`)),n)}function ib(e,t){let n=e;return t.hasAudioContext&&t.hasAudioWorklet?n:(t.hasAudioContext||(n=$y(n,`audioContext`)),t.hasAudioWorklet||(n=$y(n,`audioWorklet`)),n)}function ab(e,t){let n=e;return t.requiresAudio&&t.audioPath===Wy?(n=rb(n,t),n=ib(n,t),n):n}function ob(e){let t=[];return t=eb(t,e),t=tb(t,e),t=nb(t,e),t=ab(t,e),t}function sb(e,t){return!(e===Uy||t===Wy)}function cb(e,t){return!(!e.hasVideoFrame||!e.hasOffscreenCanvas||!e.hasReadableStream||t&&!e.hasCreateImageBitmap)}async function lb(e={},t={}){let n=qy(e.requiresAudio,!0),r=qy(e.requiresWatermark,!1);if(!Xy())return await ub(n,r,t);let i=Yy(n,r),a=Gy.get(i);if(a)return a;let o=Ky.get(i);if(o)return await o;let s=ub(n,r,t).then(e=>(Gy.set(i,e),Ky.delete(i),e)).catch(e=>{throw Ky.delete(i),e});return Ky.set(i,s),await s}async function ub(e,t,n){let r=typeof Worker<`u`,i=a()!==null,o=typeof AudioWorkletNode<`u`,s=typeof MediaStreamTrackProcessor<`u`,c=await db(r,n),l=Zy({probeResult:c,hasMainThreadMediaStreamTrackProcessor:s}),u=Qy({requiresAudio:e,hasAudioContext:i,hasAudioWorklet:o,hasMainThreadMediaStreamTrackProcessor:s,probeResult:c}),d=ob({hasWorker:r,hasAudioContext:i,hasAudioWorklet:o,hasMainThreadMediaStreamTrackProcessor:s,probeResult:c,requiresAudio:e,requiresWatermark:t,videoPath:l,audioPath:u}),f=sb(l,u),p=cb(c,t);return{isSupported:r&&f&&p,missing:d,hasWorker:r,hasAudioContext:i,hasAudioWorklet:o,hasMediaStreamTrackProcessor:c.hasMediaStreamTrackProcessor,hasMainThreadMediaStreamTrackProcessor:s,hasVideoFrame:c.hasVideoFrame,hasAudioData:c.hasAudioData,hasOffscreenCanvas:c.hasOffscreenCanvas,hasCreateImageBitmap:c.hasCreateImageBitmap,hasReadableStream:c.hasReadableStream,requiresAudio:e,requiresWatermark:t,videoPath:l,audioPath:u}}async function db(e,t){if(!e)return pb();let n=await fb().catch(()=>null);return n?await new Promise(e=>{let r=!1,i=t.probeTimeoutMilliseconds??2e3,a=t=>{r||(r=!0,n.terminate(),e(t))},o=setTimeout(()=>{a(pb())},i);n.onmessage=e=>{let t=e.data;t.type===Vy&&(clearTimeout(o),a({hasMediaStreamTrackProcessor:t.hasMediaStreamTrackProcessor===!0,hasVideoFrame:t.hasVideoFrame===!0,hasAudioData:t.hasAudioData===!0,hasOffscreenCanvas:t.hasOffscreenCanvas===!0,hasCreateImageBitmap:t.hasCreateImageBitmap===!0,hasReadableStream:t.hasReadableStream===!0}))},n.onerror=()=>{clearTimeout(o),a(pb())},Promise.resolve().then(()=>{n.postMessage({type:By})}).catch(()=>{clearTimeout(o),a(pb())})}):pb()}function fb(){return Promise.resolve().then(()=>{let e=Ry();try{let t=new Worker(e,{type:`classic`});return zy(e),t}catch(t){throw zy(e),t}})}function pb(){return{hasMediaStreamTrackProcessor:!1,hasVideoFrame:!1,hasAudioData:!1,hasOffscreenCanvas:!1,hasCreateImageBitmap:!1,hasReadableStream:!1}}let mb=`recording.audio-no-chunks`,hb=`recording.audio-silent`,gb=`recording.audio-track-ended`,_b=`audio.no-track-at-start`;function vb(e,t){let n=Error(e);return n.code=e,t&&(n.details=t),n}function yb(){let e=Error(_b);return e.code=_b,e}function bb(e){if(!(e instanceof Error))return!1;let t=e;return t.code===mb||t.code===hb||t.code===gb||t.code===`recording.no-audio-track`||t.code===`recording.no-audio-frames`||t.code===`recording.audio-zero-channels`||t.code===`recording.audio-invalid-sample-rate`}function xb(e){return e.hadTrackEndedWarning?{ok:!1,code:gb}:e.totalChunks===0?{ok:!1,code:mb}:e.nonSilentChunks===0&&(e.durationMs>0?e.mutedDurationMs/e.durationMs:0)<.9?{ok:!1,code:hb}:{ok:!0}}let Sb=`vidtreo-recorder`,Cb=`pending-uploads`,wb=`status`,Tb=`createdAt`,Eb=`Failed to prepare upload data for storage. The recorded file could not be read.`,Db=`__probe__`,Ob=new ArrayBuffer(1);var kb=class{constructor(e){if(this.db=null,e){this.databaseFactory=e;return}this.databaseFactory=indexedDB}init(){return this.db?Promise.resolve():this.openDatabase(3,!0)}openDatabase(e,t){return new Promise((n,r)=>{let i=this.createOpenRequest(e);i.onerror=()=>{let e=i.error;if(t&&e&&e.name===`VersionError`){this.openDatabase(void 0,!1).then(n).catch(r);return}if(e){r(e);return}r(Error(`Failed to open database`))},i.onsuccess=()=>{if(!i.result){r(Error(`Database result is null`));return}let e=i.result,t=this.validateRequiredSchema(e);if(t){e.close(),r(t);return}this.db=e,n()},i.onupgradeneeded=e=>{let t=e.target.result;if(!t){r(Error(`Database upgrade result is null`));return}this.initializeStoreSchema(t)}})}createOpenRequest(e){return e===void 0?this.databaseFactory.open(Sb):this.databaseFactory.open(Sb,e)}initializeStoreSchema(e){if(e.objectStoreNames.contains(Cb))return;let t=e.createObjectStore(Cb,{keyPath:`id`});t.createIndex(wb,wb,{unique:!1}),t.createIndex(Tb,Tb,{unique:!1})}validateRequiredSchema(e){if(!e.objectStoreNames.contains(Cb))return Error(`Database schema is missing required object store: pending-uploads`);let t=e.transaction([Cb],`readonly`).objectStore(Cb);return t.indexNames.contains(wb)?t.indexNames.contains(Tb)?null:Error(`Database schema is missing required index: createdAt`):Error(`Database schema is missing required index: status`)}isInitialized(){return this.db!==null}async probeWriteCapability(){if(!this.db)return{ok:!1,reason:`Database not initialized`};try{return await this.executeTransaction(`readwrite`,e=>{let t={id:Db,blobData:Ob,blobType:`application/octet-stream`,apiKey:``,backendUrl:``,filename:`probe`,status:`pending`,retryCount:0,createdAt:0,updatedAt:0};return new Promise((n,r)=>{let i=e.put(t);i.onsuccess=()=>{let t=e.delete(Db);t.onsuccess=()=>n(),t.onerror=()=>{if(t.error){r(t.error);return}r(Error(`Probe delete failed`))}},i.onerror=()=>{if(i.error){r(i.error);return}r(Error(`Probe write failed`))}})}),{ok:!0}}catch(e){return{ok:!1,reason:`Storage write probe failed. Browser may be in private browsing mode or IndexedDB writes are restricted. ${e instanceof Error?e.message:String(e)}`}}}async savePendingUpload(e){let t=this.generateUploadId(),n=Date.now(),r={...e,id:t,status:`pending`,retryCount:0,createdAt:n,updatedAt:n,blobData:await this.readBlobData(e.blob),blobType:e.blob.type};return r.blob=void 0,this.executeTransaction(`readwrite`,e=>{let n=e.add(r);return new Promise((e,r)=>{n.onsuccess=()=>e(t),n.onerror=()=>{n.error?n.error.name===`QuotaExceededError`?r(Error(`Storage quota exceeded. Please free up space or delete old uploads.`)):r(n.error):r(Error(`Failed to save upload`))}})})}getPendingUploads(e){return this.executeTransaction(`readonly`,t=>{let n=e?t.index(wb).getAll(e):t.getAll();return new Promise((e,t)=>{n.onsuccess=()=>{if(n.result===void 0){t(Error(`Failed to get uploads: result is undefined`));return}e(n.result.map(e=>this.hydrateUpload(e)))},n.onerror=()=>{n.error?t(n.error):t(Error(`Failed to get uploads`))}})})}async updateUploadStatus(e,t){let n=await this.createStoredUpdates(t);return this.executeTransaction(`readwrite`,r=>{let i=r.get(e);return new Promise((e,a)=>{i.onsuccess=()=>{let o=i.result;if(!o){a(Error(`Upload not found`));return}let s=t.updatedAt===void 0?Date.now():t.updatedAt,c={...o,...n,updatedAt:s},l=r.put(c);l.onsuccess=()=>e(),l.onerror=()=>{if(l.error){a(l.error);return}a(Error(`Failed to update upload`))}},i.onerror=()=>{i.error?a(i.error):a(Error(`Failed to get upload`))}})})}deleteUpload(e){return this.executeTransaction(`readwrite`,t=>{let n=t.delete(e);return new Promise((e,t)=>{n.onsuccess=()=>e(),n.onerror=()=>{n.error?t(n.error):t(Error(`Failed to delete upload`))}})})}async cleanupPermanentlyFailedUploads(e){let t=e===void 0?24:e;if(typeof t!=`number`||t<0)throw Error(`retentionHours must be a non-negative number`);let n=Date.now()-t*36e5,r=(await this.getPendingUploads()).filter(e=>e.status===`failed`&&e.retryCount>=10&&e.updatedAt<n);for(let e of r)await this.deleteUpload(e.id);return r.length}async getTotalStorageSize(){return(await this.getPendingUploads()).reduce((e,t)=>e+t.blob.size,0)}hydrateUpload(e){if(`blobData`in e&&e.blobData){let{blobData:t,blobType:n,...r}=e;return{...r,blob:new Blob([t],{type:n})}}return e}async createStoredUpdates(e){let t={...e};return e.blob&&(t.blobData=await this.readBlobData(e.blob),t.blobType=e.blob.type,t.blob=void 0),t}readBlobData(e){return e.arrayBuffer().catch(e=>{throw e instanceof Error?Error(`${Eb} ${e.message}`):Error(Eb)})}generateUploadId(){return`upload-${Date.now()}-${Math.random().toString(36).substring(2,11)}`}executeTransaction(e,t){if(!this.db)throw Error(`Database not initialized`);let n=this.db.transaction([Cb],e),r=n.objectStore(Cb);return new Promise((e,i)=>{let a,o=!1,s=!1;n.oncomplete=()=>{!o||s||e(a)},n.onerror=()=>{if(n.error){i(n.error);return}i(Error(`Storage transaction failed`))},n.onabort=()=>{if(n.error){i(n.error);return}i(Error(`Storage transaction aborted`))},t(r).then(e=>{a=e,o=!0},e=>{s=!0,i(e)})})}},Ab=class{constructor(){this.storageService=null,this.cleanupIntervalId=null,this.writeProbeResult=null}async initialize(e){this.storageService||=new kb,this.storageService.isInitialized()||await this.storageService.init(),this.writeProbeResult=await this.storageService.probeWriteCapability(),this.setupCleanupInterval(e)}getWriteProbeResult(){return this.writeProbeResult}setupCleanupInterval(e){this.cleanupIntervalId===null&&(this.cleanupIntervalId=window.setInterval(()=>{this.performCleanup().catch(t=>{e(i(t))})},36e5))}async performCleanup(){if(!this.storageService)throw Error(`StorageService not initialized`);await this.storageService.cleanupPermanentlyFailedUploads(24)}getStorageService(){return this.storageService}isStorageWritable(){return this.writeProbeResult?.ok===!0}destroy(){this.cleanupIntervalId!==null&&(clearInterval(this.cleanupIntervalId),this.cleanupIntervalId=null)}};function jb(){let e=globalThis;if(e.__VIDTREO_DEBUG__===!0||e.__VIDTREO_DEV__===!0)return!0;let t=typeof process<`u`&&process?.env?`production`:void 0;return t===`development`||t===`test`||typeof localStorage<`u`&&localStorage.getItem(`VIDTREO_DEBUG`)===`true`}let Mb=jb(),Nb={reset:`\x1B[0m`,bright:`\x1B[1m`,dim:`\x1B[2m`,red:`\x1B[31m`,green:`\x1B[32m`,yellow:`\x1B[33m`,blue:`\x1B[34m`,magenta:`\x1B[35m`,cyan:`\x1B[36m`,white:`\x1B[37m`,gray:`\x1B[90m`};function Pb(e,t,n){if(!Mb)return``;let r=n?.prefix||`[${e.toUpperCase()}]`;return`${Nb[n?.color||Fb(e)]}${r}${Nb.reset} ${t}`}function Fb(e){switch(e){case`error`:return`red`;case`warn`:return`yellow`;case`info`:return`cyan`;case`debug`:return`gray`;default:return`white`}}function Ib(e,t,...n){if(!Mb)return;let r=Pb(e,t);console[e](r,...n)}let $={log:(e,...t)=>{Ib(`log`,e,...t)},info:(e,...t)=>{Ib(`info`,e,...t)},warn:(e,...t)=>{Ib(`warn`,e,...t)},error:(e,...t)=>{Ib(`error`,e,...t)},debug:(e,...t)=>{Ib(`debug`,e,...t)},group:(e,t=`cyan`)=>{if(!Mb)return;let n=Nb[t],r=Nb.reset;console.group(`${n}${e}${r}`)},groupEnd:()=>{Mb&&console.groupEnd()}};function Lb(e,t){if(e==null)throw Error(t);return e}function Rb(e,t=`StreamProcessor`){if(!e)throw Error(`${t} is required`);return e}function zb(){if(typeof navigator>`u`||!navigator.mediaDevices?.getUserMedia){let e=typeof window<`u`&&window.isSecureContext===!0?`Camera access is not supported in this browser`:`Camera access requires HTTPS. Please use a secure connection (https://) or localhost.`;throw Error(e)}return navigator.mediaDevices}function Bb(e,t){let n={};if(t.originalCameraConstraints){let{deviceId:e,...r}=t.originalCameraConstraints;n={...n,...r}}e&&(n={...n,deviceId:{exact:e}});let r=t.getSelectedCameraDeviceId(),i=!1;return e&&(i=!0),n.deviceId&&(i=!0),!i&&r&&(n={...n,deviceId:{exact:r}}),n}function Vb(e){let t={echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0};return e?{...t,deviceId:{exact:e}}:t}let Hb=`live`;function Ub(e){for(let t of e)t.readyState===Hb&&t.stop()}function Wb(e){Ub(e.getTracks())}function Gb(e){Ub(e.getVideoTracks())}function Kb(e){return e?e.readyState===Hb:!1}function qb(e,t){return Kb(e)&&Kb(t)}function Jb(e,t,n){if(!Kb(e)){Wb(n);let r=`undefined`;throw e&&(r=e.readyState),Error(`Failed to get live camera ${t} track. ReadyState: ${r}`)}}let Yb=`[SourceSwitchManager]`;var Xb=class{constructor(e){this.dependencies=e}async createCameraStreamWithOriginalAudio(e){let t=this.dependencies.getOriginalCameraStream(),n;if(t&&(n=t.getAudioTracks()[0]),this.dependencies.logger.debug(`${Yb} createCameraStreamWithOriginalAudio`,{hasOriginalCameraStream:!!t,originalCameraStreamId:t?.id,hasOriginalAudioTrack:!!n,originalAudioTrackId:n?.id,originalAudioTrackReadyState:n?.readyState,originalAudioTrackEnabled:n?.enabled,originalAudioTrackMuted:n?.muted,originalAudioTrackLabel:n?.label,isTrackLive:Kb(n),cameraDeviceId:e}),!Kb(n))return this.dependencies.logger.warn(`${Yb} Original audio track is not live, cannot reuse`,{originalAudioTrackId:n?.id,originalAudioTrackReadyState:n?.readyState}),null;let r=Bb(e,{originalCameraConstraints:this.dependencies.getOriginalCameraConstraints(),getSelectedCameraDeviceId:this.dependencies.getSelectedCameraDeviceId}),i=Object.keys(r).length>0,a=!0;i&&(a=r);let o={video:a,audio:!1};this.dependencies.logger.debug(`${Yb} Requesting new video stream`,{constraints:o,cameraDeviceId:e});let s=await zb().getUserMedia(o),c=s.getVideoTracks()[0];Jb(c,`video`,s),this.dependencies.logger.debug(`${Yb} New video stream obtained`,{newStreamId:s.id,videoTrackId:c.id,videoTrackReadyState:c.readyState,newStreamAudioTracksCount:s.getAudioTracks().length});let l=[c];n&&(l=[...l,n]),this.dependencies.logger.debug(`${Yb} Creating combined stream with original audio`,{videoTrackId:c.id,audioTrackId:n?.id,audioTrackReadyState:n?.readyState,audioTrackEnabled:n?.enabled,audioTrackMuted:n?.muted,combinedTracksCount:l.length});let u=new MediaStream(l);Ub(s.getAudioTracks());let d=t?.id;return this.dependencies.setOriginalCameraStream(u),this.dependencies.logger.debug(`${Yb} Combined stream created and assigned`,{combinedStreamId:u.id,previousOriginalCameraStreamId:d,newOriginalCameraStreamId:u.id,combinedStreamVideoTracksCount:u.getVideoTracks().length,combinedStreamAudioTracksCount:u.getAudioTracks().length,combinedStreamAudioTrackId:u.getAudioTracks()[0]?.id,combinedStreamAudioTrackReadyState:u.getAudioTracks()[0]?.readyState,audioTrackStillSame:u.getAudioTracks()[0]===n}),u}async createCameraStreamWithNewAudio(e){let t=this.dependencies.getSelectedMicDeviceId(),n=Bb(e,{originalCameraConstraints:this.dependencies.getOriginalCameraConstraints(),getSelectedCameraDeviceId:this.dependencies.getSelectedCameraDeviceId}),r=Vb(t),i=Object.keys(n).length>0,a=!0;i&&(a=n);let o={video:a,audio:r},s=await zb().getUserMedia(o),c=s.getVideoTracks()[0],l=s.getAudioTracks()[0];return Jb(c,`video`,s),Jb(l,`audio`,s),this.dependencies.setOriginalCameraStream(s),s}async createNewCameraStreamForRecording(){let e=this.dependencies.getSelectedCameraDeviceId();return await this.createCameraStreamWithOriginalAudio(e)||this.createCameraStreamWithNewAudio(e)}async getCameraStream(e){let t=this.dependencies.streamManager.isRecording(),n=this.dependencies.getSelectedCameraDeviceId(),r=this.dependencies.getSelectedMicDeviceId();if(this.dependencies.streamManager.setVideoDevice(n),this.dependencies.streamManager.setAudioDevice(r),e.canReuseOriginalStream()){let e=this.dependencies.getOriginalCameraStream();if(!e)throw Error(`Original camera stream is null`);return e}if(e.canReuseManagerStream()){let e=this.dependencies.streamManager.getStream();if(!e)throw Error(`Manager stream is null`);return e}t||this.dependencies.getOriginalCameraStream()&&this.dependencies.setOriginalCameraStream(null);let i=this.dependencies.streamManager.getStream();if(!t&&i&&i!==this.dependencies.getOriginalCameraStream()&&(Wb(i),this.dependencies.streamManager.setMediaStream(null)),t)return this.dependencies.streamManager.setVideoDevice(this.dependencies.getSelectedCameraDeviceId()),this.dependencies.streamManager.setAudioDevice(this.dependencies.getSelectedMicDeviceId()),this.createNewCameraStreamForRecording();let a=await this.dependencies.streamManager.startStream();return this.dependencies.setOriginalCameraStream(a),a}};let Zb=`screen`,Qb=`No video track found in screen share stream`;async function $b(e,t,n){n.setScreenShareStream(e);let r=e.getVideoTracks()[0];if(!r)throw n.stopStreamTracks(e),Error(Qb);let i=n.combineScreenShareWithOriginalAudio(r),a=n.getOriginalCameraStream();t&&t!==a&&n.stopStreamVideoTracks(t);let o=e.getAudioTracks();for(let e of o)e.stop();return n.setCurrentSourceType(Zb),n.callbacks.onSourceChange&&await n.callbacks.onSourceChange(n.getCurrentSourceType()),ex(i,n),i}function ex(e,t){let n=e.getVideoTracks()[0];if(!n)throw Error(Qb);let r=t.getScreenShareTrackEndHandler();if(r){let e=t.streamManager.getStream();if(e){let t=e.getVideoTracks()[0];t&&t.removeEventListener(`ended`,r)}}let i=()=>{t.getCurrentSourceType()===Zb&&t.switchToCamera().catch(e=>{t.handleSwitchError(e)})};t.setScreenShareTrackEndHandler(i),n.addEventListener(`ended`,i)}function tx(e,t){let n=t.getScreenShareTrackEndHandler();if(!(n&&e))return;let r=e.getVideoTracks()[0];r&&r.removeEventListener(`ended`,n),t.setScreenShareTrackEndHandler(null)}function nx(e,t){e.onTransitionStart&&e.onTransitionStart(t)}function rx(e){e.onTransitionEnd&&e.onTransitionEnd()}function ix(e){e.onScreenSelectionStart&&e.onScreenSelectionStart()}function ax(e){e.onScreenSelectionEnd&&e.onScreenSelectionEnd()}function ox(e){ax(e),rx(e)}let sx=`Failed to get camera stream`;var cx=class{constructor(e,t={}){this.currentSourceType=`camera`,this.originalCameraStream=null,this.screenShareStream=null,this.screenShareTrackEndHandler=null,this.streamManager=e,this.callbacks=t;let n=null,r=()=>n;this.getOriginalCameraConstraints=r,this.setOriginalCameraConstraints=e=>{n=e},this.cameraStreamBuilder=new Xb({streamManager:this.streamManager,logger:{debug:(e,t)=>$.debug(e,t),warn:(e,t)=>$.warn(e,t)},getSelectedCameraDeviceId:()=>this.callbacks.getSelectedCameraDeviceId?this.callbacks.getSelectedCameraDeviceId():this.streamManager.getVideoDevice(),getSelectedMicDeviceId:()=>this.callbacks.getSelectedMicDeviceId?this.callbacks.getSelectedMicDeviceId():this.streamManager.getAudioDevice(),getOriginalCameraStream:()=>this.originalCameraStream,setOriginalCameraStream:e=>{this.originalCameraStream=e},getOriginalCameraConstraints:r})}getCurrentSourceType(){return this.currentSourceType}getOriginalCameraStream(){return this.originalCameraStream}storeOriginalCameraConstraints(e){let t=e.getVideoTracks()[0];if(!t)return;let n=t.getSettings(),r={width:n.width,height:n.height,aspectRatio:n.aspectRatio,frameRate:n.frameRate,deviceId:n.deviceId,facingMode:n.facingMode},i=this.getOriginalCameraConstraints();i&&i.width===r.width&&i.height===r.height&&i.aspectRatio===r.aspectRatio&&i.frameRate===r.frameRate&&i.deviceId===r.deviceId&&i.facingMode===r.facingMode||this.setOriginalCameraConstraints(r)}storeOriginalCameraStream(e){let t=e.getVideoTracks()[0],n=e.getAudioTracks()[0];qb(t,n)?this.originalCameraStream=new MediaStream([t,n]):this.originalCameraStream=e}createError(e){return e instanceof Error?e:Error(i(e))}waitForTracksToEnd(e){return new Promise(t=>{setTimeout(()=>{this.screenShareStream=null,t()},e)})}combineScreenShareWithOriginalAudio(e){let t;this.originalCameraStream&&(t=this.originalCameraStream.getAudioTracks()[0]),$.debug(`[SourceSwitchManager] combineScreenShareWithOriginalAudio`,{hasOriginalCameraStream:!!this.originalCameraStream,originalCameraStreamId:this.originalCameraStream?.id,hasOriginalAudioTrack:!!t,originalAudioTrackId:t?.id,originalAudioTrackReadyState:t?.readyState,originalAudioTrackEnabled:t?.enabled,originalAudioTrackMuted:t?.muted,originalAudioTrackLabel:t?.label,isTrackLive:Kb(t),screenVideoTrackId:e.id,screenVideoTrackReadyState:e.readyState});let n=[e];Kb(t)&&t?(n=[...n,t],$.debug(`[SourceSwitchManager] Added original audio track to combined stream`,{audioTrackId:t.id,combinedTracksCount:n.length})):$.warn(`[SourceSwitchManager] Original audio track is not live, not adding to combined stream`,{audioTrackId:t?.id,audioTrackReadyState:t?.readyState,combinedTracksCount:n.length});let r=new MediaStream(n);return $.debug(`[SourceSwitchManager] Combined stream created`,{combinedStreamId:r.id,combinedStreamVideoTracksCount:r.getVideoTracks().length,combinedStreamAudioTracksCount:r.getAudioTracks().length,combinedStreamAudioTrackId:r.getAudioTracks()[0]?.id,combinedStreamAudioTrackReadyState:r.getAudioTracks()[0]?.readyState}),r}isPermissionDeniedError(e){let t=i(e),n=!1;t.includes(`NotAllowedError`)&&(n=!0),t.includes(`AbortError`)&&(n=!0);let r=t.toLowerCase();return r.includes(`permission denied`)&&(n=!0),r.includes(`user denied`)&&(n=!0),n}switchToScreenCapture(){let e=this.streamManager.getStream();return e&&(this.storeOriginalCameraConstraints(e),this.storeOriginalCameraStream(e)),nx(this.callbacks,`Select screen to share...`),ix(this.callbacks),Promise.resolve().then(async()=>{let t=zb();if(typeof t.getDisplayMedia!=`function`)throw Error(`Screen sharing is not supported on this device`);return $b(await t.getDisplayMedia({video:!0,audio:!0}),e,this.getScreenShareDependencies())}).catch(e=>{if(ox(this.callbacks),this.isPermissionDeniedError(e))return null;throw e})}canReuseStream(e,t){if(!e||t&&e!==this.originalCameraStream)return!1;let n=e.getVideoTracks()[0],r=e.getAudioTracks()[0];return!(!qb(n,r)||this.callbacks.getSelectedCameraDeviceId&&this.callbacks.getSelectedCameraDeviceId()!==n.getSettings().deviceId)}canReuseOriginalStream(){return this.canReuseStream(this.originalCameraStream,!1)}canReuseManagerStream(){let e=this.streamManager.getStream();return e&&this.originalCameraStream?this.canReuseStream(e,!0):!1}getScreenShareDependencies(){return{callbacks:this.callbacks,streamManager:this.streamManager,combineScreenShareWithOriginalAudio:e=>this.combineScreenShareWithOriginalAudio(e),stopStreamTracks:e=>Wb(e),stopStreamVideoTracks:e=>Gb(e),getCurrentSourceType:()=>this.currentSourceType,setCurrentSourceType:e=>{this.currentSourceType=e},getOriginalCameraStream:()=>this.originalCameraStream,getScreenShareStream:()=>this.screenShareStream,setScreenShareStream:e=>{this.screenShareStream=e},getScreenShareTrackEndHandler:()=>this.screenShareTrackEndHandler,setScreenShareTrackEndHandler:e=>{this.screenShareTrackEndHandler=e},switchToCamera:()=>this.switchToCamera(),handleSwitchError:e=>{this.callbacks.onError&&this.callbacks.onError(this.createError(e))}}}getCameraStream(){return this.cameraStreamBuilder.getCameraStream({canReuseOriginalStream:()=>this.canReuseOriginalStream(),canReuseManagerStream:()=>this.canReuseManagerStream()})}switchToCamera(){let e=this.streamManager.isRecording();return!e&&this.currentSourceType===`camera`?Promise.resolve():Promise.resolve().then(async()=>{nx(this.callbacks,`Switching to camera...`),await this.handleScreenShareStop();let t=await this.getCameraStream();if(!t)throw Error(sx);await this.applyCameraStream(t,e),rx(this.callbacks)}).catch(e=>{throw rx(this.callbacks),e})}stopScreenShareStreamTracks(e){let t=e.getVideoTracks(),n=e.getAudioTracks();$.debug(`[SourceSwitchManager] stopping screen share tracks`,{videoTracks:t.map(e=>({id:e.id,readyState:e.readyState,displaySurface:e.getSettings().displaySurface,constraints:e.getConstraints()})),audioTracks:n.map(e=>({id:e.id,readyState:e.readyState,constraints:e.getConstraints()}))});for(let e of t)e.stop();for(let e of n)e.stop()}stopDisplayTracks(e){if(e)for(let t of e.getVideoTracks())typeof t.getSettings().displaySurface==`string`&&Kb(t)&&($.debug(`[SourceSwitchManager] stopping display track`,{id:t.id,readyState:t.readyState,constraints:t.getConstraints(),settings:t.getSettings()}),t.stop())}async handleScreenShareStop(){if(this.currentSourceType!==`screen`)return;$.debug(`[SourceSwitchManager] handleScreenShareStop invoked`,{currentSourceType:this.currentSourceType,hasScreenShareStream:!!this.screenShareStream,screenShareStreamId:this.screenShareStream?.id,hasOriginalCameraStream:!!this.originalCameraStream,originalCameraStreamId:this.originalCameraStream?.id});let e=this.screenShareStream,t=this.streamManager.getStream();if($.debug(`[SourceSwitchManager] Current stream state before stop`,{currentStreamId:t?.id,currentStreamVideoTracksCount:t?.getVideoTracks().length,currentStreamAudioTracksCount:t?.getAudioTracks().length,currentStreamAudioTrackId:t?.getAudioTracks()[0]?.id,currentStreamAudioTrackReadyState:t?.getAudioTracks()[0]?.readyState,originalCameraStreamAudioTrackId:this.originalCameraStream?.getAudioTracks()[0]?.id,originalCameraStreamAudioTrackReadyState:this.originalCameraStream?.getAudioTracks()[0]?.readyState}),e){let t=e.getAudioTracks();$.debug(`[SourceSwitchManager] Screen share stream audio tracks before stop`,{screenShareStreamId:e.id,screenShareAudioTracksCount:t.length,screenShareAudioTrackIds:t.map(e=>({id:e.id,readyState:e.readyState,enabled:e.enabled}))}),tx(e,this.getScreenShareDependencies()),this.stopScreenShareStreamTracks(e),this.stopDisplayTracks(e),this.screenShareStream=null,await this.waitForTracksToEnd(0),$.debug(`[SourceSwitchManager] Screen share stream stopped`,{screenShareAudioTracksAfterStop:t.map(e=>({id:e.id,readyState:e.readyState}))})}if(t){let e=t.getAudioTracks();$.debug(`[SourceSwitchManager] Current stream audio tracks before video stop`,{currentStreamId:t.id,currentStreamAudioTracksCount:e.length,currentStreamAudioTrackIds:e.map(e=>({id:e.id,readyState:e.readyState,enabled:e.enabled}))}),Gb(t),this.stopDisplayTracks(t),$.debug(`[SourceSwitchManager] Current stream audio tracks after video stop`,{currentStreamId:t.id,currentStreamAudioTracksCount:t.getAudioTracks().length,currentStreamAudioTrackIds:t.getAudioTracks().map(e=>({id:e.id,readyState:e.readyState,enabled:e.enabled}))})}$.debug(`[SourceSwitchManager] Original camera stream state before source change`,{hasOriginalCameraStream:!!this.originalCameraStream,originalCameraStreamId:this.originalCameraStream?.id,originalCameraStreamAudioTracksCount:this.originalCameraStream?.getAudioTracks().length,originalCameraStreamAudioTrackId:this.originalCameraStream?.getAudioTracks()[0]?.id,originalCameraStreamAudioTrackReadyState:this.originalCameraStream?.getAudioTracks()[0]?.readyState,originalCameraStreamAudioTrackEnabled:this.originalCameraStream?.getAudioTracks()[0]?.enabled}),this.currentSourceType=`camera`,this.callbacks.onSourceChange&&await this.callbacks.onSourceChange(this.currentSourceType),$.debug(`[SourceSwitchManager] handleScreenShareStop completed`,{hasScreenShareStream:!!this.screenShareStream,currentSourceType:this.currentSourceType,hasOriginalCameraStream:!!this.originalCameraStream,originalCameraStreamId:this.originalCameraStream?.id,originalCameraStreamAudioTracksCount:this.originalCameraStream?.getAudioTracks().length,originalCameraStreamAudioTrackId:this.originalCameraStream?.getAudioTracks()[0]?.id,originalCameraStreamAudioTrackReadyState:this.originalCameraStream?.getAudioTracks()[0]?.readyState})}async applyCameraStream(e,t){this.streamManager.setMediaStream(e);let n=this.currentSourceType!==`camera`;this.currentSourceType=`camera`,n&&this.callbacks.onSourceChange&&await this.callbacks.onSourceChange(this.currentSourceType),t&&await this.streamManager.switchVideoSource(e),this.callbacks.onPreviewUpdate&&await this.callbacks.onPreviewUpdate(e)}async toggleSource(){if(!this.streamManager.isRecording())return;let e;e=this.currentSourceType===`camera`?this.switchToScreen():this.switchToCamera(),await e.catch(e=>{this.handleToggleError(e)})}async switchToScreen(){let e=await this.switchToScreenCapture();if(!e){rx(this.callbacks);return}nx(this.callbacks,`Switching to screen...`),await this.streamManager.switchVideoSource(e),this.callbacks.onPreviewUpdate&&await this.callbacks.onPreviewUpdate(e),rx(this.callbacks)}handleToggleError(e){rx(this.callbacks);let t=i(e),n=!1;t.includes(`NotAllowedError`)&&(n=!0),t.includes(`AbortError`)&&(n=!0),n&&this.currentSourceType===`screen`&&this.switchToCamera().catch(e=>{this.callbacks.onError&&this.callbacks.onError(this.createError(e))}),!n&&this.callbacks.onError&&this.callbacks.onError(this.createError(e))}async handleRecordingStop(){if(this.currentSourceType!==`screen`){this.cleanup();return}await Promise.resolve().then(async()=>{let e=this.streamManager.getStream();e&&(tx(e,this.getScreenShareDependencies()),Gb(e));let t=await this.getCameraStream();if(!t)throw Error(sx);this.streamManager.setMediaStream(t),this.currentSourceType=`camera`,this.callbacks.onSourceChange&&await this.callbacks.onSourceChange(this.currentSourceType),this.callbacks.onPreviewUpdate&&await this.callbacks.onPreviewUpdate(t)}).catch(e=>{throw this.callbacks.onError&&this.callbacks.onError(this.createError(e)),e}),this.cleanup()}cleanup(){this.screenShareStream&&=(tx(this.screenShareStream,this.getScreenShareDependencies()),this.stopScreenShareStreamTracks(this.screenShareStream),null);let e=this.streamManager.getStream();e&&tx(e,this.getScreenShareDependencies()),this.screenShareTrackEndHandler=null,this.originalCameraStream=null,this.setOriginalCameraConstraints(null)}setCallbacks(e){this.callbacks={...this.callbacks,...e}}};let lx=Object.freeze({width:{ideal:Xt.width||1920},height:{ideal:Xt.height||1080},frameRate:{ideal:Xt.fps||30}}),ux=Object.freeze({video:lx,audio:!0});Object.freeze({mimeType:`video/webm;codecs=vp9,opus`});let dx={NotReadableError:`camera.in-use`,NotFoundError:`camera.not-found`,NotAllowedError:`camera.permission-denied`,OverconstrainedError:`camera.overconstrained`,TimeoutError:`camera.timeout`},fx={NotReadableError:`audio.in-use`,NotFoundError:`audio.not-found`,NotAllowedError:`audio.permission-denied`,OverconstrainedError:`audio.overconstrained`,TimeoutError:`audio.timeout`};function px(e){return e instanceof DOMException||typeof e==`object`&&e&&`name`in e&&typeof e.name==`string`?e.name:null}function mx(e){return i(e).toLowerCase()}function hx(e,t){let n=mx(e),r=t===`camera`?`camera`:`audio`;return n.includes(`permission denied`)||n.includes(`permission dismissed`)||n.includes(`not allowed`)?`${r}.permission-denied`:n.includes(`requested device not found`)||n.includes(`device not found`)||n.includes(`no camera`)||n.includes(`no microphone`)?`${r}.not-found`:n.includes(`timeout starting`)||n.includes(`timed out`)||n.includes(`timeout`)?`${r}.timeout`:n.includes(`could not start video source`)||n.includes(`could not start audio source`)||n.includes(`device in use`)?`${r}.in-use`:null}function gx(e){let t=hx(e,`camera`);if(t!==null)return t;let n=px(e);if(n!==null){let e=dx[n];if(e!==void 0)return e}return`camera.unknown`}function _x(e){let t=hx(e,`audio`);if(t!==null)return t;let n=px(e);if(n!==null){let e=fx[n];if(e!==void 0)return e}return`audio.unknown`}function vx(e){let t=i(e),n=Error(t);return n.name=`CameraError`,n.code=gx(e),n}function yx(e){let t=i(e),n=Error(t);return n.name=`AudioError`,n.code=_x(e),n}function bx(e){return px(e)===`NotReadableError`}function xx(e){return new Promise(t=>setTimeout(t,e))}var Sx=class{constructor(e={},t={}){this.mediaStream=null,this.state=`idle`,this.eventListeners=new Map,this.selectedAudioDeviceId=null,this.selectedVideoDeviceId=null,this.audioStatus=`pending`,this.audioAcquisitionPromise=null,this.pendingAudioError=null,this.acquisitionGeneration=0,this.streamConfig={...ux,...e},this.waitMilliseconds=t.waitMilliseconds??xx,this.audioRetryDelayMilliseconds=t.audioRetryDelayMilliseconds??300}getAudioStatus(){return this.audioStatus}isAudioReady(){return this.audioStatus===`acquired`}async waitForAudio(){if(this.audioStatus!==`acquired`&&(this.audioStatus===`failed`||(this.audioAcquisitionPromise&&await this.audioAcquisitionPromise,this.getAudioStatus()===`failed`)))throw this.pendingAudioError??yx(null)}setAudioStatus(e){this.audioStatus!==e&&(this.audioStatus=e,this.emit(`audiostatuschange`,{status:e}))}emitAudioTelemetry(e){this.emit(`audiotelemetry`,{event:e})}getState(){return this.state}getStream(){return this.mediaStream}getAudioStreamForAnalysis(){return this.mediaStream&&this.mediaStream.getAudioTracks().length>0?this.mediaStream:null}isActive(){return this.state===`active`||this.state===`recording`}on(e,t){this.eventListeners.has(e)||this.eventListeners.set(e,new Set);let n=this.eventListeners.get(e);return n&&n.add(t),()=>{this.off(e,t)}}off(e,t){let n=this.eventListeners.get(e);n&&n.delete(t)}once(e,t){let n=(r=>{t(r),this.off(e,n)});return this.on(e,n)}emit(e,t){let n=this.eventListeners.get(e);if(n)for(let e of n)try{e(t)}catch{}}setState(e){if(this.state===e)return;let t=this.state;this.state=e,this.emit(`statechange`,{state:e,previousState:t})}setAudioDevice(e){this.selectedAudioDeviceId=e}setVideoDevice(e){this.selectedVideoDeviceId=e}getAudioDevice(){return this.selectedAudioDeviceId}getVideoDevice(){return this.selectedVideoDeviceId}async getAvailableDevices(){try{let e=await navigator.mediaDevices.enumerateDevices();return{audioinput:e.filter(e=>e.kind===`audioinput`),videoinput:e.filter(e=>e.kind===`videoinput`)}}catch(e){throw Error(`Failed to enumerate devices: ${i(e)}`)}}buildDeviceConstraints(e,t){return e?typeof t==`object`?{...t,deviceId:{exact:e}}:{deviceId:{exact:e}}:t}buildVideoConstraints(e){return this.buildDeviceConstraints(e,this.streamConfig.video)}buildAudioConstraints(e){return this.buildDeviceConstraints(e,this.streamConfig.audio)}async startStream(){if($.debug(`[StreamManager] startStream called`,{hasExistingStream:!!this.mediaStream,selectedVideoDeviceId:this.selectedVideoDeviceId,selectedAudioDeviceId:this.selectedAudioDeviceId}),this.mediaStream){let e=this.mediaStream.getVideoTracks()[0];if(this.selectedVideoDeviceId===null)if(e?.getSettings?.()?.deviceId)$.debug(`[StreamManager] Stopping existing stream to recreate`),this.stopStream();else return $.debug(`[StreamManager] Reusing existing stream`),this.mediaStream;if(e?.getSettings&&e.getSettings().deviceId===this.selectedVideoDeviceId)return $.debug(`[StreamManager] Existing stream matches device, reusing`),this.mediaStream;$.debug(`[StreamManager] Device changed, stopping existing stream`),this.stopStream()}this.setState(`starting`),$.debug(`[StreamManager] State set to 'starting'`);try{return this.mediaStream=await this.acquireVideoAndAudioStream(),$.info(`[StreamManager] Media stream obtained`,{streamId:this.mediaStream.id,videoTracks:this.mediaStream.getVideoTracks().length,audioTracks:this.mediaStream.getAudioTracks().length}),this.setState(`active`),$.debug(`[StreamManager] State set to 'active'`),$.debug(`[StreamManager] Emitting streamstart event`),this.emit(`streamstart`,{stream:this.mediaStream}),this.mediaStream}catch(e){if(e instanceof Error&&`code`in e&&(e.name===`CameraError`||e.name===`AudioError`))throw $.error(`[StreamManager] Failed to start stream`,e),this.setState(`error`),this.emit(`error`,{error:e}),e;let t=vx(e);throw $.error(`[StreamManager] Failed to start stream`,t),this.setState(`error`),this.emit(`error`,{error:t}),t}}async acquireVideoAndAudioStream(){let e=zb(),t=this.buildVideoConstraints(this.selectedVideoDeviceId),n=this.buildAudioConstraints(this.selectedAudioDeviceId);this.setAudioStatus(`pending`),this.pendingAudioError=null,$.debug(`[StreamManager] Attempting combined getUserMedia`,{selectedVideoDeviceId:this.selectedVideoDeviceId,selectedAudioDeviceId:this.selectedAudioDeviceId});try{let r=await e.getUserMedia({video:t,audio:n}),i=r.getVideoTracks().length>0,a=r.getAudioTracks().length>0;if(i&&a)return $.debug(`[StreamManager] Combined getUserMedia succeeded with video + audio`),this.setAudioStatus(`acquired`),r;$.warn(`[StreamManager] Combined getUserMedia returned incomplete stream`,{videoTracks:r.getVideoTracks().length,audioTracks:r.getAudioTracks().length}),this.stopStreamTracks(r)}catch(e){let t=px(e),n=i(e);$.warn(`[StreamManager] Combined getUserMedia failed, falling back to separate acquisition`,{error:n,errorName:t}),this.emitAudioTelemetry({name:`audio.acquisition.fallback`,properties:{reason:`combined_getUserMedia_failed`,originalError:n,originalErrorName:t,selectedAudioDeviceId:this.selectedAudioDeviceId,selectedVideoDeviceId:this.selectedVideoDeviceId}})}let r;try{r=await e.getUserMedia({video:t,audio:!1}),$.debug(`[StreamManager] Video-only stream acquired for preview`)}catch(e){throw this.setAudioStatus(`failed`),vx(e)}this.mediaStream=r,this.acquisitionGeneration++;let a=this.acquisitionGeneration;return this.audioAcquisitionPromise=this.acquireAudioInBackground(e,n,a),r}async acquireAudioInBackground(e,t,n){try{let r=await this.acquireAudioTrackWithRetry(e,t);if(!this.mediaStream||this.acquisitionGeneration!==n){$.debug(`[StreamManager] Audio acquired but stream was replaced/stopped, discarding track`,{generation:n,currentGeneration:this.acquisitionGeneration}),r.stop();return}this.mediaStream.addTrack(r),$.info(`[StreamManager] Audio track added to stream`,{audioTrackId:r.id,audioTrackLabel:r.label,totalAudioTracks:this.mediaStream.getAudioTracks().length}),this.setAudioStatus(`acquired`)}catch(e){if(this.acquisitionGeneration!==n)return;let t=e instanceof Error&&`code`in e?e:yx(e);this.pendingAudioError=t,this.setAudioStatus(`failed`),$.error(`[StreamManager] Background audio acquisition failed`,t),this.emitAudioTelemetry({name:`audio.acquisition.failed`,properties:{errorCode:t.code,errorName:t.name,maxRetries:2,retryDelayMs:this.audioRetryDelayMilliseconds,selectedAudioDeviceId:this.selectedAudioDeviceId},error:t}),this.emit(`error`,{error:t})}finally{this.audioAcquisitionPromise=null}}resolveAudioConstraintsForAttempt(e,t){if(t!==2||typeof e!=`object`)return e;let{deviceId:n,...r}=e,i=Object.keys(r).length>0?r:!0;return $.debug(`[StreamManager] Audio retry with relaxed constraints (no deviceId)`,{attempt:t}),i}async acquireAudioTrackWithRetry(e,t){let n=null;for(let r=0;r<=2;r++)try{let n=this.resolveAudioConstraintsForAttempt(t,r),i=await e.getUserMedia({video:!1,audio:n}),a=i.getAudioTracks()[0];if(!a)throw this.stopStreamTracks(i),Error(`getUserMedia returned no audio tracks`);for(let e of i.getVideoTracks())e.stop();return $.debug(`[StreamManager] Audio track acquired`,{attempt:r,trackId:a.id,trackLabel:a.label}),r>0&&this.emitAudioTelemetry({name:`audio.acquisition.recovered`,properties:{successAttempt:r,totalAttempts:r+1,audioTrackLabel:a.label,usedRelaxedConstraints:r===2}}),a}catch(e){n=e;let t=i(e),a=px(e),o=bx(e);if($.warn(`[StreamManager] Audio acquisition failed`,{attempt:r,maxRetries:2,error:t,errorName:a,isRetriable:o}),this.emitAudioTelemetry({name:`audio.acquisition.retry`,properties:{attempt:r,maxRetries:2,errorMessage:t,errorName:a??`unknown`,isRetriable:o,usedRelaxedConstraints:r===2,willRetry:r<2&&o}}),!(r<2&&o))break;await this.waitMilliseconds(this.audioRetryDelayMilliseconds)}throw yx(n)}stopStream(){if(this.mediaStream){for(let e of this.mediaStream.getTracks())e.stop();this.mediaStream=null}this.audioStatus=`pending`,this.pendingAudioError=null,this.audioAcquisitionPromise=null,this.acquisitionGeneration++,this.state!==`idle`&&(this.setState(`idle`),this.emit(`streamstop`,void 0))}stopStreamTracks(e){for(let t of e.getTracks())t.stop()}isTrackLive(e){return e!==void 0&&e.readyState===`live`}async tryReplaceTrack(e,t,n){let r=e.replaceTrack;if(typeof r!=`function`)return!1;try{await r.call(e,t),e.stop();for(let e of n.getTracks())e!==t&&e.stop();return t.stop(),!0}catch{return!1}}recreateStreamWithNewTrack(e,t,n){for(let t of n.getTracks())t!==e&&t.stop();let r=[e];this.isTrackLive(t)&&t&&r.push(t);let i=new MediaStream(r);if(this.mediaStream)for(let e of this.mediaStream.getTracks())e!==t&&e.stop();return i}async switchDeviceTrack(e,t,n){if(!this.mediaStream)throw Error(`No active stream to switch device`);let r=t===`video`?this.mediaStream.getVideoTracks()[0]:this.mediaStream.getAudioTracks()[0],i=t===`video`?this.mediaStream.getAudioTracks()[0]:this.mediaStream.getVideoTracks()[0];if(!r){let e=t===`video`?`video`:`audio`;throw Error(`No ${e} track in current stream`)}let a={[t]:this.buildDeviceConstraints(e,n)},o=await zb().getUserMedia(a),s=t===`video`?o.getVideoTracks()[0]:o.getAudioTracks()[0];if(!s){this.stopStreamTracks(o);let e=t===`video`?`video`:`audio`;throw Error(`Failed to get new ${e} track`)}return await this.tryReplaceTrack(r,s,o)||(r.stop(),this.mediaStream=this.recreateStreamWithNewTrack(s,i,o)),t===`video`?(this.selectedVideoDeviceId=e,this.emit(`videosourcechange`,{stream:this.mediaStream})):this.selectedAudioDeviceId=e,this.mediaStream}switchVideoDevice(e){return this.switchDeviceTrack(e,`video`,this.streamConfig.video)}switchAudioDevice(e){return this.switchDeviceTrack(e,`audio`,this.streamConfig.audio)}setMediaStream(e){this.mediaStream=e}setAudioTracksEnabled(e){if(!this.mediaStream)return;let t=this.mediaStream.getAudioTracks();for(let n of t)n.enabled=e}destroy(){this.stopStream(),this.eventListeners.clear(),this.setState(`idle`)}};let Cx=`recording.stop-not-ready`,wx=`recording.finalize-not-ready`,Tx=`recording.finalize-timeout`;function Ex(e,t,n){let r=Error(`${t} [${e}]`);return r.code=e,r.isRecoverable=!0,n!==void 0&&(r.details=n),r}function Dx(e){return!(e instanceof Error)||Ox(e)?e:e.message===`Not currently recording`?Ex(Cx,`Recording is not ready to stop`):e.message===`Processing not active`?Ex(wx,`Recording is not ready to finalize`):e}function Ox(e){let t=e;return t.code===Cx||t.code===wx||t.code===Tx}let kx=[`Bytes`,`KB`,`MB`,`GB`],Ax=1024;function jx(e){if(e===0)return`0 Bytes`;let t=Math.floor(Math.log(e)/Math.log(Ax));return`${Math.round(e/Ax**t*100)/100} ${kx[t]}`}function Mx(e){let t=Math.floor(e/3600),n=Math.floor(e%3600/60),r=e%60;return t>0?`${t.toString().padStart(2,`0`)}:${n.toString().padStart(2,`0`)}:${r.toString().padStart(2,`0`)}`:`${n.toString().padStart(2,`0`)}:${r.toString().padStart(2,`0`)}`}let Nx={getCurrentTimestamp:()=>performance.now()};var Px=class{constructor(e){this.recordingStartTime=0,this.totalPausedTime=0,this.pauseStartTime=null,this.intervals=[],this.currentIntervalStart=null,this.isTracking=!1,this.visibilityChangeHandler=this.handleVisibilityChange.bind(this),this.blurHandler=this.handleBlur.bind(this),this.focusHandler=this.handleFocus.bind(this);let t=e?.getCurrentTimestamp;t===void 0?this.getCurrentTimestamp=Nx.getCurrentTimestamp:this.getCurrentTimestamp=t}start(e){this.isTracking||(this.recordingStartTime=e,this.totalPausedTime=0,this.pauseStartTime=null,this.intervals=[],this.currentIntervalStart=null,this.isTracking=!0,typeof document<`u`&&document.addEventListener(`visibilitychange`,this.visibilityChangeHandler),typeof window<`u`&&(window.addEventListener(`blur`,this.blurHandler),window.addEventListener(`focus`,this.focusHandler)),this.checkInitialState())}pause(){!this.isTracking||this.pauseStartTime!==null||(this.pauseStartTime=this.getCurrentTimestamp(),this.endCurrentIntervalIfActive())}resume(){if(!this.isTracking||this.pauseStartTime===null)return;let e=this.getCurrentTimestamp()-this.pauseStartTime;this.totalPausedTime+=e,this.pauseStartTime=null}getIntervals(){return this.endCurrentIntervalIfActive(),this.intervals.map(e=>({start:this.normalizeTimestamp(e.start),end:this.normalizeTimestamp(e.end)}))}reset(){this.intervals=[],this.currentIntervalStart=null,this.totalPausedTime=0,this.pauseStartTime=null}cleanup(){this.isTracking=!1,this.endCurrentIntervalIfActive(),typeof document<`u`&&document.removeEventListener(`visibilitychange`,this.visibilityChangeHandler),typeof window<`u`&&(window.removeEventListener(`blur`,this.blurHandler),window.removeEventListener(`focus`,this.focusHandler)),this.reset()}checkInitialState(){typeof document>`u`||document.visibilityState===`hidden`&&this.startInterval()}handleVisibilityChange(){typeof document>`u`||(document.visibilityState===`hidden`?this.startInterval():this.endCurrentIntervalIfActive())}handleBlur(){this.startInterval()}handleFocus(){this.endCurrentIntervalIfActive()}startInterval(){this.currentIntervalStart!==null||!this.isTracking||this.pauseStartTime===null&&(this.currentIntervalStart=this.getCurrentTimestamp())}endCurrentIntervalIfActive(){if(this.currentIntervalStart===null)return;let e=this.getCurrentTimestamp(),t=this.currentIntervalStart;e>t&&this.intervals.push({start:t,end:e}),this.currentIntervalStart=null}normalizeTimestamp(e){let t=(e-this.recordingStartTime-this.totalPausedTime)/1e3;return Math.max(0,t)}};let Fx=1e3,Ix=1e3,Lx={route:`local-webcodecs`,reasonCodes:[`webcodecs-supported`,`target-codec-supported`]},Rx={width:{ideal:854,max:854},height:{ideal:480,max:480},frameRate:{ideal:20,max:20}},zx={width:{ideal:1280,max:1280},height:{ideal:720,max:720},frameRate:{ideal:24,max:24}};function Bx(e){let t=e.guidance?.message??`This browser or device cannot safely record video. Try a supported browser or upload an existing video file.`,n=Error(t);return n.name=`RecordingUnsupportedError`,n.code=`recording.unsupported-with-guidance`,n.isRecoverable=!0,n}let Vx={checkRecorderSupport:lb,getCurrentTimestamp:()=>performance.now()};var Hx=class{constructor(e,t){this.recordingStartTime=0,this.recordingTimer=null,this.pauseStartTime=null,this.totalPausedTime=0,this.streamProcessor=null,this.bufferSizeUpdateInterval=null,this.tabVisibilityTracker=null,this.visibilityChangeHandler=null,this.blurHandler=null,this.focusHandler=null,this.preResolvedSupportReport=null,this.activeRouteDecision=Lx,this.mediaRecorder=null,this.mediaRecorderChunks=[],this.mediaRecorderStopPromise=null,this.mediaRecorderStopResolve=null,this.mediaRecorderStopReject=null,this.streamManager=e;let n=t?.checkRecorderSupport,r;r=n===void 0?Vx.checkRecorderSupport:n;let i=t?.getCurrentTimestamp,a;a=i===void 0?Vx.getCurrentTimestamp:i,this.dependencies={checkRecorderSupport:r,getCurrentTimestamp:a}}setPreResolvedSupportReport(e){this.preResolvedSupportReport=e}isRecording(){return this.streamManager.getState()===`recording`}getStreamProcessor(){return this.streamProcessor}getAudioStreamForAnalysis(){if(this.streamProcessor){let e=this.streamProcessor.getAudioStreamForAnalysis();if(e)return e}return this.streamManager.getAudioStreamForAnalysis()}async startRecording(e,t,n,r,i){this.activeRouteDecision=i??Lx;let a=this.streamManager.getStream(),o=0;if(a!==null&&(o=a.getAudioTracks().length),$.debug(`[StreamRecordingState] startRecording called`,{hasMediaStream:!!a,isRecording:this.isRecording(),hasProcessor:!!e,audioTracks:o}),!a)throw Error(`Stream must be started before recording`);if(this.isRecording())return $.debug(`[StreamRecordingState] Already recording, returning`),Promise.resolve();if(!(a.getAudioTracks().length>0))throw $.error(`[StreamRecordingState] Cannot start recording without audio tracks`),yb();if(this.activeRouteDecision.route===`unsupported-with-guidance`)throw Bx(this.activeRouteDecision);if(this.activeRouteDecision.route===`local-webcodecs`){let e=t.watermark!==void 0,n;if(n=this.preResolvedSupportReport?.isSupported?this.preResolvedSupportReport:await this.dependencies.checkRecorderSupport({requiresAudio:!0,requiresWatermark:e}),!n.isSupported)throw Nt({missingCapabilities:n.missing,resolutionStage:`feature-preflight`})}this.streamProcessor=e,$.debug(`[StreamRecordingState] StreamProcessor assigned, setting callbacks`),e.setOnMuteStateChange(e=>{this.streamManager.emit(`audiomutetoggle`,{muted:e})}),e.setOnSourceChange(e=>{this.streamManager.emit(`videosourcechange`,{stream:e})}),this.bufferSizeUpdateInterval=window.setInterval(()=>{if(!this.streamProcessor)return;let e=this.streamProcessor.getBufferSize(),t=jx(e);this.streamManager.emit(`recordingbufferupdate`,{size:e,formatted:t})},Fx),this.resetRecordingState();let s;n===!0&&(s={enabled:!0,text:this.resolveTabVisibilityOverlayText(r),recordingStartTime:this.recordingStartTime}),$.debug(`[StreamRecordingState] Overlay config`,{enableTabVisibilityOverlay:n,hasOverlayText:!!r,overlayText:r,overlayConfig:s}),this.activeRouteDecision.route===`safe-capture-post-recording-transcode`?(await this.startSafeCaptureRecording(a,t),$.info(`[StreamRecordingState] MediaRecorder capture started for post-recording transcode`)):($.debug(`[StreamRecordingState] Starting processing`),await e.startProcessing(a,t,s),$.info(`[StreamRecordingState] Processing started and worker ready`)),n&&($.debug(`[StreamRecordingState] Setting up tab visibility tracking`,{recordingStartTime:this.recordingStartTime}),this.tabVisibilityTracker=new Px,this.tabVisibilityTracker.start(this.recordingStartTime),this.setupVisibilityUpdates(e)),this.streamManager.setState(`recording`),this.streamManager.emit(`recordingstart`,{recorder:null}),this.startRecordingTimer()}async stopRecording(){let e=(this.dependencies.getCurrentTimestamp()-this.recordingStartTime-this.totalPausedTime)/Ix;if($.debug(`[StreamRecordingState] stopRecording called`,{hasStreamProcessor:!!this.streamProcessor,isRecording:this.isRecording(),recordingElapsedSeconds:e}),!(this.streamProcessor&&this.isRecording()))throw Ex(Cx,`Recording is not ready to stop`,{hasStreamProcessor:!!this.streamProcessor,streamState:this.streamManager.getState()});this.streamManager.setState(`stopping`),this.clearRecordingTimer(),this.clearBufferSizeInterval(),this.resetPauseState(),this.cleanupVisibilityUpdates();let t=[];this.tabVisibilityTracker?(t=this.tabVisibilityTracker.getIntervals(),$.debug(`[StreamRecordingState] Tab visibility intervals collected`,{intervalsCount:t.length,intervals:t}),this.tabVisibilityTracker.cleanup(),this.tabVisibilityTracker=null):$.debug(`[StreamRecordingState] No tab visibility tracker was active`);let n;return this.activeRouteDecision.route===`safe-capture-post-recording-transcode`?($.debug(`[StreamRecordingState] Finalizing MediaRecorder capture`),n={blob:await this.stopSafeCaptureRecording()}):($.debug(`[StreamRecordingState] Finalizing stream processor`),n=await this.streamProcessor.finalize(),$.info(`[StreamRecordingState] Stream processor finalized`,{blobSize:n.blob.size,hasBlob:!!n.blob})),this.streamManager.setState(`active`),this.streamManager.emit(`recordingstop`,{blob:n.blob,mimeType:n.blob.type||`video/mp4`}),{blob:n.blob,tabVisibilityIntervals:t,recordingStats:n.recordingStats,encoderAcceleration:n.encoderAcceleration}}pauseRecording(){this.clearRecordingTimer(),this.pauseStartTime===null&&(this.pauseStartTime=this.dependencies.getCurrentTimestamp()),this.tabVisibilityTracker&&this.tabVisibilityTracker.pause(),this.streamProcessor&&this.isRecording()&&this.streamProcessor.pause()}resumeRecording(){if(this.pauseStartTime!==null){let e=this.dependencies.getCurrentTimestamp()-this.pauseStartTime;this.totalPausedTime+=e,this.pauseStartTime=null}this.tabVisibilityTracker&&this.tabVisibilityTracker.resume(),this.startRecordingTimer(),this.streamProcessor&&this.isRecording()&&this.streamProcessor.resume()}toggleMute(){Rb(this.streamProcessor,`StreamProcessor`).toggleMute()}muteAudio(){this.streamProcessor?(this.streamProcessor.isMutedState()||this.streamProcessor.toggleMute(),this.streamManager.setAudioTracksEnabled(!1)):this.streamManager.getStream()&&(this.streamManager.setAudioTracksEnabled(!1),this.streamManager.emit(`audiomutetoggle`,{muted:!0}))}unmuteAudio(){this.streamProcessor?(this.streamProcessor.isMutedState()&&this.streamProcessor.toggleMute(),this.streamManager.setAudioTracksEnabled(!0)):this.streamManager.getStream()&&(this.streamManager.setAudioTracksEnabled(!0),this.streamManager.emit(`audiomutetoggle`,{muted:!1}))}isMuted(){if(this.streamProcessor)return this.streamProcessor.isMutedState();let e=this.streamManager.getStream();if(e){let t=e.getAudioTracks();return t.length>0&&t.every(e=>!e.enabled)}return!1}async switchVideoSource(e){await Rb(this.streamProcessor,`StreamProcessor`).switchVideoSource(e)}getCurrentVideoSource(){return Lb(Rb(this.streamProcessor,`StreamProcessor`).getCurrentVideoSource(),`Current video source is not available`)}formatTimeElapsed(e){let t=Math.floor(e/60),n=Math.floor(e%60);return`${t.toString().padStart(2,`0`)}:${n.toString().padStart(2,`0`)}`}startRecordingTimer(){this.recordingTimer=window.setInterval(()=>{let e=(this.dependencies.getCurrentTimestamp()-this.recordingStartTime-this.totalPausedTime)/Ix,t=this.formatTimeElapsed(e);this.streamManager.emit(`recordingtimeupdate`,{elapsed:e,formatted:t})},Fx)}clearRecordingTimer(){this.recordingTimer!==null&&(clearInterval(this.recordingTimer),this.recordingTimer=null)}clearBufferSizeInterval(){this.bufferSizeUpdateInterval!==null&&(clearInterval(this.bufferSizeUpdateInterval),this.bufferSizeUpdateInterval=null)}resetRecordingState(){this.recordingStartTime=this.dependencies.getCurrentTimestamp(),this.totalPausedTime=0,this.pauseStartTime=null}async startSafeCaptureRecording(e,t){if(typeof MediaRecorder>`u`)throw Bx({route:`unsupported-with-guidance`,reasonCodes:[`mediarecorder-unavailable`],guidance:{canRetry:!0,message:`This browser cannot safely record on this device. Try a supported browser or upload an existing video file.`}});await this.applySafeCaptureTrackConstraints(e),this.mediaRecorderChunks=[];let n=this.resolvePreferredSafeCaptureMimeType(t),r=n===void 0?void 0:{mimeType:n},i=new MediaRecorder(e,r);this.mediaRecorder=i,this.mediaRecorderStopPromise=new Promise((e,t)=>{this.mediaRecorderStopResolve=e,this.mediaRecorderStopReject=t}),i.ondataavailable=e=>{e.data.size>0&&this.mediaRecorderChunks.push(e.data)},i.onstop=()=>{let e=i.mimeType||this.resolveSafeCaptureMimeType(),t=new Blob(this.mediaRecorderChunks,{type:e});this.mediaRecorderStopResolve?.(t)},i.onerror=()=>{this.mediaRecorderStopReject?.(Error(`Browser recording failed before upload could start`))},i.start()}async applySafeCaptureTrackConstraints(e){let t=this.resolveSafeCaptureVideoConstraints();if(t===null)return;let n=e.getVideoTracks();await Promise.all(n.map(async e=>{try{await e.applyConstraints(t)}catch(e){$.warn(`[StreamRecordingState] Could not apply safe capture video constraints`,e)}}))}resolveSafeCaptureVideoConstraints(){let e=this.activeRouteDecision.reasonCodes;return e.includes(`insufficient-device-memory`)||e.includes(`insufficient-hardware-concurrency`)?Rx:e.includes(`android-post-recording-transcode`)?zx:null}async stopSafeCaptureRecording(){let e=this.mediaRecorder,t=this.mediaRecorderStopPromise;if(!(e&&t))throw Error(`Safe capture recorder was not started`);e.state!==`inactive`&&e.stop();try{return await t}finally{this.mediaRecorder=null,this.mediaRecorderChunks=[],this.mediaRecorderStopPromise=null,this.mediaRecorderStopResolve=null,this.mediaRecorderStopReject=null,this.activeRouteDecision=Lx}}resolveSafeCaptureMimeType(){return(this.streamManager.getStream()?.getVideoTracks().length??0)>0?`video/webm`:`audio/webm`}resolvePreferredSafeCaptureMimeType(e){return(e.format===`mp4`?[`video/mp4;codecs=avc1.42E01E,mp4a.40.2`,`video/mp4;codecs=avc1.42001f,mp4a.40.2`,`video/mp4`]:[`video/webm;codecs=vp8,opus`,`video/webm;codecs=vp9,opus`,`video/webm`]).find(e=>typeof MediaRecorder.isTypeSupported==`function`?MediaRecorder.isTypeSupported(e):!1)}resetPauseState(){this.totalPausedTime=0,this.pauseStartTime=null}resolveTabVisibilityOverlayText(e){return e===void 0||e.trim().length===0?`User in another tab`:e}setupVisibilityUpdates(e){if(typeof document>`u`||typeof window>`u`){$.warn(`[StreamRecordingState] Cannot setup visibility updates - document/window not available`);return}if(this.visibilityChangeHandler=()=>{if(typeof document>`u`)return;let t=document.visibilityState===`hidden`,n=this.dependencies.getCurrentTimestamp();$.debug(`[StreamRecordingState] Visibility change`,{isHidden:t,timestamp:n,visibilityState:document.visibilityState}),e.updateTabVisibility(t,n)},this.blurHandler=()=>{let t=this.dependencies.getCurrentTimestamp();$.debug(`[StreamRecordingState] Window blur`,{timestamp:t}),e.updateTabVisibility(!0,t)},this.focusHandler=()=>{let t=this.dependencies.getCurrentTimestamp();$.debug(`[StreamRecordingState] Window focus`,{timestamp:t}),e.updateTabVisibility(!1,t)},document.addEventListener(`visibilitychange`,this.visibilityChangeHandler),window.addEventListener(`blur`,this.blurHandler),window.addEventListener(`focus`,this.focusHandler),document.visibilityState===`hidden`){let t=this.dependencies.getCurrentTimestamp();$.debug(`[StreamRecordingState] Initial state is hidden`,{timestamp:t}),e.updateTabVisibility(!0,t)}else $.debug(`[StreamRecordingState] Initial state is visible`)}cleanupVisibilityUpdates(){this.visibilityChangeHandler&&typeof document<`u`&&(document.removeEventListener(`visibilitychange`,this.visibilityChangeHandler),this.visibilityChangeHandler=null),this.blurHandler&&typeof window<`u`&&(window.removeEventListener(`blur`,this.blurHandler),this.blurHandler=null),this.focusHandler&&typeof window<`u`&&(window.removeEventListener(`focus`,this.focusHandler),this.focusHandler=null)}destroy(){this.mediaRecorder&&this.mediaRecorder.state!==`inactive`&&this.mediaRecorder.stop(),this.mediaRecorder=null,this.mediaRecorderChunks=[],this.mediaRecorderStopPromise=null,this.mediaRecorderStopResolve=null,this.mediaRecorderStopReject=null,this.activeRouteDecision=Lx,this.streamProcessor&&=(this.streamProcessor.destroy(),null),this.cleanupVisibilityUpdates(),this.tabVisibilityTracker&&=(this.tabVisibilityTracker.cleanup(),null),this.clearRecordingTimer(),this.clearBufferSizeInterval()}},Ux=class{constructor(e={}){this.streamManager=new Sx(e),this.recordingState=new Hx(this.streamManager)}getState(){return this.streamManager.getState()}getStream(){return this.streamManager.getStream()}getAudioStreamForAnalysis(){return this.recordingState.getAudioStreamForAnalysis()}isRecording(){return this.recordingState.isRecording()}isActive(){return this.streamManager.isActive()}on(e,t){return this.streamManager.on(e,t)}off(e,t){this.streamManager.off(e,t)}once(e,t){return this.streamManager.once(e,t)}setAudioDevice(e){this.streamManager.setAudioDevice(e)}setVideoDevice(e){this.streamManager.setVideoDevice(e)}getAudioDevice(){return this.streamManager.getAudioDevice()}getVideoDevice(){return this.streamManager.getVideoDevice()}async getAvailableDevices(){return await this.streamManager.getAvailableDevices()}async startStream(){return await this.streamManager.startStream()}stopStream(){this.streamManager.stopStream()}switchVideoDevice(e){return this.streamManager.switchVideoDevice(e)}switchAudioDevice(e){return this.streamManager.switchAudioDevice(e)}async startRecording(e,t,n,r,i){return await this.recordingState.startRecording(e,t,n,r,i)}async stopRecording(){return await this.recordingState.stopRecording()}pauseRecording(){this.recordingState.pauseRecording()}resumeRecording(){this.recordingState.resumeRecording()}toggleMute(){this.recordingState.toggleMute()}muteAudio(){this.recordingState.muteAudio()}unmuteAudio(){this.recordingState.unmuteAudio()}isMuted(){return this.recordingState.isMuted()}async switchVideoSource(e){return await this.recordingState.switchVideoSource(e)}setMediaStream(e){this.streamManager.setMediaStream(e)}getCurrentVideoSource(){return this.recordingState.getCurrentVideoSource()}getAudioStatus(){return this.streamManager.getAudioStatus()}isAudioReady(){return this.streamManager.isAudioReady()}async waitForAudio(){return await this.streamManager.waitForAudio()}setPreResolvedSupportReport(e){this.recordingState.setPreResolvedSupportReport(e)}destroy(){this.recordingState.destroy(),this.streamManager.destroy()}};let Wx=new Set([`recording.audio-no-chunks`,`recording.audio-silent`,`recording.audio-track-ended`,`recording.no-audio-track`,`recording.no-audio-frames`,`recording.audio-zero-channels`,`recording.audio-invalid-sample-rate`]),Gx=new Set([`recording.codec-unsupported`,`recording.video-codec-unavailable`]),Kx=new Set([`recording.post-recording-transcode-fallback`,`transcode.post-recording-fallback`,`route.post-recording-transcode-fallback`]),qx=new Set([`recording.no-video-frames`,`recording.frame-loss`,`recording.excessive-frame-errors`,`video.first-frame-timeout`]),Jx=new Set([`recording.finalize-timeout`,`recording.finalize-timeout-low-resource`,`stop.pending-writes-timeout`]),Yx=new Set([`recording.not-started`,`recording.state-race`,`recording.not-started-state-race`]),Xx=new Set([`recording.unsupported-with-guidance`,`recording.unsupported-device`]);function Zx(e){return e.startsWith(`recording.`)?Wx.has(e):!1}function Qx(e){return e==null?null:i(e)}function $x(e){if(!(e&&typeof e==`object`&&`code`in e))return null;let t=e.code;return typeof t!=`string`||t.length===0?null:t}function eS(e){return e?Gx.has(e)?`recording.codec-unsupported`:Kx.has(e)?`recording.post-recording-transcode-fallback`:qx.has(e)?`recording.no-video-frames`:Jx.has(e)?`recording.finalize-timeout-low-resource`:Yx.has(e)?`recording.not-started-state-race`:Xx.has(e)?`recording.unsupported-device`:null:null}function tS(e,t){return t.some(t=>e.includes(t))}function nS(e){if(!e)return null;let t=e.toLowerCase();return tS(t,[`videoencoder.isconfigsupported`,`unknown codec`,`unsupported codec`,`no encodable video codec`,`video codec unavailable`])?`recording.codec-unsupported`:tS(t,[`input track cannot be ended`,`mediastreamtrackprocessor`,`video track ended`])?`recording.track-ended`:tS(t,[`no video frames`,`zero video frames`,`video.first-frame-timeout`,`failed to yield first frame`,`frame-loss`,`excessive frame errors`])?`recording.no-video-frames`:tS(t,[`finalize timeout`,`stop.pending-writes-timeout`])||t.includes(`pending writes`)&&t.includes(`timeout`)?`recording.finalize-timeout-low-resource`:tS(t,[`cannot finalize before starting`,`processing not active`,`worker not initialized`])?`recording.not-started-state-race`:tS(t,[`recording.unsupported-with-guidance`,`cannot safely record`,`recording is not supported in this browser context`])?`recording.unsupported-device`:null}function rS(e){return eS(e.errorCode??$x(e.error))||nS(e.errorMessage??Qx(e.error))}let iS=Object.freeze({visible:!1,variant:`generic`,canRetry:!1,isCameraError:!1,isAudioError:!1,isBrowserUnsupported:!1,isPermissionDenied:!1});function aS(e){let{errorCode:t,hasAudioFailed:n,error:r}=e,i=rS({errorCode:t,error:r});if(t===`browser.unsupported`)return{visible:!0,variant:`browser`,canRetry:!1,isCameraError:!1,isAudioError:!1,isBrowserUnsupported:!0,isPermissionDenied:!1};if(t&&Zx(t))return{visible:!0,variant:`audio`,canRetry:!0,isCameraError:!1,isAudioError:!0,isBrowserUnsupported:!1,isPermissionDenied:!1};if(i)return{visible:!0,variant:`generic`,canRetry:!0,isCameraError:!1,isAudioError:!1,isBrowserUnsupported:!1,isPermissionDenied:!1,actionableCode:i,isRecordingPipelineError:!0};if(t?.startsWith(`camera.`)){let e=t===`camera.permission-denied`;return{visible:!0,variant:`camera`,canRetry:!e,isCameraError:!0,isAudioError:!1,isBrowserUnsupported:!1,isPermissionDenied:e}}if(n)return{visible:!0,variant:`audio`,canRetry:!0,isCameraError:!1,isAudioError:!0,isBrowserUnsupported:!1,isPermissionDenied:!1};if(t?.startsWith(`audio.`)){let e=t===`audio.permission-denied`;return{visible:!0,variant:`audio`,canRetry:!e,isCameraError:!1,isAudioError:!0,isBrowserUnsupported:!1,isPermissionDenied:e}}return r?{visible:!0,variant:`generic`,canRetry:!0,isCameraError:!1,isAudioError:!1,isBrowserUnsupported:!1,isPermissionDenied:!1}:iS}let oS=`VIDTREO_INSTALLATION_ID`,sS=`unknown`,cS=/\[([a-z]+(?:[.-][a-z0-9]+)+)\]/i,lS=/\b([a-z]+(?:[.-][a-z0-9]+)+)\b/i;function uS(e){let t=e.storageProvider,n=t?.getItem(oS);if(n)return $.debug(`Using existing installation ID from storage`,{installationId:n}),n;let r=dS(e);return t?.setItem(oS,r),$.debug(`Created new installation ID`,{installationId:r}),r}function dS(e){let t=e.cryptoProvider;if(t?.getRandomValues){let e=new Uint8Array(16);return t.getRandomValues(e),Array.from(e).map(e=>e.toString(16).padStart(2,`0`)).join(``)}let n=e.nowProvider().toString(16),r=e.randomProvider();return`${n}-${Math.floor(r*1e9).toString(16)}`}let fS=[`sdk.init.started`,`sdk.init.succeeded`,`sdk.init.failed`],pS=[`stream.error`],mS={"sdk.init.started":`lifecycle`,"sdk.init.succeeded":`lifecycle`,"sdk.init.failed":`error`,"preview.start.succeeded":`interaction`,"preview.start.failed":`error`,"recording.start.requested":`interaction`,"recording.start.succeeded":`interaction`,"recording.start.failed":`error`,"recording.stop.requested":`interaction`,"recording.stop.succeeded":`interaction`,"recording.stop.failed":`error`,"recording.route.selected":`lifecycle`,"upload.started":`performance`,"upload.succeeded":`performance`,"upload.failed":`error`,"upload.route.selected":`lifecycle`,"transcode.route.selected":`lifecycle`,"source.switch.requested":`interaction`,"source.switch.succeeded":`interaction`,"source.switch.failed":`error`,"stream.error":`error`,"audio.acquisition.fallback":`lifecycle`,"audio.acquisition.retry":`lifecycle`,"audio.acquisition.recovered":`lifecycle`,"audio.acquisition.failed":`error`,"audio.warning":`error`,"recording.audio-missing":`error`,"storage.init.failed":`error`,"storage.write.probe.failed":`error`};var hS=class{constructor(e,t){this.pendingEvents=[],this.flushTimeoutId=null,this.throttledEventTimestamps=new Map,this.retryCountMap=new Map,this.oneTimeEventCache=new Map,this.config=e,this.dependencies=t,this.installationId=uS(this.dependencies),$.debug(`TelemetryClient initialized`,{installationId:this.installationId,backendUrl:e.backendUrl})}triggerTelemetryEvent(e){try{let t=this.dependencies.nowProvider();if(this.shouldSkipEvent(e.name,t))return;let n=mS[e.name],r=this.buildError(e.error),i=this.buildFingerprint(),a=this.buildContext(),o=this.mergeProperties(this.buildBaseProperties(i),e),s={event:e.name,category:n,timestamp:t,installationId:this.installationId,fingerprint:i,sdkVersion:`1.6.1`,context:a,properties:o,error:r};this.markEventTracking(e.name,t),this.enqueueEvent(s)}catch(t){$.error(`Telemetry event failed`,{eventName:e.name,error:i(t)})}}enqueueEvent(e){try{if(this.pendingEvents=[...this.pendingEvents,e],this.pendingEvents.length>=10){this.flushQueue();return}this.scheduleFlush()}catch(e){$.error(`Failed to enqueue telemetry event`,{error:i(e)})}}scheduleFlush(){this.flushTimeoutId||=this.dependencies.setTimeoutFunction(()=>{this.flushQueue()},1e3)}flushQueue(){try{if(this.pendingEvents.length===0){this.clearFlushTimer();return}let e=this.pendingEvents;this.pendingEvents=[],this.clearFlushTimer();let t=this.buildRequestPayload(e);$.debug(`Telemetry batch flush`,{eventsCount:t.events.length}),this.sendPayload(t).then(()=>{this.clearRetryMetadata(e)}).catch(()=>{this.requeueFailedEvents(e)})}catch(e){$.error(`Failed to flush telemetry queue`,{error:i(e)})}}clearFlushTimer(){this.flushTimeoutId&&=(this.dependencies.clearTimeoutFunction(this.flushTimeoutId),null)}buildRequestPayload(e){return{events:[...e]}}shouldSkipEvent(e,t){if(this.isOneTimeEvent(e)){let t=this.getOneTimeCacheKey(e);if(this.oneTimeEventCache.get(t))return $.debug(`Telemetry event skipped (dedupe)`,{event:e}),!0}if(this.isThrottledEvent(e)){let n=this.throttledEventTimestamps.get(e);if(n!==void 0&&t-n<5e3)return $.debug(`Telemetry event skipped (throttle)`,{event:e,lastSent:n}),!0}return!1}markEventTracking(e,t){if(this.isOneTimeEvent(e)){let t=this.getOneTimeCacheKey(e);this.oneTimeEventCache.set(t,!0)}this.isThrottledEvent(e)&&(this.throttledEventTimestamps=this.updateNumberMap(this.throttledEventTimestamps,e,t))}updateNumberMap(e,t,n){let r=new Map(e);return r.set(t,n),r}getOneTimeCacheKey(e){return`${this.installationId}:${e}`}isOneTimeEvent(e){return fS.includes(e)}isThrottledEvent(e){return pS.includes(e)}buildBaseProperties(e){let t={},n=e.userAgent,r=this.getBrowserName(n);return r&&(t={...t,browserName:r}),t}mergeProperties(e,t){let n=this.sanitizeEventProperties(t.properties),r=this.buildErrorProperties(t.error);if(Object.keys(e).length===0&&Object.keys(r).length===0&&!n)return;let i={...e,...r,...n};if(Object.keys(i).length>0)return i}sanitizeEventProperties(e){if(!e)return;let t=this.sanitizeRouteDecision(e.routeDecision);return t===void 0?e:{...e,routeDecision:t}}sanitizeRouteDecision(e){if(!(e&&typeof e==`object`))return;let t=e,n={};typeof t.selectedRoute==`string`&&(n={...n,selectedRoute:t.selectedRoute}),Array.isArray(t.reasonCodes)&&(n={...n,reasonCodes:t.reasonCodes.filter(e=>typeof e==`string`)});let r=this.sanitizeCapabilitySummary(t.capabilitySummary);if(r!==void 0&&(n={...n,capabilitySummary:r}),this.isRouteSourceType(t.sourceType)&&(n={...n,sourceType:t.sourceType}),typeof t.clientTranscodeDeferred==`boolean`&&(n={...n,clientTranscodeDeferred:t.clientTranscodeDeferred}),Object.keys(n).length!==0)return n}sanitizeCapabilitySummary(e){if(!(e&&typeof e==`object`))return;let t={};for(let[n,r]of Object.entries(e))this.isSafeCapabilityValue(r)&&(t={...t,[n]:r});if(Object.keys(t).length!==0)return t}isSafeCapabilityValue(e){return e===null||typeof e==`boolean`||typeof e==`number`||typeof e==`string`?!0:Array.isArray(e)&&e.every(e=>typeof e==`string`)}isRouteSourceType(e){return e===`live-recorder`||e===`native-camera`||e===`file-upload`}buildErrorProperties(e){if(!e)return{};let t={},n=$x(e),r=i(e),a=n??this.extractNormalizedErrorCode(r),o=rS({errorCode:a,error:e,errorMessage:r});return a&&(t={...t,errorCode:a}),o&&(t={...t,rawErrorClassification:o,recordingPipelineErrorCode:o}),t}buildFingerprint(){let e=this.dependencies.navigatorProvider;if(!e)return{};let t={userAgent:e.userAgent,language:e.language,platform:e.platform};e.hardwareConcurrency&&(t={...t,hardwareConcurrency:e.hardwareConcurrency});let n=this.getDeviceMemory(e);return n!==null&&(t={...t,deviceMemory:n}),t}buildContext(){let e=this.config.pageUrl,t=this.config.referrerUrl;if(!e){let t=this.dependencies.locationProvider;t&&(e=t.href)}if(!t){let e=this.dependencies.documentProvider;if(e){let n=e.referrer;n&&(t=n)}}return{sessionId:this.config.sessionId,userId:this.config.userId,environmentId:this.config.environmentId,appVersion:this.config.appVersion,release:this.config.release,pageUrl:e,referrerUrl:t,sdkLocation:this.config.sdkLocation,clientLocation:this.config.clientLocation}}buildError(e){if(!e)return;let t=i(e),n={message:t},r=$x(e),a=r??this.extractNormalizedErrorCode(t);return a&&(n.normalizedCode=a),r?n.code=r:a&&(n.code=a),e instanceof Error&&(!n.code&&e.name&&(n.code=e.name),e.stack&&(n.stack=e.stack)),n}extractNormalizedErrorCode(e){let t=e.match(cS);if(t?.[1])return t[1];let n=e.match(lS);return n?.[1]?n[1]:null}getBrowserName(e){return e?e.includes(`Edg`)?`edge`:e.includes(`Chrome`)?`chrome`:e.includes(`Firefox`)?`firefox`:e.includes(`Safari`)?`safari`:sS:sS}getDeviceMemory(e){let t=e;return t.deviceMemory?t.deviceMemory:null}async sendPayload(e){let t=this.buildTelemetryEndpoint(),n={method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${this.config.apiKey}`},body:JSON.stringify(e)};$.debug(`Sending telemetry to endpoint`,{endpoint:t,payloadSize:JSON.stringify(e).length,hasApiKey:!!this.config.apiKey});let r=await this.dependencies.fetchFunction(t,n).catch(e=>{throw $.error(`Failed to send telemetry`,{endpoint:t,error:i(e)}),e});if(r&&!r.ok)throw $.error(`Telemetry endpoint returned error`,{status:r.status}),Error(`Telemetry HTTP ${r.status}`)}requeueFailedEvents(e){let t=e.filter(e=>(this.retryCountMap.get(e)??0)<3);for(let e of t){let t=this.retryCountMap.get(e)??0;this.retryCountMap.set(e,t+1)}let n=e.length-t.length;if(n>0){let r=e.filter(e=>!t.includes(e));this.clearRetryMetadata(r),$.warn(`Dropped ${n} telemetry events after max retries`)}if(t.length===0)return;let r=this.pendingEvents.length,i=Math.max(0,100-r);this.pendingEvents=[...t.slice(0,i),...this.pendingEvents],this.scheduleFlush()}clearRetryMetadata(e){for(let t of e)this.retryCountMap.delete(t)}buildTelemetryEndpoint(){return this.config.endpoint?this.config.endpoint:`${this.config.backendUrl}/api/v1/telemetry`}};function gS(){let e=typeof window<`u`,t=typeof document<`u`,n=fetch,r=null,i=null,a=null,o=null,s=null,c=setTimeout,l=clearTimeout;return e&&(n=window.fetch.bind(window),r=window.crypto,i=window.localStorage,a=window.navigator,o=window.location,c=window.setTimeout.bind(window),l=window.clearTimeout.bind(window)),t&&(s=document),{fetchFunction:n,cryptoProvider:r,storageProvider:i,navigatorProvider:a,locationProvider:o,documentProvider:s,nowProvider:()=>Date.now(),randomProvider:()=>Math.random(),setTimeoutFunction:c,clearTimeoutFunction:l}}function _S(e,t,n){return new hS({apiKey:e,backendUrl:t,endpoint:n?.endpoint,sessionId:n?.sessionId,userId:n?.userId,environmentId:n?.environmentId,appVersion:n?.appVersion,release:n?.release,pageUrl:n?.pageUrl,referrerUrl:n?.referrerUrl,sdkLocation:n?.sdkLocation,clientLocation:n?.clientLocation},gS())}var vS=class{constructor(e,t){this.isProcessing=!1,this.hasRecoveredStaleUploads=!1,this.retryTimeoutId=null,this.callbacks={},this.storageService=e,this.uploadService=t,this.networkOnlineHandler=()=>{this.processQueue().catch(e=>{let t=i(e);this.callbacks.onUploadError?.(`network-recovery`,Error(t))})},window.addEventListener(`online`,this.networkOnlineHandler),this.processingIntervalId=window.setInterval(()=>{this.processQueue().catch(e=>{let t=i(e);this.callbacks.onUploadError?.(`processing-loop`,Error(t))})},5e3)}destroy(){this.clearTimer(this.processingIntervalId,clearInterval),this.clearTimer(this.retryTimeoutId,clearTimeout),window.removeEventListener(`online`,this.networkOnlineHandler)}setCallbacks(e){this.callbacks=e}async queueUpload(e){let t=await this.storageService.savePendingUpload(e);return this.processQueue().catch(e=>{let n=i(e);this.callbacks.onUploadError?.(t,Error(n))}),t}async processQueue(){if(!this.isProcessing){this.isProcessing=!0;try{if(!this.storageService.isInitialized())throw Error(`Database not initialized`);if(!this.hasRecoveredStaleUploads){let e=await this.storageService.getPendingUploads(`uploading`);await Promise.all(e.map(e=>this.storageService.updateUploadStatus(e.id,{status:`pending`}))),this.hasRecoveredStaleUploads=!0}let e=await this.storageService.getPendingUploads(`pending`);if(e.length>0){let t=this.getOldestUpload(e);await this.processUpload(t),this.isProcessing=!1;return}let t=(await this.storageService.getPendingUploads(`failed`)).filter(e=>e.retryCount<10);if(t.length>0){let e=this.getOldestFailedUpload(t),n=this.calculateRetryDelay(e.retryCount),r=Date.now()-e.updatedAt;if(r>=n)await this.storageService.updateUploadStatus(e.id,{status:`pending`,retryCount:e.retryCount}),await this.processUpload(e);else{let e=n-r;this.scheduleRetry(e)}}this.isProcessing=!1}catch(e){throw this.isProcessing=!1,Error(`Error processing upload queue: ${i(e)}`)}}}getPendingUploads(){return this.storageService.getPendingUploads()}async getStats(){let e=await this.storageService.getPendingUploads(),t={pending:0,uploading:0,failed:0,total:e.length};for(let n of e)n.status===`pending`?t.pending+=1:n.status===`uploading`?t.uploading+=1:n.status===`failed`&&(t.failed+=1);return t}getOldestUpload(e){if(e.length===0)throw Error(`Cannot get oldest upload from empty array`);return e.sort((e,t)=>e.createdAt-t.createdAt)[0]}getOldestFailedUpload(e){if(e.length===0)throw Error(`Cannot get oldest failed upload from empty array`);return e.sort((e,t)=>e.updatedAt-t.updatedAt)[0]}async processUpload(e){try{await this.storageService.updateUploadStatus(e.id,{status:`uploading`});let t=await this.uploadService.uploadVideo(e.blob,{apiKey:e.apiKey,backendUrl:e.backendUrl,filename:e.filename,metadata:e.metadata,userMetadata:e.userMetadata,onProgress:t=>{this.callbacks.onUploadProgress?.(e.id,t)}});await this.storageService.deleteUpload(e.id),this.callbacks.onUploadComplete?.(e.id,t)}catch(t){let n=i(t),r=e.retryCount+1;if(await this.storageService.updateUploadStatus(e.id,{status:`failed`,retryCount:r,lastError:n}),r>=10)this.callbacks.onUploadError?.(e.id,Error(`Upload failed after 10 attempts: ${n}`));else{let e=this.calculateRetryDelay(r);this.scheduleRetry(e)}}}calculateRetryDelay(e){let t=2e3*1.5**(e-1);return Math.min(t,3e5)}scheduleRetry(e){this.clearTimer(this.retryTimeoutId,clearTimeout),this.retryTimeoutId=window.setTimeout(()=>{this.retryTimeoutId=null,this.processQueue().catch(e=>{let t=i(e);this.callbacks.onUploadError?.(`scheduled-retry`,Error(t))})},e)}clearTimer(e,t){e!==null&&t(e)}},yS=class{uploadVideo(e,t){if(!t.filename)throw Error(`Filename is required`);if(!e.type||e.type.trim()===``)throw Error(`Blob type is required`);return this.uploadVideoFile(e,t)}uploadVideoFile(e,t){return new Promise((n,r)=>{let i=new XMLHttpRequest;if(t.onProgress){let e=t.onProgress;i.upload.addEventListener(`progress`,t=>{t.lengthComputable&&e(t.loaded/t.total)})}i.addEventListener(`load`,()=>{if(i.status>=200&&i.status<=299){this.parseSuccessResponse(i,n,r);return}this.parseErrorResponse(i,r)}),i.addEventListener(`error`,()=>{r(Error(`Network error during upload`))}),i.addEventListener(`abort`,()=>{r(Error(`Upload was aborted`))});let a=`${t.backendUrl}/api/v1/videos/upload`;i.open(`POST`,a),i.setRequestHeader(`Authorization`,`Bearer ${t.apiKey}`);let o=new FormData;o.append(`file`,e,t.filename);let s={filename:t.filename,mimeType:e.type};t.userMetadata&&(s.userMetadata=t.userMetadata),o.append(`metadata`,JSON.stringify(s)),i.send(o)})}parseSuccessResponse(e,t,n){let r=this.safeParseJsonFromXhr(e);if(!r){n(Error(`Failed to parse upload response: invalid JSON`));return}let i=r.data;if(!i){n(Error(`Failed to parse upload response: missing data`));return}t({id:i.id,publicId:i.publicId,filename:i.filename,fileSize:i.fileSize,mimeType:i.mimeType,duration:i.duration,status:i.status,uploadUrl:i.uploadUrl,createdAt:i.createdAt})}parseErrorResponse(e,t){let n=this.safeParseJsonFromXhr(e);if(n&&typeof n==`object`&&`error`in n&&typeof n.error==`string`){t(Error(n.error));return}t(Error(`Upload failed: ${e.status} ${e.statusText}`))}safeParseJsonFromXhr(e){if(!e.responseText||e.responseText.trim()===``)return null;let t=e.responseText.trim();if(!(t.startsWith(`{`)&&t.endsWith(`}`))||t.length<2)return null;let n=JSON.parse(e.responseText);return typeof n==`object`&&n?n:null}};let bS=e=>{},xS=e=>{},SS=e=>{},CS=()=>{},wS=e=>{},TS=(e,t)=>{},ES=e=>{},DS=e=>{},OS=e=>{},kS=()=>{},AS=e=>{};function jS(e){let t={onProgress:bS,onSuccess:xS,onError:SS,onClearStatus:CS};return e.upload&&(t=e.upload),t}let MS=e=>{};function NS(e){let t=AS;return e.onStorageCleanupError&&(t=e.onStorageCleanupError),t}function PS(e){let t=MS;return e.onStorageWriteError&&(t=e.onStorageWriteError),t}function FS(e,t){let n=e.recording,r=wS;n?.onStateChange&&(r=n.onStateChange);let i=TS;n?.onCountdownUpdate&&(i=n.onCountdownUpdate);let a=ES;n?.onTimerUpdate&&(a=n.onTimerUpdate);let o=DS;n?.onError&&(o=n.onError);let s=OS;n?.onRecordingComplete&&(s=n.onRecordingComplete);let c=kS;return n?.onClearUploadStatus&&(c=n.onClearUploadStatus),{onStateChange:r,onCountdownUpdate:i,onTimerUpdate:a,onError:o,onRecordingComplete:s,onClearUploadStatus:c,onStopAudioTracking:t.stopAudioTracking,onGetConfig:t.getConfig,...t.getRouteDecision&&{onGetRouteDecision:t.getRouteDecision},...t.onAudioWarning&&{onAudioWarning:t.onAudioWarning},...t.onAudioRecovered&&{onAudioRecovered:t.onAudioRecovered},...t.onTranscodingProgress&&{onTranscodingProgress:t.onTranscodingProgress}}}function IS(e,t){let n=e.sourceSwitch;return{onSourceChange:n?.onSourceChange,onPreviewUpdate:n?.onPreviewUpdate,onError:n?.onError,onTransitionStart:n?.onTransitionStart,onTransitionEnd:n?.onTransitionEnd,onScreenSelectionStart:()=>{t.isRecording()&&t.updateSourceType(!0)},onScreenSelectionEnd:()=>{t.isRecording()&&t.updateSourceType(!1)},getSelectedCameraDeviceId:t.getSelectedCameraDeviceId,getSelectedMicDeviceId:t.getSelectedMicDeviceId}}var LS=class{constructor(e={}){this.totalChunks=0,this.nonSilentChunks=0,this.lowSignalChunks=0,this.peak=0,this.rms=0,this.inputPeak=0,this.inputRms=0,this.startedAtMs=null,this.lastChunkTimestampMs=null,this.silentStartedAtMs=null,this.lowSignalStartedAtMs=null,this.mutedSpeechStartedAtMs=null,this.mutedStartedAtMs=null,this.mutedDurationMs=0,this.currentMuted=!1,this.hasHealthySignal=!1,this.silenceThreshold=this.resolveNumber(e.silenceThreshold,.001),this.lowSignalThreshold=this.resolveNumber(e.lowSignalThreshold,.05),this.mutedSpeechThreshold=this.resolveNumber(e.mutedSpeechThreshold,this.silenceThreshold),this.silentWarningDurationMs=this.resolveNumber(e.silentWarningDurationMs,2e3),this.lowSignalWarningDurationMs=this.resolveNumber(e.lowSignalWarningDurationMs,2e3),this.mutedSpeechWarningDurationMs=this.resolveNumber(e.mutedSpeechWarningDurationMs,1e4),this.noChunkWarningDurationMs=this.resolveNumber(e.noChunkWarningDurationMs,2e3)}recordChunk(e){this.markStarted(e.timestampMs),this.trackMuteState(e.timestampMs,e.isMuted);let t=this.calculateChunkStats(e.samples),n=this.resolveOptionalNumber(e.inputPeak,t.peak),r=this.resolveOptionalNumber(e.inputRms,t.rms),i=t.peak<=this.silenceThreshold,a=!e.isMuted&&t.peak>this.silenceThreshold&&t.peak<this.lowSignalThreshold,o=e.isMuted&&n>this.mutedSpeechThreshold;return this.totalChunks+=1,this.peak=t.peak,this.rms=t.rms,this.inputPeak=n,this.inputRms=r,i||(this.nonSilentChunks+=1,this.silentStartedAtMs=null),a&&(this.lowSignalChunks+=1),t.peak>=this.lowSignalThreshold&&(this.hasHealthySignal=!0),i&&this.silentStartedAtMs===null&&(this.silentStartedAtMs=e.timestampMs),a&&this.lowSignalStartedAtMs===null&&(this.lowSignalStartedAtMs=e.timestampMs),a||(this.lowSignalStartedAtMs=null),o&&this.mutedSpeechStartedAtMs===null&&(this.mutedSpeechStartedAtMs=e.timestampMs),o||(this.mutedSpeechStartedAtMs=null),this.lastChunkTimestampMs=e.timestampMs,this.snapshot(e.timestampMs,e.isMuted)}inspect(e,t){return this.markStarted(e),this.trackMuteState(e,t),this.snapshot(e,t)}reset(){this.totalChunks=0,this.nonSilentChunks=0,this.lowSignalChunks=0,this.peak=0,this.rms=0,this.inputPeak=0,this.inputRms=0,this.startedAtMs=null,this.lastChunkTimestampMs=null,this.silentStartedAtMs=null,this.lowSignalStartedAtMs=null,this.mutedSpeechStartedAtMs=null,this.mutedStartedAtMs=null,this.mutedDurationMs=0,this.currentMuted=!1,this.hasHealthySignal=!1}snapshot(e,t){let n=this.resolveSilentDuration(e),r=this.resolveLowSignalDuration(e),i=this.resolveMutedSpeechDuration(e),a=this.resolveNoChunkDuration(e),o=this.resolveMutedDuration(e,t);return{classification:this.classify(t,n,r,i,a),totalChunks:this.totalChunks,nonSilentChunks:this.nonSilentChunks,lowSignalChunks:this.lowSignalChunks,peak:this.peak,rms:this.rms,inputPeak:this.inputPeak,inputRms:this.inputRms,consecutiveSilentDurationMs:n,consecutiveLowSignalDurationMs:r,consecutiveMutedSpeechDurationMs:i,noChunkDurationMs:a,mutedDurationMs:o,hasHealthySignal:this.hasHealthySignal}}getFinalSnapshot(e,t){let n=this.resolveMutedDuration(e,t);return{totalChunks:this.totalChunks,nonSilentChunks:this.nonSilentChunks,lowSignalChunks:this.lowSignalChunks,mutedDurationMs:n,hasHealthySignal:this.hasHealthySignal}}classify(e,t,n,r,i){return this.totalChunks===0&&i>=this.noChunkWarningDurationMs?`no-chunks`:e&&r>=this.mutedSpeechWarningDurationMs?`speaking-while-muted`:e&&t>=this.silentWarningDurationMs?`muted-silence-expected`:!e&&t>=this.silentWarningDurationMs?`silent-while-unmuted`:!e&&this.nonSilentChunks>0&&this.peak<this.lowSignalThreshold&&n>=this.lowSignalWarningDurationMs?`low-signal`:`healthy`}calculateChunkStats(e){if(e.length===0)return{peak:0,rms:0};let t=0,n=0;for(let r of e){let e=Math.abs(r);t=Math.max(t,e),n+=r*r}return{peak:t,rms:Math.sqrt(n/e.length)}}resolveSilentDuration(e){return this.silentStartedAtMs===null?0:e-this.silentStartedAtMs}resolveLowSignalDuration(e){return this.lowSignalStartedAtMs===null?0:e-this.lowSignalStartedAtMs}resolveMutedSpeechDuration(e){return this.mutedSpeechStartedAtMs===null?0:e-this.mutedSpeechStartedAtMs}resolveNoChunkDuration(e){return this.lastChunkTimestampMs===null?this.startedAtMs===null?0:e-this.startedAtMs:e-this.lastChunkTimestampMs}markStarted(e){this.startedAtMs===null&&(this.startedAtMs=e)}trackMuteState(e,t){if(t!==this.currentMuted){if(t){this.mutedStartedAtMs=e,this.currentMuted=!0;return}this.mutedStartedAtMs!==null&&(this.mutedDurationMs+=e-this.mutedStartedAtMs),this.mutedStartedAtMs=null,this.currentMuted=!1}}resolveMutedDuration(e,t){return t&&this.mutedStartedAtMs!==null?this.mutedDurationMs+e-this.mutedStartedAtMs:this.mutedDurationMs}resolveNumber(e,t){if(e===void 0)return t;if(!Number.isFinite(e)||e<0)throw Error(`Audio health monitor option must be a non-negative number`);return e}resolveOptionalNumber(e,t){return e===void 0||!Number.isFinite(e)||e<0?t:e}};function RS(e){let t=e.getVideoTracks();if(t.length===0)return!1;let n=t[0];return`displaySurface`in n.getSettings()||n.label.toLowerCase().includes(`screen`)||n.label.toLowerCase().includes(`display`)}Sv();function zS(e){if(e!==void 0)return typeof e==`number`?e:e===lf?`low`:e===uf?`medium`:e===df?`high`:e===ff?`very-high`:`high`}function BS(e){let t=null,n=0;function r(){if(!t){let n=e.createBlob();t=e.createObjectUrl(n)}return n+=1,t}function i(){n!==0&&(--n,n===0&&(t&&=(e.revokeObjectUrl(t),null)))}return{acquire:r,release:i}}let VS=`vidtreo-audio-worklet`,HS=`audioChunk`,US=`setMuted`,WS=`setPaused`,GS=`shutdown`,KS=`
141
- const AUDIO_WORKLET_MESSAGE_TYPE_AUDIO_CHUNK = "${HS}";
142
- const AUDIO_WORKLET_MESSAGE_TYPE_SET_MUTED = "${US}";
143
- const AUDIO_WORKLET_MESSAGE_TYPE_SET_PAUSED = "${WS}";
144
- const AUDIO_WORKLET_MESSAGE_TYPE_SHUTDOWN = "${GS}";
140
+ };`],{type:`application/javascript`})}function zy(){let e=Ry();return URL.createObjectURL(e)}function By(e){URL.revokeObjectURL(e)}let Vy=`probe`,Hy=`probeResult`,Uy=`mediaStreamTrackProcessor`,Wy=`unavailable`,Gy=`unavailable`,Ky=new Map,qy=new Map;function Jy(e,t){return typeof e==`boolean`?e:t}function Yy(e){return e?`1`:`0`}function Xy(e,t){return[`audio`,Yy(e),`watermark`,Yy(t)].join(`|`)}function Zy(){return typeof process>`u`||process.env,!0}function Qy(e){return e.probeResult.hasMediaStreamTrackProcessor?`worker-track`:e.hasMainThreadMediaStreamTrackProcessor?`main-thread-stream`:Wy}function $y(e){return e.requiresAudio?e.hasMainThreadMediaStreamTrackProcessor&&e.probeResult.hasAudioData?`main-thread-audio-stream`:e.hasAudioContext&&e.hasAudioWorklet?`audio-worklet-chunks`:Gy:`none-required`}function eb(e,t){return e.includes(t)?e:[...e,t]}function tb(e,t){let n=e;return t.hasWorker||(n=eb(n,`worker`)),t.probeResult.hasVideoFrame||(n=eb(n,`videoFrame`)),t.probeResult.hasOffscreenCanvas||(n=eb(n,`offscreenCanvas`)),t.probeResult.hasReadableStream||(n=eb(n,`readableStream`)),n}function nb(e,t){let n=e;return t.requiresWatermark&&!t.probeResult.hasCreateImageBitmap&&(n=eb(n,`createImageBitmap`)),n}function rb(e,t){let n=e;return t.videoPath===Wy&&(n=eb(n,Uy)),n}function ib(e,t){let n=e;return t.hasMainThreadMediaStreamTrackProcessor&&t.probeResult.hasAudioData?n:(t.hasMainThreadMediaStreamTrackProcessor||(n=eb(n,Uy)),t.hasMainThreadMediaStreamTrackProcessor&&!t.probeResult.hasAudioData&&(n=eb(n,`audioData`)),n)}function ab(e,t){let n=e;return t.hasAudioContext&&t.hasAudioWorklet?n:(t.hasAudioContext||(n=eb(n,`audioContext`)),t.hasAudioWorklet||(n=eb(n,`audioWorklet`)),n)}function ob(e,t){let n=e;return t.requiresAudio&&t.audioPath===Gy?(n=ib(n,t),n=ab(n,t),n):n}function sb(e){let t=[];return t=tb(t,e),t=nb(t,e),t=rb(t,e),t=ob(t,e),t}function cb(e,t){return!(e===Wy||t===Gy)}function lb(e,t){return!(!e.hasVideoFrame||!e.hasOffscreenCanvas||!e.hasReadableStream||t&&!e.hasCreateImageBitmap)}async function ub(e={},t={}){let n=Jy(e.requiresAudio,!0),r=Jy(e.requiresWatermark,!1);if(!Zy())return await db(n,r,t);let i=Xy(n,r),a=Ky.get(i);if(a)return a;let o=qy.get(i);if(o)return await o;let s=db(n,r,t).then(e=>(Ky.set(i,e),qy.delete(i),e)).catch(e=>{throw qy.delete(i),e});return qy.set(i,s),await s}async function db(e,t,n){let r=typeof Worker<`u`,i=a()!==null,o=typeof AudioWorkletNode<`u`,s=typeof MediaStreamTrackProcessor<`u`,c=await fb(r,n),l=Qy({probeResult:c,hasMainThreadMediaStreamTrackProcessor:s}),u=$y({requiresAudio:e,hasAudioContext:i,hasAudioWorklet:o,hasMainThreadMediaStreamTrackProcessor:s,probeResult:c}),d=sb({hasWorker:r,hasAudioContext:i,hasAudioWorklet:o,hasMainThreadMediaStreamTrackProcessor:s,probeResult:c,requiresAudio:e,requiresWatermark:t,videoPath:l,audioPath:u}),f=cb(l,u),p=lb(c,t);return{isSupported:r&&f&&p,missing:d,hasWorker:r,hasAudioContext:i,hasAudioWorklet:o,hasMediaStreamTrackProcessor:c.hasMediaStreamTrackProcessor,hasMainThreadMediaStreamTrackProcessor:s,hasVideoFrame:c.hasVideoFrame,hasAudioData:c.hasAudioData,hasOffscreenCanvas:c.hasOffscreenCanvas,hasCreateImageBitmap:c.hasCreateImageBitmap,hasReadableStream:c.hasReadableStream,requiresAudio:e,requiresWatermark:t,videoPath:l,audioPath:u}}async function fb(e,t){if(!e)return mb();let n=await pb().catch(()=>null);return n?await new Promise(e=>{let r=!1,i=t.probeTimeoutMilliseconds??2e3,a=t=>{r||(r=!0,n.terminate(),e(t))},o=setTimeout(()=>{a(mb())},i);n.onmessage=e=>{let t=e.data;t.type===Hy&&(clearTimeout(o),a({hasMediaStreamTrackProcessor:t.hasMediaStreamTrackProcessor===!0,hasVideoFrame:t.hasVideoFrame===!0,hasAudioData:t.hasAudioData===!0,hasOffscreenCanvas:t.hasOffscreenCanvas===!0,hasCreateImageBitmap:t.hasCreateImageBitmap===!0,hasReadableStream:t.hasReadableStream===!0}))},n.onerror=()=>{clearTimeout(o),a(mb())},Promise.resolve().then(()=>{n.postMessage({type:Vy})}).catch(()=>{clearTimeout(o),a(mb())})}):mb()}function pb(){return Promise.resolve().then(()=>{let e=zy();try{let t=new Worker(e,{type:`classic`});return By(e),t}catch(t){throw By(e),t}})}function mb(){return{hasMediaStreamTrackProcessor:!1,hasVideoFrame:!1,hasAudioData:!1,hasOffscreenCanvas:!1,hasCreateImageBitmap:!1,hasReadableStream:!1}}let hb=`recording.audio-no-chunks`,gb=`recording.audio-silent`,_b=`recording.audio-track-ended`,vb=`audio.no-track-at-start`;function yb(e,t){let n=Error(e);return n.code=e,t&&(n.details=t),n}function bb(){let e=Error(vb);return e.code=vb,e}function xb(e){if(!(e instanceof Error))return!1;let t=e;return t.code===hb||t.code===gb||t.code===_b||t.code===`recording.no-audio-track`||t.code===`recording.no-audio-frames`||t.code===`recording.audio-zero-channels`||t.code===`recording.audio-invalid-sample-rate`}function Sb(e){return e.hadTrackEndedWarning?{ok:!1,code:_b}:e.totalChunks===0?{ok:!1,code:hb}:e.nonSilentChunks===0&&(e.durationMs>0?e.mutedDurationMs/e.durationMs:0)<.9?{ok:!1,code:gb}:{ok:!0}}let Cb=`vidtreo-recorder`,wb=`pending-uploads`,Tb=`status`,Eb=`createdAt`,Db=`Failed to prepare upload data for storage. The recorded file could not be read.`,Ob=`__probe__`,kb=new ArrayBuffer(1);var Ab=class{constructor(e){if(this.db=null,e){this.databaseFactory=e;return}this.databaseFactory=indexedDB}init(){return this.db?Promise.resolve():this.openDatabase(3,!0)}openDatabase(e,t){return new Promise((n,r)=>{let i=this.createOpenRequest(e);i.onerror=()=>{let e=i.error;if(t&&e&&e.name===`VersionError`){this.openDatabase(void 0,!1).then(n).catch(r);return}if(e){r(e);return}r(Error(`Failed to open database`))},i.onsuccess=()=>{if(!i.result){r(Error(`Database result is null`));return}let e=i.result,t=this.validateRequiredSchema(e);if(t){e.close(),r(t);return}this.db=e,n()},i.onupgradeneeded=e=>{let t=e.target.result;if(!t){r(Error(`Database upgrade result is null`));return}this.initializeStoreSchema(t)}})}createOpenRequest(e){return e===void 0?this.databaseFactory.open(Cb):this.databaseFactory.open(Cb,e)}initializeStoreSchema(e){if(e.objectStoreNames.contains(wb))return;let t=e.createObjectStore(wb,{keyPath:`id`});t.createIndex(Tb,Tb,{unique:!1}),t.createIndex(Eb,Eb,{unique:!1})}validateRequiredSchema(e){if(!e.objectStoreNames.contains(wb))return Error(`Database schema is missing required object store: pending-uploads`);let t=e.transaction([wb],`readonly`).objectStore(wb);return t.indexNames.contains(Tb)?t.indexNames.contains(Eb)?null:Error(`Database schema is missing required index: createdAt`):Error(`Database schema is missing required index: status`)}isInitialized(){return this.db!==null}async probeWriteCapability(){if(!this.db)return{ok:!1,reason:`Database not initialized`};try{return await this.executeTransaction(`readwrite`,e=>{let t={id:Ob,blobData:kb,blobType:`application/octet-stream`,apiKey:``,backendUrl:``,filename:`probe`,status:`pending`,retryCount:0,createdAt:0,updatedAt:0};return new Promise((n,r)=>{let i=e.put(t);i.onsuccess=()=>{let t=e.delete(Ob);t.onsuccess=()=>n(),t.onerror=()=>{if(t.error){r(t.error);return}r(Error(`Probe delete failed`))}},i.onerror=()=>{if(i.error){r(i.error);return}r(Error(`Probe write failed`))}})}),{ok:!0}}catch(e){return{ok:!1,reason:`Storage write probe failed. Browser may be in private browsing mode or IndexedDB writes are restricted. ${e instanceof Error?e.message:String(e)}`}}}async savePendingUpload(e){let t=this.generateUploadId(),n=Date.now(),r={...e,id:t,status:`pending`,retryCount:0,createdAt:n,updatedAt:n,blobData:await this.readBlobData(e.blob),blobType:e.blob.type};return r.blob=void 0,this.executeTransaction(`readwrite`,e=>{let n=e.add(r);return new Promise((e,r)=>{n.onsuccess=()=>e(t),n.onerror=()=>{n.error?n.error.name===`QuotaExceededError`?r(Error(`Storage quota exceeded. Please free up space or delete old uploads.`)):r(n.error):r(Error(`Failed to save upload`))}})})}getPendingUploads(e){return this.executeTransaction(`readonly`,t=>{let n=e?t.index(Tb).getAll(e):t.getAll();return new Promise((e,t)=>{n.onsuccess=()=>{if(n.result===void 0){t(Error(`Failed to get uploads: result is undefined`));return}e(n.result.map(e=>this.hydrateUpload(e)))},n.onerror=()=>{n.error?t(n.error):t(Error(`Failed to get uploads`))}})})}async updateUploadStatus(e,t){let n=await this.createStoredUpdates(t);return this.executeTransaction(`readwrite`,r=>{let i=r.get(e);return new Promise((e,a)=>{i.onsuccess=()=>{let o=i.result;if(!o){a(Error(`Upload not found`));return}let s=t.updatedAt===void 0?Date.now():t.updatedAt,c={...o,...n,updatedAt:s},l=r.put(c);l.onsuccess=()=>e(),l.onerror=()=>{if(l.error){a(l.error);return}a(Error(`Failed to update upload`))}},i.onerror=()=>{i.error?a(i.error):a(Error(`Failed to get upload`))}})})}deleteUpload(e){return this.executeTransaction(`readwrite`,t=>{let n=t.delete(e);return new Promise((e,t)=>{n.onsuccess=()=>e(),n.onerror=()=>{n.error?t(n.error):t(Error(`Failed to delete upload`))}})})}async cleanupPermanentlyFailedUploads(e){let t=e===void 0?24:e;if(typeof t!=`number`||t<0)throw Error(`retentionHours must be a non-negative number`);let n=Date.now()-t*36e5,r=(await this.getPendingUploads()).filter(e=>e.status===`failed`&&e.retryCount>=10&&e.updatedAt<n);for(let e of r)await this.deleteUpload(e.id);return r.length}async getTotalStorageSize(){return(await this.getPendingUploads()).reduce((e,t)=>e+t.blob.size,0)}hydrateUpload(e){if(`blobData`in e&&e.blobData){let{blobData:t,blobType:n,...r}=e;return{...r,blob:new Blob([t],{type:n})}}return e}async createStoredUpdates(e){let t={...e};return e.blob&&(t.blobData=await this.readBlobData(e.blob),t.blobType=e.blob.type,t.blob=void 0),t}readBlobData(e){return e.arrayBuffer().catch(e=>{throw e instanceof Error?Error(`${Db} ${e.message}`):Error(Db)})}generateUploadId(){return`upload-${Date.now()}-${Math.random().toString(36).substring(2,11)}`}executeTransaction(e,t){if(!this.db)throw Error(`Database not initialized`);let n=this.db.transaction([wb],e),r=n.objectStore(wb);return new Promise((e,i)=>{let a,o=!1,s=!1;n.oncomplete=()=>{!o||s||e(a)},n.onerror=()=>{if(n.error){i(n.error);return}i(Error(`Storage transaction failed`))},n.onabort=()=>{if(n.error){i(n.error);return}i(Error(`Storage transaction aborted`))},t(r).then(e=>{a=e,o=!0},e=>{s=!0,i(e)})})}},jb=class{constructor(){this.storageService=null,this.cleanupIntervalId=null,this.writeProbeResult=null}async initialize(e){this.storageService||=new Ab,this.storageService.isInitialized()||await this.storageService.init(),this.writeProbeResult=await this.storageService.probeWriteCapability(),this.setupCleanupInterval(e)}getWriteProbeResult(){return this.writeProbeResult}setupCleanupInterval(e){this.cleanupIntervalId===null&&(this.cleanupIntervalId=window.setInterval(()=>{this.performCleanup().catch(t=>{e(i(t))})},36e5))}async performCleanup(){if(!this.storageService)throw Error(`StorageService not initialized`);await this.storageService.cleanupPermanentlyFailedUploads(24)}getStorageService(){return this.storageService}isStorageWritable(){return this.writeProbeResult?.ok===!0}destroy(){this.cleanupIntervalId!==null&&(clearInterval(this.cleanupIntervalId),this.cleanupIntervalId=null)}};function Mb(){let e=globalThis;if(e.__VIDTREO_DEBUG__===!0||e.__VIDTREO_DEV__===!0)return!0;let t=typeof process<`u`&&process?.env?`production`:void 0;return t===`development`||t===`test`||typeof localStorage<`u`&&localStorage.getItem(`VIDTREO_DEBUG`)===`true`}let Nb=Mb(),Pb={reset:`\x1B[0m`,bright:`\x1B[1m`,dim:`\x1B[2m`,red:`\x1B[31m`,green:`\x1B[32m`,yellow:`\x1B[33m`,blue:`\x1B[34m`,magenta:`\x1B[35m`,cyan:`\x1B[36m`,white:`\x1B[37m`,gray:`\x1B[90m`};function Fb(e,t,n){if(!Nb)return``;let r=n?.prefix||`[${e.toUpperCase()}]`;return`${Pb[n?.color||Ib(e)]}${r}${Pb.reset} ${t}`}function Ib(e){switch(e){case`error`:return`red`;case`warn`:return`yellow`;case`info`:return`cyan`;case`debug`:return`gray`;default:return`white`}}function Lb(e,t,...n){if(!Nb)return;let r=Fb(e,t);console[e](r,...n)}let $={log:(e,...t)=>{Lb(`log`,e,...t)},info:(e,...t)=>{Lb(`info`,e,...t)},warn:(e,...t)=>{Lb(`warn`,e,...t)},error:(e,...t)=>{Lb(`error`,e,...t)},debug:(e,...t)=>{Lb(`debug`,e,...t)},group:(e,t=`cyan`)=>{if(!Nb)return;let n=Pb[t],r=Pb.reset;console.group(`${n}${e}${r}`)},groupEnd:()=>{Nb&&console.groupEnd()}};function Rb(e,t){if(e==null)throw Error(t);return e}function zb(e,t=`StreamProcessor`){if(!e)throw Error(`${t} is required`);return e}function Bb(){if(typeof navigator>`u`||!navigator.mediaDevices?.getUserMedia){let e=typeof window<`u`&&window.isSecureContext===!0?`Camera access is not supported in this browser`:`Camera access requires HTTPS. Please use a secure connection (https://) or localhost.`;throw Error(e)}return navigator.mediaDevices}function Vb(e,t){let n={};if(t.originalCameraConstraints){let{deviceId:e,...r}=t.originalCameraConstraints;n={...n,...r}}e&&(n={...n,deviceId:{exact:e}});let r=t.getSelectedCameraDeviceId(),i=!1;return e&&(i=!0),n.deviceId&&(i=!0),!i&&r&&(n={...n,deviceId:{exact:r}}),n}function Hb(e){let t={echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0};return e?{...t,deviceId:{exact:e}}:t}let Ub=`live`;function Wb(e){for(let t of e)t.readyState===Ub&&t.stop()}function Gb(e){Wb(e.getTracks())}function Kb(e){Wb(e.getVideoTracks())}function qb(e){return e?e.readyState===Ub:!1}function Jb(e,t){return qb(e)&&qb(t)}function Yb(e,t,n){if(!qb(e)){Gb(n);let r=`undefined`;throw e&&(r=e.readyState),Error(`Failed to get live camera ${t} track. ReadyState: ${r}`)}}let Xb=`[SourceSwitchManager]`;var Zb=class{constructor(e){this.dependencies=e}async createCameraStreamWithOriginalAudio(e){let t=this.dependencies.getOriginalCameraStream(),n;if(t&&(n=t.getAudioTracks()[0]),this.dependencies.logger.debug(`${Xb} createCameraStreamWithOriginalAudio`,{hasOriginalCameraStream:!!t,originalCameraStreamId:t?.id,hasOriginalAudioTrack:!!n,originalAudioTrackId:n?.id,originalAudioTrackReadyState:n?.readyState,originalAudioTrackEnabled:n?.enabled,originalAudioTrackMuted:n?.muted,originalAudioTrackLabel:n?.label,isTrackLive:qb(n),cameraDeviceId:e}),!qb(n))return this.dependencies.logger.warn(`${Xb} Original audio track is not live, cannot reuse`,{originalAudioTrackId:n?.id,originalAudioTrackReadyState:n?.readyState}),null;let r=Vb(e,{originalCameraConstraints:this.dependencies.getOriginalCameraConstraints(),getSelectedCameraDeviceId:this.dependencies.getSelectedCameraDeviceId}),i=Object.keys(r).length>0,a=!0;i&&(a=r);let o={video:a,audio:!1};this.dependencies.logger.debug(`${Xb} Requesting new video stream`,{constraints:o,cameraDeviceId:e});let s=await Bb().getUserMedia(o),c=s.getVideoTracks()[0];Yb(c,`video`,s),this.dependencies.logger.debug(`${Xb} New video stream obtained`,{newStreamId:s.id,videoTrackId:c.id,videoTrackReadyState:c.readyState,newStreamAudioTracksCount:s.getAudioTracks().length});let l=[c];n&&(l=[...l,n]),this.dependencies.logger.debug(`${Xb} Creating combined stream with original audio`,{videoTrackId:c.id,audioTrackId:n?.id,audioTrackReadyState:n?.readyState,audioTrackEnabled:n?.enabled,audioTrackMuted:n?.muted,combinedTracksCount:l.length});let u=new MediaStream(l);Wb(s.getAudioTracks());let d=t?.id;return this.dependencies.setOriginalCameraStream(u),this.dependencies.logger.debug(`${Xb} Combined stream created and assigned`,{combinedStreamId:u.id,previousOriginalCameraStreamId:d,newOriginalCameraStreamId:u.id,combinedStreamVideoTracksCount:u.getVideoTracks().length,combinedStreamAudioTracksCount:u.getAudioTracks().length,combinedStreamAudioTrackId:u.getAudioTracks()[0]?.id,combinedStreamAudioTrackReadyState:u.getAudioTracks()[0]?.readyState,audioTrackStillSame:u.getAudioTracks()[0]===n}),u}async createCameraStreamWithNewAudio(e){let t=this.dependencies.getSelectedMicDeviceId(),n=Vb(e,{originalCameraConstraints:this.dependencies.getOriginalCameraConstraints(),getSelectedCameraDeviceId:this.dependencies.getSelectedCameraDeviceId}),r=Hb(t),i=Object.keys(n).length>0,a=!0;i&&(a=n);let o={video:a,audio:r},s=await Bb().getUserMedia(o),c=s.getVideoTracks()[0],l=s.getAudioTracks()[0];return Yb(c,`video`,s),Yb(l,`audio`,s),this.dependencies.setOriginalCameraStream(s),s}async createNewCameraStreamForRecording(){let e=this.dependencies.getSelectedCameraDeviceId();return await this.createCameraStreamWithOriginalAudio(e)||this.createCameraStreamWithNewAudio(e)}async getCameraStream(e){let t=this.dependencies.streamManager.isRecording(),n=this.dependencies.getSelectedCameraDeviceId(),r=this.dependencies.getSelectedMicDeviceId();if(this.dependencies.streamManager.setVideoDevice(n),this.dependencies.streamManager.setAudioDevice(r),e.canReuseOriginalStream()){let e=this.dependencies.getOriginalCameraStream();if(!e)throw Error(`Original camera stream is null`);return e}if(e.canReuseManagerStream()){let e=this.dependencies.streamManager.getStream();if(!e)throw Error(`Manager stream is null`);return e}t||this.dependencies.getOriginalCameraStream()&&this.dependencies.setOriginalCameraStream(null);let i=this.dependencies.streamManager.getStream();if(!t&&i&&i!==this.dependencies.getOriginalCameraStream()&&(Gb(i),this.dependencies.streamManager.setMediaStream(null)),t)return this.dependencies.streamManager.setVideoDevice(this.dependencies.getSelectedCameraDeviceId()),this.dependencies.streamManager.setAudioDevice(this.dependencies.getSelectedMicDeviceId()),this.createNewCameraStreamForRecording();let a=await this.dependencies.streamManager.startStream();return this.dependencies.setOriginalCameraStream(a),a}};let Qb=`screen`,$b=`No video track found in screen share stream`;async function ex(e,t,n){n.setScreenShareStream(e);let r=e.getVideoTracks()[0];if(!r)throw n.stopStreamTracks(e),Error($b);let i=n.combineScreenShareWithOriginalAudio(r),a=n.getOriginalCameraStream();t&&t!==a&&n.stopStreamVideoTracks(t);let o=e.getAudioTracks();for(let e of o)e.stop();return n.setCurrentSourceType(Qb),n.callbacks.onSourceChange&&await n.callbacks.onSourceChange(n.getCurrentSourceType()),tx(i,n),i}function tx(e,t){let n=e.getVideoTracks()[0];if(!n)throw Error($b);let r=t.getScreenShareTrackEndHandler();if(r){let e=t.streamManager.getStream();if(e){let t=e.getVideoTracks()[0];t&&t.removeEventListener(`ended`,r)}}let i=()=>{t.getCurrentSourceType()===Qb&&t.switchToCamera().catch(e=>{t.handleSwitchError(e)})};t.setScreenShareTrackEndHandler(i),n.addEventListener(`ended`,i)}function nx(e,t){let n=t.getScreenShareTrackEndHandler();if(!(n&&e))return;let r=e.getVideoTracks()[0];r&&r.removeEventListener(`ended`,n),t.setScreenShareTrackEndHandler(null)}function rx(e,t){e.onTransitionStart&&e.onTransitionStart(t)}function ix(e){e.onTransitionEnd&&e.onTransitionEnd()}function ax(e){e.onScreenSelectionStart&&e.onScreenSelectionStart()}function ox(e){e.onScreenSelectionEnd&&e.onScreenSelectionEnd()}function sx(e){ox(e),ix(e)}let cx=`Failed to get camera stream`;var lx=class{constructor(e,t={}){this.currentSourceType=`camera`,this.originalCameraStream=null,this.screenShareStream=null,this.screenShareTrackEndHandler=null,this.streamManager=e,this.callbacks=t;let n=null,r=()=>n;this.getOriginalCameraConstraints=r,this.setOriginalCameraConstraints=e=>{n=e},this.cameraStreamBuilder=new Zb({streamManager:this.streamManager,logger:{debug:(e,t)=>$.debug(e,t),warn:(e,t)=>$.warn(e,t)},getSelectedCameraDeviceId:()=>this.callbacks.getSelectedCameraDeviceId?this.callbacks.getSelectedCameraDeviceId():this.streamManager.getVideoDevice(),getSelectedMicDeviceId:()=>this.callbacks.getSelectedMicDeviceId?this.callbacks.getSelectedMicDeviceId():this.streamManager.getAudioDevice(),getOriginalCameraStream:()=>this.originalCameraStream,setOriginalCameraStream:e=>{this.originalCameraStream=e},getOriginalCameraConstraints:r})}getCurrentSourceType(){return this.currentSourceType}getOriginalCameraStream(){return this.originalCameraStream}storeOriginalCameraConstraints(e){let t=e.getVideoTracks()[0];if(!t)return;let n=t.getSettings(),r={width:n.width,height:n.height,aspectRatio:n.aspectRatio,frameRate:n.frameRate,deviceId:n.deviceId,facingMode:n.facingMode},i=this.getOriginalCameraConstraints();i&&i.width===r.width&&i.height===r.height&&i.aspectRatio===r.aspectRatio&&i.frameRate===r.frameRate&&i.deviceId===r.deviceId&&i.facingMode===r.facingMode||this.setOriginalCameraConstraints(r)}storeOriginalCameraStream(e){let t=e.getVideoTracks()[0],n=e.getAudioTracks()[0];Jb(t,n)?this.originalCameraStream=new MediaStream([t,n]):this.originalCameraStream=e}createError(e){return e instanceof Error?e:Error(i(e))}waitForTracksToEnd(e){return new Promise(t=>{setTimeout(()=>{this.screenShareStream=null,t()},e)})}combineScreenShareWithOriginalAudio(e){let t;this.originalCameraStream&&(t=this.originalCameraStream.getAudioTracks()[0]),$.debug(`[SourceSwitchManager] combineScreenShareWithOriginalAudio`,{hasOriginalCameraStream:!!this.originalCameraStream,originalCameraStreamId:this.originalCameraStream?.id,hasOriginalAudioTrack:!!t,originalAudioTrackId:t?.id,originalAudioTrackReadyState:t?.readyState,originalAudioTrackEnabled:t?.enabled,originalAudioTrackMuted:t?.muted,originalAudioTrackLabel:t?.label,isTrackLive:qb(t),screenVideoTrackId:e.id,screenVideoTrackReadyState:e.readyState});let n=[e];qb(t)&&t?(n=[...n,t],$.debug(`[SourceSwitchManager] Added original audio track to combined stream`,{audioTrackId:t.id,combinedTracksCount:n.length})):$.warn(`[SourceSwitchManager] Original audio track is not live, not adding to combined stream`,{audioTrackId:t?.id,audioTrackReadyState:t?.readyState,combinedTracksCount:n.length});let r=new MediaStream(n);return $.debug(`[SourceSwitchManager] Combined stream created`,{combinedStreamId:r.id,combinedStreamVideoTracksCount:r.getVideoTracks().length,combinedStreamAudioTracksCount:r.getAudioTracks().length,combinedStreamAudioTrackId:r.getAudioTracks()[0]?.id,combinedStreamAudioTrackReadyState:r.getAudioTracks()[0]?.readyState}),r}isPermissionDeniedError(e){let t=i(e),n=!1;t.includes(`NotAllowedError`)&&(n=!0),t.includes(`AbortError`)&&(n=!0);let r=t.toLowerCase();return r.includes(`permission denied`)&&(n=!0),r.includes(`user denied`)&&(n=!0),n}switchToScreenCapture(){let e=this.streamManager.getStream();return e&&(this.storeOriginalCameraConstraints(e),this.storeOriginalCameraStream(e)),rx(this.callbacks,`Select screen to share...`),ax(this.callbacks),Promise.resolve().then(async()=>{let t=Bb();if(typeof t.getDisplayMedia!=`function`)throw Error(`Screen sharing is not supported on this device`);return ex(await t.getDisplayMedia({video:!0,audio:!0}),e,this.getScreenShareDependencies())}).catch(e=>{if(sx(this.callbacks),this.isPermissionDeniedError(e))return null;throw e})}canReuseStream(e,t){if(!e||t&&e!==this.originalCameraStream)return!1;let n=e.getVideoTracks()[0],r=e.getAudioTracks()[0];return!(!Jb(n,r)||this.callbacks.getSelectedCameraDeviceId&&this.callbacks.getSelectedCameraDeviceId()!==n.getSettings().deviceId)}canReuseOriginalStream(){return this.canReuseStream(this.originalCameraStream,!1)}canReuseManagerStream(){let e=this.streamManager.getStream();return e&&this.originalCameraStream?this.canReuseStream(e,!0):!1}getScreenShareDependencies(){return{callbacks:this.callbacks,streamManager:this.streamManager,combineScreenShareWithOriginalAudio:e=>this.combineScreenShareWithOriginalAudio(e),stopStreamTracks:e=>Gb(e),stopStreamVideoTracks:e=>Kb(e),getCurrentSourceType:()=>this.currentSourceType,setCurrentSourceType:e=>{this.currentSourceType=e},getOriginalCameraStream:()=>this.originalCameraStream,getScreenShareStream:()=>this.screenShareStream,setScreenShareStream:e=>{this.screenShareStream=e},getScreenShareTrackEndHandler:()=>this.screenShareTrackEndHandler,setScreenShareTrackEndHandler:e=>{this.screenShareTrackEndHandler=e},switchToCamera:()=>this.switchToCamera(),handleSwitchError:e=>{this.callbacks.onError&&this.callbacks.onError(this.createError(e))}}}getCameraStream(){return this.cameraStreamBuilder.getCameraStream({canReuseOriginalStream:()=>this.canReuseOriginalStream(),canReuseManagerStream:()=>this.canReuseManagerStream()})}switchToCamera(){let e=this.streamManager.isRecording();return!e&&this.currentSourceType===`camera`?Promise.resolve():Promise.resolve().then(async()=>{rx(this.callbacks,`Switching to camera...`),await this.handleScreenShareStop();let t=await this.getCameraStream();if(!t)throw Error(cx);await this.applyCameraStream(t,e),ix(this.callbacks)}).catch(e=>{throw ix(this.callbacks),e})}stopScreenShareStreamTracks(e){let t=e.getVideoTracks(),n=e.getAudioTracks();$.debug(`[SourceSwitchManager] stopping screen share tracks`,{videoTracks:t.map(e=>({id:e.id,readyState:e.readyState,displaySurface:e.getSettings().displaySurface,constraints:e.getConstraints()})),audioTracks:n.map(e=>({id:e.id,readyState:e.readyState,constraints:e.getConstraints()}))});for(let e of t)e.stop();for(let e of n)e.stop()}stopDisplayTracks(e){if(e)for(let t of e.getVideoTracks())typeof t.getSettings().displaySurface==`string`&&qb(t)&&($.debug(`[SourceSwitchManager] stopping display track`,{id:t.id,readyState:t.readyState,constraints:t.getConstraints(),settings:t.getSettings()}),t.stop())}async handleScreenShareStop(){if(this.currentSourceType!==`screen`)return;$.debug(`[SourceSwitchManager] handleScreenShareStop invoked`,{currentSourceType:this.currentSourceType,hasScreenShareStream:!!this.screenShareStream,screenShareStreamId:this.screenShareStream?.id,hasOriginalCameraStream:!!this.originalCameraStream,originalCameraStreamId:this.originalCameraStream?.id});let e=this.screenShareStream,t=this.streamManager.getStream();if($.debug(`[SourceSwitchManager] Current stream state before stop`,{currentStreamId:t?.id,currentStreamVideoTracksCount:t?.getVideoTracks().length,currentStreamAudioTracksCount:t?.getAudioTracks().length,currentStreamAudioTrackId:t?.getAudioTracks()[0]?.id,currentStreamAudioTrackReadyState:t?.getAudioTracks()[0]?.readyState,originalCameraStreamAudioTrackId:this.originalCameraStream?.getAudioTracks()[0]?.id,originalCameraStreamAudioTrackReadyState:this.originalCameraStream?.getAudioTracks()[0]?.readyState}),e){let t=e.getAudioTracks();$.debug(`[SourceSwitchManager] Screen share stream audio tracks before stop`,{screenShareStreamId:e.id,screenShareAudioTracksCount:t.length,screenShareAudioTrackIds:t.map(e=>({id:e.id,readyState:e.readyState,enabled:e.enabled}))}),nx(e,this.getScreenShareDependencies()),this.stopScreenShareStreamTracks(e),this.stopDisplayTracks(e),this.screenShareStream=null,await this.waitForTracksToEnd(0),$.debug(`[SourceSwitchManager] Screen share stream stopped`,{screenShareAudioTracksAfterStop:t.map(e=>({id:e.id,readyState:e.readyState}))})}if(t){let e=t.getAudioTracks();$.debug(`[SourceSwitchManager] Current stream audio tracks before video stop`,{currentStreamId:t.id,currentStreamAudioTracksCount:e.length,currentStreamAudioTrackIds:e.map(e=>({id:e.id,readyState:e.readyState,enabled:e.enabled}))}),Kb(t),this.stopDisplayTracks(t),$.debug(`[SourceSwitchManager] Current stream audio tracks after video stop`,{currentStreamId:t.id,currentStreamAudioTracksCount:t.getAudioTracks().length,currentStreamAudioTrackIds:t.getAudioTracks().map(e=>({id:e.id,readyState:e.readyState,enabled:e.enabled}))})}$.debug(`[SourceSwitchManager] Original camera stream state before source change`,{hasOriginalCameraStream:!!this.originalCameraStream,originalCameraStreamId:this.originalCameraStream?.id,originalCameraStreamAudioTracksCount:this.originalCameraStream?.getAudioTracks().length,originalCameraStreamAudioTrackId:this.originalCameraStream?.getAudioTracks()[0]?.id,originalCameraStreamAudioTrackReadyState:this.originalCameraStream?.getAudioTracks()[0]?.readyState,originalCameraStreamAudioTrackEnabled:this.originalCameraStream?.getAudioTracks()[0]?.enabled}),this.currentSourceType=`camera`,this.callbacks.onSourceChange&&await this.callbacks.onSourceChange(this.currentSourceType),$.debug(`[SourceSwitchManager] handleScreenShareStop completed`,{hasScreenShareStream:!!this.screenShareStream,currentSourceType:this.currentSourceType,hasOriginalCameraStream:!!this.originalCameraStream,originalCameraStreamId:this.originalCameraStream?.id,originalCameraStreamAudioTracksCount:this.originalCameraStream?.getAudioTracks().length,originalCameraStreamAudioTrackId:this.originalCameraStream?.getAudioTracks()[0]?.id,originalCameraStreamAudioTrackReadyState:this.originalCameraStream?.getAudioTracks()[0]?.readyState})}async applyCameraStream(e,t){this.streamManager.setMediaStream(e);let n=this.currentSourceType!==`camera`;this.currentSourceType=`camera`,n&&this.callbacks.onSourceChange&&await this.callbacks.onSourceChange(this.currentSourceType),t&&await this.streamManager.switchVideoSource(e),this.callbacks.onPreviewUpdate&&await this.callbacks.onPreviewUpdate(e)}async toggleSource(){if(!this.streamManager.isRecording())return;let e;e=this.currentSourceType===`camera`?this.switchToScreen():this.switchToCamera(),await e.catch(e=>{this.handleToggleError(e)})}async switchToScreen(){let e=await this.switchToScreenCapture();if(!e){ix(this.callbacks);return}rx(this.callbacks,`Switching to screen...`),await this.streamManager.switchVideoSource(e),this.callbacks.onPreviewUpdate&&await this.callbacks.onPreviewUpdate(e),ix(this.callbacks)}handleToggleError(e){ix(this.callbacks);let t=i(e),n=!1;t.includes(`NotAllowedError`)&&(n=!0),t.includes(`AbortError`)&&(n=!0),n&&this.currentSourceType===`screen`&&this.switchToCamera().catch(e=>{this.callbacks.onError&&this.callbacks.onError(this.createError(e))}),!n&&this.callbacks.onError&&this.callbacks.onError(this.createError(e))}async handleRecordingStop(){if(this.currentSourceType!==`screen`){this.cleanup();return}await Promise.resolve().then(async()=>{let e=this.streamManager.getStream();e&&(nx(e,this.getScreenShareDependencies()),Kb(e));let t=await this.getCameraStream();if(!t)throw Error(cx);this.streamManager.setMediaStream(t),this.currentSourceType=`camera`,this.callbacks.onSourceChange&&await this.callbacks.onSourceChange(this.currentSourceType),this.callbacks.onPreviewUpdate&&await this.callbacks.onPreviewUpdate(t)}).catch(e=>{throw this.callbacks.onError&&this.callbacks.onError(this.createError(e)),e}),this.cleanup()}cleanup(){this.screenShareStream&&=(nx(this.screenShareStream,this.getScreenShareDependencies()),this.stopScreenShareStreamTracks(this.screenShareStream),null);let e=this.streamManager.getStream();e&&nx(e,this.getScreenShareDependencies()),this.screenShareTrackEndHandler=null,this.originalCameraStream=null,this.setOriginalCameraConstraints(null)}setCallbacks(e){this.callbacks={...this.callbacks,...e}}};let ux=Object.freeze({width:{ideal:Xt.width||1920},height:{ideal:Xt.height||1080},frameRate:{ideal:Xt.fps||30}}),dx=Object.freeze({video:ux,audio:!0});Object.freeze({mimeType:`video/webm;codecs=vp9,opus`});let fx={NotReadableError:`camera.in-use`,NotFoundError:`camera.not-found`,NotAllowedError:`camera.permission-denied`,OverconstrainedError:`camera.overconstrained`,TimeoutError:`camera.timeout`},px={NotReadableError:`audio.in-use`,NotFoundError:`audio.not-found`,NotAllowedError:`audio.permission-denied`,OverconstrainedError:`audio.overconstrained`,TimeoutError:`audio.timeout`};function mx(e){return e instanceof DOMException||typeof e==`object`&&e&&`name`in e&&typeof e.name==`string`?e.name:null}function hx(e){return i(e).toLowerCase()}function gx(e,t){let n=hx(e),r=t===`camera`?`camera`:`audio`;return n.includes(`permission denied`)||n.includes(`permission dismissed`)||n.includes(`not allowed`)?`${r}.permission-denied`:n.includes(`requested device not found`)||n.includes(`device not found`)||n.includes(`no camera`)||n.includes(`no microphone`)?`${r}.not-found`:n.includes(`timeout starting`)||n.includes(`timed out`)||n.includes(`timeout`)?`${r}.timeout`:n.includes(`could not start video source`)||n.includes(`could not start audio source`)||n.includes(`device in use`)?`${r}.in-use`:null}function _x(e){let t=gx(e,`camera`);if(t!==null)return t;let n=mx(e);if(n!==null){let e=fx[n];if(e!==void 0)return e}return`camera.unknown`}function vx(e){let t=gx(e,`audio`);if(t!==null)return t;let n=mx(e);if(n!==null){let e=px[n];if(e!==void 0)return e}return`audio.unknown`}function yx(e){let t=i(e),n=Error(t);return n.name=`CameraError`,n.code=_x(e),n}function bx(e){let t=i(e),n=Error(t);return n.name=`AudioError`,n.code=vx(e),n}function xx(e){return mx(e)===`NotReadableError`}function Sx(e){return new Promise(t=>setTimeout(t,e))}var Cx=class{constructor(e={},t={}){this.mediaStream=null,this.state=`idle`,this.eventListeners=new Map,this.selectedAudioDeviceId=null,this.selectedVideoDeviceId=null,this.audioStatus=`pending`,this.audioAcquisitionPromise=null,this.pendingAudioError=null,this.acquisitionGeneration=0,this.streamConfig={...dx,...e},this.waitMilliseconds=t.waitMilliseconds??Sx,this.audioRetryDelayMilliseconds=t.audioRetryDelayMilliseconds??300}getAudioStatus(){return this.audioStatus}isAudioReady(){return this.audioStatus===`acquired`}async waitForAudio(){if(this.audioStatus!==`acquired`&&(this.audioStatus===`failed`||(this.audioAcquisitionPromise&&await this.audioAcquisitionPromise,this.getAudioStatus()===`failed`)))throw this.pendingAudioError??bx(null)}setAudioStatus(e){this.audioStatus!==e&&(this.audioStatus=e,this.emit(`audiostatuschange`,{status:e}))}emitAudioTelemetry(e){this.emit(`audiotelemetry`,{event:e})}getState(){return this.state}getStream(){return this.mediaStream}getAudioStreamForAnalysis(){return this.mediaStream&&this.mediaStream.getAudioTracks().length>0?this.mediaStream:null}isActive(){return this.state===`active`||this.state===`recording`}on(e,t){this.eventListeners.has(e)||this.eventListeners.set(e,new Set);let n=this.eventListeners.get(e);return n&&n.add(t),()=>{this.off(e,t)}}off(e,t){let n=this.eventListeners.get(e);n&&n.delete(t)}once(e,t){let n=(r=>{t(r),this.off(e,n)});return this.on(e,n)}emit(e,t){let n=this.eventListeners.get(e);if(n)for(let e of n)try{e(t)}catch{}}setState(e){if(this.state===e)return;let t=this.state;this.state=e,this.emit(`statechange`,{state:e,previousState:t})}setAudioDevice(e){this.selectedAudioDeviceId=e}setVideoDevice(e){this.selectedVideoDeviceId=e}getAudioDevice(){return this.selectedAudioDeviceId}getVideoDevice(){return this.selectedVideoDeviceId}async getAvailableDevices(){try{let e=await navigator.mediaDevices.enumerateDevices();return{audioinput:e.filter(e=>e.kind===`audioinput`),videoinput:e.filter(e=>e.kind===`videoinput`)}}catch(e){throw Error(`Failed to enumerate devices: ${i(e)}`)}}buildDeviceConstraints(e,t){return e?typeof t==`object`?{...t,deviceId:{exact:e}}:{deviceId:{exact:e}}:t}buildVideoConstraints(e){return this.buildDeviceConstraints(e,this.streamConfig.video)}buildAudioConstraints(e){return this.buildDeviceConstraints(e,this.streamConfig.audio)}async startStream(){if($.debug(`[StreamManager] startStream called`,{hasExistingStream:!!this.mediaStream,selectedVideoDeviceId:this.selectedVideoDeviceId,selectedAudioDeviceId:this.selectedAudioDeviceId}),this.mediaStream){let e=this.mediaStream.getVideoTracks()[0];if(this.selectedVideoDeviceId===null)if(e?.getSettings?.()?.deviceId)$.debug(`[StreamManager] Stopping existing stream to recreate`),this.stopStream();else return $.debug(`[StreamManager] Reusing existing stream`),this.mediaStream;if(e?.getSettings&&e.getSettings().deviceId===this.selectedVideoDeviceId)return $.debug(`[StreamManager] Existing stream matches device, reusing`),this.mediaStream;$.debug(`[StreamManager] Device changed, stopping existing stream`),this.stopStream()}this.setState(`starting`),$.debug(`[StreamManager] State set to 'starting'`);try{return this.mediaStream=await this.acquireVideoAndAudioStream(),$.info(`[StreamManager] Media stream obtained`,{streamId:this.mediaStream.id,videoTracks:this.mediaStream.getVideoTracks().length,audioTracks:this.mediaStream.getAudioTracks().length}),this.setState(`active`),$.debug(`[StreamManager] State set to 'active'`),$.debug(`[StreamManager] Emitting streamstart event`),this.emit(`streamstart`,{stream:this.mediaStream}),this.mediaStream}catch(e){if(e instanceof Error&&`code`in e&&(e.name===`CameraError`||e.name===`AudioError`))throw $.error(`[StreamManager] Failed to start stream`,e),this.setState(`error`),this.emit(`error`,{error:e}),e;let t=yx(e);throw $.error(`[StreamManager] Failed to start stream`,t),this.setState(`error`),this.emit(`error`,{error:t}),t}}async acquireVideoAndAudioStream(){let e=Bb(),t=this.buildVideoConstraints(this.selectedVideoDeviceId),n=this.buildAudioConstraints(this.selectedAudioDeviceId);this.setAudioStatus(`pending`),this.pendingAudioError=null,$.debug(`[StreamManager] Attempting combined getUserMedia`,{selectedVideoDeviceId:this.selectedVideoDeviceId,selectedAudioDeviceId:this.selectedAudioDeviceId});try{let r=await e.getUserMedia({video:t,audio:n}),i=r.getVideoTracks().length>0,a=r.getAudioTracks().length>0;if(i&&a)return $.debug(`[StreamManager] Combined getUserMedia succeeded with video + audio`),this.setAudioStatus(`acquired`),r;$.warn(`[StreamManager] Combined getUserMedia returned incomplete stream`,{videoTracks:r.getVideoTracks().length,audioTracks:r.getAudioTracks().length}),this.stopStreamTracks(r)}catch(e){let t=mx(e),n=i(e);$.warn(`[StreamManager] Combined getUserMedia failed, falling back to separate acquisition`,{error:n,errorName:t}),this.emitAudioTelemetry({name:`audio.acquisition.fallback`,properties:{reason:`combined_getUserMedia_failed`,originalError:n,originalErrorName:t,selectedAudioDeviceId:this.selectedAudioDeviceId,selectedVideoDeviceId:this.selectedVideoDeviceId}})}let r;try{r=await e.getUserMedia({video:t,audio:!1}),$.debug(`[StreamManager] Video-only stream acquired for preview`)}catch(e){throw this.setAudioStatus(`failed`),yx(e)}this.mediaStream=r,this.acquisitionGeneration++;let a=this.acquisitionGeneration;return this.audioAcquisitionPromise=this.acquireAudioInBackground(e,n,a),r}async acquireAudioInBackground(e,t,n){try{let r=await this.acquireAudioTrackWithRetry(e,t);if(!this.mediaStream||this.acquisitionGeneration!==n){$.debug(`[StreamManager] Audio acquired but stream was replaced/stopped, discarding track`,{generation:n,currentGeneration:this.acquisitionGeneration}),r.stop();return}this.mediaStream.addTrack(r),$.info(`[StreamManager] Audio track added to stream`,{audioTrackId:r.id,audioTrackLabel:r.label,totalAudioTracks:this.mediaStream.getAudioTracks().length}),this.setAudioStatus(`acquired`)}catch(e){if(this.acquisitionGeneration!==n)return;let t=e instanceof Error&&`code`in e?e:bx(e);this.pendingAudioError=t,this.setAudioStatus(`failed`),$.error(`[StreamManager] Background audio acquisition failed`,t),this.emitAudioTelemetry({name:`audio.acquisition.failed`,properties:{errorCode:t.code,errorName:t.name,maxRetries:2,retryDelayMs:this.audioRetryDelayMilliseconds,selectedAudioDeviceId:this.selectedAudioDeviceId},error:t}),this.emit(`error`,{error:t})}finally{this.audioAcquisitionPromise=null}}resolveAudioConstraintsForAttempt(e,t){if(t!==2||typeof e!=`object`)return e;let{deviceId:n,...r}=e,i=Object.keys(r).length>0?r:!0;return $.debug(`[StreamManager] Audio retry with relaxed constraints (no deviceId)`,{attempt:t}),i}async acquireAudioTrackWithRetry(e,t){let n=null;for(let r=0;r<=2;r++)try{let n=this.resolveAudioConstraintsForAttempt(t,r),i=await e.getUserMedia({video:!1,audio:n}),a=i.getAudioTracks()[0];if(!a)throw this.stopStreamTracks(i),Error(`getUserMedia returned no audio tracks`);for(let e of i.getVideoTracks())e.stop();return $.debug(`[StreamManager] Audio track acquired`,{attempt:r,trackId:a.id,trackLabel:a.label}),r>0&&this.emitAudioTelemetry({name:`audio.acquisition.recovered`,properties:{successAttempt:r,totalAttempts:r+1,audioTrackLabel:a.label,usedRelaxedConstraints:r===2}}),a}catch(e){n=e;let t=i(e),a=mx(e),o=xx(e);if($.warn(`[StreamManager] Audio acquisition failed`,{attempt:r,maxRetries:2,error:t,errorName:a,isRetriable:o}),this.emitAudioTelemetry({name:`audio.acquisition.retry`,properties:{attempt:r,maxRetries:2,errorMessage:t,errorName:a??`unknown`,isRetriable:o,usedRelaxedConstraints:r===2,willRetry:r<2&&o}}),!(r<2&&o))break;await this.waitMilliseconds(this.audioRetryDelayMilliseconds)}throw bx(n)}stopStream(){if(this.mediaStream){for(let e of this.mediaStream.getTracks())e.stop();this.mediaStream=null}this.audioStatus=`pending`,this.pendingAudioError=null,this.audioAcquisitionPromise=null,this.acquisitionGeneration++,this.state!==`idle`&&(this.setState(`idle`),this.emit(`streamstop`,void 0))}stopStreamTracks(e){for(let t of e.getTracks())t.stop()}isTrackLive(e){return e!==void 0&&e.readyState===`live`}async tryReplaceTrack(e,t,n){let r=e.replaceTrack;if(typeof r!=`function`)return!1;try{await r.call(e,t),e.stop();for(let e of n.getTracks())e!==t&&e.stop();return t.stop(),!0}catch{return!1}}recreateStreamWithNewTrack(e,t,n){for(let t of n.getTracks())t!==e&&t.stop();let r=[e];this.isTrackLive(t)&&t&&r.push(t);let i=new MediaStream(r);if(this.mediaStream)for(let e of this.mediaStream.getTracks())e!==t&&e.stop();return i}async switchDeviceTrack(e,t,n){if(!this.mediaStream)throw Error(`No active stream to switch device`);let r=t===`video`?this.mediaStream.getVideoTracks()[0]:this.mediaStream.getAudioTracks()[0],i=t===`video`?this.mediaStream.getAudioTracks()[0]:this.mediaStream.getVideoTracks()[0];if(!r){let e=t===`video`?`video`:`audio`;throw Error(`No ${e} track in current stream`)}let a={[t]:this.buildDeviceConstraints(e,n)},o=await Bb().getUserMedia(a),s=t===`video`?o.getVideoTracks()[0]:o.getAudioTracks()[0];if(!s){this.stopStreamTracks(o);let e=t===`video`?`video`:`audio`;throw Error(`Failed to get new ${e} track`)}return await this.tryReplaceTrack(r,s,o)||(r.stop(),this.mediaStream=this.recreateStreamWithNewTrack(s,i,o)),t===`video`?(this.selectedVideoDeviceId=e,this.emit(`videosourcechange`,{stream:this.mediaStream})):this.selectedAudioDeviceId=e,this.mediaStream}switchVideoDevice(e){return this.switchDeviceTrack(e,`video`,this.streamConfig.video)}switchAudioDevice(e){return this.switchDeviceTrack(e,`audio`,this.streamConfig.audio)}setMediaStream(e){this.mediaStream=e}setAudioTracksEnabled(e){if(!this.mediaStream)return;let t=this.mediaStream.getAudioTracks();for(let n of t)n.enabled=e}destroy(){this.stopStream(),this.eventListeners.clear(),this.setState(`idle`)}};let wx=`recording.stop-not-ready`,Tx=`recording.finalize-not-ready`,Ex=`recording.finalize-timeout`;function Dx(e,t,n){let r=Error(`${t} [${e}]`);return r.code=e,r.isRecoverable=!0,n!==void 0&&(r.details=n),r}function Ox(e){return!(e instanceof Error)||kx(e)?e:e.message===`Not currently recording`?Dx(wx,`Recording is not ready to stop`):e.message===`Processing not active`?Dx(Tx,`Recording is not ready to finalize`):e}function kx(e){let t=e;return t.code===wx||t.code===Tx||t.code===Ex}let Ax=[`Bytes`,`KB`,`MB`,`GB`],jx=1024;function Mx(e){if(e===0)return`0 Bytes`;let t=Math.floor(Math.log(e)/Math.log(jx));return`${Math.round(e/jx**t*100)/100} ${Ax[t]}`}function Nx(e){let t=Math.floor(e/3600),n=Math.floor(e%3600/60),r=e%60;return t>0?`${t.toString().padStart(2,`0`)}:${n.toString().padStart(2,`0`)}:${r.toString().padStart(2,`0`)}`:`${n.toString().padStart(2,`0`)}:${r.toString().padStart(2,`0`)}`}let Px={getCurrentTimestamp:()=>performance.now()};var Fx=class{constructor(e){this.recordingStartTime=0,this.totalPausedTime=0,this.pauseStartTime=null,this.intervals=[],this.currentIntervalStart=null,this.isTracking=!1,this.visibilityChangeHandler=this.handleVisibilityChange.bind(this),this.blurHandler=this.handleBlur.bind(this),this.focusHandler=this.handleFocus.bind(this);let t=e?.getCurrentTimestamp;t===void 0?this.getCurrentTimestamp=Px.getCurrentTimestamp:this.getCurrentTimestamp=t}start(e){this.isTracking||(this.recordingStartTime=e,this.totalPausedTime=0,this.pauseStartTime=null,this.intervals=[],this.currentIntervalStart=null,this.isTracking=!0,typeof document<`u`&&document.addEventListener(`visibilitychange`,this.visibilityChangeHandler),typeof window<`u`&&(window.addEventListener(`blur`,this.blurHandler),window.addEventListener(`focus`,this.focusHandler)),this.checkInitialState())}pause(){!this.isTracking||this.pauseStartTime!==null||(this.pauseStartTime=this.getCurrentTimestamp(),this.endCurrentIntervalIfActive())}resume(){if(!this.isTracking||this.pauseStartTime===null)return;let e=this.getCurrentTimestamp()-this.pauseStartTime;this.totalPausedTime+=e,this.pauseStartTime=null}getIntervals(){return this.endCurrentIntervalIfActive(),this.intervals.map(e=>({start:this.normalizeTimestamp(e.start),end:this.normalizeTimestamp(e.end)}))}reset(){this.intervals=[],this.currentIntervalStart=null,this.totalPausedTime=0,this.pauseStartTime=null}cleanup(){this.isTracking=!1,this.endCurrentIntervalIfActive(),typeof document<`u`&&document.removeEventListener(`visibilitychange`,this.visibilityChangeHandler),typeof window<`u`&&(window.removeEventListener(`blur`,this.blurHandler),window.removeEventListener(`focus`,this.focusHandler)),this.reset()}checkInitialState(){typeof document>`u`||document.visibilityState===`hidden`&&this.startInterval()}handleVisibilityChange(){typeof document>`u`||(document.visibilityState===`hidden`?this.startInterval():this.endCurrentIntervalIfActive())}handleBlur(){this.startInterval()}handleFocus(){this.endCurrentIntervalIfActive()}startInterval(){this.currentIntervalStart!==null||!this.isTracking||this.pauseStartTime===null&&(this.currentIntervalStart=this.getCurrentTimestamp())}endCurrentIntervalIfActive(){if(this.currentIntervalStart===null)return;let e=this.getCurrentTimestamp(),t=this.currentIntervalStart;e>t&&this.intervals.push({start:t,end:e}),this.currentIntervalStart=null}normalizeTimestamp(e){let t=(e-this.recordingStartTime-this.totalPausedTime)/1e3;return Math.max(0,t)}};let Ix=1e3,Lx=1e3,Rx={route:`local-webcodecs`,reasonCodes:[`webcodecs-supported`,`target-codec-supported`]},zx={width:{ideal:854,max:854},height:{ideal:480,max:480},frameRate:{ideal:20,max:20}},Bx={width:{ideal:1280,max:1280},height:{ideal:720,max:720},frameRate:{ideal:24,max:24}};function Vx(e){let t=e.guidance?.message??`This browser or device cannot safely record video. Try a supported browser or upload an existing video file.`,n=Error(t);return n.name=`RecordingUnsupportedError`,n.code=`recording.unsupported-with-guidance`,n.isRecoverable=!0,n}let Hx={checkRecorderSupport:ub,getCurrentTimestamp:()=>performance.now()};var Ux=class{constructor(e,t){this.recordingStartTime=0,this.recordingTimer=null,this.pauseStartTime=null,this.totalPausedTime=0,this.streamProcessor=null,this.bufferSizeUpdateInterval=null,this.tabVisibilityTracker=null,this.visibilityChangeHandler=null,this.blurHandler=null,this.focusHandler=null,this.preResolvedSupportReport=null,this.activeRouteDecision=Rx,this.mediaRecorder=null,this.mediaRecorderChunks=[],this.mediaRecorderStopPromise=null,this.mediaRecorderStopResolve=null,this.mediaRecorderStopReject=null,this.streamManager=e;let n=t?.checkRecorderSupport,r;r=n===void 0?Hx.checkRecorderSupport:n;let i=t?.getCurrentTimestamp,a;a=i===void 0?Hx.getCurrentTimestamp:i,this.dependencies={checkRecorderSupport:r,getCurrentTimestamp:a}}setPreResolvedSupportReport(e){this.preResolvedSupportReport=e}isRecording(){return this.streamManager.getState()===`recording`}getStreamProcessor(){return this.streamProcessor}getAudioStreamForAnalysis(){if(this.streamProcessor){let e=this.streamProcessor.getAudioStreamForAnalysis();if(e)return e}return this.streamManager.getAudioStreamForAnalysis()}async startRecording(e,t,n,r,i){this.activeRouteDecision=i??Rx;let a=this.streamManager.getStream(),o=0;if(a!==null&&(o=a.getAudioTracks().length),$.debug(`[StreamRecordingState] startRecording called`,{hasMediaStream:!!a,isRecording:this.isRecording(),hasProcessor:!!e,audioTracks:o}),!a)throw Error(`Stream must be started before recording`);if(this.isRecording())return $.debug(`[StreamRecordingState] Already recording, returning`),Promise.resolve();if(!(a.getAudioTracks().length>0))throw $.error(`[StreamRecordingState] Cannot start recording without audio tracks`),bb();if(this.activeRouteDecision.route===`unsupported-with-guidance`)throw Vx(this.activeRouteDecision);if(this.activeRouteDecision.route===`local-webcodecs`){let e=t.watermark!==void 0,n;if(n=this.preResolvedSupportReport?.isSupported?this.preResolvedSupportReport:await this.dependencies.checkRecorderSupport({requiresAudio:!0,requiresWatermark:e}),!n.isSupported)throw Nt({missingCapabilities:n.missing,resolutionStage:`feature-preflight`})}this.streamProcessor=e,$.debug(`[StreamRecordingState] StreamProcessor assigned, setting callbacks`),e.setOnMuteStateChange(e=>{this.streamManager.emit(`audiomutetoggle`,{muted:e})}),e.setOnSourceChange(e=>{this.streamManager.emit(`videosourcechange`,{stream:e})}),this.bufferSizeUpdateInterval=window.setInterval(()=>{if(!this.streamProcessor)return;let e=this.streamProcessor.getBufferSize(),t=Mx(e);this.streamManager.emit(`recordingbufferupdate`,{size:e,formatted:t})},Ix),this.resetRecordingState();let s;n===!0&&(s={enabled:!0,text:this.resolveTabVisibilityOverlayText(r),recordingStartTime:this.recordingStartTime}),$.debug(`[StreamRecordingState] Overlay config`,{enableTabVisibilityOverlay:n,hasOverlayText:!!r,overlayText:r,overlayConfig:s}),this.activeRouteDecision.route===`safe-capture-post-recording-transcode`?(await this.startSafeCaptureRecording(a,t),$.info(`[StreamRecordingState] MediaRecorder capture started for post-recording transcode`)):($.debug(`[StreamRecordingState] Starting processing`),await e.startProcessing(a,t,s),$.info(`[StreamRecordingState] Processing started and worker ready`)),n&&($.debug(`[StreamRecordingState] Setting up tab visibility tracking`,{recordingStartTime:this.recordingStartTime}),this.tabVisibilityTracker=new Fx,this.tabVisibilityTracker.start(this.recordingStartTime),this.setupVisibilityUpdates(e)),this.streamManager.setState(`recording`),this.streamManager.emit(`recordingstart`,{recorder:null}),this.startRecordingTimer()}async stopRecording(){let e=(this.dependencies.getCurrentTimestamp()-this.recordingStartTime-this.totalPausedTime)/Lx;if($.debug(`[StreamRecordingState] stopRecording called`,{hasStreamProcessor:!!this.streamProcessor,isRecording:this.isRecording(),recordingElapsedSeconds:e}),!(this.streamProcessor&&this.isRecording()))throw Dx(wx,`Recording is not ready to stop`,{hasStreamProcessor:!!this.streamProcessor,streamState:this.streamManager.getState()});this.streamManager.setState(`stopping`),this.clearRecordingTimer(),this.clearBufferSizeInterval(),this.resetPauseState(),this.cleanupVisibilityUpdates();let t=[];this.tabVisibilityTracker?(t=this.tabVisibilityTracker.getIntervals(),$.debug(`[StreamRecordingState] Tab visibility intervals collected`,{intervalsCount:t.length,intervals:t}),this.tabVisibilityTracker.cleanup(),this.tabVisibilityTracker=null):$.debug(`[StreamRecordingState] No tab visibility tracker was active`);let n;return this.activeRouteDecision.route===`safe-capture-post-recording-transcode`?($.debug(`[StreamRecordingState] Finalizing MediaRecorder capture`),n={blob:await this.stopSafeCaptureRecording()}):($.debug(`[StreamRecordingState] Finalizing stream processor`),n=await this.streamProcessor.finalize(),$.info(`[StreamRecordingState] Stream processor finalized`,{blobSize:n.blob.size,hasBlob:!!n.blob})),this.streamManager.setState(`active`),this.streamManager.emit(`recordingstop`,{blob:n.blob,mimeType:n.blob.type||`video/mp4`}),{blob:n.blob,tabVisibilityIntervals:t,recordingStats:n.recordingStats,encoderAcceleration:n.encoderAcceleration}}pauseRecording(){this.clearRecordingTimer(),this.pauseStartTime===null&&(this.pauseStartTime=this.dependencies.getCurrentTimestamp()),this.tabVisibilityTracker&&this.tabVisibilityTracker.pause(),this.streamProcessor&&this.isRecording()&&this.streamProcessor.pause()}resumeRecording(){if(this.pauseStartTime!==null){let e=this.dependencies.getCurrentTimestamp()-this.pauseStartTime;this.totalPausedTime+=e,this.pauseStartTime=null}this.tabVisibilityTracker&&this.tabVisibilityTracker.resume(),this.startRecordingTimer(),this.streamProcessor&&this.isRecording()&&this.streamProcessor.resume()}toggleMute(){zb(this.streamProcessor,`StreamProcessor`).toggleMute()}muteAudio(){this.streamProcessor?(this.streamProcessor.isMutedState()||this.streamProcessor.toggleMute(),this.streamManager.setAudioTracksEnabled(!1)):this.streamManager.getStream()&&(this.streamManager.setAudioTracksEnabled(!1),this.streamManager.emit(`audiomutetoggle`,{muted:!0}))}unmuteAudio(){this.streamProcessor?(this.streamProcessor.isMutedState()&&this.streamProcessor.toggleMute(),this.streamManager.setAudioTracksEnabled(!0)):this.streamManager.getStream()&&(this.streamManager.setAudioTracksEnabled(!0),this.streamManager.emit(`audiomutetoggle`,{muted:!1}))}isMuted(){if(this.streamProcessor)return this.streamProcessor.isMutedState();let e=this.streamManager.getStream();if(e){let t=e.getAudioTracks();return t.length>0&&t.every(e=>!e.enabled)}return!1}async switchVideoSource(e){await zb(this.streamProcessor,`StreamProcessor`).switchVideoSource(e)}getCurrentVideoSource(){return Rb(zb(this.streamProcessor,`StreamProcessor`).getCurrentVideoSource(),`Current video source is not available`)}formatTimeElapsed(e){let t=Math.floor(e/60),n=Math.floor(e%60);return`${t.toString().padStart(2,`0`)}:${n.toString().padStart(2,`0`)}`}startRecordingTimer(){this.recordingTimer=window.setInterval(()=>{let e=(this.dependencies.getCurrentTimestamp()-this.recordingStartTime-this.totalPausedTime)/Lx,t=this.formatTimeElapsed(e);this.streamManager.emit(`recordingtimeupdate`,{elapsed:e,formatted:t})},Ix)}clearRecordingTimer(){this.recordingTimer!==null&&(clearInterval(this.recordingTimer),this.recordingTimer=null)}clearBufferSizeInterval(){this.bufferSizeUpdateInterval!==null&&(clearInterval(this.bufferSizeUpdateInterval),this.bufferSizeUpdateInterval=null)}resetRecordingState(){this.recordingStartTime=this.dependencies.getCurrentTimestamp(),this.totalPausedTime=0,this.pauseStartTime=null}async startSafeCaptureRecording(e,t){if(typeof MediaRecorder>`u`)throw Vx({route:`unsupported-with-guidance`,reasonCodes:[`mediarecorder-unavailable`],guidance:{canRetry:!0,message:`This browser cannot safely record on this device. Try a supported browser or upload an existing video file.`}});await this.applySafeCaptureTrackConstraints(e),this.mediaRecorderChunks=[];let n=this.resolvePreferredSafeCaptureMimeType(t),r=n===void 0?void 0:{mimeType:n},i=new MediaRecorder(e,r);this.mediaRecorder=i,this.mediaRecorderStopPromise=new Promise((e,t)=>{this.mediaRecorderStopResolve=e,this.mediaRecorderStopReject=t}),i.ondataavailable=e=>{e.data.size>0&&this.mediaRecorderChunks.push(e.data)},i.onstop=()=>{let e=i.mimeType||this.resolveSafeCaptureMimeType(),t=new Blob(this.mediaRecorderChunks,{type:e});this.mediaRecorderStopResolve?.(t)},i.onerror=()=>{this.mediaRecorderStopReject?.(Error(`Browser recording failed before upload could start`))},i.start()}async applySafeCaptureTrackConstraints(e){let t=this.resolveSafeCaptureVideoConstraints();if(t===null)return;let n=e.getVideoTracks();await Promise.all(n.map(async e=>{try{await e.applyConstraints(t)}catch(e){$.warn(`[StreamRecordingState] Could not apply safe capture video constraints`,e)}}))}resolveSafeCaptureVideoConstraints(){let e=this.activeRouteDecision.reasonCodes;return e.includes(`insufficient-device-memory`)||e.includes(`insufficient-hardware-concurrency`)?zx:e.includes(`android-post-recording-transcode`)?Bx:null}async stopSafeCaptureRecording(){let e=this.mediaRecorder,t=this.mediaRecorderStopPromise;if(!(e&&t))throw Error(`Safe capture recorder was not started`);e.state!==`inactive`&&e.stop();try{return await t}finally{this.mediaRecorder=null,this.mediaRecorderChunks=[],this.mediaRecorderStopPromise=null,this.mediaRecorderStopResolve=null,this.mediaRecorderStopReject=null,this.activeRouteDecision=Rx}}resolveSafeCaptureMimeType(){return(this.streamManager.getStream()?.getVideoTracks().length??0)>0?`video/webm`:`audio/webm`}resolvePreferredSafeCaptureMimeType(e){return(e.format===`mp4`?[`video/mp4;codecs=avc1.42E01E,mp4a.40.2`,`video/mp4;codecs=avc1.42001f,mp4a.40.2`,`video/mp4`]:[`video/webm;codecs=vp8,opus`,`video/webm;codecs=vp9,opus`,`video/webm`]).find(e=>typeof MediaRecorder.isTypeSupported==`function`?MediaRecorder.isTypeSupported(e):!1)}resetPauseState(){this.totalPausedTime=0,this.pauseStartTime=null}resolveTabVisibilityOverlayText(e){return e===void 0||e.trim().length===0?`User in another tab`:e}setupVisibilityUpdates(e){if(typeof document>`u`||typeof window>`u`){$.warn(`[StreamRecordingState] Cannot setup visibility updates - document/window not available`);return}if(this.visibilityChangeHandler=()=>{if(typeof document>`u`)return;let t=document.visibilityState===`hidden`,n=this.dependencies.getCurrentTimestamp();$.debug(`[StreamRecordingState] Visibility change`,{isHidden:t,timestamp:n,visibilityState:document.visibilityState}),e.updateTabVisibility(t,n)},this.blurHandler=()=>{let t=this.dependencies.getCurrentTimestamp();$.debug(`[StreamRecordingState] Window blur`,{timestamp:t}),e.updateTabVisibility(!0,t)},this.focusHandler=()=>{let t=this.dependencies.getCurrentTimestamp();$.debug(`[StreamRecordingState] Window focus`,{timestamp:t}),e.updateTabVisibility(!1,t)},document.addEventListener(`visibilitychange`,this.visibilityChangeHandler),window.addEventListener(`blur`,this.blurHandler),window.addEventListener(`focus`,this.focusHandler),document.visibilityState===`hidden`){let t=this.dependencies.getCurrentTimestamp();$.debug(`[StreamRecordingState] Initial state is hidden`,{timestamp:t}),e.updateTabVisibility(!0,t)}else $.debug(`[StreamRecordingState] Initial state is visible`)}cleanupVisibilityUpdates(){this.visibilityChangeHandler&&typeof document<`u`&&(document.removeEventListener(`visibilitychange`,this.visibilityChangeHandler),this.visibilityChangeHandler=null),this.blurHandler&&typeof window<`u`&&(window.removeEventListener(`blur`,this.blurHandler),this.blurHandler=null),this.focusHandler&&typeof window<`u`&&(window.removeEventListener(`focus`,this.focusHandler),this.focusHandler=null)}destroy(){this.mediaRecorder&&this.mediaRecorder.state!==`inactive`&&this.mediaRecorder.stop(),this.mediaRecorder=null,this.mediaRecorderChunks=[],this.mediaRecorderStopPromise=null,this.mediaRecorderStopResolve=null,this.mediaRecorderStopReject=null,this.activeRouteDecision=Rx,this.streamProcessor&&=(this.streamProcessor.destroy(),null),this.cleanupVisibilityUpdates(),this.tabVisibilityTracker&&=(this.tabVisibilityTracker.cleanup(),null),this.clearRecordingTimer(),this.clearBufferSizeInterval()}},Wx=class{constructor(e={}){this.streamManager=new Cx(e),this.recordingState=new Ux(this.streamManager)}getState(){return this.streamManager.getState()}getStream(){return this.streamManager.getStream()}getAudioStreamForAnalysis(){return this.recordingState.getAudioStreamForAnalysis()}isRecording(){return this.recordingState.isRecording()}isActive(){return this.streamManager.isActive()}on(e,t){return this.streamManager.on(e,t)}off(e,t){this.streamManager.off(e,t)}once(e,t){return this.streamManager.once(e,t)}setAudioDevice(e){this.streamManager.setAudioDevice(e)}setVideoDevice(e){this.streamManager.setVideoDevice(e)}getAudioDevice(){return this.streamManager.getAudioDevice()}getVideoDevice(){return this.streamManager.getVideoDevice()}async getAvailableDevices(){return await this.streamManager.getAvailableDevices()}async startStream(){return await this.streamManager.startStream()}stopStream(){this.streamManager.stopStream()}switchVideoDevice(e){return this.streamManager.switchVideoDevice(e)}switchAudioDevice(e){return this.streamManager.switchAudioDevice(e)}async startRecording(e,t,n,r,i){return await this.recordingState.startRecording(e,t,n,r,i)}async stopRecording(){return await this.recordingState.stopRecording()}pauseRecording(){this.recordingState.pauseRecording()}resumeRecording(){this.recordingState.resumeRecording()}toggleMute(){this.recordingState.toggleMute()}muteAudio(){this.recordingState.muteAudio()}unmuteAudio(){this.recordingState.unmuteAudio()}isMuted(){return this.recordingState.isMuted()}async switchVideoSource(e){return await this.recordingState.switchVideoSource(e)}setMediaStream(e){this.streamManager.setMediaStream(e)}getCurrentVideoSource(){return this.recordingState.getCurrentVideoSource()}getAudioStatus(){return this.streamManager.getAudioStatus()}isAudioReady(){return this.streamManager.isAudioReady()}async waitForAudio(){return await this.streamManager.waitForAudio()}setPreResolvedSupportReport(e){this.recordingState.setPreResolvedSupportReport(e)}destroy(){this.recordingState.destroy(),this.streamManager.destroy()}};let Gx=new Set([`recording.audio-no-chunks`,`recording.audio-silent`,`recording.audio-track-ended`,`recording.no-audio-track`,`recording.no-audio-frames`,`recording.audio-zero-channels`,`recording.audio-invalid-sample-rate`]),Kx=new Set([`recording.codec-unsupported`,`recording.video-codec-unavailable`]),qx=new Set([`recording.post-recording-transcode-fallback`,`transcode.post-recording-fallback`,`route.post-recording-transcode-fallback`]),Jx=new Set([`recording.no-video-frames`,`recording.frame-loss`,`recording.excessive-frame-errors`,`video.first-frame-timeout`]),Yx=new Set([`recording.finalize-timeout`,`recording.finalize-timeout-low-resource`,`stop.pending-writes-timeout`]),Xx=new Set([`recording.not-started`,`recording.state-race`,`recording.not-started-state-race`]),Zx=new Set([`recording.unsupported-with-guidance`,`recording.unsupported-device`]);function Qx(e){return e.startsWith(`recording.`)?Gx.has(e):!1}function $x(e){return e==null?null:i(e)}function eS(e){if(!(e&&typeof e==`object`&&`code`in e))return null;let t=e.code;return typeof t!=`string`||t.length===0?null:t}function tS(e){return e?Kx.has(e)?`recording.codec-unsupported`:qx.has(e)?`recording.post-recording-transcode-fallback`:Jx.has(e)?`recording.no-video-frames`:Yx.has(e)?`recording.finalize-timeout-low-resource`:Xx.has(e)?`recording.not-started-state-race`:Zx.has(e)?`recording.unsupported-device`:null:null}function nS(e,t){return t.some(t=>e.includes(t))}function rS(e){if(!e)return null;let t=e.toLowerCase();return nS(t,[`videoencoder.isconfigsupported`,`unknown codec`,`unsupported codec`,`no encodable video codec`,`video codec unavailable`])?`recording.codec-unsupported`:nS(t,[`input track cannot be ended`,`mediastreamtrackprocessor`,`video track ended`])?`recording.track-ended`:nS(t,[`no video frames`,`zero video frames`,`video.first-frame-timeout`,`failed to yield first frame`,`frame-loss`,`excessive frame errors`])?`recording.no-video-frames`:nS(t,[`finalize timeout`,`stop.pending-writes-timeout`])||t.includes(`pending writes`)&&t.includes(`timeout`)?`recording.finalize-timeout-low-resource`:nS(t,[`cannot finalize before starting`,`processing not active`,`worker not initialized`])?`recording.not-started-state-race`:nS(t,[`recording.unsupported-with-guidance`,`cannot safely record`,`recording is not supported in this browser context`])?`recording.unsupported-device`:null}function iS(e){return tS(e.errorCode??eS(e.error))||rS(e.errorMessage??$x(e.error))}let aS=Object.freeze({visible:!1,variant:`generic`,canRetry:!1,isCameraError:!1,isAudioError:!1,isBrowserUnsupported:!1,isPermissionDenied:!1});function oS(e){let{errorCode:t,hasAudioFailed:n,error:r}=e,i=iS({errorCode:t,error:r});if(t===`browser.unsupported`)return{visible:!0,variant:`browser`,canRetry:!1,isCameraError:!1,isAudioError:!1,isBrowserUnsupported:!0,isPermissionDenied:!1};if(t&&Qx(t))return{visible:!0,variant:`audio`,canRetry:!0,isCameraError:!1,isAudioError:!0,isBrowserUnsupported:!1,isPermissionDenied:!1};if(i)return{visible:!0,variant:`generic`,canRetry:!0,isCameraError:!1,isAudioError:!1,isBrowserUnsupported:!1,isPermissionDenied:!1,actionableCode:i,isRecordingPipelineError:!0};if(t?.startsWith(`camera.`)){let e=t===`camera.permission-denied`;return{visible:!0,variant:`camera`,canRetry:!e,isCameraError:!0,isAudioError:!1,isBrowserUnsupported:!1,isPermissionDenied:e}}if(n)return{visible:!0,variant:`audio`,canRetry:!0,isCameraError:!1,isAudioError:!0,isBrowserUnsupported:!1,isPermissionDenied:!1};if(t?.startsWith(`audio.`)){let e=t===`audio.permission-denied`;return{visible:!0,variant:`audio`,canRetry:!e,isCameraError:!1,isAudioError:!0,isBrowserUnsupported:!1,isPermissionDenied:e}}return r?{visible:!0,variant:`generic`,canRetry:!0,isCameraError:!1,isAudioError:!1,isBrowserUnsupported:!1,isPermissionDenied:!1}:aS}let sS=`VIDTREO_INSTALLATION_ID`,cS=`unknown`,lS=/\[([a-z]+(?:[.-][a-z0-9]+)+)\]/i,uS=/\b([a-z]+(?:[.-][a-z0-9]+)+)\b/i;function dS(e){let t=e.storageProvider,n=t?.getItem(sS);if(n)return $.debug(`Using existing installation ID from storage`,{installationId:n}),n;let r=fS(e);return t?.setItem(sS,r),$.debug(`Created new installation ID`,{installationId:r}),r}function fS(e){let t=e.cryptoProvider;if(t?.getRandomValues){let e=new Uint8Array(16);return t.getRandomValues(e),Array.from(e).map(e=>e.toString(16).padStart(2,`0`)).join(``)}let n=e.nowProvider().toString(16),r=e.randomProvider();return`${n}-${Math.floor(r*1e9).toString(16)}`}let pS=[`sdk.init.started`,`sdk.init.succeeded`,`sdk.init.failed`],mS=[`stream.error`],hS={"sdk.init.started":`lifecycle`,"sdk.init.succeeded":`lifecycle`,"sdk.init.failed":`error`,"preview.start.succeeded":`interaction`,"preview.start.failed":`error`,"recording.start.requested":`interaction`,"recording.start.succeeded":`interaction`,"recording.start.failed":`error`,"recording.stop.requested":`interaction`,"recording.stop.succeeded":`interaction`,"recording.stop.failed":`error`,"recording.route.selected":`lifecycle`,"upload.started":`performance`,"upload.succeeded":`performance`,"upload.failed":`error`,"upload.route.selected":`lifecycle`,"transcode.route.selected":`lifecycle`,"source.switch.requested":`interaction`,"source.switch.succeeded":`interaction`,"source.switch.failed":`error`,"stream.error":`error`,"audio.acquisition.fallback":`lifecycle`,"audio.acquisition.retry":`lifecycle`,"audio.acquisition.recovered":`lifecycle`,"audio.acquisition.failed":`error`,"audio.warning":`error`,"recording.audio-missing":`error`,"storage.init.failed":`error`,"storage.write.probe.failed":`error`};var gS=class{constructor(e,t){this.pendingEvents=[],this.flushTimeoutId=null,this.throttledEventTimestamps=new Map,this.retryCountMap=new Map,this.oneTimeEventCache=new Map,this.config=e,this.dependencies=t,this.installationId=dS(this.dependencies),$.debug(`TelemetryClient initialized`,{installationId:this.installationId,backendUrl:e.backendUrl})}triggerTelemetryEvent(e){try{let t=this.dependencies.nowProvider();if(this.shouldSkipEvent(e.name,t))return;let n=hS[e.name],r=this.buildError(e.error),i=this.buildFingerprint(),a=this.buildContext(),o=this.mergeProperties(this.buildBaseProperties(i),e),s={event:e.name,category:n,timestamp:t,installationId:this.installationId,fingerprint:i,sdkVersion:`1.6.2`,context:a,properties:o,error:r};this.markEventTracking(e.name,t),this.enqueueEvent(s)}catch(t){$.error(`Telemetry event failed`,{eventName:e.name,error:i(t)})}}enqueueEvent(e){try{if(this.pendingEvents=[...this.pendingEvents,e],this.pendingEvents.length>=10){this.flushQueue();return}this.scheduleFlush()}catch(e){$.error(`Failed to enqueue telemetry event`,{error:i(e)})}}scheduleFlush(){this.flushTimeoutId||=this.dependencies.setTimeoutFunction(()=>{this.flushQueue()},1e3)}flushQueue(){try{if(this.pendingEvents.length===0){this.clearFlushTimer();return}let e=this.pendingEvents;this.pendingEvents=[],this.clearFlushTimer();let t=this.buildRequestPayload(e);$.debug(`Telemetry batch flush`,{eventsCount:t.events.length}),this.sendPayload(t).then(()=>{this.clearRetryMetadata(e)}).catch(()=>{this.requeueFailedEvents(e)})}catch(e){$.error(`Failed to flush telemetry queue`,{error:i(e)})}}clearFlushTimer(){this.flushTimeoutId&&=(this.dependencies.clearTimeoutFunction(this.flushTimeoutId),null)}buildRequestPayload(e){return{events:[...e]}}shouldSkipEvent(e,t){if(this.isOneTimeEvent(e)){let t=this.getOneTimeCacheKey(e);if(this.oneTimeEventCache.get(t))return $.debug(`Telemetry event skipped (dedupe)`,{event:e}),!0}if(this.isThrottledEvent(e)){let n=this.throttledEventTimestamps.get(e);if(n!==void 0&&t-n<5e3)return $.debug(`Telemetry event skipped (throttle)`,{event:e,lastSent:n}),!0}return!1}markEventTracking(e,t){if(this.isOneTimeEvent(e)){let t=this.getOneTimeCacheKey(e);this.oneTimeEventCache.set(t,!0)}this.isThrottledEvent(e)&&(this.throttledEventTimestamps=this.updateNumberMap(this.throttledEventTimestamps,e,t))}updateNumberMap(e,t,n){let r=new Map(e);return r.set(t,n),r}getOneTimeCacheKey(e){return`${this.installationId}:${e}`}isOneTimeEvent(e){return pS.includes(e)}isThrottledEvent(e){return mS.includes(e)}buildBaseProperties(e){let t={},n=e.userAgent,r=this.getBrowserName(n);return r&&(t={...t,browserName:r}),t}mergeProperties(e,t){let n=this.sanitizeEventProperties(t.properties),r=this.buildErrorProperties(t.error);if(Object.keys(e).length===0&&Object.keys(r).length===0&&!n)return;let i={...e,...r,...n};if(Object.keys(i).length>0)return i}sanitizeEventProperties(e){if(!e)return;let t=this.sanitizeRouteDecision(e.routeDecision);return t===void 0?e:{...e,routeDecision:t}}sanitizeRouteDecision(e){if(!(e&&typeof e==`object`))return;let t=e,n={};typeof t.selectedRoute==`string`&&(n={...n,selectedRoute:t.selectedRoute}),Array.isArray(t.reasonCodes)&&(n={...n,reasonCodes:t.reasonCodes.filter(e=>typeof e==`string`)});let r=this.sanitizeCapabilitySummary(t.capabilitySummary);if(r!==void 0&&(n={...n,capabilitySummary:r}),this.isRouteSourceType(t.sourceType)&&(n={...n,sourceType:t.sourceType}),typeof t.clientTranscodeDeferred==`boolean`&&(n={...n,clientTranscodeDeferred:t.clientTranscodeDeferred}),Object.keys(n).length!==0)return n}sanitizeCapabilitySummary(e){if(!(e&&typeof e==`object`))return;let t={};for(let[n,r]of Object.entries(e))this.isSafeCapabilityValue(r)&&(t={...t,[n]:r});if(Object.keys(t).length!==0)return t}isSafeCapabilityValue(e){return e===null||typeof e==`boolean`||typeof e==`number`||typeof e==`string`?!0:Array.isArray(e)&&e.every(e=>typeof e==`string`)}isRouteSourceType(e){return e===`live-recorder`||e===`native-camera`||e===`file-upload`}buildErrorProperties(e){if(!e)return{};let t={},n=eS(e),r=i(e),a=n??this.extractNormalizedErrorCode(r),o=iS({errorCode:a,error:e,errorMessage:r});return a&&(t={...t,errorCode:a}),o&&(t={...t,rawErrorClassification:o,recordingPipelineErrorCode:o}),t}buildFingerprint(){let e=this.dependencies.navigatorProvider;if(!e)return{};let t={userAgent:e.userAgent,language:e.language,platform:e.platform};e.hardwareConcurrency&&(t={...t,hardwareConcurrency:e.hardwareConcurrency});let n=this.getDeviceMemory(e);return n!==null&&(t={...t,deviceMemory:n}),t}buildContext(){let e=this.config.pageUrl,t=this.config.referrerUrl;if(!e){let t=this.dependencies.locationProvider;t&&(e=t.href)}if(!t){let e=this.dependencies.documentProvider;if(e){let n=e.referrer;n&&(t=n)}}return{sessionId:this.config.sessionId,userId:this.config.userId,environmentId:this.config.environmentId,appVersion:this.config.appVersion,release:this.config.release,pageUrl:e,referrerUrl:t,sdkLocation:this.config.sdkLocation,clientLocation:this.config.clientLocation}}buildError(e){if(!e)return;let t=i(e),n={message:t},r=eS(e),a=r??this.extractNormalizedErrorCode(t);return a&&(n.normalizedCode=a),r?n.code=r:a&&(n.code=a),e instanceof Error&&(!n.code&&e.name&&(n.code=e.name),e.stack&&(n.stack=e.stack)),n}extractNormalizedErrorCode(e){let t=e.match(lS);if(t?.[1])return t[1];let n=e.match(uS);return n?.[1]?n[1]:null}getBrowserName(e){return e?e.includes(`Edg`)?`edge`:e.includes(`Chrome`)?`chrome`:e.includes(`Firefox`)?`firefox`:e.includes(`Safari`)?`safari`:cS:cS}getDeviceMemory(e){let t=e;return t.deviceMemory?t.deviceMemory:null}async sendPayload(e){let t=this.buildTelemetryEndpoint(),n={method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${this.config.apiKey}`},body:JSON.stringify(e)};$.debug(`Sending telemetry to endpoint`,{endpoint:t,payloadSize:JSON.stringify(e).length,hasApiKey:!!this.config.apiKey});let r=await this.dependencies.fetchFunction(t,n).catch(e=>{throw $.error(`Failed to send telemetry`,{endpoint:t,error:i(e)}),e});if(r&&!r.ok)throw $.error(`Telemetry endpoint returned error`,{status:r.status}),Error(`Telemetry HTTP ${r.status}`)}requeueFailedEvents(e){let t=e.filter(e=>(this.retryCountMap.get(e)??0)<3);for(let e of t){let t=this.retryCountMap.get(e)??0;this.retryCountMap.set(e,t+1)}let n=e.length-t.length;if(n>0){let r=e.filter(e=>!t.includes(e));this.clearRetryMetadata(r),$.warn(`Dropped ${n} telemetry events after max retries`)}if(t.length===0)return;let r=this.pendingEvents.length,i=Math.max(0,100-r);this.pendingEvents=[...t.slice(0,i),...this.pendingEvents],this.scheduleFlush()}clearRetryMetadata(e){for(let t of e)this.retryCountMap.delete(t)}buildTelemetryEndpoint(){return this.config.endpoint?this.config.endpoint:`${this.config.backendUrl}/api/v1/telemetry`}};function _S(){let e=typeof window<`u`,t=typeof document<`u`,n=fetch,r=null,i=null,a=null,o=null,s=null,c=setTimeout,l=clearTimeout;return e&&(n=window.fetch.bind(window),r=window.crypto,i=window.localStorage,a=window.navigator,o=window.location,c=window.setTimeout.bind(window),l=window.clearTimeout.bind(window)),t&&(s=document),{fetchFunction:n,cryptoProvider:r,storageProvider:i,navigatorProvider:a,locationProvider:o,documentProvider:s,nowProvider:()=>Date.now(),randomProvider:()=>Math.random(),setTimeoutFunction:c,clearTimeoutFunction:l}}function vS(e,t,n){return new gS({apiKey:e,backendUrl:t,endpoint:n?.endpoint,sessionId:n?.sessionId,userId:n?.userId,environmentId:n?.environmentId,appVersion:n?.appVersion,release:n?.release,pageUrl:n?.pageUrl,referrerUrl:n?.referrerUrl,sdkLocation:n?.sdkLocation,clientLocation:n?.clientLocation},_S())}var yS=class{constructor(e,t){this.isProcessing=!1,this.hasRecoveredStaleUploads=!1,this.retryTimeoutId=null,this.callbacks={},this.storageService=e,this.uploadService=t,this.networkOnlineHandler=()=>{this.processQueue().catch(e=>{let t=i(e);this.callbacks.onUploadError?.(`network-recovery`,Error(t))})},window.addEventListener(`online`,this.networkOnlineHandler),this.processingIntervalId=window.setInterval(()=>{this.processQueue().catch(e=>{let t=i(e);this.callbacks.onUploadError?.(`processing-loop`,Error(t))})},5e3)}destroy(){this.clearTimer(this.processingIntervalId,clearInterval),this.clearTimer(this.retryTimeoutId,clearTimeout),window.removeEventListener(`online`,this.networkOnlineHandler)}setCallbacks(e){this.callbacks=e}async queueUpload(e){let t=await this.storageService.savePendingUpload(e);return this.processQueue().catch(e=>{let n=i(e);this.callbacks.onUploadError?.(t,Error(n))}),t}async processQueue(){if(!this.isProcessing){this.isProcessing=!0;try{if(!this.storageService.isInitialized())throw Error(`Database not initialized`);if(!this.hasRecoveredStaleUploads){let e=await this.storageService.getPendingUploads(`uploading`);await Promise.all(e.map(e=>this.storageService.updateUploadStatus(e.id,{status:`pending`}))),this.hasRecoveredStaleUploads=!0}let e=await this.storageService.getPendingUploads(`pending`);if(e.length>0){let t=this.getOldestUpload(e);await this.processUpload(t),this.isProcessing=!1;return}let t=(await this.storageService.getPendingUploads(`failed`)).filter(e=>e.retryCount<10);if(t.length>0){let e=this.getOldestFailedUpload(t),n=this.calculateRetryDelay(e.retryCount),r=Date.now()-e.updatedAt;if(r>=n)await this.storageService.updateUploadStatus(e.id,{status:`pending`,retryCount:e.retryCount}),await this.processUpload(e);else{let e=n-r;this.scheduleRetry(e)}}this.isProcessing=!1}catch(e){throw this.isProcessing=!1,Error(`Error processing upload queue: ${i(e)}`)}}}getPendingUploads(){return this.storageService.getPendingUploads()}async getStats(){let e=await this.storageService.getPendingUploads(),t={pending:0,uploading:0,failed:0,total:e.length};for(let n of e)n.status===`pending`?t.pending+=1:n.status===`uploading`?t.uploading+=1:n.status===`failed`&&(t.failed+=1);return t}getOldestUpload(e){if(e.length===0)throw Error(`Cannot get oldest upload from empty array`);return e.sort((e,t)=>e.createdAt-t.createdAt)[0]}getOldestFailedUpload(e){if(e.length===0)throw Error(`Cannot get oldest failed upload from empty array`);return e.sort((e,t)=>e.updatedAt-t.updatedAt)[0]}async processUpload(e){try{await this.storageService.updateUploadStatus(e.id,{status:`uploading`});let t=await this.uploadService.uploadVideo(e.blob,{apiKey:e.apiKey,backendUrl:e.backendUrl,filename:e.filename,mimeType:e.mimeType,metadata:e.metadata,userMetadata:e.userMetadata,onProgress:t=>{this.callbacks.onUploadProgress?.(e.id,t)}});await this.storageService.deleteUpload(e.id),this.callbacks.onUploadComplete?.(e.id,t)}catch(t){let n=i(t),r=e.retryCount+1;if(await this.storageService.updateUploadStatus(e.id,{status:`failed`,retryCount:r,lastError:n}),r>=10)this.callbacks.onUploadError?.(e.id,Error(`Upload failed after 10 attempts: ${n}`));else{let e=this.calculateRetryDelay(r);this.scheduleRetry(e)}}}calculateRetryDelay(e){let t=2e3*1.5**(e-1);return Math.min(t,3e5)}scheduleRetry(e){this.clearTimer(this.retryTimeoutId,clearTimeout),this.retryTimeoutId=window.setTimeout(()=>{this.retryTimeoutId=null,this.processQueue().catch(e=>{let t=i(e);this.callbacks.onUploadError?.(`scheduled-retry`,Error(t))})},e)}clearTimer(e,t){e!==null&&t(e)}},bS=class{uploadVideo(e,t){if(!t.filename)throw Error(`Filename is required`);if(!e.type||e.type.trim()===``)throw Error(`Blob type is required`);return this.uploadVideoFile(e,t)}uploadVideoFile(e,t){return new Promise((n,r)=>{let i=new XMLHttpRequest,a=this.createUploadBlob(e,t.mimeType);if(t.onProgress){let e=t.onProgress;i.upload.addEventListener(`progress`,t=>{t.lengthComputable&&e(t.loaded/t.total)})}i.addEventListener(`load`,()=>{if(i.status>=200&&i.status<=299){this.parseSuccessResponse(i,n,r);return}this.parseErrorResponse(i,r)}),i.addEventListener(`error`,()=>{r(Error(`Network error during upload`))}),i.addEventListener(`abort`,()=>{r(Error(`Upload was aborted`))});let o=`${t.backendUrl}/api/v1/videos/upload`;i.open(`POST`,o),i.setRequestHeader(`Authorization`,`Bearer ${t.apiKey}`);let s=new FormData;s.append(`file`,a,t.filename);let c={filename:t.filename,mimeType:a.type};t.userMetadata&&(c.userMetadata=t.userMetadata),s.append(`metadata`,JSON.stringify(c)),i.send(s)})}createUploadBlob(e,t){let n=this.resolveUploadMimeType(e,t);return n===e.type?e:new Blob([e],{type:n})}resolveUploadMimeType(e,t){return t&&t.trim().length>0?this.normalizeMimeType(t):this.normalizeMimeType(e.type)}normalizeMimeType(e){let[t]=e.split(`;`);return t===void 0?e.trim().toLowerCase():t.trim().toLowerCase()}parseSuccessResponse(e,t,n){let r=this.safeParseJsonFromXhr(e);if(!r){n(Error(`Failed to parse upload response: invalid JSON`));return}let i=r.data;if(!i){n(Error(`Failed to parse upload response: missing data`));return}t({id:i.id,publicId:i.publicId,filename:i.filename,fileSize:i.fileSize,mimeType:i.mimeType,duration:i.duration,status:i.status,uploadUrl:i.uploadUrl,createdAt:i.createdAt})}parseErrorResponse(e,t){let n=this.safeParseJsonFromXhr(e);if(n&&typeof n==`object`&&`error`in n&&typeof n.error==`string`){t(Error(n.error));return}t(Error(`Upload failed: ${e.status} ${e.statusText}`))}safeParseJsonFromXhr(e){if(!e.responseText||e.responseText.trim()===``)return null;let t=e.responseText.trim();if(!(t.startsWith(`{`)&&t.endsWith(`}`))||t.length<2)return null;let n=JSON.parse(e.responseText);return typeof n==`object`&&n?n:null}};let xS=e=>{},SS=e=>{},CS=e=>{},wS=()=>{},TS=e=>{},ES=(e,t)=>{},DS=e=>{},OS=e=>{},kS=e=>{},AS=()=>{},jS=e=>{};function MS(e){let t={onProgress:xS,onSuccess:SS,onError:CS,onClearStatus:wS};return e.upload&&(t=e.upload),t}let NS=e=>{};function PS(e){let t=jS;return e.onStorageCleanupError&&(t=e.onStorageCleanupError),t}function FS(e){let t=NS;return e.onStorageWriteError&&(t=e.onStorageWriteError),t}function IS(e,t){let n=e.recording,r=TS;n?.onStateChange&&(r=n.onStateChange);let i=ES;n?.onCountdownUpdate&&(i=n.onCountdownUpdate);let a=DS;n?.onTimerUpdate&&(a=n.onTimerUpdate);let o=OS;n?.onError&&(o=n.onError);let s=kS;n?.onRecordingComplete&&(s=n.onRecordingComplete);let c=AS;return n?.onClearUploadStatus&&(c=n.onClearUploadStatus),{onStateChange:r,onCountdownUpdate:i,onTimerUpdate:a,onError:o,onRecordingComplete:s,onClearUploadStatus:c,onStopAudioTracking:t.stopAudioTracking,onGetConfig:t.getConfig,...t.getRouteDecision&&{onGetRouteDecision:t.getRouteDecision},...t.onAudioWarning&&{onAudioWarning:t.onAudioWarning},...t.onAudioRecovered&&{onAudioRecovered:t.onAudioRecovered},...t.onTranscodingProgress&&{onTranscodingProgress:t.onTranscodingProgress}}}function LS(e,t){let n=e.sourceSwitch;return{onSourceChange:n?.onSourceChange,onPreviewUpdate:n?.onPreviewUpdate,onError:n?.onError,onTransitionStart:n?.onTransitionStart,onTransitionEnd:n?.onTransitionEnd,onScreenSelectionStart:()=>{t.isRecording()&&t.updateSourceType(!0)},onScreenSelectionEnd:()=>{t.isRecording()&&t.updateSourceType(!1)},getSelectedCameraDeviceId:t.getSelectedCameraDeviceId,getSelectedMicDeviceId:t.getSelectedMicDeviceId}}var RS=class{constructor(e={}){this.totalChunks=0,this.nonSilentChunks=0,this.lowSignalChunks=0,this.peak=0,this.rms=0,this.inputPeak=0,this.inputRms=0,this.startedAtMs=null,this.lastChunkTimestampMs=null,this.silentStartedAtMs=null,this.lowSignalStartedAtMs=null,this.mutedSpeechStartedAtMs=null,this.mutedStartedAtMs=null,this.mutedDurationMs=0,this.currentMuted=!1,this.hasHealthySignal=!1,this.silenceThreshold=this.resolveNumber(e.silenceThreshold,.001),this.lowSignalThreshold=this.resolveNumber(e.lowSignalThreshold,.05),this.mutedSpeechThreshold=this.resolveNumber(e.mutedSpeechThreshold,this.silenceThreshold),this.silentWarningDurationMs=this.resolveNumber(e.silentWarningDurationMs,2e3),this.lowSignalWarningDurationMs=this.resolveNumber(e.lowSignalWarningDurationMs,2e3),this.mutedSpeechWarningDurationMs=this.resolveNumber(e.mutedSpeechWarningDurationMs,1e4),this.noChunkWarningDurationMs=this.resolveNumber(e.noChunkWarningDurationMs,2e3)}recordChunk(e){this.markStarted(e.timestampMs),this.trackMuteState(e.timestampMs,e.isMuted);let t=this.calculateChunkStats(e.samples),n=this.resolveOptionalNumber(e.inputPeak,t.peak),r=this.resolveOptionalNumber(e.inputRms,t.rms),i=t.peak<=this.silenceThreshold,a=!e.isMuted&&t.peak>this.silenceThreshold&&t.peak<this.lowSignalThreshold,o=e.isMuted&&n>this.mutedSpeechThreshold;return this.totalChunks+=1,this.peak=t.peak,this.rms=t.rms,this.inputPeak=n,this.inputRms=r,i||(this.nonSilentChunks+=1,this.silentStartedAtMs=null),a&&(this.lowSignalChunks+=1),t.peak>=this.lowSignalThreshold&&(this.hasHealthySignal=!0),i&&this.silentStartedAtMs===null&&(this.silentStartedAtMs=e.timestampMs),a&&this.lowSignalStartedAtMs===null&&(this.lowSignalStartedAtMs=e.timestampMs),a||(this.lowSignalStartedAtMs=null),o&&this.mutedSpeechStartedAtMs===null&&(this.mutedSpeechStartedAtMs=e.timestampMs),o||(this.mutedSpeechStartedAtMs=null),this.lastChunkTimestampMs=e.timestampMs,this.snapshot(e.timestampMs,e.isMuted)}inspect(e,t){return this.markStarted(e),this.trackMuteState(e,t),this.snapshot(e,t)}reset(){this.totalChunks=0,this.nonSilentChunks=0,this.lowSignalChunks=0,this.peak=0,this.rms=0,this.inputPeak=0,this.inputRms=0,this.startedAtMs=null,this.lastChunkTimestampMs=null,this.silentStartedAtMs=null,this.lowSignalStartedAtMs=null,this.mutedSpeechStartedAtMs=null,this.mutedStartedAtMs=null,this.mutedDurationMs=0,this.currentMuted=!1,this.hasHealthySignal=!1}snapshot(e,t){let n=this.resolveSilentDuration(e),r=this.resolveLowSignalDuration(e),i=this.resolveMutedSpeechDuration(e),a=this.resolveNoChunkDuration(e),o=this.resolveMutedDuration(e,t);return{classification:this.classify(t,n,r,i,a),totalChunks:this.totalChunks,nonSilentChunks:this.nonSilentChunks,lowSignalChunks:this.lowSignalChunks,peak:this.peak,rms:this.rms,inputPeak:this.inputPeak,inputRms:this.inputRms,consecutiveSilentDurationMs:n,consecutiveLowSignalDurationMs:r,consecutiveMutedSpeechDurationMs:i,noChunkDurationMs:a,mutedDurationMs:o,hasHealthySignal:this.hasHealthySignal}}getFinalSnapshot(e,t){let n=this.resolveMutedDuration(e,t);return{totalChunks:this.totalChunks,nonSilentChunks:this.nonSilentChunks,lowSignalChunks:this.lowSignalChunks,mutedDurationMs:n,hasHealthySignal:this.hasHealthySignal}}classify(e,t,n,r,i){return this.totalChunks===0&&i>=this.noChunkWarningDurationMs?`no-chunks`:e&&r>=this.mutedSpeechWarningDurationMs?`speaking-while-muted`:e&&t>=this.silentWarningDurationMs?`muted-silence-expected`:!e&&t>=this.silentWarningDurationMs?`silent-while-unmuted`:!e&&this.nonSilentChunks>0&&this.peak<this.lowSignalThreshold&&n>=this.lowSignalWarningDurationMs?`low-signal`:`healthy`}calculateChunkStats(e){if(e.length===0)return{peak:0,rms:0};let t=0,n=0;for(let r of e){let e=Math.abs(r);t=Math.max(t,e),n+=r*r}return{peak:t,rms:Math.sqrt(n/e.length)}}resolveSilentDuration(e){return this.silentStartedAtMs===null?0:e-this.silentStartedAtMs}resolveLowSignalDuration(e){return this.lowSignalStartedAtMs===null?0:e-this.lowSignalStartedAtMs}resolveMutedSpeechDuration(e){return this.mutedSpeechStartedAtMs===null?0:e-this.mutedSpeechStartedAtMs}resolveNoChunkDuration(e){return this.lastChunkTimestampMs===null?this.startedAtMs===null?0:e-this.startedAtMs:e-this.lastChunkTimestampMs}markStarted(e){this.startedAtMs===null&&(this.startedAtMs=e)}trackMuteState(e,t){if(t!==this.currentMuted){if(t){this.mutedStartedAtMs=e,this.currentMuted=!0;return}this.mutedStartedAtMs!==null&&(this.mutedDurationMs+=e-this.mutedStartedAtMs),this.mutedStartedAtMs=null,this.currentMuted=!1}}resolveMutedDuration(e,t){return t&&this.mutedStartedAtMs!==null?this.mutedDurationMs+e-this.mutedStartedAtMs:this.mutedDurationMs}resolveNumber(e,t){if(e===void 0)return t;if(!Number.isFinite(e)||e<0)throw Error(`Audio health monitor option must be a non-negative number`);return e}resolveOptionalNumber(e,t){return e===void 0||!Number.isFinite(e)||e<0?t:e}};function zS(e){let t=e.getVideoTracks();if(t.length===0)return!1;let n=t[0];return`displaySurface`in n.getSettings()||n.label.toLowerCase().includes(`screen`)||n.label.toLowerCase().includes(`display`)}Sv();function BS(e){if(e!==void 0)return typeof e==`number`?e:e===lf?`low`:e===uf?`medium`:e===df?`high`:e===ff?`very-high`:`high`}function VS(e){let t=null,n=0;function r(){if(!t){let n=e.createBlob();t=e.createObjectUrl(n)}return n+=1,t}function i(){n!==0&&(--n,n===0&&(t&&=(e.revokeObjectUrl(t),null)))}return{acquire:r,release:i}}let HS=`vidtreo-audio-worklet`,US=`audioChunk`,WS=`setMuted`,GS=`setPaused`,KS=`shutdown`,qS=`
141
+ const AUDIO_WORKLET_MESSAGE_TYPE_AUDIO_CHUNK = "${US}";
142
+ const AUDIO_WORKLET_MESSAGE_TYPE_SET_MUTED = "${WS}";
143
+ const AUDIO_WORKLET_MESSAGE_TYPE_SET_PAUSED = "${GS}";
144
+ const AUDIO_WORKLET_MESSAGE_TYPE_SHUTDOWN = "${KS}";
145
145
 
146
146
  class VidtreoAudioWorkletProcessor extends AudioWorkletProcessor {
147
147
  constructor() {
@@ -239,8 +239,8 @@ class VidtreoAudioWorkletProcessor extends AudioWorkletProcessor {
239
239
  }
240
240
  }
241
241
 
242
- registerProcessor("${VS}", VidtreoAudioWorkletProcessor);
243
- `;function qS(){if(typeof Blob>`u`||typeof URL>`u`)throw Error(`Blob and URL APIs are required for audio worklet loading`);return new Blob([KS],{type:`application/javascript`})}let JS=BS({createBlob:qS,createObjectUrl:e=>URL.createObjectURL(e),revokeObjectUrl:e=>{URL.revokeObjectURL(e)}});var YS=class{constructor(){this.audioContext=null,this.audioWorkletNode=null,this.audioSourceNode=null,this.audioDestinationNode=null,this.audioConfig=null,this.onAudioChunk=null,this.isMuted=!1,this.isPaused=!1,this.isProcessing=!1,this.hasAudioWorkletUrlLease=!1}async initialize(e,t){if(!e)throw Error(`Audio stream is required`);if(e.getAudioTracks().length===0)throw Error(`Audio stream has no tracks`);let n=a();if(!n)throw Error(`AudioContext is not supported in this browser`);this.onAudioChunk=t;try{let t=JS.acquire();this.hasAudioWorkletUrlLease=!0;let r=new n;this.audioContext=r,r.resume().catch(e=>{$.warn(`[AudioWorkletController] Failed to resume AudioContext`,i(e))}),await r.audioWorklet.addModule(t).catch(e=>{let t=i(e);throw Error(`Failed to load AudioWorklet module: ${t}`)});let a=new AudioWorkletNode(r,VS,{numberOfInputs:1,numberOfOutputs:1,outputChannelCount:[1]});a.port.onmessage=this.handleWorkletMessage.bind(this),this.audioWorkletNode=a,this.audioSourceNode=r.createMediaStreamSource(e),this.audioDestinationNode=r.createGain(),this.audioDestinationNode.gain.value=0;let o={sampleRate:r.sampleRate,numberOfChannels:1,format:`f32-planar`};return this.audioConfig=o,this.setMuted(this.isMuted),this.setPaused(this.isPaused),o}catch(e){throw await this.cleanupAfterInitializeFailure(),this.normalizeInitializationError(e)}}async startProcessing(){if(!this.isProcessing){if(!this.audioContext)throw Error(`AudioContext is not initialized`);if(!this.audioWorkletNode)throw Error(`AudioWorklet node is not initialized`);if(!this.audioSourceNode)throw Error(`Audio source node is not initialized`);if(!this.audioDestinationNode)throw Error(`AudioWorklet graph is not initialized`);this.audioSourceNode.connect(this.audioWorkletNode),this.audioWorkletNode.connect(this.audioDestinationNode),this.audioDestinationNode.connect(this.audioContext.destination),await this.audioContext.resume(),this.isProcessing=!0}}setMuted(e){this.isMuted=e,this.audioWorkletNode&&this.audioWorkletNode.port.postMessage({type:US,isMuted:e})}setPaused(e){this.isPaused=e,this.audioWorkletNode&&this.audioWorkletNode.port.postMessage({type:WS,isPaused:e})}close(){this.disconnectAudioNodes(!0),this.closeAudioContext(),this.audioConfig=null,this.onAudioChunk=null,this.isMuted=!1,this.isPaused=!1,this.isProcessing=!1,this.releaseAudioWorkletUrlLease()}getConfig(){return this.audioConfig}handleWorkletMessage(e){let t=e.data;if(!t||t.type!==HS)return;let n=this.parseAudioBuffer(t.data);if(!n||!this.onAudioChunk)return;let r={data:n,frames:t.frames,numberOfChannels:t.numberOfChannels,sampleRate:t.sampleRate,timestamp:t.timestamp,inputPeak:t.inputPeak,inputRms:t.inputRms};this.onAudioChunk(r)}parseAudioBuffer(e){return e instanceof Float32Array?e:e instanceof ArrayBuffer?new Float32Array(e):null}async cleanupAfterInitializeFailure(){this.disconnectAudioNodes(!1),await this.closeAudioContext(),this.audioConfig=null,this.onAudioChunk=null,this.releaseAudioWorkletUrlLease()}normalizeInitializationError(e){if(e instanceof Error)return e;let t=i(e);return Error(t)}disconnectAudioNodes(e){this.audioWorkletNode&&=(e&&this.audioWorkletNode.port.postMessage({type:GS}),this.audioWorkletNode.disconnect(),null),this.audioSourceNode&&=(this.audioSourceNode.disconnect(),null),this.audioDestinationNode&&=(this.audioDestinationNode.disconnect(),null)}closeAudioContext(){if(!this.audioContext)return Promise.resolve();let e=this.audioContext;return this.audioContext=null,e.close().catch(e=>{$.warn(`[AudioWorkletController] Failed to close AudioContext`,i(e))})}releaseAudioWorkletUrlLease(){this.hasAudioWorkletUrlLease&&=(JS.release(),!1)}},XS=class{constructor(e){this.audioWorkletController=null,this.audioWorkletConfig=null,this.onChunk=e.onChunk;let t=()=>new YS;e.createController&&(t=e.createController),this.createController=t}async prepareAudioConfig(e){if(!e)return this.audioWorkletConfig=null,null;this.audioWorkletController||=this.createController();let t=new MediaStream([e]);return this.audioWorkletConfig=await this.audioWorkletController.initialize(t,e=>this.onChunk(e)).catch(e=>{throw this.stop(),e}),this.createWorkerAudioConfig(this.audioWorkletConfig)}async startProcessing(){this.audioWorkletController&&await this.audioWorkletController.startProcessing()}stop(){this.audioWorkletController&&=(this.audioWorkletController.close(),null),this.audioWorkletConfig=null}setMuted(e){this.audioWorkletController&&this.audioWorkletController.setMuted(e)}setPaused(e){this.audioWorkletController&&this.audioWorkletController.setPaused(e)}createWorkerAudioConfig(e){return e?{sampleRate:e.sampleRate,numberOfChannels:e.numberOfChannels,format:e.format}:null}};let ZS=`recording.video-track-ended`;function QS(e={}){let t=Error(`Video track ended before recording could start [${ZS}]`);return t.code=ZS,t.isRecoverable=!0,t.details=e,t}function $S(e,t={}){if(e.readyState!==`live`)throw QS({...t,trackId:e.id,readyState:e.readyState})}let eC=`video.first-frame-timeout`,tC={createVideoStreamFromTrack:e=>typeof MediaStreamTrackProcessor>`u`?null:($S(e,{stage:`preflight-stream-create`}),new MediaStreamTrackProcessor({track:e}).readable),setTimeout:(e,t)=>window.setTimeout(e,t),clearTimeout:e=>window.clearTimeout(e),performanceNow:()=>performance.now()};async function nC(e,t=3e3,n={}){let r={createVideoStreamFromTrack:n.createVideoStreamFromTrack??tC.createVideoStreamFromTrack,setTimeout:n.setTimeout??tC.setTimeout,clearTimeout:n.clearTimeout??tC.clearTimeout,performanceNow:n.performanceNow??tC.performanceNow},i=r.performanceNow();$S(e,{stage:`preflight-original-track`});let a=rC(e);$S(a,{stage:`preflight-cloned-track`});let o=r.createVideoStreamFromTrack(a);if(!o)return iC(a,e),$.debug(`[VideoFramePreflight] Cannot create stream from track, skipping preflight`),{elapsedMs:r.performanceNow()-i};let s=await aC(o,t,r),c=r.performanceNow()-i;if($.debug(`[VideoFramePreflight] Completed`,{elapsedMs:c,timedOut:s===null}),s===null){await o.cancel().catch(()=>void 0),iC(a,e);let n=Error(`Video stream failed to yield first frame within ${t}ms`);throw n.code=eC,n.elapsedMs=c,n}return s.frame.close(),s.reader.releaseLock(),o.cancel().catch(()=>void 0),iC(a,e),{elapsedMs:c}}function rC(e){return typeof e.clone==`function`?e.clone():e}function iC(e,t){e!==t&&e.stop()}async function aC(e,t,n){let r=e.getReader(),i,a=!1,o=()=>a?!1:(a=!0,i!==void 0&&n.clearTimeout(i),!0),s=new Promise(e=>{i=n.setTimeout(()=>{o()&&e(null)},t)}),c=r.read().then(({value:e,done:t})=>!o()||t||!e?null:{frame:e,reader:r}).catch(()=>(o(),null)),l=await Promise.race([c,s]);return l===null&&(await r.cancel().catch(()=>void 0),r.releaseLock()),l}function oC(e,t){if(e.length===0)return null;t.stopCurrentVideoTrack();let n=e[0];$S(n,{stage:`prepare-original-track`});let r=t.cloneVideoTrack(n);return $S(r,{stage:`prepare-cloned-track`}),t.setCurrentVideoTrack(r),r}function sC(e,t){if(e.length===0)return null;let n=e[0];return t.cloneAudioTrack(n)}function cC(e,t,n){if(!e)return{videoTrack:null,videoStream:null};if($S(e,{stage:`select-video-input`}),t.hasMediaStreamTrackProcessor)return{videoTrack:e,videoStream:null};let r=n.createVideoStreamFromTrack(e);if(r)return{videoTrack:null,videoStream:r};throw n.createBrowserUnsupportedError()}function lC(e){if(!e||typeof e.getSettings!=`function`)return;let t=e.getSettings(),n={};typeof t.width==`number`&&(n.width=t.width),typeof t.height==`number`&&(n.height=t.height),typeof t.facingMode==`string`&&(n.facingMode=t.facingMode);let r=t;return typeof r.rotation==`number`&&(n.rotation=r.rotation),n}function uC(e){return e.isMobileDevice()}function dC(e,t,n,r){r.logger.debug(`[WorkerProcessor] Track details`,{hasVideoTrack:!!e,hasVideoStream:!!n,videoTrackId:e?.id,videoTrackKind:e?.kind,videoTrackReadyState:e?.readyState,hasAudioTrack:!!t,audioTrackId:t?.id,audioTrackKind:t?.kind,audioTrackReadyState:t?.readyState})}function fC(e,t){if(!e||typeof e.getSettings!=`function`)return;let n=mC(e.getSettings()),r;typeof e.getCapabilities==`function`&&(r=hC(e.getCapabilities())),t.logger.debug(`[WorkerProcessor] Video track settings`,n),r&&t.logger.debug(`[WorkerProcessor] Video track capabilities`,r)}function pC(e){let t=e.getViewportMetadata();t&&e.logger.debug(`[WorkerProcessor] Viewport metadata`,t)}function mC(e){let t=e;return{width:e.width,height:e.height,frameRate:e.frameRate,aspectRatio:e.aspectRatio,facingMode:e.facingMode,resizeMode:t.resizeMode,deviceId:e.deviceId,groupId:e.groupId,rotation:t.rotation}}function hC(e){let t=e;return{width:e.width,height:e.height,frameRate:e.frameRate,aspectRatio:e.aspectRatio,facingMode:e.facingMode,resizeMode:t.resizeMode}}function gC(e){let{createWorker:t,workerUrl:n,onMessage:r,onError:i,logger:a}=e;a.debug(`[WorkerProcessor] Worker URL created`,{urlType:typeof n,isBlobUrl:n.startsWith(`blob:`)});let o=t(n);return a.debug(`[WorkerProcessor] Worker created successfully`),o.onmessage=r,o.onerror=i,a.debug(`[WorkerProcessor] Worker event handlers attached`),o}function _C(e){let{videoTrack:t,videoStream:n,audioStream:r,isMobileDevice:i,videoSettings:a,viewportMetadata:o,audioConfig:s,workerConfig:c,overlayConfig:l}=e;return{type:`start`,videoTrack:t,videoStream:n,audioStream:r,isMobileDevice:i,videoSettings:a,viewportMetadata:o,audioConfig:s,config:c,overlayConfig:l}}function vC(e,t){return{type:`switchSource`,videoTrack:e,videoStream:t}}function yC(e,t,n=null){let r=[];return e&&(r=[...r,e]),t&&(r=[...r,t]),n&&(r=[...r,n]),r}var bC=class{constructor(e){this.workerProbePromise=null,this.workerProbeResolve=null,this.workerProbeTimeoutId=null,this.workerProbeResult=null,this.dependencies=e}handleProbeResult(e){this.finalizeProbeResult(e)}async getProbeResult(e){if(this.workerProbeResult)return this.workerProbeResult;if(this.workerProbePromise)return await this.workerProbePromise;let t=new Promise(e=>{this.workerProbeResolve=e});return this.workerProbePromise=t,this.workerProbeTimeoutId=this.dependencies.setTimeout(()=>{let e=this.getEmptyProbeResult();this.finalizeProbeResult(e)},this.dependencies.timeoutMilliseconds),e.postMessage({type:By}),await t}finalizeProbeResult(e){this.workerProbeTimeoutId!==null&&(this.dependencies.clearTimeout(this.workerProbeTimeoutId),this.workerProbeTimeoutId=null),this.workerProbeResult=e,this.workerProbeResolve&&=(this.workerProbeResolve(e),null),this.workerProbePromise=null}getEmptyProbeResult(){return{type:Vy,hasMediaStreamTrackProcessor:!1,hasVideoFrame:!1,hasAudioData:!1,hasOffscreenCanvas:!1,hasCreateImageBitmap:!1,hasReadableStream:!1}}};function xC(){if(typeof Blob>`u`||typeof URL>`u`)throw Error(`Blob and URL APIs are required for worker loading`);return new Blob([`(() => {
242
+ registerProcessor("${HS}", VidtreoAudioWorkletProcessor);
243
+ `;function JS(){if(typeof Blob>`u`||typeof URL>`u`)throw Error(`Blob and URL APIs are required for audio worklet loading`);return new Blob([qS],{type:`application/javascript`})}let YS=VS({createBlob:JS,createObjectUrl:e=>URL.createObjectURL(e),revokeObjectUrl:e=>{URL.revokeObjectURL(e)}});var XS=class{constructor(){this.audioContext=null,this.audioWorkletNode=null,this.audioSourceNode=null,this.audioDestinationNode=null,this.audioConfig=null,this.onAudioChunk=null,this.isMuted=!1,this.isPaused=!1,this.isProcessing=!1,this.hasAudioWorkletUrlLease=!1}async initialize(e,t){if(!e)throw Error(`Audio stream is required`);if(e.getAudioTracks().length===0)throw Error(`Audio stream has no tracks`);let n=a();if(!n)throw Error(`AudioContext is not supported in this browser`);this.onAudioChunk=t;try{let t=YS.acquire();this.hasAudioWorkletUrlLease=!0;let r=new n;this.audioContext=r,r.resume().catch(e=>{$.warn(`[AudioWorkletController] Failed to resume AudioContext`,i(e))}),await r.audioWorklet.addModule(t).catch(e=>{let t=i(e);throw Error(`Failed to load AudioWorklet module: ${t}`)});let a=new AudioWorkletNode(r,HS,{numberOfInputs:1,numberOfOutputs:1,outputChannelCount:[1]});a.port.onmessage=this.handleWorkletMessage.bind(this),this.audioWorkletNode=a,this.audioSourceNode=r.createMediaStreamSource(e),this.audioDestinationNode=r.createGain(),this.audioDestinationNode.gain.value=0;let o={sampleRate:r.sampleRate,numberOfChannels:1,format:`f32-planar`};return this.audioConfig=o,this.setMuted(this.isMuted),this.setPaused(this.isPaused),o}catch(e){throw await this.cleanupAfterInitializeFailure(),this.normalizeInitializationError(e)}}async startProcessing(){if(!this.isProcessing){if(!this.audioContext)throw Error(`AudioContext is not initialized`);if(!this.audioWorkletNode)throw Error(`AudioWorklet node is not initialized`);if(!this.audioSourceNode)throw Error(`Audio source node is not initialized`);if(!this.audioDestinationNode)throw Error(`AudioWorklet graph is not initialized`);this.audioSourceNode.connect(this.audioWorkletNode),this.audioWorkletNode.connect(this.audioDestinationNode),this.audioDestinationNode.connect(this.audioContext.destination),await this.audioContext.resume(),this.isProcessing=!0}}setMuted(e){this.isMuted=e,this.audioWorkletNode&&this.audioWorkletNode.port.postMessage({type:WS,isMuted:e})}setPaused(e){this.isPaused=e,this.audioWorkletNode&&this.audioWorkletNode.port.postMessage({type:GS,isPaused:e})}close(){this.disconnectAudioNodes(!0),this.closeAudioContext(),this.audioConfig=null,this.onAudioChunk=null,this.isMuted=!1,this.isPaused=!1,this.isProcessing=!1,this.releaseAudioWorkletUrlLease()}getConfig(){return this.audioConfig}handleWorkletMessage(e){let t=e.data;if(!t||t.type!==US)return;let n=this.parseAudioBuffer(t.data);if(!n||!this.onAudioChunk)return;let r={data:n,frames:t.frames,numberOfChannels:t.numberOfChannels,sampleRate:t.sampleRate,timestamp:t.timestamp,inputPeak:t.inputPeak,inputRms:t.inputRms};this.onAudioChunk(r)}parseAudioBuffer(e){return e instanceof Float32Array?e:e instanceof ArrayBuffer?new Float32Array(e):null}async cleanupAfterInitializeFailure(){this.disconnectAudioNodes(!1),await this.closeAudioContext(),this.audioConfig=null,this.onAudioChunk=null,this.releaseAudioWorkletUrlLease()}normalizeInitializationError(e){if(e instanceof Error)return e;let t=i(e);return Error(t)}disconnectAudioNodes(e){this.audioWorkletNode&&=(e&&this.audioWorkletNode.port.postMessage({type:KS}),this.audioWorkletNode.disconnect(),null),this.audioSourceNode&&=(this.audioSourceNode.disconnect(),null),this.audioDestinationNode&&=(this.audioDestinationNode.disconnect(),null)}closeAudioContext(){if(!this.audioContext)return Promise.resolve();let e=this.audioContext;return this.audioContext=null,e.close().catch(e=>{$.warn(`[AudioWorkletController] Failed to close AudioContext`,i(e))})}releaseAudioWorkletUrlLease(){this.hasAudioWorkletUrlLease&&=(YS.release(),!1)}},ZS=class{constructor(e){this.audioWorkletController=null,this.audioWorkletConfig=null,this.onChunk=e.onChunk;let t=()=>new XS;e.createController&&(t=e.createController),this.createController=t}async prepareAudioConfig(e){if(!e)return this.audioWorkletConfig=null,null;this.audioWorkletController||=this.createController();let t=new MediaStream([e]);return this.audioWorkletConfig=await this.audioWorkletController.initialize(t,e=>this.onChunk(e)).catch(e=>{throw this.stop(),e}),this.createWorkerAudioConfig(this.audioWorkletConfig)}async startProcessing(){this.audioWorkletController&&await this.audioWorkletController.startProcessing()}stop(){this.audioWorkletController&&=(this.audioWorkletController.close(),null),this.audioWorkletConfig=null}setMuted(e){this.audioWorkletController&&this.audioWorkletController.setMuted(e)}setPaused(e){this.audioWorkletController&&this.audioWorkletController.setPaused(e)}createWorkerAudioConfig(e){return e?{sampleRate:e.sampleRate,numberOfChannels:e.numberOfChannels,format:e.format}:null}};let QS=`recording.video-track-ended`;function $S(e={}){let t=Error(`Video track ended before recording could start [${QS}]`);return t.code=QS,t.isRecoverable=!0,t.details=e,t}function eC(e,t={}){if(e.readyState!==`live`)throw $S({...t,trackId:e.id,readyState:e.readyState})}let tC=`video.first-frame-timeout`,nC={createVideoStreamFromTrack:e=>typeof MediaStreamTrackProcessor>`u`?null:(eC(e,{stage:`preflight-stream-create`}),new MediaStreamTrackProcessor({track:e}).readable),setTimeout:(e,t)=>window.setTimeout(e,t),clearTimeout:e=>window.clearTimeout(e),performanceNow:()=>performance.now()};async function rC(e,t=3e3,n={}){let r={createVideoStreamFromTrack:n.createVideoStreamFromTrack??nC.createVideoStreamFromTrack,setTimeout:n.setTimeout??nC.setTimeout,clearTimeout:n.clearTimeout??nC.clearTimeout,performanceNow:n.performanceNow??nC.performanceNow},i=r.performanceNow();eC(e,{stage:`preflight-original-track`});let a=iC(e);eC(a,{stage:`preflight-cloned-track`});let o=r.createVideoStreamFromTrack(a);if(!o)return aC(a,e),$.debug(`[VideoFramePreflight] Cannot create stream from track, skipping preflight`),{elapsedMs:r.performanceNow()-i};let s=await oC(o,t,r),c=r.performanceNow()-i;if($.debug(`[VideoFramePreflight] Completed`,{elapsedMs:c,timedOut:s===null}),s===null){await o.cancel().catch(()=>void 0),aC(a,e);let n=Error(`Video stream failed to yield first frame within ${t}ms`);throw n.code=tC,n.elapsedMs=c,n}return s.frame.close(),s.reader.releaseLock(),o.cancel().catch(()=>void 0),aC(a,e),{elapsedMs:c}}function iC(e){return typeof e.clone==`function`?e.clone():e}function aC(e,t){e!==t&&e.stop()}async function oC(e,t,n){let r=e.getReader(),i,a=!1,o=()=>a?!1:(a=!0,i!==void 0&&n.clearTimeout(i),!0),s=new Promise(e=>{i=n.setTimeout(()=>{o()&&e(null)},t)}),c=r.read().then(({value:e,done:t})=>!o()||t||!e?null:{frame:e,reader:r}).catch(()=>(o(),null)),l=await Promise.race([c,s]);return l===null&&(await r.cancel().catch(()=>void 0),r.releaseLock()),l}function sC(e,t){if(e.length===0)return null;t.stopCurrentVideoTrack();let n=e[0];eC(n,{stage:`prepare-original-track`});let r=t.cloneVideoTrack(n);return eC(r,{stage:`prepare-cloned-track`}),t.setCurrentVideoTrack(r),r}function cC(e,t){if(e.length===0)return null;let n=e[0];return t.cloneAudioTrack(n)}function lC(e,t,n){if(!e)return{videoTrack:null,videoStream:null};if(eC(e,{stage:`select-video-input`}),t.hasMediaStreamTrackProcessor)return{videoTrack:e,videoStream:null};let r=n.createVideoStreamFromTrack(e);if(r)return{videoTrack:null,videoStream:r};throw n.createBrowserUnsupportedError()}function uC(e){if(!e||typeof e.getSettings!=`function`)return;let t=e.getSettings(),n={};typeof t.width==`number`&&(n.width=t.width),typeof t.height==`number`&&(n.height=t.height),typeof t.facingMode==`string`&&(n.facingMode=t.facingMode);let r=t;return typeof r.rotation==`number`&&(n.rotation=r.rotation),n}function dC(e){return e.isMobileDevice()}function fC(e,t,n,r){r.logger.debug(`[WorkerProcessor] Track details`,{hasVideoTrack:!!e,hasVideoStream:!!n,videoTrackId:e?.id,videoTrackKind:e?.kind,videoTrackReadyState:e?.readyState,hasAudioTrack:!!t,audioTrackId:t?.id,audioTrackKind:t?.kind,audioTrackReadyState:t?.readyState})}function pC(e,t){if(!e||typeof e.getSettings!=`function`)return;let n=hC(e.getSettings()),r;typeof e.getCapabilities==`function`&&(r=gC(e.getCapabilities())),t.logger.debug(`[WorkerProcessor] Video track settings`,n),r&&t.logger.debug(`[WorkerProcessor] Video track capabilities`,r)}function mC(e){let t=e.getViewportMetadata();t&&e.logger.debug(`[WorkerProcessor] Viewport metadata`,t)}function hC(e){let t=e;return{width:e.width,height:e.height,frameRate:e.frameRate,aspectRatio:e.aspectRatio,facingMode:e.facingMode,resizeMode:t.resizeMode,deviceId:e.deviceId,groupId:e.groupId,rotation:t.rotation}}function gC(e){let t=e;return{width:e.width,height:e.height,frameRate:e.frameRate,aspectRatio:e.aspectRatio,facingMode:e.facingMode,resizeMode:t.resizeMode}}function _C(e){let{createWorker:t,workerUrl:n,onMessage:r,onError:i,logger:a}=e;a.debug(`[WorkerProcessor] Worker URL created`,{urlType:typeof n,isBlobUrl:n.startsWith(`blob:`)});let o=t(n);return a.debug(`[WorkerProcessor] Worker created successfully`),o.onmessage=r,o.onerror=i,a.debug(`[WorkerProcessor] Worker event handlers attached`),o}function vC(e){let{videoTrack:t,videoStream:n,audioStream:r,isMobileDevice:i,videoSettings:a,viewportMetadata:o,audioConfig:s,workerConfig:c,overlayConfig:l}=e;return{type:`start`,videoTrack:t,videoStream:n,audioStream:r,isMobileDevice:i,videoSettings:a,viewportMetadata:o,audioConfig:s,config:c,overlayConfig:l}}function yC(e,t){return{type:`switchSource`,videoTrack:e,videoStream:t}}function bC(e,t,n=null){let r=[];return e&&(r=[...r,e]),t&&(r=[...r,t]),n&&(r=[...r,n]),r}var xC=class{constructor(e){this.workerProbePromise=null,this.workerProbeResolve=null,this.workerProbeTimeoutId=null,this.workerProbeResult=null,this.dependencies=e}handleProbeResult(e){this.finalizeProbeResult(e)}async getProbeResult(e){if(this.workerProbeResult)return this.workerProbeResult;if(this.workerProbePromise)return await this.workerProbePromise;let t=new Promise(e=>{this.workerProbeResolve=e});return this.workerProbePromise=t,this.workerProbeTimeoutId=this.dependencies.setTimeout(()=>{let e=this.getEmptyProbeResult();this.finalizeProbeResult(e)},this.dependencies.timeoutMilliseconds),e.postMessage({type:Vy}),await t}finalizeProbeResult(e){this.workerProbeTimeoutId!==null&&(this.dependencies.clearTimeout(this.workerProbeTimeoutId),this.workerProbeTimeoutId=null),this.workerProbeResult=e,this.workerProbeResolve&&=(this.workerProbeResolve(e),null),this.workerProbePromise=null}getEmptyProbeResult(){return{type:Hy,hasMediaStreamTrackProcessor:!1,hasVideoFrame:!1,hasAudioData:!1,hasOffscreenCanvas:!1,hasCreateImageBitmap:!1,hasReadableStream:!1}}};function SC(){if(typeof Blob>`u`||typeof URL>`u`)throw Error(`Blob and URL APIs are required for worker loading`);return new Blob([`(() => {
244
244
  var __create = Object.create;
245
245
  var __getProtoOf = Object.getPrototypeOf;
246
246
  var __defProp = Object.defineProperty;
@@ -12826,7 +12826,7 @@ Mediabunny was loaded twice.\` + " This will likely cause Mediabunny not to work
12826
12826
  initializeRecorderWorker();
12827
12827
  }
12828
12828
  })();
12829
- `],{type:`application/javascript`})}let SC=BS({createBlob:xC,createObjectUrl:e=>URL.createObjectURL(e),revokeObjectUrl:e=>{URL.revokeObjectURL(e)}});function CC(){return SC.acquire()}function wC(){SC.release()}let TC=1e3,EC=`format`,DC=new Map,OC=new Map;function kC(e){return e===void 0?`undefined`:String(e)}function AC(e){return e.join(`,`)}function jC(e,t){return`${e}=${t}`}function MC(e,t,n){if(e.has(t)&&e.delete(t),e.set(t,n),e.size<=50)return;let r=e.keys().next();r.done||e.delete(r.value)}var NC=class{constructor(e={}){this.worker=null,this.hasWorkerUrlLease=!1,this.chunks=[],this.totalSize=0,this.isActive=!1,this.audioTrackClone=null,this.audioTrackWarningTarget=null,this.isMuted=!1,this.currentVideoTrack=null,this.isPaused=!1,this.overlayConfig=null,this.readyPromiseResolve=null,this.readyPromiseReject=null,this.lastConfigFps=30,this.pendingFatalError=null,this.lastRecordingStats=null,this.audioWasExpected=!1,this.lastEncoderAcceleration=null,this.audioHealthMonitor=new LS,this.audioHealthIntervalId=null,this.emittedAudioWarnings=new Set,this.audioTrackEndedDuringSession=!1,this.recordingStartTimestampMs=null,this.noFrameWatchdogId=null,this.handleAudioTrackEnded=()=>{this.audioTrackEndedDuringSession=!0,this.emitAudioWarningOnce({code:`audio.track-ended`})},this.handleAudioTrackMuted=()=>{this.emitAudioWarningOnce({code:`audio.track-muted-by-browser`})},this.handleAudioTrackUnmuted=()=>{this.emittedAudioWarnings.delete(`audio.track-muted-by-browser`)&&this.onAudioRecovered&&this.onAudioRecovered()};let t=e=>new Worker(e,{type:`classic`});e.createWorker&&(t=e.createWorker);let n=e=>typeof MediaStreamTrackProcessor>`u`?null:($S(e,{stage:`main-thread-stream-create`}),new MediaStreamTrackProcessor({track:e}).readable);e.createVideoStreamFromTrack&&(n=e.createVideoStreamFromTrack);let r=()=>on();e.isLinuxPlatform&&(r=e.isLinuxPlatform),this.createVideoStreamFromTrackFn=n,this.isLinuxPlatformFn=r,e.videoFramePreflightDeps?this.videoFramePreflightDeps=e.videoFramePreflightDeps:this.videoFramePreflightDeps={},e.noFrameWatchdogDelayMs===void 0?this.watchdogDelayMs=5e3:this.watchdogDelayMs=e.noFrameWatchdogDelayMs;let i=!!e.createWorker;this.workerProbeManager=new bC({setTimeout:window.setTimeout.bind(window),clearTimeout:window.clearTimeout.bind(window),timeoutMilliseconds:2e3}),this.audioWorkletManager=new XS({onChunk:this.handleAudioWorkletChunk.bind(this)});let a=e=>{let t=e.data;switch(t.type){case`ready`:this.readyPromiseResolve&&(this.readyPromiseResolve(),this.readyPromiseResolve=null,this.readyPromiseReject=null);break;case Vy:this.workerProbeManager.handleProbeResult(t);break;case`debugLog`:t.payload?$.debug(t.message,t.payload):$.debug(t.message);break;case`error`:if($.error(`[WorkerProcessor] Worker error:`,t.error),this.readyPromiseReject){let e=this.readyPromiseReject;this.readyPromiseReject=null,this.readyPromiseResolve=null,e(Error(t.error));break}this.onError&&this.onError(Error(t.error));break;case`chunk`:this.chunks.push({data:t.data,position:t.position}),this.totalSize=Math.max(this.totalSize,t.position+t.data.length);break;case`bufferUpdate`:this.onBufferUpdate&&this.onBufferUpdate(t.size,t.formatted);break;case`stateChange`:$.debug(`[WorkerProcessor] State changed:`,t.state),this.isPaused=t.state===`paused`;break;case`fatalError`:if(this.readyPromiseReject){let e=this.readyPromiseReject;this.readyPromiseReject=null,this.readyPromiseResolve=null,e(Error(`${t.message} [${t.code}]`));break}this.pendingFatalError=t;break;case`recordingStats`:this.lastRecordingStats=t,this.handleNoFrameWatchdogStats(t);break;case`encoderAcceleration`:this.lastEncoderAcceleration=t.acceleration,$.info(`[WorkerProcessor] Encoder acceleration resolved`,{acceleration:t.acceleration});break;default:$.warn(`[WorkerProcessor] Unknown response type:`,t)}},o=e=>{if($.error(`[WorkerProcessor] Worker error event:`,{message:e.message,filename:e.filename,lineno:e.lineno,colno:e.colno,error:e.error}),this.readyPromiseReject){let t=this.readyPromiseReject;this.readyPromiseReject=null,this.readyPromiseResolve=null,t(Error(e.message||`Unknown worker error`));return}if(this.onError){let t=e.message;t||=`Unknown worker error`,this.onError(Error(t))}},s=typeof Worker<`u`,c=!1;if(s&&(c=!0),i&&(c=!0),!c)throw $.error(`[WorkerProcessor] Web Workers are not supported`),Error(`Web Workers are not supported`);let l=CC();this.hasWorkerUrlLease=!0;try{this.worker=gC({createWorker:t,workerUrl:l,onMessage:a,onError:o,logger:$})}catch(e){throw this.releaseWorkerUrlLease(),e}}prewarm(){this.worker&&this.workerProbeManager.getProbeResult(this.worker).catch(()=>void 0)}getWorkerProbeResult(){let e=this.getWorkerOrThrow();return this.workerProbeManager.getProbeResult(e)}async startProcessing(e,t,n){this.getWorkerOrThrow(),this.ensureProcessingInactive(),this.resetProcessingState(n),this.stopAudioWorklet(),this.audioWorkletManager=new XS({onChunk:this.handleAudioWorkletChunk.bind(this)});let r=this.resolveRecordingFormat(t),i=Ht(r,{isLinuxPlatform:this.isLinuxPlatformFn()}),a=this.resolveAudioBitrate(t,r),o=await this.resolveAudioCodecWithCache(t,r,i,a),s=await this.resolveVideoCodecWithCache(t,r,i),c=RS(e);$.debug(`[WorkerProcessor] Starting processing`,{isScreenCapture:c,fps:t.fps,codec:s,bitrate:t.bitrate});let l=this.buildWorkerTranscodeConfig(t,o,a,s,r);typeof t.fps==`number`&&t.fps>0&&(this.lastConfigFps=t.fps);let u=e.getVideoTracks(),d=e.getAudioTracks();$.debug(`[WorkerProcessor] Preparing to start processing`,{videoTracksCount:u.length,audioTracksCount:d.length,hasWorker:!!this.worker});try{let e=this.getVideoInputSelectorDependencies(),t=oC(u,e),n=sC(d,e),r=await this.getWorkerProbeResult();t&&($.debug(`[WorkerProcessor] Running video first-frame preflight`),await nC(t,3e3,this.videoFramePreflightDeps),$.debug(`[WorkerProcessor] Video first-frame preflight passed`));let i=cC(t,r,e),a=uC(e),o=lC(t);fC(t,e),pC(e),dC(t,n,i.videoStream,e);let s=e.getViewportMetadata(),c;s&&(c={orientationAngle:s.orientationAngle,windowOrientation:s.windowOrientation});let{audioConfig:f,audioStream:p,shouldStartAudioWorklet:m}=await this.prepareAudioPipeline(n,r),h=this.buildOverlayConfigToSend(),g=_C({videoTrack:i.videoTrack,videoStream:i.videoStream,audioStream:p,isMobileDevice:a,videoSettings:o,viewportMetadata:c,audioConfig:f,workerConfig:l,overlayConfig:h}),_=yC(i.videoStream,p,i.videoTrack);$.debug(`[WorkerProcessor] Posting message to worker`,{transferablesCount:_.length,messageType:g.type}),await this.postStartMessage(g,_,m),this.startNoFrameWatchdog(),m&&this.startAudioHealthMonitoring()}catch(e){throw this.resetStartProcessingStateAfterFailure(),e}}getWorkerOrThrow(){if(!this.worker)throw Error(`Worker not initialized`);return this.worker}ensureProcessingInactive(){if(this.isActive)throw Error(`Processing already active`)}handleAudioWorkletChunk(e){if(!(this.isWorkerActive()&&this.worker))return;this.recordAudioHealthChunk(e);let t={type:`audioChunk`,data:e.data,frames:e.frames,numberOfChannels:e.numberOfChannels,sampleRate:e.sampleRate,timestamp:e.timestamp},n=[];e.data.buffer instanceof ArrayBuffer&&n.push(e.data.buffer),this.worker.postMessage(t,n)}resetProcessingState(e){this.isActive=!0,this.isMuted=!1,this.isPaused=!1,this.chunks=[],this.totalSize=0,this.audioWasExpected=!1,this.audioHealthMonitor.reset(),this.emittedAudioWarnings=new Set,this.audioTrackEndedDuringSession=!1,this.recordingStartTimestampMs=performance.now(),this.pendingFatalError=null,this.lastRecordingStats=null,this.lastEncoderAcceleration=null,this.stopAudioHealthMonitoring(),this.stopNoFrameWatchdog(),e?this.overlayConfig=e:this.overlayConfig=null}resetStartProcessingStateAfterFailure(){this.isActive=!1,this.isPaused=!1,this.stopAudioHealthMonitoring(),this.stopNoFrameWatchdog(),this.stopAudioWorklet(),this.detachAudioTrackWarnings(),this.stopCurrentVideoTrack(),this.pendingFatalError=null,this.lastRecordingStats=null,this.lastEncoderAcceleration=null}recordAudioHealthChunk(e){let t=this.audioHealthMonitor.recordChunk({samples:e.data,timestampMs:performance.now(),isMuted:this.isMuted,inputPeak:e.inputPeak,inputRms:e.inputRms});this.emitAudioWarning(t.classification,{durationMs:Math.max(t.consecutiveSilentDurationMs,t.consecutiveLowSignalDurationMs,t.consecutiveMutedSpeechDurationMs),peak:t.inputPeak,rms:t.inputRms})}startAudioHealthMonitoring(){this.stopAudioHealthMonitoring(),this.audioHealthIntervalId=window.setInterval(()=>{if(!this.isActive)return;let e=this.audioHealthMonitor.inspect(performance.now(),this.isMuted);this.emitAudioWarning(e.classification,{durationMs:Math.max(e.noChunkDurationMs,e.consecutiveSilentDurationMs,e.consecutiveLowSignalDurationMs,e.consecutiveMutedSpeechDurationMs),peak:e.inputPeak,rms:e.inputRms})},1e3)}stopAudioHealthMonitoring(){this.audioHealthIntervalId!==null&&(window.clearInterval(this.audioHealthIntervalId),this.audioHealthIntervalId=null)}startNoFrameWatchdog(){this.stopNoFrameWatchdog(),this.noFrameWatchdogId=window.setTimeout(()=>{this.noFrameWatchdogId=null,this.isWorkerActive()&&this.worker&&this.worker.postMessage({type:`requestStats`})},this.watchdogDelayMs)}stopNoFrameWatchdog(){this.noFrameWatchdogId!==null&&(window.clearTimeout(this.noFrameWatchdogId),this.noFrameWatchdogId=null)}handleNoFrameWatchdogStats(e){if(!this.isActive||e.videoFrameCount>0)return;$.error(`[WorkerProcessor] No video frames received after watchdog delay`,{videoFrameCount:e.videoFrameCount,totalFrameErrors:e.totalFrameErrors,totalFramesProcessed:e.totalFramesProcessed});let t=Error(`No video frames received after ${this.watchdogDelayMs/TC}s — video stream may be unresponsive [${eC}]`);this.onError&&this.onError(t),this.cancel()}emitAudioWarning(e,t){if(e===`healthy`){let e=this.emittedAudioWarnings.size>0;this.emittedAudioWarnings.clear(),e&&this.onAudioRecovered&&this.onAudioRecovered();return}if(e===`muted-silence-expected`){let e=!1;this.emittedAudioWarnings.delete(`audio.no-signal`)&&(e=!0),this.emittedAudioWarnings.delete(`audio.no-chunks`)&&(e=!0),this.emittedAudioWarnings.delete(`audio.low-signal`)&&(e=!0),this.emittedAudioWarnings.delete(`audio.speaking-while-muted`)&&(e=!0),e&&this.onAudioRecovered&&this.onAudioRecovered();return}let n=this.createAudioWarning(e,t);n&&this.emitAudioWarningOnce(n)}emitAudioWarningOnce(e){this.onAudioWarning&&(this.emittedAudioWarnings.has(e.code)||(this.emittedAudioWarnings.add(e.code),this.onAudioWarning(e)))}createAudioWarning(e,t){return e===`no-chunks`?{code:`audio.no-chunks`,durationMs:t.durationMs}:e===`silent-while-unmuted`?{code:`audio.no-signal`,durationMs:t.durationMs}:e===`low-signal`?{code:`audio.low-signal`,peak:t.peak,rms:t.rms}:e===`speaking-while-muted`?{code:`audio.speaking-while-muted`,durationMs:t.durationMs,peak:t.peak,rms:t.rms}:null}assertRuntimeAudioHealth(){let e=performance.now(),t=this.recordingStartTimestampMs??e,n=Math.max(0,e-t),r=this.audioHealthMonitor.getFinalSnapshot(e,this.isMuted),i=xb({totalChunks:r.totalChunks,nonSilentChunks:r.nonSilentChunks,mutedDurationMs:r.mutedDurationMs,durationMs:n,hadTrackEndedWarning:this.audioTrackEndedDuringSession});if(!i.ok)throw vb(i.code,{totalChunks:r.totalChunks,nonSilentChunks:r.nonSilentChunks,mutedDurationMs:r.mutedDurationMs,durationMs:n,hadTrackEndedWarning:this.audioTrackEndedDuringSession})}resolveRecordingFormat(e){let t=e.format;return t||=`mp4`,t}resolveAudioBitrate(e,t){return e.audioBitrate===void 0?Kt(t):e.audioBitrate}async resolveAudioCodec(e,t,n,r){return await ny({format:t,overrideCodec:e.audioCodec,policy:n,bitrate:r})}async resolveVideoCodec(e,t,n){return await ty({format:t,overrideCodec:e.codec,policy:n,width:e.width,height:e.height,bitrate:e.bitrate})}async resolveAudioCodecWithCache(e,t,n,r){let i=this.buildAudioCodecCacheKey(e,t,n,r),a=DC.get(i);if(a)return a;let o=await this.resolveAudioCodec(e,t,n,r);return MC(DC,i,o),o}async resolveVideoCodecWithCache(e,t,n){let r=this.buildVideoCodecCacheKey(e,t,n),i=OC.get(r);if(i)return i;let a=await this.resolveVideoCodec(e,t,n);return MC(OC,r,a),a}buildAudioCodecCacheKey(e,t,n,r){let i=kC(e.audioCodec),a=kC(n.preferredAudioCodec),o=AC(n.audioCodecFallbackOrder),s=kC(r);return[jC(EC,kC(t)),jC(`audioOverride`,i),jC(`audioBitrate`,s),jC(`policyPreferredAudio`,a),jC(`policyAudioFallback`,o)].join(`|`)}buildVideoCodecCacheKey(e,t,n){let r=kC(e.codec),i=kC(e.width),a=kC(e.height),o=kC(e.bitrate),s=kC(n.preferredVideoCodec),c=AC(n.videoCodecFallbackOrder);return[jC(EC,kC(t)),jC(`videoOverride`,r),jC(`width`,i),jC(`height`,a),jC(`videoBitrate`,o),jC(`policyPreferredVideo`,s),jC(`policyVideoFallback`,c)].join(`|`)}buildWorkerTranscodeConfig(e,t,n,r,i){return{width:e.width,height:e.height,fps:e.fps,bitrate:zS(e.bitrate),audioCodec:t,audioBitrate:n,codec:r,keyFrameInterval:5,latencyMode:e.latencyMode,format:i,watermark:e.watermark}}async prepareAudioPipeline(e,t){if(!e)return $.debug(`[WorkerProcessor] Audio pipeline disabled (no track)`),{audioConfig:null,audioStream:null,shouldStartAudioWorklet:!1};let n=await this.prepareAudioConfig(e);if(!n)throw this.createBrowserUnsupportedError();return $.debug(`[WorkerProcessor] Audio pipeline selected`,{path:`audio-worklet-chunks`,sampleRate:n.sampleRate,numberOfChannels:n.numberOfChannels}),{audioConfig:n,audioStream:null,shouldStartAudioWorklet:!0}}buildOverlayConfigToSend(){if(this.overlayConfig)return this.overlayConfig}async postStartMessage(e,t,n){let r=this.getWorkerOrThrow(),i=new Promise((e,t)=>{this.readyPromiseResolve=e,this.readyPromiseReject=t});try{r.postMessage(e,t),$.debug(`[WorkerProcessor] Message posted successfully`),await i,$.debug(`[WorkerProcessor] Worker confirmed ready`),n&&(this.audioWasExpected=!0,await this.startAudioWorkletProcessing())}catch(e){throw $.error(`[WorkerProcessor] Failed to post message:`,e),this.readyPromiseResolve=null,this.readyPromiseReject=null,this.stopNoFrameWatchdog(),this.stopAudioWorklet(),this.worker&&this.isActive&&this.worker.postMessage({type:`stop`}),this.isActive=!1,e}}pause(){this.worker&&this.isActive&&(this.worker.postMessage({type:`pause`}),this.setAudioWorkletPaused(!0))}resume(){this.isWorkerActive()&&this.worker&&(this.worker.postMessage({type:`resume`}),this.setAudioWorkletPaused(!1))}isWorkerActive(){return!!(this.worker&&this.isActive)}toggleMute(){this.isMuted=!this.isMuted,this.onMuteStateChange&&this.onMuteStateChange(this.isMuted),this.isWorkerActive()&&this.worker&&this.worker.postMessage({type:`toggleMute`}),this.setAudioWorkletMuted(this.isMuted)}async switchVideoSource(e){if(!(this.isWorkerActive()&&this.worker))return $.debug(`[WorkerProcessor] Cannot switch source - worker not active`,{hasWorker:!!this.worker,isActive:this.isActive}),Promise.resolve();let t=e.getVideoTracks();if($.debug(`[WorkerProcessor] Switching video source`,{videoTracksCount:t.length}),t.length===0)return $.warn(`[WorkerProcessor] No video tracks in new stream`),Promise.resolve();let n=RS(e),r=this.lastConfigFps;$.debug(`[WorkerProcessor] Source type detected`,{isScreenCapture:n,targetFps:r});let i={type:`updateFps`,fps:r};this.worker.postMessage(i);let a={type:`updateSourceType`,isScreenCapture:n};this.worker.postMessage(a);let o=this.getVideoInputSelectorDependencies(),s=oC(t,o);if(!s)return $.warn(`[WorkerProcessor] Unable to prepare video track`),Promise.resolve();$.debug(`[WorkerProcessor] New video track details`,{trackId:s.id,trackKind:s.kind,trackReadyState:s.readyState});let c=cC(s,await this.getWorkerProbeResult(),o),l=vC(c.videoTrack,c.videoStream),u=yC(c.videoStream,null,c.videoTrack);try{return $.debug(`[WorkerProcessor] Posting switch source message`),this.worker.postMessage(l,u),$.debug(`[WorkerProcessor] Switch source message posted`),new Promise(e=>{setTimeout(()=>{e()},0)})}catch(e){throw $.error(`[WorkerProcessor] Failed to switch source:`,e),e}}finalize(){if(!this.isWorkerActive())throw Ex(wx,`Recording is not ready to finalize`,{hasWorker:!!this.worker,isActive:this.isActive});let e=performance.now();return new Promise((t,n)=>{let r=this.worker;if(!r){n(Error(`Worker not initialized`));return}let i=null,a=()=>{i!==null&&(clearTimeout(i),i=null)},o=()=>{r.removeEventListener(`message`,l)},s=!1,c=()=>s?!1:(s=!0,a(),o(),!0),l=r=>{if(s)return;let i=r.data;if(i.type===`fatalError`){this.pendingFatalError=i;return}if(i.type===`recordingStats`){this.lastRecordingStats=i;return}if(i.type===`stateChange`&&i.state===`stopped`){this.handleFinalizeStopped(c,t,n,e);return}i.type===`error`&&this.handleFinalizeError(c,n,i.error,e)};i=setTimeout(()=>{if(!c())return;$.error(`[WorkerProcessor] Finalize timeout reached`,{elapsedSeconds:(performance.now()-e)/TC,recordingStats:this.buildRecordingStatsSummary(this.lastRecordingStats)});let t=this.lastRecordingStats;this.resetFinalizeRuntimeState(),n(Ex(Tx,this.buildFinalizeTimeoutMessage(t),{recordingStats:this.buildRecordingStatsSummary(t)}))},3e4),r.addEventListener(`message`,l),r.postMessage({type:`requestStats`}),r.postMessage({type:`stop`})})}handleFinalizeStopped(e,t,n,r){let i=this.lastRecordingStats,a=this.lastEncoderAcceleration;if(this.pendingFatalError!==null){let t=this.pendingFatalError;if(!e())return;this.resetFinalizeRuntimeState(),n(Error(this.buildFatalFinalizeErrorMessage(t,i)));return}e()&&(this.resetFinalizeRuntimeState(),Promise.resolve().then(()=>this.createBlobFromChunks(i,a)).then(e=>{t(e)},e=>{this.rejectFinalizeBlobCreationError(n,e,r)}))}handleFinalizeError(e,t,n,r){e()&&(this.resetFinalizeRuntimeState(),$.error(`[WorkerProcessor] Finalize failed`,{elapsedSeconds:(performance.now()-r)/TC,error:n}),t(Error(n)))}buildFatalFinalizeErrorMessage(e,t){return t===null?`${e.message} [${e.code}]`:`${e.message} [${e.code}] frames=${t.videoFrameCount} errors=${t.totalFrameErrors}`}buildFinalizeTimeoutMessage(e){return e===null?`Finalize timeout`:`Finalize timeout frames=${e.videoFrameCount} errors=${e.totalFrameErrors} processed=${e.totalFramesProcessed}`}buildRecordingStatsSummary(e){return e===null?null:{videoFrameCount:e.videoFrameCount,totalFrameErrors:e.totalFrameErrors,totalFramesProcessed:e.totalFramesProcessed}}resetFinalizeRuntimeState(){this.isActive=!1,this.stopAudioHealthMonitoring(),this.stopNoFrameWatchdog(),this.stopAudioWorklet(),this.detachAudioTrackWarnings(),this.pendingFatalError=null,this.lastRecordingStats=null,this.lastEncoderAcceleration=null}createBlobFromChunks(e,t){let n=[...this.chunks].sort((e,t)=>e.position-t.position),r=new ArrayBuffer(this.totalSize),i=new Uint8Array(r);for(let e of n)i.set(e.data,e.position);Py(r),Fy(r),this.audioWasExpected&&(this.assertRuntimeAudioHealth(),Iy(r));let a={blob:new Blob([r],{type:`video/mp4`}),totalSize:this.totalSize};return e!==null&&(a.recordingStats={totalFrameErrors:e.totalFrameErrors,totalFramesProcessed:e.totalFramesProcessed,videoFrameCount:e.videoFrameCount}),t!==null&&(a.encoderAcceleration=t),a}rejectFinalizeBlobCreationError(e,t,n){if($.error(`[WorkerProcessor] Finalize failed while creating blob`,{elapsedSeconds:(performance.now()-n)/TC,error:i(t)}),t instanceof Error){e(t);return}e(Error(i(t)))}cancel(){return this.worker&&this.isActive&&this.worker.postMessage({type:`stop`}),this.stopAudioHealthMonitoring(),this.stopNoFrameWatchdog(),this.stopAudioWorklet(),this.detachAudioTrackWarnings(),this.isActive=!1,this.isPaused=!1,this.chunks=[],this.totalSize=0,this.audioWasExpected=!1,this.emittedAudioWarnings=new Set,this.audioTrackEndedDuringSession=!1,this.recordingStartTimestampMs=null,this.pendingFatalError=null,this.lastRecordingStats=null,this.lastEncoderAcceleration=null,Promise.resolve()}destroy(){this.worker&&=(this.worker.terminate(),null),this.releaseWorkerUrlLease(),this.stopAudioHealthMonitoring(),this.stopNoFrameWatchdog(),this.stopAudioWorklet(),this.detachAudioTrackWarnings(),this.isActive=!1,this.isPaused=!1,this.chunks=[],this.totalSize=0}cleanup(){this.destroy()}warmupEncoder(e){if(!this.worker)return;let t=e.format||`mp4`,n=Ht(t),r=e.codec||n.preferredVideoCodec,i=e.audioBitrate===void 0?n.audioBitrate:e.audioBitrate,a=Ht(t,{isLinuxPlatform:this.isLinuxPlatformFn()}),o=this.resolveAudioBitrate(e,t);this.resolveAudioCodecWithCache(e,t,a,o).catch(this.handleWarmupCacheError),this.resolveVideoCodecWithCache(e,t,a).catch(this.handleWarmupCacheError);let s={type:`warmup`,config:this.buildWorkerTranscodeConfig(e,n.preferredAudioCodec,i,r,t)};this.worker.postMessage(s)}getBufferSize(){return this.totalSize}getMutedState(){return this.isMuted}updateTabVisibility(e,t){if(!(this.isWorkerActive()&&this.worker)){$.warn(`[WorkerProcessor] Cannot update visibility - worker not active`,{isActive:this.isActive,hasWorker:!!this.worker});return}$.debug(`[WorkerProcessor] Sending visibility update to worker`,{isHidden:e,timestamp:t,timestampSeconds:t/TC});let n={type:`updateVisibility`,isHidden:e,timestamp:t};this.worker.postMessage(n)}updateSourceType(e){if(!(this.isWorkerActive()&&this.worker)){$.warn(`[WorkerProcessor] Cannot update source type - worker not active`,{isActive:this.isActive,hasWorker:!!this.worker});return}$.debug(`[WorkerProcessor] Sending source type update to worker`,{isScreenCapture:e});let t={type:`updateSourceType`,isScreenCapture:e};this.worker.postMessage(t)}async startAudioWorkletProcessing(){await this.audioWorkletManager.startProcessing()}stopAudioWorklet(){this.audioWorkletManager.stop()}setAudioWorkletMuted(e){this.audioWorkletManager.setMuted(e)}setAudioWorkletPaused(e){this.audioWorkletManager.setPaused(e)}prepareAudioConfig(e){return this.audioWorkletManager.prepareAudioConfig(e)}handleWarmupCacheError(){}createBrowserUnsupportedError(){return Nt({resolutionStage:`feature-preflight`})}getVideoInputSelectorDependencies(){return{stopCurrentVideoTrack:()=>this.stopCurrentVideoTrack(),cloneVideoTrack:e=>this.cloneVideoTrack(e),cloneAudioTrack:e=>this.cloneAudioTrack(e),setCurrentVideoTrack:e=>{this.currentVideoTrack=e},createVideoStreamFromTrack:e=>this.createVideoStreamFromTrackFn(e),createBrowserUnsupportedError:()=>this.createBrowserUnsupportedError(),getViewportMetadata:()=>{if(typeof window>`u`)return null;let e=window.screen,t,n,r,i;return e&&(i=e.orientation),i?.type&&(t=i.type),i&&typeof i.angle==`number`&&(n=i.angle),typeof window.orientation==`number`&&(r=window.orientation),{innerWidth:window.innerWidth,innerHeight:window.innerHeight,orientation:t,orientationAngle:n,windowOrientation:r}},logger:{debug:(e,t)=>$.debug(e,t),warn:(e,t)=>$.warn(e,t)},isMobileDevice:()=>Qt()}}isPausedState(){return this.isPaused}getClonedAudioTrack(){return this.audioTrackClone}getAudioStreamForAnalysis(){return this.audioTrackClone?new MediaStream([this.audioTrackClone]):null}setOnBufferUpdate(e){this.onBufferUpdate=e}setOnError(e){this.onError=e}setOnMuteStateChange(e){this.onMuteStateChange=e}setOnAudioWarning(e){this.onAudioWarning=e}setOnAudioRecovered(e){this.onAudioRecovered=e}cloneVideoTrack(e){if($.debug(`[WorkerProcessor] Original video track:`,{id:e.id,kind:e.kind,readyState:e.readyState,hasClone:typeof e.clone==`function`}),typeof e.clone==`function`)try{let t=e.clone();return $.debug(`[WorkerProcessor] Video track cloned successfully:`,{id:t.id,kind:t.kind,readyState:t.readyState}),t}catch(e){$.error(`[WorkerProcessor] Failed to clone video track:`,e);let t=i(e);throw Error(`Failed to clone video track: ${t}`)}return $.warn(`[WorkerProcessor] Video track clone() not available, using original`),e}attachAudioTrackWarnings(e){this.detachAudioTrackWarnings(),e.addEventListener(`ended`,this.handleAudioTrackEnded),e.addEventListener(`mute`,this.handleAudioTrackMuted),e.addEventListener(`unmute`,this.handleAudioTrackUnmuted),this.audioTrackWarningTarget=e}detachAudioTrackWarnings(){this.audioTrackWarningTarget&&=(this.audioTrackWarningTarget.removeEventListener(`ended`,this.handleAudioTrackEnded),this.audioTrackWarningTarget.removeEventListener(`mute`,this.handleAudioTrackMuted),this.audioTrackWarningTarget.removeEventListener(`unmute`,this.handleAudioTrackUnmuted),null)}cloneAudioTrack(e){if($.debug(`[WorkerProcessor] Original audio track:`,{id:e.id,kind:e.kind,readyState:e.readyState,hasClone:typeof e.clone==`function`}),typeof e.clone==`function`)try{let t=e.clone();return this.audioTrackClone=t,this.attachAudioTrackWarnings(t),$.debug(`[WorkerProcessor] Audio track cloned successfully:`,{id:t.id,kind:t.kind,readyState:t.readyState}),t}catch(e){$.error(`[WorkerProcessor] Failed to clone audio track:`,e);let t=i(e);throw Error(`Failed to clone audio track: ${t}`)}return $.warn(`[WorkerProcessor] Audio track clone() not available, using original`),this.audioTrackClone=e,this.attachAudioTrackWarnings(e),e}stopCurrentVideoTrack(){this.currentVideoTrack&&this.currentVideoTrack.readyState===`live`&&this.currentVideoTrack.stop(),this.currentVideoTrack=null}releaseWorkerUrlLease(){this.hasWorkerUrlLease&&=(wC(),!1)}},PC=class{constructor(e={}){this.currentVideoStream=null;let t=()=>new NC;e.workerProcessorFactory&&(t=e.workerProcessorFactory);try{this.workerProcessor=t(),$.debug(`[StreamProcessor] Using worker-based processing`)}catch(e){let t=i(e);throw Error(`Failed to initialize worker: ${t}`)}}async startProcessing(e,t,n){this.workerProcessor.setOnBufferUpdate((e,t)=>{$.debug(`[StreamProcessor] Buffer update:`,{size:e,formatted:t}),this.onBufferUpdate&&this.onBufferUpdate(e,t)}),this.workerProcessor.setOnError(e=>{$.error(`[StreamProcessor] Worker error:`,e),this.onError&&this.onError(e)}),this.currentVideoStream=e,await this.workerProcessor.startProcessing(e,t,n)}updateTabVisibility(e,t){this.workerProcessor.updateTabVisibility(e,t)}updateSourceType(e){this.workerProcessor.updateSourceType(e)}pause(){this.workerProcessor.pause()}resume(){this.workerProcessor.resume()}isPausedState(){return this.workerProcessor.isPausedState()}async finalize(){return $.debug(`[StreamProcessor] finalize called`),await this.workerProcessor.finalize()}toggleMute(){this.workerProcessor.toggleMute()}isMutedState(){return this.workerProcessor.getMutedState()}getClonedAudioTrack(){return this.workerProcessor.getClonedAudioTrack()}getAudioStreamForAnalysis(){return this.workerProcessor.getAudioStreamForAnalysis()}async switchVideoSource(e){await this.workerProcessor.switchVideoSource(e),this.currentVideoStream=e,this.onSourceChange&&this.onSourceChange(e)}getCurrentVideoSource(){return this.currentVideoStream}getBufferSize(){return this.workerProcessor.getBufferSize()}setOnMuteStateChange(e){this.workerProcessor.setOnMuteStateChange(e)}setOnSourceChange(e){this.onSourceChange=e}setOnBufferUpdate(e){this.onBufferUpdate=e}setOnError(e){this.onError=e}setOnAudioWarning(e){this.workerProcessor.setOnAudioWarning(e)}setOnAudioRecovered(e){this.workerProcessor.setOnAudioRecovered(e)}warmupEncoder(e){this.workerProcessor.warmupEncoder(e)}prewarm(){this.workerProcessor.prewarm()}async cancel(){await this.workerProcessor.cancel(),this.currentVideoStream=null}destroy(){this.workerProcessor.destroy(),this.currentVideoStream=null}};let FC=1e3,IC=`recording`,LC=`idle`,RC={route:`local-webcodecs`,reasonCodes:[`webcodecs-supported`,`target-codec-supported`]},zC={transcodeVideo:cy};function BC(e){switch(e.format){case`mp4`:return`video/mp4`;case`webm`:return`video/webm`;case`mkv`:return`video/x-matroska`;case`mov`:return`video/quicktime`;default:return null}}function VC(e,t){let n=BC(t);return n!==null&&e.type.toLowerCase().startsWith(n)}var HC=class{constructor(e,t,n){this.recordingState=LC,this.countdownDuration=5e3,this.countdownRemaining=0,this.countdownTimeoutId=null,this.countdownIntervalId=null,this.countdownStartTime=null,this.isPaused=!1,this.maxRecordingTime=null,this.maxTimeTimer=null,this.recordingStartTime=null,this.maxTimeRemaining=null,this.recordingSeconds=0,this.recordingIntervalId=null,this.pauseStartTime=null,this.totalPausedTime=0,this.streamProcessor=null,this.originalCameraStream=null,this.enableTabVisibilityOverlay=!1,this.startupAborted=!1,this.activeRecordingConfig=null,this.activeRouteDecision=RC,this.streamManager=e,this.callbacks=t,this.dependencies={...zC,...n}}setCountdownDuration(e){this.countdownDuration=e}setMaxRecordingTime(e){this.maxRecordingTime=e}setTabVisibilityOverlayConfig(e,t){this.enableTabVisibilityOverlay=e,this.tabVisibilityOverlayText=t}getRecordingState(){return this.recordingState}isPausedState(){return this.isPaused}getRecordingSeconds(){return this.recordingSeconds}getStreamProcessor(){return this.streamProcessor}updateSourceType(e){this.recordingState!==IC||!this.streamProcessor||this.streamProcessor.updateSourceType(e)}setOriginalCameraStream(e){this.originalCameraStream=e}getOriginalCameraStream(){return this.originalCameraStream}prewarmStreamProcessor(e){let t=this.getOrCreateStreamProcessor();t.prewarm(),e&&t.warmupEncoder(e)}async startRecording(){try{this.callbacks.onClearUploadStatus(),this.countdownDuration>0?this.startCountdown():await this.doStartRecording()}catch(e){this.handleError(e),this.recordingState=LC,this.cancelCountdown()}}startCountdown(){this.recordingState=`countdown`,this.countdownRemaining=Math.ceil(this.countdownDuration/FC),this.countdownStartTime=Date.now(),this.callbacks.onCountdownUpdate(this.recordingState,this.countdownRemaining),this.countdownIntervalId=window.setInterval(()=>{if(!this.countdownStartTime)return;let e=Date.now()-this.countdownStartTime,t=Math.max(0,Math.ceil((this.countdownDuration-e)/FC)),n=this.countdownRemaining;this.countdownRemaining=t,n!==t&&this.callbacks.onCountdownUpdate(this.recordingState,this.countdownRemaining)},100),this.countdownTimeoutId=window.setTimeout(async()=>{await this.doStartRecording().catch(()=>void 0)},this.countdownDuration)}async doStartRecording(){$.debug(`[RecordingManager] doStartRecording called`),this.cancelCountdown(),this.resetRecordingState(),this.startupAborted=!1;let e=this.streamManager.getStream();if($.debug(`[RecordingManager] Current stream:`,{hasStream:!!e,audioTracks:e?.getAudioTracks().length||0,videoTracks:e?.getVideoTracks().length||0}),!e){$.warn(`[RecordingManager] No stream available`),this.handleError(Error(`No stream available for recording`)),this.recordingState=LC,this.callbacks.onStateChange(this.recordingState);return}this.originalCameraStream=e,$.debug(`[RecordingManager] Ensuring stream processor`);let t=this.getOrCreateStreamProcessor();$.debug(`[RecordingManager] StreamProcessor ready:`,!!t);let n=null,r=await this.callbacks.onGetConfig().then(e=>(n=e,null)).catch(e=>e);if(r){this.handleError(r),this.recordingState=LC,this.callbacks.onStateChange(this.recordingState);return}if(!n){this.handleError(Error(`Failed to get recording config`)),this.recordingState=LC,this.callbacks.onStateChange(this.recordingState);return}let i=await this.resolveRouteDecision();if(i instanceof Error){this.handleError(i),this.recordingState=LC,this.callbacks.onStateChange(this.recordingState);return}this.callbacks.onAudioWarning&&t.setOnAudioWarning(this.callbacks.onAudioWarning),this.callbacks.onAudioRecovered&&t.setOnAudioRecovered(this.callbacks.onAudioRecovered),t.setOnError(e=>{this.handleFatalProcessorError(e)}),this.activeRecordingConfig=n,this.activeRouteDecision=i,$.debug(`[RecordingManager] Starting recording with stream manager`);let a=await this.streamManager.startRecording(t,n,this.enableTabVisibilityOverlay,this.tabVisibilityOverlayText,i).then(()=>null).catch(e=>($.error(`[RecordingManager] Error starting recording:`,e),e));if(a){this.activeRecordingConfig=null,this.activeRouteDecision=RC,this.handleError(a),this.recordingState=LC,this.callbacks.onStateChange(this.recordingState);return}if(this.startupAborted){this.startupAborted=!1;return}$.info(`[RecordingManager] Recording started successfully`),this.recordingState=IC,this.callbacks.onStateChange(this.recordingState),this.startRecordingTimer(),this.recordingStartTime=Date.now(),this.maxRecordingTime&&this.maxRecordingTime>0&&(this.maxTimeRemaining=this.maxRecordingTime,this.startMaxTimeTimer())}async stopRecording(){$.debug(`[RecordingManager] stopRecording called`);try{if(this.recordingState!==IC){let e=this.recordingState;throw this.cancelCountdown(),Ex(Cx,`Recording is not ready to stop`,{recordingState:e,hasStreamProcessor:!!this.streamProcessor})}this.cancelCountdown(),this.clearTimer(this.recordingIntervalId,clearInterval),this.recordingIntervalId=null,this.clearTimer(this.maxTimeTimer,clearTimeout),this.maxTimeTimer=null,this.resetPauseState(),this.callbacks.onStopAudioTracking(),$.debug(`[RecordingManager] Stopping recording in stream manager`);let e=await this.streamManager.stopRecording(),t=await this.resolveFinalRecordingBlob(e.blob);$.info(`[RecordingManager] Recording stopped, blob size:`,t.size),this.recordingState=LC,this.callbacks.onStateChange(this.recordingState),this.recordingSeconds=0,this.streamProcessor&&=(this.streamProcessor.destroy(),null),this.callbacks.onRecordingComplete(t);let n={};return e.recordingStats!==void 0&&(n.videoFrameCount=e.recordingStats.videoFrameCount,n.totalFrameErrors=e.recordingStats.totalFrameErrors,n.totalFramesProcessed=e.recordingStats.totalFramesProcessed),e.encoderAcceleration!==void 0&&(n.encoderAcceleration=e.encoderAcceleration),{blob:t,telemetryProperties:n}}catch(e){let t=Dx(e);throw this.handleError(t),this.recordingState=LC,this.callbacks.onStateChange(this.recordingState),t}finally{this.activeRecordingConfig=null,this.activeRouteDecision=RC}}pauseRecording(){if(!(this.recordingState!==IC||this.isPaused)&&(this.streamManager.pauseRecording(),this.isPaused=!0,this.clearTimer(this.recordingIntervalId,clearInterval),this.recordingIntervalId=null,this.pauseStartTime=Date.now(),this.maxTimeTimer!==null&&this.recordingStartTime!==null&&this.maxRecordingTime!==null)){let e=Date.now()-this.recordingStartTime-this.totalPausedTime;this.maxTimeRemaining=Math.max(0,this.maxRecordingTime-e),this.clearTimer(this.maxTimeTimer,clearTimeout),this.maxTimeTimer=null}}resumeRecording(){this.recordingState!==IC||!this.isPaused||(this.streamManager.resumeRecording(),this.isPaused=!1,this.updatePausedDuration(),this.startRecordingTimer(),this.maxTimeRemaining!==null&&this.maxTimeRemaining>0&&this.startMaxTimeTimer())}cancelCountdown(){this.clearTimer(this.countdownTimeoutId,clearTimeout),this.countdownTimeoutId=null,this.clearTimer(this.countdownIntervalId,clearInterval),this.countdownIntervalId=null,this.recordingState=LC,this.countdownRemaining=0,this.countdownStartTime=null,this.callbacks.onCountdownUpdate(this.recordingState,this.countdownRemaining)}cleanup(){this.cancelCountdown(),this.clearTimer(this.recordingIntervalId,clearInterval),this.recordingIntervalId=null,this.clearTimer(this.maxTimeTimer,clearTimeout),this.maxTimeTimer=null,this.streamProcessor&&=(this.streamProcessor.destroy(),null)}resetRecordingState(){this.isPaused=!1,this.recordingSeconds=0,this.totalPausedTime=0,this.pauseStartTime=null,this.recordingStartTime=null,this.maxTimeRemaining=null}async resolveFinalRecordingBlob(e){if(this.activeRouteDecision.route!==`safe-capture-post-recording-transcode`)return e;if(!this.activeRecordingConfig)throw Error(`Recording config unavailable for final video processing`);if(VC(e,this.activeRecordingConfig))return e;this.callbacks.onTranscodingProgress?.(0);let t=await this.dependencies.transcodeVideo(e,this.activeRecordingConfig,e=>{this.callbacks.onTranscodingProgress?.(e)});return this.callbacks.onTranscodingProgress?.(1),t.blob}resetPauseState(){this.isPaused=!1,this.pauseStartTime=null,this.totalPausedTime=0}getOrCreateStreamProcessor(){if(this.streamProcessor)return this.streamProcessor;let e=new PC;return this.streamProcessor=e,e}async resolveRouteDecision(){return this.callbacks.onGetRouteDecision?await this.callbacks.onGetRouteDecision().then(e=>e).catch(e=>e instanceof Error?e:Error(i(e))):RC}updatePausedDuration(){if(this.pauseStartTime===null)throw Error(`Pause start time not set`);let e=Date.now()-this.pauseStartTime;this.totalPausedTime+=e,this.pauseStartTime=null}startRecordingTimer(){if(this.recordingIntervalId!==null)return;let e=Mx(this.recordingSeconds);this.callbacks.onTimerUpdate(e),this.recordingIntervalId=window.setInterval(()=>{this.recordingSeconds+=1;let e=Mx(this.recordingSeconds);this.callbacks.onTimerUpdate(e)},1e3)}startMaxTimeTimer(){this.maxTimeRemaining===null||this.maxTimeRemaining<=0||(this.clearTimer(this.maxTimeTimer,clearTimeout),this.maxTimeTimer=window.setTimeout(async()=>{this.recordingState===IC&&!this.isPaused&&await this.stopRecording()},this.maxTimeRemaining))}clearTimer(e,t){e!==null&&t(e)}handleError(e){let t=e instanceof Error?e:Error(i(e));this.callbacks.onError(t)}handleFatalProcessorError(e){this.recordingState===IC&&(this.clearTimer(this.recordingIntervalId,clearInterval),this.recordingIntervalId=null,this.clearTimer(this.maxTimeTimer,clearTimeout),this.maxTimeTimer=null,this.resetPauseState()),!(!this.streamProcessor&&this.recordingState!==IC)&&($.error(`[RecordingManager] Fatal processor error, stopping recording`,e),this.startupAborted=!0,this.streamProcessor&&=(this.streamProcessor.destroy(),null),this.recordingState=LC,this.callbacks.onStateChange(this.recordingState),this.recordingSeconds=0,this.callbacks.onError(e))}},UC=class{constructor(e){this.client=null,this.createTelemetryClient=e.createTelemetryClient}initialize(e,t){typeof e==`string`&&e.length>0&&typeof t==`string`&&t.length>0&&(this.client=this.createTelemetryClient(e,t))}sendEvent(e,t,n){if(!this.client)return;let r={name:e};t&&(r={...r,properties:t}),n&&(r={...r,error:n}),this.client.triggerTelemetryEvent(r)}async executeAction(e){e.requestedEvent&&this.sendEvent(e.requestedEvent,e.properties);let t=null;if(await e.action().catch(e=>{t=e}),t)throw this.sendEvent(e.failedEvent,e.properties,t),t;this.sendEvent(e.succeededEvent,e.properties)}async executeActionWithResult(e){e.requestedEvent&&this.sendEvent(e.requestedEvent,e.properties);let t=null,n=null;if(await e.action().then(e=>{n=e}).catch(e=>{t=e}),t)throw this.sendEvent(e.failedEvent,e.properties,t),t;if(n===null)throw Error(`Telemetry action failed to return result`);let r=this.resolveResultTelemetryProperties(n,e.getPropertiesFromResult),i=this.mergeTelemetryProperties(e.properties,r);return this.sendEvent(e.succeededEvent,i),n}resolveResultTelemetryProperties(e,t){if(t!==void 0)return t(e)}mergeTelemetryProperties(e,t){if(!(e===void 0&&t===void 0))return e===void 0?t:t===void 0?e:{...e,...t}}},WC=class{constructor(){this.metadataById=new Map}getMetadata(e){return this.metadataById.get(e)}setMetadata(e,t){let n=new Map(this.metadataById);n.set(e,t),this.metadataById=n}clearMetadata(e){let t=new Map(this.metadataById);t.delete(e),this.metadataById=t}};let GC=`[RecorderController]`;var KC=class{constructor(e={}){this.uploadService=null,this.uploadQueueManager=null,this.isInitialized=!1,this.isDemo=!1,this.isDestroyed=!1,this.enableTabVisibilityOverlay=!1,this.recordingWarmupTimeoutId=null,this.audioTelemetryUnsub=null,this.callbacks=e,this.streamManager=new Ux,this.configManager=new dn,this.storageManager=new Ab,this.deviceManager=new fn(this.streamManager,e.device),this.audioLevelAnalyzer=new o,this.uploadService=new yS,this.uploadCallbacks=jS(e),this.telemetryManager=new UC({createTelemetryClient:_S}),this.uploadMetadataManager=new WC;let t=FS(e,{stopAudioTracking:()=>this.audioLevelAnalyzer.stopTracking(),getConfig:()=>Promise.resolve(this.configManager.getConfigForRecording()),getRouteDecision:async()=>await this.resolveRecordingRouteDecision(`live-recorder`),onAudioWarning:e.recording?.onAudioWarning?t=>{this.sendAudioWarningTelemetry(t),e.recording?.onAudioWarning?.(t)}:e=>{this.sendAudioWarningTelemetry(e)},...e.recording?.onAudioRecovered&&{onAudioRecovered:e.recording.onAudioRecovered},...e.recording?.onTranscodingProgress&&{onTranscodingProgress:e.recording.onTranscodingProgress}});this.recordingManager=new HC(this.streamManager,t);let n=IS(e,{isRecording:()=>this.isRecording(),updateSourceType:e=>{this.recordingManager.updateSourceType(e)},getSelectedCameraDeviceId:()=>this.deviceManager.getSelectedCameraDeviceId(),getSelectedMicDeviceId:()=>this.deviceManager.getSelectedMicDeviceId()});this.sourceSwitchManager=new cx(this.streamManager,n);let r=e.stream;r&&(this.streamManager.on(`streamstart`,({stream:e})=>{$.debug(`${GC} streamstart event received, calling callback`),r.onStreamStart&&r.onStreamStart(e)}),this.streamManager.on(`streamstop`,()=>{$.debug(`${GC} streamstop event received, calling callback`),r.onStreamStop&&r.onStreamStop()}),this.streamManager.on(`error`,({error:e})=>{$.error(`${GC} stream error event received, calling callback`,e),this.telemetryManager.sendEvent(`stream.error`,{sourceType:this.getCurrentSourceType()},e),r.onError&&r.onError(e)})),this.audioTelemetryUnsub=this.streamManager.on(`audiotelemetry`,({event:e})=>{let t=this.getBrowserNameForTelemetry();this.telemetryManager.sendEvent(e.name,{...e.properties,browserName:t,sourceType:this.getCurrentSourceType()},e.error)})}async initialize(e){if(this.isInitialized)return;await this.validateRecorderSupport();let t=!1;typeof e.demo==`boolean`&&(t=e.demo),this.isDemo=t;let n=null;typeof e.apiKey==`string`&&e.apiKey.length>0&&(n=e.apiKey);let r=null;typeof e.backendUrl==`string`&&e.backendUrl.length>0&&(r=e.backendUrl),this.telemetryManager.initialize(n,r),await this.telemetryManager.executeAction({requestedEvent:`sdk.init.started`,succeededEvent:`sdk.init.succeeded`,failedEvent:`sdk.init.failed`,action:async()=>{await this.initializeConfig(n,r),this.applyRecordingConfig(e),await this.initializeStorage(),this.isInitialized=!0,this.scheduleRecordingWarmup()}})}async startStream(){let e=this.getCurrentSourceType();await this.telemetryManager.executeAction({succeededEvent:`preview.start.succeeded`,failedEvent:`preview.start.failed`,action:async()=>{$.debug(`${GC} startStream called`),await this.streamManager.startStream(),this.ignorePromiseRejection(this.ensureConfigReady()),this.ignorePromiseRejection(this.configManager.getConfig().then(e=>{this.recordingManager.prewarmStreamProcessor(e)})),this.prewarmSupportCheck(),$.debug(`${GC} startStream completed`)},properties:{sourceType:e}})}async stopStream(){await this.streamManager.stopStream()}switchVideoDevice(e){return this.streamManager.switchVideoDevice(e)}switchAudioDevice(e){return this.streamManager.switchAudioDevice(e)}async startRecording(){let e=this.getCurrentSourceType();await this.telemetryManager.executeAction({requestedEvent:`recording.start.requested`,succeededEvent:`recording.start.succeeded`,failedEvent:`recording.start.failed`,action:async()=>{await this.ensureConfigReady(),await this.streamManager.waitForAudio(),await this.recordingManager.startRecording()},properties:{sourceType:e}})}async stopRecording(){let e=this.getCurrentSourceType();try{return(await this.telemetryManager.executeActionWithResult({requestedEvent:`recording.stop.requested`,succeededEvent:`recording.stop.succeeded`,failedEvent:`recording.stop.failed`,action:async()=>{let e=await this.recordingManager.stopRecording();return await this.sourceSwitchManager.handleRecordingStop().catch(()=>{throw Error(`Source switch cleanup failed`)}),this.streamManager.stopStream(),e},properties:{sourceType:e},getPropertiesFromResult:e=>e.telemetryProperties})).blob}catch(e){throw bb(e)&&this.sendAudioMissingTelemetry(e),e}}sendAudioMissingTelemetry(e){let t={code:e.code,sourceType:this.getCurrentSourceType(),browserName:this.getBrowserNameForTelemetry()};e.details&&(t.durationMs=e.details.durationMs,t.totalChunks=e.details.totalChunks,t.nonSilentChunks=e.details.nonSilentChunks,t.mutedDurationMs=e.details.mutedDurationMs,t.silenceRatio=e.details.durationMs>0?e.details.mutedDurationMs/e.details.durationMs:0,t.hadTrackEndedWarning=e.details.hadTrackEndedWarning),this.telemetryManager.sendEvent(`recording.audio-missing`,t)}getTabVisibilityOverlayConfig(){return{enabled:this.enableTabVisibilityOverlay,text:this.tabVisibilityOverlayText}}pauseRecording(){this.recordingManager.pauseRecording()}resumeRecording(){this.recordingManager.resumeRecording()}async switchSource(e){await this.telemetryManager.executeAction({requestedEvent:`source.switch.requested`,succeededEvent:`source.switch.succeeded`,failedEvent:`source.switch.failed`,action:async()=>{await this.sourceSwitchManager.toggleSource()},properties:{sourceType:e}})}setCameraDevice(e){this.deviceManager.setCameraDevice(e)}setMicDevice(e){this.deviceManager.setMicDevice(e)}getAvailableDevices(){return this.deviceManager.getAvailableDevices()}muteAudio(){this.streamManager.muteAudio()}unmuteAudio(){this.streamManager.unmuteAudio()}toggleMute(){this.streamManager.toggleMute()}getIsMuted(){return this.streamManager.isMuted()}startAudioLevelTracking(e,t){if(!t)throw Error(`Audio level callbacks are required`);return this.audioLevelAnalyzer.startTracking(e,t,()=>this.streamManager.isMuted()),Promise.resolve()}stopAudioLevelTracking(){this.audioLevelAnalyzer.stopTracking()}getAudioLevel(){return this.audioLevelAnalyzer.getAudioLevel()}async uploadVideo(e,t,n,r){this.uploadCallbacks.onClearStatus();let i=await Cv(e),a=`recording-${Date.now()}.mp4`,o=this.getCurrentSourceType(),s;if(Object.keys(r).length>0&&(s=r),this.telemetryManager.sendEvent(`upload.started`,{filename:a,duration:i,sourceType:o}),!this.uploadQueueManager){await this.uploadDirectlyWithoutQueue({blob:e,apiKey:t,backendUrl:n,filename:a,duration:i,sourceType:o,userMetadata:s});return}let c=await this.uploadQueueManager.queueUpload({blob:e,apiKey:t,backendUrl:n,filename:a,duration:i,metadata:void 0,userMetadata:s});this.uploadMetadataManager.setMetadata(c,{filename:a,duration:i,sourceType:o})}async uploadDirectlyWithoutQueue(e){if(!this.uploadService){let t=Error(`Upload service not available`);throw this.uploadCallbacks.onError(t),this.telemetryManager.sendEvent(`upload.failed`,{filename:e.filename,duration:e.duration,sourceType:e.sourceType},t),t}try{let t=await this.uploadService.uploadVideo(e.blob,{apiKey:e.apiKey,backendUrl:e.backendUrl,filename:e.filename,metadata:void 0,userMetadata:e.userMetadata,onProgress:this.uploadCallbacks.onProgress});this.uploadCallbacks.onSuccess(t),this.telemetryManager.sendEvent(`upload.succeeded`,{filename:e.filename,duration:e.duration,sourceType:e.sourceType,recordingId:t.id})}catch(t){let n=t instanceof Error?t:Error(i(t));throw this.uploadCallbacks.onError(n),this.telemetryManager.sendEvent(`upload.failed`,{filename:e.filename,duration:e.duration,sourceType:e.sourceType},n),n}}getStream(){return this.streamManager.getStream()}isConfigReady(){return this.configManager.isConfigReady()}ensureConfigReady(){return this.isDemo||this.configManager.isConfigReady()?Promise.resolve():this.configManager.fetchConfig().then(()=>void 0).catch(()=>void 0)}cleanup(){this.isDestroyed=!0,this.recordingWarmupTimeoutId!==null&&(clearTimeout(this.recordingWarmupTimeoutId),this.recordingWarmupTimeoutId=null),this.audioTelemetryUnsub&&=(this.audioTelemetryUnsub(),null),this.uploadQueueManager?.destroy(),this.storageManager.destroy(),this.recordingManager.cleanup(),this.audioLevelAnalyzer.stopTracking(),this.sourceSwitchManager.cleanup()}getRecordingState(){return this.recordingManager.getRecordingState()}isPaused(){return this.recordingManager.isPausedState()}getCurrentSourceType(){return this.sourceSwitchManager.getCurrentSourceType()}getOriginalCameraStream(){return this.sourceSwitchManager.getOriginalCameraStream()}getStreamManager(){return this.streamManager}getAudioStreamForAnalysis(){return this.streamManager.getAudioStreamForAnalysis()}getDeviceManager(){return this.deviceManager}getConfig(){return this.configManager.getConfig()}getUploadService(){return this.uploadService}isRecording(){return this.streamManager.isRecording()}isActive(){return this.streamManager.isActive()}isAudioReady(){return this.streamManager.isAudioReady()}getAudioStatus(){return this.streamManager.getAudioStatus()}sendAudioWarningTelemetry(e){let t={code:e.code,sourceType:this.getCurrentSourceType(),browserName:this.getBrowserNameForTelemetry()};`durationMs`in e&&(t.durationMs=e.durationMs),`peak`in e&&(t.peak=e.peak),`rms`in e&&(t.rms=e.rms),this.telemetryManager.sendEvent(`audio.warning`,t)}getBrowserNameForTelemetry(){try{return Mt()}catch{return`unknown`}}async resolveRecordingRouteDecision(e){let t=this.configManager.getConfigForRecording(),n=this.buildCodecProbeCandidates(t),r=await Lv({codecCandidates:n}),i=Gv({profile:r,targetCodecIds:n.map(e=>e.id)});return this.telemetryManager.sendEvent(`recording.route.selected`,{routeDecision:this.buildRouteTelemetryProperties(i,r,e)}),i}buildCodecProbeCandidates(e){let t=e.width??1280,n=e.height??720,r=typeof e.bitrate==`number`?e.bitrate:25e5,i=e.fps??30;return this.resolveTargetCodecIds(e.codec).map(e=>({id:`${e}-${t}x${n}`,config:{codec:e,width:t,height:n,bitrate:r,framerate:i}}))}resolveTargetCodecIds(e){switch(e){case`avc`:return[`avc1.640028`,`avc1.42001f`];case`vp9`:return[`vp09.00.10.08`];case`vp8`:return[`vp8`];case`av1`:return[`av01.0.08M.08`];case`hevc`:return[`hvc1.1.6.L123.B0`];default:return[`avc1.640028`,`avc1.42001f`,`vp09.00.10.08`,`vp8`]}}buildRouteTelemetryProperties(e,t,n){return{selectedRoute:e.route,reasonCodes:e.reasonCodes,sourceType:n,clientTranscodeDeferred:e.route===`safe-capture-post-recording-transcode`,capabilitySummary:{browserName:t.browser.normalizedName,osName:t.os.name,deviceMemory:t.resources.deviceMemory??null,hardwareConcurrency:t.resources.hardwareConcurrency??null,effectiveType:t.network.effectiveType??null,online:t.network.online??null,isSecureContext:t.features.isSecureContext,hasMediaRecorder:t.features.hasMediaRecorder,hasVideoEncoder:t.features.hasVideoEncoder,supportedCodecIds:t.codecProbeResults.filter(e=>e.supported).map(e=>e.id)}}}async initializeConfig(e,t){let n=!0;e===null&&(n=!1),t===null&&(n=!1),n&&e!==null&&t!==null&&await this.configManager.initialize(e,t)}applyRecordingConfig(e){e.countdownDuration!==void 0&&this.recordingManager.setCountdownDuration(e.countdownDuration),e.maxRecordingTime!==void 0&&this.recordingManager.setMaxRecordingTime(e.maxRecordingTime),e.enableTabVisibilityOverlay!==void 0&&(this.enableTabVisibilityOverlay=e.enableTabVisibilityOverlay),e.tabVisibilityOverlayText!==void 0&&(this.tabVisibilityOverlayText=e.tabVisibilityOverlayText),this.recordingManager.setTabVisibilityOverlayConfig(this.enableTabVisibilityOverlay,this.tabVisibilityOverlayText)}async initializeStorage(){if(this.isDestroyed)return;let e=NS(this.callbacks);try{await this.storageManager.initialize(e)}catch(e){let t=e instanceof Error?e:Error(i(e)),n=i(t);this.telemetryManager.sendEvent(`storage.init.failed`,{reason:n},t),PS(this.callbacks)(n);return}if(this.isDestroyed)return;let t=this.storageManager.getWriteProbeResult();if(!t?.ok){let e=t?.reason??`Storage write probe did not complete`;this.telemetryManager.sendEvent(`storage.write.probe.failed`,{reason:e}),PS(this.callbacks)(e);return}let n=this.storageManager.getStorageService();n&&this.uploadService&&(this.uploadQueueManager=new vS(n,this.uploadService),this.uploadQueueManager.setCallbacks({onUploadProgress:(e,t)=>{this.uploadCallbacks.onProgress(t)},onUploadComplete:(e,t)=>{this.uploadCallbacks.onSuccess(t);let n=this.uploadMetadataManager.getMetadata(e);n&&(this.telemetryManager.sendEvent(`upload.succeeded`,{filename:n.filename,duration:n.duration,sourceType:n.sourceType,recordingId:t.id}),this.uploadMetadataManager.clearMetadata(e))},onUploadError:(e,t)=>{this.uploadCallbacks.onError(t);let n=this.uploadMetadataManager.getMetadata(e);n&&(this.telemetryManager.sendEvent(`upload.failed`,{filename:n.filename,duration:n.duration,sourceType:n.sourceType},t),this.uploadMetadataManager.clearMetadata(e))}}))}async validateRecorderSupport(){Ft();let e=await lb({requiresAudio:!1,requiresWatermark:!1});if(!e.isSupported)throw Nt({missingCapabilities:e.missing,resolutionStage:`feature-preflight`})}scheduleRecordingWarmup(){this.recordingWarmupTimeoutId!==null&&(clearTimeout(this.recordingWarmupTimeoutId),this.recordingWarmupTimeoutId=null),!this.isDestroyed&&(this.recordingWarmupTimeoutId=setTimeout(()=>{this.recordingWarmupTimeoutId=null,!this.isDestroyed&&(this.ignorePromiseRejection(this.ensureConfigReady()),this.ignorePromiseRejection(this.configManager.getConfig().then(e=>{this.recordingManager.prewarmStreamProcessor(e)})))},0))}ignorePromiseRejection(e){e.catch(()=>void 0)}prewarmSupportCheck(){this.ignorePromiseRejection(lb({requiresAudio:!0,requiresWatermark:!0}).then(e=>{this.streamManager.setPreResolvedSupportReport(e)}))}};let qC=/<a\s[^>]*href="(?<href>[^"]+)"[^>]*>(?<text>[^<]+)<\/a>/,JC=/\starget=["'](?<target>[^"']+)["']/,YC=/^[a-zA-Z][a-zA-Z\d+\-.]*:/,XC=`{version}`;function ZC(e,t){return e?e.toLowerCase().includes(t):!1}function QC(e){let t=e.trim();if(!t)return null;let n=t.toLowerCase();return!YC.test(n)||n.startsWith(`http:`)||n.startsWith(`https:`)?t:null}function $C(e,t,n,r){return e===`browser.unsupported`?r.browserUnsupportedDynamic?nw(r.browserUnsupportedDynamic,t,n):ZC(t,`safari`)?r.browserUnsupportedSafari:ZC(t,`firefox`)?r.browserUnsupportedFirefox:r.browserUnsupported:r.browserUnsupported}function ew(e,t){return e===`camera.in-use`?t.cameraInUse:e===`camera.not-found`?t.cameraNotFound:e===`camera.permission-denied`?t.cameraPermissionDenied:e===`camera.timeout`?t.cameraTimeout??t.failedToStartCamera:t.failedToStartCamera}function tw(e,t){return e===`audio.in-use`?t.audioInUse:e===`audio.not-found`?t.audioNotFound:e===`audio.permission-denied`?t.audioPermissionDenied:e===`audio.timeout`?t.audioTimeout??t.failedToStartAudio:t.failedToStartAudio}function nw(e,t,n){let r=`This browser`;t&&t.trim().length>0&&(r=t);let i=e.replace(`{browser}`,r);return n&&n.trim().length>0&&n?(i=i.replace(XC,n),i):(i=i.replace(` ({version})`,``),i=i.replace(XC,``),i)}function rw(e){let t=qC.exec(e);if(!t?.groups)return{prefix:e,linkText:null,linkHref:null,linkTarget:null,suffix:``};let n=t.index,r=n+t[0].length,i=e.slice(0,n),a=e.slice(r),o=QC(t.groups.href);if(!o)return{prefix:i+t.groups.text+a,linkText:null,linkHref:null,linkTarget:null,suffix:``};let s=JC.exec(t[0])?.groups?.target??null;return{prefix:i,linkText:t.groups.text,linkHref:o,linkTarget:s,suffix:a}}function iw(){let e=globalThis.navigator&&typeof globalThis.navigator.userAgent==`string`?globalThis.navigator.userAgent:``,t=new wt(e).getResult(),n=t.device.type,r=n===`mobile`||n===`tablet`;return $.debug(`Mobile detection result`,{userAgent:e,deviceType:n,isMobile:r,device:t.device,os:t.os,browser:t.browser}),r}function aw(){let e=jt(),t=null;e.name.length>0&&(t=e.name);let n=null;return e.version.length>0&&(n=e.version),{browserName:t,browserVersion:n}}function ow(e){let t=t=>{if(!(`code`in t))return;let n=t;if(n.code!==`browser.unsupported`){(n.code?.startsWith(`camera.`)||n.code?.startsWith(`audio.`)||n.code?.startsWith(`recording.`))&&e.updateState({errorCode:n.code,canRetry:!0,browserName:null,browserVersion:null});return}let r=aw(),i=r.browserName;n.browserName&&n.browserName.length>0&&(i=n.browserName);let a=r.browserVersion;n.browserVersion&&n.browserVersion.length>0&&(a=n.browserVersion),e.updateState({errorCode:`browser.unsupported`,canRetry:!1,browserName:i,browserVersion:a})};return{recording:{onStateChange:t=>{e.updateState({recordingState:t}),t===`idle`&&(e.isProcessingBlob=!1)},onCountdownUpdate:(t,n)=>{e.updateState({recordingState:t,countdown:n})},onTimerUpdate:t=>{e.updateState({timer:t})},onError:n=>{t(n),e.updateState({error:i(n),transcodingProgress:null})},onRecordingComplete:t=>{e.updateState({countdown:null}),e.processRecordingBlob(t).catch(t=>{e.updateState({error:i(t)})})},onClearUploadStatus:()=>{e.updateState({uploadProgress:null})},onTranscodingProgress:t=>{e.updateState({transcodingProgress:t})},onAudioWarning:t=>{e.updateState({audioWarning:t}),e.dispatchEvent(new CustomEvent(`vidtreo:audio-warning`,{detail:t}))},onAudioRecovered:()=>{e.updateState({audioWarning:null}),e.dispatchEvent(new CustomEvent(`vidtreo:audio-recovered`))},onStopAudioTracking:()=>void 0,onGetConfig:()=>{if(!e.controller)throw Error(`Controller not initialized`);return e.isDemo?Promise.resolve(Zt(`mp4`)):e.controller.getConfig()}},sourceSwitch:{onSourceChange:e=>Promise.resolve(),onPreviewUpdate:t=>(e.updateState({stream:t}),Promise.resolve()),onError:n=>{t(n),e.updateState({error:i(n)})},onTransitionStart:t=>{e.updateState({transitionMessage:t})},onTransitionEnd:()=>{e.updateState({transitionMessage:null})}},storage:{onUploadProgress:()=>void 0,onUploadComplete:()=>void 0,onUploadError:()=>void 0},onStorageCleanupError:t=>{e.updateState({error:t})}}}function sw(e,t){let n=(e=>e===``||e===`default`?null:e)(t);return e.setCameraDevice(n),e.switchVideoDevice(n)}function cw(e,t){let n=(e=>e===``||e===`default`?null:e)(t);return e.setMicDevice(n),e.switchAudioDevice(n)}async function lw(e,t=`camera`){e.isActive()||await e.startStream(),t!==e.getCurrentSourceType()&&await e.switchSource(t),await e.startRecording()}async function uw(e,t,n,r){return await e.stopRecording()}function dw(e){e.pauseRecording()}function fw(e){e.resumeRecording()}async function pw(e,t){await e.switchSource(t)}let mw=`camera`,hw=`screen`,gw=`recording`,_w=`browser.unsupported`,vw=[.8,1.2,.9];function yw(e,t){let{uploadProgress:n,uploadingLabel:r}=e,{overlay:i,fill:a,text:o}=t;if(!i)return;if(n===null){i.style.display=`none`;return}i.style.display=`block`;let s=Math.round(n*100);a&&(a.style.width=`${s}%`),o&&(o.textContent=`${r} ${s}%`)}function bw(e,t){let{transitionMessage:n}=e,{overlay:r,message:i}=t;if(r){if(!n){r.classList.remove(`vidtreo-active`);return}r.classList.add(`vidtreo-active`),i&&(i.textContent=n)}}let xw=`none`,Sw=`flex`,Cw=`inline-flex`,ww=`checking`,Tw=`blocked`,Ew=`ready`,Dw=`vidtreo-active`,Ow=`vidtreo-permission-flow--fading`,kw=`vidtreo-permission-flow-action--requesting`;function Aw(e){return{container:e.querySelector(`#permissionFlow`),spinner:e.querySelector(`#permissionFlowSpinner`),title:e.querySelector(`#permissionFlowTitle`),subtitle:e.querySelector(`#permissionFlowSubtitle`),actionButton:e.querySelector(`#btnAllowPermission`),buttonIcon:e.querySelector(`#permissionFlowBtnIcon`),buttonSpinner:e.querySelector(`#permissionFlowBtnSpinner`),buttonText:e.querySelector(`#permissionFlowBtnText`),recovery:e.querySelector(`#permissionFlowRecovery`),recoveryTitle:e.querySelector(`#permissionFlowRecoveryTitle`),recoveryText:e.querySelector(`#permissionFlowRecoveryText`),retryButton:e.querySelector(`#btnRetryPermission`),recoveryGuideUrl:e.querySelector(`#recoveryGuideUrl`),recoveryGuidePopoverUrl:e.querySelector(`#recoveryGuidePopoverUrl`)}}function jw(e){return e.permissions.camera===`granted`?`microphone`:`camera`}function Mw(e,t){return t.cameraTitle}function Nw(e,t){return t.cameraLabel}function Pw(e,t){return t.allowCamera}function Fw(e,t,n){let r=e.step,i=!1;(r===ww||r===`awaiting-user`||r===Tw||r===Ew)&&(i=!0);let a=r===Ew,o=r===Tw,s=r===ww,c=jw(e),l=Mw(c,t),u=Nw(c,t),d=Pw(c,t),f=t.recoveryInstructions;return e.recoveryData?.resetInstructions&&(f=e.recoveryData.resetInstructions),{isVisible:i,isFadingOut:n,isSpinnerOnly:a,isBlocked:o,isRequesting:s,titleText:l,subtitleText:u,actionLabel:d,requestingText:t.statusRequesting,recoveryTitleText:t.recoveryTitle,recoveryInstructionsText:f}}function Iw(e,t,n){if(e){if(t){e.style.display=n;return}e.style.display=xw}}function Lw(e,t){if(t.isVisible)e.classList.add(Dw);else return e.classList.remove(Dw),e.classList.remove(Ow),!1;return t.isFadingOut?e.classList.add(Ow):e.classList.remove(Ow),!0}function Rw(e,t,n){Iw(e.actionButton,n,Cw),e.actionButton&&(t.isRequesting?(e.actionButton.classList.add(kw),e.actionButton.disabled=!0):(e.actionButton.classList.remove(kw),e.actionButton.disabled=!1)),Iw(e.buttonIcon,n&&!t.isRequesting,Cw),Iw(e.buttonSpinner,n&&t.isRequesting,Cw),e.buttonText&&(t.isRequesting?e.buttonText.textContent=t.requestingText:e.buttonText.textContent=t.actionLabel)}function zw(){if(globalThis.window===void 0)return`vidtreo.com`;let e=globalThis.window.location.hostname||`vidtreo.com`;return e.length>20?`${e.slice(0,20)}...`:e}function Bw(e,t){if(Iw(e.recovery,t.isBlocked,Sw),e.recoveryTitle&&(e.recoveryTitle.textContent=t.recoveryTitleText),Iw(e.recoveryText,!1,xw),Iw(e.retryButton,!1,xw),t.isBlocked){let t=zw();e.recoveryGuideUrl&&(e.recoveryGuideUrl.textContent=t),e.recoveryGuidePopoverUrl&&(e.recoveryGuidePopoverUrl.textContent=t)}}function Vw(e,t){t&&(e.actionButton&&t.onAllow&&(e.actionButton.onclick=t.onAllow),e.retryButton&&t.onRetry&&(e.retryButton.onclick=t.onRetry))}function Hw(e,t,n){let{container:r}=t;if(!r||!Lw(r,e))return;let i=!e.isSpinnerOnly;Iw(t.spinner,e.isSpinnerOnly,Cw),Iw(t.title,i&&!e.isBlocked,Sw),Iw(t.subtitle,i&&!e.isBlocked,Sw),t.title&&(t.title.textContent=e.titleText),t.subtitle&&(t.subtitle.textContent=e.subtitleText),Rw(t,e,i&&!e.isBlocked),Bw(t,e),Vw(t,n)}function Uw(e,t){e.textContent=``;let n=document.createTextNode(t.prefix);if(e.append(n),t.linkText&&t.linkHref){let n=document.createElement(`a`),r=t.linkTarget;n.href=t.linkHref,r&&(n.target=r),r===`_blank`&&(n.rel=`noopener noreferrer`),n.textContent=t.linkText,e.append(n)}let r=document.createTextNode(t.suffix);e.append(r)}function Ww(e){let{stream:t,transitionMessage:n,isVideoLoaded:r}=e;return{showPreviewSkeleton:!!t&&!r&&!n,showVideoPreview:!!t}}function Gw(e,t){let{previewSkeleton:n,videoPreview:r}=t;n&&(e.showPreviewSkeleton?n.style.display=`block`:n.style.display=`none`),r&&(e.showVideoPreview?r.style.display=`block`:r.style.display=`none`)}function Kw(e,t,n){let{videoPreview:r}=t,{onVideoLoaded:a,onError:o,startAudioAnalysis:s,stopAudioAnalysis:c}=n;if(r){if(!e){r.srcObject=null,c();return}r.srcObject=e,r.onloadeddata=()=>{a()},r.play().catch(e=>o(i(e))),s(e)}}function qw(e){return{startCameraArea:e.querySelector(`#startCameraArea`),startCameraButton:e.querySelector(`#startCameraButton`),cameraIcon:e.querySelector(`#startCameraArea .vidtreo-camera-icon`),cameraText:e.querySelector(`#startCameraArea .vidtreo-camera-text`),cameraHint:e.querySelector(`#startCameraArea .vidtreo-camera-hint`),previewSkeleton:e.querySelector(`#previewSkeleton`),previewSkeletonText:e.querySelector(`#previewSkeleton .vidtreo-skeleton-text`),videoPreview:e.querySelector(`#videoPreview`),countdownOverlay:e.querySelector(`#countdownOverlay`),countdownNumber:e.querySelector(`#countdownNumber`),recordingTimerRow:e.querySelector(`#recordingTimerRow`),recordingTimer:e.querySelector(`#recordingTimer`),recIndicatorTop:e.querySelector(`#recIndicatorTop`),audioLevelBars:e.querySelector(`#audioLevelBars`)}}function Jw(e,t,n,r,i,a){if(e.stream)return{shouldShow:!1,iconClassName:``,browserErrorContent:null,textContent:null,hintText:null,retryButtonLabel:null};let o=aS({errorCode:e.errorCode,hasAudioFailed:!1,error:null}),s=o.isCameraError||o.isAudioError,c=!(o.isBrowserUnsupported||s),l=o.isBrowserUnsupported||s?`ph-fill ph-warning-circle`:`ph-fill ph-camera`,u=null,d=null;o.isBrowserUnsupported&&(u=rw(n)),o.isAudioError&&(d=i),o.isCameraError&&(d=r),c&&(d=t.initializingCamera);let f=c?t.grantPermissions:null,p=s&&!o.isPermissionDenied?a:null;return{shouldShow:!0,iconClassName:l,browserErrorContent:u,textContent:d,hintText:f,retryButtonLabel:p}}function Yw(e,t){let n=!1;return e&&(n=!0),{shouldShow:n,text:t.switchingDevice}}function Xw(e,t,n){let r=!1;return e===`countdown`&&t!==null&&(r=!0),{shouldShow:r,countdown:t,text:n.recordingStartsIn}}function Zw(e,t){return{shouldShow:e,text:t.rec}}function Qw(e,t){return{shouldShow:e,timer:t}}function $w(e){return{shouldShow:e}}function eT(e,t){let{state:n,isVideoLoaded:r,isRecording:i,translations:a}=e;tT(Jw(n,a,$C(n.errorCode,n.browserName,n.browserVersion,{browserUnsupported:a.browserUnsupported,browserUnsupportedDynamic:a.browserUnsupportedDynamic,browserUnsupportedSafari:a.browserUnsupportedSafari,browserUnsupportedFirefox:a.browserUnsupportedFirefox}),ew(n.errorCode??``,{cameraInUse:a.cameraInUse,cameraNotFound:a.cameraNotFound,cameraPermissionDenied:a.cameraPermissionDenied,cameraTimeout:a.cameraTimeout,failedToStartCamera:a.failedToStartCamera}),tw(n.errorCode??``,{audioInUse:a.audioInUse,audioNotFound:a.audioNotFound,audioPermissionDenied:a.audioPermissionDenied,audioTimeout:a.audioTimeout,failedToStartAudio:a.failedToStartAudio}),a.retryCamera),t,e.onRetryCamera),nT(Yw(n.transitionMessage,a),t),Gw(Ww({stream:n.stream,transitionMessage:n.transitionMessage,isVideoLoaded:r}),{previewSkeleton:t.previewSkeleton,videoPreview:t.videoPreview}),rT(Xw(n.recordingState,n.countdown,a),t),iT(Zw(i,a),t),aT(Qw(i,n.timer),t),oT($w(i),t)}function tT(e,t,n){let{startCameraArea:r,startCameraButton:i,cameraIcon:a,cameraText:o,cameraHint:s}=t;if(r){if(!e.shouldShow){r.style.display=`none`;return}r.style.display=`block`,a&&(a.innerHTML=`<i class="${e.iconClassName}" style="font-size: 48px;"></i>`),o&&(e.browserErrorContent&&Uw(o,e.browserErrorContent),e.textContent&&(o.textContent=e.textContent)),s&&(e.hintText?(s.textContent=e.hintText,s.style.display=`block`):s.style.display=`none`),i&&(e.retryButtonLabel?(i.textContent=e.retryButtonLabel,i.hidden=!1,i.className=`vidtreo-error-retry`,i.onclick=e=>{e.preventDefault(),e.stopPropagation(),n&&n()}):(i.hidden=!0,i.onclick=null))}}function nT(e,t){let{previewSkeleton:n,previewSkeletonText:r}=t;n&&(e.shouldShow?n.style.display=`block`:n.style.display=`none`,r&&(r.textContent=e.text))}function rT(e,t){let{countdownOverlay:n,countdownNumber:r}=t;n&&(e.shouldShow?n.classList.add(`vidtreo-active`):n.classList.remove(`vidtreo-active`),r&&e.countdown!==null&&(r.textContent=e.countdown.toString()))}function iT(e,t){let{recIndicatorTop:n}=t;n&&(e.shouldShow?n.style.display=`block`:n.style.display=`none`)}function aT(e,t){let{recordingTimerRow:n,recordingTimer:r}=t;n&&(e.shouldShow?n.style.display=`flex`:n.style.display=`none`,r&&(r.textContent=e.timer))}function oT(e,t){let{audioLevelBars:n}=t;n&&(e.shouldShow?n.style.display=`flex`:n.style.display=`none`)}let sT=`inline-flex`;function cT(e){let{stream:t,buttonVisibility:n,currentSourceType:r,isMuted:i,isAudioReady:a,isStopLocked:o,stopLockedTooltip:s,recordingState:c,buttonTranslations:l}=e,u=!!t,d=c===`idle`&&u,f=d&&!a,p=f?l.microphoneConnecting:``,m=!1;(n.showPauseButton||n.showResumeButton)&&(m=!0);let h=l.pause,g=`ph-fill ph-pause`;n.showResumeButton&&(h=l.resume,g=`ph-fill ph-play`);let _=l.mute,v=`ph-fill ph-microphone`;i&&(_=l.unmute,v=`ph-fill ph-microphone-slash`);let y=`ph-fill ph-monitor`;r!==mw&&(y=`ph-fill ph-camera`);let b=!1;return n.showDownloadButton&&(b=!0),{showRecordingControls:u,showSettingsButton:n.showSettingsButton,showRecordButton:d,isRecordDisabled:f,recordTooltip:p,showMuteButton:n.showMuteButton,showPauseButton:m,showStopButton:n.showStopButton,showSwitchSourceButton:n.showSwitchSourceButton,showDownloadButton:b,pauseTitle:h,pauseIconClassName:g,muteTitle:_,muteIconClassName:v,switchSourceIconClassName:y,isMuted:i,isStopLocked:o,stopLockedTooltip:s,settingsTitle:l.settings,switchSourceTitle:l.switchSource,downloadTitle:l.download,buttonTranslations:l}}function lT(e){return{recordingControls:e.querySelector(`#recordingControls`),settingsButton:e.querySelector(`#btnSettings`),recordButton:e.querySelector(`#btnRecord`),muteButton:e.querySelector(`#btnMute`),muteIcon:e.querySelector(`#iconMute`),pauseButton:e.querySelector(`#btnPause`),pauseIcon:e.querySelector(`#iconPause`),stopButton:e.querySelector(`#btnStop`),switchSourceButton:e.querySelector(`#btnSwitchSource`),switchSourceIcon:e.querySelector(`#iconSwitchSource`),downloadButton:e.querySelector(`#btnDownload`)}}function uT(e,t){let{recordingControls:n,settingsButton:r,recordButton:i,muteButton:a,muteIcon:o,pauseButton:s,pauseIcon:c,stopButton:l,switchSourceButton:u,switchSourceIcon:d,downloadButton:f}=t;fT(n,e),pT(r,e),mT(i,e),hT(a,e),gT(o,e),_T(s,e),vT(c,e),yT(l,e),bT(u,e),xT(d,e),ST(f,e)}function dT(e,t,n){e&&(t?e.style.display=n:e.style.display=`none`)}function fT(e,t){dT(e,t.showRecordingControls,`block`)}function pT(e,t){dT(e,t.showSettingsButton,sT),e&&(e.title=t.settingsTitle)}function mT(e,t){if(dT(e,t.showRecordButton,sT),!e)return;e.disabled=t.isRecordDisabled,e.classList.toggle(`vidtreo-record-button-disabled`,t.isRecordDisabled),e.title=t.recordTooltip,e.setAttribute(`aria-disabled`,String(t.isRecordDisabled));let n=e.querySelector(`i`),r=e.querySelector(`span`);t.isRecordDisabled?(n&&(n.className=`ph-fill ph-microphone vidtreo-mic-connecting-indicator`,n.style.fontSize=`18px`),r&&(r.textContent=t.recordTooltip)):(n&&(n.className=`ph-fill ph-circle`,n.style.fontSize=`24px`),r&&(r.textContent=t.buttonTranslations?.record??`Record`))}function hT(e,t){dT(e,t.showMuteButton,sT),e&&(e.title=t.muteTitle,e.classList.toggle(`vidtreo-muted`,t.isMuted))}function gT(e,t){e&&(e.className=t.muteIconClassName)}function _T(e,t){dT(e,t.showPauseButton,sT),e&&(e.title=t.pauseTitle)}function vT(e,t){e&&(e.className=t.pauseIconClassName)}function yT(e,t){if(dT(e,t.showStopButton,sT),e){if(e.classList.toggle(`vidtreo-stop-button-locked`,t.isStopLocked),e.setAttribute(`aria-disabled`,String(t.isStopLocked)),t.isStopLocked){e.title=t.stopLockedTooltip;return}e.title=``}}function bT(e,t){dT(e,t.showSwitchSourceButton,sT),e&&(e.title=t.switchSourceTitle)}function xT(e,t){e&&(e.className=t.switchSourceIconClassName)}function ST(e,t){dT(e,t.showDownloadButton,sT),e&&(e.title=t.downloadTitle)}function CT(e){let{stream:t,showSettings:n}=e,r=!1;return t&&n&&(r=!0),{shouldShow:r}}function wT(e,t,n){if(t){if(!e.shouldShow){t.classList.remove(`vidtreo-active`);return}t.classList.add(`vidtreo-active`),n()}}function TT(e){return e.toggleMute(),e.getIsMuted()}function ET(e){if(!e)return;let t=URL.createObjectURL(e),n=document.createElement(`a`);n.href=t,n.download=`recording-${Date.now()}.mp4`,document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(t)}let DT={en:{initializingCamera:`Initializing camera...`,grantPermissions:`Grant camera and microphone permissions when prompted`,browserUnsupported:`This browser is not supported`,browserUnsupportedDynamic:`{browser} ({version}) is not supported, please use <a href="https://www.google.com/chrome/" target="_blank">Chrome</a>`,browserUnsupportedSafari:`Safari is not supported, please use <a href="https://www.google.com/chrome/" target="_blank">Chrome</a>`,browserUnsupportedFirefox:`Firefox is not supported, please use <a href="https://www.google.com/chrome/" target="_blank">Chrome</a>`,retryCamera:`Retry Camera`,cameraInUse:`Your camera is being used by another application. Close other apps using the camera (Zoom, Teams, Discord) and try again.`,cameraNotFound:`No camera detected. Connect a camera or check your device settings.`,cameraPermissionDenied:`Camera access was denied. Allow camera access in your browser settings and try again.`,cameraTimeout:`The camera took too long to start. Close other apps using the camera and try again.`,audioInUse:`Your microphone is being used by another application. Close other apps using the microphone (Zoom, Teams, Discord) and try again.`,audioNotFound:`No microphone detected. Connect a microphone or check your device settings.`,audioPermissionDenied:`Microphone access was denied. Allow microphone access in your browser settings and try again.`,audioTimeout:`The microphone took too long to start. Close other apps using the microphone and try again.`,failedToStartAudio:`Failed to start microphone`,audioErrorTitle:`Microphone unavailable`,audioErrorMessage:`We couldn't access your microphone. It may be in use by another app like Zoom, Teams, or Discord. Please close it and try again.`,audioErrorRetry:`Try again`,audioMissingTitle:`Recording has no audio`,audioMissingMessage:`We couldn't capture audio in this recording. Your microphone may have been disconnected or blocked by the browser. Check your microphone and record again.`,audioSilentTitle:`Recording is silent`,audioSilentMessage:`We didn't detect any sound during the recording. Make sure your microphone is working and not muted by your operating system, then record again.`,audioProcessingErrorTitle:`Audio processing error`,audioProcessingErrorMessage:`We couldn't process the audio in this recording. Please record again.`,audioMissingRetry:`Record again`,audioWarningNoSignalTitle:`No microphone signal`,audioWarningNoSignalMessage:`We're not detecting any sound. Check that your microphone is active.`,audioWarningLowSignalTitle:`Audio is very quiet`,audioWarningLowSignalMessage:`Move closer to the microphone or turn up the input volume.`,audioWarningSpeakingMutedTitle:`You're speaking while muted`,audioWarningSpeakingMutedMessage:`Unmute your microphone if you want your voice in the recording.`,audioWarningTrackEndedTitle:`Microphone disconnected`,audioWarningTrackEndedMessage:`The microphone was disconnected. Reconnect it before continuing.`,audioWarningNoChunksTitle:`No microphone input`,audioWarningNoChunksMessage:`We're not receiving audio from the microphone. Check browser permissions.`,audioWarningTrackMutedTitle:`Microphone muted by browser`,audioWarningTrackMutedMessage:`The browser muted your microphone. Check site settings.`,audioWarningDismiss:`Dismiss`,cameraErrorTitle:`Camera unavailable`,cameraErrorMessage:`We couldn't access your camera. It may be in use by another app or permissions may be denied.`,browserErrorTitle:`Browser not supported`,browserErrorMessage:`This browser is not supported. Please use Chrome for the best experience.`,recordingCodecUnsupportedTitle:`Recording format not supported`,recordingCodecUnsupportedMessage:`This device can't use the selected video format. Close other apps, update Chrome if possible, and record again.`,recordingServerTranscodeFallbackTitle:`Finalizing on device`,recordingServerTranscodeFallbackMessage:`We're finishing the video on this device before upload. Keep this tab open.`,recordingTrackEndedTitle:`Camera stopped during recording`,recordingTrackEndedMessage:`The camera feed ended before the recording finished. Check that the camera is still connected and record again.`,recordingFinalizeTimeoutTitle:`Recording took too long to finish`,recordingFinalizeTimeoutMessage:`This device may be low on memory or processing power. Close other apps or browser tabs, then record again.`,recordingStateRaceTitle:`Recording did not start correctly`,recordingStateRaceMessage:`The recording could not be finalized because it did not start cleanly. Please refresh the page and record again.`,recordingNoFramesTitle:`No video was captured`,recordingNoFramesMessage:`We couldn't receive video frames from the camera. Check your camera connection and record again.`,recordingUnsupportedTitle:`Recording not available`,recordingUnsupportedMessage:`This device or browser can't record video reliably right now. Check your connection, update Chrome if possible, or use another device.`,recordingPipelineRetry:`Record again`,genericErrorTitle:`Something went wrong`,genericErrorMessage:`An unexpected error occurred. Please try again.`,errorRetry:`Try again`,switchingDevice:`Switching device...`,recordingStartsIn:`Recording starts in...`,switchingSource:`Switching source...`,rec:`REC`,settings:`Settings`,record:`Record`,stop:`Stop`,pause:`Pause`,resume:`Resume`,mute:`Mute`,unmute:`Unmute`,switchSource:`Switch Source`,camera:`Camera`,microphone:`Microphone`,microphoneConnecting:`Connecting microphone...`,minimumRecordingTimeNotReached:`You have not met the minimum recording time yet`,processVideo:`Process Video`,processing:`Processing...`,finishing:`Finishing...`,uploading:`Uploading...`,switchingCamera:`Switching camera...`,switchingMicrophone:`Switching microphone...`,failedToStartCamera:`Failed to start camera`,userInAnotherTab:`User in another tab`,download:`Download`,nativeCameraSelectVideo:`Select Video from Gallery`,nativeCameraRecordVideo:`Record with Camera`,errorTitle:`Configuration Error`,errorGeneric:`An error occurred while loading the configuration`,mobileOpenCamera:`Open Camera`,mobileOpenCameraTitle:`Record a Video`,mobileOpenCameraDescription:`Tap the button below to start recording`,mobileCloseCamera:`Close`,mobilePermissionDenied:`Camera Access Denied`,mobilePermissionDeniedDescription:`Please allow camera access in your browser settings to record video.`,permissionFlowTitle:`Set Up Your Camera`,permissionFlowCameraTitle:`Camera & Microphone`,permissionFlowMicrophoneTitle:`Camera & Microphone`,permissionFlowCameraLabel:`We need access to your camera and microphone to start recording`,permissionFlowMicrophoneLabel:`We need access to your camera and microphone to start recording`,permissionFlowStatusPending:`Pending`,permissionFlowStatusGranted:`Ready`,permissionFlowStatusDenied:`Blocked`,permissionFlowStatusRequesting:`Click "Allow" in the browser popup above`,permissionFlowAllowCamera:`Allow Access`,permissionFlowAllowMicrophone:`Allow Access`,permissionFlowRetry:`Try Again`,permissionFlowRecoveryTitle:`Allow access to continue`,permissionFlowRecoveryInstructions:`Open your browser settings and allow camera and microphone access, then try again.`,permissionFlowConnecting:`Setting up...`},es:{initializingCamera:`Inicializando cámara...`,grantPermissions:`Otorga permisos de cámara y micrófono cuando se solicite`,browserUnsupported:`Este navegador no es compatible`,browserUnsupportedDynamic:`{browser} ({version}) no es compatible, por favor usa <a href="https://www.google.com/chrome/" target="_blank">Chrome</a>`,browserUnsupportedSafari:`Safari no es compatible, usa <a href="https://www.google.com/chrome/" target="_blank">Chrome</a>`,browserUnsupportedFirefox:`Firefox no es compatible, usa <a href="https://www.google.com/chrome/" target="_blank">Chrome</a>`,retryCamera:`Reintentar Cámara`,cameraInUse:`Tu cámara está siendo usada por otra aplicación. Cierra otras apps que usen la cámara (Zoom, Teams, Discord) e intenta de nuevo.`,cameraNotFound:`No se detectó ninguna cámara. Conecta una cámara o revisa la configuración de tu dispositivo.`,cameraPermissionDenied:`Se denegó el acceso a la cámara. Permite el acceso a la cámara en la configuración de tu navegador e intenta de nuevo.`,cameraTimeout:`La cámara tardó demasiado en iniciar. Cierra otras apps que usen la cámara e intenta de nuevo.`,audioInUse:`Tu micrófono está siendo usado por otra aplicación. Cierra otras apps que usen el micrófono (Zoom, Teams, Discord) e intenta de nuevo.`,audioNotFound:`No se detectó ningún micrófono. Conecta un micrófono o revisa la configuración de tu dispositivo.`,audioPermissionDenied:`Se denegó el acceso al micrófono. Permite el acceso al micrófono en la configuración de tu navegador e intenta de nuevo.`,audioTimeout:`El micrófono tardó demasiado en iniciar. Cierra otras apps que usen el micrófono e intenta de nuevo.`,failedToStartAudio:`Error al iniciar el micrófono`,audioErrorTitle:`Micrófono no disponible`,audioErrorMessage:`No pudimos acceder a tu micrófono. Puede estar en uso por otra app como Zoom, Teams o Discord. Ciérrala e inténtalo de nuevo.`,audioErrorRetry:`Intentar de nuevo`,audioMissingTitle:`La grabación no tiene audio`,audioMissingMessage:`No pudimos capturar audio en esta grabación. Es posible que el micrófono se haya desconectado o que el navegador lo haya bloqueado. Verifica tu micrófono y vuelve a grabar.`,audioSilentTitle:`La grabación quedó en silencio`,audioSilentMessage:`No detectamos sonido durante la grabación. Verifica que tu micrófono esté funcionando y no esté silenciado por el sistema, luego vuelve a grabar.`,audioProcessingErrorTitle:`Error al procesar el audio`,audioProcessingErrorMessage:`No pudimos procesar el audio de esta grabación. Por favor vuelve a grabar.`,audioMissingRetry:`Grabar de nuevo`,audioWarningNoSignalTitle:`Sin señal del micrófono`,audioWarningNoSignalMessage:`No estamos detectando sonido. Verifica que tu micrófono esté activo.`,audioWarningLowSignalTitle:`Audio muy bajo`,audioWarningLowSignalMessage:`Acércate al micrófono o sube el volumen de entrada.`,audioWarningSpeakingMutedTitle:`Estás hablando muteado`,audioWarningSpeakingMutedMessage:`Activa el micrófono si quieres que tu voz se escuche en la grabación.`,audioWarningTrackEndedTitle:`Micrófono desconectado`,audioWarningTrackEndedMessage:`Se desconectó el micrófono. Reconéctalo antes de continuar.`,audioWarningNoChunksTitle:`Sin entrada del micrófono`,audioWarningNoChunksMessage:`No estamos recibiendo audio del micrófono. Revisa los permisos del navegador.`,audioWarningTrackMutedTitle:`Micrófono silenciado por el navegador`,audioWarningTrackMutedMessage:`El navegador silenció tu micrófono. Revisa la configuración del sitio.`,audioWarningDismiss:`Cerrar`,cameraErrorTitle:`Cámara no disponible`,cameraErrorMessage:`No pudimos acceder a tu cámara. Puede estar en uso por otra app o los permisos pueden estar denegados.`,browserErrorTitle:`Navegador no compatible`,browserErrorMessage:`Este navegador no es compatible. Por favor usa Chrome para la mejor experiencia.`,recordingCodecUnsupportedTitle:`Formato de grabación no compatible`,recordingCodecUnsupportedMessage:`Este dispositivo no puede usar el formato de video seleccionado. Cierra otras apps, actualiza Chrome si es posible y vuelve a grabar.`,recordingServerTranscodeFallbackTitle:`Finalizando en el dispositivo`,recordingServerTranscodeFallbackMessage:`Estamos finalizando el video en este dispositivo antes de subirlo. Mantén esta pestaña abierta.`,recordingTrackEndedTitle:`La cámara se detuvo durante la grabación`,recordingTrackEndedMessage:`La señal de la cámara terminó antes de finalizar la grabación. Verifica que la cámara siga conectada y vuelve a grabar.`,recordingFinalizeTimeoutTitle:`La grabación tardó demasiado en finalizar`,recordingFinalizeTimeoutMessage:`Es posible que este dispositivo tenga poca memoria o potencia de procesamiento. Cierra otras apps o pestañas del navegador y vuelve a grabar.`,recordingStateRaceTitle:`La grabación no inició correctamente`,recordingStateRaceMessage:`No se pudo finalizar la grabación porque no inició correctamente. Actualiza la página y vuelve a grabar.`,recordingNoFramesTitle:`No se capturó video`,recordingNoFramesMessage:`No pudimos recibir fotogramas de video de la cámara. Verifica la conexión de la cámara y vuelve a grabar.`,recordingUnsupportedTitle:`Grabación no disponible`,recordingUnsupportedMessage:`Este dispositivo o navegador no puede grabar video de forma estable ahora. Revisa tu conexión, actualiza Chrome si es posible o usa otro dispositivo.`,recordingPipelineRetry:`Grabar de nuevo`,genericErrorTitle:`Algo salió mal`,genericErrorMessage:`Ocurrió un error inesperado. Por favor intenta de nuevo.`,errorRetry:`Intentar de nuevo`,switchingDevice:`Cambiando dispositivo...`,recordingStartsIn:`La grabación comienza en...`,switchingSource:`Cambiando fuente...`,rec:`GRAB`,settings:`Configuración`,record:`Grabar`,stop:`Detener`,pause:`Pausar`,resume:`Reanudar`,mute:`Silenciar`,unmute:`Activar sonido`,switchSource:`Cambiar Fuente`,camera:`Cámara`,microphone:`Micrófono`,microphoneConnecting:`Conectando micrófono...`,minimumRecordingTimeNotReached:`Aun no cumples el tiempo minimo de grabacion`,processVideo:`Procesar Video`,processing:`Procesando...`,finishing:`Finalizando...`,uploading:`Subiendo...`,switchingCamera:`Cambiando cámara...`,switchingMicrophone:`Cambiando micrófono...`,failedToStartCamera:`Error al iniciar la cámara`,userInAnotherTab:`Usuario en otra pestaña`,download:`Descargar`,nativeCameraSelectVideo:`Seleccionar Video de la Galería`,nativeCameraRecordVideo:`Grabar con Cámara`,errorTitle:`Error de Configuración`,errorGeneric:`Ocurrió un error al cargar la configuración`,mobileOpenCamera:`Abrir Cámara`,mobileOpenCameraTitle:`Grabar un Video`,mobileOpenCameraDescription:`Toca el botón para comenzar a grabar`,mobileCloseCamera:`Cerrar`,mobilePermissionDenied:`Acceso a Cámara Denegado`,mobilePermissionDeniedDescription:`Por favor permite el acceso a la cámara en la configuración de tu navegador para grabar video.`,permissionFlowTitle:`Configurar tu Cámara`,permissionFlowCameraTitle:`Cámara y Micrófono`,permissionFlowMicrophoneTitle:`Cámara y Micrófono`,permissionFlowCameraLabel:`Necesitamos acceso a tu cámara y micrófono para comenzar a grabar`,permissionFlowMicrophoneLabel:`Necesitamos acceso a tu cámara y micrófono para comenzar a grabar`,permissionFlowStatusPending:`Pendiente`,permissionFlowStatusGranted:`Listo`,permissionFlowStatusDenied:`Bloqueado`,permissionFlowStatusRequesting:`Haz clic en "Permitir" en el aviso del navegador`,permissionFlowAllowCamera:`Permitir Acceso`,permissionFlowAllowMicrophone:`Permitir Acceso`,permissionFlowRetry:`Reintentar`,permissionFlowRecoveryTitle:`Permite el acceso para continuar`,permissionFlowRecoveryInstructions:`Abre la configuración de tu navegador y permite el acceso a la cámara y micrófono, luego intenta de nuevo.`,permissionFlowConnecting:`Preparando...`}};var OT=class{constructor(e=`en`,t={}){this.lang=e,this.customTexts=t}setLang(e){this.lang=e}setCustomTexts(e){this.customTexts=e}t(e){return this.customTexts[e]?this.customTexts[e]:(DT[this.lang]||DT.en)[e]}getAll(){return{...DT[this.lang]||DT.en,...this.customTexts}}};let kT=new Map;function AT(e){e.style.position=`fixed`,e.style.top=`0`,e.style.left=`0`,e.style.width=`100vw`,e.style.height=`100vh`,e.style.height=`100dvh`,e.style.zIndex=`9999`,e.style.pointerEvents=`none`}function jT(e){e.style.pointerEvents=`auto`}function MT(e){e.style.pointerEvents=`none`}var NT=class{constructor(e=`vidtreo-portal-root`){this.portalContainer=null,this.contentWrapper=null,this.isRegistered=!1,this.containerId=e,this.instanceId=`portal-${Date.now()}-${Math.random().toString(36).slice(2,9)}`}get container(){return this.contentWrapper}get isActive(){return this.contentWrapper!==null&&this.portalContainer!==null}open(){let e=document.getElementById(this.containerId);return e||(e=document.createElement(`div`),e.id=this.containerId,AT(e),document.body.appendChild(e)),this.portalContainer=e,this.contentWrapper=document.createElement(`div`),this.contentWrapper.setAttribute(`data-portal-instance`,this.instanceId),this.contentWrapper.style.width=`100%`,this.contentWrapper.style.height=`100%`,this.portalContainer.appendChild(this.contentWrapper),this.registerInstance(),jT(e),this.contentWrapper}render(e){this.contentWrapper&&(this.contentWrapper.innerHTML=e)}querySelector(e){return this.contentWrapper?this.contentWrapper.querySelector(e):null}close(){this.contentWrapper&&=(this.contentWrapper.innerHTML=``,this.contentWrapper.remove(),null),this.unregisterInstance(),this.updatePortalContainerState()}destroy(){this.close(),this.portalContainer=null}registerInstance(){if(this.isRegistered)return;let e=kT.get(this.containerId);e||(e=new Set,kT.set(this.containerId,e)),e.add(this),this.isRegistered=!0}unregisterInstance(){if(!this.isRegistered)return;let e=kT.get(this.containerId);e&&(e.delete(this),e.size===0&&kT.delete(this.containerId)),this.isRegistered=!1}updatePortalContainerState(){if(!this.portalContainer)return;let e=kT.get(this.containerId);e&&e.size>0?jT(this.portalContainer):(MT(this.portalContainer),this.portalContainer.childNodes.length===0&&this.portalContainer.remove())}},PT=class{constructor(e){this.state={isModalOpen:!1,permissionRequested:!1,prevUploading:!1},this.escapeHandler=null,this.initCheckInterval=null,this.callbacks=e,this.portalManager=new NT}get canCloseModal(){let{recordingState:e}=this.callbacks.getState();return!(e===`recording`||e===`countdown`)}get isModalOpen(){return this.state.isModalOpen}get portal(){return this.portalManager}openModal(){this.state.isModalOpen=!0,this.state.permissionRequested=!1,this.portalManager.open(),document.body.style.overflow=`hidden`,this.setupEscapeHandler(),this.callbacks.renderMobile(),this.requestCameraPreview()}closeModal(){this.canCloseModal&&(this.callbacks.stopPreview(),this.state.isModalOpen=!1,this.state.permissionRequested=!1,document.body.style.overflow=``,this.removeEscapeHandler(),this.portalManager.close(),this.callbacks.renderMobile())}checkUploadCompletion(e){let t=this.state.prevUploading,n=e!==null;this.state.prevUploading=n,t&&!n&&this.state.isModalOpen&&this.closeModal()}requestCameraPreview(){if(this.state.permissionRequested)return;let e=()=>{this.callbacks.isInitialized()?(this.state.permissionRequested=!0,this.callbacks.startPreview().catch(()=>{})):this.initCheckInterval=setTimeout(e,100)};e()}setupEscapeHandler(){this.escapeHandler=e=>{e.key===`Escape`&&this.canCloseModal&&this.closeModal()},document.addEventListener(`keydown`,this.escapeHandler)}removeEscapeHandler(){this.escapeHandler&&=(document.removeEventListener(`keydown`,this.escapeHandler),null)}destroy(){this.removeEscapeHandler(),this.portalManager.destroy(),document.body.style.overflow=``,this.initCheckInterval&&=(clearTimeout(this.initCheckInterval),null)}},FT=class{constructor(e,t){this.state={file:null,transcodingProgress:null,uploadProgress:null,isTranscoding:!1,isConfigLoading:!0,error:null,transcodedBlob:null},this.handler=null,this.config=e,this.callbacks=t;let n=e.backendUrl||`https://core.vidtreo.com`,r=null;e.apiKey&&!e.demo&&(r=un.getInstance({apiKey:e.apiKey,backendUrl:n}));let i=new yS;this.handler=new dy({apiKey:e.apiKey,backendUrl:n,maxRecordingTime:e.maxRecordingTime,maxFileSize:e.maxFileSize,userMetadata:e.userMetadata},r,i),e.apiKey&&!e.demo?(this.updateState({isConfigLoading:!0}),this.handler.preloadConfig().then(()=>this.updateState({isConfigLoading:!1})).catch(()=>{this.updateState({isConfigLoading:!1,error:`Failed to load settings`})})):this.updateState({isConfigLoading:!1})}updateState(e){this.state={...this.state,...e},this.callbacks.onStateChange()}getState(){return this.state}async handleFileSelect(e){if(this.updateState({error:null}),!this.handler)throw Error(`Handler not initialized`);try{let t=await this.handler.handleFileSelection(e);return this.updateState({file:t}),t}catch(e){let t=i(e),n=e instanceof Error?e:Error(t);throw this.updateState({error:t}),this.callbacks.onError?.(n),n}}async processAndUpload(e){let t=e||this.state.file;if(!(t&&this.handler))return;let n=this.config.demo;try{if(this.updateState({isTranscoding:!0,transcodingProgress:0,error:null}),n){let e=await ly(t.file,Xt,e=>{this.updateState({transcodingProgress:e}),this.callbacks.onTranscodingProgress?.(e)});this.updateState({transcodedBlob:e.blob,isTranscoding:!1,transcodingProgress:null})}else{let e=await this.handler.processAndUpload(e=>{this.updateState({transcodingProgress:e}),this.callbacks.onTranscodingProgress?.(e)},e=>{this.updateState({uploadProgress:e}),this.callbacks.onUploadProgress?.(e)});this.updateState({file:null,transcodingProgress:null,uploadProgress:null,isTranscoding:!1}),this.callbacks.onUploadComplete?.({recordingId:e.recordingId||``,uploadUrl:e.uploadUrl||``})}}catch(e){let t=i(e),r=e instanceof Error?e:Error(t);this.updateState({error:t,isTranscoding:!1,transcodingProgress:null,uploadProgress:null,transcodedBlob:null}),this.callbacks.onError?.(r),n||this.callbacks.onUploadError?.(r)}}downloadVideo(){if(!this.state.transcodedBlob)return;let e=URL.createObjectURL(this.state.transcodedBlob),t=document.createElement(`a`);t.href=e,t.download=`recording-${Date.now()}.mp4`,document.body.appendChild(t),t.click(),document.body.removeChild(t),URL.revokeObjectURL(e)}reset(){this.updateState({file:null,transcodingProgress:null,uploadProgress:null,error:null,isTranscoding:!1,transcodedBlob:null})}destroy(){this.handler&&this.handler.cancel(),this.handler=null}};function IT(e){return{preview:{initializingCamera:e.initializingCamera,grantPermissions:e.grantPermissions,browserUnsupported:e.browserUnsupported,browserUnsupportedDynamic:e.browserUnsupportedDynamic,browserUnsupportedSafari:e.browserUnsupportedSafari,browserUnsupportedFirefox:e.browserUnsupportedFirefox,retryCamera:e.retryCamera,cameraInUse:e.cameraInUse,cameraNotFound:e.cameraNotFound,cameraPermissionDenied:e.cameraPermissionDenied,cameraTimeout:e.cameraTimeout,failedToStartCamera:e.failedToStartCamera,audioInUse:e.audioInUse,audioNotFound:e.audioNotFound,audioPermissionDenied:e.audioPermissionDenied,audioTimeout:e.audioTimeout,failedToStartAudio:e.failedToStartAudio,switchingDevice:e.switchingDevice,recordingStartsIn:e.recordingStartsIn,rec:e.rec},buttons:{settings:e.settings,record:e.record,stop:e.stop,minimumRecordingTimeNotReached:e.minimumRecordingTimeNotReached,pause:e.pause,resume:e.resume,mute:e.mute,unmute:e.unmute,switchSource:e.switchSource,download:e.download,microphoneConnecting:e.microphoneConnecting},settings:{settings:e.settings,camera:e.camera,microphone:e.microphone}}}var LT=class{constructor(e){if(this.proxyEndpoint=e.proxyEndpoint,this.proxyEndpoint)throw Error(`Proxy mode not yet implemented`);this.service=new yS}uploadVideo(e,t){if(this.proxyEndpoint)throw Error(`Proxy mode not yet implemented`);return this.service.uploadVideo(e,t)}},RT=`:root{--vidtreo-background:0 0% 100%;--vidtreo-foreground:0 0% 3.9%;--vidtreo-card:0 0% 100%;--vidtreo-card-foreground:0 0% 3.9%;--vidtreo-primary:0 0% 9%;--vidtreo-primary-foreground:0 0% 98%;--vidtreo-secondary:0 0% 96.1%;--vidtreo-secondary-foreground:0 0% 9%;--vidtreo-muted:0 0% 96.1%;--vidtreo-muted-foreground:0 0% 45.1%;--vidtreo-accent:0 0% 96.1%;--vidtreo-accent-foreground:0 0% 9%;--vidtreo-destructive:0 84.2% 60.2%;--vidtreo-destructive-foreground:0 0% 98%;--vidtreo-border:0 0% 89.8%;--vidtreo-input:0 0% 89.8%;--vidtreo-ring:0 0% 3.9%;--vidtreo-radius:.5rem;--vidtreo-preview-bg:0 0% 0%;--vidtreo-z-modal-overlay:9999;--vidtreo-z-settings-panel:200;--vidtreo-z-error-overlay:100;--vidtreo-z-countdown-overlay:20;--vidtreo-z-progress-overlay:20;--vidtreo-z-controls:10}.vidtreo-preview-container{aspect-ratio:9/16;background:hsl(var(--vidtreo-preview-bg));contain:layout style;will-change:auto;backface-visibility:hidden;isolation:isolate;border:none;border-radius:0;justify-content:center;align-items:center;width:100%;display:flex;position:relative;overflow:visible;transform:translateZ(0)}.vidtreo-preview-container:before{display:none}@media (width>=768px){.vidtreo-preview-container{aspect-ratio:16/9}}.vidtreo-camera-area{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;contain:layout style paint;backface-visibility:hidden;isolation:isolate;will-change:auto;width:100%;height:100%;font-family:-apple-system,BlinkMacSystemFont,SF Pro Display,SF Pro Text,system-ui,sans-serif;display:none;position:relative;transform:translateZ(0)}.vidtreo-source-transition-overlay{z-index:var(--vidtreo-z-error-overlay);backdrop-filter:blur(4px);contain:layout style paint;backface-visibility:hidden;will-change:opacity;background:#000000b3;border-radius:0;flex-direction:column;justify-content:center;align-items:center;transition:opacity .3s;display:none;position:absolute;inset:0;transform:translateZ(0)}.vidtreo-source-transition-overlay.vidtreo-active{animation:.2s vidtreo-fadeIn;display:flex}@keyframes vidtreo-fadeIn{0%{opacity:0}to{opacity:1}}.vidtreo-transition-spinner{border:4px solid #ffffff4d;border-top-color:#667eea;border-radius:50%;width:40px;height:40px;margin-bottom:12px;animation:.8s linear infinite vidtreo-spin}@keyframes vidtreo-spin{to{transform:rotate(360deg)}}.vidtreo-transition-message{color:#fff;text-align:center;font-size:14px;font-weight:500}.vidtreo-camera-area.vidtreo-active{display:block}.vidtreo-preview-skeleton{z-index:var(--vidtreo-z-controls);contain:layout style paint;backface-visibility:hidden;will-change:auto;background:#000;border-radius:0;flex-direction:column;justify-content:center;align-items:center;gap:1rem;display:flex;position:absolute;inset:0;transform:translateZ(0)}.vidtreo-skeleton-spinner{border:4px solid #ffffff4d;border-top-color:#fff;border-radius:50%;width:40px;height:40px;animation:.8s linear infinite vidtreo-spin}.vidtreo-skeleton-text{color:#fff;font-size:.875rem;font-weight:500}.vidtreo-video-preview{object-fit:cover;will-change:auto;backface-visibility:hidden;background:#000;border-radius:0;width:100%;height:100%;transition:opacity .3s,transform .3s;display:block;position:absolute;inset:0;transform:translateZ(0)}.vidtreo-video-preview-skeleton{z-index:2;contain:layout style paint;backface-visibility:hidden;will-change:auto;background:#000;border-radius:0;width:100%;height:100%;position:absolute;inset:0;overflow:hidden;transform:translateZ(0)}.vidtreo-skeleton-shimmer{background:linear-gradient(90deg, hsl(var(--vidtreo-muted)) 0%, hsl(var(--vidtreo-muted) / .5) 50%, hsl(var(--vidtreo-muted)) 100%);background-size:200% 100%;animation:1.5s ease-in-out infinite vidtreo-shimmer;position:absolute;inset:0}@keyframes vidtreo-shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}.vidtreo-video-preview-skeleton.vidtreo-hidden{opacity:0;pointer-events:none;transition:opacity .3s}.vidtreo-video-preview.vidtreo-screen-share{object-fit:cover}.vidtreo-video-preview.vidtreo-transitioning{opacity:.5;transform:scale(.98)}.vidtreo-countdown-overlay{z-index:var(--vidtreo-z-countdown-overlay);contain:layout style paint;backface-visibility:hidden;will-change:auto;background:#000000f2;border-radius:0;justify-content:center;align-items:center;display:none;position:absolute;inset:0;transform:translateZ(0)}.vidtreo-countdown-overlay.vidtreo-active{display:flex}.vidtreo-countdown-content{flex-direction:column;align-items:center;gap:1rem;display:flex}.vidtreo-countdown-number{color:#fff;font-size:9rem;font-weight:700;animation:.3s vidtreo-zoomIn}@keyframes vidtreo-zoomIn{0%{opacity:0;transform:scale(.5)}to{opacity:1;transform:scale(1)}}.vidtreo-countdown-text{color:#fff;margin-top:1rem;font-size:.875rem;font-weight:500}.vidtreo-settings-panel{z-index:var(--vidtreo-z-settings-panel);contain:layout style paint;backface-visibility:hidden;background:#0006;border:none;border-radius:.75rem;flex-direction:column;width:90%;margin-left:-47%;padding:.625rem;display:none;overflow:hidden;transform:translateZ(0);position:absolute!important;bottom:4rem!important;left:50%!important}.vidtreo-settings-panel.vidtreo-active{display:flex}.vidtreo-settings-content{will-change:transform;backface-visibility:hidden;flex-direction:column;width:100%;display:flex;transform:translateZ(0)}.vidtreo-settings-content.vidtreo-slide-right{animation:.3s vidtreo-slideRight}.vidtreo-settings-content.vidtreo-slide-left{animation:.3s vidtreo-slideLeft}.vidtreo-settings-content.vidtreo-slide-none{will-change:auto;animation:none}@keyframes vidtreo-slideIn{0%{opacity:0;transform:translateY(1rem)}to{opacity:1;transform:translateY(0)}}@keyframes vidtreo-slideRight{0%{opacity:0;transform:translate(-100%)}to{opacity:1;transform:translate(0)}}@keyframes vidtreo-slideLeft{0%{opacity:0;transform:translate(100%)}to{opacity:1;transform:translate(0)}}.vidtreo-settings-header{color:#fff;cursor:pointer;text-align:left;background:0 0;border:none;align-items:center;gap:.75rem;width:100%;margin-bottom:1rem;padding:0;display:flex}.vidtreo-settings-back-icon{color:#fff;flex-shrink:0}.vidtreo-settings-title{color:#fff;margin:0;font-size:.875rem;font-weight:600}.vidtreo-device-options-container{flex-direction:column;gap:.375rem;display:flex}.vidtreo-device-option-nav{cursor:pointer;color:#fff;background:0 0;border:none;border-radius:.5rem;align-items:center;gap:1rem;width:100%;padding:.5rem .75rem;transition:background-color .2s;display:flex}.vidtreo-device-option-nav:hover{background:#fff3}.vidtreo-device-option-nav-content{flex-shrink:0;align-items:center;gap:.75rem;display:flex}.vidtreo-device-option-nav-label{color:#fff;font-size:.875rem;font-weight:500}.vidtreo-device-option-nav-value{flex:1;justify-content:flex-end;align-items:center;gap:.5rem;min-width:0;display:flex}.vidtreo-device-option-nav-value-text{color:#fffc;text-overflow:ellipsis;white-space:nowrap;text-align:right;flex:1;font-size:.875rem;overflow:hidden}.vidtreo-device-option-nav-chevron{color:#fff;font-size:1.25rem;line-height:1}.vidtreo-device-list{flex-direction:column;gap:0;max-height:200px;display:flex;overflow-y:auto}.vidtreo-device-list::-webkit-scrollbar{width:4px}.vidtreo-device-list::-webkit-scrollbar-track{background:0 0}.vidtreo-device-list::-webkit-scrollbar-thumb{background:#fff3;border-radius:2px}.vidtreo-device-list::-webkit-scrollbar-thumb:hover{background:#ffffff4d}.vidtreo-device-option{cursor:pointer;color:#fff;text-align:left;background:0 0;border:none;border-radius:.5rem;align-items:center;gap:.75rem;width:100%;padding:.5rem .75rem;transition:background-color .2s;display:flex}.vidtreo-device-option:hover{background:#fff3}.vidtreo-device-option-check-container{flex-shrink:0;justify-content:center;align-items:center;width:20px;height:20px;display:flex}.vidtreo-device-checkmark-placeholder{flex-shrink:0;width:20px;height:20px}.vidtreo-device-checkmark{color:#fff;flex-shrink:0}.vidtreo-device-option-label{color:#fff;flex:1;font-size:.875rem}.vidtreo-device-empty{color:#fff9;text-align:center;padding:1rem 0;font-size:.875rem}.vidtreo-audio-level-bars{height:1rem;z-index:var(--vidtreo-z-controls);contain:layout style paint;will-change:auto;backface-visibility:hidden;align-items:center;gap:.125rem;transform:translateZ(0);display:flex!important;position:absolute!important;bottom:.75rem!important;right:.75rem!important}@media (width>=768px){.vidtreo-audio-level-bars{height:1.25rem}}.vidtreo-audio-level-bar{background:#ffffff80;border-radius:9999px;align-self:flex-end;width:.125rem;transition:all .1s}.vidtreo-recording-controls{z-index:var(--vidtreo-z-controls);contain:layout style;will-change:auto;backface-visibility:hidden;position:absolute!important;bottom:12px!important;left:50%!important;transform:translate(-50%)translateZ(0)!important}.vidtreo-recording-controls-row{will-change:auto;justify-content:center;align-items:center;gap:.5rem;display:flex;transform:translateZ(0)}.vidtreo-recording-timer-row{justify-content:space-between;align-items:center;gap:.5rem;display:flex}.vidtreo-recording-timer-badge{z-index:var(--vidtreo-z-controls);contain:layout style paint;will-change:auto;backface-visibility:hidden;background:#0000004d;border:none;border-radius:9999px;align-items:center;gap:.375rem;padding:.25rem .5rem;transform:translateZ(0);box-shadow:0 1px 3px #0000001a,0 1px 2px -1px #0000001a;display:flex!important;position:absolute!important;top:.75rem!important;right:.75rem!important}.vidtreo-recording-dot-small{background:hsl(var(--vidtreo-destructive));border-radius:50%;width:.375rem;height:.375rem;animation:1.5s ease-in-out infinite vidtreo-pulse}.vidtreo-recording-timer-text{color:#fff;font-family:monospace;font-size:.75rem;font-weight:500}.vidtreo-control-buttons-row{will-change:auto;justify-content:center;align-items:center;gap:.375rem;height:auto;min-height:2rem;display:flex;transform:translateZ(0)}@media (width>=768px){.vidtreo-control-buttons-row{min-height:2.25rem}}.vidtreo-control-button{cursor:pointer;color:#fff;box-sizing:border-box;vertical-align:top;contain:layout style paint;will-change:auto;backface-visibility:hidden;background:#0000004d;border:none;border-radius:9999px;flex-shrink:0;justify-content:center;align-items:center;width:2rem;height:2rem;min-height:2rem;max-height:2rem;margin:0;padding:.25rem;transition:background-color .2s;display:inline-flex;position:relative;transform:translateZ(0)}.vidtreo-control-button:before{content:"";z-index:0;border-radius:9999px;transition:background-color .2s;position:absolute;inset:.25rem}.vidtreo-control-button svg{color:inherit;z-index:1;flex-shrink:0;position:relative;width:22px!important;height:22px!important}@media (width>=768px){.vidtreo-control-button svg{width:24px!important;height:24px!important}.vidtreo-control-button{width:2.25rem;height:2.25rem;min-height:2.25rem;max-height:2.25rem}}.vidtreo-control-button:hover:not(:disabled):before{background:#fff3}.vidtreo-control-button:disabled{opacity:.5;cursor:not-allowed}.vidtreo-control-button.vidtreo-muted:before{background:#0000004d}.vidtreo-control-button.vidtreo-muted:hover:not(:disabled):before{background:#fff3}.vidtreo-record-button{background:hsl(var(--vidtreo-destructive));height:2rem;min-height:2rem;max-height:2rem;color:hsl(var(--vidtreo-destructive-foreground));box-sizing:border-box;vertical-align:top;cursor:pointer;border:none;border-radius:9999px;flex-shrink:0;justify-content:center;align-items:center;gap:.375rem;width:auto;margin:0;padding:0 .75rem;font-size:.75rem;font-weight:500;line-height:1;transition:background-color .2s,filter .2s;display:inline-flex}@media (width>=768px){.vidtreo-record-button{height:2.25rem;min-height:2.25rem;max-height:2.25rem;font-size:.875rem}}.vidtreo-record-button:hover:not(:disabled){filter:brightness(.85)}.vidtreo-record-button.vidtreo-stop-button-locked{opacity:.5;cursor:not-allowed;filter:none}.vidtreo-record-button.vidtreo-stop-button-locked:hover{filter:none}#startButton.vidtreo-record-button{animation:2s ease-in-out infinite vidtreo-record-glow-pulse}@keyframes vidtreo-record-glow-pulse{0%,to{box-shadow:0 0 8px 2px #ef444466,0 0 16px 4px #ef444433}50%{box-shadow:0 0 16px 4px #ef444499,0 0 32px 8px #ef44444d}}#startButton.vidtreo-record-button:hover:not(:disabled){animation-play-state:paused;box-shadow:0 0 20px 6px #ef4444b3,0 0 40px 10px #ef444459}.vidtreo-rec-indicator-top{contain:layout style paint;will-change:auto;backface-visibility:hidden;background:#0000004d;border:none;border-radius:9999px;align-items:center;gap:.375rem;padding:.25rem .5rem;transform:translateZ(0);box-shadow:0 1px 3px #0000001a,0 1px 2px -1px #0000001a;display:flex!important;position:absolute!important;top:.75rem!important;left:.75rem!important}.vidtreo-rec-indicator-top span{color:#fff;font-size:.75rem;font-weight:500}.vidtreo-start-camera-area{text-align:center;cursor:pointer;z-index:1;contain:layout style paint;backface-visibility:hidden;will-change:auto;background:#000;border:none;border-radius:0;flex-direction:column;justify-content:center;align-items:center;padding:40px;transition:all .3s;display:flex;position:absolute;inset:0;transform:translateZ(0)}.vidtreo-start-camera-area:hover:not(.vidtreo-loading){background:#000}.vidtreo-start-camera-area.vidtreo-loading{cursor:wait;opacity:.7}.vidtreo-start-camera-area.vidtreo-loading .vidtreo-camera-text{color:#fff;opacity:.7}.vidtreo-camera-icon{color:#fff;justify-content:center;margin-bottom:16px;font-size:48px;display:flex}.vidtreo-camera-text{color:#fff;margin-bottom:8px;font-weight:600}.vidtreo-camera-text a{color:#3b82f6;text-decoration:underline}.vidtreo-camera-text a:hover{color:#2563eb}.vidtreo-camera-hint{color:#fff;opacity:.8;font-size:12px}@keyframes vidtreo-pulse{0%,to{opacity:1}50%{opacity:.3}}.vidtreo-progress{margin-top:20px;display:none}.vidtreo-progress.vidtreo-active{display:block}.vidtreo-progress-bar{background:#e0e0e0;border-radius:4px;width:100%;height:8px;margin-bottom:8px;overflow:hidden}.vidtreo-progress-fill{background:linear-gradient(90deg,#667eea 0%,#764ba2 100%);width:0%;height:100%;transition:width .3s}.vidtreo-progress-text{text-align:center;color:#fff;font-size:14px}.vidtreo-error{color:#fff;text-align:center;z-index:var(--vidtreo-z-error-overlay);word-wrap:break-word;background:#dc2626;border:none;border-radius:.5rem;max-width:90%;padding:1rem 1.25rem;font-size:.875rem;font-weight:500;display:none;position:absolute;top:.75rem;left:50%;transform:translate(-50%);box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a}.vidtreo-error.vidtreo-active{animation:.3s ease-out vidtreo-error-fade-in-slide-down;display:block}@keyframes vidtreo-error-fade-in-slide-down{0%{opacity:0;transform:translate(-50%)translateY(-1rem)}to{opacity:1;transform:translate(-50%)translateY(0)}}.vidtreo-upload-progress{margin-top:20px;display:none}.vidtreo-upload-progress.vidtreo-active{display:block}.vidtreo-preview-container .vidtreo-upload-progress{margin-top:0}.vidtreo-upload-status{border-radius:8px;margin-top:20px;padding:16px;display:none}.vidtreo-upload-status.vidtreo-active{display:block}.vidtreo-upload-status.vidtreo-success{color:#22543d;background:#f0f9ff;border:2px solid #48bb78}.vidtreo-upload-status.vidtreo-error{color:#c33;background:#fee;border:2px solid #fcc}.vidtreo-upload-status-text{font-size:14px;font-weight:500}.vidtreo-preview-error{aspect-ratio:9/16;background:hsl(var(--vidtreo-preview-bg));contain:strict;will-change:auto;backface-visibility:hidden;isolation:isolate;border:none;border-radius:0;justify-content:center;align-items:center;width:100%;display:flex;position:relative;overflow:hidden;transform:translateZ(0)}@media (width>=768px){.vidtreo-preview-error{aspect-ratio:16/9}}.vidtreo-error-content{text-align:center;color:#fff;flex-direction:column;justify-content:center;align-items:center;gap:1rem;max-width:400px;padding:2rem;display:flex}.vidtreo-error-icon{font-size:3rem;line-height:1}.vidtreo-error-title{font-size:1.25rem;font-weight:600;line-height:1.2}.vidtreo-error-message{opacity:.9;word-break:break-word;font-size:.875rem;line-height:1.5}.vidtreo-error-config{text-align:left;border-top:1px solid #fff3;width:100%;margin-top:1.5rem;padding-top:1.5rem}.vidtreo-error-config-title{color:#fff;margin-bottom:.75rem;font-size:.875rem;font-weight:600}.vidtreo-error-config-item{color:#ffffffd9;margin-bottom:.5rem;font-size:.8125rem;line-height:1.6}.vidtreo-error-config-item code{color:#fff;background:#ffffff26;border-radius:.25rem;padding:.125rem .375rem;font-family:monospace;font-size:.75rem}.vidtreo-error-retry{background:hsl(var(--vidtreo-destructive));color:hsl(var(--vidtreo-destructive-foreground));cursor:pointer;border:none;border-radius:.375rem;margin-top:.5rem;padding:.5rem 1rem;font-size:.875rem;font-weight:500;transition:filter .2s}.vidtreo-error-retry:hover:not(:disabled){filter:brightness(.85)}.vidtreo-error-retry:disabled{opacity:.5;cursor:not-allowed}.vidtreo-error-overlay{background:hsl(var(--vidtreo-preview-bg));z-index:var(--vidtreo-z-error-overlay);justify-content:center;align-items:center;display:flex;position:absolute;inset:0}.vidtreo-native-camera-container{aspect-ratio:9/16;background:hsl(var(--vidtreo-preview-bg));border-radius:0;justify-content:center;align-items:center;width:100%;display:flex;position:relative;overflow:hidden}@media (width>=768px){.vidtreo-native-camera-container{aspect-ratio:16/9}}.vidtreo-native-camera-container:has(.vidtreo-native-camera-preview-container){background:0 0}.vidtreo-config-loading-indicator{z-index:var(--vidtreo-z-controls);position:absolute;top:8px;right:8px}.vidtreo-spinner-small{border:2px solid #ffffff4d;border-top-color:#fff;border-radius:50%;width:16px;height:16px;animation:.6s linear infinite spin}.vidtreo-native-camera-empty-state{flex-direction:column;justify-content:center;align-items:center;gap:16px;width:100%;height:100%;padding:24px;display:flex;position:relative}.vidtreo-native-camera-buttons{flex-direction:column;gap:12px;width:100%;max-width:300px;display:flex}.vidtreo-native-camera-process-button,.vidtreo-native-camera-download-button{z-index:30;position:absolute;bottom:24px;left:50%;transform:translate(-50%)}.vidtreo-native-camera-process-button .vidtreo-btn,.vidtreo-native-camera-download-button .vidtreo-btn{min-width:200px}.vidtreo-btn{border-radius:var(--vidtreo-radius);cursor:pointer;border:none;padding:12px 24px;font-size:1rem;font-weight:500;transition:all .2s}.vidtreo-btn:disabled{opacity:.5;cursor:not-allowed}.vidtreo-btn-primary{background:hsl(var(--vidtreo-primary));color:hsl(var(--vidtreo-primary-foreground))}.vidtreo-btn-primary:hover:not(:disabled){filter:brightness(.9)}.vidtreo-btn-secondary{background:hsl(var(--vidtreo-secondary));color:hsl(var(--vidtreo-secondary-foreground));border:1px solid hsl(var(--vidtreo-border))}.vidtreo-btn-secondary:hover:not(:disabled){background:hsl(var(--vidtreo-accent))}.vidtreo-transcoding-progress{width:100%;max-width:400px;padding:16px}.vidtreo-progress-bar{background:#fff3;border-radius:4px;width:100%;height:8px;overflow:hidden}.vidtreo-progress-fill{background:hsl(var(--vidtreo-primary));height:100%;transition:width .3s}.vidtreo-progress-text{text-align:center;color:hsl(var(--vidtreo-foreground));margin-top:8px;font-size:.875rem}.vidtreo-native-camera-preview-container{background:0 0;justify-content:center;align-items:center;width:100%;height:100%;display:flex;position:relative}.vidtreo-native-camera-preview-image{object-fit:contain;width:100%;height:100%;display:block}.vidtreo-progress-overlay{backdrop-filter:blur(4px);width:100%;height:100%;z-index:var(--vidtreo-z-progress-overlay);pointer-events:none;background:#000000b3;flex-direction:column;justify-content:center;align-items:center;display:flex;position:absolute;inset:0}.vidtreo-progress-overlay .vidtreo-transcoding-progress,.vidtreo-progress-overlay .vidtreo-upload-progress{pointer-events:auto;background:0 0;flex-direction:column;align-items:center;gap:12px;width:90%;max-width:400px;padding:0;display:flex;position:relative}.vidtreo-progress-overlay .vidtreo-progress-bar,.vidtreo-progress-overlay .vidtreo-upload-progress-bar{background:#fff3;border-radius:4px;width:100%;height:8px;overflow:hidden}.vidtreo-progress-overlay .vidtreo-progress-fill{background:#fff;height:100%;transition:width .3s}.vidtreo-progress-overlay .vidtreo-progress-text,.vidtreo-progress-overlay .vidtreo-upload-progress-text{text-align:center;color:#fff;margin-top:0;font-size:.875rem;font-weight:500}.vidtreo-progress-overlay .vidtreo-upload-progress-bar{background:#fff3;border-radius:4px;width:100%;height:8px;overflow:hidden}.vidtreo-progress-overlay .vidtreo-upload-progress-fill{background:#fff;height:100%;transition:width .3s}.vidtreo-progress-overlay .vidtreo-progress-indeterminate{background:linear-gradient(90deg,#0000 0%,#fff 50%,#0000 100%) 0 0/200% 100%;width:100%;animation:1.5s ease-in-out infinite vidtreo-progress-indeterminate}@keyframes vidtreo-progress-indeterminate{0%{background-position:200% 0}to{background-position:-200% 0}}.vidtreo-mobile-web-recorder{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;width:100%;height:100%;font-family:-apple-system,BlinkMacSystemFont,SF Pro Display,SF Pro Text,system-ui,sans-serif}.vidtreo-camera-area button,.vidtreo-camera-area input,.vidtreo-camera-area select,.vidtreo-camera-area textarea,.vidtreo-mobile-web-recorder button,.vidtreo-mobile-web-recorder input,.vidtreo-mobile-web-recorder select,.vidtreo-mobile-web-recorder textarea,.vidtreo-permission-flow button{font-family:inherit}.vidtreo-mobile-landing-container{aspect-ratio:4/3;background:hsl(var(--vidtreo-preview-bg));border-radius:0;justify-content:center;align-items:center;width:100%;min-height:100%;max-height:100%;display:flex;position:relative;overflow:hidden}.vidtreo-mobile-landing-content{text-align:center;flex-direction:column;justify-content:center;align-items:center;gap:1.25rem;padding:2rem;display:flex}.vidtreo-mobile-landing-title{color:#fff;margin:0;font-size:1.25rem;font-weight:600;line-height:1.3}.vidtreo-mobile-landing-description{color:#ffffffbf;max-width:280px;margin:0;font-size:.875rem;line-height:1.5}.vidtreo-mobile-open-camera-btn{border-radius:9999px;justify-content:center;align-items:center;gap:.625rem;min-width:200px;margin-top:.5rem;padding:.875rem 1.75rem;font-size:1rem;font-weight:600;transition:all .2s;animation:2s ease-in-out infinite vidtreo-btn-glow-pulse;display:inline-flex}@keyframes vidtreo-btn-glow-pulse{0%,to{box-shadow:0 0 8px 2px #ffffff4d,0 0 16px 4px #ffffff26}50%{box-shadow:0 0 16px 4px #ffffff80,0 0 32px 8px #ffffff40}}.vidtreo-mobile-open-camera-btn:hover:not(:disabled){animation-play-state:paused;transform:scale(1.02);box-shadow:0 0 20px 6px #fff9,0 0 40px 10px #ffffff4d}.vidtreo-mobile-open-camera-btn:active:not(:disabled){transform:scale(.98)}.vidtreo-mobile-open-camera-btn:disabled{box-shadow:none;animation:none}#vidtreo-portal-root{z-index:9999;pointer-events:none;width:100vw;height:100dvh;position:fixed;top:0;left:0}#vidtreo-portal-root>*{pointer-events:auto}.vidtreo-mobile-modal-overlay{--vidtreo-safe-top:0px;--vidtreo-safe-bottom:0px;--vidtreo-safe-left:0px;--vidtreo-safe-right:0px;width:100vw;height:100dvh;z-index:var(--vidtreo-z-modal-overlay);background:#000;flex-direction:column;height:-webkit-fill-available;animation:.3s ease-out vidtreo-modal-fade-in;display:flex;position:fixed;inset:0}@keyframes vidtreo-modal-fade-in{0%{opacity:0}to{opacity:1}}.vidtreo-mobile-modal-header{padding:.75rem;padding-top:calc(.75rem + var(--vidtreo-safe-top,0px));z-index:var(--vidtreo-z-error-overlay);pointer-events:none;justify-content:center;display:flex;position:absolute;top:0;left:0;right:0}.vidtreo-mobile-modal-close-btn{color:#ffffffe6;cursor:pointer;pointer-events:auto;backdrop-filter:blur(4px);background:#00000080;border:none;border-radius:9999px;justify-content:center;align-items:center;gap:.375rem;height:2rem;padding:0 .75rem;font-size:.75rem;font-weight:500;transition:all .2s;display:flex}.vidtreo-mobile-modal-close-btn:hover:not(:disabled){background:#000000b3}.vidtreo-mobile-modal-close-btn:disabled{opacity:.3;cursor:not-allowed}.vidtreo-mobile-modal-content{width:100%;height:100%;padding-top:var(--vidtreo-safe-top,0px);padding-bottom:var(--vidtreo-safe-bottom,0px);padding-left:var(--vidtreo-safe-left,0px);padding-right:var(--vidtreo-safe-right,0px);flex-direction:column;flex:1;display:flex;position:relative}.vidtreo-mobile-recorder-content{--vidtreo-safe-top:0px;--vidtreo-safe-bottom:0px;--vidtreo-safe-left:0px;--vidtreo-safe-right:0px;flex-direction:column;width:100%;height:100%;display:flex;position:relative}.vidtreo-mobile-recorder-content .vidtreo-preview-container{aspect-ratio:unset;flex:1;width:100%;height:100%}.vidtreo-mobile-recorder-content .vidtreo-video-preview{object-fit:cover}.vidtreo-mobile-preview{flex:1;aspect-ratio:unset!important;height:100%!important}.vidtreo-mobile-recorder-content .vidtreo-recording-controls{bottom:calc(24px + var(--vidtreo-safe-bottom,0px))!important}.vidtreo-mobile-recorder-content .vidtreo-audio-level-bars{bottom:calc(12px + var(--vidtreo-safe-bottom,0px))!important}.vidtreo-mobile-recorder-content .vidtreo-settings-panel{bottom:calc(7rem + var(--vidtreo-safe-bottom,0px))!important}.vidtreo-mobile-recorder-content .vidtreo-rec-indicator-top,.vidtreo-mobile-recorder-content .vidtreo-recording-timer-badge{contain:layout style;height:2rem;padding:0 .75rem;top:calc(.75rem + var(--vidtreo-safe-top,0px))!important}.vidtreo-mobile-recorder-content .vidtreo-recording-timer-text{white-space:nowrap;color:#fff;min-width:3rem;font-size:.875rem;display:inline-block}.vidtreo-mobile-recorder-content .vidtreo-error{top:calc(3.5rem + var(--vidtreo-safe-top,0px))!important}.vidtreo-mobile-recorder-content .vidtreo-control-buttons-row{gap:.75rem;min-height:4rem}.vidtreo-mobile-recorder-content .vidtreo-control-button{width:4rem;height:4rem;min-height:4rem;max-height:4rem}.vidtreo-mobile-recorder-content .vidtreo-control-button svg{width:1.5rem;height:1.5rem}.vidtreo-mobile-recorder-content .vidtreo-record-button{gap:.5rem;height:4rem;min-height:4rem;max-height:4rem;padding:0 1.5rem;font-size:1rem}.vidtreo-mobile-recorder-content .vidtreo-record-button svg{width:1.5rem;height:1.5rem}.vidtreo-permission-flow{z-index:var(--vidtreo-z-modal-overlay);contain:layout style paint;backface-visibility:hidden;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;background:#000;flex-direction:column;justify-content:center;align-items:center;gap:1.25rem;font-family:-apple-system,BlinkMacSystemFont,SF Pro Display,SF Pro Text,system-ui,sans-serif;display:none;position:absolute;inset:0;transform:translateZ(0)}.vidtreo-permission-flow.vidtreo-active{animation:.4s cubic-bezier(.2,0,0,1) vidtreo-fadeIn;display:flex}.vidtreo-permission-flow-title{color:#fff;text-align:center;margin:0;font-size:1.25rem;font-weight:600;line-height:1.3}.vidtreo-permission-flow-subtitle{color:#ffffffbf;text-align:center;letter-spacing:-.005em;max-width:280px;margin:0;font-size:.875rem;line-height:1.5}.vidtreo-permission-flow-action{background:hsl(var(--vidtreo-primary));color:hsl(var(--vidtreo-primary-foreground));cursor:pointer;letter-spacing:-.01em;border:none;border-radius:9999px;justify-content:center;align-items:center;gap:.625rem;min-width:200px;margin-top:.5rem;padding:.875rem 1.75rem;font-size:1rem;font-weight:600;transition:all .2s;animation:2s ease-in-out infinite vidtreo-btn-glow-pulse;display:inline-flex}.vidtreo-permission-flow-action:hover:not(:disabled){animation-play-state:paused;transform:scale(1.02);box-shadow:0 0 20px 6px #fff9,0 0 40px 10px #ffffff4d}.vidtreo-permission-flow-action:active:not(:disabled){transform:scale(.98)}.vidtreo-permission-flow-action:disabled{opacity:.5;cursor:not-allowed;box-shadow:none;animation:none}.vidtreo-permission-flow-action--requesting{opacity:.55;cursor:wait;box-shadow:none;animation:none}@keyframes vidtreo-spinner-rotate{to{transform:rotate(360deg)}}.vidtreo-permission-flow-spinner{border:2px solid #ffffff4d;border-top-color:hsl(var(--vidtreo-primary-foreground));border-radius:50%;flex-shrink:0;width:1.125rem;height:1.125rem;animation:.8s linear infinite vidtreo-spinner-rotate;display:inline-block}.vidtreo-permission-flow-spinner--large{border-width:3px;width:2.5rem;height:2.5rem}.vidtreo-permission-flow-recovery{text-align:center;flex-direction:column;align-items:center;gap:1.25rem;max-width:280px;display:flex}.vidtreo-permission-flow-recovery-text{color:#fff6;letter-spacing:-.005em;margin:0;font-size:.75rem;line-height:1.6}.vidtreo-permission-flow-retry{background:hsl(var(--vidtreo-primary));color:hsl(var(--vidtreo-primary-foreground));cursor:pointer;letter-spacing:-.01em;border:none;border-radius:9999px;justify-content:center;align-items:center;gap:.625rem;min-width:200px;padding:.875rem 1.75rem;font-size:1rem;font-weight:600;transition:all .2s;animation:2s ease-in-out infinite vidtreo-btn-glow-pulse;display:inline-flex}.vidtreo-permission-flow-retry:hover:not(:disabled){animation-play-state:paused;transform:scale(1.02);box-shadow:0 0 20px 6px #fff9,0 0 40px 10px #ffffff4d}.vidtreo-permission-flow-retry:active:not(:disabled){transform:scale(.98)}@keyframes vidtreo-fadeOut{0%{opacity:1}to{opacity:0}}.vidtreo-permission-flow.vidtreo-permission-flow--fading{pointer-events:none;animation:.6s ease-out forwards vidtreo-fadeOut}.vidtreo-recovery-guide{width:100%;max-width:280px;margin:0 auto;position:relative}.vidtreo-recovery-guide:after{content:"";z-index:20;pointer-events:none;background:linear-gradient(#0000 0%,#000 100%);height:60px;position:absolute;bottom:0;left:0;right:0}.vidtreo-recovery-guide:before{content:"";z-index:20;pointer-events:none;background:linear-gradient(90deg,#0000 0%,#000 100%);width:50px;position:absolute;top:0;bottom:0;right:0}.vidtreo-recovery-guide-browser{background:#161616;border-top:1px solid #ffffff1a;border-left:1px solid #ffffff1a;border-radius:10px 0 0;animation:.5s vidtreo-fadeIn;position:relative;overflow:hidden}.vidtreo-recovery-guide-titlebar{z-index:3;background:#1e1e1e;border-bottom:1px solid #ffffff0f;align-items:center;gap:8px;padding:8px 10px;display:flex;position:relative}.vidtreo-recovery-guide-dots{flex-shrink:0;gap:5px;display:flex}.vidtreo-recovery-guide-dot{border-radius:50%;width:8px;height:8px}.vidtreo-recovery-guide-dot--close{background:#ff5f57}.vidtreo-recovery-guide-dot--min{background:#febc2e}.vidtreo-recovery-guide-dot--max{background:#28c840}.vidtreo-recovery-guide-addressbar{background:#2a2a2a;border-radius:5px;flex:1;align-items:center;gap:5px;min-width:0;padding:4px 8px;display:flex}.vidtreo-recovery-guide-lock{color:#ffffff80;flex-shrink:0;align-items:center;animation:7s ease-in-out infinite vidtreo-lock-pulse;display:flex}.vidtreo-recovery-guide-lock-svg{display:block}.vidtreo-recovery-guide-url{color:#ffffff80;white-space:nowrap;text-overflow:ellipsis;font-family:-apple-system,BlinkMacSystemFont,system-ui,sans-serif;font-size:.65rem;overflow:hidden}.vidtreo-recovery-guide-cursor{z-index:40;pointer-events:none;filter:drop-shadow(0 2px 4px #0009);animation:7s ease-in-out infinite vidtreo-cursor-move;position:absolute;top:12px;left:62px}.vidtreo-recovery-guide-cursor-svg{display:block}.vidtreo-recovery-guide-browser-bg{background:#161616;height:110px}.vidtreo-recovery-guide-popover{z-index:30;background:#252525;border:1px solid #ffffff1a;border-radius:10px;padding:8px 12px 12px;animation:7s ease-in-out infinite vidtreo-popover-reveal;position:absolute;top:34px;left:12px;right:12px;box-shadow:0 8px 30px #0009,0 2px 8px #0006,0 0 0 1px #ffffff0f}.vidtreo-recovery-guide-popover-header{color:#ffffffd9;white-space:nowrap;text-overflow:ellipsis;text-align:left;padding-bottom:6px;font-family:-apple-system,BlinkMacSystemFont,system-ui,sans-serif;font-size:.65rem;font-weight:600;overflow:hidden}.vidtreo-recovery-guide-popover-divider{background:#ffffff14;height:1px}.vidtreo-recovery-guide-perm-row{justify-content:space-between;align-items:center;padding:7px 0;display:flex}.vidtreo-recovery-guide-perm-row+.vidtreo-recovery-guide-perm-row{border-top:1px solid #ffffff0f}.vidtreo-recovery-guide-perm-group{align-items:center;gap:8px;display:flex}.vidtreo-recovery-guide-perm-icon{flex-shrink:0;width:14px;height:14px;position:relative}.vidtreo-recovery-guide-icon-off,.vidtreo-recovery-guide-icon-on{justify-content:center;align-items:center;display:flex;position:absolute;inset:0}.vidtreo-recovery-guide-icon-off{color:#fff6;animation:7s ease-in-out infinite vidtreo-icon-hide}.vidtreo-recovery-guide-icon-on{color:#34d399;animation:7s ease-in-out infinite vidtreo-icon-show}.vidtreo-recovery-guide-perm-label{color:#ffffffd9;font-family:-apple-system,BlinkMacSystemFont,system-ui,sans-serif;font-size:.7rem}.vidtreo-recovery-guide-switch{flex-shrink:0;width:32px;height:18px;position:relative}.vidtreo-recovery-guide-switch-track{background:#ffffff26;border-radius:9px;animation:7s ease-in-out infinite vidtreo-track-on;position:absolute;inset:0}.vidtreo-recovery-guide-switch-knob{background:#fff;border-radius:50%;width:14px;height:14px;animation:7s ease-in-out infinite vidtreo-knob-slide;position:absolute;top:2px;left:2px;box-shadow:0 1px 3px #0000004d}.vidtreo-recovery-guide-switch--delayed{animation-delay:.85s}@keyframes vidtreo-cursor-move{0%{opacity:0;transform:translate(100px,12px)}8%{opacity:1}22%{transform:translate(0)}26%{transform:translate(0)scale(.75)}30%{opacity:1;transform:translate(0)scale(1)}33%{opacity:1;transform:translate(0)}38%{opacity:1;transform:translate(65px,63px)}42%{transform:translate(65px,63px)scale(.75)}45%{opacity:1;transform:translate(65px,63px)scale(1)}48%{opacity:1;transform:translate(65px,97px)}52%{transform:translate(65px,97px)scale(.75)}55%{opacity:1;transform:translate(65px,97px)scale(1)}60%{opacity:0}to{opacity:0;transform:translate(100px,12px)}}@keyframes vidtreo-popover-reveal{0%,27%{opacity:0;transform:translateY(-6px)scale(.96)}33%,82%{opacity:1;transform:translateY(0)scale(1)}88%,to{opacity:0;transform:translateY(-6px)scale(.96)}}@keyframes vidtreo-track-on{0%,34%{background:#ffffff26}40%,92%{background:#34d399}96%,to{background:#ffffff26}}@keyframes vidtreo-knob-slide{0%,34%{transform:translate(0)}40%,92%{transform:translate(14px)}96%,to{transform:translate(0)}}@keyframes vidtreo-icon-hide{0%,34%{opacity:1}40%,92%{opacity:0}96%,to{opacity:1}}@keyframes vidtreo-icon-show{0%,34%{opacity:0}40%,92%{opacity:1}96%,to{opacity:0}}@keyframes vidtreo-lock-pulse{0%,15%{color:#ffffff80}22%,30%{color:#34d399}38%,to{color:#ffffff80}}.vidtreo-record-button.vidtreo-record-button-disabled,.vidtreo-record-button-disabled{opacity:.6;cursor:not-allowed;pointer-events:none;filter:grayscale(.3)}.vidtreo-mic-connecting-indicator{justify-content:center;align-items:center;animation:1.4s ease-in-out infinite vidtreo-mic-pulse;display:inline-flex}@keyframes vidtreo-mic-pulse{0%,to{opacity:.4}50%{opacity:1}}.vidtreo-audio-error-overlay{z-index:var(--vidtreo-z-error-overlay);text-align:center;background:#000000d9;flex-direction:column;justify-content:center;align-items:center;padding:2rem 1.5rem;animation:.3s ease-out vidtreo-audio-overlay-fade-in;display:flex;position:absolute;inset:0}@supports (backdrop-filter:blur(8px)){.vidtreo-audio-error-overlay{-webkit-backdrop-filter:blur(8px);background:#000000bf}}@keyframes vidtreo-audio-overlay-fade-in{0%{opacity:0}to{opacity:1}}.vidtreo-audio-error-icon{background:#ef444426;border-radius:50%;justify-content:center;align-items:center;width:56px;height:56px;margin-bottom:1rem;display:flex}.vidtreo-audio-error-icon svg{color:#ef4444;width:28px;height:28px}.vidtreo-audio-error-title{color:#fff;margin:0 0 .5rem;font-size:1.125rem;font-weight:600;line-height:1.4}.vidtreo-audio-error-message{color:#ffffffb3;max-width:320px;margin:0 0 1.5rem;font-size:.875rem;line-height:1.6}.vidtreo-audio-error-retry{color:#111;cursor:pointer;background:#fff;border:none;border-radius:9999px;align-items:center;gap:.5rem;padding:.75rem 1.5rem;font-family:inherit;font-size:.875rem;font-weight:600;transition:background .15s,transform .1s;display:inline-flex}.vidtreo-audio-error-retry:hover{background:#f0f0f0}.vidtreo-audio-error-retry:active{transform:scale(.97)}.vidtreo-audio-error-retry svg{width:16px;height:16px}.vidtreo-audio-warning-toast{z-index:var(--vidtreo-z-error-overlay);color:#ffffffeb;pointer-events:auto;background:#1111118c;border:1px solid #ffffff14;border-radius:12px;align-items:flex-start;gap:.625rem;max-width:min(420px,100% - 2rem);padding:.625rem .875rem;font-family:inherit;animation:.2s ease-out vidtreo-audio-warning-toast-fade-in;display:flex;position:absolute;top:1rem;left:50%;transform:translate(-50%);box-shadow:0 4px 16px #00000040}@supports (backdrop-filter:blur(10px)){.vidtreo-audio-warning-toast{-webkit-backdrop-filter:blur(10px)saturate(140%);background:#11111173}}.vidtreo-audio-warning-toast--critical{border-color:#ef444473}.vidtreo-audio-warning-toast--critical .vidtreo-audio-warning-toast__icon{color:#ef4444}.vidtreo-audio-warning-toast--soft{border-color:#f59e0b73}.vidtreo-audio-warning-toast--soft .vidtreo-audio-warning-toast__icon{color:#f59e0b}.vidtreo-audio-warning-toast__icon{flex:none;justify-content:center;align-items:center;width:20px;height:20px;margin-top:1px;display:inline-flex}.vidtreo-audio-warning-toast__content{flex-direction:column;flex:auto;gap:2px;min-width:0;display:flex}.vidtreo-audio-warning-toast__title{color:#fff;font-size:.8125rem;font-weight:600;line-height:1.3}.vidtreo-audio-warning-toast__message{color:#ffffffb8;font-size:.75rem;font-weight:400;line-height:1.4}.vidtreo-audio-warning-toast__dismiss{color:#ffffffa6;cursor:pointer;background:0 0;border:none;border-radius:6px;flex:none;justify-content:center;align-items:center;width:22px;height:22px;margin-left:.25rem;padding:0;font-family:inherit;transition:background .15s,color .15s;display:inline-flex}.vidtreo-audio-warning-toast__dismiss:hover{color:#fffffff2;background:#ffffff1a}@keyframes vidtreo-audio-warning-toast-fade-in{0%{opacity:0;transform:translate(-50%,-8px)}to{opacity:1;transform:translate(-50%)}}`;function zT(e){return`
12829
+ `],{type:`application/javascript`})}let CC=VS({createBlob:SC,createObjectUrl:e=>URL.createObjectURL(e),revokeObjectUrl:e=>{URL.revokeObjectURL(e)}});function wC(){return CC.acquire()}function TC(){CC.release()}let EC=1e3,DC=`format`,OC=new Map,kC=new Map;function AC(e){return e===void 0?`undefined`:String(e)}function jC(e){return e.join(`,`)}function MC(e,t){return`${e}=${t}`}function NC(e,t,n){if(e.has(t)&&e.delete(t),e.set(t,n),e.size<=50)return;let r=e.keys().next();r.done||e.delete(r.value)}var PC=class{constructor(e={}){this.worker=null,this.hasWorkerUrlLease=!1,this.chunks=[],this.totalSize=0,this.isActive=!1,this.audioTrackClone=null,this.audioTrackWarningTarget=null,this.isMuted=!1,this.currentVideoTrack=null,this.isPaused=!1,this.overlayConfig=null,this.readyPromiseResolve=null,this.readyPromiseReject=null,this.lastConfigFps=30,this.pendingFatalError=null,this.lastRecordingStats=null,this.audioWasExpected=!1,this.lastEncoderAcceleration=null,this.audioHealthMonitor=new RS,this.audioHealthIntervalId=null,this.emittedAudioWarnings=new Set,this.audioTrackEndedDuringSession=!1,this.recordingStartTimestampMs=null,this.noFrameWatchdogId=null,this.handleAudioTrackEnded=()=>{this.audioTrackEndedDuringSession=!0,this.emitAudioWarningOnce({code:`audio.track-ended`})},this.handleAudioTrackMuted=()=>{this.emitAudioWarningOnce({code:`audio.track-muted-by-browser`})},this.handleAudioTrackUnmuted=()=>{this.emittedAudioWarnings.delete(`audio.track-muted-by-browser`)&&this.onAudioRecovered&&this.onAudioRecovered()};let t=e=>new Worker(e,{type:`classic`});e.createWorker&&(t=e.createWorker);let n=e=>typeof MediaStreamTrackProcessor>`u`?null:(eC(e,{stage:`main-thread-stream-create`}),new MediaStreamTrackProcessor({track:e}).readable);e.createVideoStreamFromTrack&&(n=e.createVideoStreamFromTrack);let r=()=>on();e.isLinuxPlatform&&(r=e.isLinuxPlatform),this.createVideoStreamFromTrackFn=n,this.isLinuxPlatformFn=r,e.videoFramePreflightDeps?this.videoFramePreflightDeps=e.videoFramePreflightDeps:this.videoFramePreflightDeps={},e.noFrameWatchdogDelayMs===void 0?this.watchdogDelayMs=5e3:this.watchdogDelayMs=e.noFrameWatchdogDelayMs;let i=!!e.createWorker;this.workerProbeManager=new xC({setTimeout:window.setTimeout.bind(window),clearTimeout:window.clearTimeout.bind(window),timeoutMilliseconds:2e3}),this.audioWorkletManager=new ZS({onChunk:this.handleAudioWorkletChunk.bind(this)});let a=e=>{let t=e.data;switch(t.type){case`ready`:this.readyPromiseResolve&&(this.readyPromiseResolve(),this.readyPromiseResolve=null,this.readyPromiseReject=null);break;case Hy:this.workerProbeManager.handleProbeResult(t);break;case`debugLog`:t.payload?$.debug(t.message,t.payload):$.debug(t.message);break;case`error`:if($.error(`[WorkerProcessor] Worker error:`,t.error),this.readyPromiseReject){let e=this.readyPromiseReject;this.readyPromiseReject=null,this.readyPromiseResolve=null,e(Error(t.error));break}this.onError&&this.onError(Error(t.error));break;case`chunk`:this.chunks.push({data:t.data,position:t.position}),this.totalSize=Math.max(this.totalSize,t.position+t.data.length);break;case`bufferUpdate`:this.onBufferUpdate&&this.onBufferUpdate(t.size,t.formatted);break;case`stateChange`:$.debug(`[WorkerProcessor] State changed:`,t.state),this.isPaused=t.state===`paused`;break;case`fatalError`:if(this.readyPromiseReject){let e=this.readyPromiseReject;this.readyPromiseReject=null,this.readyPromiseResolve=null,e(Error(`${t.message} [${t.code}]`));break}this.pendingFatalError=t;break;case`recordingStats`:this.lastRecordingStats=t,this.handleNoFrameWatchdogStats(t);break;case`encoderAcceleration`:this.lastEncoderAcceleration=t.acceleration,$.info(`[WorkerProcessor] Encoder acceleration resolved`,{acceleration:t.acceleration});break;default:$.warn(`[WorkerProcessor] Unknown response type:`,t)}},o=e=>{if($.error(`[WorkerProcessor] Worker error event:`,{message:e.message,filename:e.filename,lineno:e.lineno,colno:e.colno,error:e.error}),this.readyPromiseReject){let t=this.readyPromiseReject;this.readyPromiseReject=null,this.readyPromiseResolve=null,t(Error(e.message||`Unknown worker error`));return}if(this.onError){let t=e.message;t||=`Unknown worker error`,this.onError(Error(t))}},s=typeof Worker<`u`,c=!1;if(s&&(c=!0),i&&(c=!0),!c)throw $.error(`[WorkerProcessor] Web Workers are not supported`),Error(`Web Workers are not supported`);let l=wC();this.hasWorkerUrlLease=!0;try{this.worker=_C({createWorker:t,workerUrl:l,onMessage:a,onError:o,logger:$})}catch(e){throw this.releaseWorkerUrlLease(),e}}prewarm(){this.worker&&this.workerProbeManager.getProbeResult(this.worker).catch(()=>void 0)}getWorkerProbeResult(){let e=this.getWorkerOrThrow();return this.workerProbeManager.getProbeResult(e)}async startProcessing(e,t,n){this.getWorkerOrThrow(),this.ensureProcessingInactive(),this.resetProcessingState(n),this.stopAudioWorklet(),this.audioWorkletManager=new ZS({onChunk:this.handleAudioWorkletChunk.bind(this)});let r=this.resolveRecordingFormat(t),i=Ht(r,{isLinuxPlatform:this.isLinuxPlatformFn()}),a=this.resolveAudioBitrate(t,r),o=await this.resolveAudioCodecWithCache(t,r,i,a),s=await this.resolveVideoCodecWithCache(t,r,i),c=zS(e);$.debug(`[WorkerProcessor] Starting processing`,{isScreenCapture:c,fps:t.fps,codec:s,bitrate:t.bitrate});let l=this.buildWorkerTranscodeConfig(t,o,a,s,r);typeof t.fps==`number`&&t.fps>0&&(this.lastConfigFps=t.fps);let u=e.getVideoTracks(),d=e.getAudioTracks();$.debug(`[WorkerProcessor] Preparing to start processing`,{videoTracksCount:u.length,audioTracksCount:d.length,hasWorker:!!this.worker});try{let e=this.getVideoInputSelectorDependencies(),t=sC(u,e),n=cC(d,e),r=await this.getWorkerProbeResult();t&&($.debug(`[WorkerProcessor] Running video first-frame preflight`),await rC(t,3e3,this.videoFramePreflightDeps),$.debug(`[WorkerProcessor] Video first-frame preflight passed`));let i=lC(t,r,e),a=dC(e),o=uC(t);pC(t,e),mC(e),fC(t,n,i.videoStream,e);let s=e.getViewportMetadata(),c;s&&(c={orientationAngle:s.orientationAngle,windowOrientation:s.windowOrientation});let{audioConfig:f,audioStream:p,shouldStartAudioWorklet:m}=await this.prepareAudioPipeline(n,r),h=this.buildOverlayConfigToSend(),g=vC({videoTrack:i.videoTrack,videoStream:i.videoStream,audioStream:p,isMobileDevice:a,videoSettings:o,viewportMetadata:c,audioConfig:f,workerConfig:l,overlayConfig:h}),_=bC(i.videoStream,p,i.videoTrack);$.debug(`[WorkerProcessor] Posting message to worker`,{transferablesCount:_.length,messageType:g.type}),await this.postStartMessage(g,_,m),this.startNoFrameWatchdog(),m&&this.startAudioHealthMonitoring()}catch(e){throw this.resetStartProcessingStateAfterFailure(),e}}getWorkerOrThrow(){if(!this.worker)throw Error(`Worker not initialized`);return this.worker}ensureProcessingInactive(){if(this.isActive)throw Error(`Processing already active`)}handleAudioWorkletChunk(e){if(!(this.isWorkerActive()&&this.worker))return;this.recordAudioHealthChunk(e);let t={type:`audioChunk`,data:e.data,frames:e.frames,numberOfChannels:e.numberOfChannels,sampleRate:e.sampleRate,timestamp:e.timestamp},n=[];e.data.buffer instanceof ArrayBuffer&&n.push(e.data.buffer),this.worker.postMessage(t,n)}resetProcessingState(e){this.isActive=!0,this.isMuted=!1,this.isPaused=!1,this.chunks=[],this.totalSize=0,this.audioWasExpected=!1,this.audioHealthMonitor.reset(),this.emittedAudioWarnings=new Set,this.audioTrackEndedDuringSession=!1,this.recordingStartTimestampMs=performance.now(),this.pendingFatalError=null,this.lastRecordingStats=null,this.lastEncoderAcceleration=null,this.stopAudioHealthMonitoring(),this.stopNoFrameWatchdog(),e?this.overlayConfig=e:this.overlayConfig=null}resetStartProcessingStateAfterFailure(){this.isActive=!1,this.isPaused=!1,this.stopAudioHealthMonitoring(),this.stopNoFrameWatchdog(),this.stopAudioWorklet(),this.detachAudioTrackWarnings(),this.stopCurrentVideoTrack(),this.pendingFatalError=null,this.lastRecordingStats=null,this.lastEncoderAcceleration=null}recordAudioHealthChunk(e){let t=this.audioHealthMonitor.recordChunk({samples:e.data,timestampMs:performance.now(),isMuted:this.isMuted,inputPeak:e.inputPeak,inputRms:e.inputRms});this.emitAudioWarning(t.classification,{durationMs:Math.max(t.consecutiveSilentDurationMs,t.consecutiveLowSignalDurationMs,t.consecutiveMutedSpeechDurationMs),peak:t.inputPeak,rms:t.inputRms})}startAudioHealthMonitoring(){this.stopAudioHealthMonitoring(),this.audioHealthIntervalId=window.setInterval(()=>{if(!this.isActive)return;let e=this.audioHealthMonitor.inspect(performance.now(),this.isMuted);this.emitAudioWarning(e.classification,{durationMs:Math.max(e.noChunkDurationMs,e.consecutiveSilentDurationMs,e.consecutiveLowSignalDurationMs,e.consecutiveMutedSpeechDurationMs),peak:e.inputPeak,rms:e.inputRms})},1e3)}stopAudioHealthMonitoring(){this.audioHealthIntervalId!==null&&(window.clearInterval(this.audioHealthIntervalId),this.audioHealthIntervalId=null)}startNoFrameWatchdog(){this.stopNoFrameWatchdog(),this.noFrameWatchdogId=window.setTimeout(()=>{this.noFrameWatchdogId=null,this.isWorkerActive()&&this.worker&&this.worker.postMessage({type:`requestStats`})},this.watchdogDelayMs)}stopNoFrameWatchdog(){this.noFrameWatchdogId!==null&&(window.clearTimeout(this.noFrameWatchdogId),this.noFrameWatchdogId=null)}handleNoFrameWatchdogStats(e){if(!this.isActive||e.videoFrameCount>0)return;$.error(`[WorkerProcessor] No video frames received after watchdog delay`,{videoFrameCount:e.videoFrameCount,totalFrameErrors:e.totalFrameErrors,totalFramesProcessed:e.totalFramesProcessed});let t=Error(`No video frames received after ${this.watchdogDelayMs/EC}s — video stream may be unresponsive [${tC}]`);this.onError&&this.onError(t),this.cancel()}emitAudioWarning(e,t){if(e===`healthy`){let e=this.emittedAudioWarnings.size>0;this.emittedAudioWarnings.clear(),e&&this.onAudioRecovered&&this.onAudioRecovered();return}if(e===`muted-silence-expected`){let e=!1;this.emittedAudioWarnings.delete(`audio.no-signal`)&&(e=!0),this.emittedAudioWarnings.delete(`audio.no-chunks`)&&(e=!0),this.emittedAudioWarnings.delete(`audio.low-signal`)&&(e=!0),this.emittedAudioWarnings.delete(`audio.speaking-while-muted`)&&(e=!0),e&&this.onAudioRecovered&&this.onAudioRecovered();return}let n=this.createAudioWarning(e,t);n&&this.emitAudioWarningOnce(n)}emitAudioWarningOnce(e){this.onAudioWarning&&(this.emittedAudioWarnings.has(e.code)||(this.emittedAudioWarnings.add(e.code),this.onAudioWarning(e)))}createAudioWarning(e,t){return e===`no-chunks`?{code:`audio.no-chunks`,durationMs:t.durationMs}:e===`silent-while-unmuted`?{code:`audio.no-signal`,durationMs:t.durationMs}:e===`low-signal`?{code:`audio.low-signal`,peak:t.peak,rms:t.rms}:e===`speaking-while-muted`?{code:`audio.speaking-while-muted`,durationMs:t.durationMs,peak:t.peak,rms:t.rms}:null}assertRuntimeAudioHealth(){let e=performance.now(),t=this.recordingStartTimestampMs??e,n=Math.max(0,e-t),r=this.audioHealthMonitor.getFinalSnapshot(e,this.isMuted),i=Sb({totalChunks:r.totalChunks,nonSilentChunks:r.nonSilentChunks,mutedDurationMs:r.mutedDurationMs,durationMs:n,hadTrackEndedWarning:this.audioTrackEndedDuringSession});if(!i.ok)throw yb(i.code,{totalChunks:r.totalChunks,nonSilentChunks:r.nonSilentChunks,mutedDurationMs:r.mutedDurationMs,durationMs:n,hadTrackEndedWarning:this.audioTrackEndedDuringSession})}resolveRecordingFormat(e){let t=e.format;return t||=`mp4`,t}resolveAudioBitrate(e,t){return e.audioBitrate===void 0?Kt(t):e.audioBitrate}async resolveAudioCodec(e,t,n,r){return await ny({format:t,overrideCodec:e.audioCodec,policy:n,bitrate:r})}async resolveVideoCodec(e,t,n){return await ty({format:t,overrideCodec:e.codec,policy:n,width:e.width,height:e.height,bitrate:e.bitrate})}async resolveAudioCodecWithCache(e,t,n,r){let i=this.buildAudioCodecCacheKey(e,t,n,r),a=OC.get(i);if(a)return a;let o=await this.resolveAudioCodec(e,t,n,r);return NC(OC,i,o),o}async resolveVideoCodecWithCache(e,t,n){let r=this.buildVideoCodecCacheKey(e,t,n),i=kC.get(r);if(i)return i;let a=await this.resolveVideoCodec(e,t,n);return NC(kC,r,a),a}buildAudioCodecCacheKey(e,t,n,r){let i=AC(e.audioCodec),a=AC(n.preferredAudioCodec),o=jC(n.audioCodecFallbackOrder),s=AC(r);return[MC(DC,AC(t)),MC(`audioOverride`,i),MC(`audioBitrate`,s),MC(`policyPreferredAudio`,a),MC(`policyAudioFallback`,o)].join(`|`)}buildVideoCodecCacheKey(e,t,n){let r=AC(e.codec),i=AC(e.width),a=AC(e.height),o=AC(e.bitrate),s=AC(n.preferredVideoCodec),c=jC(n.videoCodecFallbackOrder);return[MC(DC,AC(t)),MC(`videoOverride`,r),MC(`width`,i),MC(`height`,a),MC(`videoBitrate`,o),MC(`policyPreferredVideo`,s),MC(`policyVideoFallback`,c)].join(`|`)}buildWorkerTranscodeConfig(e,t,n,r,i){return{width:e.width,height:e.height,fps:e.fps,bitrate:BS(e.bitrate),audioCodec:t,audioBitrate:n,codec:r,keyFrameInterval:5,latencyMode:e.latencyMode,format:i,watermark:e.watermark}}async prepareAudioPipeline(e,t){if(!e)return $.debug(`[WorkerProcessor] Audio pipeline disabled (no track)`),{audioConfig:null,audioStream:null,shouldStartAudioWorklet:!1};let n=await this.prepareAudioConfig(e);if(!n)throw this.createBrowserUnsupportedError();return $.debug(`[WorkerProcessor] Audio pipeline selected`,{path:`audio-worklet-chunks`,sampleRate:n.sampleRate,numberOfChannels:n.numberOfChannels}),{audioConfig:n,audioStream:null,shouldStartAudioWorklet:!0}}buildOverlayConfigToSend(){if(this.overlayConfig)return this.overlayConfig}async postStartMessage(e,t,n){let r=this.getWorkerOrThrow(),i=new Promise((e,t)=>{this.readyPromiseResolve=e,this.readyPromiseReject=t});try{r.postMessage(e,t),$.debug(`[WorkerProcessor] Message posted successfully`),await i,$.debug(`[WorkerProcessor] Worker confirmed ready`),n&&(this.audioWasExpected=!0,await this.startAudioWorkletProcessing())}catch(e){throw $.error(`[WorkerProcessor] Failed to post message:`,e),this.readyPromiseResolve=null,this.readyPromiseReject=null,this.stopNoFrameWatchdog(),this.stopAudioWorklet(),this.worker&&this.isActive&&this.worker.postMessage({type:`stop`}),this.isActive=!1,e}}pause(){this.worker&&this.isActive&&(this.worker.postMessage({type:`pause`}),this.setAudioWorkletPaused(!0))}resume(){this.isWorkerActive()&&this.worker&&(this.worker.postMessage({type:`resume`}),this.setAudioWorkletPaused(!1))}isWorkerActive(){return!!(this.worker&&this.isActive)}toggleMute(){this.isMuted=!this.isMuted,this.onMuteStateChange&&this.onMuteStateChange(this.isMuted),this.isWorkerActive()&&this.worker&&this.worker.postMessage({type:`toggleMute`}),this.setAudioWorkletMuted(this.isMuted)}async switchVideoSource(e){if(!(this.isWorkerActive()&&this.worker))return $.debug(`[WorkerProcessor] Cannot switch source - worker not active`,{hasWorker:!!this.worker,isActive:this.isActive}),Promise.resolve();let t=e.getVideoTracks();if($.debug(`[WorkerProcessor] Switching video source`,{videoTracksCount:t.length}),t.length===0)return $.warn(`[WorkerProcessor] No video tracks in new stream`),Promise.resolve();let n=zS(e),r=this.lastConfigFps;$.debug(`[WorkerProcessor] Source type detected`,{isScreenCapture:n,targetFps:r});let i={type:`updateFps`,fps:r};this.worker.postMessage(i);let a={type:`updateSourceType`,isScreenCapture:n};this.worker.postMessage(a);let o=this.getVideoInputSelectorDependencies(),s=sC(t,o);if(!s)return $.warn(`[WorkerProcessor] Unable to prepare video track`),Promise.resolve();$.debug(`[WorkerProcessor] New video track details`,{trackId:s.id,trackKind:s.kind,trackReadyState:s.readyState});let c=lC(s,await this.getWorkerProbeResult(),o),l=yC(c.videoTrack,c.videoStream),u=bC(c.videoStream,null,c.videoTrack);try{return $.debug(`[WorkerProcessor] Posting switch source message`),this.worker.postMessage(l,u),$.debug(`[WorkerProcessor] Switch source message posted`),new Promise(e=>{setTimeout(()=>{e()},0)})}catch(e){throw $.error(`[WorkerProcessor] Failed to switch source:`,e),e}}finalize(){if(!this.isWorkerActive())throw Dx(Tx,`Recording is not ready to finalize`,{hasWorker:!!this.worker,isActive:this.isActive});let e=performance.now();return new Promise((t,n)=>{let r=this.worker;if(!r){n(Error(`Worker not initialized`));return}let i=null,a=()=>{i!==null&&(clearTimeout(i),i=null)},o=()=>{r.removeEventListener(`message`,l)},s=!1,c=()=>s?!1:(s=!0,a(),o(),!0),l=r=>{if(s)return;let i=r.data;if(i.type===`fatalError`){this.pendingFatalError=i;return}if(i.type===`recordingStats`){this.lastRecordingStats=i;return}if(i.type===`stateChange`&&i.state===`stopped`){this.handleFinalizeStopped(c,t,n,e);return}i.type===`error`&&this.handleFinalizeError(c,n,i.error,e)};i=setTimeout(()=>{if(!c())return;$.error(`[WorkerProcessor] Finalize timeout reached`,{elapsedSeconds:(performance.now()-e)/EC,recordingStats:this.buildRecordingStatsSummary(this.lastRecordingStats)});let t=this.lastRecordingStats;this.resetFinalizeRuntimeState(),n(Dx(Ex,this.buildFinalizeTimeoutMessage(t),{recordingStats:this.buildRecordingStatsSummary(t)}))},3e4),r.addEventListener(`message`,l),r.postMessage({type:`requestStats`}),r.postMessage({type:`stop`})})}handleFinalizeStopped(e,t,n,r){let i=this.lastRecordingStats,a=this.lastEncoderAcceleration;if(this.pendingFatalError!==null){let t=this.pendingFatalError;if(!e())return;this.resetFinalizeRuntimeState(),n(Error(this.buildFatalFinalizeErrorMessage(t,i)));return}e()&&(this.resetFinalizeRuntimeState(),Promise.resolve().then(()=>this.createBlobFromChunks(i,a)).then(e=>{t(e)},e=>{this.rejectFinalizeBlobCreationError(n,e,r)}))}handleFinalizeError(e,t,n,r){e()&&(this.resetFinalizeRuntimeState(),$.error(`[WorkerProcessor] Finalize failed`,{elapsedSeconds:(performance.now()-r)/EC,error:n}),t(Error(n)))}buildFatalFinalizeErrorMessage(e,t){return t===null?`${e.message} [${e.code}]`:`${e.message} [${e.code}] frames=${t.videoFrameCount} errors=${t.totalFrameErrors}`}buildFinalizeTimeoutMessage(e){return e===null?`Finalize timeout`:`Finalize timeout frames=${e.videoFrameCount} errors=${e.totalFrameErrors} processed=${e.totalFramesProcessed}`}buildRecordingStatsSummary(e){return e===null?null:{videoFrameCount:e.videoFrameCount,totalFrameErrors:e.totalFrameErrors,totalFramesProcessed:e.totalFramesProcessed}}resetFinalizeRuntimeState(){this.isActive=!1,this.stopAudioHealthMonitoring(),this.stopNoFrameWatchdog(),this.stopAudioWorklet(),this.detachAudioTrackWarnings(),this.pendingFatalError=null,this.lastRecordingStats=null,this.lastEncoderAcceleration=null}createBlobFromChunks(e,t){let n=[...this.chunks].sort((e,t)=>e.position-t.position),r=new ArrayBuffer(this.totalSize),i=new Uint8Array(r);for(let e of n)i.set(e.data,e.position);Fy(r),Iy(r),this.audioWasExpected&&(this.assertRuntimeAudioHealth(),Ly(r));let a={blob:new Blob([r],{type:`video/mp4`}),totalSize:this.totalSize};return e!==null&&(a.recordingStats={totalFrameErrors:e.totalFrameErrors,totalFramesProcessed:e.totalFramesProcessed,videoFrameCount:e.videoFrameCount}),t!==null&&(a.encoderAcceleration=t),a}rejectFinalizeBlobCreationError(e,t,n){if($.error(`[WorkerProcessor] Finalize failed while creating blob`,{elapsedSeconds:(performance.now()-n)/EC,error:i(t)}),t instanceof Error){e(t);return}e(Error(i(t)))}cancel(){return this.worker&&this.isActive&&this.worker.postMessage({type:`stop`}),this.stopAudioHealthMonitoring(),this.stopNoFrameWatchdog(),this.stopAudioWorklet(),this.detachAudioTrackWarnings(),this.isActive=!1,this.isPaused=!1,this.chunks=[],this.totalSize=0,this.audioWasExpected=!1,this.emittedAudioWarnings=new Set,this.audioTrackEndedDuringSession=!1,this.recordingStartTimestampMs=null,this.pendingFatalError=null,this.lastRecordingStats=null,this.lastEncoderAcceleration=null,Promise.resolve()}destroy(){this.worker&&=(this.worker.terminate(),null),this.releaseWorkerUrlLease(),this.stopAudioHealthMonitoring(),this.stopNoFrameWatchdog(),this.stopAudioWorklet(),this.detachAudioTrackWarnings(),this.isActive=!1,this.isPaused=!1,this.chunks=[],this.totalSize=0}cleanup(){this.destroy()}warmupEncoder(e){if(!this.worker)return;let t=e.format||`mp4`,n=Ht(t),r=e.codec||n.preferredVideoCodec,i=e.audioBitrate===void 0?n.audioBitrate:e.audioBitrate,a=Ht(t,{isLinuxPlatform:this.isLinuxPlatformFn()}),o=this.resolveAudioBitrate(e,t);this.resolveAudioCodecWithCache(e,t,a,o).catch(this.handleWarmupCacheError),this.resolveVideoCodecWithCache(e,t,a).catch(this.handleWarmupCacheError);let s={type:`warmup`,config:this.buildWorkerTranscodeConfig(e,n.preferredAudioCodec,i,r,t)};this.worker.postMessage(s)}getBufferSize(){return this.totalSize}getMutedState(){return this.isMuted}updateTabVisibility(e,t){if(!(this.isWorkerActive()&&this.worker)){$.warn(`[WorkerProcessor] Cannot update visibility - worker not active`,{isActive:this.isActive,hasWorker:!!this.worker});return}$.debug(`[WorkerProcessor] Sending visibility update to worker`,{isHidden:e,timestamp:t,timestampSeconds:t/EC});let n={type:`updateVisibility`,isHidden:e,timestamp:t};this.worker.postMessage(n)}updateSourceType(e){if(!(this.isWorkerActive()&&this.worker)){$.warn(`[WorkerProcessor] Cannot update source type - worker not active`,{isActive:this.isActive,hasWorker:!!this.worker});return}$.debug(`[WorkerProcessor] Sending source type update to worker`,{isScreenCapture:e});let t={type:`updateSourceType`,isScreenCapture:e};this.worker.postMessage(t)}async startAudioWorkletProcessing(){await this.audioWorkletManager.startProcessing()}stopAudioWorklet(){this.audioWorkletManager.stop()}setAudioWorkletMuted(e){this.audioWorkletManager.setMuted(e)}setAudioWorkletPaused(e){this.audioWorkletManager.setPaused(e)}prepareAudioConfig(e){return this.audioWorkletManager.prepareAudioConfig(e)}handleWarmupCacheError(){}createBrowserUnsupportedError(){return Nt({resolutionStage:`feature-preflight`})}getVideoInputSelectorDependencies(){return{stopCurrentVideoTrack:()=>this.stopCurrentVideoTrack(),cloneVideoTrack:e=>this.cloneVideoTrack(e),cloneAudioTrack:e=>this.cloneAudioTrack(e),setCurrentVideoTrack:e=>{this.currentVideoTrack=e},createVideoStreamFromTrack:e=>this.createVideoStreamFromTrackFn(e),createBrowserUnsupportedError:()=>this.createBrowserUnsupportedError(),getViewportMetadata:()=>{if(typeof window>`u`)return null;let e=window.screen,t,n,r,i;return e&&(i=e.orientation),i?.type&&(t=i.type),i&&typeof i.angle==`number`&&(n=i.angle),typeof window.orientation==`number`&&(r=window.orientation),{innerWidth:window.innerWidth,innerHeight:window.innerHeight,orientation:t,orientationAngle:n,windowOrientation:r}},logger:{debug:(e,t)=>$.debug(e,t),warn:(e,t)=>$.warn(e,t)},isMobileDevice:()=>Qt()}}isPausedState(){return this.isPaused}getClonedAudioTrack(){return this.audioTrackClone}getAudioStreamForAnalysis(){return this.audioTrackClone?new MediaStream([this.audioTrackClone]):null}setOnBufferUpdate(e){this.onBufferUpdate=e}setOnError(e){this.onError=e}setOnMuteStateChange(e){this.onMuteStateChange=e}setOnAudioWarning(e){this.onAudioWarning=e}setOnAudioRecovered(e){this.onAudioRecovered=e}cloneVideoTrack(e){if($.debug(`[WorkerProcessor] Original video track:`,{id:e.id,kind:e.kind,readyState:e.readyState,hasClone:typeof e.clone==`function`}),typeof e.clone==`function`)try{let t=e.clone();return $.debug(`[WorkerProcessor] Video track cloned successfully:`,{id:t.id,kind:t.kind,readyState:t.readyState}),t}catch(e){$.error(`[WorkerProcessor] Failed to clone video track:`,e);let t=i(e);throw Error(`Failed to clone video track: ${t}`)}return $.warn(`[WorkerProcessor] Video track clone() not available, using original`),e}attachAudioTrackWarnings(e){this.detachAudioTrackWarnings(),e.addEventListener(`ended`,this.handleAudioTrackEnded),e.addEventListener(`mute`,this.handleAudioTrackMuted),e.addEventListener(`unmute`,this.handleAudioTrackUnmuted),this.audioTrackWarningTarget=e}detachAudioTrackWarnings(){this.audioTrackWarningTarget&&=(this.audioTrackWarningTarget.removeEventListener(`ended`,this.handleAudioTrackEnded),this.audioTrackWarningTarget.removeEventListener(`mute`,this.handleAudioTrackMuted),this.audioTrackWarningTarget.removeEventListener(`unmute`,this.handleAudioTrackUnmuted),null)}cloneAudioTrack(e){if($.debug(`[WorkerProcessor] Original audio track:`,{id:e.id,kind:e.kind,readyState:e.readyState,hasClone:typeof e.clone==`function`}),typeof e.clone==`function`)try{let t=e.clone();return this.audioTrackClone=t,this.attachAudioTrackWarnings(t),$.debug(`[WorkerProcessor] Audio track cloned successfully:`,{id:t.id,kind:t.kind,readyState:t.readyState}),t}catch(e){$.error(`[WorkerProcessor] Failed to clone audio track:`,e);let t=i(e);throw Error(`Failed to clone audio track: ${t}`)}return $.warn(`[WorkerProcessor] Audio track clone() not available, using original`),this.audioTrackClone=e,this.attachAudioTrackWarnings(e),e}stopCurrentVideoTrack(){this.currentVideoTrack&&this.currentVideoTrack.readyState===`live`&&this.currentVideoTrack.stop(),this.currentVideoTrack=null}releaseWorkerUrlLease(){this.hasWorkerUrlLease&&=(TC(),!1)}},FC=class{constructor(e={}){this.currentVideoStream=null;let t=()=>new PC;e.workerProcessorFactory&&(t=e.workerProcessorFactory);try{this.workerProcessor=t(),$.debug(`[StreamProcessor] Using worker-based processing`)}catch(e){let t=i(e);throw Error(`Failed to initialize worker: ${t}`)}}async startProcessing(e,t,n){this.workerProcessor.setOnBufferUpdate((e,t)=>{$.debug(`[StreamProcessor] Buffer update:`,{size:e,formatted:t}),this.onBufferUpdate&&this.onBufferUpdate(e,t)}),this.workerProcessor.setOnError(e=>{$.error(`[StreamProcessor] Worker error:`,e),this.onError&&this.onError(e)}),this.currentVideoStream=e,await this.workerProcessor.startProcessing(e,t,n)}updateTabVisibility(e,t){this.workerProcessor.updateTabVisibility(e,t)}updateSourceType(e){this.workerProcessor.updateSourceType(e)}pause(){this.workerProcessor.pause()}resume(){this.workerProcessor.resume()}isPausedState(){return this.workerProcessor.isPausedState()}async finalize(){return $.debug(`[StreamProcessor] finalize called`),await this.workerProcessor.finalize()}toggleMute(){this.workerProcessor.toggleMute()}isMutedState(){return this.workerProcessor.getMutedState()}getClonedAudioTrack(){return this.workerProcessor.getClonedAudioTrack()}getAudioStreamForAnalysis(){return this.workerProcessor.getAudioStreamForAnalysis()}async switchVideoSource(e){await this.workerProcessor.switchVideoSource(e),this.currentVideoStream=e,this.onSourceChange&&this.onSourceChange(e)}getCurrentVideoSource(){return this.currentVideoStream}getBufferSize(){return this.workerProcessor.getBufferSize()}setOnMuteStateChange(e){this.workerProcessor.setOnMuteStateChange(e)}setOnSourceChange(e){this.onSourceChange=e}setOnBufferUpdate(e){this.onBufferUpdate=e}setOnError(e){this.onError=e}setOnAudioWarning(e){this.workerProcessor.setOnAudioWarning(e)}setOnAudioRecovered(e){this.workerProcessor.setOnAudioRecovered(e)}warmupEncoder(e){this.workerProcessor.warmupEncoder(e)}prewarm(){this.workerProcessor.prewarm()}async cancel(){await this.workerProcessor.cancel(),this.currentVideoStream=null}destroy(){this.workerProcessor.destroy(),this.currentVideoStream=null}};let IC=1e3,LC=`recording`,RC=`idle`,zC={route:`local-webcodecs`,reasonCodes:[`webcodecs-supported`,`target-codec-supported`]},BC={transcodeVideo:ly};function VC(e,t){let n=ry(t.format);return e.type.toLowerCase().startsWith(n)}var HC=class{constructor(e,t,n){this.recordingState=RC,this.countdownDuration=5e3,this.countdownRemaining=0,this.countdownTimeoutId=null,this.countdownIntervalId=null,this.countdownStartTime=null,this.isPaused=!1,this.maxRecordingTime=null,this.maxTimeTimer=null,this.recordingStartTime=null,this.maxTimeRemaining=null,this.recordingSeconds=0,this.recordingIntervalId=null,this.pauseStartTime=null,this.totalPausedTime=0,this.streamProcessor=null,this.originalCameraStream=null,this.enableTabVisibilityOverlay=!1,this.startupAborted=!1,this.activeRecordingConfig=null,this.activeRouteDecision=zC,this.streamManager=e,this.callbacks=t,this.dependencies={...BC,...n}}setCountdownDuration(e){this.countdownDuration=e}setMaxRecordingTime(e){this.maxRecordingTime=e}setTabVisibilityOverlayConfig(e,t){this.enableTabVisibilityOverlay=e,this.tabVisibilityOverlayText=t}getRecordingState(){return this.recordingState}isPausedState(){return this.isPaused}getRecordingSeconds(){return this.recordingSeconds}getStreamProcessor(){return this.streamProcessor}updateSourceType(e){this.recordingState!==LC||!this.streamProcessor||this.streamProcessor.updateSourceType(e)}setOriginalCameraStream(e){this.originalCameraStream=e}getOriginalCameraStream(){return this.originalCameraStream}prewarmStreamProcessor(e){let t=this.getOrCreateStreamProcessor();t.prewarm(),e&&t.warmupEncoder(e)}async startRecording(){try{this.callbacks.onClearUploadStatus(),this.countdownDuration>0?this.startCountdown():await this.doStartRecording()}catch(e){this.handleError(e),this.recordingState=RC,this.cancelCountdown()}}startCountdown(){this.recordingState=`countdown`,this.countdownRemaining=Math.ceil(this.countdownDuration/IC),this.countdownStartTime=Date.now(),this.callbacks.onCountdownUpdate(this.recordingState,this.countdownRemaining),this.countdownIntervalId=window.setInterval(()=>{if(!this.countdownStartTime)return;let e=Date.now()-this.countdownStartTime,t=Math.max(0,Math.ceil((this.countdownDuration-e)/IC)),n=this.countdownRemaining;this.countdownRemaining=t,n!==t&&this.callbacks.onCountdownUpdate(this.recordingState,this.countdownRemaining)},100),this.countdownTimeoutId=window.setTimeout(async()=>{await this.doStartRecording().catch(()=>void 0)},this.countdownDuration)}async doStartRecording(){$.debug(`[RecordingManager] doStartRecording called`),this.cancelCountdown(),this.resetRecordingState(),this.startupAborted=!1;let e=this.streamManager.getStream();if($.debug(`[RecordingManager] Current stream:`,{hasStream:!!e,audioTracks:e?.getAudioTracks().length||0,videoTracks:e?.getVideoTracks().length||0}),!e){$.warn(`[RecordingManager] No stream available`),this.handleError(Error(`No stream available for recording`)),this.recordingState=RC,this.callbacks.onStateChange(this.recordingState);return}this.originalCameraStream=e,$.debug(`[RecordingManager] Ensuring stream processor`);let t=this.getOrCreateStreamProcessor();$.debug(`[RecordingManager] StreamProcessor ready:`,!!t);let n=null,r=await this.callbacks.onGetConfig().then(e=>(n=e,null)).catch(e=>e);if(r){this.handleError(r),this.recordingState=RC,this.callbacks.onStateChange(this.recordingState);return}if(!n){this.handleError(Error(`Failed to get recording config`)),this.recordingState=RC,this.callbacks.onStateChange(this.recordingState);return}let i=await this.resolveRouteDecision();if(i instanceof Error){this.handleError(i),this.recordingState=RC,this.callbacks.onStateChange(this.recordingState);return}this.callbacks.onAudioWarning&&t.setOnAudioWarning(this.callbacks.onAudioWarning),this.callbacks.onAudioRecovered&&t.setOnAudioRecovered(this.callbacks.onAudioRecovered),t.setOnError(e=>{this.handleFatalProcessorError(e)}),this.activeRecordingConfig=n,this.activeRouteDecision=i,$.debug(`[RecordingManager] Starting recording with stream manager`);let a=await this.streamManager.startRecording(t,n,this.enableTabVisibilityOverlay,this.tabVisibilityOverlayText,i).then(()=>null).catch(e=>($.error(`[RecordingManager] Error starting recording:`,e),e));if(a){this.activeRecordingConfig=null,this.activeRouteDecision=zC,this.handleError(a),this.recordingState=RC,this.callbacks.onStateChange(this.recordingState);return}if(this.startupAborted){this.startupAborted=!1;return}$.info(`[RecordingManager] Recording started successfully`),this.recordingState=LC,this.callbacks.onStateChange(this.recordingState),this.startRecordingTimer(),this.recordingStartTime=Date.now(),this.maxRecordingTime&&this.maxRecordingTime>0&&(this.maxTimeRemaining=this.maxRecordingTime,this.startMaxTimeTimer())}async stopRecording(){$.debug(`[RecordingManager] stopRecording called`);try{if(this.recordingState!==LC){let e=this.recordingState;throw this.cancelCountdown(),Dx(wx,`Recording is not ready to stop`,{recordingState:e,hasStreamProcessor:!!this.streamProcessor})}this.cancelCountdown(),this.clearTimer(this.recordingIntervalId,clearInterval),this.recordingIntervalId=null,this.clearTimer(this.maxTimeTimer,clearTimeout),this.maxTimeTimer=null,this.resetPauseState(),this.callbacks.onStopAudioTracking(),$.debug(`[RecordingManager] Stopping recording in stream manager`);let e=await this.streamManager.stopRecording(),t=await this.resolveFinalRecordingBlob(e.blob);$.info(`[RecordingManager] Recording stopped, blob size:`,t.size),this.recordingState=RC,this.callbacks.onStateChange(this.recordingState),this.recordingSeconds=0,this.streamProcessor&&=(this.streamProcessor.destroy(),null),this.callbacks.onRecordingComplete(t);let n={};return e.recordingStats!==void 0&&(n.videoFrameCount=e.recordingStats.videoFrameCount,n.totalFrameErrors=e.recordingStats.totalFrameErrors,n.totalFramesProcessed=e.recordingStats.totalFramesProcessed),e.encoderAcceleration!==void 0&&(n.encoderAcceleration=e.encoderAcceleration),{blob:t,telemetryProperties:n}}catch(e){let t=Ox(e);throw this.handleError(t),this.recordingState=RC,this.callbacks.onStateChange(this.recordingState),t}finally{this.activeRecordingConfig=null,this.activeRouteDecision=zC}}pauseRecording(){if(!(this.recordingState!==LC||this.isPaused)&&(this.streamManager.pauseRecording(),this.isPaused=!0,this.clearTimer(this.recordingIntervalId,clearInterval),this.recordingIntervalId=null,this.pauseStartTime=Date.now(),this.maxTimeTimer!==null&&this.recordingStartTime!==null&&this.maxRecordingTime!==null)){let e=Date.now()-this.recordingStartTime-this.totalPausedTime;this.maxTimeRemaining=Math.max(0,this.maxRecordingTime-e),this.clearTimer(this.maxTimeTimer,clearTimeout),this.maxTimeTimer=null}}resumeRecording(){this.recordingState!==LC||!this.isPaused||(this.streamManager.resumeRecording(),this.isPaused=!1,this.updatePausedDuration(),this.startRecordingTimer(),this.maxTimeRemaining!==null&&this.maxTimeRemaining>0&&this.startMaxTimeTimer())}cancelCountdown(){this.clearTimer(this.countdownTimeoutId,clearTimeout),this.countdownTimeoutId=null,this.clearTimer(this.countdownIntervalId,clearInterval),this.countdownIntervalId=null,this.recordingState=RC,this.countdownRemaining=0,this.countdownStartTime=null,this.callbacks.onCountdownUpdate(this.recordingState,this.countdownRemaining)}cleanup(){this.cancelCountdown(),this.clearTimer(this.recordingIntervalId,clearInterval),this.recordingIntervalId=null,this.clearTimer(this.maxTimeTimer,clearTimeout),this.maxTimeTimer=null,this.streamProcessor&&=(this.streamProcessor.destroy(),null)}resetRecordingState(){this.isPaused=!1,this.recordingSeconds=0,this.totalPausedTime=0,this.pauseStartTime=null,this.recordingStartTime=null,this.maxTimeRemaining=null}async resolveFinalRecordingBlob(e){if(this.activeRouteDecision.route!==`safe-capture-post-recording-transcode`)return e;if(!this.activeRecordingConfig)throw Error(`Recording config unavailable for final video processing`);if(VC(e,this.activeRecordingConfig))return e;this.callbacks.onTranscodingProgress?.(0);let t=await this.dependencies.transcodeVideo(e,this.activeRecordingConfig,e=>{this.callbacks.onTranscodingProgress?.(e)});return this.callbacks.onTranscodingProgress?.(1),t.blob}resetPauseState(){this.isPaused=!1,this.pauseStartTime=null,this.totalPausedTime=0}getOrCreateStreamProcessor(){if(this.streamProcessor)return this.streamProcessor;let e=new FC;return this.streamProcessor=e,e}async resolveRouteDecision(){return this.callbacks.onGetRouteDecision?await this.callbacks.onGetRouteDecision().then(e=>e).catch(e=>e instanceof Error?e:Error(i(e))):zC}updatePausedDuration(){if(this.pauseStartTime===null)throw Error(`Pause start time not set`);let e=Date.now()-this.pauseStartTime;this.totalPausedTime+=e,this.pauseStartTime=null}startRecordingTimer(){if(this.recordingIntervalId!==null)return;let e=Nx(this.recordingSeconds);this.callbacks.onTimerUpdate(e),this.recordingIntervalId=window.setInterval(()=>{this.recordingSeconds+=1;let e=Nx(this.recordingSeconds);this.callbacks.onTimerUpdate(e)},1e3)}startMaxTimeTimer(){this.maxTimeRemaining===null||this.maxTimeRemaining<=0||(this.clearTimer(this.maxTimeTimer,clearTimeout),this.maxTimeTimer=window.setTimeout(async()=>{this.recordingState===LC&&!this.isPaused&&await this.stopRecording()},this.maxTimeRemaining))}clearTimer(e,t){e!==null&&t(e)}handleError(e){let t=e instanceof Error?e:Error(i(e));this.callbacks.onError(t)}handleFatalProcessorError(e){this.recordingState===LC&&(this.clearTimer(this.recordingIntervalId,clearInterval),this.recordingIntervalId=null,this.clearTimer(this.maxTimeTimer,clearTimeout),this.maxTimeTimer=null,this.resetPauseState()),!(!this.streamProcessor&&this.recordingState!==LC)&&($.error(`[RecordingManager] Fatal processor error, stopping recording`,e),this.startupAborted=!0,this.streamProcessor&&=(this.streamProcessor.destroy(),null),this.recordingState=RC,this.callbacks.onStateChange(this.recordingState),this.recordingSeconds=0,this.callbacks.onError(e))}},UC=class{constructor(e){this.client=null,this.createTelemetryClient=e.createTelemetryClient}initialize(e,t){typeof e==`string`&&e.length>0&&typeof t==`string`&&t.length>0&&(this.client=this.createTelemetryClient(e,t))}sendEvent(e,t,n){if(!this.client)return;let r={name:e};t&&(r={...r,properties:t}),n&&(r={...r,error:n}),this.client.triggerTelemetryEvent(r)}async executeAction(e){e.requestedEvent&&this.sendEvent(e.requestedEvent,e.properties);let t=null;if(await e.action().catch(e=>{t=e}),t)throw this.sendEvent(e.failedEvent,e.properties,t),t;this.sendEvent(e.succeededEvent,e.properties)}async executeActionWithResult(e){e.requestedEvent&&this.sendEvent(e.requestedEvent,e.properties);let t=null,n=null;if(await e.action().then(e=>{n=e}).catch(e=>{t=e}),t)throw this.sendEvent(e.failedEvent,e.properties,t),t;if(n===null)throw Error(`Telemetry action failed to return result`);let r=this.resolveResultTelemetryProperties(n,e.getPropertiesFromResult),i=this.mergeTelemetryProperties(e.properties,r);return this.sendEvent(e.succeededEvent,i),n}resolveResultTelemetryProperties(e,t){if(t!==void 0)return t(e)}mergeTelemetryProperties(e,t){if(!(e===void 0&&t===void 0))return e===void 0?t:t===void 0?e:{...e,...t}}},WC=class{constructor(){this.metadataById=new Map}getMetadata(e){return this.metadataById.get(e)}setMetadata(e,t){let n=new Map(this.metadataById);n.set(e,t),this.metadataById=n}clearMetadata(e){let t=new Map(this.metadataById);t.delete(e),this.metadataById=t}};let GC=`[RecorderController]`;var KC=class{constructor(e={}){this.uploadService=null,this.uploadQueueManager=null,this.isInitialized=!1,this.isDemo=!1,this.isDestroyed=!1,this.enableTabVisibilityOverlay=!1,this.recordingWarmupTimeoutId=null,this.audioTelemetryUnsub=null,this.callbacks=e,this.streamManager=new Wx,this.configManager=new dn,this.storageManager=new jb,this.deviceManager=new fn(this.streamManager,e.device),this.audioLevelAnalyzer=new o,this.uploadService=new bS,this.uploadCallbacks=MS(e),this.telemetryManager=new UC({createTelemetryClient:vS}),this.uploadMetadataManager=new WC;let t=IS(e,{stopAudioTracking:()=>this.audioLevelAnalyzer.stopTracking(),getConfig:()=>Promise.resolve(this.configManager.getConfigForRecording()),getRouteDecision:async()=>await this.resolveRecordingRouteDecision(`live-recorder`),onAudioWarning:e.recording?.onAudioWarning?t=>{this.sendAudioWarningTelemetry(t),e.recording?.onAudioWarning?.(t)}:e=>{this.sendAudioWarningTelemetry(e)},...e.recording?.onAudioRecovered&&{onAudioRecovered:e.recording.onAudioRecovered},...e.recording?.onTranscodingProgress&&{onTranscodingProgress:e.recording.onTranscodingProgress}});this.recordingManager=new HC(this.streamManager,t);let n=LS(e,{isRecording:()=>this.isRecording(),updateSourceType:e=>{this.recordingManager.updateSourceType(e)},getSelectedCameraDeviceId:()=>this.deviceManager.getSelectedCameraDeviceId(),getSelectedMicDeviceId:()=>this.deviceManager.getSelectedMicDeviceId()});this.sourceSwitchManager=new lx(this.streamManager,n);let r=e.stream;r&&(this.streamManager.on(`streamstart`,({stream:e})=>{$.debug(`${GC} streamstart event received, calling callback`),r.onStreamStart&&r.onStreamStart(e)}),this.streamManager.on(`streamstop`,()=>{$.debug(`${GC} streamstop event received, calling callback`),r.onStreamStop&&r.onStreamStop()}),this.streamManager.on(`error`,({error:e})=>{$.error(`${GC} stream error event received, calling callback`,e),this.telemetryManager.sendEvent(`stream.error`,{sourceType:this.getCurrentSourceType()},e),r.onError&&r.onError(e)})),this.audioTelemetryUnsub=this.streamManager.on(`audiotelemetry`,({event:e})=>{let t=this.getBrowserNameForTelemetry();this.telemetryManager.sendEvent(e.name,{...e.properties,browserName:t,sourceType:this.getCurrentSourceType()},e.error)})}async initialize(e){if(this.isInitialized)return;await this.validateRecorderSupport();let t=!1;typeof e.demo==`boolean`&&(t=e.demo),this.isDemo=t;let n=null;typeof e.apiKey==`string`&&e.apiKey.length>0&&(n=e.apiKey);let r=null;typeof e.backendUrl==`string`&&e.backendUrl.length>0&&(r=e.backendUrl),this.telemetryManager.initialize(n,r),await this.telemetryManager.executeAction({requestedEvent:`sdk.init.started`,succeededEvent:`sdk.init.succeeded`,failedEvent:`sdk.init.failed`,action:async()=>{await this.initializeConfig(n,r),this.applyRecordingConfig(e),await this.initializeStorage(),this.isInitialized=!0,this.scheduleRecordingWarmup()}})}async startStream(){let e=this.getCurrentSourceType();await this.telemetryManager.executeAction({succeededEvent:`preview.start.succeeded`,failedEvent:`preview.start.failed`,action:async()=>{$.debug(`${GC} startStream called`),await this.streamManager.startStream(),this.ignorePromiseRejection(this.ensureConfigReady()),this.ignorePromiseRejection(this.configManager.getConfig().then(e=>{this.recordingManager.prewarmStreamProcessor(e)})),this.prewarmSupportCheck(),$.debug(`${GC} startStream completed`)},properties:{sourceType:e}})}async stopStream(){await this.streamManager.stopStream()}switchVideoDevice(e){return this.streamManager.switchVideoDevice(e)}switchAudioDevice(e){return this.streamManager.switchAudioDevice(e)}async startRecording(){let e=this.getCurrentSourceType();await this.telemetryManager.executeAction({requestedEvent:`recording.start.requested`,succeededEvent:`recording.start.succeeded`,failedEvent:`recording.start.failed`,action:async()=>{await this.ensureConfigReady(),await this.streamManager.waitForAudio(),await this.recordingManager.startRecording()},properties:{sourceType:e}})}async stopRecording(){let e=this.getCurrentSourceType();try{return(await this.telemetryManager.executeActionWithResult({requestedEvent:`recording.stop.requested`,succeededEvent:`recording.stop.succeeded`,failedEvent:`recording.stop.failed`,action:async()=>{let e=await this.recordingManager.stopRecording();return await this.sourceSwitchManager.handleRecordingStop().catch(()=>{throw Error(`Source switch cleanup failed`)}),this.streamManager.stopStream(),e},properties:{sourceType:e},getPropertiesFromResult:e=>e.telemetryProperties})).blob}catch(e){throw xb(e)&&this.sendAudioMissingTelemetry(e),e}}sendAudioMissingTelemetry(e){let t={code:e.code,sourceType:this.getCurrentSourceType(),browserName:this.getBrowserNameForTelemetry()};e.details&&(t.durationMs=e.details.durationMs,t.totalChunks=e.details.totalChunks,t.nonSilentChunks=e.details.nonSilentChunks,t.mutedDurationMs=e.details.mutedDurationMs,t.silenceRatio=e.details.durationMs>0?e.details.mutedDurationMs/e.details.durationMs:0,t.hadTrackEndedWarning=e.details.hadTrackEndedWarning),this.telemetryManager.sendEvent(`recording.audio-missing`,t)}getTabVisibilityOverlayConfig(){return{enabled:this.enableTabVisibilityOverlay,text:this.tabVisibilityOverlayText}}pauseRecording(){this.recordingManager.pauseRecording()}resumeRecording(){this.recordingManager.resumeRecording()}async switchSource(e){await this.telemetryManager.executeAction({requestedEvent:`source.switch.requested`,succeededEvent:`source.switch.succeeded`,failedEvent:`source.switch.failed`,action:async()=>{await this.sourceSwitchManager.toggleSource()},properties:{sourceType:e}})}setCameraDevice(e){this.deviceManager.setCameraDevice(e)}setMicDevice(e){this.deviceManager.setMicDevice(e)}getAvailableDevices(){return this.deviceManager.getAvailableDevices()}muteAudio(){this.streamManager.muteAudio()}unmuteAudio(){this.streamManager.unmuteAudio()}toggleMute(){this.streamManager.toggleMute()}getIsMuted(){return this.streamManager.isMuted()}startAudioLevelTracking(e,t){if(!t)throw Error(`Audio level callbacks are required`);return this.audioLevelAnalyzer.startTracking(e,t,()=>this.streamManager.isMuted()),Promise.resolve()}stopAudioLevelTracking(){this.audioLevelAnalyzer.stopTracking()}getAudioLevel(){return this.audioLevelAnalyzer.getAudioLevel()}async uploadVideo(e,t,n,r){this.uploadCallbacks.onClearStatus();let i=await Cv(e),a=this.configManager.getConfigForRecording().format,o=`recording-${Date.now()}.${iy(a)}`,s=ry(a),c=this.getCurrentSourceType(),l;if(Object.keys(r).length>0&&(l=r),this.telemetryManager.sendEvent(`upload.started`,{filename:o,duration:i,sourceType:c}),!this.uploadQueueManager){await this.uploadDirectlyWithoutQueue({blob:e,apiKey:t,backendUrl:n,filename:o,mimeType:s,duration:i,sourceType:c,userMetadata:l});return}let u=await this.uploadQueueManager.queueUpload({blob:e,apiKey:t,backendUrl:n,filename:o,mimeType:s,duration:i,metadata:void 0,userMetadata:l});this.uploadMetadataManager.setMetadata(u,{filename:o,duration:i,sourceType:c})}async uploadDirectlyWithoutQueue(e){if(!this.uploadService){let t=Error(`Upload service not available`);throw this.uploadCallbacks.onError(t),this.telemetryManager.sendEvent(`upload.failed`,{filename:e.filename,duration:e.duration,sourceType:e.sourceType},t),t}try{let t=await this.uploadService.uploadVideo(e.blob,{apiKey:e.apiKey,backendUrl:e.backendUrl,filename:e.filename,mimeType:e.mimeType,metadata:void 0,userMetadata:e.userMetadata,onProgress:this.uploadCallbacks.onProgress});this.uploadCallbacks.onSuccess(t),this.telemetryManager.sendEvent(`upload.succeeded`,{filename:e.filename,duration:e.duration,sourceType:e.sourceType,recordingId:t.id})}catch(t){let n=t instanceof Error?t:Error(i(t));throw this.uploadCallbacks.onError(n),this.telemetryManager.sendEvent(`upload.failed`,{filename:e.filename,duration:e.duration,sourceType:e.sourceType},n),n}}getStream(){return this.streamManager.getStream()}isConfigReady(){return this.configManager.isConfigReady()}ensureConfigReady(){return this.isDemo||this.configManager.isConfigReady()?Promise.resolve():this.configManager.fetchConfig().then(()=>void 0).catch(()=>void 0)}cleanup(){this.isDestroyed=!0,this.recordingWarmupTimeoutId!==null&&(clearTimeout(this.recordingWarmupTimeoutId),this.recordingWarmupTimeoutId=null),this.audioTelemetryUnsub&&=(this.audioTelemetryUnsub(),null),this.uploadQueueManager?.destroy(),this.storageManager.destroy(),this.recordingManager.cleanup(),this.audioLevelAnalyzer.stopTracking(),this.sourceSwitchManager.cleanup()}getRecordingState(){return this.recordingManager.getRecordingState()}isPaused(){return this.recordingManager.isPausedState()}getCurrentSourceType(){return this.sourceSwitchManager.getCurrentSourceType()}getOriginalCameraStream(){return this.sourceSwitchManager.getOriginalCameraStream()}getStreamManager(){return this.streamManager}getAudioStreamForAnalysis(){return this.streamManager.getAudioStreamForAnalysis()}getDeviceManager(){return this.deviceManager}getConfig(){return this.configManager.getConfig()}getUploadService(){return this.uploadService}isRecording(){return this.streamManager.isRecording()}isActive(){return this.streamManager.isActive()}isAudioReady(){return this.streamManager.isAudioReady()}getAudioStatus(){return this.streamManager.getAudioStatus()}sendAudioWarningTelemetry(e){let t={code:e.code,sourceType:this.getCurrentSourceType(),browserName:this.getBrowserNameForTelemetry()};`durationMs`in e&&(t.durationMs=e.durationMs),`peak`in e&&(t.peak=e.peak),`rms`in e&&(t.rms=e.rms),this.telemetryManager.sendEvent(`audio.warning`,t)}getBrowserNameForTelemetry(){try{return Mt()}catch{return`unknown`}}async resolveRecordingRouteDecision(e){let t=this.configManager.getConfigForRecording(),n=this.buildCodecProbeCandidates(t),r=await Lv({codecCandidates:n}),i=Gv({profile:r,targetCodecIds:n.map(e=>e.id)});return this.telemetryManager.sendEvent(`recording.route.selected`,{routeDecision:this.buildRouteTelemetryProperties(i,r,e)}),i}buildCodecProbeCandidates(e){let t=e.width??1280,n=e.height??720,r=typeof e.bitrate==`number`?e.bitrate:25e5,i=e.fps??30;return this.resolveTargetCodecIds(e.codec).map(e=>({id:`${e}-${t}x${n}`,config:{codec:e,width:t,height:n,bitrate:r,framerate:i}}))}resolveTargetCodecIds(e){switch(e){case`avc`:return[`avc1.640028`,`avc1.42001f`];case`vp9`:return[`vp09.00.10.08`];case`vp8`:return[`vp8`];case`av1`:return[`av01.0.08M.08`];case`hevc`:return[`hvc1.1.6.L123.B0`];default:return[`avc1.640028`,`avc1.42001f`,`vp09.00.10.08`,`vp8`]}}buildRouteTelemetryProperties(e,t,n){return{selectedRoute:e.route,reasonCodes:e.reasonCodes,sourceType:n,clientTranscodeDeferred:e.route===`safe-capture-post-recording-transcode`,capabilitySummary:{browserName:t.browser.normalizedName,osName:t.os.name,deviceMemory:t.resources.deviceMemory??null,hardwareConcurrency:t.resources.hardwareConcurrency??null,effectiveType:t.network.effectiveType??null,online:t.network.online??null,isSecureContext:t.features.isSecureContext,hasMediaRecorder:t.features.hasMediaRecorder,hasVideoEncoder:t.features.hasVideoEncoder,supportedCodecIds:t.codecProbeResults.filter(e=>e.supported).map(e=>e.id)}}}async initializeConfig(e,t){let n=!0;e===null&&(n=!1),t===null&&(n=!1),n&&e!==null&&t!==null&&await this.configManager.initialize(e,t)}applyRecordingConfig(e){e.countdownDuration!==void 0&&this.recordingManager.setCountdownDuration(e.countdownDuration),e.maxRecordingTime!==void 0&&this.recordingManager.setMaxRecordingTime(e.maxRecordingTime),e.enableTabVisibilityOverlay!==void 0&&(this.enableTabVisibilityOverlay=e.enableTabVisibilityOverlay),e.tabVisibilityOverlayText!==void 0&&(this.tabVisibilityOverlayText=e.tabVisibilityOverlayText),this.recordingManager.setTabVisibilityOverlayConfig(this.enableTabVisibilityOverlay,this.tabVisibilityOverlayText)}async initializeStorage(){if(this.isDestroyed)return;let e=PS(this.callbacks);try{await this.storageManager.initialize(e)}catch(e){let t=e instanceof Error?e:Error(i(e)),n=i(t);this.telemetryManager.sendEvent(`storage.init.failed`,{reason:n},t),FS(this.callbacks)(n);return}if(this.isDestroyed)return;let t=this.storageManager.getWriteProbeResult();if(!t?.ok){let e=t?.reason??`Storage write probe did not complete`;this.telemetryManager.sendEvent(`storage.write.probe.failed`,{reason:e}),FS(this.callbacks)(e);return}let n=this.storageManager.getStorageService();n&&this.uploadService&&(this.uploadQueueManager=new yS(n,this.uploadService),this.uploadQueueManager.setCallbacks({onUploadProgress:(e,t)=>{this.uploadCallbacks.onProgress(t)},onUploadComplete:(e,t)=>{this.uploadCallbacks.onSuccess(t);let n=this.uploadMetadataManager.getMetadata(e);n&&(this.telemetryManager.sendEvent(`upload.succeeded`,{filename:n.filename,duration:n.duration,sourceType:n.sourceType,recordingId:t.id}),this.uploadMetadataManager.clearMetadata(e))},onUploadError:(e,t)=>{this.uploadCallbacks.onError(t);let n=this.uploadMetadataManager.getMetadata(e);n&&(this.telemetryManager.sendEvent(`upload.failed`,{filename:n.filename,duration:n.duration,sourceType:n.sourceType},t),this.uploadMetadataManager.clearMetadata(e))}}))}async validateRecorderSupport(){Ft();let e=await ub({requiresAudio:!1,requiresWatermark:!1});if(!e.isSupported)throw Nt({missingCapabilities:e.missing,resolutionStage:`feature-preflight`})}scheduleRecordingWarmup(){this.recordingWarmupTimeoutId!==null&&(clearTimeout(this.recordingWarmupTimeoutId),this.recordingWarmupTimeoutId=null),!this.isDestroyed&&(this.recordingWarmupTimeoutId=setTimeout(()=>{this.recordingWarmupTimeoutId=null,!this.isDestroyed&&(this.ignorePromiseRejection(this.ensureConfigReady()),this.ignorePromiseRejection(this.configManager.getConfig().then(e=>{this.recordingManager.prewarmStreamProcessor(e)})))},0))}ignorePromiseRejection(e){e.catch(()=>void 0)}prewarmSupportCheck(){this.ignorePromiseRejection(ub({requiresAudio:!0,requiresWatermark:!0}).then(e=>{this.streamManager.setPreResolvedSupportReport(e)}))}};let qC=/<a\s[^>]*href="(?<href>[^"]+)"[^>]*>(?<text>[^<]+)<\/a>/,JC=/\starget=["'](?<target>[^"']+)["']/,YC=/^[a-zA-Z][a-zA-Z\d+\-.]*:/,XC=`{version}`;function ZC(e,t){return e?e.toLowerCase().includes(t):!1}function QC(e){let t=e.trim();if(!t)return null;let n=t.toLowerCase();return!YC.test(n)||n.startsWith(`http:`)||n.startsWith(`https:`)?t:null}function $C(e,t,n,r){return e===`browser.unsupported`?r.browserUnsupportedDynamic?nw(r.browserUnsupportedDynamic,t,n):ZC(t,`safari`)?r.browserUnsupportedSafari:ZC(t,`firefox`)?r.browserUnsupportedFirefox:r.browserUnsupported:r.browserUnsupported}function ew(e,t){return e===`camera.in-use`?t.cameraInUse:e===`camera.not-found`?t.cameraNotFound:e===`camera.permission-denied`?t.cameraPermissionDenied:e===`camera.timeout`?t.cameraTimeout??t.failedToStartCamera:t.failedToStartCamera}function tw(e,t){return e===`audio.in-use`?t.audioInUse:e===`audio.not-found`?t.audioNotFound:e===`audio.permission-denied`?t.audioPermissionDenied:e===`audio.timeout`?t.audioTimeout??t.failedToStartAudio:t.failedToStartAudio}function nw(e,t,n){let r=`This browser`;t&&t.trim().length>0&&(r=t);let i=e.replace(`{browser}`,r);return n&&n.trim().length>0&&n?(i=i.replace(XC,n),i):(i=i.replace(` ({version})`,``),i=i.replace(XC,``),i)}function rw(e){let t=qC.exec(e);if(!t?.groups)return{prefix:e,linkText:null,linkHref:null,linkTarget:null,suffix:``};let n=t.index,r=n+t[0].length,i=e.slice(0,n),a=e.slice(r),o=QC(t.groups.href);if(!o)return{prefix:i+t.groups.text+a,linkText:null,linkHref:null,linkTarget:null,suffix:``};let s=JC.exec(t[0])?.groups?.target??null;return{prefix:i,linkText:t.groups.text,linkHref:o,linkTarget:s,suffix:a}}function iw(){let e=globalThis.navigator&&typeof globalThis.navigator.userAgent==`string`?globalThis.navigator.userAgent:``,t=new wt(e).getResult(),n=t.device.type,r=n===`mobile`||n===`tablet`;return $.debug(`Mobile detection result`,{userAgent:e,deviceType:n,isMobile:r,device:t.device,os:t.os,browser:t.browser}),r}function aw(){let e=jt(),t=null;e.name.length>0&&(t=e.name);let n=null;return e.version.length>0&&(n=e.version),{browserName:t,browserVersion:n}}function ow(e){let t=t=>{if(!(`code`in t))return;let n=t;if(n.code!==`browser.unsupported`){(n.code?.startsWith(`camera.`)||n.code?.startsWith(`audio.`)||n.code?.startsWith(`recording.`))&&e.updateState({errorCode:n.code,canRetry:!0,browserName:null,browserVersion:null});return}let r=aw(),i=r.browserName;n.browserName&&n.browserName.length>0&&(i=n.browserName);let a=r.browserVersion;n.browserVersion&&n.browserVersion.length>0&&(a=n.browserVersion),e.updateState({errorCode:`browser.unsupported`,canRetry:!1,browserName:i,browserVersion:a})};return{recording:{onStateChange:t=>{e.updateState({recordingState:t}),t===`idle`&&(e.isProcessingBlob=!1)},onCountdownUpdate:(t,n)=>{e.updateState({recordingState:t,countdown:n})},onTimerUpdate:t=>{e.updateState({timer:t})},onError:n=>{t(n),e.updateState({error:i(n),transcodingProgress:null})},onRecordingComplete:t=>{e.updateState({countdown:null}),e.processRecordingBlob(t).catch(t=>{e.updateState({error:i(t)})})},onClearUploadStatus:()=>{e.updateState({uploadProgress:null})},onTranscodingProgress:t=>{e.updateState({transcodingProgress:t})},onAudioWarning:t=>{e.updateState({audioWarning:t}),e.dispatchEvent(new CustomEvent(`vidtreo:audio-warning`,{detail:t}))},onAudioRecovered:()=>{e.updateState({audioWarning:null}),e.dispatchEvent(new CustomEvent(`vidtreo:audio-recovered`))},onStopAudioTracking:()=>void 0,onGetConfig:()=>{if(!e.controller)throw Error(`Controller not initialized`);return e.isDemo?Promise.resolve(Zt(`mp4`)):e.controller.getConfig()}},sourceSwitch:{onSourceChange:e=>Promise.resolve(),onPreviewUpdate:t=>(e.updateState({stream:t}),Promise.resolve()),onError:n=>{t(n),e.updateState({error:i(n)})},onTransitionStart:t=>{e.updateState({transitionMessage:t})},onTransitionEnd:()=>{e.updateState({transitionMessage:null})}},storage:{onUploadProgress:()=>void 0,onUploadComplete:()=>void 0,onUploadError:()=>void 0},onStorageCleanupError:t=>{e.updateState({error:t})}}}function sw(e,t){let n=(e=>e===``||e===`default`?null:e)(t);return e.setCameraDevice(n),e.switchVideoDevice(n)}function cw(e,t){let n=(e=>e===``||e===`default`?null:e)(t);return e.setMicDevice(n),e.switchAudioDevice(n)}async function lw(e,t=`camera`){e.isActive()||await e.startStream(),t!==e.getCurrentSourceType()&&await e.switchSource(t),await e.startRecording()}async function uw(e,t,n,r){return await e.stopRecording()}function dw(e){e.pauseRecording()}function fw(e){e.resumeRecording()}async function pw(e,t){await e.switchSource(t)}let mw=`camera`,hw=`screen`,gw=`recording`,_w=`browser.unsupported`,vw=[.8,1.2,.9];function yw(e,t){let{uploadProgress:n,uploadingLabel:r}=e,{overlay:i,fill:a,text:o}=t;if(!i)return;if(n===null){i.style.display=`none`;return}i.style.display=`block`;let s=Math.round(n*100);a&&(a.style.width=`${s}%`),o&&(o.textContent=`${r} ${s}%`)}function bw(e,t){let{transitionMessage:n}=e,{overlay:r,message:i}=t;if(r){if(!n){r.classList.remove(`vidtreo-active`);return}r.classList.add(`vidtreo-active`),i&&(i.textContent=n)}}let xw=`none`,Sw=`flex`,Cw=`inline-flex`,ww=`checking`,Tw=`blocked`,Ew=`ready`,Dw=`vidtreo-active`,Ow=`vidtreo-permission-flow--fading`,kw=`vidtreo-permission-flow-action--requesting`;function Aw(e){return{container:e.querySelector(`#permissionFlow`),spinner:e.querySelector(`#permissionFlowSpinner`),title:e.querySelector(`#permissionFlowTitle`),subtitle:e.querySelector(`#permissionFlowSubtitle`),actionButton:e.querySelector(`#btnAllowPermission`),buttonIcon:e.querySelector(`#permissionFlowBtnIcon`),buttonSpinner:e.querySelector(`#permissionFlowBtnSpinner`),buttonText:e.querySelector(`#permissionFlowBtnText`),recovery:e.querySelector(`#permissionFlowRecovery`),recoveryTitle:e.querySelector(`#permissionFlowRecoveryTitle`),recoveryText:e.querySelector(`#permissionFlowRecoveryText`),retryButton:e.querySelector(`#btnRetryPermission`),recoveryGuideUrl:e.querySelector(`#recoveryGuideUrl`),recoveryGuidePopoverUrl:e.querySelector(`#recoveryGuidePopoverUrl`)}}function jw(e){return e.permissions.camera===`granted`?`microphone`:`camera`}function Mw(e,t){return t.cameraTitle}function Nw(e,t){return t.cameraLabel}function Pw(e,t){return t.allowCamera}function Fw(e,t,n){let r=e.step,i=!1;(r===ww||r===`awaiting-user`||r===Tw||r===Ew)&&(i=!0);let a=r===Ew,o=r===Tw,s=r===ww,c=jw(e),l=Mw(c,t),u=Nw(c,t),d=Pw(c,t),f=t.recoveryInstructions;return e.recoveryData?.resetInstructions&&(f=e.recoveryData.resetInstructions),{isVisible:i,isFadingOut:n,isSpinnerOnly:a,isBlocked:o,isRequesting:s,titleText:l,subtitleText:u,actionLabel:d,requestingText:t.statusRequesting,recoveryTitleText:t.recoveryTitle,recoveryInstructionsText:f}}function Iw(e,t,n){if(e){if(t){e.style.display=n;return}e.style.display=xw}}function Lw(e,t){if(t.isVisible)e.classList.add(Dw);else return e.classList.remove(Dw),e.classList.remove(Ow),!1;return t.isFadingOut?e.classList.add(Ow):e.classList.remove(Ow),!0}function Rw(e,t,n){Iw(e.actionButton,n,Cw),e.actionButton&&(t.isRequesting?(e.actionButton.classList.add(kw),e.actionButton.disabled=!0):(e.actionButton.classList.remove(kw),e.actionButton.disabled=!1)),Iw(e.buttonIcon,n&&!t.isRequesting,Cw),Iw(e.buttonSpinner,n&&t.isRequesting,Cw),e.buttonText&&(t.isRequesting?e.buttonText.textContent=t.requestingText:e.buttonText.textContent=t.actionLabel)}function zw(){if(globalThis.window===void 0)return`vidtreo.com`;let e=globalThis.window.location.hostname||`vidtreo.com`;return e.length>20?`${e.slice(0,20)}...`:e}function Bw(e,t){if(Iw(e.recovery,t.isBlocked,Sw),e.recoveryTitle&&(e.recoveryTitle.textContent=t.recoveryTitleText),Iw(e.recoveryText,!1,xw),Iw(e.retryButton,!1,xw),t.isBlocked){let t=zw();e.recoveryGuideUrl&&(e.recoveryGuideUrl.textContent=t),e.recoveryGuidePopoverUrl&&(e.recoveryGuidePopoverUrl.textContent=t)}}function Vw(e,t){t&&(e.actionButton&&t.onAllow&&(e.actionButton.onclick=t.onAllow),e.retryButton&&t.onRetry&&(e.retryButton.onclick=t.onRetry))}function Hw(e,t,n){let{container:r}=t;if(!r||!Lw(r,e))return;let i=!e.isSpinnerOnly;Iw(t.spinner,e.isSpinnerOnly,Cw),Iw(t.title,i&&!e.isBlocked,Sw),Iw(t.subtitle,i&&!e.isBlocked,Sw),t.title&&(t.title.textContent=e.titleText),t.subtitle&&(t.subtitle.textContent=e.subtitleText),Rw(t,e,i&&!e.isBlocked),Bw(t,e),Vw(t,n)}function Uw(e,t){e.textContent=``;let n=document.createTextNode(t.prefix);if(e.append(n),t.linkText&&t.linkHref){let n=document.createElement(`a`),r=t.linkTarget;n.href=t.linkHref,r&&(n.target=r),r===`_blank`&&(n.rel=`noopener noreferrer`),n.textContent=t.linkText,e.append(n)}let r=document.createTextNode(t.suffix);e.append(r)}function Ww(e){let{stream:t,transitionMessage:n,isVideoLoaded:r}=e;return{showPreviewSkeleton:!!t&&!r&&!n,showVideoPreview:!!t}}function Gw(e,t){let{previewSkeleton:n,videoPreview:r}=t;n&&(e.showPreviewSkeleton?n.style.display=`block`:n.style.display=`none`),r&&(e.showVideoPreview?r.style.display=`block`:r.style.display=`none`)}function Kw(e,t,n){let{videoPreview:r}=t,{onVideoLoaded:a,onError:o,startAudioAnalysis:s,stopAudioAnalysis:c}=n;if(r){if(!e){r.srcObject=null,c();return}r.srcObject=e,r.onloadeddata=()=>{a()},r.play().catch(e=>o(i(e))),s(e)}}function qw(e){return{startCameraArea:e.querySelector(`#startCameraArea`),startCameraButton:e.querySelector(`#startCameraButton`),cameraIcon:e.querySelector(`#startCameraArea .vidtreo-camera-icon`),cameraText:e.querySelector(`#startCameraArea .vidtreo-camera-text`),cameraHint:e.querySelector(`#startCameraArea .vidtreo-camera-hint`),previewSkeleton:e.querySelector(`#previewSkeleton`),previewSkeletonText:e.querySelector(`#previewSkeleton .vidtreo-skeleton-text`),videoPreview:e.querySelector(`#videoPreview`),countdownOverlay:e.querySelector(`#countdownOverlay`),countdownNumber:e.querySelector(`#countdownNumber`),recordingTimerRow:e.querySelector(`#recordingTimerRow`),recordingTimer:e.querySelector(`#recordingTimer`),recIndicatorTop:e.querySelector(`#recIndicatorTop`),audioLevelBars:e.querySelector(`#audioLevelBars`)}}function Jw(e,t,n,r,i,a){if(e.stream)return{shouldShow:!1,iconClassName:``,browserErrorContent:null,textContent:null,hintText:null,retryButtonLabel:null};let o=oS({errorCode:e.errorCode,hasAudioFailed:!1,error:null}),s=o.isCameraError||o.isAudioError,c=!(o.isBrowserUnsupported||s),l=o.isBrowserUnsupported||s?`ph-fill ph-warning-circle`:`ph-fill ph-camera`,u=null,d=null;o.isBrowserUnsupported&&(u=rw(n)),o.isAudioError&&(d=i),o.isCameraError&&(d=r),c&&(d=t.initializingCamera);let f=c?t.grantPermissions:null,p=s&&!o.isPermissionDenied?a:null;return{shouldShow:!0,iconClassName:l,browserErrorContent:u,textContent:d,hintText:f,retryButtonLabel:p}}function Yw(e,t){let n=!1;return e&&(n=!0),{shouldShow:n,text:t.switchingDevice}}function Xw(e,t,n){let r=!1;return e===`countdown`&&t!==null&&(r=!0),{shouldShow:r,countdown:t,text:n.recordingStartsIn}}function Zw(e,t){return{shouldShow:e,text:t.rec}}function Qw(e,t){return{shouldShow:e,timer:t}}function $w(e){return{shouldShow:e}}function eT(e,t){let{state:n,isVideoLoaded:r,isRecording:i,translations:a}=e;tT(Jw(n,a,$C(n.errorCode,n.browserName,n.browserVersion,{browserUnsupported:a.browserUnsupported,browserUnsupportedDynamic:a.browserUnsupportedDynamic,browserUnsupportedSafari:a.browserUnsupportedSafari,browserUnsupportedFirefox:a.browserUnsupportedFirefox}),ew(n.errorCode??``,{cameraInUse:a.cameraInUse,cameraNotFound:a.cameraNotFound,cameraPermissionDenied:a.cameraPermissionDenied,cameraTimeout:a.cameraTimeout,failedToStartCamera:a.failedToStartCamera}),tw(n.errorCode??``,{audioInUse:a.audioInUse,audioNotFound:a.audioNotFound,audioPermissionDenied:a.audioPermissionDenied,audioTimeout:a.audioTimeout,failedToStartAudio:a.failedToStartAudio}),a.retryCamera),t,e.onRetryCamera),nT(Yw(n.transitionMessage,a),t),Gw(Ww({stream:n.stream,transitionMessage:n.transitionMessage,isVideoLoaded:r}),{previewSkeleton:t.previewSkeleton,videoPreview:t.videoPreview}),rT(Xw(n.recordingState,n.countdown,a),t),iT(Zw(i,a),t),aT(Qw(i,n.timer),t),oT($w(i),t)}function tT(e,t,n){let{startCameraArea:r,startCameraButton:i,cameraIcon:a,cameraText:o,cameraHint:s}=t;if(r){if(!e.shouldShow){r.style.display=`none`;return}r.style.display=`block`,a&&(a.innerHTML=`<i class="${e.iconClassName}" style="font-size: 48px;"></i>`),o&&(e.browserErrorContent&&Uw(o,e.browserErrorContent),e.textContent&&(o.textContent=e.textContent)),s&&(e.hintText?(s.textContent=e.hintText,s.style.display=`block`):s.style.display=`none`),i&&(e.retryButtonLabel?(i.textContent=e.retryButtonLabel,i.hidden=!1,i.className=`vidtreo-error-retry`,i.onclick=e=>{e.preventDefault(),e.stopPropagation(),n&&n()}):(i.hidden=!0,i.onclick=null))}}function nT(e,t){let{previewSkeleton:n,previewSkeletonText:r}=t;n&&(e.shouldShow?n.style.display=`block`:n.style.display=`none`,r&&(r.textContent=e.text))}function rT(e,t){let{countdownOverlay:n,countdownNumber:r}=t;n&&(e.shouldShow?n.classList.add(`vidtreo-active`):n.classList.remove(`vidtreo-active`),r&&e.countdown!==null&&(r.textContent=e.countdown.toString()))}function iT(e,t){let{recIndicatorTop:n}=t;n&&(e.shouldShow?n.style.display=`block`:n.style.display=`none`)}function aT(e,t){let{recordingTimerRow:n,recordingTimer:r}=t;n&&(e.shouldShow?n.style.display=`flex`:n.style.display=`none`,r&&(r.textContent=e.timer))}function oT(e,t){let{audioLevelBars:n}=t;n&&(e.shouldShow?n.style.display=`flex`:n.style.display=`none`)}let sT=`inline-flex`;function cT(e){let{stream:t,buttonVisibility:n,currentSourceType:r,isMuted:i,isAudioReady:a,isStopLocked:o,stopLockedTooltip:s,recordingState:c,buttonTranslations:l}=e,u=!!t,d=c===`idle`&&u,f=d&&!a,p=f?l.microphoneConnecting:``,m=!1;(n.showPauseButton||n.showResumeButton)&&(m=!0);let h=l.pause,g=`ph-fill ph-pause`;n.showResumeButton&&(h=l.resume,g=`ph-fill ph-play`);let _=l.mute,v=`ph-fill ph-microphone`;i&&(_=l.unmute,v=`ph-fill ph-microphone-slash`);let y=`ph-fill ph-monitor`;r!==mw&&(y=`ph-fill ph-camera`);let b=!1;return n.showDownloadButton&&(b=!0),{showRecordingControls:u,showSettingsButton:n.showSettingsButton,showRecordButton:d,isRecordDisabled:f,recordTooltip:p,showMuteButton:n.showMuteButton,showPauseButton:m,showStopButton:n.showStopButton,showSwitchSourceButton:n.showSwitchSourceButton,showDownloadButton:b,pauseTitle:h,pauseIconClassName:g,muteTitle:_,muteIconClassName:v,switchSourceIconClassName:y,isMuted:i,isStopLocked:o,stopLockedTooltip:s,settingsTitle:l.settings,switchSourceTitle:l.switchSource,downloadTitle:l.download,buttonTranslations:l}}function lT(e){return{recordingControls:e.querySelector(`#recordingControls`),settingsButton:e.querySelector(`#btnSettings`),recordButton:e.querySelector(`#btnRecord`),muteButton:e.querySelector(`#btnMute`),muteIcon:e.querySelector(`#iconMute`),pauseButton:e.querySelector(`#btnPause`),pauseIcon:e.querySelector(`#iconPause`),stopButton:e.querySelector(`#btnStop`),switchSourceButton:e.querySelector(`#btnSwitchSource`),switchSourceIcon:e.querySelector(`#iconSwitchSource`),downloadButton:e.querySelector(`#btnDownload`)}}function uT(e,t){let{recordingControls:n,settingsButton:r,recordButton:i,muteButton:a,muteIcon:o,pauseButton:s,pauseIcon:c,stopButton:l,switchSourceButton:u,switchSourceIcon:d,downloadButton:f}=t;fT(n,e),pT(r,e),mT(i,e),hT(a,e),gT(o,e),_T(s,e),vT(c,e),yT(l,e),bT(u,e),xT(d,e),ST(f,e)}function dT(e,t,n){e&&(t?e.style.display=n:e.style.display=`none`)}function fT(e,t){dT(e,t.showRecordingControls,`block`)}function pT(e,t){dT(e,t.showSettingsButton,sT),e&&(e.title=t.settingsTitle)}function mT(e,t){if(dT(e,t.showRecordButton,sT),!e)return;e.disabled=t.isRecordDisabled,e.classList.toggle(`vidtreo-record-button-disabled`,t.isRecordDisabled),e.title=t.recordTooltip,e.setAttribute(`aria-disabled`,String(t.isRecordDisabled));let n=e.querySelector(`i`),r=e.querySelector(`span`);t.isRecordDisabled?(n&&(n.className=`ph-fill ph-microphone vidtreo-mic-connecting-indicator`,n.style.fontSize=`18px`),r&&(r.textContent=t.recordTooltip)):(n&&(n.className=`ph-fill ph-circle`,n.style.fontSize=`24px`),r&&(r.textContent=t.buttonTranslations?.record??`Record`))}function hT(e,t){dT(e,t.showMuteButton,sT),e&&(e.title=t.muteTitle,e.classList.toggle(`vidtreo-muted`,t.isMuted))}function gT(e,t){e&&(e.className=t.muteIconClassName)}function _T(e,t){dT(e,t.showPauseButton,sT),e&&(e.title=t.pauseTitle)}function vT(e,t){e&&(e.className=t.pauseIconClassName)}function yT(e,t){if(dT(e,t.showStopButton,sT),e){if(e.classList.toggle(`vidtreo-stop-button-locked`,t.isStopLocked),e.setAttribute(`aria-disabled`,String(t.isStopLocked)),t.isStopLocked){e.title=t.stopLockedTooltip;return}e.title=``}}function bT(e,t){dT(e,t.showSwitchSourceButton,sT),e&&(e.title=t.switchSourceTitle)}function xT(e,t){e&&(e.className=t.switchSourceIconClassName)}function ST(e,t){dT(e,t.showDownloadButton,sT),e&&(e.title=t.downloadTitle)}function CT(e){let{stream:t,showSettings:n}=e,r=!1;return t&&n&&(r=!0),{shouldShow:r}}function wT(e,t,n){if(t){if(!e.shouldShow){t.classList.remove(`vidtreo-active`);return}t.classList.add(`vidtreo-active`),n()}}function TT(e){return e.toggleMute(),e.getIsMuted()}function ET(e){if(!e)return;let t=URL.createObjectURL(e),n=document.createElement(`a`);n.href=t,n.download=`recording-${Date.now()}.mp4`,document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(t)}let DT={en:{initializingCamera:`Initializing camera...`,grantPermissions:`Grant camera and microphone permissions when prompted`,browserUnsupported:`This browser is not supported`,browserUnsupportedDynamic:`{browser} ({version}) is not supported, please use <a href="https://www.google.com/chrome/" target="_blank">Chrome</a>`,browserUnsupportedSafari:`Safari is not supported, please use <a href="https://www.google.com/chrome/" target="_blank">Chrome</a>`,browserUnsupportedFirefox:`Firefox is not supported, please use <a href="https://www.google.com/chrome/" target="_blank">Chrome</a>`,retryCamera:`Retry Camera`,cameraInUse:`Your camera is being used by another application. Close other apps using the camera (Zoom, Teams, Discord) and try again.`,cameraNotFound:`No camera detected. Connect a camera or check your device settings.`,cameraPermissionDenied:`Camera access was denied. Allow camera access in your browser settings and try again.`,cameraTimeout:`The camera took too long to start. Close other apps using the camera and try again.`,audioInUse:`Your microphone is being used by another application. Close other apps using the microphone (Zoom, Teams, Discord) and try again.`,audioNotFound:`No microphone detected. Connect a microphone or check your device settings.`,audioPermissionDenied:`Microphone access was denied. Allow microphone access in your browser settings and try again.`,audioTimeout:`The microphone took too long to start. Close other apps using the microphone and try again.`,failedToStartAudio:`Failed to start microphone`,audioErrorTitle:`Microphone unavailable`,audioErrorMessage:`We couldn't access your microphone. It may be in use by another app like Zoom, Teams, or Discord. Please close it and try again.`,audioErrorRetry:`Try again`,audioMissingTitle:`Recording has no audio`,audioMissingMessage:`We couldn't capture audio in this recording. Your microphone may have been disconnected or blocked by the browser. Check your microphone and record again.`,audioSilentTitle:`Recording is silent`,audioSilentMessage:`We didn't detect any sound during the recording. Make sure your microphone is working and not muted by your operating system, then record again.`,audioProcessingErrorTitle:`Audio processing error`,audioProcessingErrorMessage:`We couldn't process the audio in this recording. Please record again.`,audioMissingRetry:`Record again`,audioWarningNoSignalTitle:`No microphone signal`,audioWarningNoSignalMessage:`We're not detecting any sound. Check that your microphone is active.`,audioWarningLowSignalTitle:`Audio is very quiet`,audioWarningLowSignalMessage:`Move closer to the microphone or turn up the input volume.`,audioWarningSpeakingMutedTitle:`You're speaking while muted`,audioWarningSpeakingMutedMessage:`Unmute your microphone if you want your voice in the recording.`,audioWarningTrackEndedTitle:`Microphone disconnected`,audioWarningTrackEndedMessage:`The microphone was disconnected. Reconnect it before continuing.`,audioWarningNoChunksTitle:`No microphone input`,audioWarningNoChunksMessage:`We're not receiving audio from the microphone. Check browser permissions.`,audioWarningTrackMutedTitle:`Microphone muted by browser`,audioWarningTrackMutedMessage:`The browser muted your microphone. Check site settings.`,audioWarningDismiss:`Dismiss`,cameraErrorTitle:`Camera unavailable`,cameraErrorMessage:`We couldn't access your camera. It may be in use by another app or permissions may be denied.`,browserErrorTitle:`Browser not supported`,browserErrorMessage:`This browser is not supported. Please use Chrome for the best experience.`,recordingCodecUnsupportedTitle:`Recording format not supported`,recordingCodecUnsupportedMessage:`This device can't use the selected video format. Close other apps, update Chrome if possible, and record again.`,recordingServerTranscodeFallbackTitle:`Finalizing on device`,recordingServerTranscodeFallbackMessage:`We're finishing the video on this device before upload. Keep this tab open.`,recordingTrackEndedTitle:`Camera stopped during recording`,recordingTrackEndedMessage:`The camera feed ended before the recording finished. Check that the camera is still connected and record again.`,recordingFinalizeTimeoutTitle:`Recording took too long to finish`,recordingFinalizeTimeoutMessage:`This device may be low on memory or processing power. Close other apps or browser tabs, then record again.`,recordingStateRaceTitle:`Recording did not start correctly`,recordingStateRaceMessage:`The recording could not be finalized because it did not start cleanly. Please refresh the page and record again.`,recordingNoFramesTitle:`No video was captured`,recordingNoFramesMessage:`We couldn't receive video frames from the camera. Check your camera connection and record again.`,recordingUnsupportedTitle:`Recording not available`,recordingUnsupportedMessage:`This device or browser can't record video reliably right now. Check your connection, update Chrome if possible, or use another device.`,recordingPipelineRetry:`Record again`,genericErrorTitle:`Something went wrong`,genericErrorMessage:`An unexpected error occurred. Please try again.`,errorRetry:`Try again`,switchingDevice:`Switching device...`,recordingStartsIn:`Recording starts in...`,switchingSource:`Switching source...`,rec:`REC`,settings:`Settings`,record:`Record`,stop:`Stop`,pause:`Pause`,resume:`Resume`,mute:`Mute`,unmute:`Unmute`,switchSource:`Switch Source`,camera:`Camera`,microphone:`Microphone`,microphoneConnecting:`Connecting microphone...`,minimumRecordingTimeNotReached:`You have not met the minimum recording time yet`,processVideo:`Process Video`,processing:`Processing...`,finishing:`Finishing...`,uploading:`Uploading...`,switchingCamera:`Switching camera...`,switchingMicrophone:`Switching microphone...`,failedToStartCamera:`Failed to start camera`,userInAnotherTab:`User in another tab`,download:`Download`,nativeCameraSelectVideo:`Select Video from Gallery`,nativeCameraRecordVideo:`Record with Camera`,errorTitle:`Configuration Error`,errorGeneric:`An error occurred while loading the configuration`,mobileOpenCamera:`Open Camera`,mobileOpenCameraTitle:`Record a Video`,mobileOpenCameraDescription:`Tap the button below to start recording`,mobileCloseCamera:`Close`,mobilePermissionDenied:`Camera Access Denied`,mobilePermissionDeniedDescription:`Please allow camera access in your browser settings to record video.`,permissionFlowTitle:`Set Up Your Camera`,permissionFlowCameraTitle:`Camera & Microphone`,permissionFlowMicrophoneTitle:`Camera & Microphone`,permissionFlowCameraLabel:`We need access to your camera and microphone to start recording`,permissionFlowMicrophoneLabel:`We need access to your camera and microphone to start recording`,permissionFlowStatusPending:`Pending`,permissionFlowStatusGranted:`Ready`,permissionFlowStatusDenied:`Blocked`,permissionFlowStatusRequesting:`Click "Allow" in the browser popup above`,permissionFlowAllowCamera:`Allow Access`,permissionFlowAllowMicrophone:`Allow Access`,permissionFlowRetry:`Try Again`,permissionFlowRecoveryTitle:`Allow access to continue`,permissionFlowRecoveryInstructions:`Open your browser settings and allow camera and microphone access, then try again.`,permissionFlowConnecting:`Setting up...`},es:{initializingCamera:`Inicializando cámara...`,grantPermissions:`Otorga permisos de cámara y micrófono cuando se solicite`,browserUnsupported:`Este navegador no es compatible`,browserUnsupportedDynamic:`{browser} ({version}) no es compatible, por favor usa <a href="https://www.google.com/chrome/" target="_blank">Chrome</a>`,browserUnsupportedSafari:`Safari no es compatible, usa <a href="https://www.google.com/chrome/" target="_blank">Chrome</a>`,browserUnsupportedFirefox:`Firefox no es compatible, usa <a href="https://www.google.com/chrome/" target="_blank">Chrome</a>`,retryCamera:`Reintentar Cámara`,cameraInUse:`Tu cámara está siendo usada por otra aplicación. Cierra otras apps que usen la cámara (Zoom, Teams, Discord) e intenta de nuevo.`,cameraNotFound:`No se detectó ninguna cámara. Conecta una cámara o revisa la configuración de tu dispositivo.`,cameraPermissionDenied:`Se denegó el acceso a la cámara. Permite el acceso a la cámara en la configuración de tu navegador e intenta de nuevo.`,cameraTimeout:`La cámara tardó demasiado en iniciar. Cierra otras apps que usen la cámara e intenta de nuevo.`,audioInUse:`Tu micrófono está siendo usado por otra aplicación. Cierra otras apps que usen el micrófono (Zoom, Teams, Discord) e intenta de nuevo.`,audioNotFound:`No se detectó ningún micrófono. Conecta un micrófono o revisa la configuración de tu dispositivo.`,audioPermissionDenied:`Se denegó el acceso al micrófono. Permite el acceso al micrófono en la configuración de tu navegador e intenta de nuevo.`,audioTimeout:`El micrófono tardó demasiado en iniciar. Cierra otras apps que usen el micrófono e intenta de nuevo.`,failedToStartAudio:`Error al iniciar el micrófono`,audioErrorTitle:`Micrófono no disponible`,audioErrorMessage:`No pudimos acceder a tu micrófono. Puede estar en uso por otra app como Zoom, Teams o Discord. Ciérrala e inténtalo de nuevo.`,audioErrorRetry:`Intentar de nuevo`,audioMissingTitle:`La grabación no tiene audio`,audioMissingMessage:`No pudimos capturar audio en esta grabación. Es posible que el micrófono se haya desconectado o que el navegador lo haya bloqueado. Verifica tu micrófono y vuelve a grabar.`,audioSilentTitle:`La grabación quedó en silencio`,audioSilentMessage:`No detectamos sonido durante la grabación. Verifica que tu micrófono esté funcionando y no esté silenciado por el sistema, luego vuelve a grabar.`,audioProcessingErrorTitle:`Error al procesar el audio`,audioProcessingErrorMessage:`No pudimos procesar el audio de esta grabación. Por favor vuelve a grabar.`,audioMissingRetry:`Grabar de nuevo`,audioWarningNoSignalTitle:`Sin señal del micrófono`,audioWarningNoSignalMessage:`No estamos detectando sonido. Verifica que tu micrófono esté activo.`,audioWarningLowSignalTitle:`Audio muy bajo`,audioWarningLowSignalMessage:`Acércate al micrófono o sube el volumen de entrada.`,audioWarningSpeakingMutedTitle:`Estás hablando muteado`,audioWarningSpeakingMutedMessage:`Activa el micrófono si quieres que tu voz se escuche en la grabación.`,audioWarningTrackEndedTitle:`Micrófono desconectado`,audioWarningTrackEndedMessage:`Se desconectó el micrófono. Reconéctalo antes de continuar.`,audioWarningNoChunksTitle:`Sin entrada del micrófono`,audioWarningNoChunksMessage:`No estamos recibiendo audio del micrófono. Revisa los permisos del navegador.`,audioWarningTrackMutedTitle:`Micrófono silenciado por el navegador`,audioWarningTrackMutedMessage:`El navegador silenció tu micrófono. Revisa la configuración del sitio.`,audioWarningDismiss:`Cerrar`,cameraErrorTitle:`Cámara no disponible`,cameraErrorMessage:`No pudimos acceder a tu cámara. Puede estar en uso por otra app o los permisos pueden estar denegados.`,browserErrorTitle:`Navegador no compatible`,browserErrorMessage:`Este navegador no es compatible. Por favor usa Chrome para la mejor experiencia.`,recordingCodecUnsupportedTitle:`Formato de grabación no compatible`,recordingCodecUnsupportedMessage:`Este dispositivo no puede usar el formato de video seleccionado. Cierra otras apps, actualiza Chrome si es posible y vuelve a grabar.`,recordingServerTranscodeFallbackTitle:`Finalizando en el dispositivo`,recordingServerTranscodeFallbackMessage:`Estamos finalizando el video en este dispositivo antes de subirlo. Mantén esta pestaña abierta.`,recordingTrackEndedTitle:`La cámara se detuvo durante la grabación`,recordingTrackEndedMessage:`La señal de la cámara terminó antes de finalizar la grabación. Verifica que la cámara siga conectada y vuelve a grabar.`,recordingFinalizeTimeoutTitle:`La grabación tardó demasiado en finalizar`,recordingFinalizeTimeoutMessage:`Es posible que este dispositivo tenga poca memoria o potencia de procesamiento. Cierra otras apps o pestañas del navegador y vuelve a grabar.`,recordingStateRaceTitle:`La grabación no inició correctamente`,recordingStateRaceMessage:`No se pudo finalizar la grabación porque no inició correctamente. Actualiza la página y vuelve a grabar.`,recordingNoFramesTitle:`No se capturó video`,recordingNoFramesMessage:`No pudimos recibir fotogramas de video de la cámara. Verifica la conexión de la cámara y vuelve a grabar.`,recordingUnsupportedTitle:`Grabación no disponible`,recordingUnsupportedMessage:`Este dispositivo o navegador no puede grabar video de forma estable ahora. Revisa tu conexión, actualiza Chrome si es posible o usa otro dispositivo.`,recordingPipelineRetry:`Grabar de nuevo`,genericErrorTitle:`Algo salió mal`,genericErrorMessage:`Ocurrió un error inesperado. Por favor intenta de nuevo.`,errorRetry:`Intentar de nuevo`,switchingDevice:`Cambiando dispositivo...`,recordingStartsIn:`La grabación comienza en...`,switchingSource:`Cambiando fuente...`,rec:`GRAB`,settings:`Configuración`,record:`Grabar`,stop:`Detener`,pause:`Pausar`,resume:`Reanudar`,mute:`Silenciar`,unmute:`Activar sonido`,switchSource:`Cambiar Fuente`,camera:`Cámara`,microphone:`Micrófono`,microphoneConnecting:`Conectando micrófono...`,minimumRecordingTimeNotReached:`Aun no cumples el tiempo minimo de grabacion`,processVideo:`Procesar Video`,processing:`Procesando...`,finishing:`Finalizando...`,uploading:`Subiendo...`,switchingCamera:`Cambiando cámara...`,switchingMicrophone:`Cambiando micrófono...`,failedToStartCamera:`Error al iniciar la cámara`,userInAnotherTab:`Usuario en otra pestaña`,download:`Descargar`,nativeCameraSelectVideo:`Seleccionar Video de la Galería`,nativeCameraRecordVideo:`Grabar con Cámara`,errorTitle:`Error de Configuración`,errorGeneric:`Ocurrió un error al cargar la configuración`,mobileOpenCamera:`Abrir Cámara`,mobileOpenCameraTitle:`Grabar un Video`,mobileOpenCameraDescription:`Toca el botón para comenzar a grabar`,mobileCloseCamera:`Cerrar`,mobilePermissionDenied:`Acceso a Cámara Denegado`,mobilePermissionDeniedDescription:`Por favor permite el acceso a la cámara en la configuración de tu navegador para grabar video.`,permissionFlowTitle:`Configurar tu Cámara`,permissionFlowCameraTitle:`Cámara y Micrófono`,permissionFlowMicrophoneTitle:`Cámara y Micrófono`,permissionFlowCameraLabel:`Necesitamos acceso a tu cámara y micrófono para comenzar a grabar`,permissionFlowMicrophoneLabel:`Necesitamos acceso a tu cámara y micrófono para comenzar a grabar`,permissionFlowStatusPending:`Pendiente`,permissionFlowStatusGranted:`Listo`,permissionFlowStatusDenied:`Bloqueado`,permissionFlowStatusRequesting:`Haz clic en "Permitir" en el aviso del navegador`,permissionFlowAllowCamera:`Permitir Acceso`,permissionFlowAllowMicrophone:`Permitir Acceso`,permissionFlowRetry:`Reintentar`,permissionFlowRecoveryTitle:`Permite el acceso para continuar`,permissionFlowRecoveryInstructions:`Abre la configuración de tu navegador y permite el acceso a la cámara y micrófono, luego intenta de nuevo.`,permissionFlowConnecting:`Preparando...`}};var OT=class{constructor(e=`en`,t={}){this.lang=e,this.customTexts=t}setLang(e){this.lang=e}setCustomTexts(e){this.customTexts=e}t(e){return this.customTexts[e]?this.customTexts[e]:(DT[this.lang]||DT.en)[e]}getAll(){return{...DT[this.lang]||DT.en,...this.customTexts}}};let kT=new Map;function AT(e){e.style.position=`fixed`,e.style.top=`0`,e.style.left=`0`,e.style.width=`100vw`,e.style.height=`100vh`,e.style.height=`100dvh`,e.style.zIndex=`9999`,e.style.pointerEvents=`none`}function jT(e){e.style.pointerEvents=`auto`}function MT(e){e.style.pointerEvents=`none`}var NT=class{constructor(e=`vidtreo-portal-root`){this.portalContainer=null,this.contentWrapper=null,this.isRegistered=!1,this.containerId=e,this.instanceId=`portal-${Date.now()}-${Math.random().toString(36).slice(2,9)}`}get container(){return this.contentWrapper}get isActive(){return this.contentWrapper!==null&&this.portalContainer!==null}open(){let e=document.getElementById(this.containerId);return e||(e=document.createElement(`div`),e.id=this.containerId,AT(e),document.body.appendChild(e)),this.portalContainer=e,this.contentWrapper=document.createElement(`div`),this.contentWrapper.setAttribute(`data-portal-instance`,this.instanceId),this.contentWrapper.style.width=`100%`,this.contentWrapper.style.height=`100%`,this.portalContainer.appendChild(this.contentWrapper),this.registerInstance(),jT(e),this.contentWrapper}render(e){this.contentWrapper&&(this.contentWrapper.innerHTML=e)}querySelector(e){return this.contentWrapper?this.contentWrapper.querySelector(e):null}close(){this.contentWrapper&&=(this.contentWrapper.innerHTML=``,this.contentWrapper.remove(),null),this.unregisterInstance(),this.updatePortalContainerState()}destroy(){this.close(),this.portalContainer=null}registerInstance(){if(this.isRegistered)return;let e=kT.get(this.containerId);e||(e=new Set,kT.set(this.containerId,e)),e.add(this),this.isRegistered=!0}unregisterInstance(){if(!this.isRegistered)return;let e=kT.get(this.containerId);e&&(e.delete(this),e.size===0&&kT.delete(this.containerId)),this.isRegistered=!1}updatePortalContainerState(){if(!this.portalContainer)return;let e=kT.get(this.containerId);e&&e.size>0?jT(this.portalContainer):(MT(this.portalContainer),this.portalContainer.childNodes.length===0&&this.portalContainer.remove())}},PT=class{constructor(e){this.state={isModalOpen:!1,permissionRequested:!1,prevUploading:!1},this.escapeHandler=null,this.initCheckInterval=null,this.callbacks=e,this.portalManager=new NT}get canCloseModal(){let{recordingState:e}=this.callbacks.getState();return!(e===`recording`||e===`countdown`)}get isModalOpen(){return this.state.isModalOpen}get portal(){return this.portalManager}openModal(){this.state.isModalOpen=!0,this.state.permissionRequested=!1,this.portalManager.open(),document.body.style.overflow=`hidden`,this.setupEscapeHandler(),this.callbacks.renderMobile(),this.requestCameraPreview()}closeModal(){this.canCloseModal&&(this.callbacks.stopPreview(),this.state.isModalOpen=!1,this.state.permissionRequested=!1,document.body.style.overflow=``,this.removeEscapeHandler(),this.portalManager.close(),this.callbacks.renderMobile())}checkUploadCompletion(e){let t=this.state.prevUploading,n=e!==null;this.state.prevUploading=n,t&&!n&&this.state.isModalOpen&&this.closeModal()}requestCameraPreview(){if(this.state.permissionRequested)return;let e=()=>{this.callbacks.isInitialized()?(this.state.permissionRequested=!0,this.callbacks.startPreview().catch(()=>{})):this.initCheckInterval=setTimeout(e,100)};e()}setupEscapeHandler(){this.escapeHandler=e=>{e.key===`Escape`&&this.canCloseModal&&this.closeModal()},document.addEventListener(`keydown`,this.escapeHandler)}removeEscapeHandler(){this.escapeHandler&&=(document.removeEventListener(`keydown`,this.escapeHandler),null)}destroy(){this.removeEscapeHandler(),this.portalManager.destroy(),document.body.style.overflow=``,this.initCheckInterval&&=(clearTimeout(this.initCheckInterval),null)}},FT=class{constructor(e,t){this.state={file:null,transcodingProgress:null,uploadProgress:null,isTranscoding:!1,isConfigLoading:!0,error:null,transcodedBlob:null},this.handler=null,this.config=e,this.callbacks=t;let n=e.backendUrl||`https://core.vidtreo.com`,r=null;e.apiKey&&!e.demo&&(r=un.getInstance({apiKey:e.apiKey,backendUrl:n}));let i=new bS;this.handler=new fy({apiKey:e.apiKey,backendUrl:n,maxRecordingTime:e.maxRecordingTime,maxFileSize:e.maxFileSize,userMetadata:e.userMetadata},r,i),e.apiKey&&!e.demo?(this.updateState({isConfigLoading:!0}),this.handler.preloadConfig().then(()=>this.updateState({isConfigLoading:!1})).catch(()=>{this.updateState({isConfigLoading:!1,error:`Failed to load settings`})})):this.updateState({isConfigLoading:!1})}updateState(e){this.state={...this.state,...e},this.callbacks.onStateChange()}getState(){return this.state}async handleFileSelect(e){if(this.updateState({error:null}),!this.handler)throw Error(`Handler not initialized`);try{let t=await this.handler.handleFileSelection(e);return this.updateState({file:t}),t}catch(e){let t=i(e),n=e instanceof Error?e:Error(t);throw this.updateState({error:t}),this.callbacks.onError?.(n),n}}async processAndUpload(e){let t=e||this.state.file;if(!(t&&this.handler))return;let n=this.config.demo;try{if(this.updateState({isTranscoding:!0,transcodingProgress:0,error:null}),n){let e=await uy(t.file,Xt,e=>{this.updateState({transcodingProgress:e}),this.callbacks.onTranscodingProgress?.(e)});this.updateState({transcodedBlob:e.blob,isTranscoding:!1,transcodingProgress:null})}else{let e=await this.handler.processAndUpload(e=>{this.updateState({transcodingProgress:e}),this.callbacks.onTranscodingProgress?.(e)},e=>{this.updateState({uploadProgress:e}),this.callbacks.onUploadProgress?.(e)});this.updateState({file:null,transcodingProgress:null,uploadProgress:null,isTranscoding:!1}),this.callbacks.onUploadComplete?.({recordingId:e.recordingId||``,uploadUrl:e.uploadUrl||``})}}catch(e){let t=i(e),r=e instanceof Error?e:Error(t);this.updateState({error:t,isTranscoding:!1,transcodingProgress:null,uploadProgress:null,transcodedBlob:null}),this.callbacks.onError?.(r),n||this.callbacks.onUploadError?.(r)}}downloadVideo(){if(!this.state.transcodedBlob)return;let e=URL.createObjectURL(this.state.transcodedBlob),t=document.createElement(`a`);t.href=e,t.download=`recording-${Date.now()}.mp4`,document.body.appendChild(t),t.click(),document.body.removeChild(t),URL.revokeObjectURL(e)}reset(){this.updateState({file:null,transcodingProgress:null,uploadProgress:null,error:null,isTranscoding:!1,transcodedBlob:null})}destroy(){this.handler&&this.handler.cancel(),this.handler=null}};function IT(e){return{preview:{initializingCamera:e.initializingCamera,grantPermissions:e.grantPermissions,browserUnsupported:e.browserUnsupported,browserUnsupportedDynamic:e.browserUnsupportedDynamic,browserUnsupportedSafari:e.browserUnsupportedSafari,browserUnsupportedFirefox:e.browserUnsupportedFirefox,retryCamera:e.retryCamera,cameraInUse:e.cameraInUse,cameraNotFound:e.cameraNotFound,cameraPermissionDenied:e.cameraPermissionDenied,cameraTimeout:e.cameraTimeout,failedToStartCamera:e.failedToStartCamera,audioInUse:e.audioInUse,audioNotFound:e.audioNotFound,audioPermissionDenied:e.audioPermissionDenied,audioTimeout:e.audioTimeout,failedToStartAudio:e.failedToStartAudio,switchingDevice:e.switchingDevice,recordingStartsIn:e.recordingStartsIn,rec:e.rec},buttons:{settings:e.settings,record:e.record,stop:e.stop,minimumRecordingTimeNotReached:e.minimumRecordingTimeNotReached,pause:e.pause,resume:e.resume,mute:e.mute,unmute:e.unmute,switchSource:e.switchSource,download:e.download,microphoneConnecting:e.microphoneConnecting},settings:{settings:e.settings,camera:e.camera,microphone:e.microphone}}}var LT=class{constructor(e){if(this.proxyEndpoint=e.proxyEndpoint,this.proxyEndpoint)throw Error(`Proxy mode not yet implemented`);this.service=new bS}uploadVideo(e,t){if(this.proxyEndpoint)throw Error(`Proxy mode not yet implemented`);return this.service.uploadVideo(e,t)}},RT=`:root{--vidtreo-background:0 0% 100%;--vidtreo-foreground:0 0% 3.9%;--vidtreo-card:0 0% 100%;--vidtreo-card-foreground:0 0% 3.9%;--vidtreo-primary:0 0% 9%;--vidtreo-primary-foreground:0 0% 98%;--vidtreo-secondary:0 0% 96.1%;--vidtreo-secondary-foreground:0 0% 9%;--vidtreo-muted:0 0% 96.1%;--vidtreo-muted-foreground:0 0% 45.1%;--vidtreo-accent:0 0% 96.1%;--vidtreo-accent-foreground:0 0% 9%;--vidtreo-destructive:0 84.2% 60.2%;--vidtreo-destructive-foreground:0 0% 98%;--vidtreo-border:0 0% 89.8%;--vidtreo-input:0 0% 89.8%;--vidtreo-ring:0 0% 3.9%;--vidtreo-radius:.5rem;--vidtreo-preview-bg:0 0% 0%;--vidtreo-z-modal-overlay:9999;--vidtreo-z-settings-panel:200;--vidtreo-z-error-overlay:100;--vidtreo-z-countdown-overlay:20;--vidtreo-z-progress-overlay:20;--vidtreo-z-controls:10}.vidtreo-preview-container{aspect-ratio:9/16;background:hsl(var(--vidtreo-preview-bg));contain:layout style;will-change:auto;backface-visibility:hidden;isolation:isolate;border:none;border-radius:0;justify-content:center;align-items:center;width:100%;display:flex;position:relative;overflow:visible;transform:translateZ(0)}.vidtreo-preview-container:before{display:none}@media (width>=768px){.vidtreo-preview-container{aspect-ratio:16/9}}.vidtreo-camera-area{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;contain:layout style paint;backface-visibility:hidden;isolation:isolate;will-change:auto;width:100%;height:100%;font-family:-apple-system,BlinkMacSystemFont,SF Pro Display,SF Pro Text,system-ui,sans-serif;display:none;position:relative;transform:translateZ(0)}.vidtreo-source-transition-overlay{z-index:var(--vidtreo-z-error-overlay);backdrop-filter:blur(4px);contain:layout style paint;backface-visibility:hidden;will-change:opacity;background:#000000b3;border-radius:0;flex-direction:column;justify-content:center;align-items:center;transition:opacity .3s;display:none;position:absolute;inset:0;transform:translateZ(0)}.vidtreo-source-transition-overlay.vidtreo-active{animation:.2s vidtreo-fadeIn;display:flex}@keyframes vidtreo-fadeIn{0%{opacity:0}to{opacity:1}}.vidtreo-transition-spinner{border:4px solid #ffffff4d;border-top-color:#667eea;border-radius:50%;width:40px;height:40px;margin-bottom:12px;animation:.8s linear infinite vidtreo-spin}@keyframes vidtreo-spin{to{transform:rotate(360deg)}}.vidtreo-transition-message{color:#fff;text-align:center;font-size:14px;font-weight:500}.vidtreo-camera-area.vidtreo-active{display:block}.vidtreo-preview-skeleton{z-index:var(--vidtreo-z-controls);contain:layout style paint;backface-visibility:hidden;will-change:auto;background:#000;border-radius:0;flex-direction:column;justify-content:center;align-items:center;gap:1rem;display:flex;position:absolute;inset:0;transform:translateZ(0)}.vidtreo-skeleton-spinner{border:4px solid #ffffff4d;border-top-color:#fff;border-radius:50%;width:40px;height:40px;animation:.8s linear infinite vidtreo-spin}.vidtreo-skeleton-text{color:#fff;font-size:.875rem;font-weight:500}.vidtreo-video-preview{object-fit:cover;will-change:auto;backface-visibility:hidden;background:#000;border-radius:0;width:100%;height:100%;transition:opacity .3s,transform .3s;display:block;position:absolute;inset:0;transform:translateZ(0)}.vidtreo-video-preview-skeleton{z-index:2;contain:layout style paint;backface-visibility:hidden;will-change:auto;background:#000;border-radius:0;width:100%;height:100%;position:absolute;inset:0;overflow:hidden;transform:translateZ(0)}.vidtreo-skeleton-shimmer{background:linear-gradient(90deg, hsl(var(--vidtreo-muted)) 0%, hsl(var(--vidtreo-muted) / .5) 50%, hsl(var(--vidtreo-muted)) 100%);background-size:200% 100%;animation:1.5s ease-in-out infinite vidtreo-shimmer;position:absolute;inset:0}@keyframes vidtreo-shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}.vidtreo-video-preview-skeleton.vidtreo-hidden{opacity:0;pointer-events:none;transition:opacity .3s}.vidtreo-video-preview.vidtreo-screen-share{object-fit:cover}.vidtreo-video-preview.vidtreo-transitioning{opacity:.5;transform:scale(.98)}.vidtreo-countdown-overlay{z-index:var(--vidtreo-z-countdown-overlay);contain:layout style paint;backface-visibility:hidden;will-change:auto;background:#000000f2;border-radius:0;justify-content:center;align-items:center;display:none;position:absolute;inset:0;transform:translateZ(0)}.vidtreo-countdown-overlay.vidtreo-active{display:flex}.vidtreo-countdown-content{flex-direction:column;align-items:center;gap:1rem;display:flex}.vidtreo-countdown-number{color:#fff;font-size:9rem;font-weight:700;animation:.3s vidtreo-zoomIn}@keyframes vidtreo-zoomIn{0%{opacity:0;transform:scale(.5)}to{opacity:1;transform:scale(1)}}.vidtreo-countdown-text{color:#fff;margin-top:1rem;font-size:.875rem;font-weight:500}.vidtreo-settings-panel{z-index:var(--vidtreo-z-settings-panel);contain:layout style paint;backface-visibility:hidden;background:#0006;border:none;border-radius:.75rem;flex-direction:column;width:90%;margin-left:-47%;padding:.625rem;display:none;overflow:hidden;transform:translateZ(0);position:absolute!important;bottom:4rem!important;left:50%!important}.vidtreo-settings-panel.vidtreo-active{display:flex}.vidtreo-settings-content{will-change:transform;backface-visibility:hidden;flex-direction:column;width:100%;display:flex;transform:translateZ(0)}.vidtreo-settings-content.vidtreo-slide-right{animation:.3s vidtreo-slideRight}.vidtreo-settings-content.vidtreo-slide-left{animation:.3s vidtreo-slideLeft}.vidtreo-settings-content.vidtreo-slide-none{will-change:auto;animation:none}@keyframes vidtreo-slideIn{0%{opacity:0;transform:translateY(1rem)}to{opacity:1;transform:translateY(0)}}@keyframes vidtreo-slideRight{0%{opacity:0;transform:translate(-100%)}to{opacity:1;transform:translate(0)}}@keyframes vidtreo-slideLeft{0%{opacity:0;transform:translate(100%)}to{opacity:1;transform:translate(0)}}.vidtreo-settings-header{color:#fff;cursor:pointer;text-align:left;background:0 0;border:none;align-items:center;gap:.75rem;width:100%;margin-bottom:1rem;padding:0;display:flex}.vidtreo-settings-back-icon{color:#fff;flex-shrink:0}.vidtreo-settings-title{color:#fff;margin:0;font-size:.875rem;font-weight:600}.vidtreo-device-options-container{flex-direction:column;gap:.375rem;display:flex}.vidtreo-device-option-nav{cursor:pointer;color:#fff;background:0 0;border:none;border-radius:.5rem;align-items:center;gap:1rem;width:100%;padding:.5rem .75rem;transition:background-color .2s;display:flex}.vidtreo-device-option-nav:hover{background:#fff3}.vidtreo-device-option-nav-content{flex-shrink:0;align-items:center;gap:.75rem;display:flex}.vidtreo-device-option-nav-label{color:#fff;font-size:.875rem;font-weight:500}.vidtreo-device-option-nav-value{flex:1;justify-content:flex-end;align-items:center;gap:.5rem;min-width:0;display:flex}.vidtreo-device-option-nav-value-text{color:#fffc;text-overflow:ellipsis;white-space:nowrap;text-align:right;flex:1;font-size:.875rem;overflow:hidden}.vidtreo-device-option-nav-chevron{color:#fff;font-size:1.25rem;line-height:1}.vidtreo-device-list{flex-direction:column;gap:0;max-height:200px;display:flex;overflow-y:auto}.vidtreo-device-list::-webkit-scrollbar{width:4px}.vidtreo-device-list::-webkit-scrollbar-track{background:0 0}.vidtreo-device-list::-webkit-scrollbar-thumb{background:#fff3;border-radius:2px}.vidtreo-device-list::-webkit-scrollbar-thumb:hover{background:#ffffff4d}.vidtreo-device-option{cursor:pointer;color:#fff;text-align:left;background:0 0;border:none;border-radius:.5rem;align-items:center;gap:.75rem;width:100%;padding:.5rem .75rem;transition:background-color .2s;display:flex}.vidtreo-device-option:hover{background:#fff3}.vidtreo-device-option-check-container{flex-shrink:0;justify-content:center;align-items:center;width:20px;height:20px;display:flex}.vidtreo-device-checkmark-placeholder{flex-shrink:0;width:20px;height:20px}.vidtreo-device-checkmark{color:#fff;flex-shrink:0}.vidtreo-device-option-label{color:#fff;flex:1;font-size:.875rem}.vidtreo-device-empty{color:#fff9;text-align:center;padding:1rem 0;font-size:.875rem}.vidtreo-audio-level-bars{height:1rem;z-index:var(--vidtreo-z-controls);contain:layout style paint;will-change:auto;backface-visibility:hidden;align-items:center;gap:.125rem;transform:translateZ(0);display:flex!important;position:absolute!important;bottom:.75rem!important;right:.75rem!important}@media (width>=768px){.vidtreo-audio-level-bars{height:1.25rem}}.vidtreo-audio-level-bar{background:#ffffff80;border-radius:9999px;align-self:flex-end;width:.125rem;transition:all .1s}.vidtreo-recording-controls{z-index:var(--vidtreo-z-controls);contain:layout style;will-change:auto;backface-visibility:hidden;position:absolute!important;bottom:12px!important;left:50%!important;transform:translate(-50%)translateZ(0)!important}.vidtreo-recording-controls-row{will-change:auto;justify-content:center;align-items:center;gap:.5rem;display:flex;transform:translateZ(0)}.vidtreo-recording-timer-row{justify-content:space-between;align-items:center;gap:.5rem;display:flex}.vidtreo-recording-timer-badge{z-index:var(--vidtreo-z-controls);contain:layout style paint;will-change:auto;backface-visibility:hidden;background:#0000004d;border:none;border-radius:9999px;align-items:center;gap:.375rem;padding:.25rem .5rem;transform:translateZ(0);box-shadow:0 1px 3px #0000001a,0 1px 2px -1px #0000001a;display:flex!important;position:absolute!important;top:.75rem!important;right:.75rem!important}.vidtreo-recording-dot-small{background:hsl(var(--vidtreo-destructive));border-radius:50%;width:.375rem;height:.375rem;animation:1.5s ease-in-out infinite vidtreo-pulse}.vidtreo-recording-timer-text{color:#fff;font-family:monospace;font-size:.75rem;font-weight:500}.vidtreo-control-buttons-row{will-change:auto;justify-content:center;align-items:center;gap:.375rem;height:auto;min-height:2rem;display:flex;transform:translateZ(0)}@media (width>=768px){.vidtreo-control-buttons-row{min-height:2.25rem}}.vidtreo-control-button{cursor:pointer;color:#fff;box-sizing:border-box;vertical-align:top;contain:layout style paint;will-change:auto;backface-visibility:hidden;background:#0000004d;border:none;border-radius:9999px;flex-shrink:0;justify-content:center;align-items:center;width:2rem;height:2rem;min-height:2rem;max-height:2rem;margin:0;padding:.25rem;transition:background-color .2s;display:inline-flex;position:relative;transform:translateZ(0)}.vidtreo-control-button:before{content:"";z-index:0;border-radius:9999px;transition:background-color .2s;position:absolute;inset:.25rem}.vidtreo-control-button svg{color:inherit;z-index:1;flex-shrink:0;position:relative;width:22px!important;height:22px!important}@media (width>=768px){.vidtreo-control-button svg{width:24px!important;height:24px!important}.vidtreo-control-button{width:2.25rem;height:2.25rem;min-height:2.25rem;max-height:2.25rem}}.vidtreo-control-button:hover:not(:disabled):before{background:#fff3}.vidtreo-control-button:disabled{opacity:.5;cursor:not-allowed}.vidtreo-control-button.vidtreo-muted:before{background:#0000004d}.vidtreo-control-button.vidtreo-muted:hover:not(:disabled):before{background:#fff3}.vidtreo-record-button{background:hsl(var(--vidtreo-destructive));height:2rem;min-height:2rem;max-height:2rem;color:hsl(var(--vidtreo-destructive-foreground));box-sizing:border-box;vertical-align:top;cursor:pointer;border:none;border-radius:9999px;flex-shrink:0;justify-content:center;align-items:center;gap:.375rem;width:auto;margin:0;padding:0 .75rem;font-size:.75rem;font-weight:500;line-height:1;transition:background-color .2s,filter .2s;display:inline-flex}@media (width>=768px){.vidtreo-record-button{height:2.25rem;min-height:2.25rem;max-height:2.25rem;font-size:.875rem}}.vidtreo-record-button:hover:not(:disabled){filter:brightness(.85)}.vidtreo-record-button.vidtreo-stop-button-locked{opacity:.5;cursor:not-allowed;filter:none}.vidtreo-record-button.vidtreo-stop-button-locked:hover{filter:none}#startButton.vidtreo-record-button{animation:2s ease-in-out infinite vidtreo-record-glow-pulse}@keyframes vidtreo-record-glow-pulse{0%,to{box-shadow:0 0 8px 2px #ef444466,0 0 16px 4px #ef444433}50%{box-shadow:0 0 16px 4px #ef444499,0 0 32px 8px #ef44444d}}#startButton.vidtreo-record-button:hover:not(:disabled){animation-play-state:paused;box-shadow:0 0 20px 6px #ef4444b3,0 0 40px 10px #ef444459}.vidtreo-rec-indicator-top{contain:layout style paint;will-change:auto;backface-visibility:hidden;background:#0000004d;border:none;border-radius:9999px;align-items:center;gap:.375rem;padding:.25rem .5rem;transform:translateZ(0);box-shadow:0 1px 3px #0000001a,0 1px 2px -1px #0000001a;display:flex!important;position:absolute!important;top:.75rem!important;left:.75rem!important}.vidtreo-rec-indicator-top span{color:#fff;font-size:.75rem;font-weight:500}.vidtreo-start-camera-area{text-align:center;cursor:pointer;z-index:1;contain:layout style paint;backface-visibility:hidden;will-change:auto;background:#000;border:none;border-radius:0;flex-direction:column;justify-content:center;align-items:center;padding:40px;transition:all .3s;display:flex;position:absolute;inset:0;transform:translateZ(0)}.vidtreo-start-camera-area:hover:not(.vidtreo-loading){background:#000}.vidtreo-start-camera-area.vidtreo-loading{cursor:wait;opacity:.7}.vidtreo-start-camera-area.vidtreo-loading .vidtreo-camera-text{color:#fff;opacity:.7}.vidtreo-camera-icon{color:#fff;justify-content:center;margin-bottom:16px;font-size:48px;display:flex}.vidtreo-camera-text{color:#fff;margin-bottom:8px;font-weight:600}.vidtreo-camera-text a{color:#3b82f6;text-decoration:underline}.vidtreo-camera-text a:hover{color:#2563eb}.vidtreo-camera-hint{color:#fff;opacity:.8;font-size:12px}@keyframes vidtreo-pulse{0%,to{opacity:1}50%{opacity:.3}}.vidtreo-progress{margin-top:20px;display:none}.vidtreo-progress.vidtreo-active{display:block}.vidtreo-progress-bar{background:#e0e0e0;border-radius:4px;width:100%;height:8px;margin-bottom:8px;overflow:hidden}.vidtreo-progress-fill{background:linear-gradient(90deg,#667eea 0%,#764ba2 100%);width:0%;height:100%;transition:width .3s}.vidtreo-progress-text{text-align:center;color:#fff;font-size:14px}.vidtreo-error{color:#fff;text-align:center;z-index:var(--vidtreo-z-error-overlay);word-wrap:break-word;background:#dc2626;border:none;border-radius:.5rem;max-width:90%;padding:1rem 1.25rem;font-size:.875rem;font-weight:500;display:none;position:absolute;top:.75rem;left:50%;transform:translate(-50%);box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a}.vidtreo-error.vidtreo-active{animation:.3s ease-out vidtreo-error-fade-in-slide-down;display:block}@keyframes vidtreo-error-fade-in-slide-down{0%{opacity:0;transform:translate(-50%)translateY(-1rem)}to{opacity:1;transform:translate(-50%)translateY(0)}}.vidtreo-upload-progress{margin-top:20px;display:none}.vidtreo-upload-progress.vidtreo-active{display:block}.vidtreo-preview-container .vidtreo-upload-progress{margin-top:0}.vidtreo-upload-status{border-radius:8px;margin-top:20px;padding:16px;display:none}.vidtreo-upload-status.vidtreo-active{display:block}.vidtreo-upload-status.vidtreo-success{color:#22543d;background:#f0f9ff;border:2px solid #48bb78}.vidtreo-upload-status.vidtreo-error{color:#c33;background:#fee;border:2px solid #fcc}.vidtreo-upload-status-text{font-size:14px;font-weight:500}.vidtreo-preview-error{aspect-ratio:9/16;background:hsl(var(--vidtreo-preview-bg));contain:strict;will-change:auto;backface-visibility:hidden;isolation:isolate;border:none;border-radius:0;justify-content:center;align-items:center;width:100%;display:flex;position:relative;overflow:hidden;transform:translateZ(0)}@media (width>=768px){.vidtreo-preview-error{aspect-ratio:16/9}}.vidtreo-error-content{text-align:center;color:#fff;flex-direction:column;justify-content:center;align-items:center;gap:1rem;max-width:400px;padding:2rem;display:flex}.vidtreo-error-icon{font-size:3rem;line-height:1}.vidtreo-error-title{font-size:1.25rem;font-weight:600;line-height:1.2}.vidtreo-error-message{opacity:.9;word-break:break-word;font-size:.875rem;line-height:1.5}.vidtreo-error-config{text-align:left;border-top:1px solid #fff3;width:100%;margin-top:1.5rem;padding-top:1.5rem}.vidtreo-error-config-title{color:#fff;margin-bottom:.75rem;font-size:.875rem;font-weight:600}.vidtreo-error-config-item{color:#ffffffd9;margin-bottom:.5rem;font-size:.8125rem;line-height:1.6}.vidtreo-error-config-item code{color:#fff;background:#ffffff26;border-radius:.25rem;padding:.125rem .375rem;font-family:monospace;font-size:.75rem}.vidtreo-error-retry{background:hsl(var(--vidtreo-destructive));color:hsl(var(--vidtreo-destructive-foreground));cursor:pointer;border:none;border-radius:.375rem;margin-top:.5rem;padding:.5rem 1rem;font-size:.875rem;font-weight:500;transition:filter .2s}.vidtreo-error-retry:hover:not(:disabled){filter:brightness(.85)}.vidtreo-error-retry:disabled{opacity:.5;cursor:not-allowed}.vidtreo-error-overlay{background:hsl(var(--vidtreo-preview-bg));z-index:var(--vidtreo-z-error-overlay);justify-content:center;align-items:center;display:flex;position:absolute;inset:0}.vidtreo-native-camera-container{aspect-ratio:9/16;background:hsl(var(--vidtreo-preview-bg));border-radius:0;justify-content:center;align-items:center;width:100%;display:flex;position:relative;overflow:hidden}@media (width>=768px){.vidtreo-native-camera-container{aspect-ratio:16/9}}.vidtreo-native-camera-container:has(.vidtreo-native-camera-preview-container){background:0 0}.vidtreo-config-loading-indicator{z-index:var(--vidtreo-z-controls);position:absolute;top:8px;right:8px}.vidtreo-spinner-small{border:2px solid #ffffff4d;border-top-color:#fff;border-radius:50%;width:16px;height:16px;animation:.6s linear infinite spin}.vidtreo-native-camera-empty-state{flex-direction:column;justify-content:center;align-items:center;gap:16px;width:100%;height:100%;padding:24px;display:flex;position:relative}.vidtreo-native-camera-buttons{flex-direction:column;gap:12px;width:100%;max-width:300px;display:flex}.vidtreo-native-camera-process-button,.vidtreo-native-camera-download-button{z-index:30;position:absolute;bottom:24px;left:50%;transform:translate(-50%)}.vidtreo-native-camera-process-button .vidtreo-btn,.vidtreo-native-camera-download-button .vidtreo-btn{min-width:200px}.vidtreo-btn{border-radius:var(--vidtreo-radius);cursor:pointer;border:none;padding:12px 24px;font-size:1rem;font-weight:500;transition:all .2s}.vidtreo-btn:disabled{opacity:.5;cursor:not-allowed}.vidtreo-btn-primary{background:hsl(var(--vidtreo-primary));color:hsl(var(--vidtreo-primary-foreground))}.vidtreo-btn-primary:hover:not(:disabled){filter:brightness(.9)}.vidtreo-btn-secondary{background:hsl(var(--vidtreo-secondary));color:hsl(var(--vidtreo-secondary-foreground));border:1px solid hsl(var(--vidtreo-border))}.vidtreo-btn-secondary:hover:not(:disabled){background:hsl(var(--vidtreo-accent))}.vidtreo-transcoding-progress{width:100%;max-width:400px;padding:16px}.vidtreo-progress-bar{background:#fff3;border-radius:4px;width:100%;height:8px;overflow:hidden}.vidtreo-progress-fill{background:hsl(var(--vidtreo-primary));height:100%;transition:width .3s}.vidtreo-progress-text{text-align:center;color:hsl(var(--vidtreo-foreground));margin-top:8px;font-size:.875rem}.vidtreo-native-camera-preview-container{background:0 0;justify-content:center;align-items:center;width:100%;height:100%;display:flex;position:relative}.vidtreo-native-camera-preview-image{object-fit:contain;width:100%;height:100%;display:block}.vidtreo-progress-overlay{backdrop-filter:blur(4px);width:100%;height:100%;z-index:var(--vidtreo-z-progress-overlay);pointer-events:none;background:#000000b3;flex-direction:column;justify-content:center;align-items:center;display:flex;position:absolute;inset:0}.vidtreo-progress-overlay .vidtreo-transcoding-progress,.vidtreo-progress-overlay .vidtreo-upload-progress{pointer-events:auto;background:0 0;flex-direction:column;align-items:center;gap:12px;width:90%;max-width:400px;padding:0;display:flex;position:relative}.vidtreo-progress-overlay .vidtreo-progress-bar,.vidtreo-progress-overlay .vidtreo-upload-progress-bar{background:#fff3;border-radius:4px;width:100%;height:8px;overflow:hidden}.vidtreo-progress-overlay .vidtreo-progress-fill{background:#fff;height:100%;transition:width .3s}.vidtreo-progress-overlay .vidtreo-progress-text,.vidtreo-progress-overlay .vidtreo-upload-progress-text{text-align:center;color:#fff;margin-top:0;font-size:.875rem;font-weight:500}.vidtreo-progress-overlay .vidtreo-upload-progress-bar{background:#fff3;border-radius:4px;width:100%;height:8px;overflow:hidden}.vidtreo-progress-overlay .vidtreo-upload-progress-fill{background:#fff;height:100%;transition:width .3s}.vidtreo-progress-overlay .vidtreo-progress-indeterminate{background:linear-gradient(90deg,#0000 0%,#fff 50%,#0000 100%) 0 0/200% 100%;width:100%;animation:1.5s ease-in-out infinite vidtreo-progress-indeterminate}@keyframes vidtreo-progress-indeterminate{0%{background-position:200% 0}to{background-position:-200% 0}}.vidtreo-mobile-web-recorder{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;width:100%;height:100%;font-family:-apple-system,BlinkMacSystemFont,SF Pro Display,SF Pro Text,system-ui,sans-serif}.vidtreo-camera-area button,.vidtreo-camera-area input,.vidtreo-camera-area select,.vidtreo-camera-area textarea,.vidtreo-mobile-web-recorder button,.vidtreo-mobile-web-recorder input,.vidtreo-mobile-web-recorder select,.vidtreo-mobile-web-recorder textarea,.vidtreo-permission-flow button{font-family:inherit}.vidtreo-mobile-landing-container{aspect-ratio:4/3;background:hsl(var(--vidtreo-preview-bg));border-radius:0;justify-content:center;align-items:center;width:100%;min-height:100%;max-height:100%;display:flex;position:relative;overflow:hidden}.vidtreo-mobile-landing-content{text-align:center;flex-direction:column;justify-content:center;align-items:center;gap:1.25rem;padding:2rem;display:flex}.vidtreo-mobile-landing-title{color:#fff;margin:0;font-size:1.25rem;font-weight:600;line-height:1.3}.vidtreo-mobile-landing-description{color:#ffffffbf;max-width:280px;margin:0;font-size:.875rem;line-height:1.5}.vidtreo-mobile-open-camera-btn{border-radius:9999px;justify-content:center;align-items:center;gap:.625rem;min-width:200px;margin-top:.5rem;padding:.875rem 1.75rem;font-size:1rem;font-weight:600;transition:all .2s;animation:2s ease-in-out infinite vidtreo-btn-glow-pulse;display:inline-flex}@keyframes vidtreo-btn-glow-pulse{0%,to{box-shadow:0 0 8px 2px #ffffff4d,0 0 16px 4px #ffffff26}50%{box-shadow:0 0 16px 4px #ffffff80,0 0 32px 8px #ffffff40}}.vidtreo-mobile-open-camera-btn:hover:not(:disabled){animation-play-state:paused;transform:scale(1.02);box-shadow:0 0 20px 6px #fff9,0 0 40px 10px #ffffff4d}.vidtreo-mobile-open-camera-btn:active:not(:disabled){transform:scale(.98)}.vidtreo-mobile-open-camera-btn:disabled{box-shadow:none;animation:none}#vidtreo-portal-root{z-index:9999;pointer-events:none;width:100vw;height:100dvh;position:fixed;top:0;left:0}#vidtreo-portal-root>*{pointer-events:auto}.vidtreo-mobile-modal-overlay{--vidtreo-safe-top:0px;--vidtreo-safe-bottom:0px;--vidtreo-safe-left:0px;--vidtreo-safe-right:0px;width:100vw;height:100dvh;z-index:var(--vidtreo-z-modal-overlay);background:#000;flex-direction:column;height:-webkit-fill-available;animation:.3s ease-out vidtreo-modal-fade-in;display:flex;position:fixed;inset:0}@keyframes vidtreo-modal-fade-in{0%{opacity:0}to{opacity:1}}.vidtreo-mobile-modal-header{padding:.75rem;padding-top:calc(.75rem + var(--vidtreo-safe-top,0px));z-index:var(--vidtreo-z-error-overlay);pointer-events:none;justify-content:center;display:flex;position:absolute;top:0;left:0;right:0}.vidtreo-mobile-modal-close-btn{color:#ffffffe6;cursor:pointer;pointer-events:auto;backdrop-filter:blur(4px);background:#00000080;border:none;border-radius:9999px;justify-content:center;align-items:center;gap:.375rem;height:2rem;padding:0 .75rem;font-size:.75rem;font-weight:500;transition:all .2s;display:flex}.vidtreo-mobile-modal-close-btn:hover:not(:disabled){background:#000000b3}.vidtreo-mobile-modal-close-btn:disabled{opacity:.3;cursor:not-allowed}.vidtreo-mobile-modal-content{width:100%;height:100%;padding-top:var(--vidtreo-safe-top,0px);padding-bottom:var(--vidtreo-safe-bottom,0px);padding-left:var(--vidtreo-safe-left,0px);padding-right:var(--vidtreo-safe-right,0px);flex-direction:column;flex:1;display:flex;position:relative}.vidtreo-mobile-recorder-content{--vidtreo-safe-top:0px;--vidtreo-safe-bottom:0px;--vidtreo-safe-left:0px;--vidtreo-safe-right:0px;flex-direction:column;width:100%;height:100%;display:flex;position:relative}.vidtreo-mobile-recorder-content .vidtreo-preview-container{aspect-ratio:unset;flex:1;width:100%;height:100%}.vidtreo-mobile-recorder-content .vidtreo-video-preview{object-fit:cover}.vidtreo-mobile-preview{flex:1;aspect-ratio:unset!important;height:100%!important}.vidtreo-mobile-recorder-content .vidtreo-recording-controls{bottom:calc(24px + var(--vidtreo-safe-bottom,0px))!important}.vidtreo-mobile-recorder-content .vidtreo-audio-level-bars{bottom:calc(12px + var(--vidtreo-safe-bottom,0px))!important}.vidtreo-mobile-recorder-content .vidtreo-settings-panel{bottom:calc(7rem + var(--vidtreo-safe-bottom,0px))!important}.vidtreo-mobile-recorder-content .vidtreo-rec-indicator-top,.vidtreo-mobile-recorder-content .vidtreo-recording-timer-badge{contain:layout style;height:2rem;padding:0 .75rem;top:calc(.75rem + var(--vidtreo-safe-top,0px))!important}.vidtreo-mobile-recorder-content .vidtreo-recording-timer-text{white-space:nowrap;color:#fff;min-width:3rem;font-size:.875rem;display:inline-block}.vidtreo-mobile-recorder-content .vidtreo-error{top:calc(3.5rem + var(--vidtreo-safe-top,0px))!important}.vidtreo-mobile-recorder-content .vidtreo-control-buttons-row{gap:.75rem;min-height:4rem}.vidtreo-mobile-recorder-content .vidtreo-control-button{width:4rem;height:4rem;min-height:4rem;max-height:4rem}.vidtreo-mobile-recorder-content .vidtreo-control-button svg{width:1.5rem;height:1.5rem}.vidtreo-mobile-recorder-content .vidtreo-record-button{gap:.5rem;height:4rem;min-height:4rem;max-height:4rem;padding:0 1.5rem;font-size:1rem}.vidtreo-mobile-recorder-content .vidtreo-record-button svg{width:1.5rem;height:1.5rem}.vidtreo-permission-flow{z-index:var(--vidtreo-z-modal-overlay);contain:layout style paint;backface-visibility:hidden;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;background:#000;flex-direction:column;justify-content:center;align-items:center;gap:1.25rem;font-family:-apple-system,BlinkMacSystemFont,SF Pro Display,SF Pro Text,system-ui,sans-serif;display:none;position:absolute;inset:0;transform:translateZ(0)}.vidtreo-permission-flow.vidtreo-active{animation:.4s cubic-bezier(.2,0,0,1) vidtreo-fadeIn;display:flex}.vidtreo-permission-flow-title{color:#fff;text-align:center;margin:0;font-size:1.25rem;font-weight:600;line-height:1.3}.vidtreo-permission-flow-subtitle{color:#ffffffbf;text-align:center;letter-spacing:-.005em;max-width:280px;margin:0;font-size:.875rem;line-height:1.5}.vidtreo-permission-flow-action{background:hsl(var(--vidtreo-primary));color:hsl(var(--vidtreo-primary-foreground));cursor:pointer;letter-spacing:-.01em;border:none;border-radius:9999px;justify-content:center;align-items:center;gap:.625rem;min-width:200px;margin-top:.5rem;padding:.875rem 1.75rem;font-size:1rem;font-weight:600;transition:all .2s;animation:2s ease-in-out infinite vidtreo-btn-glow-pulse;display:inline-flex}.vidtreo-permission-flow-action:hover:not(:disabled){animation-play-state:paused;transform:scale(1.02);box-shadow:0 0 20px 6px #fff9,0 0 40px 10px #ffffff4d}.vidtreo-permission-flow-action:active:not(:disabled){transform:scale(.98)}.vidtreo-permission-flow-action:disabled{opacity:.5;cursor:not-allowed;box-shadow:none;animation:none}.vidtreo-permission-flow-action--requesting{opacity:.55;cursor:wait;box-shadow:none;animation:none}@keyframes vidtreo-spinner-rotate{to{transform:rotate(360deg)}}.vidtreo-permission-flow-spinner{border:2px solid #ffffff4d;border-top-color:hsl(var(--vidtreo-primary-foreground));border-radius:50%;flex-shrink:0;width:1.125rem;height:1.125rem;animation:.8s linear infinite vidtreo-spinner-rotate;display:inline-block}.vidtreo-permission-flow-spinner--large{border-width:3px;width:2.5rem;height:2.5rem}.vidtreo-permission-flow-recovery{text-align:center;flex-direction:column;align-items:center;gap:1.25rem;max-width:280px;display:flex}.vidtreo-permission-flow-recovery-text{color:#fff6;letter-spacing:-.005em;margin:0;font-size:.75rem;line-height:1.6}.vidtreo-permission-flow-retry{background:hsl(var(--vidtreo-primary));color:hsl(var(--vidtreo-primary-foreground));cursor:pointer;letter-spacing:-.01em;border:none;border-radius:9999px;justify-content:center;align-items:center;gap:.625rem;min-width:200px;padding:.875rem 1.75rem;font-size:1rem;font-weight:600;transition:all .2s;animation:2s ease-in-out infinite vidtreo-btn-glow-pulse;display:inline-flex}.vidtreo-permission-flow-retry:hover:not(:disabled){animation-play-state:paused;transform:scale(1.02);box-shadow:0 0 20px 6px #fff9,0 0 40px 10px #ffffff4d}.vidtreo-permission-flow-retry:active:not(:disabled){transform:scale(.98)}@keyframes vidtreo-fadeOut{0%{opacity:1}to{opacity:0}}.vidtreo-permission-flow.vidtreo-permission-flow--fading{pointer-events:none;animation:.6s ease-out forwards vidtreo-fadeOut}.vidtreo-recovery-guide{width:100%;max-width:280px;margin:0 auto;position:relative}.vidtreo-recovery-guide:after{content:"";z-index:20;pointer-events:none;background:linear-gradient(#0000 0%,#000 100%);height:60px;position:absolute;bottom:0;left:0;right:0}.vidtreo-recovery-guide:before{content:"";z-index:20;pointer-events:none;background:linear-gradient(90deg,#0000 0%,#000 100%);width:50px;position:absolute;top:0;bottom:0;right:0}.vidtreo-recovery-guide-browser{background:#161616;border-top:1px solid #ffffff1a;border-left:1px solid #ffffff1a;border-radius:10px 0 0;animation:.5s vidtreo-fadeIn;position:relative;overflow:hidden}.vidtreo-recovery-guide-titlebar{z-index:3;background:#1e1e1e;border-bottom:1px solid #ffffff0f;align-items:center;gap:8px;padding:8px 10px;display:flex;position:relative}.vidtreo-recovery-guide-dots{flex-shrink:0;gap:5px;display:flex}.vidtreo-recovery-guide-dot{border-radius:50%;width:8px;height:8px}.vidtreo-recovery-guide-dot--close{background:#ff5f57}.vidtreo-recovery-guide-dot--min{background:#febc2e}.vidtreo-recovery-guide-dot--max{background:#28c840}.vidtreo-recovery-guide-addressbar{background:#2a2a2a;border-radius:5px;flex:1;align-items:center;gap:5px;min-width:0;padding:4px 8px;display:flex}.vidtreo-recovery-guide-lock{color:#ffffff80;flex-shrink:0;align-items:center;animation:7s ease-in-out infinite vidtreo-lock-pulse;display:flex}.vidtreo-recovery-guide-lock-svg{display:block}.vidtreo-recovery-guide-url{color:#ffffff80;white-space:nowrap;text-overflow:ellipsis;font-family:-apple-system,BlinkMacSystemFont,system-ui,sans-serif;font-size:.65rem;overflow:hidden}.vidtreo-recovery-guide-cursor{z-index:40;pointer-events:none;filter:drop-shadow(0 2px 4px #0009);animation:7s ease-in-out infinite vidtreo-cursor-move;position:absolute;top:12px;left:62px}.vidtreo-recovery-guide-cursor-svg{display:block}.vidtreo-recovery-guide-browser-bg{background:#161616;height:110px}.vidtreo-recovery-guide-popover{z-index:30;background:#252525;border:1px solid #ffffff1a;border-radius:10px;padding:8px 12px 12px;animation:7s ease-in-out infinite vidtreo-popover-reveal;position:absolute;top:34px;left:12px;right:12px;box-shadow:0 8px 30px #0009,0 2px 8px #0006,0 0 0 1px #ffffff0f}.vidtreo-recovery-guide-popover-header{color:#ffffffd9;white-space:nowrap;text-overflow:ellipsis;text-align:left;padding-bottom:6px;font-family:-apple-system,BlinkMacSystemFont,system-ui,sans-serif;font-size:.65rem;font-weight:600;overflow:hidden}.vidtreo-recovery-guide-popover-divider{background:#ffffff14;height:1px}.vidtreo-recovery-guide-perm-row{justify-content:space-between;align-items:center;padding:7px 0;display:flex}.vidtreo-recovery-guide-perm-row+.vidtreo-recovery-guide-perm-row{border-top:1px solid #ffffff0f}.vidtreo-recovery-guide-perm-group{align-items:center;gap:8px;display:flex}.vidtreo-recovery-guide-perm-icon{flex-shrink:0;width:14px;height:14px;position:relative}.vidtreo-recovery-guide-icon-off,.vidtreo-recovery-guide-icon-on{justify-content:center;align-items:center;display:flex;position:absolute;inset:0}.vidtreo-recovery-guide-icon-off{color:#fff6;animation:7s ease-in-out infinite vidtreo-icon-hide}.vidtreo-recovery-guide-icon-on{color:#34d399;animation:7s ease-in-out infinite vidtreo-icon-show}.vidtreo-recovery-guide-perm-label{color:#ffffffd9;font-family:-apple-system,BlinkMacSystemFont,system-ui,sans-serif;font-size:.7rem}.vidtreo-recovery-guide-switch{flex-shrink:0;width:32px;height:18px;position:relative}.vidtreo-recovery-guide-switch-track{background:#ffffff26;border-radius:9px;animation:7s ease-in-out infinite vidtreo-track-on;position:absolute;inset:0}.vidtreo-recovery-guide-switch-knob{background:#fff;border-radius:50%;width:14px;height:14px;animation:7s ease-in-out infinite vidtreo-knob-slide;position:absolute;top:2px;left:2px;box-shadow:0 1px 3px #0000004d}.vidtreo-recovery-guide-switch--delayed{animation-delay:.85s}@keyframes vidtreo-cursor-move{0%{opacity:0;transform:translate(100px,12px)}8%{opacity:1}22%{transform:translate(0)}26%{transform:translate(0)scale(.75)}30%{opacity:1;transform:translate(0)scale(1)}33%{opacity:1;transform:translate(0)}38%{opacity:1;transform:translate(65px,63px)}42%{transform:translate(65px,63px)scale(.75)}45%{opacity:1;transform:translate(65px,63px)scale(1)}48%{opacity:1;transform:translate(65px,97px)}52%{transform:translate(65px,97px)scale(.75)}55%{opacity:1;transform:translate(65px,97px)scale(1)}60%{opacity:0}to{opacity:0;transform:translate(100px,12px)}}@keyframes vidtreo-popover-reveal{0%,27%{opacity:0;transform:translateY(-6px)scale(.96)}33%,82%{opacity:1;transform:translateY(0)scale(1)}88%,to{opacity:0;transform:translateY(-6px)scale(.96)}}@keyframes vidtreo-track-on{0%,34%{background:#ffffff26}40%,92%{background:#34d399}96%,to{background:#ffffff26}}@keyframes vidtreo-knob-slide{0%,34%{transform:translate(0)}40%,92%{transform:translate(14px)}96%,to{transform:translate(0)}}@keyframes vidtreo-icon-hide{0%,34%{opacity:1}40%,92%{opacity:0}96%,to{opacity:1}}@keyframes vidtreo-icon-show{0%,34%{opacity:0}40%,92%{opacity:1}96%,to{opacity:0}}@keyframes vidtreo-lock-pulse{0%,15%{color:#ffffff80}22%,30%{color:#34d399}38%,to{color:#ffffff80}}.vidtreo-record-button.vidtreo-record-button-disabled,.vidtreo-record-button-disabled{opacity:.6;cursor:not-allowed;pointer-events:none;filter:grayscale(.3)}.vidtreo-mic-connecting-indicator{justify-content:center;align-items:center;animation:1.4s ease-in-out infinite vidtreo-mic-pulse;display:inline-flex}@keyframes vidtreo-mic-pulse{0%,to{opacity:.4}50%{opacity:1}}.vidtreo-audio-error-overlay{z-index:var(--vidtreo-z-error-overlay);text-align:center;background:#000000d9;flex-direction:column;justify-content:center;align-items:center;padding:2rem 1.5rem;animation:.3s ease-out vidtreo-audio-overlay-fade-in;display:flex;position:absolute;inset:0}@supports (backdrop-filter:blur(8px)){.vidtreo-audio-error-overlay{-webkit-backdrop-filter:blur(8px);background:#000000bf}}@keyframes vidtreo-audio-overlay-fade-in{0%{opacity:0}to{opacity:1}}.vidtreo-audio-error-icon{background:#ef444426;border-radius:50%;justify-content:center;align-items:center;width:56px;height:56px;margin-bottom:1rem;display:flex}.vidtreo-audio-error-icon svg{color:#ef4444;width:28px;height:28px}.vidtreo-audio-error-title{color:#fff;margin:0 0 .5rem;font-size:1.125rem;font-weight:600;line-height:1.4}.vidtreo-audio-error-message{color:#ffffffb3;max-width:320px;margin:0 0 1.5rem;font-size:.875rem;line-height:1.6}.vidtreo-audio-error-retry{color:#111;cursor:pointer;background:#fff;border:none;border-radius:9999px;align-items:center;gap:.5rem;padding:.75rem 1.5rem;font-family:inherit;font-size:.875rem;font-weight:600;transition:background .15s,transform .1s;display:inline-flex}.vidtreo-audio-error-retry:hover{background:#f0f0f0}.vidtreo-audio-error-retry:active{transform:scale(.97)}.vidtreo-audio-error-retry svg{width:16px;height:16px}.vidtreo-audio-warning-toast{z-index:var(--vidtreo-z-error-overlay);color:#ffffffeb;pointer-events:auto;background:#1111118c;border:1px solid #ffffff14;border-radius:12px;align-items:flex-start;gap:.625rem;max-width:min(420px,100% - 2rem);padding:.625rem .875rem;font-family:inherit;animation:.2s ease-out vidtreo-audio-warning-toast-fade-in;display:flex;position:absolute;top:1rem;left:50%;transform:translate(-50%);box-shadow:0 4px 16px #00000040}@supports (backdrop-filter:blur(10px)){.vidtreo-audio-warning-toast{-webkit-backdrop-filter:blur(10px)saturate(140%);background:#11111173}}.vidtreo-audio-warning-toast--critical{border-color:#ef444473}.vidtreo-audio-warning-toast--critical .vidtreo-audio-warning-toast__icon{color:#ef4444}.vidtreo-audio-warning-toast--soft{border-color:#f59e0b73}.vidtreo-audio-warning-toast--soft .vidtreo-audio-warning-toast__icon{color:#f59e0b}.vidtreo-audio-warning-toast__icon{flex:none;justify-content:center;align-items:center;width:20px;height:20px;margin-top:1px;display:inline-flex}.vidtreo-audio-warning-toast__content{flex-direction:column;flex:auto;gap:2px;min-width:0;display:flex}.vidtreo-audio-warning-toast__title{color:#fff;font-size:.8125rem;font-weight:600;line-height:1.3}.vidtreo-audio-warning-toast__message{color:#ffffffb8;font-size:.75rem;font-weight:400;line-height:1.4}.vidtreo-audio-warning-toast__dismiss{color:#ffffffa6;cursor:pointer;background:0 0;border:none;border-radius:6px;flex:none;justify-content:center;align-items:center;width:22px;height:22px;margin-left:.25rem;padding:0;font-family:inherit;transition:background .15s,color .15s;display:inline-flex}.vidtreo-audio-warning-toast__dismiss:hover{color:#fffffff2;background:#ffffff1a}@keyframes vidtreo-audio-warning-toast-fade-in{0%{opacity:0;transform:translate(-50%,-8px)}to{opacity:1;transform:translate(-50%)}}`;function zT(e){return`
12830
12830
  <style>${RT}</style>
12831
12831
  <div class="vidtreo-mobile-landing-container">
12832
12832
  <div class="vidtreo-mobile-landing-content">
@@ -13381,9 +13381,9 @@ Mediabunny was loaded twice.\` + " This will likely cause Mediabunny not to work
13381
13381
  </div>
13382
13382
 
13383
13383
  </div>
13384
- `;function WT(e,t,n,r){return{showSettingsButton:!e&&r.enableDeviceChange!==!1,showMuteButton:e&&r.enableMute!==!1,showPauseButton:e&&r.enablePause!==!1&&t===`recording`&&!n,showResumeButton:e&&r.enablePause!==!1&&n,showStopButton:e,showSwitchSourceButton:e&&r.enableSourceSwitching!==!1}}let GT=/^https?:\/\//i;function KT(e){return e?GT.test(e)?e:`https://${e}`:`https://core.vidtreo.com`}function qT(e,t,n){let r=e.getAttribute(t);return r===null?n:r!==`false`}function JT(e,t){let n=e.getAttribute(t);if(!n)return;let r=Number.parseInt(n,10);if(!Number.isNaN(r))return r}function YT(e,t){let n=e.getAttribute(t);if(n!==null)return n}function XT(e){return{apiKey:e.getAttribute(`api-key`)||``,backendUrl:KT(e.getAttribute(`backend-url`)),demo:qT(e,`demo`,!1),enableSourceSwitching:qT(e,`enable-source-switching`,!0),enableMute:qT(e,`enable-mute`,!0),enablePause:qT(e,`enable-pause`,!0),enableDeviceChange:qT(e,`enable-device-change`,!0),enableTabVisibilityOverlay:qT(e,`enable-tab-visibility-overlay`,!1)}}function ZT(e){let t={},n=JT(e,`countdown-duration`);n!==void 0&&(t.countdownDuration=n);let r=JT(e,`max-recording-time`);r!==void 0&&(t.maxRecordingTime=r);let i=JT(e,`min-time-record`);return i!==void 0&&(t.minTimeRecord=i),t}function QT(e,t,n){return e?t!==void 0&&t.trim().length>0?t:n!==void 0&&n.trim().length>0?n:void 0:t}function $T(e,t){let n=e.getAttribute(`user-metadata`);if(n)try{let e=JSON.parse(n);return{...t,...e}}catch(e){throw Error(`Invalid user-metadata JSON: ${i(e)}`)}}function eE(e,t,n){let r=XT(e),i=ZT(e),a=YT(e,`tab-visibility-overlay-text`),o=QT(r.enableTabVisibilityOverlay===!0,a,n),s=$T(e,t),c={...r,...i};return o!==void 0&&(c={...c,tabVisibilityOverlayText:o}),s!==void 0&&(c={...c,userMetadata:s}),c}function tE(){if(typeof document>`u`||document.querySelector(`script[src*="@phosphor-icons/web"]`))return;let e=document.createElement(`script`);e.src=`https://unpkg.com/@phosphor-icons/web`,e.async=!0,document.head.appendChild(e)}let nE=1e3,rE=/^\d+$/;function iE(e){return rE.test(e)}function aE(e){let t=e.trim();if(t.length===0)return 0;let n=t.split(`:`);if(n.length!==2&&n.length!==3)return 0;for(let e of n)if(!iE(e))return 0;if(n.length===2){let e=Number.parseInt(n[0],10),t=Number.parseInt(n[1],10);return(e*60+t)*nE}let r=Number.parseInt(n[0],10),i=Number.parseInt(n[1],10),a=Number.parseInt(n[2],10);return((r*60+i)*60+a)*nE}function oE(e,t,n){return!n||e==null||Number.isFinite(e)===!1||e<=0?!1:aE(t)<e}function sE(){let e=Error(`Minimum recording time has not been reached yet`);return e.code=`recording.minimum-time-not-reached`,e}let cE={requiresAudio:!1,requiresWatermark:!1},lE={step:`idle`,permissions:{camera:`unknown`,microphone:`unknown`},denialType:`none`,isSecureContext:!0,isComplete:!1,canRetry:!0,shouldProbeUnknown:!0},uE={recordingState:`idle`,stream:null,isVideoLoaded:!1,isMuted:!1,isPaused:!1,isAudioReady:!1,hasAudioFailed:!1,showSettings:!1,error:null,errorCode:null,canRetry:!1,browserName:null,browserVersion:null,countdown:null,timer:`00:00`,uploadProgress:null,transcodingProgress:null,transitionMessage:null,recordedBlob:null,audioWarning:null,devices:{cameras:[],microphones:[],selectedCamera:null,selectedMic:null},configError:null};var dE=class extends HTMLElement{constructor(...e){super(...e),this.controller=null,this.audioStatusUnsub=null,this.uploadService=null,this.state={...uE},this.config={},this.isMounted=!1,this.connectionGeneration=0,this.initialized=!1,this.isInitializing=!1,this.isProcessingBlob=!1,this.audioBarsContainer=null,this.previewContentElements=null,this.recordingControlsElements=null,this.videoPreviewElements=null,this.permissionFlowElements=null,this.overlayElements=null,this.settingsPanelElement=null,this.audioWarningAutoDismissId=null,this.audioContext=null,this.analyser=null,this.animationFrameId=null,this.mobileManager=null,this.nativeCameraManager=null,this.permissionFlowOrchestrator=null,this.permissionFlowSnapshot=lE,this.overlayPhase=`hidden`,this.overlayFadeTimeoutId=null,this.isStartingPreview=!1,this.i18n=new OT,this.settingsView=`main`,this.slideDirection=`none`}static{this.observedAttributes=[`api-key`,`backend-url`,`countdown-duration`,`min-time-record`,`max-recording-time`,`user-metadata`,`enable-source-switching`,`enable-mute`,`enable-pause`,`enable-device-change`,`enable-tab-visibility-overlay`,`tab-visibility-overlay-text`,`demo`,`mobile-mode`,`lang`]}get isDemo(){return this.hasAttribute(`demo`)&&this.getAttribute(`demo`)!==`false`}get lang(){return this.getAttribute(`lang`)||`en`}async connectedCallback(){this.connectionGeneration+=1;let e=this.connectionGeneration;this.i18n.setLang(this.lang);let t=this.shouldProbeWebRecorderSupport();if(await this.probeWebRecorderSupport(t,e),this.shouldAbortConnection(e))return;let n=this.getEffectiveMobileMode();this.initializeRecorderForMobileMode(n)}disconnectedCallback(){this.connectionGeneration+=1,this.isMounted=!1,this.mobileManager?.destroy(),this.nativeCameraManager?.destroy(),this.cleanup()}async probeWebRecorderSupport(e,t){this.isMounted||(this.isMounted=!0,e&&await lb(cE).then(e=>{if(!this.shouldAbortConnection(t)){if(!e.isSupported){this.updateUnsupportedBrowserState();return}this.updateState({errorCode:null,canRetry:!1,browserName:null,browserVersion:null})}}).catch(()=>{this.shouldAbortConnection(t)||this.updateUnsupportedBrowserState()}))}updateUnsupportedBrowserState(){let e=aw();this.updateState({errorCode:_w,canRetry:!1,browserName:e.browserName,browserVersion:e.browserVersion})}clearBrowserUnsupportedState(){this.updateState({errorCode:null,canRetry:!1,browserName:null,browserVersion:null})}applyBrowserUnsupportedStateFromError(e){if(!(e&&typeof e==`object`&&`code`in e))return;let t=e;if(t.code?.startsWith(`camera.`)||t.code?.startsWith(`audio.`)||t.code?.startsWith(`recording.`)){this.updateState({errorCode:t.code,canRetry:!0,browserName:null,browserVersion:null});return}if(t.code!==_w)return;let n=aw(),r=n.browserName;t.browserName&&t.browserName.length>0&&(r=t.browserName);let i=n.browserVersion;t.browserVersion&&t.browserVersion.length>0&&(i=t.browserVersion),this.updateState({errorCode:_w,canRetry:!1,browserName:r,browserVersion:i})}resolveBrowserErrorState(){let e=this.state.errorCode,t=this.state.browserName,n=this.state.browserVersion;if(e===_w&&t===null){let e=aw();t=e.browserName,n===null&&(n=e.browserVersion)}return{errorCode:e,browserName:t,browserVersion:n}}shouldAbortConnection(e){return!this.isConnected||e!==this.connectionGeneration}initializeRecorderForMobileMode(e){if(!iw()){this.innerHTML=UT(),this.init();return}if(e===`native`){this.initNativeCamera();return}if(e===`overlay`){this.mobileManager=new PT({getState:()=>({recordingState:this.state.recordingState,uploadProgress:this.state.uploadProgress}),isInitialized:()=>this.initialized,startPreview:()=>this.startPreview(),stopPreview:()=>this.stopPreview(),renderMobile:()=>this.renderMobile()}),this.renderMobile(),this.init();return}this.innerHTML=UT(),this.init()}getRequestedMobileMode(){let e=this.getAttribute(`mobile-mode`);return e===null?null:e===`embed`?`embed`:e===`native`?`native`:`overlay`}shouldProbeWebRecorderSupport(){return this.getRequestedMobileMode()!==`native`}getEffectiveMobileMode(){let e=this.getRequestedMobileMode();return e===null?`overlay`:e}initNativeCamera(){this.config=this.resolveRecorderComponentConfig({}),this.nativeCameraManager=new FT({apiKey:this.config.apiKey,backendUrl:this.config.backendUrl,maxRecordingTime:this.config.maxRecordingTime,userMetadata:this.config.userMetadata,demo:this.isDemo},{onStateChange:()=>this.renderNativeCamera(),onUploadComplete:e=>{this.dispatchEvent(new CustomEvent(`recording-complete`,{detail:e,bubbles:!0,composed:!0}))},onError:e=>{this.dispatchEvent(new CustomEvent(`error`,{detail:{error:e.message},bubbles:!0,composed:!0}))}}),this.renderNativeCamera(),tE()}renderNativeCamera(){if(!this.nativeCameraManager)return;let e=this.nativeCameraManager.getState();this.innerHTML=VT(this.i18n);let t=e.file!==null,n=!(t||e.isTranscoding)&&e.uploadProgress===null&&!e.transcodedBlob;this.setElementDisplay(`#nativeCameraEmptyState`,n),this.setElementDisplay(`#nativePreviewContainer`,t||!!e.transcodedBlob),this.setElementDisplay(`#nativeProgressOverlay`,e.isTranscoding||e.uploadProgress!==null),this.updateNativeCameraProgress(e),this.updateNativeCameraPreview(e,t);let r=this.isDemo&&!!e.transcodedBlob&&!e.isTranscoding&&e.uploadProgress===null;this.setElementDisplay(`#nativeActions`,r),this.updateNativeCameraError(e),this.setupNativeCameraListeners()}setElementDisplay(e,t){let n=this.querySelector(e);n instanceof HTMLElement&&(t&&(n.style.display=``),t||(n.style.display=`none`))}updateNativeCameraProgress(e){let t=this.querySelector(`#nativeUploadProgressFill`),n=this.querySelector(`#nativeUploadProgressText`),r=null;t instanceof HTMLElement&&(r=t);let i=e.uploadProgress!==null,a=e.isTranscoding&&!i,o=0;e.uploadProgress!==null&&(o=e.uploadProgress);let s=0;e.transcodingProgress!==null&&(s=e.transcodingProgress),i&&this.setElementDisplay(`#nativeUploadProgress`,!0),r&&i&&(r.style.width=`${o}%`),n&&i&&(n.textContent=`${this.i18n.t(`uploading`)} ${Math.round(o)}%`),a&&this.setElementDisplay(`#nativeUploadProgress`,!0),r&&a&&(r.style.width=`${s}%`),n&&a&&(n.textContent=`${this.i18n.t(`finishing`)} ${Math.round(s)}%`)}updateNativeCameraPreview(e,t){let n=this.querySelector(`#nativeVideoPreview`);if(n){if(t&&e.file){n.src=URL.createObjectURL(e.file.file);return}e.transcodedBlob&&(n.src=URL.createObjectURL(e.transcodedBlob))}}updateNativeCameraError(e){let t=this.querySelector(`.vidtreo-native-camera-container`);if(!t)return;let n=t.querySelector(`.vidtreo-audio-error-overlay`);if(!e.error){n&&n.remove();return}let r=`generic|${e.error}`;if(n&&n.dataset.signature===r)return;n&&n.remove();let i=this.getDeviceErrorIcon(`generic`),a=this.i18n.t(`genericErrorTitle`),o=this.i18n.t(`errorRetry`);n=document.createElement(`div`),n.className=`vidtreo-audio-error-overlay`,n.dataset.variant=`generic`,n.dataset.signature=r;let s=document.createElement(`div`);s.className=`vidtreo-audio-error-icon`,s.innerHTML=i,n.appendChild(s);let c=document.createElement(`h3`);c.className=`vidtreo-audio-error-title`,c.textContent=a,n.appendChild(c);let l=document.createElement(`p`);l.className=`vidtreo-audio-error-message`,l.textContent=e.error,n.appendChild(l);let u=document.createElement(`button`);u.className=`vidtreo-audio-error-retry`,u.type=`button`,u.innerHTML=`<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 256 256">
13384
+ `;function WT(e,t,n,r){return{showSettingsButton:!e&&r.enableDeviceChange!==!1,showMuteButton:e&&r.enableMute!==!1,showPauseButton:e&&r.enablePause!==!1&&t===`recording`&&!n,showResumeButton:e&&r.enablePause!==!1&&n,showStopButton:e,showSwitchSourceButton:e&&r.enableSourceSwitching!==!1}}let GT=/^https?:\/\//i;function KT(e){return e?GT.test(e)?e:`https://${e}`:`https://core.vidtreo.com`}function qT(e,t,n){let r=e.getAttribute(t);return r===null?n:r!==`false`}function JT(e,t){let n=e.getAttribute(t);if(!n)return;let r=Number.parseInt(n,10);if(!Number.isNaN(r))return r}function YT(e,t){let n=e.getAttribute(t);if(n!==null)return n}function XT(e){return{apiKey:e.getAttribute(`api-key`)||``,backendUrl:KT(e.getAttribute(`backend-url`)),demo:qT(e,`demo`,!1),enableSourceSwitching:qT(e,`enable-source-switching`,!0),enableMute:qT(e,`enable-mute`,!0),enablePause:qT(e,`enable-pause`,!0),enableDeviceChange:qT(e,`enable-device-change`,!0),enableTabVisibilityOverlay:qT(e,`enable-tab-visibility-overlay`,!1)}}function ZT(e){let t={},n=JT(e,`countdown-duration`);n!==void 0&&(t.countdownDuration=n);let r=JT(e,`max-recording-time`);r!==void 0&&(t.maxRecordingTime=r);let i=JT(e,`min-time-record`);return i!==void 0&&(t.minTimeRecord=i),t}function QT(e,t,n){return e?t!==void 0&&t.trim().length>0?t:n!==void 0&&n.trim().length>0?n:void 0:t}function $T(e,t){let n=e.getAttribute(`user-metadata`);if(n)try{let e=JSON.parse(n);return{...t,...e}}catch(e){throw Error(`Invalid user-metadata JSON: ${i(e)}`)}}function eE(e,t,n){let r=XT(e),i=ZT(e),a=YT(e,`tab-visibility-overlay-text`),o=QT(r.enableTabVisibilityOverlay===!0,a,n),s=$T(e,t),c={...r,...i};return o!==void 0&&(c={...c,tabVisibilityOverlayText:o}),s!==void 0&&(c={...c,userMetadata:s}),c}function tE(){if(typeof document>`u`||document.querySelector(`script[src*="@phosphor-icons/web"]`))return;let e=document.createElement(`script`);e.src=`https://unpkg.com/@phosphor-icons/web`,e.async=!0,document.head.appendChild(e)}let nE=1e3,rE=/^\d+$/;function iE(e){return rE.test(e)}function aE(e){let t=e.trim();if(t.length===0)return 0;let n=t.split(`:`);if(n.length!==2&&n.length!==3)return 0;for(let e of n)if(!iE(e))return 0;if(n.length===2){let e=Number.parseInt(n[0],10),t=Number.parseInt(n[1],10);return(e*60+t)*nE}let r=Number.parseInt(n[0],10),i=Number.parseInt(n[1],10),a=Number.parseInt(n[2],10);return((r*60+i)*60+a)*nE}function oE(e,t,n){return!n||e==null||Number.isFinite(e)===!1||e<=0?!1:aE(t)<e}function sE(){let e=Error(`Minimum recording time has not been reached yet`);return e.code=`recording.minimum-time-not-reached`,e}let cE={requiresAudio:!1,requiresWatermark:!1},lE={step:`idle`,permissions:{camera:`unknown`,microphone:`unknown`},denialType:`none`,isSecureContext:!0,isComplete:!1,canRetry:!0,shouldProbeUnknown:!0},uE={recordingState:`idle`,stream:null,isVideoLoaded:!1,isMuted:!1,isPaused:!1,isAudioReady:!1,hasAudioFailed:!1,showSettings:!1,error:null,errorCode:null,canRetry:!1,browserName:null,browserVersion:null,countdown:null,timer:`00:00`,uploadProgress:null,transcodingProgress:null,transitionMessage:null,recordedBlob:null,audioWarning:null,devices:{cameras:[],microphones:[],selectedCamera:null,selectedMic:null},configError:null};var dE=class extends HTMLElement{constructor(...e){super(...e),this.controller=null,this.audioStatusUnsub=null,this.uploadService=null,this.state={...uE},this.config={},this.isMounted=!1,this.connectionGeneration=0,this.initialized=!1,this.isInitializing=!1,this.isProcessingBlob=!1,this.audioBarsContainer=null,this.previewContentElements=null,this.recordingControlsElements=null,this.videoPreviewElements=null,this.permissionFlowElements=null,this.overlayElements=null,this.settingsPanelElement=null,this.audioWarningAutoDismissId=null,this.audioContext=null,this.analyser=null,this.animationFrameId=null,this.mobileManager=null,this.nativeCameraManager=null,this.permissionFlowOrchestrator=null,this.permissionFlowSnapshot=lE,this.overlayPhase=`hidden`,this.overlayFadeTimeoutId=null,this.isStartingPreview=!1,this.i18n=new OT,this.settingsView=`main`,this.slideDirection=`none`}static{this.observedAttributes=[`api-key`,`backend-url`,`countdown-duration`,`min-time-record`,`max-recording-time`,`user-metadata`,`enable-source-switching`,`enable-mute`,`enable-pause`,`enable-device-change`,`enable-tab-visibility-overlay`,`tab-visibility-overlay-text`,`demo`,`mobile-mode`,`lang`]}get isDemo(){return this.hasAttribute(`demo`)&&this.getAttribute(`demo`)!==`false`}get lang(){return this.getAttribute(`lang`)||`en`}async connectedCallback(){this.connectionGeneration+=1;let e=this.connectionGeneration;this.i18n.setLang(this.lang);let t=this.shouldProbeWebRecorderSupport();if(await this.probeWebRecorderSupport(t,e),this.shouldAbortConnection(e))return;let n=this.getEffectiveMobileMode();this.initializeRecorderForMobileMode(n)}disconnectedCallback(){this.connectionGeneration+=1,this.isMounted=!1,this.mobileManager?.destroy(),this.nativeCameraManager?.destroy(),this.cleanup()}async probeWebRecorderSupport(e,t){this.isMounted||(this.isMounted=!0,e&&await ub(cE).then(e=>{if(!this.shouldAbortConnection(t)){if(!e.isSupported){this.updateUnsupportedBrowserState();return}this.updateState({errorCode:null,canRetry:!1,browserName:null,browserVersion:null})}}).catch(()=>{this.shouldAbortConnection(t)||this.updateUnsupportedBrowserState()}))}updateUnsupportedBrowserState(){let e=aw();this.updateState({errorCode:_w,canRetry:!1,browserName:e.browserName,browserVersion:e.browserVersion})}clearBrowserUnsupportedState(){this.updateState({errorCode:null,canRetry:!1,browserName:null,browserVersion:null})}applyBrowserUnsupportedStateFromError(e){if(!(e&&typeof e==`object`&&`code`in e))return;let t=e;if(t.code?.startsWith(`camera.`)||t.code?.startsWith(`audio.`)||t.code?.startsWith(`recording.`)){this.updateState({errorCode:t.code,canRetry:!0,browserName:null,browserVersion:null});return}if(t.code!==_w)return;let n=aw(),r=n.browserName;t.browserName&&t.browserName.length>0&&(r=t.browserName);let i=n.browserVersion;t.browserVersion&&t.browserVersion.length>0&&(i=t.browserVersion),this.updateState({errorCode:_w,canRetry:!1,browserName:r,browserVersion:i})}resolveBrowserErrorState(){let e=this.state.errorCode,t=this.state.browserName,n=this.state.browserVersion;if(e===_w&&t===null){let e=aw();t=e.browserName,n===null&&(n=e.browserVersion)}return{errorCode:e,browserName:t,browserVersion:n}}shouldAbortConnection(e){return!this.isConnected||e!==this.connectionGeneration}initializeRecorderForMobileMode(e){if(!iw()){this.innerHTML=UT(),this.init();return}if(e===`native`){this.initNativeCamera();return}if(e===`overlay`){this.mobileManager=new PT({getState:()=>({recordingState:this.state.recordingState,uploadProgress:this.state.uploadProgress}),isInitialized:()=>this.initialized,startPreview:()=>this.startPreview(),stopPreview:()=>this.stopPreview(),renderMobile:()=>this.renderMobile()}),this.renderMobile(),this.init();return}this.innerHTML=UT(),this.init()}getRequestedMobileMode(){let e=this.getAttribute(`mobile-mode`);return e===null?null:e===`embed`?`embed`:e===`native`?`native`:`overlay`}shouldProbeWebRecorderSupport(){return this.getRequestedMobileMode()!==`native`}getEffectiveMobileMode(){let e=this.getRequestedMobileMode();return e===null?`overlay`:e}initNativeCamera(){this.config=this.resolveRecorderComponentConfig({}),this.nativeCameraManager=new FT({apiKey:this.config.apiKey,backendUrl:this.config.backendUrl,maxRecordingTime:this.config.maxRecordingTime,userMetadata:this.config.userMetadata,demo:this.isDemo},{onStateChange:()=>this.renderNativeCamera(),onUploadComplete:e=>{this.dispatchEvent(new CustomEvent(`recording-complete`,{detail:e,bubbles:!0,composed:!0}))},onError:e=>{this.dispatchEvent(new CustomEvent(`error`,{detail:{error:e.message},bubbles:!0,composed:!0}))}}),this.renderNativeCamera(),tE()}renderNativeCamera(){if(!this.nativeCameraManager)return;let e=this.nativeCameraManager.getState();this.innerHTML=VT(this.i18n);let t=e.file!==null,n=!(t||e.isTranscoding)&&e.uploadProgress===null&&!e.transcodedBlob;this.setElementDisplay(`#nativeCameraEmptyState`,n),this.setElementDisplay(`#nativePreviewContainer`,t||!!e.transcodedBlob),this.setElementDisplay(`#nativeProgressOverlay`,e.isTranscoding||e.uploadProgress!==null),this.updateNativeCameraProgress(e),this.updateNativeCameraPreview(e,t);let r=this.isDemo&&!!e.transcodedBlob&&!e.isTranscoding&&e.uploadProgress===null;this.setElementDisplay(`#nativeActions`,r),this.updateNativeCameraError(e),this.setupNativeCameraListeners()}setElementDisplay(e,t){let n=this.querySelector(e);n instanceof HTMLElement&&(t&&(n.style.display=``),t||(n.style.display=`none`))}updateNativeCameraProgress(e){let t=this.querySelector(`#nativeUploadProgressFill`),n=this.querySelector(`#nativeUploadProgressText`),r=null;t instanceof HTMLElement&&(r=t);let i=e.uploadProgress!==null,a=e.isTranscoding&&!i,o=0;e.uploadProgress!==null&&(o=e.uploadProgress);let s=0;e.transcodingProgress!==null&&(s=e.transcodingProgress),i&&this.setElementDisplay(`#nativeUploadProgress`,!0),r&&i&&(r.style.width=`${o}%`),n&&i&&(n.textContent=`${this.i18n.t(`uploading`)} ${Math.round(o)}%`),a&&this.setElementDisplay(`#nativeUploadProgress`,!0),r&&a&&(r.style.width=`${s}%`),n&&a&&(n.textContent=`${this.i18n.t(`finishing`)} ${Math.round(s)}%`)}updateNativeCameraPreview(e,t){let n=this.querySelector(`#nativeVideoPreview`);if(n){if(t&&e.file){n.src=URL.createObjectURL(e.file.file);return}e.transcodedBlob&&(n.src=URL.createObjectURL(e.transcodedBlob))}}updateNativeCameraError(e){let t=this.querySelector(`.vidtreo-native-camera-container`);if(!t)return;let n=t.querySelector(`.vidtreo-audio-error-overlay`);if(!e.error){n&&n.remove();return}let r=`generic|${e.error}`;if(n&&n.dataset.signature===r)return;n&&n.remove();let i=this.getDeviceErrorIcon(`generic`),a=this.i18n.t(`genericErrorTitle`),o=this.i18n.t(`errorRetry`);n=document.createElement(`div`),n.className=`vidtreo-audio-error-overlay`,n.dataset.variant=`generic`,n.dataset.signature=r;let s=document.createElement(`div`);s.className=`vidtreo-audio-error-icon`,s.innerHTML=i,n.appendChild(s);let c=document.createElement(`h3`);c.className=`vidtreo-audio-error-title`,c.textContent=a,n.appendChild(c);let l=document.createElement(`p`);l.className=`vidtreo-audio-error-message`,l.textContent=e.error,n.appendChild(l);let u=document.createElement(`button`);u.className=`vidtreo-audio-error-retry`,u.type=`button`,u.innerHTML=`<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 256 256">
13385
13385
  <path d="M240,56v48a8,8,0,0,1-8,8H184a8,8,0,0,1,0-16h28.69L187.8,71.11A88,88,0,0,0,40.36,98.72,8,8,0,1,1,24.64,93.28,104,104,0,0,1,198.13,60.87L224,86.75V56a8,8,0,0,1,16,0ZM215.36,157.28a88,88,0,0,1-147.44,27.61L43.31,160H72a8,8,0,0,0,0-16H24a8,8,0,0,0-8,8v48a8,8,0,0,0,16,0V169.25l25.87,25.88A104,104,0,0,0,231.36,162.72a8,8,0,0,1-16,5.44Z"/>
13386
- </svg>`;let d=document.createElement(`span`);d.textContent=o,u.appendChild(d),u.addEventListener(`click`,e=>{e.preventDefault(),e.stopPropagation(),this.nativeCameraManager?.reset()}),n.appendChild(u),t.appendChild(n)}setupNativeCameraListeners(){let e=this.querySelector(`#btnSelectVideo`),t=this.querySelector(`#btnRecordVideo`),n=this.querySelector(`#btnNativeRetake`),r=this.querySelector(`#nativeCameraInput`);e?.addEventListener(`click`,()=>{r&&(r.accept=`video/*`,r.removeAttribute(`capture`),r.click())}),t?.addEventListener(`click`,()=>{r&&(r.accept=`video/*`,r.setAttribute(`capture`,`environment`),r.click())}),n?.addEventListener(`click`,()=>{this.nativeCameraManager?.reset()}),r?.addEventListener(`change`,async e=>{let t=e.target,n=t.files?.[0];if(n&&this.nativeCameraManager)try{let e=await this.nativeCameraManager.handleFileSelect(n);await this.nativeCameraManager.processAndUpload(e)}catch{}t.value=``})}attributeChangedCallback(e,t,n){if(t!==n){if(e===`min-time-record`){let e=eE(this,{});this.config={...this.config,minTimeRecord:e.minTimeRecord},this.render();return}[`api-key`,`backend-url`,`demo`].includes(e)&&(this.initialized&&this.cleanup(),this.init())}}async init(){if(!this.isInitializing){this.isInitializing=!0;try{this.initialized&&this.cleanup(),this.config=this.resolveRecorderComponentConfig({});let e=this.config.apiKey||``,t=this.config.backendUrl||``;if(!(this.isDemo||e)){this.updateState({configError:Error(`apiKey is required. Provide it as an attribute or ensure demo mode is enabled.`)}),this.isInitializing=!1;return}this.isDemo||(this.uploadService=new LT({apiKey:e,backendUrl:t})),this.controller=new KC(ow(this));let n={...this.config};if(await this.controller.initialize(n),await this.initializePermissionFlow(),this.initialized=!0,this.updateState({configError:null}),this.clearBrowserUnsupportedState(),this.mobileManager){tE();return}this.cacheUiElements(),this.renderPermissionFlow(),this.setupEventListeners(),tE(),this.getCanStartStreamFromPermissionFlow(this.permissionFlowSnapshot)&&setTimeout(()=>this.startPreview(),100)}catch(e){this.applyBrowserUnsupportedStateFromError(e),this.updateState({error:i(e)})}finally{this.isInitializing=!1}}}renderConfigError(){let e=this.state,t=!!e.configError;if(this.toggleDisplay(`#configErrorOverlay`,t),t&&e.configError){let t=e.configError.message.includes(`apiKey is required`);this.toggleDisplay(`#configErrorMessageDefault`,!t),this.toggleDisplay(`#configErrorDetails`,t),t||this.setText(`#configErrorMessageDefault`,e.configError.message)}}resolveRecorderComponentConfig(e){return eE(this,e,this.i18n.t(`userInAnotherTab`))}cleanup(){this.audioStatusUnsub&&=(this.audioStatusUnsub(),null),this.cleanupPermissionFlow(),this.controller&&=(this.controller.cleanup(),null),this.stopAudioAnalysis(),this.initialized=!1,this.state={...uE},this.permissionFlowElements=null}updateState(e){let t={...this.state,...e};e.stream!==void 0&&(t={...t,isVideoLoaded:!1}),e.recordingState!==void 0&&t.showSettings&&t.recordingState===gw&&(t={...t,showSettings:!1}),this.state=t,this.mobileManager&&e.uploadProgress!==void 0&&this.mobileManager.checkUploadCompletion(this.state.uploadProgress),this.render(),e.stream!==void 0&&this.handleStreamUpdate(this.state.stream),this.state.devices.cameras.length===0&&this.state.stream&&this.updateDevices()}async updateDevices(){if(!this.controller)return;let e=this.controller.getDeviceManager(),t=await e.getAvailableDevices();this.updateState({devices:{cameras:t.videoinput,microphones:t.audioinput,selectedCamera:e.getSelectedCameraDeviceId(),selectedMic:e.getSelectedMicDeviceId()}})}handleStreamUpdate(e){this.videoPreviewElements||this.cacheUiElements(),this.videoPreviewElements&&Kw(e,this.videoPreviewElements,{onVideoLoaded:()=>{this.updateState({isVideoLoaded:!0}),this.updateOverlayPhase()},onError:e=>{this.updateState({error:e})},startAudioAnalysis:e=>this.startAudioAnalysis(e),stopAudioAnalysis:()=>this.stopAudioAnalysis()})}startAudioAnalysis(e){if(this.stopAudioAnalysis(),e.getAudioTracks().length!==0)try{this.audioContext=new AudioContext;let t=this.audioContext.createMediaStreamSource(e);this.analyser=this.audioContext.createAnalyser(),this.analyser.fftSize=64,t.connect(this.analyser);let n=new Uint8Array(this.analyser.frequencyBinCount),r=()=>{if(!this.analyser)return;this.analyser.getByteFrequencyData(n);let e=0;for(let t of n)e+=t;let t=e/n.length,i=Math.min(1,t/128);this.renderAudioBars(i),this.animationFrameId=requestAnimationFrame(r)};r()}catch(e){this.updateState({error:i(e)})}}stopAudioAnalysis(){this.animationFrameId&&=(cancelAnimationFrame(this.animationFrameId),null),this.audioContext&&=(this.audioContext.close(),null)}renderAudioBars(e){if(!this.audioBarsContainer)return;let t=vw,n=``;if(!this.state.isMuted)for(let r of t){let t=Math.max(4,e*24*r);n+=`<div class="vidtreo-audio-level-bar" style="height: ${t}px;"></div>`}this.audioBarsContainer.innerHTML=n}render(){if(this.mobileManager&&!this.mobileManager.isModalOpen||(this.previewContentElements&&this.recordingControlsElements&&this.overlayElements&&this.videoPreviewElements||this.cacheUiElements(),!(this.previewContentElements&&this.recordingControlsElements&&this.overlayElements&&this.videoPreviewElements)))return;let e=this.i18n.getAll(),t=IT(e),n=this.state.recordingState===gw||this.state.isPaused,r=oE(this.config.minTimeRecord,this.state.timer,n),a={enableDeviceChange:this.config.enableDeviceChange,enableMute:this.config.enableMute,enablePause:this.config.enablePause,enableSourceSwitching:this.config.enableSourceSwitching},o=WT(n,this.state.recordingState,this.state.isPaused,a),s=!1;this.isDemo&&!n&&this.state.recordingState===`idle`&&this.state.recordedBlob!==null&&(s=!0);let c={...o,showDownloadButton:s},l=mw;this.controller&&(l=this.controller.getCurrentSourceType());let{errorCode:u,browserName:d,browserVersion:f}=this.resolveBrowserErrorState();eT({state:{stream:this.state.stream,transitionMessage:this.state.transitionMessage,recordingState:this.state.recordingState,countdown:this.state.countdown,timer:this.state.timer,isMuted:this.state.isMuted,isPaused:this.state.isPaused,errorCode:u,browserName:d,browserVersion:f},isVideoLoaded:this.state.isVideoLoaded,isRecording:n,controller:this.controller,audioLevel:0,buttonVisibility:c,currentSourceType:l,onStartRecording:()=>this.handleRecord(),onStopRecording:()=>this.handleStop(),onSwitchSource:()=>this.handleSwitch(),onToggleSettings:()=>this.updateState({showSettings:!this.state.showSettings}),onToggleMute:()=>this.handleMute(),onPause:()=>this.handlePauseToggle(),onResume:()=>this.handlePauseToggle(),onRetryCamera:()=>{this.startPreview().catch(e=>{let t;t=e instanceof Error?e:Error(i(e)),this.dispatchEvent(new CustomEvent(`error`,{detail:{error:t.message},bubbles:!0,composed:!0}))})},onLoadedChange:()=>this.updateState({isVideoLoaded:!0}),onDownload:()=>this.handleDownload(),translations:t.preview,buttonTranslations:t.buttons},this.previewContentElements),uT(cT({stream:this.state.stream,buttonVisibility:c,currentSourceType:l,isMuted:this.state.isMuted,isAudioReady:this.state.isAudioReady,onDownload:()=>this.handleDownload(),onPause:()=>this.handlePauseToggle(),onResume:()=>this.handlePauseToggle(),onStartRecording:()=>this.handleRecord(),onStopRecording:()=>this.handleStop(),onSwitchSource:()=>this.handleSwitch(),onToggleMute:()=>this.handleMute(),onToggleSettings:()=>this.updateState({showSettings:!this.state.showSettings}),recordingState:this.state.recordingState,isStopLocked:r,stopLockedTooltip:t.buttons.minimumRecordingTimeNotReached,buttonTranslations:t.buttons}),this.recordingControlsElements),yw({uploadProgress:this.state.transcodingProgress??this.state.uploadProgress,uploadingLabel:this.state.transcodingProgress===null?e.uploading:e.finishing},{overlay:this.overlayElements.uploadOverlay,fill:this.overlayElements.uploadFill,text:this.overlayElements.uploadText}),bw({transitionMessage:this.state.transitionMessage},{overlay:this.overlayElements.transitionOverlay,message:this.overlayElements.transitionMessage}),wT(CT({stream:this.state.stream,showSettings:this.state.showSettings,devices:this.state.devices,onCameraChange:e=>this.handleCameraChange(e),onMicChange:e=>this.handleMicChange(e),translations:t.settings}),this.settingsPanelElement,()=>this.renderSettings()),this.renderDeviceErrorOverlay(),this.renderAudioWarningToast(n),this.renderPermissionFlow(),this.renderMobileIndicators(n),this.renderConfigError()}renderAudioWarningToast(e){let t=this.shadowRoot;if(!t)return;let n=t.querySelector(`.vidtreo-audio-warning-toast`),r=this.state.audioWarning;if(!(e&&r!==null)){n&&(n.remove(),this.clearAudioWarningAutoDismiss());return}if(r===null)return;let i=this.resolveAudioWarningSeverity(r.code),a=this.resolveAudioWarningCopy(r.code),o=`${r.code}|${i}`;if(n&&n.dataset.signature===o)return;n&&n.remove(),this.clearAudioWarningAutoDismiss();let s=t.querySelector(`.vidtreo-preview-container`);if(!s)return;let c=document.createElement(`div`);c.className=`vidtreo-audio-warning-toast vidtreo-audio-warning-toast--${i}`,c.dataset.signature=o,c.setAttribute(`role`,`status`),c.setAttribute(`aria-live`,`polite`);let l=document.createElement(`span`);l.className=`vidtreo-audio-warning-toast__icon`,l.innerHTML=this.getAudioWarningIcon(i),c.appendChild(l);let u=document.createElement(`span`);u.className=`vidtreo-audio-warning-toast__content`;let d=document.createElement(`span`);d.className=`vidtreo-audio-warning-toast__title`,d.textContent=a.title;let f=document.createElement(`span`);if(f.className=`vidtreo-audio-warning-toast__message`,f.textContent=a.message,u.appendChild(d),u.appendChild(f),c.appendChild(u),i===`critical`||r.code===`audio.no-signal`){let e=document.createElement(`button`);e.className=`vidtreo-audio-warning-toast__dismiss`,e.type=`button`,e.setAttribute(`aria-label`,this.i18n.t(`audioWarningDismiss`)),e.innerHTML=`<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" viewBox="0 0 256 256"><path d="M205.66,194.34a8,8,0,0,1-11.32,11.32L128,139.31,61.66,205.66a8,8,0,0,1-11.32-11.32L116.69,128,50.34,61.66A8,8,0,0,1,61.66,50.34L128,116.69l66.34-66.35a8,8,0,0,1,11.32,11.32L139.31,128Z"/></svg>`,e.addEventListener(`click`,e=>{e.preventDefault(),e.stopPropagation(),this.updateState({audioWarning:null})}),c.appendChild(e)}r.code===`audio.low-signal`&&(this.audioWarningAutoDismissId=window.setTimeout(()=>{this.audioWarningAutoDismissId=null,this.updateState({audioWarning:null})},6e3)),s.appendChild(c)}clearAudioWarningAutoDismiss(){this.audioWarningAutoDismissId!==null&&(window.clearTimeout(this.audioWarningAutoDismissId),this.audioWarningAutoDismissId=null)}resolveAudioWarningSeverity(e){return e===`audio.track-ended`||e===`audio.track-muted-by-browser`||e===`audio.no-chunks`?`critical`:`soft`}resolveAudioWarningCopy(e){switch(e){case`audio.no-signal`:return{title:this.i18n.t(`audioWarningNoSignalTitle`),message:this.i18n.t(`audioWarningNoSignalMessage`)};case`audio.low-signal`:return{title:this.i18n.t(`audioWarningLowSignalTitle`),message:this.i18n.t(`audioWarningLowSignalMessage`)};case`audio.speaking-while-muted`:return{title:this.i18n.t(`audioWarningSpeakingMutedTitle`),message:this.i18n.t(`audioWarningSpeakingMutedMessage`)};case`audio.track-ended`:return{title:this.i18n.t(`audioWarningTrackEndedTitle`),message:this.i18n.t(`audioWarningTrackEndedMessage`)};case`audio.no-chunks`:return{title:this.i18n.t(`audioWarningNoChunksTitle`),message:this.i18n.t(`audioWarningNoChunksMessage`)};case`audio.track-muted-by-browser`:return{title:this.i18n.t(`audioWarningTrackMutedTitle`),message:this.i18n.t(`audioWarningTrackMutedMessage`)};default:return{title:``,message:``}}}getAudioWarningIcon(e){return e===`critical`?`<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 256 256"><path d="M213.92,210.62a8,8,0,1,1-11.84,10.76L176,193.63V200a48,48,0,0,1-83.43,32.45A47.84,47.84,0,0,1,80,200V176a8,8,0,0,1,16,0v24a32,32,0,0,0,55.12,22.13L120,188.68V200a8,8,0,0,1-16,0V172.67l-16-17.6V200a8,8,0,0,1-16,0V138.27l-16-17.6V144a8,8,0,0,1-16,0V104.67L42.08,45.38A8,8,0,1,1,53.92,34.62ZM176,152V80A48,48,0,0,0,82.33,60.89l13.73,15.1A32,32,0,0,1,160,80v56.67Z"/></svg>`:`<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 256 256"><path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm-8,80V80a8,8,0,0,1,16,0v24a8,8,0,0,1-16,0Zm20,52a12,12,0,1,1-12-12A12,12,0,0,1,140,156Z"/></svg>`}renderDeviceErrorOverlay(){let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`.vidtreo-audio-error-overlay`),n=aS({errorCode:this.state.errorCode,hasAudioFailed:this.state.hasAudioFailed,error:this.state.error}),r=n.variant===`generic`;if(!(n.visible&&(r||this.state.recordingState===`idle`))){t&&t.remove();return}let i=r&&!n.actionableCode&&this.state.error?this.state.error:null,a=`${n.variant}|${n.actionableCode||``}|${i||``}`;if(t&&t.dataset.signature===a)return;t&&t.remove();let o=e.querySelector(`.vidtreo-preview-container`);if(!o)return;let s=this.getDeviceErrorIcon(n.variant),c=n.variant===`audio`?this.resolveAudioOverlayCopy(this.state.errorCode):null,l=n.variant===`camera`?this.resolveCameraOverlayCopy(this.state.errorCode):null,u=n.actionableCode?this.resolveRecordingOverlayCopy(n.actionableCode):null,d=this.resolveDeviceErrorOverlayCopy(n.variant,i,c,l,u);t=document.createElement(`div`),t.className=`vidtreo-audio-error-overlay`,t.dataset.variant=n.variant,t.dataset.signature=a;let f=document.createElement(`div`);f.className=`vidtreo-audio-error-icon`,f.innerHTML=s,t.appendChild(f);let p=document.createElement(`h3`);p.className=`vidtreo-audio-error-title`,p.textContent=d.title,t.appendChild(p);let m=document.createElement(`p`);m.className=`vidtreo-audio-error-message`,m.textContent=d.message,t.appendChild(m);let h=null;if(n.canRetry){h=document.createElement(`button`),h.className=`vidtreo-audio-error-retry`,h.type=`button`,h.innerHTML=`<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 256 256">
13386
+ </svg>`;let d=document.createElement(`span`);d.textContent=o,u.appendChild(d),u.addEventListener(`click`,e=>{e.preventDefault(),e.stopPropagation(),this.nativeCameraManager?.reset()}),n.appendChild(u),t.appendChild(n)}setupNativeCameraListeners(){let e=this.querySelector(`#btnSelectVideo`),t=this.querySelector(`#btnRecordVideo`),n=this.querySelector(`#btnNativeRetake`),r=this.querySelector(`#nativeCameraInput`);e?.addEventListener(`click`,()=>{r&&(r.accept=`video/*`,r.removeAttribute(`capture`),r.click())}),t?.addEventListener(`click`,()=>{r&&(r.accept=`video/*`,r.setAttribute(`capture`,`environment`),r.click())}),n?.addEventListener(`click`,()=>{this.nativeCameraManager?.reset()}),r?.addEventListener(`change`,async e=>{let t=e.target,n=t.files?.[0];if(n&&this.nativeCameraManager)try{let e=await this.nativeCameraManager.handleFileSelect(n);await this.nativeCameraManager.processAndUpload(e)}catch{}t.value=``})}attributeChangedCallback(e,t,n){if(t!==n){if(e===`min-time-record`){let e=eE(this,{});this.config={...this.config,minTimeRecord:e.minTimeRecord},this.render();return}[`api-key`,`backend-url`,`demo`].includes(e)&&(this.initialized&&this.cleanup(),this.init())}}async init(){if(!this.isInitializing){this.isInitializing=!0;try{this.initialized&&this.cleanup(),this.config=this.resolveRecorderComponentConfig({});let e=this.config.apiKey||``,t=this.config.backendUrl||``;if(!(this.isDemo||e)){this.updateState({configError:Error(`apiKey is required. Provide it as an attribute or ensure demo mode is enabled.`)}),this.isInitializing=!1;return}this.isDemo||(this.uploadService=new LT({apiKey:e,backendUrl:t})),this.controller=new KC(ow(this));let n={...this.config};if(await this.controller.initialize(n),await this.initializePermissionFlow(),this.initialized=!0,this.updateState({configError:null}),this.clearBrowserUnsupportedState(),this.mobileManager){tE();return}this.cacheUiElements(),this.renderPermissionFlow(),this.setupEventListeners(),tE(),this.getCanStartStreamFromPermissionFlow(this.permissionFlowSnapshot)&&setTimeout(()=>this.startPreview(),100)}catch(e){this.applyBrowserUnsupportedStateFromError(e),this.updateState({error:i(e)})}finally{this.isInitializing=!1}}}renderConfigError(){let e=this.state,t=!!e.configError;if(this.toggleDisplay(`#configErrorOverlay`,t),t&&e.configError){let t=e.configError.message.includes(`apiKey is required`);this.toggleDisplay(`#configErrorMessageDefault`,!t),this.toggleDisplay(`#configErrorDetails`,t),t||this.setText(`#configErrorMessageDefault`,e.configError.message)}}resolveRecorderComponentConfig(e){return eE(this,e,this.i18n.t(`userInAnotherTab`))}cleanup(){this.audioStatusUnsub&&=(this.audioStatusUnsub(),null),this.cleanupPermissionFlow(),this.controller&&=(this.controller.cleanup(),null),this.stopAudioAnalysis(),this.initialized=!1,this.state={...uE},this.permissionFlowElements=null}updateState(e){let t={...this.state,...e};e.stream!==void 0&&(t={...t,isVideoLoaded:!1}),e.recordingState!==void 0&&t.showSettings&&t.recordingState===gw&&(t={...t,showSettings:!1}),this.state=t,this.mobileManager&&e.uploadProgress!==void 0&&this.mobileManager.checkUploadCompletion(this.state.uploadProgress),this.render(),e.stream!==void 0&&this.handleStreamUpdate(this.state.stream),this.state.devices.cameras.length===0&&this.state.stream&&this.updateDevices()}async updateDevices(){if(!this.controller)return;let e=this.controller.getDeviceManager(),t=await e.getAvailableDevices();this.updateState({devices:{cameras:t.videoinput,microphones:t.audioinput,selectedCamera:e.getSelectedCameraDeviceId(),selectedMic:e.getSelectedMicDeviceId()}})}handleStreamUpdate(e){this.videoPreviewElements||this.cacheUiElements(),this.videoPreviewElements&&Kw(e,this.videoPreviewElements,{onVideoLoaded:()=>{this.updateState({isVideoLoaded:!0}),this.updateOverlayPhase()},onError:e=>{this.updateState({error:e})},startAudioAnalysis:e=>this.startAudioAnalysis(e),stopAudioAnalysis:()=>this.stopAudioAnalysis()})}startAudioAnalysis(e){if(this.stopAudioAnalysis(),e.getAudioTracks().length!==0)try{this.audioContext=new AudioContext;let t=this.audioContext.createMediaStreamSource(e);this.analyser=this.audioContext.createAnalyser(),this.analyser.fftSize=64,t.connect(this.analyser);let n=new Uint8Array(this.analyser.frequencyBinCount),r=()=>{if(!this.analyser)return;this.analyser.getByteFrequencyData(n);let e=0;for(let t of n)e+=t;let t=e/n.length,i=Math.min(1,t/128);this.renderAudioBars(i),this.animationFrameId=requestAnimationFrame(r)};r()}catch(e){this.updateState({error:i(e)})}}stopAudioAnalysis(){this.animationFrameId&&=(cancelAnimationFrame(this.animationFrameId),null),this.audioContext&&=(this.audioContext.close(),null)}renderAudioBars(e){if(!this.audioBarsContainer)return;let t=vw,n=``;if(!this.state.isMuted)for(let r of t){let t=Math.max(4,e*24*r);n+=`<div class="vidtreo-audio-level-bar" style="height: ${t}px;"></div>`}this.audioBarsContainer.innerHTML=n}render(){if(this.mobileManager&&!this.mobileManager.isModalOpen||(this.previewContentElements&&this.recordingControlsElements&&this.overlayElements&&this.videoPreviewElements||this.cacheUiElements(),!(this.previewContentElements&&this.recordingControlsElements&&this.overlayElements&&this.videoPreviewElements)))return;let e=this.i18n.getAll(),t=IT(e),n=this.state.recordingState===gw||this.state.isPaused,r=oE(this.config.minTimeRecord,this.state.timer,n),a={enableDeviceChange:this.config.enableDeviceChange,enableMute:this.config.enableMute,enablePause:this.config.enablePause,enableSourceSwitching:this.config.enableSourceSwitching},o=WT(n,this.state.recordingState,this.state.isPaused,a),s=!1;this.isDemo&&!n&&this.state.recordingState===`idle`&&this.state.recordedBlob!==null&&(s=!0);let c={...o,showDownloadButton:s},l=mw;this.controller&&(l=this.controller.getCurrentSourceType());let{errorCode:u,browserName:d,browserVersion:f}=this.resolveBrowserErrorState();eT({state:{stream:this.state.stream,transitionMessage:this.state.transitionMessage,recordingState:this.state.recordingState,countdown:this.state.countdown,timer:this.state.timer,isMuted:this.state.isMuted,isPaused:this.state.isPaused,errorCode:u,browserName:d,browserVersion:f},isVideoLoaded:this.state.isVideoLoaded,isRecording:n,controller:this.controller,audioLevel:0,buttonVisibility:c,currentSourceType:l,onStartRecording:()=>this.handleRecord(),onStopRecording:()=>this.handleStop(),onSwitchSource:()=>this.handleSwitch(),onToggleSettings:()=>this.updateState({showSettings:!this.state.showSettings}),onToggleMute:()=>this.handleMute(),onPause:()=>this.handlePauseToggle(),onResume:()=>this.handlePauseToggle(),onRetryCamera:()=>{this.startPreview().catch(e=>{let t;t=e instanceof Error?e:Error(i(e)),this.dispatchEvent(new CustomEvent(`error`,{detail:{error:t.message},bubbles:!0,composed:!0}))})},onLoadedChange:()=>this.updateState({isVideoLoaded:!0}),onDownload:()=>this.handleDownload(),translations:t.preview,buttonTranslations:t.buttons},this.previewContentElements),uT(cT({stream:this.state.stream,buttonVisibility:c,currentSourceType:l,isMuted:this.state.isMuted,isAudioReady:this.state.isAudioReady,onDownload:()=>this.handleDownload(),onPause:()=>this.handlePauseToggle(),onResume:()=>this.handlePauseToggle(),onStartRecording:()=>this.handleRecord(),onStopRecording:()=>this.handleStop(),onSwitchSource:()=>this.handleSwitch(),onToggleMute:()=>this.handleMute(),onToggleSettings:()=>this.updateState({showSettings:!this.state.showSettings}),recordingState:this.state.recordingState,isStopLocked:r,stopLockedTooltip:t.buttons.minimumRecordingTimeNotReached,buttonTranslations:t.buttons}),this.recordingControlsElements),yw({uploadProgress:this.state.transcodingProgress??this.state.uploadProgress,uploadingLabel:this.state.transcodingProgress===null?e.uploading:e.finishing},{overlay:this.overlayElements.uploadOverlay,fill:this.overlayElements.uploadFill,text:this.overlayElements.uploadText}),bw({transitionMessage:this.state.transitionMessage},{overlay:this.overlayElements.transitionOverlay,message:this.overlayElements.transitionMessage}),wT(CT({stream:this.state.stream,showSettings:this.state.showSettings,devices:this.state.devices,onCameraChange:e=>this.handleCameraChange(e),onMicChange:e=>this.handleMicChange(e),translations:t.settings}),this.settingsPanelElement,()=>this.renderSettings()),this.renderDeviceErrorOverlay(),this.renderAudioWarningToast(n),this.renderPermissionFlow(),this.renderMobileIndicators(n),this.renderConfigError()}renderAudioWarningToast(e){let t=this.shadowRoot;if(!t)return;let n=t.querySelector(`.vidtreo-audio-warning-toast`),r=this.state.audioWarning;if(!(e&&r!==null)){n&&(n.remove(),this.clearAudioWarningAutoDismiss());return}if(r===null)return;let i=this.resolveAudioWarningSeverity(r.code),a=this.resolveAudioWarningCopy(r.code),o=`${r.code}|${i}`;if(n&&n.dataset.signature===o)return;n&&n.remove(),this.clearAudioWarningAutoDismiss();let s=t.querySelector(`.vidtreo-preview-container`);if(!s)return;let c=document.createElement(`div`);c.className=`vidtreo-audio-warning-toast vidtreo-audio-warning-toast--${i}`,c.dataset.signature=o,c.setAttribute(`role`,`status`),c.setAttribute(`aria-live`,`polite`);let l=document.createElement(`span`);l.className=`vidtreo-audio-warning-toast__icon`,l.innerHTML=this.getAudioWarningIcon(i),c.appendChild(l);let u=document.createElement(`span`);u.className=`vidtreo-audio-warning-toast__content`;let d=document.createElement(`span`);d.className=`vidtreo-audio-warning-toast__title`,d.textContent=a.title;let f=document.createElement(`span`);if(f.className=`vidtreo-audio-warning-toast__message`,f.textContent=a.message,u.appendChild(d),u.appendChild(f),c.appendChild(u),i===`critical`||r.code===`audio.no-signal`){let e=document.createElement(`button`);e.className=`vidtreo-audio-warning-toast__dismiss`,e.type=`button`,e.setAttribute(`aria-label`,this.i18n.t(`audioWarningDismiss`)),e.innerHTML=`<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" viewBox="0 0 256 256"><path d="M205.66,194.34a8,8,0,0,1-11.32,11.32L128,139.31,61.66,205.66a8,8,0,0,1-11.32-11.32L116.69,128,50.34,61.66A8,8,0,0,1,61.66,50.34L128,116.69l66.34-66.35a8,8,0,0,1,11.32,11.32L139.31,128Z"/></svg>`,e.addEventListener(`click`,e=>{e.preventDefault(),e.stopPropagation(),this.updateState({audioWarning:null})}),c.appendChild(e)}r.code===`audio.low-signal`&&(this.audioWarningAutoDismissId=window.setTimeout(()=>{this.audioWarningAutoDismissId=null,this.updateState({audioWarning:null})},6e3)),s.appendChild(c)}clearAudioWarningAutoDismiss(){this.audioWarningAutoDismissId!==null&&(window.clearTimeout(this.audioWarningAutoDismissId),this.audioWarningAutoDismissId=null)}resolveAudioWarningSeverity(e){return e===`audio.track-ended`||e===`audio.track-muted-by-browser`||e===`audio.no-chunks`?`critical`:`soft`}resolveAudioWarningCopy(e){switch(e){case`audio.no-signal`:return{title:this.i18n.t(`audioWarningNoSignalTitle`),message:this.i18n.t(`audioWarningNoSignalMessage`)};case`audio.low-signal`:return{title:this.i18n.t(`audioWarningLowSignalTitle`),message:this.i18n.t(`audioWarningLowSignalMessage`)};case`audio.speaking-while-muted`:return{title:this.i18n.t(`audioWarningSpeakingMutedTitle`),message:this.i18n.t(`audioWarningSpeakingMutedMessage`)};case`audio.track-ended`:return{title:this.i18n.t(`audioWarningTrackEndedTitle`),message:this.i18n.t(`audioWarningTrackEndedMessage`)};case`audio.no-chunks`:return{title:this.i18n.t(`audioWarningNoChunksTitle`),message:this.i18n.t(`audioWarningNoChunksMessage`)};case`audio.track-muted-by-browser`:return{title:this.i18n.t(`audioWarningTrackMutedTitle`),message:this.i18n.t(`audioWarningTrackMutedMessage`)};default:return{title:``,message:``}}}getAudioWarningIcon(e){return e===`critical`?`<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 256 256"><path d="M213.92,210.62a8,8,0,1,1-11.84,10.76L176,193.63V200a48,48,0,0,1-83.43,32.45A47.84,47.84,0,0,1,80,200V176a8,8,0,0,1,16,0v24a32,32,0,0,0,55.12,22.13L120,188.68V200a8,8,0,0,1-16,0V172.67l-16-17.6V200a8,8,0,0,1-16,0V138.27l-16-17.6V144a8,8,0,0,1-16,0V104.67L42.08,45.38A8,8,0,1,1,53.92,34.62ZM176,152V80A48,48,0,0,0,82.33,60.89l13.73,15.1A32,32,0,0,1,160,80v56.67Z"/></svg>`:`<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 256 256"><path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm-8,80V80a8,8,0,0,1,16,0v24a8,8,0,0,1-16,0Zm20,52a12,12,0,1,1-12-12A12,12,0,0,1,140,156Z"/></svg>`}renderDeviceErrorOverlay(){let e=this.shadowRoot;if(!e)return;let t=e.querySelector(`.vidtreo-audio-error-overlay`),n=oS({errorCode:this.state.errorCode,hasAudioFailed:this.state.hasAudioFailed,error:this.state.error}),r=n.variant===`generic`;if(!(n.visible&&(r||this.state.recordingState===`idle`))){t&&t.remove();return}let i=r&&!n.actionableCode&&this.state.error?this.state.error:null,a=`${n.variant}|${n.actionableCode||``}|${i||``}`;if(t&&t.dataset.signature===a)return;t&&t.remove();let o=e.querySelector(`.vidtreo-preview-container`);if(!o)return;let s=this.getDeviceErrorIcon(n.variant),c=n.variant===`audio`?this.resolveAudioOverlayCopy(this.state.errorCode):null,l=n.variant===`camera`?this.resolveCameraOverlayCopy(this.state.errorCode):null,u=n.actionableCode?this.resolveRecordingOverlayCopy(n.actionableCode):null,d=this.resolveDeviceErrorOverlayCopy(n.variant,i,c,l,u);t=document.createElement(`div`),t.className=`vidtreo-audio-error-overlay`,t.dataset.variant=n.variant,t.dataset.signature=a;let f=document.createElement(`div`);f.className=`vidtreo-audio-error-icon`,f.innerHTML=s,t.appendChild(f);let p=document.createElement(`h3`);p.className=`vidtreo-audio-error-title`,p.textContent=d.title,t.appendChild(p);let m=document.createElement(`p`);m.className=`vidtreo-audio-error-message`,m.textContent=d.message,t.appendChild(m);let h=null;if(n.canRetry){h=document.createElement(`button`),h.className=`vidtreo-audio-error-retry`,h.type=`button`,h.innerHTML=`<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 256 256">
13387
13387
  <path d="M240,56v48a8,8,0,0,1-8,8H184a8,8,0,0,1,0-16h28.69L187.8,71.11A88,88,0,0,0,40.36,98.72,8,8,0,1,1,24.64,93.28,104,104,0,0,1,198.13,60.87L224,86.75V56a8,8,0,0,1,16,0ZM215.36,157.28a88,88,0,0,1-147.44,27.61L43.31,160H72a8,8,0,0,0,0-16H24a8,8,0,0,0-8,8v48a8,8,0,0,0,16,0V169.25l25.87,25.88A104,104,0,0,0,231.36,162.72a8,8,0,0,1-16,5.44Z"/>
13388
13388
  </svg>`;let e=document.createElement(`span`);e.textContent=d.retryLabel,h.appendChild(e),t.appendChild(h)}h&&h.addEventListener(`click`,e=>{e.preventDefault(),e.stopPropagation(),t?.remove(),this.updateState({hasAudioFailed:!1,errorCode:null,error:null}),this.startPreview().catch(e=>{})}),o.appendChild(t)}resolveDeviceErrorOverlayCopy(e,t,n,r,i){return n||r||i||{title:this.getDeviceErrorTitle(e),message:t||this.getDeviceErrorMessage(e),retryLabel:this.i18n.t(`errorRetry`)}}getDeviceErrorIcon(e){switch(e){case`audio`:return`<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" fill="currentColor" viewBox="0 0 256 256">
13389
13389
  <path d="M213.92,210.62a8,8,0,1,1-11.84,10.76L176,193.63V200a48,48,0,0,1-83.43,32.45A47.84,47.84,0,0,1,80,200V176a8,8,0,0,1,16,0v24a32,32,0,0,0,55.12,22.13L120,188.68V200a8,8,0,0,1-16,0V172.67l-16-17.6V200a8,8,0,0,1-16,0V138.27l-16-17.6V144a8,8,0,0,1-16,0V104.67L42.08,45.38A8,8,0,1,1,53.92,34.62ZM176,152V80A48,48,0,0,0,82.33,60.89l13.73,15.1A32,32,0,0,1,160,80v56.67Z"/>