@vidtreo/recorder-wc 1.6.4 → 1.7.1

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&&=Ad(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??uf,d=await bf(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 Zf(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 Zf(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 Uf(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 Sd?e:typeof VideoFrame<`u`&&e instanceof VideoFrame?new Sd(e):new Sd(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 Uf(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??uf,o=await vf(d,{numberOfChannels:t.process&&t.processedNumberOfChannels?t.processedNumberOfChannels:c,sampleRate:t.process&&t.processedSampleRate?t.processedSampleRate:l,bitrate:a});if(!o.some(e=>Ii.includes(e))&&d.some(e=>Ii.includes(e))&&(c!==pv||l!==mv)){let e=(await vf(d,{numberOfChannels:pv,sampleRate:mv,bitrate:a})).find(e=>Ii.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 tp(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&&qd(i.format)!==e.sampleFormat&&(i=Yd(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 Vd))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 tp(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:()=>Yu,ALL_FORMATS:()=>$u,ALL_TRACK_TYPES:()=>nv,AUDIO_CODECS:()=>Li,AdtsInputFormat:()=>zu,AdtsOutputFormat:()=>Z_,AppendOnlyStreamTarget:()=>gg,AttachedFile:()=>xi,AudioBufferSink:()=>np,AudioBufferSource:()=>C_,AudioSample:()=>Vd,AudioSampleResource:()=>Bd,AudioSampleSink:()=>tp,AudioSampleSource:()=>S_,AudioSource:()=>y_,BaseMediaSampleSink:()=>Gf,BlobSource:()=>ru,BufferSource:()=>nu,BufferTarget:()=>fg,CanvasSink:()=>Qf,CanvasSource:()=>__,CmafOutputFormat:()=>W_,ConcurrentRunner:()=>vi,Conversion:()=>hv,ConversionCanceledError:()=>gv,CustomAudioDecoder:()=>Tf,CustomAudioEncoder:()=>Df,CustomPathedSource:()=>tu,CustomVideoDecoder:()=>wf,CustomVideoEncoder:()=>Ef,EncodedAudioPacketSource:()=>b_,EncodedPacket:()=>R,EncodedPacketSink:()=>Uf,EncodedVideoPacketSource:()=>d_,EventEmitter:()=>gi,FLAC:()=>Xu,FilePathSource:()=>cu,FilePathTarget:()=>_g,FlacInputFormat:()=>Ru,FlacOutputFormat:()=>Q_,HLS:()=>Qu,HLS_FORMATS:()=>ed,HlsInputFormat:()=>Vu,HlsOutputFormat:()=>ev,Input:()=>vp,InputAudioTrack:()=>sp,InputDisposedError:()=>bp,InputFormat:()=>ku,InputTrack:()=>ip,InputVideoTrack:()=>op,IsobmffInputFormat:()=>Au,IsobmffOutputFormat:()=>H_,MATROSKA:()=>Wu,MP3:()=>Ku,MP4:()=>Hu,MPEG_TS:()=>Zu,MatroskaInputFormat:()=>Nu,MediaSource:()=>c_,MediaStreamAudioTrackSource:()=>w_,MediaStreamVideoTrackSource:()=>v_,MkvOutputFormat:()=>K_,MovOutputFormat:()=>G_,Mp3InputFormat:()=>Fu,Mp3OutputFormat:()=>J_,Mp4InputFormat:()=>ju,Mp4OutputFormat:()=>U_,MpegTsInputFormat:()=>Bu,MpegTsOutputFormat:()=>$_,NON_PCM_AUDIO_CODECS:()=>Ii,NullTarget:()=>vg,OGG:()=>Ju,OggInputFormat:()=>Lu,OggOutputFormat:()=>X_,Output:()=>lv,OutputAudioTrack:()=>av,OutputFormat:()=>V_,OutputSubtitleTrack:()=>ov,OutputTrack:()=>rv,OutputTrackGroup:()=>sv,OutputVideoTrack:()=>iv,PCM_AUDIO_CODECS:()=>Fi,PathedSource:()=>$l,PathedTarget:()=>bg,QTFF:()=>Uu,QUALITY_HIGH:()=>uf,QUALITY_LOW:()=>cf,QUALITY_MEDIUM:()=>lf,QUALITY_VERY_HIGH:()=>df,QUALITY_VERY_LOW:()=>sf,Quality:()=>of,QuickTimeInputFormat:()=>Mu,RangedSource:()=>pu,RangedTarget:()=>yg,ReadableStreamSource:()=>uu,RichImageData:()=>bi,SUBTITLE_CODECS:()=>Ri,Source:()=>Zl,SourceRef:()=>Ql,StreamSource:()=>lu,StreamTarget:()=>hg,SubtitleSource:()=>M_,Target:()=>lg,TextSubtitleSource:()=>N_,UnsupportedInputFormatError:()=>yp,UrlSource:()=>su,VIDEO_CODECS:()=>L,VIDEO_SAMPLE_PIXEL_FORMATS:()=>bd,VideoSample:()=>Sd,VideoSampleColorSpace:()=>Od,VideoSampleResource:()=>yd,VideoSampleSink:()=>Zf,VideoSampleSource:()=>g_,VideoSource:()=>l_,WAVE:()=>qu,WEBM:()=>Gu,WavOutputFormat:()=>Y_,WaveInputFormat:()=>Iu,WebMInputFormat:()=>Pu,WebMOutputFormat:()=>q_,asc:()=>cp,canDecode:()=>sd,canDecodeAudio:()=>ld,canDecodeVideo:()=>cd,canEncode:()=>ff,canEncodeAudio:()=>mf,canEncodeSubtitles:()=>hf,canEncodeVideo:()=>pf,desc:()=>lp,getDecodableAudioCodecs:()=>fd,getDecodableCodecs:()=>ud,getDecodableVideoCodecs:()=>dd,getEncodableAudioCodecs:()=>vf,getEncodableCodecs:()=>gf,getEncodableSubtitleCodecs:()=>yf,getEncodableVideoCodecs:()=>_f,getFirstEncodableAudioCodec:()=>xf,getFirstEncodableSubtitleCodec:()=>Sf,getFirstEncodableVideoCodec:()=>bf,prefer:()=>up,registerDecoder:()=>Mf,registerEncoder:()=>Nf,registerVideoSampleTransformer:()=>wd}),xv,Sv=n((()=>{uv(),tv(),P_(),ma(),pd(),Cf(),xg(),F(),mu(),nd(),xp(),mp(),Lo(),Xd(),rp(),yv(),Pf(),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 ru(e),n=new vp({formats:[Hu],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(){return typeof navigator>`u`?null:navigator.mediaCapabilities}function Nv(e){let t=e.toLowerCase();return t.startsWith(`avc1`)||t.startsWith(`av01`)||t.startsWith(`hvc1`)||t.startsWith(`hev1`)?`video/mp4;codecs="${e}"`:t===`vp8`||t.startsWith(`vp09`)||t.startsWith(`vp9`)?`video/webm;codecs="${e}"`:null}function Pv(e){let t=Mv();if(!t)return Promise.resolve(null);let n=Nv(e.codec);return n===null||typeof e.bitrate!=`number`||typeof e.framerate!=`number`?Promise.resolve(null):t.encodingInfo({type:`record`,video:{contentType:n,width:e.width,height:e.height,bitrate:e.bitrate,framerate:e.framerate}})}function Fv(e){return globalThis.VideoEncoder===void 0?Promise.resolve({config:e,supported:!1}):globalThis.VideoEncoder.isConfigSupported(e)}function Iv(e){return{navigatorProvider:e?.navigatorProvider??Ov(),secureContextProvider:e?.secureContextProvider??kv,mediaRecorderAvailabilityProvider:e?.mediaRecorderAvailabilityProvider??Av,videoEncoderAvailabilityProvider:e?.videoEncoderAvailabilityProvider??jv,codecSupportProbe:e?.codecSupportProbe??Fv,encodingCapabilityProbe:e?.encodingCapabilityProbe??Pv}}function Lv(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 Rv(e){return e instanceof Error?e.message:String(e)}async function zv(e,t,n){try{let r=await t(e.config),i=await Bv(e.config,n),a={id:e.id,config:e.config,supported:r.supported===!0};return i===void 0?a:{...a,encodingCapability:i}}catch(t){return{id:e.id,config:e.config,supported:!1,errorCode:`codec-probe-error`,errorMessage:Rv(t)}}}function Bv(e,t){return Promise.resolve().then(()=>t(e)).then(e=>{if(e!==null)return{supported:e.supported===!0,smooth:e.smooth===!0,powerEfficient:e.powerEfficient===!0}}).catch(e=>({supported:!1,smooth:!1,powerEfficient:!1,errorCode:`encoding-capability-probe-error`,errorMessage:Rv(e)}))}async function Vv(e={}){let t=Iv(e.dependencies),{browser:n,os:r}=Lv(t.navigatorProvider?.userAgent),i=await Promise.all((e.codecCandidates??[]).map(e=>zv(e,t.codecSupportProbe,t.encodingCapabilityProbe)));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 Hv(e,t){let n=e.resources.deviceMemory;return n===void 0||n>=t}function Uv(e,t){let n=e.resources.hardwareConcurrency;return n===void 0||n>=t}function Wv(e,t){let n=new Set(t);return e.codecProbeResults.find(e=>n.has(e.id)&&e.supported)}function Gv(e,t){return e.features.isSecureContext&&e.features.hasMediaRecorder&&e.features.hasVideoEncoder&&t&&e.network.online!==!1}function Kv(e,t,n,r,i,a,o){let s=[];return e.features.isSecureContext||s.push(`insecure-context`),e.features.hasVideoEncoder||s.push(`webcodecs-unavailable`),t||s.push(`target-codec-unsupported`),n||s.push(`insufficient-device-memory`),r||s.push(`insufficient-hardware-concurrency`),i||s.push(`encoding-capability-unsupported`),a||s.push(`encoding-not-smooth`),o||s.push(`encoding-not-power-efficient`),s}function qv(e){let t=[];return e.features.hasMediaRecorder||t.push(`mediarecorder-unavailable`),e.network.online===!1&&t.push(`offline`),t}function Jv(e){let t=e?.encodingCapability;return t===void 0||t.errorCode!==void 0||t.supported===!0}function Yv(e){let t=e?.encodingCapability;return t===void 0||t.errorCode!==void 0||t.supported!==!0||t.smooth===!0}function Xv(e){let t=e?.encodingCapability;return t===void 0||t.errorCode!==void 0||t.supported!==!0||t.powerEfficient===!0}function Zv(e){let t=e.resourceThresholds?.minDeviceMemory??4,n=e.resourceThresholds?.minHardwareConcurrency??5,r=Wv(e.profile,e.targetCodecIds),i=r?.id,a=i!==void 0,o=Hv(e.profile,t),s=Uv(e.profile,n),c=Jv(r),l=Yv(r),u=Xv(r),d=Kv(e.profile,a,o,s,c,l,u);return e.profile.features.isSecureContext&&e.profile.features.hasVideoEncoder&&a&&e.profile.network.online!==!1&&o&&s&&c&&l&&u?{route:`local-webcodecs`,reasonCodes:[`webcodecs-supported`,`target-codec-supported`],selectedCodecId:i}:Gv(e.profile,a)?{route:`safe-capture-post-recording-transcode`,reasonCodes:[...d,`mediarecorder-supported`],selectedCodecId:i}:{route:`unsupported-with-guidance`,reasonCodes:[...d,...qv(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 Qv=[`prefer-hardware`,`no-preference`,`prefer-software`];async function $v(){let e=(await Promise.allSettled([Promise.resolve().then(()=>(Sv(),bv))]))[0];return e.status===`fulfilled`?e.value:null}let ey={loadMediabunnyModule:$v};function ty(e){let t=e?.loadMediabunnyModule,n;return n=t===void 0?ey.loadMediabunnyModule:t,{loadMediabunnyModule:n}}function ny(e,t){return t===void 0||e.includes(t)?e:[...e,t]}function ry(e,t){let n=[];e!==void 0&&t.videoCodecFallbackOrder.includes(e)&&(n=ny(n,e)),n=ny(n,t.preferredVideoCodec);for(let e of t.videoCodecFallbackOrder)n=ny(n,e);return n}function iy(e,t){let n=[];e!==void 0&&t.audioCodecFallbackOrder.includes(e)&&(n=ny(n,e)),n=ny(n,t.preferredAudioCodec);for(let e of t.audioCodecFallbackOrder)n=ny(n,e);return n}function ay(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 oy(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 sy(e){let t=await ty(e.dependencies).loadMediabunnyModule();if(t===null)return e.policy.preferredVideoCodec;let n=t.canEncodeVideo;if(typeof n!=`function`)return e.policy.preferredVideoCodec;let r=ry(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 Qv){let t={...a,hardwareAcceleration:e},i=await Promise.all(r.map(e=>oy(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 ay(e.format,r,s)}async function cy(e){let t=await ty(e.dependencies).loadMediabunnyModule();if(t===null)return e.policy.preferredAudioCodec;let n=t.getFirstEncodableAudioCodec;if(typeof n!=`function`)return e.policy.preferredAudioCodec;let r=iy(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 ly(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 uy(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 dy(e){if(typeof e==`string`)return new cu(e);if(e instanceof Blob)return new ru(e);throw Error(`Invalid input type. Expected Blob, File, or file path string.`)}function fy(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 py(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 my(e){if(!e.isValid){let t=e.discardedTracks.map(e=>e.reason).join(`, `);throw Error(`Conversion is invalid. Discarded tracks: ${t}`)}}async function hy(e,t={},n){let r=t.format;r===void 0&&(r=Xt.format);let i={...Xt,...t,format:r},a=dy(e),o=Ht(i.format,{isLinuxPlatform:on()});i.audioBitrate===void 0&&(i.audioBitrate=Kt(i.format)),i.audioCodec=await cy({format:i.format,overrideCodec:i.audioCodec,policy:o,bitrate:i.audioBitrate}),i.codec=await sy({format:i.format,overrideCodec:i.codec,policy:o,width:i.width,height:i.height,bitrate:i.bitrate});let s=new vp({formats:$u,source:a}),c=new lv({format:fy(i.format),target:new fg}),l=await hv.init({input:s,output:c,...py(i)});my(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=ly(i.format);return{buffer:u,blob:new Blob([u],{type:d})}}async function gy(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 cy({format:i.format,overrideCodec:i.audioCodec,policy:a,bitrate:i.audioBitrate}),i.codec=await sy({format:i.format,overrideCodec:i.codec,policy:a,width:i.width,height:i.height,bitrate:i.bitrate});let o=new vp({formats:$u,source:new ru(e)}),s=new lv({format:fy(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}});my(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=ly(i.format);return{buffer:l,blob:new Blob([l],{type:u})}}function _y(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 vy=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 _y(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 gy(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 Zv({profile:await Vv({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 yy={isLinuxPlatform:on()};Ht(`mp4`,yy).preferredAudioCodec,Ht(`mov`,yy).preferredAudioCodec,Ht(`mkv`,yy).preferredAudioCodec,Ht(`webm`,yy).preferredAudioCodec;let by=`recording.invalid-container-layout`,xy=`recording.no-video-track`,Sy=`recording.no-audio-track`,Cy=`moov`,wy=`trak`,Ty=`stsz`,Ey=`soun`;function Dy(e){return e>=6e3&&e<=384e3}function Oy(e){let t=Error(by);return t.code=by,t.detectedBoxTypes=e,t}function ky(e){let t=Error(e);return t.code=e,t}function Ay(e){return e instanceof Uint8Array?e:new Uint8Array(e)}function jy(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 My(e,t){let n=e.getUint32(t,!1),r=e.getUint32(t+4,!1);return n*4294967296+r}function Ny(e){let t=new Set;for(let n of e)t.add(n);return[...t]}function Py(e,t,n){let r=new DataView(e.buffer,e.byteOffset,e.byteLength),i=[],a=t;for(;a<n;){if(!(a+8<=n))throw Oy(i.map(e=>e.type));let e=r.getUint32(a,!1),t=jy(r,a+4),o=e,s=8;if(e===1){let e=a+8;if(!(e+8<=n))throw Oy(i.map(e=>e.type));o=My(r,e),s=16}if(e===0&&(o=n-a),!(o>=s))throw Oy(i.map(e=>e.type));let c=a+o;if(!(c<=n))throw Oy(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 Fy(e,t){for(let n of e)if(n.type===t)return n;return null}function Iy(e,t,n){if(!(t+4<=n))throw Oy([]);return jy(e,t)}function Ly(e,t){let n=Fy(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 Ry(e,t){let n=Fy(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 zy(e,t,n){let r=new DataView(e.buffer,e.byteOffset,e.byteLength),i=Fy(Py(e,t.payloadStartOffset,t.endOffset),`mdia`);if(i===null)return{isMatchingTrack:!1,sampleCount:0,channelCount:0,sampleRate:0,durationSeconds:0};let a=Py(e,i.payloadStartOffset,i.endOffset),o=Fy(a,`hdlr`);if(o===null||Iy(r,o.payloadStartOffset+8,o.endOffset)!==n)return{isMatchingTrack:!1,sampleCount:0,channelCount:0,sampleRate:0,durationSeconds:0};let s=Ly(r,a),c=Fy(a,`minf`);if(c===null)return{isMatchingTrack:!0,sampleCount:0,channelCount:0,sampleRate:0,durationSeconds:s};let l=Fy(Py(e,c.payloadStartOffset,c.endOffset),`stbl`);if(l===null)return{isMatchingTrack:!0,sampleCount:0,channelCount:0,sampleRate:0,durationSeconds:s};let u=Py(e,l.payloadStartOffset,l.endOffset),d=Fy(u,Ty);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 Oy([Ty]);return{isMatchingTrack:!0,sampleCount:r.getUint32(f,!1),...n===Ey?Ry(r,u):{channelCount:0,sampleRate:0},durationSeconds:s}}function By(e){let t=Ay(e),n=t.byteLength,r=new DataView(t.buffer,t.byteOffset,t.byteLength),i=[],a=0;for(;a<n;){if(!(a+8<=n))throw Oy(i.map(e=>e.type));let e=r.getUint32(a,!1),t=jy(r,a+4),o=e,s=8;if(e===1){let e=a+8;if(!(e+8<=n))throw Oy(i.map(e=>e.type));o=My(r,e),s=16}if(e===0&&(o=n-a),!(o>=s))throw Oy(i.map(e=>e.type));let c=a+o;if(!(c<=n))throw Oy(i.map(e=>e.type));i.push({type:t,size:o,startOffset:a,endOffset:c}),a=c}return i}function Vy(e){let t=By(e).filter(e=>e.type===`moof`||e.type===`mfra`).map(e=>e.type);if(t.length>0)throw Oy(Ny(t))}function Hy(e){let t=Ay(e),n=Fy(Py(t,0,t.byteLength),Cy);if(n===null)throw ky(xy);let r=Py(t,n.payloadStartOffset,n.endOffset).filter(e=>e.type===wy);if(r.length===0)throw ky(xy);let i=!1;for(let e of r){let n=zy(t,e,`vide`);if(n.isMatchingTrack&&(i=!0,n.sampleCount>0))return}throw ky(i?`recording.no-video-frames`:xy)}function Uy(e){let t=Ay(e),n=Fy(Py(t,0,t.byteLength),Cy);if(n===null)throw ky(Sy);let r=Py(t,n.payloadStartOffset,n.endOffset).filter(e=>e.type===wy);if(r.length===0)throw ky(Sy);let i=!1;for(let e of r){let n=zy(t,e,Ey);if(n.isMatchingTrack&&(i=!0,n.sampleCount!==0)){if(n.channelCount===0)throw ky(`recording.audio-zero-channels`);if(!Dy(n.sampleRate))throw ky(`recording.audio-invalid-sample-rate`);return}}throw ky(i?`recording.no-audio-frames`:Sy)}function Wy(){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 ru(e),n=new vp({formats:[Hu],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(){return typeof navigator>`u`?null:navigator.mediaCapabilities}function Nv(e){let t=e.toLowerCase();return t.startsWith(`avc1`)||t.startsWith(`av01`)||t.startsWith(`hvc1`)||t.startsWith(`hev1`)?`video/mp4;codecs="${e}"`:t===`vp8`||t.startsWith(`vp09`)||t.startsWith(`vp9`)?`video/webm;codecs="${e}"`:null}function Pv(e){let t=Mv();if(!t)return Promise.resolve(null);let n=Nv(e.codec);return n===null||typeof e.bitrate!=`number`||typeof e.framerate!=`number`?Promise.resolve(null):t.encodingInfo({type:`record`,video:{contentType:n,width:e.width,height:e.height,bitrate:e.bitrate,framerate:e.framerate}})}function Fv(e){return globalThis.VideoEncoder===void 0?Promise.resolve({config:e,supported:!1}):globalThis.VideoEncoder.isConfigSupported(e)}function Iv(e){return{navigatorProvider:e?.navigatorProvider??Ov(),secureContextProvider:e?.secureContextProvider??kv,mediaRecorderAvailabilityProvider:e?.mediaRecorderAvailabilityProvider??Av,videoEncoderAvailabilityProvider:e?.videoEncoderAvailabilityProvider??jv,codecSupportProbe:e?.codecSupportProbe??Fv,encodingCapabilityProbe:e?.encodingCapabilityProbe??Pv}}function Lv(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 Rv(e){return e instanceof Error?e.message:String(e)}async function zv(e,t,n){try{let r=await t(e.config),i=await Bv(e.config,n),a={id:e.id,config:e.config,supported:r.supported===!0};return i===void 0?a:{...a,encodingCapability:i}}catch(t){return{id:e.id,config:e.config,supported:!1,errorCode:`codec-probe-error`,errorMessage:Rv(t)}}}function Bv(e,t){return Promise.resolve().then(()=>t(e)).then(e=>{if(e!==null)return{supported:e.supported===!0,smooth:e.smooth===!0,powerEfficient:e.powerEfficient===!0}}).catch(e=>({supported:!1,smooth:!1,powerEfficient:!1,errorCode:`encoding-capability-probe-error`,errorMessage:Rv(e)}))}async function Vv(e={}){let t=Iv(e.dependencies),{browser:n,os:r}=Lv(t.navigatorProvider?.userAgent),i=await Promise.all((e.codecCandidates??[]).map(e=>zv(e,t.codecSupportProbe,t.encodingCapabilityProbe)));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 Hv(e,t){let n=e.resources.deviceMemory;return n===void 0||n>=t}function Uv(e,t){let n=e.resources.hardwareConcurrency;return n===void 0||n>=t}function Wv(e,t){let n=new Set(t);return e.codecProbeResults.find(e=>n.has(e.id)&&e.supported)}function Gv(e,t){return e.features.isSecureContext&&e.features.hasMediaRecorder&&e.features.hasVideoEncoder&&t&&e.network.online!==!1}function Kv(e,t,n,r,i,a,o){let s=[];return e.features.isSecureContext||s.push(`insecure-context`),e.features.hasVideoEncoder||s.push(`webcodecs-unavailable`),t||s.push(`target-codec-unsupported`),n||s.push(`insufficient-device-memory`),r||s.push(`insufficient-hardware-concurrency`),i||s.push(`encoding-capability-unsupported`),a||s.push(`encoding-not-smooth`),o||s.push(`encoding-not-power-efficient`),s}function qv(e){let t=[];return e.features.hasMediaRecorder||t.push(`mediarecorder-unavailable`),e.network.online===!1&&t.push(`offline`),t}function Jv(e){return e.os.name.toLowerCase().includes(`android`)}function Yv(e,t){let n=[...t];return Jv(e)&&n.push(`android-post-recording-transcode`),n.push(`mediarecorder-supported`),n}function Xv(e){let t=e?.encodingCapability;return t===void 0||t.errorCode!==void 0||t.supported===!0}function Zv(e){let t=e?.encodingCapability;return t===void 0||t.errorCode!==void 0||t.supported!==!0||t.smooth===!0}function Qv(e){let t=e?.encodingCapability;return t===void 0||t.errorCode!==void 0||t.supported!==!0||t.powerEfficient===!0}function $v(e){let t=e.resourceThresholds?.minDeviceMemory??4,n=e.resourceThresholds?.minHardwareConcurrency??5,r=Wv(e.profile,e.targetCodecIds),i=r?.id,a=i!==void 0,o=Hv(e.profile,t),s=Uv(e.profile,n),c=Xv(r),l=Zv(r),u=Qv(r),d=Kv(e.profile,a,o,s,c,l,u);return Jv(e.profile)&&Gv(e.profile,a)?{route:`safe-capture-post-recording-transcode`,reasonCodes:Yv(e.profile,d),selectedCodecId:i}:e.profile.features.isSecureContext&&e.profile.features.hasVideoEncoder&&a&&e.profile.network.online!==!1&&o&&s&&c&&l&&u?{route:`local-webcodecs`,reasonCodes:[`webcodecs-supported`,`target-codec-supported`],selectedCodecId:i}:Gv(e.profile,a)?{route:`safe-capture-post-recording-transcode`,reasonCodes:Yv(e.profile,d),selectedCodecId:i}:{route:`unsupported-with-guidance`,reasonCodes:[...d,...qv(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 ey=[`prefer-hardware`,`no-preference`,`prefer-software`];async function ty(){let e=(await Promise.allSettled([Promise.resolve().then(()=>(Sv(),bv))]))[0];return e.status===`fulfilled`?e.value:null}let ny={loadMediabunnyModule:ty};function ry(e){let t=e?.loadMediabunnyModule,n;return n=t===void 0?ny.loadMediabunnyModule:t,{loadMediabunnyModule:n}}function iy(e,t){return t===void 0||e.includes(t)?e:[...e,t]}function ay(e,t){let n=[];e!==void 0&&t.videoCodecFallbackOrder.includes(e)&&(n=iy(n,e)),n=iy(n,t.preferredVideoCodec);for(let e of t.videoCodecFallbackOrder)n=iy(n,e);return n}function oy(e,t){let n=[];e!==void 0&&t.audioCodecFallbackOrder.includes(e)&&(n=iy(n,e)),n=iy(n,t.preferredAudioCodec);for(let e of t.audioCodecFallbackOrder)n=iy(n,e);return n}function sy(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 cy(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 ly(e){let t=await ry(e.dependencies).loadMediabunnyModule();if(t===null)return e.policy.preferredVideoCodec;let n=t.canEncodeVideo;if(typeof n!=`function`)return e.policy.preferredVideoCodec;let r=ay(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 ey){let t={...a,hardwareAcceleration:e},i=await Promise.all(r.map(e=>cy(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 sy(e.format,r,s)}async function uy(e){let t=await ry(e.dependencies).loadMediabunnyModule();if(t===null)return e.policy.preferredAudioCodec;let n=t.getFirstEncodableAudioCodec;if(typeof n!=`function`)return e.policy.preferredAudioCodec;let r=oy(e.overrideCodec,e.policy),i={};e.bitrate!==void 0&&(i.bitrate=e.bitrate),e.numberOfChannels!==void 0&&(i.numberOfChannels=e.numberOfChannels),e.sampleRate!==void 0&&(i.sampleRate=e.sampleRate);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 dy(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 fy(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 py(e){if(typeof e==`string`)return new cu(e);if(e instanceof Blob)return new ru(e);throw Error(`Invalid input type. Expected Blob, File, or file path string.`)}function my(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 hy(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 gy(e){if(!e.isValid){let t=e.discardedTracks.map(e=>e.reason).join(`, `);throw Error(`Conversion is invalid. Discarded tracks: ${t}`)}}async function _y(e,t={},n){let r=t.format;r===void 0&&(r=Xt.format);let i={...Xt,...t,format:r},a=py(e),o=Ht(i.format,{isLinuxPlatform:on()});i.audioBitrate===void 0&&(i.audioBitrate=Kt(i.format)),i.audioCodec=await uy({format:i.format,overrideCodec:i.audioCodec,policy:o,bitrate:i.audioBitrate}),i.codec=await ly({format:i.format,overrideCodec:i.codec,policy:o,width:i.width,height:i.height,bitrate:i.bitrate});let s=new vp({formats:$u,source:a}),c=new lv({format:my(i.format),target:new fg}),l=await hv.init({input:s,output:c,...hy(i)});gy(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=dy(i.format);return{buffer:u,blob:new Blob([u],{type:d})}}async function vy(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 uy({format:i.format,overrideCodec:i.audioCodec,policy:a,bitrate:i.audioBitrate}),i.codec=await ly({format:i.format,overrideCodec:i.codec,policy:a,width:i.width,height:i.height,bitrate:i.bitrate});let o=new vp({formats:$u,source:new ru(e)}),s=new lv({format:my(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}});gy(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=dy(i.format);return{buffer:l,blob:new Blob([l],{type:u})}}function yy(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 by=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 yy(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 vy(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 $v({profile:await Vv({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 xy={isLinuxPlatform:on()};Ht(`mp4`,xy).preferredAudioCodec,Ht(`mov`,xy).preferredAudioCodec,Ht(`mkv`,xy).preferredAudioCodec,Ht(`webm`,xy).preferredAudioCodec;let Sy=`recording.invalid-container-layout`,Cy=`recording.no-video-track`,wy=`recording.no-audio-track`,Ty=`moov`,Ey=`trak`,Dy=`stsz`,Oy=`soun`;function ky(e){return e>=6e3&&e<=384e3}function Ay(e){let t=Error(Sy);return t.code=Sy,t.detectedBoxTypes=e,t}function jy(e){let t=Error(e);return t.code=e,t}function My(e){return e instanceof Uint8Array?e:new Uint8Array(e)}function Ny(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 Py(e,t){let n=e.getUint32(t,!1),r=e.getUint32(t+4,!1);return n*4294967296+r}function Fy(e){let t=new Set;for(let n of e)t.add(n);return[...t]}function Iy(e,t,n){let r=new DataView(e.buffer,e.byteOffset,e.byteLength),i=[],a=t;for(;a<n;){if(!(a+8<=n))throw Ay(i.map(e=>e.type));let e=r.getUint32(a,!1),t=Ny(r,a+4),o=e,s=8;if(e===1){let e=a+8;if(!(e+8<=n))throw Ay(i.map(e=>e.type));o=Py(r,e),s=16}if(e===0&&(o=n-a),!(o>=s))throw Ay(i.map(e=>e.type));let c=a+o;if(!(c<=n))throw Ay(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 Ly(e,t){for(let n of e)if(n.type===t)return n;return null}function Ry(e,t,n){if(!(t+4<=n))throw Ay([]);return Ny(e,t)}function zy(e,t){let n=Ly(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 By(e,t){let n=Ly(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 Vy(e,t,n){let r=new DataView(e.buffer,e.byteOffset,e.byteLength),i=Ly(Iy(e,t.payloadStartOffset,t.endOffset),`mdia`);if(i===null)return{isMatchingTrack:!1,sampleCount:0,channelCount:0,sampleRate:0,durationSeconds:0};let a=Iy(e,i.payloadStartOffset,i.endOffset),o=Ly(a,`hdlr`);if(o===null||Ry(r,o.payloadStartOffset+8,o.endOffset)!==n)return{isMatchingTrack:!1,sampleCount:0,channelCount:0,sampleRate:0,durationSeconds:0};let s=zy(r,a),c=Ly(a,`minf`);if(c===null)return{isMatchingTrack:!0,sampleCount:0,channelCount:0,sampleRate:0,durationSeconds:s};let l=Ly(Iy(e,c.payloadStartOffset,c.endOffset),`stbl`);if(l===null)return{isMatchingTrack:!0,sampleCount:0,channelCount:0,sampleRate:0,durationSeconds:s};let u=Iy(e,l.payloadStartOffset,l.endOffset),d=Ly(u,Dy);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 Ay([Dy]);return{isMatchingTrack:!0,sampleCount:r.getUint32(f,!1),...n===Oy?By(r,u):{channelCount:0,sampleRate:0},durationSeconds:s}}function Hy(e){let t=My(e),n=t.byteLength,r=new DataView(t.buffer,t.byteOffset,t.byteLength),i=[],a=0;for(;a<n;){if(!(a+8<=n))throw Ay(i.map(e=>e.type));let e=r.getUint32(a,!1),t=Ny(r,a+4),o=e,s=8;if(e===1){let e=a+8;if(!(e+8<=n))throw Ay(i.map(e=>e.type));o=Py(r,e),s=16}if(e===0&&(o=n-a),!(o>=s))throw Ay(i.map(e=>e.type));let c=a+o;if(!(c<=n))throw Ay(i.map(e=>e.type));i.push({type:t,size:o,startOffset:a,endOffset:c}),a=c}return i}function Uy(e){let t=Hy(e).filter(e=>e.type===`moof`||e.type===`mfra`).map(e=>e.type);if(t.length>0)throw Ay(Fy(t))}function Wy(e){let t=My(e),n=Ly(Iy(t,0,t.byteLength),Ty);if(n===null)throw jy(Cy);let r=Iy(t,n.payloadStartOffset,n.endOffset).filter(e=>e.type===Ey);if(r.length===0)throw jy(Cy);let i=!1;for(let e of r){let n=Vy(t,e,`vide`);if(n.isMatchingTrack&&(i=!0,n.sampleCount>0))return}throw jy(i?`recording.no-video-frames`:Cy)}function Gy(e){let t=My(e),n=Ly(Iy(t,0,t.byteLength),Ty);if(n===null)throw jy(wy);let r=Iy(t,n.payloadStartOffset,n.endOffset).filter(e=>e.type===Ey);if(r.length===0)throw jy(wy);let i=!1;for(let e of r){let n=Vy(t,e,Oy);if(n.isMatchingTrack&&(i=!0,n.sampleCount!==0)){if(n.channelCount===0)throw jy(`recording.audio-zero-channels`);if(!ky(n.sampleRate))throw jy(`recording.audio-invalid-sample-rate`);return}}throw jy(i?`recording.no-audio-frames`:wy)}function Ky(){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 Gy(){let e=Wy();return URL.createObjectURL(e)}function Ky(e){URL.revokeObjectURL(e)}let qy=`probe`,Jy=`probeResult`,Yy=`mediaStreamTrackProcessor`,Xy=`unavailable`,Zy=`unavailable`,Qy=new Map,$y=new Map;function eb(e,t){return typeof e==`boolean`?e:t}function tb(e){return e?`1`:`0`}function nb(e,t){return[`audio`,tb(e),`watermark`,tb(t)].join(`|`)}function rb(){return typeof process>`u`||process.env,!0}function ib(e){return e.probeResult.hasMediaStreamTrackProcessor?`worker-track`:e.hasMainThreadMediaStreamTrackProcessor?`main-thread-stream`:Xy}function ab(e){return e.requiresAudio?e.hasMainThreadMediaStreamTrackProcessor&&e.probeResult.hasAudioData?`main-thread-audio-stream`:e.hasAudioContext&&e.hasAudioWorklet?`audio-worklet-chunks`:Zy:`none-required`}function ob(e,t){return e.includes(t)?e:[...e,t]}function sb(e,t){let n=e;return t.hasWorker||(n=ob(n,`worker`)),t.probeResult.hasVideoFrame||(n=ob(n,`videoFrame`)),t.probeResult.hasOffscreenCanvas||(n=ob(n,`offscreenCanvas`)),t.probeResult.hasReadableStream||(n=ob(n,`readableStream`)),n}function cb(e,t){let n=e;return t.requiresWatermark&&!t.probeResult.hasCreateImageBitmap&&(n=ob(n,`createImageBitmap`)),n}function lb(e,t){let n=e;return t.videoPath===Xy&&(n=ob(n,Yy)),n}function ub(e,t){let n=e;return t.hasMainThreadMediaStreamTrackProcessor&&t.probeResult.hasAudioData?n:(t.hasMainThreadMediaStreamTrackProcessor||(n=ob(n,Yy)),t.hasMainThreadMediaStreamTrackProcessor&&!t.probeResult.hasAudioData&&(n=ob(n,`audioData`)),n)}function db(e,t){let n=e;return t.hasAudioContext&&t.hasAudioWorklet?n:(t.hasAudioContext||(n=ob(n,`audioContext`)),t.hasAudioWorklet||(n=ob(n,`audioWorklet`)),n)}function fb(e,t){let n=e;return t.requiresAudio&&t.audioPath===Zy?(n=ub(n,t),n=db(n,t),n):n}function pb(e){let t=[];return t=sb(t,e),t=cb(t,e),t=lb(t,e),t=fb(t,e),t}function mb(e,t){return!(e===Xy||t===Zy)}function hb(e,t){return!(!e.hasVideoFrame||!e.hasOffscreenCanvas||!e.hasReadableStream||t&&!e.hasCreateImageBitmap)}async function gb(e={},t={}){let n=eb(e.requiresAudio,!0),r=eb(e.requiresWatermark,!1);if(!rb())return await _b(n,r,t);let i=nb(n,r),a=Qy.get(i);if(a)return a;let o=$y.get(i);if(o)return await o;let s=_b(n,r,t).then(e=>(Qy.set(i,e),$y.delete(i),e)).catch(e=>{throw $y.delete(i),e});return $y.set(i,s),await s}async function _b(e,t,n){let r=typeof Worker<`u`,i=a()!==null,o=typeof AudioWorkletNode<`u`,s=typeof MediaStreamTrackProcessor<`u`,c=await vb(r,n),l=ib({probeResult:c,hasMainThreadMediaStreamTrackProcessor:s}),u=ab({requiresAudio:e,hasAudioContext:i,hasAudioWorklet:o,hasMainThreadMediaStreamTrackProcessor:s,probeResult:c}),d=pb({hasWorker:r,hasAudioContext:i,hasAudioWorklet:o,hasMainThreadMediaStreamTrackProcessor:s,probeResult:c,requiresAudio:e,requiresWatermark:t,videoPath:l,audioPath:u}),f=mb(l,u),p=hb(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 vb(e,t){if(!e)return bb();let n=await yb().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(bb())},i);n.onmessage=e=>{let t=e.data;t.type===Jy&&(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(bb())},Promise.resolve().then(()=>{n.postMessage({type:qy})}).catch(()=>{clearTimeout(o),a(bb())})}):bb()}function yb(){return Promise.resolve().then(()=>{let e=Gy();try{let t=new Worker(e,{type:`classic`});return Ky(e),t}catch(t){throw Ky(e),t}})}function bb(){return{hasMediaStreamTrackProcessor:!1,hasVideoFrame:!1,hasAudioData:!1,hasOffscreenCanvas:!1,hasCreateImageBitmap:!1,hasReadableStream:!1}}let xb=`recording.audio-no-chunks`,Sb=`recording.audio-silent`,Cb=`recording.audio-track-ended`,wb=`audio.no-track-at-start`;function Tb(e,t){let n=Error(e);return n.code=e,t&&(n.details=t),n}function Eb(){let e=Error(wb);return e.code=wb,e}function Db(e){if(!(e instanceof Error))return!1;let t=e;return t.code===xb||t.code===Sb||t.code===Cb||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 Ob(e){return e.hadTrackEndedWarning?{ok:!1,code:Cb}:e.totalChunks===0?{ok:!1,code:xb}:e.nonSilentChunks===0&&(e.durationMs>0?e.mutedDurationMs/e.durationMs:0)<.9?{ok:!1,code:Sb}:{ok:!0}}let kb=`vidtreo-recorder`,Ab=`pending-uploads`,jb=`status`,Mb=`createdAt`,Nb=`Failed to prepare upload data for storage. The recorded file could not be read.`,Pb=`__probe__`,Fb=new ArrayBuffer(1);var Ib=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(kb):this.databaseFactory.open(kb,e)}initializeStoreSchema(e){if(e.objectStoreNames.contains(Ab))return;let t=e.createObjectStore(Ab,{keyPath:`id`});t.createIndex(jb,jb,{unique:!1}),t.createIndex(Mb,Mb,{unique:!1})}validateRequiredSchema(e){if(!e.objectStoreNames.contains(Ab))return Error(`Database schema is missing required object store: pending-uploads`);let t=e.transaction([Ab],`readonly`).objectStore(Ab);return t.indexNames.contains(jb)?t.indexNames.contains(Mb)?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:Pb,blobData:Fb,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(Pb);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(jb).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(`${Nb} ${e.message}`):Error(Nb)})}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([Ab],e),r=n.objectStore(Ab);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)})})}},Lb=class{constructor(){this.storageService=null,this.cleanupIntervalId=null,this.writeProbeResult=null}async initialize(e){this.storageService||=new Ib,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 Rb(){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 zb=Rb(),Bb={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 Vb(e,t,n){if(!zb)return``;let r=n?.prefix||`[${e.toUpperCase()}]`;return`${Bb[n?.color||Hb(e)]}${r}${Bb.reset} ${t}`}function Hb(e){switch(e){case`error`:return`red`;case`warn`:return`yellow`;case`info`:return`cyan`;case`debug`:return`gray`;default:return`white`}}function Ub(e,t,...n){if(!zb)return;let r=Vb(e,t);console[e](r,...n)}let $={log:(e,...t)=>{Ub(`log`,e,...t)},info:(e,...t)=>{Ub(`info`,e,...t)},warn:(e,...t)=>{Ub(`warn`,e,...t)},error:(e,...t)=>{Ub(`error`,e,...t)},debug:(e,...t)=>{Ub(`debug`,e,...t)},group:(e,t=`cyan`)=>{if(!zb)return;let n=Bb[t],r=Bb.reset;console.group(`${n}${e}${r}`)},groupEnd:()=>{zb&&console.groupEnd()}};function Wb(e,t){if(e==null)throw Error(t);return e}function Gb(e,t=`StreamProcessor`){if(!e)throw Error(`${t} is required`);return e}function Kb(){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 qb(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 Jb(e){let t={echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0};return e?{...t,deviceId:{exact:e}}:t}let Yb=`live`;function Xb(e){for(let t of e)t.readyState===Yb&&t.stop()}function Zb(e){Xb(e.getTracks())}function Qb(e){Xb(e.getVideoTracks())}function $b(e){return e?e.readyState===Yb:!1}function ex(e,t){return $b(e)&&$b(t)}function tx(e,t,n){if(!$b(e)){Zb(n);let r=`undefined`;throw e&&(r=e.readyState),Error(`Failed to get live camera ${t} track. ReadyState: ${r}`)}}let nx=`[SourceSwitchManager]`;var rx=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(`${nx} createCameraStreamWithOriginalAudio`,{hasOriginalCameraStream:!!t,originalCameraStreamId:t?.id,hasOriginalAudioTrack:!!n,originalAudioTrackId:n?.id,originalAudioTrackReadyState:n?.readyState,originalAudioTrackEnabled:n?.enabled,originalAudioTrackMuted:n?.muted,originalAudioTrackLabel:n?.label,isTrackLive:$b(n),cameraDeviceId:e}),!$b(n))return this.dependencies.logger.warn(`${nx} Original audio track is not live, cannot reuse`,{originalAudioTrackId:n?.id,originalAudioTrackReadyState:n?.readyState}),null;let r=qb(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(`${nx} Requesting new video stream`,{constraints:o,cameraDeviceId:e});let s=await Kb().getUserMedia(o),c=s.getVideoTracks()[0];tx(c,`video`,s),this.dependencies.logger.debug(`${nx} 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(`${nx} 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);Xb(s.getAudioTracks());let d=t?.id;return this.dependencies.setOriginalCameraStream(u),this.dependencies.logger.debug(`${nx} 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=qb(e,{originalCameraConstraints:this.dependencies.getOriginalCameraConstraints(),getSelectedCameraDeviceId:this.dependencies.getSelectedCameraDeviceId}),r=Jb(t),i=Object.keys(n).length>0,a=!0;i&&(a=n);let o={video:a,audio:r},s=await Kb().getUserMedia(o),c=s.getVideoTracks()[0],l=s.getAudioTracks()[0];return tx(c,`video`,s),tx(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()&&(Zb(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 ix=`screen`,ax=`No video track found in screen share stream`;async function ox(e,t,n){n.setScreenShareStream(e);let r=e.getVideoTracks()[0];if(!r)throw n.stopStreamTracks(e),Error(ax);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(ix),n.callbacks.onSourceChange&&await n.callbacks.onSourceChange(n.getCurrentSourceType()),sx(i,n),i}function sx(e,t){let n=e.getVideoTracks()[0];if(!n)throw Error(ax);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()===ix&&t.switchToCamera().catch(e=>{t.handleSwitchError(e)})};t.setScreenShareTrackEndHandler(i),n.addEventListener(`ended`,i)}function cx(e,t){let n=t.getScreenShareTrackEndHandler();if(!(n&&e))return;let r=e.getVideoTracks()[0];r&&r.removeEventListener(`ended`,n),t.setScreenShareTrackEndHandler(null)}function lx(e,t){e.onTransitionStart&&e.onTransitionStart(t)}function ux(e){e.onTransitionEnd&&e.onTransitionEnd()}function dx(e){e.onScreenSelectionStart&&e.onScreenSelectionStart()}function fx(e){e.onScreenSelectionEnd&&e.onScreenSelectionEnd()}function px(e){fx(e),ux(e)}let mx=`Failed to get camera stream`;var hx=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 rx({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];ex(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:$b(t),screenVideoTrackId:e.id,screenVideoTrackReadyState:e.readyState});let n=[e];$b(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)),lx(this.callbacks,`Select screen to share...`),dx(this.callbacks),Promise.resolve().then(async()=>{let t=Kb();if(typeof t.getDisplayMedia!=`function`)throw Error(`Screen sharing is not supported on this device`);return ox(await t.getDisplayMedia({video:!0,audio:!0}),e,this.getScreenShareDependencies())}).catch(e=>{if(px(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!(!ex(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=>Zb(e),stopStreamVideoTracks:e=>Qb(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()=>{lx(this.callbacks,`Switching to camera...`),await this.handleScreenShareStop();let t=await this.getCameraStream();if(!t)throw Error(mx);await this.applyCameraStream(t,e),ux(this.callbacks)}).catch(e=>{throw ux(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`&&$b(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}))}),cx(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}))}),Qb(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){ux(this.callbacks);return}lx(this.callbacks,`Switching to screen...`),await this.streamManager.switchVideoSource(e),this.callbacks.onPreviewUpdate&&await this.callbacks.onPreviewUpdate(e),ux(this.callbacks)}handleToggleError(e){ux(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&&(cx(e,this.getScreenShareDependencies()),Qb(e));let t=await this.getCameraStream();if(!t)throw Error(mx);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&&=(cx(this.screenShareStream,this.getScreenShareDependencies()),this.stopScreenShareStreamTracks(this.screenShareStream),null);let e=this.streamManager.getStream();e&&cx(e,this.getScreenShareDependencies()),this.screenShareTrackEndHandler=null,this.originalCameraStream=null,this.setOriginalCameraConstraints(null)}setCallbacks(e){this.callbacks={...this.callbacks,...e}}};let gx=Object.freeze({width:{ideal:Xt.width||1920},height:{ideal:Xt.height||1080},frameRate:{ideal:Xt.fps||30}}),_x=Object.freeze({video:gx,audio:!0});Object.freeze({mimeType:`video/webm;codecs=vp9,opus`});let vx={NotReadableError:`camera.in-use`,NotFoundError:`camera.not-found`,NotAllowedError:`camera.permission-denied`,OverconstrainedError:`camera.overconstrained`,TimeoutError:`camera.timeout`},yx={NotReadableError:`audio.in-use`,NotFoundError:`audio.not-found`,NotAllowedError:`audio.permission-denied`,OverconstrainedError:`audio.overconstrained`,TimeoutError:`audio.timeout`};function bx(e){return e instanceof DOMException||typeof e==`object`&&e&&`name`in e&&typeof e.name==`string`?e.name:null}function xx(e){return i(e).toLowerCase()}function Sx(e,t){let n=xx(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 Cx(e){let t=Sx(e,`camera`);if(t!==null)return t;let n=bx(e);if(n!==null){let e=vx[n];if(e!==void 0)return e}return`camera.unknown`}function wx(e){let t=Sx(e,`audio`);if(t!==null)return t;let n=bx(e);if(n!==null){let e=yx[n];if(e!==void 0)return e}return`audio.unknown`}function Tx(e){let t=i(e),n=Error(t);return n.name=`CameraError`,n.code=Cx(e),n}function Ex(e){let t=i(e),n=Error(t);return n.name=`AudioError`,n.code=wx(e),n}function Dx(e){return bx(e)===`NotReadableError`}function Ox(e){return new Promise(t=>setTimeout(t,e))}var kx=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={..._x,...e},this.waitMilliseconds=t.waitMilliseconds??Ox,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??Ex(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=Tx(e);throw $.error(`[StreamManager] Failed to start stream`,t),this.setState(`error`),this.emit(`error`,{error:t}),t}}async acquireVideoAndAudioStream(){let e=Kb(),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=bx(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`),Tx(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:Ex(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=bx(e),o=Dx(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 Ex(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 Kb().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 Ax=`recording.stop-not-ready`,jx=`recording.finalize-not-ready`,Mx=`recording.finalize-timeout`,Nx=`recording.upload-in-progress`;function Px(e,t,n){let r=Error(`${t} [${e}]`);return r.code=e,r.isRecoverable=!0,n!==void 0&&(r.details=n),r}function Fx(e){return!(e instanceof Error)||Ix(e)?e:e.message===`Not currently recording`?Px(Ax,`Recording is not ready to stop`):e.message===`Processing not active`?Px(jx,`Recording is not ready to finalize`):e}function Ix(e){let t=e;return t.code===Ax||t.code===jx||t.code===Mx||t.code===Nx}let Lx=[`Bytes`,`KB`,`MB`,`GB`],Rx=1024;function zx(e){if(e===0)return`0 Bytes`;let t=Math.floor(Math.log(e)/Math.log(Rx));return`${Math.round(e/Rx**t*100)/100} ${Lx[t]}`}function Bx(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 Vx={getCurrentTimestamp:()=>performance.now()};var Hx=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=Vx.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 Ux=1e3,Wx=1e3,Gx={route:`local-webcodecs`,reasonCodes:[`webcodecs-supported`,`target-codec-supported`]},Kx={width:{ideal:854,max:854},height:{ideal:480,max:480},frameRate:{ideal:20,max:20}};function qx(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 Jx={checkRecorderSupport:gb,getCurrentTimestamp:()=>performance.now()};var Yx=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=Gx,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?Jx.checkRecorderSupport:n;let i=t?.getCurrentTimestamp,a;a=i===void 0?Jx.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??Gx;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`),Eb();if(this.activeRouteDecision.route===`unsupported-with-guidance`)throw qx(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=zx(e);this.streamManager.emit(`recordingbufferupdate`,{size:e,formatted:t})},Ux),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 Hx,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)/Wx;if($.debug(`[StreamRecordingState] stopRecording called`,{hasStreamProcessor:!!this.streamProcessor,isRecording:this.isRecording(),recordingElapsedSeconds:e}),!(this.streamProcessor&&this.isRecording()))throw Px(Ax,`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(){Gb(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 Gb(this.streamProcessor,`StreamProcessor`).switchVideoSource(e)}getCurrentVideoSource(){return Wb(Gb(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)/Wx,t=this.formatTimeElapsed(e);this.streamManager.emit(`recordingtimeupdate`,{elapsed:e,formatted:t})},Ux)}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 qx({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`)||e.includes(`encoding-capability-unsupported`)||e.includes(`encoding-not-smooth`)||e.includes(`encoding-not-power-efficient`)?Kx: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=Gx}}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=Gx,this.streamProcessor&&=(this.streamProcessor.destroy(),null),this.cleanupVisibilityUpdates(),this.tabVisibilityTracker&&=(this.tabVisibilityTracker.cleanup(),null),this.clearRecordingTimer(),this.clearBufferSizeInterval()}},Xx=class{constructor(e={}){this.streamManager=new kx(e),this.recordingState=new Yx(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 Zx=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`]),Qx=new Set([`recording.codec-unsupported`,`recording.video-codec-unavailable`]),$x=new Set([`recording.post-recording-transcode-fallback`,`transcode.post-recording-fallback`,`route.post-recording-transcode-fallback`]),eS=new Set([`recording.no-video-frames`,`recording.frame-loss`,`recording.excessive-frame-errors`,`video.first-frame-timeout`]),tS=new Set([`recording.finalize-timeout`,`recording.finalize-timeout-low-resource`,`stop.pending-writes-timeout`]),nS=new Set([`recording.not-started`,`recording.state-race`,`recording.not-started-state-race`]),rS=new Set([`recording.unsupported-with-guidance`,`recording.unsupported-device`]);function iS(e){return e.startsWith(`recording.`)?Zx.has(e):!1}function aS(e){return e==null?null:i(e)}function oS(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 sS(e){return e?Qx.has(e)?`recording.codec-unsupported`:$x.has(e)?`recording.post-recording-transcode-fallback`:eS.has(e)?`recording.no-video-frames`:tS.has(e)?`recording.finalize-timeout-low-resource`:nS.has(e)?`recording.not-started-state-race`:rS.has(e)?`recording.unsupported-device`:null:null}function cS(e,t){return t.some(t=>e.includes(t))}function lS(e){if(!e)return null;let t=e.toLowerCase();return cS(t,[`videoencoder.isconfigsupported`,`unknown codec`,`unsupported codec`,`no encodable video codec`,`video codec unavailable`])?`recording.codec-unsupported`:cS(t,[`input track cannot be ended`,`mediastreamtrackprocessor`,`video track ended`])?`recording.track-ended`:cS(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`:cS(t,[`finalize timeout`,`stop.pending-writes-timeout`])||t.includes(`pending writes`)&&t.includes(`timeout`)?`recording.finalize-timeout-low-resource`:cS(t,[`cannot finalize before starting`,`processing not active`,`worker not initialized`])?`recording.not-started-state-race`:cS(t,[`recording.unsupported-with-guidance`,`cannot safely record`,`recording is not supported in this browser context`])?`recording.unsupported-device`:null}function uS(e){return sS(e.errorCode??oS(e.error))||lS(e.errorMessage??aS(e.error))}let dS=Object.freeze({visible:!1,variant:`generic`,canRetry:!1,isCameraError:!1,isAudioError:!1,isBrowserUnsupported:!1,isPermissionDenied:!1});function fS(e){let{errorCode:t,hasAudioFailed:n,error:r}=e,i=uS({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&&iS(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}:dS}let pS=`VIDTREO_INSTALLATION_ID`,mS=`unknown`,hS=/\[([a-z]+(?:[.-][a-z0-9]+)+)\]/i,gS=/\b([a-z]+(?:[.-][a-z0-9]+)+)\b/i;function _S(e){let t=e.storageProvider,n=t?.getItem(pS);if(n)return $.debug(`Using existing installation ID from storage`,{installationId:n}),n;let r=vS(e);return t?.setItem(pS,r),$.debug(`Created new installation ID`,{installationId:r}),r}function vS(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 yS=[`sdk.init.started`,`sdk.init.succeeded`,`sdk.init.failed`],bS=[`stream.error`],xS={"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":`performance`,"recording.audio-missing":`error`,"storage.init.failed":`error`,"storage.write.probe.failed":`error`};var SS=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=_S(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=xS[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.3`,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 yS.includes(e)}isThrottledEvent(e){return bS.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=oS(e),r=i(e),a=n??this.extractNormalizedErrorCode(r),o=uS({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=oS(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(hS);if(t?.[1])return t[1];let n=e.match(gS);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`:mS:mS}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 CS(){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 wS(e,t,n){return new SS({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},CS())}var TS=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)}},ES=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 DS=e=>{},OS=e=>{},kS=e=>{},AS=()=>{},jS=e=>{},MS=(e,t)=>{},NS=e=>{},PS=e=>{},FS=e=>{},IS=()=>{},LS=e=>{};function RS(e){let t={onProgress:DS,onSuccess:OS,onError:kS,onClearStatus:AS};return e.upload&&(t=e.upload),t}let zS=e=>{};function BS(e){let t=LS;return e.onStorageCleanupError&&(t=e.onStorageCleanupError),t}function VS(e){let t=zS;return e.onStorageWriteError&&(t=e.onStorageWriteError),t}function HS(e,t){let n=e.recording,r=jS;n?.onStateChange&&(r=n.onStateChange);let i=MS;n?.onCountdownUpdate&&(i=n.onCountdownUpdate);let a=NS;n?.onTimerUpdate&&(a=n.onTimerUpdate);let o=PS;n?.onError&&(o=n.onError);let s=FS;n?.onRecordingComplete&&(s=n.onRecordingComplete);let c=IS;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 US(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 WS=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 GS(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 KS(e){if(e!==void 0)return typeof e==`number`?e:e===cf?`low`:e===lf?`medium`:e===uf?`high`:e===df?`very-high`:`high`}function qS(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 JS=`vidtreo-audio-worklet`,YS=`audioChunk`,XS=`setMuted`,ZS=`setPaused`,QS=`shutdown`,$S=`
141
- const AUDIO_WORKLET_MESSAGE_TYPE_AUDIO_CHUNK = "${YS}";
142
- const AUDIO_WORKLET_MESSAGE_TYPE_SET_MUTED = "${XS}";
143
- const AUDIO_WORKLET_MESSAGE_TYPE_SET_PAUSED = "${ZS}";
144
- const AUDIO_WORKLET_MESSAGE_TYPE_SHUTDOWN = "${QS}";
140
+ };`],{type:`application/javascript`})}function qy(){let e=Ky();return URL.createObjectURL(e)}function Jy(e){URL.revokeObjectURL(e)}let Yy=`probe`,Xy=`probeResult`,Zy=`mediaStreamTrackProcessor`,Qy=`unavailable`,$y=`unavailable`,eb=new Map,tb=new Map;function nb(e,t){return typeof e==`boolean`?e:t}function rb(e){return e?`1`:`0`}function ib(e,t){return[`audio`,rb(e),`watermark`,rb(t)].join(`|`)}function ab(){return typeof process>`u`||process.env,!0}function ob(e){return e.probeResult.hasMediaStreamTrackProcessor?`worker-track`:e.hasMainThreadMediaStreamTrackProcessor?`main-thread-stream`:Qy}function sb(e){return e.requiresAudio?e.hasMainThreadMediaStreamTrackProcessor&&e.probeResult.hasAudioData?`main-thread-audio-stream`:e.hasAudioContext&&e.hasAudioWorklet?`audio-worklet-chunks`:$y:`none-required`}function cb(e,t){return e.includes(t)?e:[...e,t]}function lb(e,t){let n=e;return t.hasWorker||(n=cb(n,`worker`)),t.probeResult.hasVideoFrame||(n=cb(n,`videoFrame`)),t.probeResult.hasOffscreenCanvas||(n=cb(n,`offscreenCanvas`)),t.probeResult.hasReadableStream||(n=cb(n,`readableStream`)),n}function ub(e,t){let n=e;return t.requiresWatermark&&!t.probeResult.hasCreateImageBitmap&&(n=cb(n,`createImageBitmap`)),n}function db(e,t){let n=e;return t.videoPath===Qy&&(n=cb(n,Zy)),n}function fb(e,t){let n=e;return t.hasMainThreadMediaStreamTrackProcessor&&t.probeResult.hasAudioData?n:(t.hasMainThreadMediaStreamTrackProcessor||(n=cb(n,Zy)),t.hasMainThreadMediaStreamTrackProcessor&&!t.probeResult.hasAudioData&&(n=cb(n,`audioData`)),n)}function pb(e,t){let n=e;return t.hasAudioContext&&t.hasAudioWorklet?n:(t.hasAudioContext||(n=cb(n,`audioContext`)),t.hasAudioWorklet||(n=cb(n,`audioWorklet`)),n)}function mb(e,t){let n=e;return t.requiresAudio&&t.audioPath===$y?(n=fb(n,t),n=pb(n,t),n):n}function hb(e){let t=[];return t=lb(t,e),t=ub(t,e),t=db(t,e),t=mb(t,e),t}function gb(e,t){return!(e===Qy||t===$y)}function _b(e,t){return!(!e.hasVideoFrame||!e.hasOffscreenCanvas||!e.hasReadableStream||t&&!e.hasCreateImageBitmap)}async function vb(e={},t={}){let n=nb(e.requiresAudio,!0),r=nb(e.requiresWatermark,!1);if(!ab())return await yb(n,r,t);let i=ib(n,r),a=eb.get(i);if(a)return a;let o=tb.get(i);if(o)return await o;let s=yb(n,r,t).then(e=>(eb.set(i,e),tb.delete(i),e)).catch(e=>{throw tb.delete(i),e});return tb.set(i,s),await s}async function yb(e,t,n){let r=typeof Worker<`u`,i=a()!==null,o=typeof AudioWorkletNode<`u`,s=typeof MediaStreamTrackProcessor<`u`,c=await bb(r,n),l=ob({probeResult:c,hasMainThreadMediaStreamTrackProcessor:s}),u=sb({requiresAudio:e,hasAudioContext:i,hasAudioWorklet:o,hasMainThreadMediaStreamTrackProcessor:s,probeResult:c}),d=hb({hasWorker:r,hasAudioContext:i,hasAudioWorklet:o,hasMainThreadMediaStreamTrackProcessor:s,probeResult:c,requiresAudio:e,requiresWatermark:t,videoPath:l,audioPath:u}),f=gb(l,u),p=_b(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 bb(e,t){if(!e)return Sb();let n=await xb().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(Sb())},i);n.onmessage=e=>{let t=e.data;t.type===Xy&&(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(Sb())},Promise.resolve().then(()=>{n.postMessage({type:Yy})}).catch(()=>{clearTimeout(o),a(Sb())})}):Sb()}function xb(){return Promise.resolve().then(()=>{let e=qy();try{let t=new Worker(e,{type:`classic`});return Jy(e),t}catch(t){throw Jy(e),t}})}function Sb(){return{hasMediaStreamTrackProcessor:!1,hasVideoFrame:!1,hasAudioData:!1,hasOffscreenCanvas:!1,hasCreateImageBitmap:!1,hasReadableStream:!1}}let Cb=`recording.audio-no-chunks`,wb=`recording.audio-silent`,Tb=`recording.audio-track-ended`,Eb=`audio.no-track-at-start`;function Db(e,t){let n=Error(e);return n.code=e,t&&(n.details=t),n}function Ob(){let e=Error(Eb);return e.code=Eb,e}function kb(e){if(!(e instanceof Error))return!1;let t=e;return t.code===Cb||t.code===wb||t.code===Tb||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 Ab(e){return e.hadTrackEndedWarning?{ok:!1,code:Tb}:e.totalChunks===0?{ok:!1,code:Cb}:e.nonSilentChunks===0&&(e.durationMs>0?e.mutedDurationMs/e.durationMs:0)<.9?{ok:!1,code:wb}:{ok:!0}}let jb=`vidtreo-recorder`,Mb=`pending-uploads`,Nb=`status`,Pb=`createdAt`,Fb=`Failed to prepare upload data for storage. The recorded file could not be read.`,Ib=`__probe__`,Lb=new ArrayBuffer(1);var Rb=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(jb):this.databaseFactory.open(jb,e)}initializeStoreSchema(e){if(e.objectStoreNames.contains(Mb))return;let t=e.createObjectStore(Mb,{keyPath:`id`});t.createIndex(Nb,Nb,{unique:!1}),t.createIndex(Pb,Pb,{unique:!1})}validateRequiredSchema(e){if(!e.objectStoreNames.contains(Mb))return Error(`Database schema is missing required object store: pending-uploads`);let t=e.transaction([Mb],`readonly`).objectStore(Mb);return t.indexNames.contains(Nb)?t.indexNames.contains(Pb)?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:Ib,blobData:Lb,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(Ib);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(Nb).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(`${Fb} ${e.message}`):Error(Fb)})}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([Mb],e),r=n.objectStore(Mb);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)})})}},zb=class{constructor(){this.storageService=null,this.cleanupIntervalId=null,this.writeProbeResult=null}async initialize(e){this.storageService||=new Rb,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 Bb(){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 Vb=Bb(),Hb={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 Ub(e,t,n){if(!Vb)return``;let r=n?.prefix||`[${e.toUpperCase()}]`;return`${Hb[n?.color||Wb(e)]}${r}${Hb.reset} ${t}`}function Wb(e){switch(e){case`error`:return`red`;case`warn`:return`yellow`;case`info`:return`cyan`;case`debug`:return`gray`;default:return`white`}}function Gb(e,t,...n){if(!Vb)return;let r=Ub(e,t);console[e](r,...n)}let $={log:(e,...t)=>{Gb(`log`,e,...t)},info:(e,...t)=>{Gb(`info`,e,...t)},warn:(e,...t)=>{Gb(`warn`,e,...t)},error:(e,...t)=>{Gb(`error`,e,...t)},debug:(e,...t)=>{Gb(`debug`,e,...t)},group:(e,t=`cyan`)=>{if(!Vb)return;let n=Hb[t],r=Hb.reset;console.group(`${n}${e}${r}`)},groupEnd:()=>{Vb&&console.groupEnd()}};function Kb(e,t){if(e==null)throw Error(t);return e}function qb(e,t=`StreamProcessor`){if(!e)throw Error(`${t} is required`);return e}function Jb(){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 Yb(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 Xb(e){let t={echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0};return e?{...t,deviceId:{exact:e}}:t}let Zb=`live`;function Qb(e){for(let t of e)t.readyState===Zb&&t.stop()}function $b(e){Qb(e.getTracks())}function ex(e){Qb(e.getVideoTracks())}function tx(e){return e?e.readyState===Zb:!1}function nx(e,t){return tx(e)&&tx(t)}function rx(e,t,n){if(!tx(e)){$b(n);let r=`undefined`;throw e&&(r=e.readyState),Error(`Failed to get live camera ${t} track. ReadyState: ${r}`)}}let ix=`[SourceSwitchManager]`;var ax=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(`${ix} createCameraStreamWithOriginalAudio`,{hasOriginalCameraStream:!!t,originalCameraStreamId:t?.id,hasOriginalAudioTrack:!!n,originalAudioTrackId:n?.id,originalAudioTrackReadyState:n?.readyState,originalAudioTrackEnabled:n?.enabled,originalAudioTrackMuted:n?.muted,originalAudioTrackLabel:n?.label,isTrackLive:tx(n),cameraDeviceId:e}),!tx(n))return this.dependencies.logger.warn(`${ix} Original audio track is not live, cannot reuse`,{originalAudioTrackId:n?.id,originalAudioTrackReadyState:n?.readyState}),null;let r=Yb(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(`${ix} Requesting new video stream`,{constraints:o,cameraDeviceId:e});let s=await Jb().getUserMedia(o),c=s.getVideoTracks()[0];rx(c,`video`,s),this.dependencies.logger.debug(`${ix} 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(`${ix} 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);Qb(s.getAudioTracks());let d=t?.id;return this.dependencies.setOriginalCameraStream(u),this.dependencies.logger.debug(`${ix} 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=Yb(e,{originalCameraConstraints:this.dependencies.getOriginalCameraConstraints(),getSelectedCameraDeviceId:this.dependencies.getSelectedCameraDeviceId}),r=Xb(t),i=Object.keys(n).length>0,a=!0;i&&(a=n);let o={video:a,audio:r},s=await Jb().getUserMedia(o),c=s.getVideoTracks()[0],l=s.getAudioTracks()[0];return rx(c,`video`,s),rx(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()&&($b(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 ox=`screen`,sx=`No video track found in screen share stream`;async function cx(e,t,n){n.setScreenShareStream(e);let r=e.getVideoTracks()[0];if(!r)throw n.stopStreamTracks(e),Error(sx);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(ox),n.callbacks.onSourceChange&&await n.callbacks.onSourceChange(n.getCurrentSourceType()),lx(i,n),i}function lx(e,t){let n=e.getVideoTracks()[0];if(!n)throw Error(sx);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()===ox&&t.switchToCamera().catch(e=>{t.handleSwitchError(e)})};t.setScreenShareTrackEndHandler(i),n.addEventListener(`ended`,i)}function ux(e,t){let n=t.getScreenShareTrackEndHandler();if(!(n&&e))return;let r=e.getVideoTracks()[0];r&&r.removeEventListener(`ended`,n),t.setScreenShareTrackEndHandler(null)}function dx(e,t){e.onTransitionStart&&e.onTransitionStart(t)}function fx(e){e.onTransitionEnd&&e.onTransitionEnd()}function px(e){e.onScreenSelectionStart&&e.onScreenSelectionStart()}function mx(e){e.onScreenSelectionEnd&&e.onScreenSelectionEnd()}function hx(e){mx(e),fx(e)}let gx=`Failed to get camera stream`;var _x=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 ax({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];nx(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:tx(t),screenVideoTrackId:e.id,screenVideoTrackReadyState:e.readyState});let n=[e];tx(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)),dx(this.callbacks,`Select screen to share...`),px(this.callbacks),Promise.resolve().then(async()=>{let t=Jb();if(typeof t.getDisplayMedia!=`function`)throw Error(`Screen sharing is not supported on this device`);return cx(await t.getDisplayMedia({video:!0,audio:!0}),e,this.getScreenShareDependencies())}).catch(e=>{if(hx(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!(!nx(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=>$b(e),stopStreamVideoTracks:e=>ex(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()=>{dx(this.callbacks,`Switching to camera...`),await this.handleScreenShareStop();let t=await this.getCameraStream();if(!t)throw Error(gx);await this.applyCameraStream(t,e),fx(this.callbacks)}).catch(e=>{throw fx(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`&&tx(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}))}),ux(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}))}),ex(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){fx(this.callbacks);return}dx(this.callbacks,`Switching to screen...`),await this.streamManager.switchVideoSource(e),this.callbacks.onPreviewUpdate&&await this.callbacks.onPreviewUpdate(e),fx(this.callbacks)}handleToggleError(e){fx(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&&(ux(e,this.getScreenShareDependencies()),ex(e));let t=await this.getCameraStream();if(!t)throw Error(gx);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&&=(ux(this.screenShareStream,this.getScreenShareDependencies()),this.stopScreenShareStreamTracks(this.screenShareStream),null);let e=this.streamManager.getStream();e&&ux(e,this.getScreenShareDependencies()),this.screenShareTrackEndHandler=null,this.originalCameraStream=null,this.setOriginalCameraConstraints(null)}setCallbacks(e){this.callbacks={...this.callbacks,...e}}};let vx=Object.freeze({width:{ideal:Xt.width||1920},height:{ideal:Xt.height||1080},frameRate:{ideal:Xt.fps||30}}),yx=Object.freeze({video:vx,audio:!0});Object.freeze({mimeType:`video/webm;codecs=vp9,opus`});let bx={NotReadableError:`camera.in-use`,NotFoundError:`camera.not-found`,NotAllowedError:`camera.permission-denied`,OverconstrainedError:`camera.overconstrained`,TimeoutError:`camera.timeout`},xx={NotReadableError:`audio.in-use`,NotFoundError:`audio.not-found`,NotAllowedError:`audio.permission-denied`,OverconstrainedError:`audio.overconstrained`,TimeoutError:`audio.timeout`};function Sx(e){return e instanceof DOMException||typeof e==`object`&&e&&`name`in e&&typeof e.name==`string`?e.name:null}function Cx(e){return i(e).toLowerCase()}function wx(e,t){let n=Cx(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 Tx(e){let t=wx(e,`camera`);if(t!==null)return t;let n=Sx(e);if(n!==null){let e=bx[n];if(e!==void 0)return e}return`camera.unknown`}function Ex(e){let t=wx(e,`audio`);if(t!==null)return t;let n=Sx(e);if(n!==null){let e=xx[n];if(e!==void 0)return e}return`audio.unknown`}function Dx(e){let t=i(e),n=Error(t);return n.name=`CameraError`,n.code=Tx(e),n}function Ox(e){let t=i(e),n=Error(t);return n.name=`AudioError`,n.code=Ex(e),n}function kx(e){return Sx(e)===`NotReadableError`}function Ax(e){return new Promise(t=>setTimeout(t,e))}var jx=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={...yx,...e},this.waitMilliseconds=t.waitMilliseconds??Ax,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??Ox(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=Dx(e);throw $.error(`[StreamManager] Failed to start stream`,t),this.setState(`error`),this.emit(`error`,{error:t}),t}}async acquireVideoAndAudioStream(){let e=Jb(),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=Sx(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`),Dx(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:Ox(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=Sx(e),o=kx(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 Ox(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 Jb().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 Mx=`recording.stop-not-ready`,Nx=`recording.finalize-not-ready`,Px=`recording.finalize-timeout`,Fx=`recording.upload-in-progress`;function Ix(e,t,n){let r=Error(`${t} [${e}]`);return r.code=e,r.isRecoverable=!0,n!==void 0&&(r.details=n),r}function Lx(e){return!(e instanceof Error)||Rx(e)?e:e.message===`Not currently recording`?Ix(Mx,`Recording is not ready to stop`):e.message===`Processing not active`?Ix(Nx,`Recording is not ready to finalize`):e}function Rx(e){let t=e;return t.code===Mx||t.code===Nx||t.code===Px||t.code===Fx}let zx=[`Bytes`,`KB`,`MB`,`GB`],Bx=1024;function Vx(e){if(e===0)return`0 Bytes`;let t=Math.floor(Math.log(e)/Math.log(Bx));return`${Math.round(e/Bx**t*100)/100} ${zx[t]}`}function Hx(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 Ux={getCurrentTimestamp:()=>performance.now()};var Wx=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=Ux.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 Gx=1e3,Kx=1e3,qx={route:`local-webcodecs`,reasonCodes:[`webcodecs-supported`,`target-codec-supported`]},Jx={width:{ideal:854,max:854},height:{ideal:480,max:480},frameRate:{ideal:20,max:20}},Yx={width:{ideal:1280,max:1280},height:{ideal:720,max:720},frameRate:{ideal:24,max:24}},Xx=`android-post-recording-transcode`;function Zx(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 Qx={checkRecorderSupport:vb,getCurrentTimestamp:()=>performance.now()};var $x=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=qx,this.mediaRecorder=null,this.mediaRecorderChunks=[],this.mediaRecorderStopPromise=null,this.mediaRecorderStopResolve=null,this.mediaRecorderStopReject=null,this.mediaRecorderError=null,this.mediaRecorderErrorTimeoutId=null,this.streamManager=e;let n=t?.checkRecorderSupport,r;r=n===void 0?Qx.checkRecorderSupport:n;let i=t?.getCurrentTimestamp,a;a=i===void 0?Qx.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??qx;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`),Ob();if(this.activeRouteDecision.route===`unsupported-with-guidance`)throw Zx(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=Vx(e);this.streamManager.emit(`recordingbufferupdate`,{size:e,formatted:t})},Gx),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 Wx,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)/Kx;if($.debug(`[StreamRecordingState] stopRecording called`,{hasStreamProcessor:!!this.streamProcessor,isRecording:this.isRecording(),recordingElapsedSeconds:e}),!(this.streamProcessor&&this.isRecording()))throw Ix(Mx,`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;if(this.activeRouteDecision.route===`safe-capture-post-recording-transcode`){let e=await this.stopSafeCaptureRecording();$.debug(`[StreamRecordingState] Finalizing MediaRecorder capture`),n={blob:e.blob,mediaRecorderDiagnostics:e.diagnostics}}else $.debug(`[StreamRecordingState] Finalizing stream processor`),n=await this.streamProcessor.finalize(),$.info(`[StreamRecordingState] Stream processor finalized`,{blobSize:n.blob.size,hasBlob:!!n.blob});return 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,mediaRecorderDiagnostics:n.mediaRecorderDiagnostics}}pauseRecording(){this.clearRecordingTimer(),this.pauseStartTime===null&&(this.pauseStartTime=this.dependencies.getCurrentTimestamp()),this.tabVisibilityTracker&&this.tabVisibilityTracker.pause(),this.mediaRecorder?.state===`recording`&&this.mediaRecorder.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.mediaRecorder?.state===`paused`&&this.mediaRecorder.resume?.(),this.startRecordingTimer(),this.streamProcessor&&this.isRecording()&&this.streamProcessor.resume()}toggleMute(){qb(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 qb(this.streamProcessor,`StreamProcessor`).switchVideoSource(e)}getCurrentVideoSource(){return Kb(qb(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)/Kx,t=this.formatTimeElapsed(e);this.streamManager.emit(`recordingtimeupdate`,{elapsed:e,formatted:t})},Gx)}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 Zx({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=[],this.mediaRecorderError=null;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}),this.mediaRecorderStopPromise.catch(()=>void 0),i.ondataavailable=e=>{e.data.size>0&&this.mediaRecorderChunks.push(e.data)},i.onstop=()=>{if(this.clearMediaRecorderErrorTimeout(),this.mediaRecorderError!==null){this.updateMediaRecorderErrorDiagnostics(i),this.mediaRecorderStopReject?.(this.mediaRecorderError);return}let e=i.mimeType||this.resolveSafeCaptureMimeType(),t=new Blob(this.mediaRecorderChunks,{type:e}),n=this.buildMediaRecorderDiagnostics(i);if(t.size>0){this.mediaRecorderStopResolve?.({blob:t,diagnostics:n});return}this.mediaRecorderStopReject?.(this.createEmptyMediaRecorderError(i))},i.onerror=e=>{this.mediaRecorderError=this.createMediaRecorderError(e,i)},i.start(1e3)}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`)||e.includes(`encoding-capability-unsupported`)||e.includes(`encoding-not-smooth`)||e.includes(`encoding-not-power-efficient`)?Jx:e.includes(Xx)?Yx: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(),this.scheduleMediaRecorderErrorFinalizeTimeout(e);try{return await t}finally{this.mediaRecorder=null,this.mediaRecorderChunks=[],this.mediaRecorderStopPromise=null,this.mediaRecorderStopResolve=null,this.mediaRecorderStopReject=null,this.mediaRecorderError=null,this.clearMediaRecorderErrorTimeout(),this.activeRouteDecision=qx}}resolveSafeCaptureMimeType(){return(this.streamManager.getStream()?.getVideoTracks().length??0)>0?`video/webm`:`audio/webm`}resolvePreferredSafeCaptureMimeType(e){let t=e=>typeof MediaRecorder.isTypeSupported==`function`?MediaRecorder.isTypeSupported(e):!1,n=[`video/webm;codecs=vp8,opus`,`video/webm;codecs=vp9,opus`,`video/webm`],r=[`video/mp4;codecs=avc1.42E01E,mp4a.40.2`,`video/mp4;codecs=avc1.42001f,mp4a.40.2`,`video/mp4`],i=r;return this.shouldPreferWebmSafeCapture(e)?i=[...n,...r]:e.format!==`mp4`&&(i=n),i.find(t)}shouldPreferWebmSafeCapture(e){return e.format===`mp4`?this.activeRouteDecision.reasonCodes.includes(Xx):!1}scheduleMediaRecorderErrorFinalizeTimeout(e){this.mediaRecorderErrorTimeoutId===null&&(this.mediaRecorderErrorTimeoutId=window.setTimeout(()=>{if(this.mediaRecorderError!==null){this.mediaRecorderStopReject?.(this.mediaRecorderError);return}this.mediaRecorderStopReject?.(this.createEmptyMediaRecorderError(e))},5e3))}clearMediaRecorderErrorTimeout(){this.mediaRecorderErrorTimeoutId!==null&&(window.clearTimeout(this.mediaRecorderErrorTimeoutId),this.mediaRecorderErrorTimeoutId=null)}createMediaRecorderError(e,t){let n=e.error,r=Error(`Browser recording failed before upload could start`);return r.name=`MediaRecorderRecordingError`,r.code=`recording.mediarecorder-error`,r.mediaRecorderMimeType=t.mimeType,r.mediaRecorderChunkCount=this.mediaRecorderChunks.length,r.mediaRecorderChunkSize=this.getMediaRecorderChunkSize(),n?.name&&(r.mediaRecorderErrorName=n.name),n?.message&&(r.mediaRecorderErrorMessage=n.message),r}createEmptyMediaRecorderError(e){let t=Error(`Browser recording produced no data before upload could start`);return t.name=`MediaRecorderEmptyDataError`,t.code=`recording.mediarecorder-empty`,t.mediaRecorderMimeType=e.mimeType,t.mediaRecorderChunkCount=this.mediaRecorderChunks.length,t.mediaRecorderChunkSize=this.getMediaRecorderChunkSize(),this.mediaRecorderError?.mediaRecorderErrorName&&(t.mediaRecorderErrorName=this.mediaRecorderError.mediaRecorderErrorName),this.mediaRecorderError?.mediaRecorderErrorMessage&&(t.mediaRecorderErrorMessage=this.mediaRecorderError.mediaRecorderErrorMessage),t}updateMediaRecorderErrorDiagnostics(e){this.mediaRecorderError!==null&&(this.mediaRecorderError.mediaRecorderMimeType=e.mimeType,this.mediaRecorderError.mediaRecorderChunkCount=this.mediaRecorderChunks.length,this.mediaRecorderError.mediaRecorderChunkSize=this.getMediaRecorderChunkSize())}buildMediaRecorderDiagnostics(e){let t={mediaRecorderMimeType:e.mimeType,mediaRecorderChunkCount:this.mediaRecorderChunks.length,mediaRecorderChunkSize:this.getMediaRecorderChunkSize(),mediaRecorderHadError:this.mediaRecorderError!==null};return this.mediaRecorderError?.mediaRecorderErrorName&&(t.mediaRecorderErrorName=this.mediaRecorderError.mediaRecorderErrorName),this.mediaRecorderError?.mediaRecorderErrorMessage&&(t.mediaRecorderErrorMessage=this.mediaRecorderError.mediaRecorderErrorMessage),t}getMediaRecorderChunkSize(){return this.mediaRecorderChunks.reduce((e,t)=>e+t.size,0)}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.mediaRecorderError=null,this.clearMediaRecorderErrorTimeout(),this.activeRouteDecision=qx,this.streamProcessor&&=(this.streamProcessor.destroy(),null),this.cleanupVisibilityUpdates(),this.tabVisibilityTracker&&=(this.tabVisibilityTracker.cleanup(),null),this.clearRecordingTimer(),this.clearBufferSizeInterval()}},eS=class{constructor(e={}){this.streamManager=new jx(e),this.recordingState=new $x(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 tS=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`]),nS=new Set([`recording.codec-unsupported`,`recording.video-codec-unavailable`]),rS=new Set([`recording.post-recording-transcode-fallback`,`recording.mediarecorder-empty`,`recording.mediarecorder-error`,`transcode.post-recording-fallback`,`route.post-recording-transcode-fallback`]),iS=new Set([`recording.no-video-frames`,`recording.frame-loss`,`recording.excessive-frame-errors`,`video.first-frame-timeout`]),aS=new Set([`recording.finalize-timeout`,`recording.finalize-timeout-low-resource`,`stop.pending-writes-timeout`]),oS=new Set([`recording.not-started`,`recording.state-race`,`recording.not-started-state-race`]),sS=new Set([`recording.unsupported-with-guidance`,`recording.unsupported-device`]);function cS(e){return e.startsWith(`recording.`)?tS.has(e):!1}function lS(e){return e==null?null:i(e)}function uS(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 dS(e){return e?nS.has(e)?`recording.codec-unsupported`:rS.has(e)?`recording.post-recording-transcode-fallback`:iS.has(e)?`recording.no-video-frames`:aS.has(e)?`recording.finalize-timeout-low-resource`:oS.has(e)?`recording.not-started-state-race`:sS.has(e)?`recording.unsupported-device`:null:null}function fS(e,t){return t.some(t=>e.includes(t))}function pS(e){if(!e)return null;let t=e.toLowerCase();return fS(t,[`videoencoder.isconfigsupported`,`unknown codec`,`unsupported codec`,`no encodable video codec`,`video codec unavailable`])?`recording.codec-unsupported`:fS(t,[`input track cannot be ended`,`mediastreamtrackprocessor`,`video track ended`])?`recording.track-ended`:fS(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`:fS(t,[`finalize timeout`,`stop.pending-writes-timeout`])||t.includes(`pending writes`)&&t.includes(`timeout`)?`recording.finalize-timeout-low-resource`:fS(t,[`cannot finalize before starting`,`processing not active`,`worker not initialized`])?`recording.not-started-state-race`:fS(t,[`recording.unsupported-with-guidance`,`cannot safely record`,`recording is not supported in this browser context`])?`recording.unsupported-device`:null}function mS(e){return dS(e.errorCode??uS(e.error))||pS(e.errorMessage??lS(e.error))}let hS=Object.freeze({visible:!1,variant:`generic`,canRetry:!1,isCameraError:!1,isAudioError:!1,isBrowserUnsupported:!1,isPermissionDenied:!1});function gS(e){let{errorCode:t,hasAudioFailed:n,error:r}=e,i=mS({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&&cS(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}:hS}let _S=`VIDTREO_INSTALLATION_ID`,vS=`unknown`,yS=/\[([a-z]+(?:[.-][a-z0-9]+)+)\]/i,bS=/\b([a-z]+(?:[.-][a-z0-9]+)+)\b/i,xS=[`mediaRecorderErrorName`,`mediaRecorderErrorMessage`,`mediaRecorderMimeType`,`mediaRecorderChunkCount`,`mediaRecorderChunkSize`];function SS(e){let t=e.storageProvider,n=t?.getItem(_S);if(n)return $.debug(`Using existing installation ID from storage`,{installationId:n}),n;let r=CS(e);return t?.setItem(_S,r),$.debug(`Created new installation ID`,{installationId:r}),r}function CS(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 wS=[`sdk.init.started`,`sdk.init.succeeded`,`sdk.init.failed`],TS=[`stream.error`],ES={"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":`performance`,"recording.audio-missing":`error`,"storage.init.failed":`error`,"storage.write.probe.failed":`error`};var DS=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=SS(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=ES[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.7.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 wS.includes(e)}isThrottledEvent(e){return TS.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=uS(e),r=i(e),a=n??this.extractNormalizedErrorCode(r),o=mS({errorCode:a,error:e,errorMessage:r});return a&&(t={...t,errorCode:a}),o&&(t={...t,rawErrorClassification:o,recordingPipelineErrorCode:o}),{...t,...this.buildMediaRecorderErrorProperties(e)}}buildMediaRecorderErrorProperties(e){if(!(e&&typeof e==`object`))return{};let t=e,n={};for(let e of xS){let r=t[e];(typeof r==`string`||typeof r==`number`||typeof r==`boolean`)&&(n={...n,[e]:r})}return n}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=uS(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(yS);if(t?.[1])return t[1];let n=e.match(bS);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`:vS:vS}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 OS(){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 kS(e,t,n){return new DS({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},OS())}var AS=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)}},jS=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 MS=e=>{},NS=e=>{},PS=e=>{},FS=()=>{},IS=e=>{},LS=(e,t)=>{},RS=e=>{},zS=e=>{},BS=e=>{},VS=()=>{},HS=e=>{};function US(e){let t={onProgress:MS,onSuccess:NS,onError:PS,onClearStatus:FS};return e.upload&&(t=e.upload),t}let WS=e=>{};function GS(e){let t=HS;return e.onStorageCleanupError&&(t=e.onStorageCleanupError),t}function KS(e){let t=WS;return e.onStorageWriteError&&(t=e.onStorageWriteError),t}function qS(e,t){let n=e.recording,r=IS;n?.onStateChange&&(r=n.onStateChange);let i=LS;n?.onCountdownUpdate&&(i=n.onCountdownUpdate);let a=RS;n?.onTimerUpdate&&(a=n.onTimerUpdate);let o=zS;n?.onError&&(o=n.onError);let s=BS;n?.onRecordingComplete&&(s=n.onRecordingComplete);let c=VS;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 JS(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 YS=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 XS(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===cf?`low`:e===lf?`medium`:e===uf?`high`:e===df?`very-high`:`high`}function QS(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 $S=`vidtreo-audio-worklet`,eC=`audioChunk`,tC=`setMuted`,nC=`setPaused`,rC=`shutdown`,iC=`
141
+ const AUDIO_WORKLET_MESSAGE_TYPE_AUDIO_CHUNK = "${eC}";
142
+ const AUDIO_WORKLET_MESSAGE_TYPE_SET_MUTED = "${tC}";
143
+ const AUDIO_WORKLET_MESSAGE_TYPE_SET_PAUSED = "${nC}";
144
+ const AUDIO_WORKLET_MESSAGE_TYPE_SHUTDOWN = "${rC}";
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("${JS}", VidtreoAudioWorkletProcessor);
243
- `;function eC(){if(typeof Blob>`u`||typeof URL>`u`)throw Error(`Blob and URL APIs are required for audio worklet loading`);return new Blob([$S],{type:`application/javascript`})}let tC=qS({createBlob:eC,createObjectUrl:e=>URL.createObjectURL(e),revokeObjectUrl:e=>{URL.revokeObjectURL(e)}});var nC=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=tC.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,JS,{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:XS,isMuted:e})}setPaused(e){this.isPaused=e,this.audioWorkletNode&&this.audioWorkletNode.port.postMessage({type:ZS,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!==YS)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:QS}),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&&=(tC.release(),!1)}},rC=class{constructor(e){this.audioWorkletController=null,this.audioWorkletConfig=null,this.onChunk=e.onChunk;let t=()=>new nC;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 iC=`recording.video-track-ended`;function aC(e={}){let t=Error(`Video track ended before recording could start [${iC}]`);return t.code=iC,t.isRecoverable=!0,t.details=e,t}function oC(e,t={}){if(e.readyState!==`live`)throw aC({...t,trackId:e.id,readyState:e.readyState})}let sC=`video.first-frame-timeout`,cC={createVideoStreamFromTrack:e=>typeof MediaStreamTrackProcessor>`u`?null:(oC(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 lC(e,t=3e3,n={}){let r={createVideoStreamFromTrack:n.createVideoStreamFromTrack??cC.createVideoStreamFromTrack,setTimeout:n.setTimeout??cC.setTimeout,clearTimeout:n.clearTimeout??cC.clearTimeout,performanceNow:n.performanceNow??cC.performanceNow},i=r.performanceNow();oC(e,{stage:`preflight-original-track`});let a=uC(e);oC(a,{stage:`preflight-cloned-track`});let o=r.createVideoStreamFromTrack(a);if(!o)return dC(a,e),$.debug(`[VideoFramePreflight] Cannot create stream from track, skipping preflight`),{elapsedMs:r.performanceNow()-i};let s=await fC(o,t,r),c=r.performanceNow()-i;if($.debug(`[VideoFramePreflight] Completed`,{elapsedMs:c,timedOut:s===null}),s===null){await o.cancel().catch(()=>void 0),dC(a,e);let n=Error(`Video stream failed to yield first frame within ${t}ms`);throw n.code=sC,n.elapsedMs=c,n}return s.frame.close(),s.reader.releaseLock(),o.cancel().catch(()=>void 0),dC(a,e),{elapsedMs:c}}function uC(e){return typeof e.clone==`function`?e.clone():e}function dC(e,t){e!==t&&e.stop()}async function fC(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 pC(e,t){if(e.length===0)return null;t.stopCurrentVideoTrack();let n=e[0];oC(n,{stage:`prepare-original-track`});let r=t.cloneVideoTrack(n);return oC(r,{stage:`prepare-cloned-track`}),t.setCurrentVideoTrack(r),r}function mC(e,t){if(e.length===0)return null;let n=e[0];return t.cloneAudioTrack(n)}function hC(e,t,n){if(!e)return{videoTrack:null,videoStream:null};if(oC(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 gC(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 _C(e){return e.isMobileDevice()}function vC(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 yC(e,t){if(!e||typeof e.getSettings!=`function`)return;let n=xC(e.getSettings()),r;typeof e.getCapabilities==`function`&&(r=SC(e.getCapabilities())),t.logger.debug(`[WorkerProcessor] Video track settings`,n),r&&t.logger.debug(`[WorkerProcessor] Video track capabilities`,r)}function bC(e){let t=e.getViewportMetadata();t&&e.logger.debug(`[WorkerProcessor] Viewport metadata`,t)}function xC(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 SC(e){let t=e;return{width:e.width,height:e.height,frameRate:e.frameRate,aspectRatio:e.aspectRatio,facingMode:e.facingMode,resizeMode:t.resizeMode}}function CC(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 wC(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 TC(e,t){return{type:`switchSource`,videoTrack:e,videoStream:t}}function EC(e,t,n=null){let r=[];return e&&(r=[...r,e]),t&&(r=[...r,t]),n&&(r=[...r,n]),r}var DC=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:qy}),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:Jy,hasMediaStreamTrackProcessor:!1,hasVideoFrame:!1,hasAudioData:!1,hasOffscreenCanvas:!1,hasCreateImageBitmap:!1,hasReadableStream:!1}}};function OC(){if(typeof Blob>`u`||typeof URL>`u`)throw Error(`Blob and URL APIs are required for worker loading`);return new Blob([`(() => {
242
+ registerProcessor("${$S}", VidtreoAudioWorkletProcessor);
243
+ `;function aC(){if(typeof Blob>`u`||typeof URL>`u`)throw Error(`Blob and URL APIs are required for audio worklet loading`);return new Blob([iC],{type:`application/javascript`})}let oC=QS({createBlob:aC,createObjectUrl:e=>URL.createObjectURL(e),revokeObjectUrl:e=>{URL.revokeObjectURL(e)}});var sC=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=oC.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,$S,{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:tC,isMuted:e})}setPaused(e){this.isPaused=e,this.audioWorkletNode&&this.audioWorkletNode.port.postMessage({type:nC,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!==eC)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:rC}),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&&=(oC.release(),!1)}},cC=class{constructor(e){this.audioWorkletController=null,this.audioWorkletConfig=null,this.onChunk=e.onChunk;let t=()=>new sC;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 lC=`recording.video-track-ended`;function uC(e={}){let t=Error(`Video track ended before recording could start [${lC}]`);return t.code=lC,t.isRecoverable=!0,t.details=e,t}function dC(e,t={}){if(e.readyState!==`live`)throw uC({...t,trackId:e.id,readyState:e.readyState})}let fC=`video.first-frame-timeout`,pC={createVideoStreamFromTrack:e=>typeof MediaStreamTrackProcessor>`u`?null:(dC(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 mC(e,t=3e3,n={}){let r={createVideoStreamFromTrack:n.createVideoStreamFromTrack??pC.createVideoStreamFromTrack,setTimeout:n.setTimeout??pC.setTimeout,clearTimeout:n.clearTimeout??pC.clearTimeout,performanceNow:n.performanceNow??pC.performanceNow},i=r.performanceNow();dC(e,{stage:`preflight-original-track`});let a=hC(e);dC(a,{stage:`preflight-cloned-track`});let o=r.createVideoStreamFromTrack(a);if(!o)return gC(a,e),$.debug(`[VideoFramePreflight] Cannot create stream from track, skipping preflight`),{elapsedMs:r.performanceNow()-i};let s=await _C(o,t,r),c=r.performanceNow()-i;if($.debug(`[VideoFramePreflight] Completed`,{elapsedMs:c,timedOut:s===null}),s===null){await o.cancel().catch(()=>void 0),gC(a,e);let n=Error(`Video stream failed to yield first frame within ${t}ms`);throw n.code=fC,n.elapsedMs=c,n}return s.frame.close(),s.reader.releaseLock(),o.cancel().catch(()=>void 0),gC(a,e),{elapsedMs:c}}function hC(e){return typeof e.clone==`function`?e.clone():e}function gC(e,t){e!==t&&e.stop()}async function _C(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 vC(e,t){if(e.length===0)return null;t.stopCurrentVideoTrack();let n=e[0];dC(n,{stage:`prepare-original-track`});let r=t.cloneVideoTrack(n);return dC(r,{stage:`prepare-cloned-track`}),t.setCurrentVideoTrack(r),r}function yC(e,t){if(e.length===0)return null;let n=e[0];return t.cloneAudioTrack(n)}function bC(e,t,n){if(!e)return{videoTrack:null,videoStream:null};if(dC(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 xC(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 SC(e){return e.isMobileDevice()}function CC(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 wC(e,t){if(!e||typeof e.getSettings!=`function`)return;let n=EC(e.getSettings()),r;typeof e.getCapabilities==`function`&&(r=DC(e.getCapabilities())),t.logger.debug(`[WorkerProcessor] Video track settings`,n),r&&t.logger.debug(`[WorkerProcessor] Video track capabilities`,r)}function TC(e){let t=e.getViewportMetadata();t&&e.logger.debug(`[WorkerProcessor] Viewport metadata`,t)}function EC(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 DC(e){let t=e;return{width:e.width,height:e.height,frameRate:e.frameRate,aspectRatio:e.aspectRatio,facingMode:e.facingMode,resizeMode:t.resizeMode}}function OC(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 kC(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 AC(e,t){return{type:`switchSource`,videoTrack:e,videoStream:t}}function jC(e,t,n=null){let r=[];return e&&(r=[...r,e]),t&&(r=[...r,t]),n&&(r=[...r,n]),r}var MC=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:Yy}),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:Xy,hasMediaStreamTrackProcessor:!1,hasVideoFrame:!1,hasAudioData:!1,hasOffscreenCanvas:!1,hasCreateImageBitmap:!1,hasReadableStream:!1}}};function NC(){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,8 +12826,8 @@ Mediabunny was loaded twice.\` + " This will likely cause Mediabunny not to work
12826
12826
  initializeRecorderWorker();
12827
12827
  }
12828
12828
  })();
12829
- `],{type:`application/javascript`})}let kC=qS({createBlob:OC,createObjectUrl:e=>URL.createObjectURL(e),revokeObjectUrl:e=>{URL.revokeObjectURL(e)}});function AC(){return kC.acquire()}function jC(){kC.release()}let MC=1e3,NC=`format`,PC=new Map,FC=new Map;function IC(e){return e===void 0?`undefined`:String(e)}function LC(e){return e.join(`,`)}function RC(e,t){return`${e}=${t}`}function zC(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 BC=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 WS,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:(oC(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 DC({setTimeout:window.setTimeout.bind(window),clearTimeout:window.clearTimeout.bind(window),timeoutMilliseconds:2e3}),this.audioWorkletManager=new rC({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 Jy: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=AC();this.hasWorkerUrlLease=!0;try{this.worker=CC({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 rC({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=GS(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=pC(u,e),n=mC(d,e),r=await this.getWorkerProbeResult();t&&($.debug(`[WorkerProcessor] Running video first-frame preflight`),await lC(t,3e3,this.videoFramePreflightDeps),$.debug(`[WorkerProcessor] Video first-frame preflight passed`));let i=hC(t,r,e),a=_C(e),o=gC(t);yC(t,e),bC(e),vC(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=wC({videoTrack:i.videoTrack,videoStream:i.videoStream,audioStream:p,isMobileDevice:a,videoSettings:o,viewportMetadata:c,audioConfig:f,workerConfig:l,overlayConfig:h}),_=EC(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/MC}s — video stream may be unresponsive [${sC}]`);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=Ob({totalChunks:r.totalChunks,nonSilentChunks:r.nonSilentChunks,mutedDurationMs:r.mutedDurationMs,durationMs:n,hadTrackEndedWarning:this.audioTrackEndedDuringSession});if(!i.ok)throw Tb(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 cy({format:t,overrideCodec:e.audioCodec,policy:n,bitrate:r})}async resolveVideoCodec(e,t,n){return await sy({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=PC.get(i);if(a)return a;let o=await this.resolveAudioCodec(e,t,n,r);return zC(PC,i,o),o}async resolveVideoCodecWithCache(e,t,n){let r=this.buildVideoCodecCacheKey(e,t,n),i=FC.get(r);if(i)return i;let a=await this.resolveVideoCodec(e,t,n);return zC(FC,r,a),a}buildAudioCodecCacheKey(e,t,n,r){let i=IC(e.audioCodec),a=IC(n.preferredAudioCodec),o=LC(n.audioCodecFallbackOrder),s=IC(r);return[RC(NC,IC(t)),RC(`audioOverride`,i),RC(`audioBitrate`,s),RC(`policyPreferredAudio`,a),RC(`policyAudioFallback`,o)].join(`|`)}buildVideoCodecCacheKey(e,t,n){let r=IC(e.codec),i=IC(e.width),a=IC(e.height),o=IC(e.bitrate),s=IC(n.preferredVideoCodec),c=LC(n.videoCodecFallbackOrder);return[RC(NC,IC(t)),RC(`videoOverride`,r),RC(`width`,i),RC(`height`,a),RC(`videoBitrate`,o),RC(`policyPreferredVideo`,s),RC(`policyVideoFallback`,c)].join(`|`)}buildWorkerTranscodeConfig(e,t,n,r,i){return{width:e.width,height:e.height,fps:e.fps,bitrate:KS(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=GS(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=pC(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=hC(s,await this.getWorkerProbeResult(),o),l=TC(c.videoTrack,c.videoStream),u=EC(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 Px(jx,`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)/MC,recordingStats:this.buildRecordingStatsSummary(this.lastRecordingStats)});let t=this.lastRecordingStats;this.resetFinalizeRuntimeState(),n(Px(Mx,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)/MC,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);Vy(r),Hy(r),this.audioWasExpected&&(this.assertRuntimeAudioHealth(),Uy(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)/MC,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/MC});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&&=(jC(),!1)}},VC=class{constructor(e={}){this.currentVideoStream=null;let t=()=>new BC;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 HC=1e3,UC=`recording`,WC=`idle`,GC={route:`local-webcodecs`,reasonCodes:[`webcodecs-supported`,`target-codec-supported`]},KC={transcodeVideo:hy};function qC(e,t){let n=ly(t.format);return e.type.toLowerCase().startsWith(n)}var JC=class{constructor(e,t,n){this.recordingState=WC,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=GC,this.streamManager=e,this.callbacks=t,this.dependencies={...KC,...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!==UC||!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=WC,this.cancelCountdown()}}startCountdown(){this.recordingState=`countdown`,this.countdownRemaining=Math.ceil(this.countdownDuration/HC),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)/HC)),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=WC,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=WC,this.callbacks.onStateChange(this.recordingState);return}if(!n){this.handleError(Error(`Failed to get recording config`)),this.recordingState=WC,this.callbacks.onStateChange(this.recordingState);return}let i=await this.resolveRouteDecision();if(i instanceof Error){this.handleError(i),this.recordingState=WC,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=GC,this.handleError(a),this.recordingState=WC,this.callbacks.onStateChange(this.recordingState);return}if(this.startupAborted){this.startupAborted=!1;return}$.info(`[RecordingManager] Recording started successfully`),this.recordingState=UC,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!==UC){let e=this.recordingState;throw this.cancelCountdown(),Px(Ax,`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=WC,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=Fx(e);throw this.handleError(t),this.recordingState=WC,this.callbacks.onStateChange(this.recordingState),t}finally{this.activeRecordingConfig=null,this.activeRouteDecision=GC}}pauseRecording(){if(!(this.recordingState!==UC||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!==UC||!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=WC,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(qC(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 VC;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))):GC}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=Bx(this.recordingSeconds);this.callbacks.onTimerUpdate(e),this.recordingIntervalId=window.setInterval(()=>{this.recordingSeconds+=1;let e=Bx(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===UC&&!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===UC&&(this.clearTimer(this.recordingIntervalId,clearInterval),this.recordingIntervalId=null,this.clearTimer(this.maxTimeTimer,clearTimeout),this.maxTimeTimer=null,this.resetPauseState()),!(!this.streamProcessor&&this.recordingState!==UC)&&($.error(`[RecordingManager] Fatal processor error, stopping recording`,e),this.startupAborted=!0,this.streamProcessor&&=(this.streamProcessor.destroy(),null),this.recordingState=WC,this.callbacks.onStateChange(this.recordingState),this.recordingSeconds=0,this.callbacks.onError(e))}},YC=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}}},XC=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 ZC=`[RecorderController]`;var QC=class{constructor(e={}){this.uploadService=null,this.uploadQueueManager=null,this.isInitialized=!1,this.isDemo=!1,this.isDestroyed=!1,this.enableTabVisibilityOverlay=!1,this.isUploadInProgress=!1,this.recordingWarmupTimeoutId=null,this.audioTelemetryUnsub=null,this.callbacks=e,this.streamManager=new Xx,this.configManager=new dn,this.storageManager=new Lb,this.deviceManager=new fn(this.streamManager,e.device),this.audioLevelAnalyzer=new o,this.uploadService=new ES,this.uploadCallbacks=RS(e),this.telemetryManager=new YC({createTelemetryClient:wS}),this.uploadMetadataManager=new XC;let t=HS(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 JC(this.streamManager,t);let n=US(e,{isRecording:()=>this.isRecording(),updateSourceType:e=>{this.recordingManager.updateSourceType(e)},getSelectedCameraDeviceId:()=>this.deviceManager.getSelectedCameraDeviceId(),getSelectedMicDeviceId:()=>this.deviceManager.getSelectedMicDeviceId()});this.sourceSwitchManager=new hx(this.streamManager,n);let r=e.stream;r&&(this.streamManager.on(`streamstart`,({stream:e})=>{$.debug(`${ZC} streamstart event received, calling callback`),r.onStreamStart&&r.onStreamStart(e)}),this.streamManager.on(`streamstop`,()=>{$.debug(`${ZC} streamstop event received, calling callback`),r.onStreamStop&&r.onStreamStop()}),this.streamManager.on(`error`,({error:e})=>{$.error(`${ZC} 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(`${ZC} startStream called`),await this.streamManager.startStream(),this.ignorePromiseRejection(this.ensureConfigReady()),this.ignorePromiseRejection(this.configManager.getConfig().then(e=>{this.recordingManager.prewarmStreamProcessor(e)})),this.prewarmSupportCheck(),$.debug(`${ZC} 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()=>{if(this.isUploading())throw Px(Nx,`Previous recording is still being uploaded`);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 Db(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,e)}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()}uploadVideo(e,t,n,r){return this.uploadCallbacks.onClearStatus(),this.isUploadInProgress=!0,this.uploadVideoAfterStatusClear(e,t,n,r).catch(e=>{throw this.isUploadInProgress=!1,e})}async uploadVideoAfterStatusClear(e,t,n,r){let i=await Cv(e),a=this.configManager.getConfigForRecording().format,o=`recording-${Date.now()}.${uy(a)}`,s=ly(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}finally{this.isUploadInProgress=!1}}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.isUploadInProgress=!1,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}isUploading(){return this.isUploadInProgress}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 Vv({codecCandidates:n}),i=Zv({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),supportedEncodingCodecIds:t.codecProbeResults.filter(e=>e.encodingCapability?.supported===!0).map(e=>e.id),smoothEncodingCodecIds:t.codecProbeResults.filter(e=>e.encodingCapability?.smooth===!0).map(e=>e.id),powerEfficientEncodingCodecIds:t.codecProbeResults.filter(e=>e.encodingCapability?.powerEfficient===!0).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=BS(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),VS(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`,n=Error(e);this.telemetryManager.sendEvent(`storage.write.probe.failed`,{reason:e},n),VS(this.callbacks)(e);return}let n=this.storageManager.getStorageService();n&&this.uploadService&&(this.uploadQueueManager=new TS(n,this.uploadService),this.uploadQueueManager.setCallbacks({onUploadProgress:(e,t)=>{this.uploadCallbacks.onProgress(t)},onUploadComplete:(e,t)=>{this.isUploadInProgress=!1,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.isUploadInProgress=!1,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 gb({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(gb({requiresAudio:!0,requiresWatermark:!0}).then(e=>{this.streamManager.setPreResolvedSupportReport(e)}))}};let $C=/<a\s[^>]*href="(?<href>[^"]+)"[^>]*>(?<text>[^<]+)<\/a>/,ew=/\starget=["'](?<target>[^"']+)["']/,tw=/^[a-zA-Z][a-zA-Z\d+\-.]*:/,nw=`{version}`;function rw(e,t){return e?e.toLowerCase().includes(t):!1}function iw(e){let t=e.trim();if(!t)return null;let n=t.toLowerCase();return!tw.test(n)||n.startsWith(`http:`)||n.startsWith(`https:`)?t:null}function aw(e,t,n,r){return e===`browser.unsupported`?r.browserUnsupportedDynamic?cw(r.browserUnsupportedDynamic,t,n):rw(t,`safari`)?r.browserUnsupportedSafari:rw(t,`firefox`)?r.browserUnsupportedFirefox:r.browserUnsupported:r.browserUnsupported}function ow(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 sw(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 cw(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(nw,n),i):(i=i.replace(` ({version})`,``),i=i.replace(nw,``),i)}function lw(e){let t=$C.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=iw(t.groups.href);if(!o)return{prefix:i+t.groups.text+a,linkText:null,linkHref:null,linkTarget:null,suffix:``};let s=ew.exec(t[0])?.groups?.target??null;return{prefix:i,linkText:t.groups.text,linkHref:o,linkTarget:s,suffix:a}}function uw(){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 dw(){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 fw(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=dw(),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})},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 pw(e,t){let n=(e=>e===``||e===`default`?null:e)(t);return e.setCameraDevice(n),e.switchVideoDevice(n)}function mw(e,t){let n=(e=>e===``||e===`default`?null:e)(t);return e.setMicDevice(n),e.switchAudioDevice(n)}async function hw(e,t=`camera`){e.isActive()||await e.startStream(),t!==e.getCurrentSourceType()&&await e.switchSource(t),await e.startRecording()}async function gw(e,t,n,r){return await e.stopRecording()}function _w(e){e.pauseRecording()}function vw(e){e.resumeRecording()}async function yw(e,t){await e.switchSource(t)}let bw=`camera`,xw=`screen`,Sw=`recording`,Cw=`browser.unsupported`,ww=[.8,1.2,.9];function Tw(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 Ew(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 Dw=`none`,Ow=`flex`,kw=`inline-flex`,Aw=`checking`,jw=`blocked`,Mw=`ready`,Nw=`vidtreo-active`,Pw=`vidtreo-permission-flow--fading`,Fw=`vidtreo-permission-flow-action--requesting`;function Iw(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 Lw(e){return e.permissions.camera===`granted`?`microphone`:`camera`}function Rw(e,t){return t.cameraTitle}function zw(e,t){return t.cameraLabel}function Bw(e,t){return t.allowCamera}function Vw(e,t,n){let r=e.step,i=!1;(r===Aw||r===`awaiting-user`||r===jw||r===Mw)&&(i=!0);let a=r===Mw,o=r===jw,s=r===Aw,c=Lw(e),l=Rw(c,t),u=zw(c,t),d=Bw(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 Hw(e,t,n){if(e){if(t){e.style.display=n;return}e.style.display=Dw}}function Uw(e,t){if(t.isVisible)e.classList.add(Nw);else return e.classList.remove(Nw),e.classList.remove(Pw),!1;return t.isFadingOut?e.classList.add(Pw):e.classList.remove(Pw),!0}function Ww(e,t,n){Hw(e.actionButton,n,kw),e.actionButton&&(t.isRequesting?(e.actionButton.classList.add(Fw),e.actionButton.disabled=!0):(e.actionButton.classList.remove(Fw),e.actionButton.disabled=!1)),Hw(e.buttonIcon,n&&!t.isRequesting,kw),Hw(e.buttonSpinner,n&&t.isRequesting,kw),e.buttonText&&(t.isRequesting?e.buttonText.textContent=t.requestingText:e.buttonText.textContent=t.actionLabel)}function Gw(){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 Kw(e,t){if(Hw(e.recovery,t.isBlocked,Ow),e.recoveryTitle&&(e.recoveryTitle.textContent=t.recoveryTitleText),Hw(e.recoveryText,!1,Dw),Hw(e.retryButton,!1,Dw),t.isBlocked){let t=Gw();e.recoveryGuideUrl&&(e.recoveryGuideUrl.textContent=t),e.recoveryGuidePopoverUrl&&(e.recoveryGuidePopoverUrl.textContent=t)}}function qw(e,t){t&&(e.actionButton&&t.onAllow&&(e.actionButton.onclick=t.onAllow),e.retryButton&&t.onRetry&&(e.retryButton.onclick=t.onRetry))}function Jw(e,t,n){let{container:r}=t;if(!r||!Uw(r,e))return;let i=!e.isSpinnerOnly;Hw(t.spinner,e.isSpinnerOnly,kw),Hw(t.title,i&&!e.isBlocked,Ow),Hw(t.subtitle,i&&!e.isBlocked,Ow),t.title&&(t.title.textContent=e.titleText),t.subtitle&&(t.subtitle.textContent=e.subtitleText),Ww(t,e,i&&!e.isBlocked),Kw(t,e),qw(t,n)}function Yw(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 Xw(e){let{stream:t,transitionMessage:n,isVideoLoaded:r}=e;return{showPreviewSkeleton:!!t&&!r&&!n,showVideoPreview:!!t}}function Zw(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 Qw(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 $w(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 eT(e,t,n,r,i,a){if(e.stream)return{shouldShow:!1,iconClassName:``,browserErrorContent:null,textContent:null,hintText:null,retryButtonLabel:null};let o=fS({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=lw(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 tT(e,t){let n=!1;return e&&(n=!0),{shouldShow:n,text:t.switchingDevice}}function nT(e,t,n){let r=!1;return e===`countdown`&&t!==null&&(r=!0),{shouldShow:r,countdown:t,text:n.recordingStartsIn}}function rT(e,t){return{shouldShow:e,text:t.rec}}function iT(e,t){return{shouldShow:e,timer:t}}function aT(e){return{shouldShow:e}}function oT(e,t){let{state:n,isVideoLoaded:r,isRecording:i,translations:a}=e;sT(eT(n,a,aw(n.errorCode,n.browserName,n.browserVersion,{browserUnsupported:a.browserUnsupported,browserUnsupportedDynamic:a.browserUnsupportedDynamic,browserUnsupportedSafari:a.browserUnsupportedSafari,browserUnsupportedFirefox:a.browserUnsupportedFirefox}),ow(n.errorCode??``,{cameraInUse:a.cameraInUse,cameraNotFound:a.cameraNotFound,cameraPermissionDenied:a.cameraPermissionDenied,cameraTimeout:a.cameraTimeout,failedToStartCamera:a.failedToStartCamera}),sw(n.errorCode??``,{audioInUse:a.audioInUse,audioNotFound:a.audioNotFound,audioPermissionDenied:a.audioPermissionDenied,audioTimeout:a.audioTimeout,failedToStartAudio:a.failedToStartAudio}),a.retryCamera),t,e.onRetryCamera),cT(tT(n.transitionMessage,a),t),Zw(Xw({stream:n.stream,transitionMessage:n.transitionMessage,isVideoLoaded:r}),{previewSkeleton:t.previewSkeleton,videoPreview:t.videoPreview}),lT(nT(n.recordingState,n.countdown,a),t),uT(rT(i,a),t),dT(iT(i,n.timer),t),fT(aT(i),t)}function sT(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&&Yw(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 cT(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 lT(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 uT(e,t){let{recIndicatorTop:n}=t;n&&(e.shouldShow?n.style.display=`block`:n.style.display=`none`)}function dT(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 fT(e,t){let{audioLevelBars:n}=t;n&&(e.shouldShow?n.style.display=`flex`:n.style.display=`none`)}let pT=`inline-flex`;function mT(e){let{stream:t,buttonVisibility:n,currentSourceType:r,isMuted:i,isAudioReady:a,isProcessingRecording:o,isStopLocked:s,stopLockedTooltip:c,recordingState:l,buttonTranslations:u}=e,d=!!t,f=l===`idle`&&d&&!o,p=f&&!a,m=p?u.microphoneConnecting:``,h=!1;(n.showPauseButton||n.showResumeButton)&&(h=!0);let g=u.pause,_=`ph-fill ph-pause`;n.showResumeButton&&(g=u.resume,_=`ph-fill ph-play`);let v=u.mute,y=`ph-fill ph-microphone`;i&&(v=u.unmute,y=`ph-fill ph-microphone-slash`);let b=`ph-fill ph-monitor`;r!==bw&&(b=`ph-fill ph-camera`);let x=!1;return n.showDownloadButton&&(x=!0),{showRecordingControls:d,showSettingsButton:n.showSettingsButton,showRecordButton:f,isRecordDisabled:p,recordTooltip:m,showMuteButton:n.showMuteButton,showPauseButton:h,showStopButton:n.showStopButton,showSwitchSourceButton:n.showSwitchSourceButton,showDownloadButton:x,pauseTitle:g,pauseIconClassName:_,muteTitle:v,muteIconClassName:y,switchSourceIconClassName:b,isMuted:i,isStopLocked:s,stopLockedTooltip:c,settingsTitle:u.settings,switchSourceTitle:u.switchSource,downloadTitle:u.download,buttonTranslations:u}}function hT(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 gT(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;vT(n,e),yT(r,e),bT(i,e),xT(a,e),ST(o,e),CT(s,e),wT(c,e),TT(l,e),ET(u,e),DT(d,e),OT(f,e)}function _T(e,t,n){e&&(t?e.style.display=n:e.style.display=`none`)}function vT(e,t){_T(e,t.showRecordingControls,`block`)}function yT(e,t){_T(e,t.showSettingsButton,pT),e&&(e.title=t.settingsTitle)}function bT(e,t){if(_T(e,t.showRecordButton,pT),!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 xT(e,t){_T(e,t.showMuteButton,pT),e&&(e.title=t.muteTitle,e.classList.toggle(`vidtreo-muted`,t.isMuted))}function ST(e,t){e&&(e.className=t.muteIconClassName)}function CT(e,t){_T(e,t.showPauseButton,pT),e&&(e.title=t.pauseTitle)}function wT(e,t){e&&(e.className=t.pauseIconClassName)}function TT(e,t){if(_T(e,t.showStopButton,pT),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 ET(e,t){_T(e,t.showSwitchSourceButton,pT),e&&(e.title=t.switchSourceTitle)}function DT(e,t){e&&(e.className=t.switchSourceIconClassName)}function OT(e,t){_T(e,t.showDownloadButton,pT),e&&(e.title=t.downloadTitle)}function kT(e){let{stream:t,showSettings:n}=e,r=!1;return t&&n&&(r=!0),{shouldShow:r}}function AT(e,t,n){if(t){if(!e.shouldShow){t.classList.remove(`vidtreo-active`);return}t.classList.add(`vidtreo-active`),n()}}function jT(e){return e.toggleMute(),e.getIsMuted()}function MT(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 NT={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 PT=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]:(NT[this.lang]||NT.en)[e]}getAll(){return{...NT[this.lang]||NT.en,...this.customTexts}}};let FT=new Map;function IT(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 LT(e){e.style.pointerEvents=`auto`}function RT(e){e.style.pointerEvents=`none`}var zT=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,IT(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(),LT(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=FT.get(this.containerId);e||(e=new Set,FT.set(this.containerId,e)),e.add(this),this.isRegistered=!0}unregisterInstance(){if(!this.isRegistered)return;let e=FT.get(this.containerId);e&&(e.delete(this),e.size===0&&FT.delete(this.containerId)),this.isRegistered=!1}updatePortalContainerState(){if(!this.portalContainer)return;let e=FT.get(this.containerId);e&&e.size>0?LT(this.portalContainer):(RT(this.portalContainer),this.portalContainer.childNodes.length===0&&this.portalContainer.remove())}},BT=class{constructor(e){this.state={isModalOpen:!1,permissionRequested:!1,prevUploading:!1},this.escapeHandler=null,this.initCheckInterval=null,this.callbacks=e,this.portalManager=new zT}get canCloseModal(){let{recordingState:e,uploadProgress:t,transcodingProgress:n}=this.callbacks.getState();return!(e===`recording`||e===`countdown`||t!==null||n!==null)}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)}},VT=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 ES;this.handler=new vy({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 gy(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 HT(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 UT=class{constructor(e){if(this.proxyEndpoint=e.proxyEndpoint,this.proxyEndpoint)throw Error(`Proxy mode not yet implemented`);this.service=new ES}uploadVideo(e,t){if(this.proxyEndpoint)throw Error(`Proxy mode not yet implemented`);return this.service.uploadVideo(e,t)}},WT=`: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:auto;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 GT(e){return`
12830
- <style>${WT}</style>
12829
+ `],{type:`application/javascript`})}let PC=QS({createBlob:NC,createObjectUrl:e=>URL.createObjectURL(e),revokeObjectUrl:e=>{URL.revokeObjectURL(e)}});function FC(){return PC.acquire()}function IC(){PC.release()}let LC=1e3,RC=`format`,zC=new Map,BC=new Map;function VC(e){return e===void 0?`undefined`:String(e)}function HC(e){return e.join(`,`)}function UC(e,t){return`${e}=${t}`}function WC(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 GC=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 YS,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:(dC(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 MC({setTimeout:window.setTimeout.bind(window),clearTimeout:window.clearTimeout.bind(window),timeoutMilliseconds:2e3}),this.audioWorkletManager=new cC({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 Xy: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=FC();this.hasWorkerUrlLease=!0;try{this.worker=OC({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 cC({onChunk:this.handleAudioWorkletChunk.bind(this)});let r=this.resolveRecordingFormat(t),i=Ht(r,{isLinuxPlatform:this.isLinuxPlatformFn()}),a=this.resolveAudioBitrate(t,r),o=await this.resolveVideoCodecWithCache(t,r,i),s=XS(e);$.debug(`[WorkerProcessor] Starting processing`,{isScreenCapture:s,fps:t.fps,codec:o,bitrate:t.bitrate}),typeof t.fps==`number`&&t.fps>0&&(this.lastConfigFps=t.fps);let c=e.getVideoTracks(),l=e.getAudioTracks();$.debug(`[WorkerProcessor] Preparing to start processing`,{videoTracksCount:c.length,audioTracksCount:l.length,hasWorker:!!this.worker});try{let e=this.getVideoInputSelectorDependencies(),n=vC(c,e),s=yC(l,e),u=await this.getWorkerProbeResult();n&&($.debug(`[WorkerProcessor] Running video first-frame preflight`),await mC(n,3e3,this.videoFramePreflightDeps),$.debug(`[WorkerProcessor] Video first-frame preflight passed`));let d=bC(n,u,e),f=SC(e),p=xC(n);wC(n,e),TC(e),CC(n,s,d.videoStream,e);let m=e.getViewportMetadata(),h;m&&(h={orientationAngle:m.orientationAngle,windowOrientation:m.windowOrientation});let{audioConfig:g,audioStream:_,shouldStartAudioWorklet:v}=await this.prepareAudioPipeline(s,u),y=await this.resolveAudioCodecWithCache(t,r,i,a,g),b=this.buildWorkerTranscodeConfig(t,y,a,o,r),x=this.buildOverlayConfigToSend(),S=kC({videoTrack:d.videoTrack,videoStream:d.videoStream,audioStream:_,isMobileDevice:f,videoSettings:p,viewportMetadata:h,audioConfig:g,workerConfig:b,overlayConfig:x}),C=jC(d.videoStream,_,d.videoTrack);$.debug(`[WorkerProcessor] Posting message to worker`,{transferablesCount:C.length,messageType:S.type}),await this.postStartMessage(S,C,v),this.startNoFrameWatchdog(),v&&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/LC}s — video stream may be unresponsive [${fC}]`);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=Ab({totalChunks:r.totalChunks,nonSilentChunks:r.nonSilentChunks,mutedDurationMs:r.mutedDurationMs,durationMs:n,hadTrackEndedWarning:this.audioTrackEndedDuringSession});if(!i.ok)throw Db(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,i){return await uy({format:t,overrideCodec:e.audioCodec,policy:n,bitrate:r,numberOfChannels:i?.numberOfChannels,sampleRate:i?.sampleRate})}async resolveVideoCodec(e,t,n){return await ly({format:t,overrideCodec:e.codec,policy:n,width:e.width,height:e.height,bitrate:e.bitrate})}async resolveAudioCodecWithCache(e,t,n,r,i){let a=this.buildAudioCodecCacheKey(e,t,n,r,i),o=zC.get(a);if(o)return o;let s=await this.resolveAudioCodec(e,t,n,r,i);return WC(zC,a,s),s}async resolveVideoCodecWithCache(e,t,n){let r=this.buildVideoCodecCacheKey(e,t,n),i=BC.get(r);if(i)return i;let a=await this.resolveVideoCodec(e,t,n);return WC(BC,r,a),a}buildAudioCodecCacheKey(e,t,n,r,i){let a=VC(e.audioCodec),o=VC(n.preferredAudioCodec),s=HC(n.audioCodecFallbackOrder),c=VC(r),l=VC(i?.numberOfChannels),u=VC(i?.sampleRate);return[UC(RC,VC(t)),UC(`audioOverride`,a),UC(`audioBitrate`,c),UC(`audioChannels`,l),UC(`audioSampleRate`,u),UC(`policyPreferredAudio`,o),UC(`policyAudioFallback`,s)].join(`|`)}buildVideoCodecCacheKey(e,t,n){let r=VC(e.codec),i=VC(e.width),a=VC(e.height),o=VC(e.bitrate),s=VC(n.preferredVideoCodec),c=HC(n.videoCodecFallbackOrder);return[UC(RC,VC(t)),UC(`videoOverride`,r),UC(`width`,i),UC(`height`,a),UC(`videoBitrate`,o),UC(`policyPreferredVideo`,s),UC(`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=XS(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=vC(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=bC(s,await this.getWorkerProbeResult(),o),l=AC(c.videoTrack,c.videoStream),u=jC(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 Ix(Nx,`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)/LC,recordingStats:this.buildRecordingStatsSummary(this.lastRecordingStats)});let t=this.lastRecordingStats;this.resetFinalizeRuntimeState(),n(Ix(Px,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)/LC,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);Uy(r),Wy(r),this.audioWasExpected&&(this.assertRuntimeAudioHealth(),Gy(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)/LC,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,null).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/LC});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&&=(IC(),!1)}},KC=class{constructor(e={}){this.currentVideoStream=null;let t=()=>new GC;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 qC=1e3,JC=`recording`,YC=`idle`,XC={route:`local-webcodecs`,reasonCodes:[`webcodecs-supported`,`target-codec-supported`]},ZC={transcodeVideo:_y};function QC(e,t){let n=dy(t.format);return e.type.toLowerCase().startsWith(n)}var $C=class{constructor(e,t,n){this.recordingState=YC,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=XC,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!==JC||!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=YC,this.cancelCountdown()}}startCountdown(){this.recordingState=`countdown`,this.countdownRemaining=Math.ceil(this.countdownDuration/qC),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)/qC)),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=YC,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=YC,this.callbacks.onStateChange(this.recordingState);return}if(!n){this.handleError(Error(`Failed to get recording config`)),this.recordingState=YC,this.callbacks.onStateChange(this.recordingState);return}let i=await this.resolveRouteDecision();if(i instanceof Error){this.handleError(i),this.recordingState=YC,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=XC,this.handleError(a),this.recordingState=YC,this.callbacks.onStateChange(this.recordingState);return}if(this.startupAborted){this.startupAborted=!1;return}$.info(`[RecordingManager] Recording started successfully`),this.recordingState=JC,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!==JC){let e=this.recordingState;throw this.cancelCountdown(),Ix(Mx,`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=YC,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),e.mediaRecorderDiagnostics!==void 0&&Object.assign(n,e.mediaRecorderDiagnostics),{blob:t,telemetryProperties:n}}catch(e){let t=Lx(e);throw this.handleError(t),this.recordingState=YC,this.callbacks.onStateChange(this.recordingState),this.streamProcessor&&=(this.streamProcessor.destroy(),null),t}finally{this.activeRecordingConfig=null,this.activeRouteDecision=XC}}pauseRecording(){if(!(this.recordingState!==JC||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!==JC||!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=YC,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(QC(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 KC;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))):XC}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=Hx(this.recordingSeconds);this.callbacks.onTimerUpdate(e),this.recordingIntervalId=window.setInterval(()=>{this.recordingSeconds+=1;let e=Hx(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===JC&&!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===JC&&(this.clearTimer(this.recordingIntervalId,clearInterval),this.recordingIntervalId=null,this.clearTimer(this.maxTimeTimer,clearTimeout),this.maxTimeTimer=null,this.resetPauseState()),!(!this.streamProcessor&&this.recordingState!==JC)&&($.error(`[RecordingManager] Fatal processor error, stopping recording`,e),this.startupAborted=!0,this.streamProcessor&&=(this.streamProcessor.destroy(),null),this.recordingState=YC,this.callbacks.onStateChange(this.recordingState),this.recordingSeconds=0,this.callbacks.onError(e))}},ew=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}}},tw=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 nw=`[RecorderController]`;var rw=class{constructor(e={}){this.uploadService=null,this.uploadQueueManager=null,this.isInitialized=!1,this.isDemo=!1,this.isDestroyed=!1,this.enableTabVisibilityOverlay=!1,this.isUploadInProgress=!1,this.recordingWarmupTimeoutId=null,this.audioTelemetryUnsub=null,this.callbacks=e,this.streamManager=new eS,this.configManager=new dn,this.storageManager=new zb,this.deviceManager=new fn(this.streamManager,e.device),this.audioLevelAnalyzer=new o,this.uploadService=new jS,this.uploadCallbacks=US(e),this.telemetryManager=new ew({createTelemetryClient:kS}),this.uploadMetadataManager=new tw;let t=qS(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 $C(this.streamManager,t);let n=JS(e,{isRecording:()=>this.isRecording(),updateSourceType:e=>{this.recordingManager.updateSourceType(e)},getSelectedCameraDeviceId:()=>this.deviceManager.getSelectedCameraDeviceId(),getSelectedMicDeviceId:()=>this.deviceManager.getSelectedMicDeviceId()});this.sourceSwitchManager=new _x(this.streamManager,n);let r=e.stream;r&&(this.streamManager.on(`streamstart`,({stream:e})=>{$.debug(`${nw} streamstart event received, calling callback`),r.onStreamStart&&r.onStreamStart(e)}),this.streamManager.on(`streamstop`,()=>{$.debug(`${nw} streamstop event received, calling callback`),r.onStreamStop&&r.onStreamStop()}),this.streamManager.on(`error`,({error:e})=>{$.error(`${nw} 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(`${nw} startStream called`),await this.streamManager.startStream(),this.ignorePromiseRejection(this.ensureConfigReady()),this.ignorePromiseRejection(this.configManager.getConfig().then(e=>{this.recordingManager.prewarmStreamProcessor(e)})),this.prewarmSupportCheck(),$.debug(`${nw} 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()=>{if(this.isUploading())throw Ix(Fx,`Previous recording is still being uploaded`);await this.ensureConfigReady(),await this.streamManager.waitForAudio(),await this.recordingManager.startRecording()},properties:{sourceType:e}})}async stopRecording(){let e=this.getCurrentSourceType(),t=!0;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`)}),e},properties:{sourceType:e},getPropertiesFromResult:e=>e.telemetryProperties})).blob}catch(e){throw t=this.shouldStopStreamAfterStopFailure(e),kb(e)&&this.sendAudioMissingTelemetry(e),e}finally{t&&this.streamManager.stopStream()}}shouldStopStreamAfterStopFailure(e){return e&&typeof e==`object`&&`code`in e?e.code!==Mx:!0}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,e)}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()}uploadVideo(e,t,n,r){return this.uploadCallbacks.onClearStatus(),this.isUploadInProgress=!0,this.uploadVideoAfterStatusClear(e,t,n,r).catch(e=>{throw this.isUploadInProgress=!1,e})}async uploadVideoAfterStatusClear(e,t,n,r){let i=await Cv(e),a=this.configManager.getConfigForRecording().format,o=`recording-${Date.now()}.${fy(a)}`,s=dy(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}finally{this.isUploadInProgress=!1}}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.isUploadInProgress=!1,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}isUploading(){return this.isUploadInProgress}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 Vv({codecCandidates:n}),i=$v({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),supportedEncodingCodecIds:t.codecProbeResults.filter(e=>e.encodingCapability?.supported===!0).map(e=>e.id),smoothEncodingCodecIds:t.codecProbeResults.filter(e=>e.encodingCapability?.smooth===!0).map(e=>e.id),powerEfficientEncodingCodecIds:t.codecProbeResults.filter(e=>e.encodingCapability?.powerEfficient===!0).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=GS(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),KS(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`,n=Error(e);this.telemetryManager.sendEvent(`storage.write.probe.failed`,{reason:e},n),KS(this.callbacks)(e);return}let n=this.storageManager.getStorageService();n&&this.uploadService&&(this.uploadQueueManager=new AS(n,this.uploadService),this.uploadQueueManager.setCallbacks({onUploadProgress:(e,t)=>{this.uploadCallbacks.onProgress(t)},onUploadComplete:(e,t)=>{this.isUploadInProgress=!1,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.isUploadInProgress=!1,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 vb({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(vb({requiresAudio:!0,requiresWatermark:!0}).then(e=>{this.streamManager.setPreResolvedSupportReport(e)}))}};let iw=/<a\s[^>]*href="(?<href>[^"]+)"[^>]*>(?<text>[^<]+)<\/a>/,aw=/\starget=["'](?<target>[^"']+)["']/,ow=/^[a-zA-Z][a-zA-Z\d+\-.]*:/,sw=`{version}`;function cw(e,t){return e?e.toLowerCase().includes(t):!1}function lw(e){let t=e.trim();if(!t)return null;let n=t.toLowerCase();return!ow.test(n)||n.startsWith(`http:`)||n.startsWith(`https:`)?t:null}function uw(e,t,n,r){return e===`browser.unsupported`?r.browserUnsupportedDynamic?pw(r.browserUnsupportedDynamic,t,n):cw(t,`safari`)?r.browserUnsupportedSafari:cw(t,`firefox`)?r.browserUnsupportedFirefox:r.browserUnsupported:r.browserUnsupported}function dw(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 fw(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 pw(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(sw,n),i):(i=i.replace(` ({version})`,``),i=i.replace(sw,``),i)}function mw(e){let t=iw.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=lw(t.groups.href);if(!o)return{prefix:i+t.groups.text+a,linkText:null,linkHref:null,linkTarget:null,suffix:``};let s=aw.exec(t[0])?.groups?.target??null;return{prefix:i,linkText:t.groups.text,linkHref:o,linkTarget:s,suffix:a}}function hw(){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 gw(){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 _w(e){let t=t=>{if(!(`code`in t))return;let n=t,r=typeof n.code==`string`?n.code:null;if(r===null)return;if(r!==`browser.unsupported`){(r.startsWith(`camera.`)||r.startsWith(`audio.`)||r.startsWith(`recording.`))&&e.updateState({errorCode:r,canRetry:!0,browserName:null,browserVersion:null});return}let i=gw(),a=i.browserName;n.browserName&&n.browserName.length>0&&(a=n.browserName);let o=i.browserVersion;n.browserVersion&&n.browserVersion.length>0&&(o=n.browserVersion),e.updateState({errorCode:`browser.unsupported`,canRetry:!1,browserName:a,browserVersion:o})};return{recording:{onStateChange:t=>{e.updateState({recordingState:t})},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,uploadProgress:null})},onRecordingComplete:t=>{e.updateState({countdown:null}),e.processRecordingBlob(t).catch(t=>{e.updateState({error:i(t),transcodingProgress:null,uploadProgress:null})})},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 vw(e,t){let n=(e=>e===``||e===`default`?null:e)(t);return e.setCameraDevice(n),e.switchVideoDevice(n)}function yw(e,t){let n=(e=>e===``||e===`default`?null:e)(t);return e.setMicDevice(n),e.switchAudioDevice(n)}async function bw(e,t=`camera`){e.isActive()||await e.startStream(),t!==e.getCurrentSourceType()&&await e.switchSource(t),await e.startRecording()}async function xw(e,t,n,r){return await e.stopRecording()}function Sw(e){e.pauseRecording()}function Cw(e){e.resumeRecording()}async function ww(e,t){await e.switchSource(t)}let Tw=`camera`,Ew=`screen`,Dw=`recording`,Ow=`browser.unsupported`,kw=[.8,1.2,.9];function Aw(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`,jw(i.querySelector(`#finishingProgress`),!1),jw(i.querySelector(`#uploadProgress`),!1);return}i.style.display=`block`;let s=i.querySelector(`#finishingProgress`),c=i.querySelector(`#uploadProgress`),l=e.isTranscoding===!0&&s!==null;jw(s,l),jw(c,!l);let u=Math.round(n*100),d=a,f=o;if(l){let e=i.querySelector(`#finishingProgressFill`),t=i.querySelector(`#finishingProgressText`);e!==null&&(d=e),t!==null&&(f=t)}d&&(d.style.width=`${u}%`),f&&(f.textContent=`${r} ${u}%`)}function jw(e,t){e&&(e.style.display=t?`block`:`none`)}function Mw(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 Nw=`none`,Pw=`flex`,Fw=`inline-flex`,Iw=`checking`,Lw=`blocked`,Rw=`ready`,zw=`vidtreo-active`,Bw=`vidtreo-permission-flow--fading`,Vw=`vidtreo-permission-flow-action--requesting`;function Hw(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 Uw(e){return e.permissions.camera===`granted`?`microphone`:`camera`}function Ww(e,t){return t.cameraTitle}function Gw(e,t){return t.cameraLabel}function Kw(e,t){return t.allowCamera}function qw(e,t,n){let r=e.step,i=!1;(r===Iw||r===`awaiting-user`||r===Lw||r===Rw)&&(i=!0);let a=r===Rw,o=r===Lw,s=r===Iw,c=Uw(e),l=Ww(c,t),u=Gw(c,t),d=Kw(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 Jw(e,t,n){if(e){if(t){e.style.display=n;return}e.style.display=Nw}}function Yw(e,t){if(t.isVisible)e.classList.add(zw);else return e.classList.remove(zw),e.classList.remove(Bw),!1;return t.isFadingOut?e.classList.add(Bw):e.classList.remove(Bw),!0}function Xw(e,t,n){Jw(e.actionButton,n,Fw),e.actionButton&&(t.isRequesting?(e.actionButton.classList.add(Vw),e.actionButton.disabled=!0):(e.actionButton.classList.remove(Vw),e.actionButton.disabled=!1)),Jw(e.buttonIcon,n&&!t.isRequesting,Fw),Jw(e.buttonSpinner,n&&t.isRequesting,Fw),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 Qw(e,t){if(Jw(e.recovery,t.isBlocked,Pw),e.recoveryTitle&&(e.recoveryTitle.textContent=t.recoveryTitleText),Jw(e.recoveryText,!1,Nw),Jw(e.retryButton,!1,Nw),t.isBlocked){let t=Zw();e.recoveryGuideUrl&&(e.recoveryGuideUrl.textContent=t),e.recoveryGuidePopoverUrl&&(e.recoveryGuidePopoverUrl.textContent=t)}}function $w(e,t){t&&(e.actionButton&&t.onAllow&&(e.actionButton.onclick=t.onAllow),e.retryButton&&t.onRetry&&(e.retryButton.onclick=t.onRetry))}function eT(e,t,n){let{container:r}=t;if(!r||!Yw(r,e))return;let i=!e.isSpinnerOnly;Jw(t.spinner,e.isSpinnerOnly,Fw),Jw(t.title,i&&!e.isBlocked,Pw),Jw(t.subtitle,i&&!e.isBlocked,Pw),t.title&&(t.title.textContent=e.titleText),t.subtitle&&(t.subtitle.textContent=e.subtitleText),Xw(t,e,i&&!e.isBlocked),Qw(t,e),$w(t,n)}function tT(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 nT(e){let{stream:t,transitionMessage:n,isVideoLoaded:r}=e;return{showPreviewSkeleton:!!t&&!r&&!n,showVideoPreview:!!t}}function rT(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 iT(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 aT(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 oT(e,t,n,r,i,a){if(e.stream)return{shouldShow:!1,iconClassName:``,browserErrorContent:null,textContent:null,hintText:null,retryButtonLabel:null};let o=gS({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=mw(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 sT(e,t){let n=!1;return e&&(n=!0),{shouldShow:n,text:t.switchingDevice}}function cT(e,t,n){let r=!1;return e===`countdown`&&t!==null&&(r=!0),{shouldShow:r,countdown:t,text:n.recordingStartsIn}}function lT(e,t){return{shouldShow:e,text:t.rec}}function uT(e,t){return{shouldShow:e,timer:t}}function dT(e){return{shouldShow:e}}function fT(e,t){let{state:n,isVideoLoaded:r,isRecording:i,translations:a}=e;pT(oT(n,a,uw(n.errorCode,n.browserName,n.browserVersion,{browserUnsupported:a.browserUnsupported,browserUnsupportedDynamic:a.browserUnsupportedDynamic,browserUnsupportedSafari:a.browserUnsupportedSafari,browserUnsupportedFirefox:a.browserUnsupportedFirefox}),dw(n.errorCode??``,{cameraInUse:a.cameraInUse,cameraNotFound:a.cameraNotFound,cameraPermissionDenied:a.cameraPermissionDenied,cameraTimeout:a.cameraTimeout,failedToStartCamera:a.failedToStartCamera}),fw(n.errorCode??``,{audioInUse:a.audioInUse,audioNotFound:a.audioNotFound,audioPermissionDenied:a.audioPermissionDenied,audioTimeout:a.audioTimeout,failedToStartAudio:a.failedToStartAudio}),a.retryCamera),t,e.onRetryCamera),mT(sT(n.transitionMessage,a),t),rT(nT({stream:n.stream,transitionMessage:n.transitionMessage,isVideoLoaded:r}),{previewSkeleton:t.previewSkeleton,videoPreview:t.videoPreview}),hT(cT(n.recordingState,n.countdown,a),t),gT(lT(i,a),t),_T(uT(i,n.timer),t),vT(dT(i),t)}function pT(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&&tT(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 mT(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 hT(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 gT(e,t){let{recIndicatorTop:n}=t;n&&(e.shouldShow?n.style.display=`block`:n.style.display=`none`)}function _T(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 vT(e,t){let{audioLevelBars:n}=t;n&&(e.shouldShow?n.style.display=`flex`:n.style.display=`none`)}let yT=`inline-flex`;function bT(e){let{stream:t,buttonVisibility:n,currentSourceType:r,isMuted:i,isAudioReady:a,isProcessingRecording:o,isStopLocked:s,stopLockedTooltip:c,recordingState:l,buttonTranslations:u}=e,d=!!t,f=l===`idle`&&d&&!o,p=f&&!a,m=p?u.microphoneConnecting:``,h=!1;(n.showPauseButton||n.showResumeButton)&&(h=!0);let g=u.pause,_=`ph-fill ph-pause`;n.showResumeButton&&(g=u.resume,_=`ph-fill ph-play`);let v=u.mute,y=`ph-fill ph-microphone`;i&&(v=u.unmute,y=`ph-fill ph-microphone-slash`);let b=`ph-fill ph-monitor`;r!==Tw&&(b=`ph-fill ph-camera`);let x=!1;return n.showDownloadButton&&(x=!0),{showRecordingControls:d,showSettingsButton:n.showSettingsButton,showRecordButton:f,isRecordDisabled:p,recordTooltip:m,showMuteButton:n.showMuteButton,showPauseButton:h,showStopButton:n.showStopButton,showSwitchSourceButton:n.showSwitchSourceButton,showDownloadButton:x,pauseTitle:g,pauseIconClassName:_,muteTitle:v,muteIconClassName:y,switchSourceIconClassName:b,isMuted:i,isStopLocked:s,stopLockedTooltip:c,settingsTitle:u.settings,switchSourceTitle:u.switchSource,downloadTitle:u.download,buttonTranslations:u}}function xT(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 ST(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;wT(n,e),TT(r,e),ET(i,e),DT(a,e),OT(o,e),kT(s,e),AT(c,e),jT(l,e),MT(u,e),NT(d,e),PT(f,e)}function CT(e,t,n){e&&(t?e.style.display=n:e.style.display=`none`)}function wT(e,t){CT(e,t.showRecordingControls,`block`)}function TT(e,t){CT(e,t.showSettingsButton,yT),e&&(e.title=t.settingsTitle)}function ET(e,t){if(CT(e,t.showRecordButton,yT),!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 DT(e,t){CT(e,t.showMuteButton,yT),e&&(e.title=t.muteTitle,e.classList.toggle(`vidtreo-muted`,t.isMuted))}function OT(e,t){e&&(e.className=t.muteIconClassName)}function kT(e,t){CT(e,t.showPauseButton,yT),e&&(e.title=t.pauseTitle)}function AT(e,t){e&&(e.className=t.pauseIconClassName)}function jT(e,t){if(CT(e,t.showStopButton,yT),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 MT(e,t){CT(e,t.showSwitchSourceButton,yT),e&&(e.title=t.switchSourceTitle)}function NT(e,t){e&&(e.className=t.switchSourceIconClassName)}function PT(e,t){CT(e,t.showDownloadButton,yT),e&&(e.title=t.downloadTitle)}function FT(e){let{stream:t,showSettings:n}=e,r=!1;return t&&n&&(r=!0),{shouldShow:r}}function IT(e,t,n){if(t){if(!e.shouldShow){t.classList.remove(`vidtreo-active`);return}t.classList.add(`vidtreo-active`),n()}}function LT(e){return e.toggleMute(),e.getIsMuted()}function RT(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 zT={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 BT=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]:(zT[this.lang]||zT.en)[e]}getAll(){return{...zT[this.lang]||zT.en,...this.customTexts}}};let VT=new Map;function HT(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 UT(e){e.style.pointerEvents=`auto`}function WT(e){e.style.pointerEvents=`none`}var GT=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,HT(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(),UT(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=VT.get(this.containerId);e||(e=new Set,VT.set(this.containerId,e)),e.add(this),this.isRegistered=!0}unregisterInstance(){if(!this.isRegistered)return;let e=VT.get(this.containerId);e&&(e.delete(this),e.size===0&&VT.delete(this.containerId)),this.isRegistered=!1}updatePortalContainerState(){if(!this.portalContainer)return;let e=VT.get(this.containerId);e&&e.size>0?UT(this.portalContainer):(WT(this.portalContainer),this.portalContainer.childNodes.length===0&&this.portalContainer.remove())}},KT=class{constructor(e){this.state={isModalOpen:!1,permissionRequested:!1,prevUploading:!1},this.escapeHandler=null,this.initCheckInterval=null,this.callbacks=e,this.portalManager=new GT}get canCloseModal(){let{recordingState:e,uploadProgress:t,transcodingProgress:n}=this.callbacks.getState();return!(e===`recording`||e===`countdown`||t!==null||n!==null)}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)}},qT=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 jS;this.handler=new by({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 vy(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 JT(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 YT=class{constructor(e){if(this.proxyEndpoint=e.proxyEndpoint,this.proxyEndpoint)throw Error(`Proxy mode not yet implemented`);this.service=new jS}uploadVideo(e,t){if(this.proxyEndpoint)throw Error(`Proxy mode not yet implemented`);return this.service.uploadVideo(e,t)}},XT=`: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:auto;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
+ <style>${XT}</style>
12831
12831
  <div class="vidtreo-mobile-landing-container">
12832
12832
  <div class="vidtreo-mobile-landing-content">
12833
12833
  <h2 class="vidtreo-mobile-landing-title">
@@ -12845,8 +12845,8 @@ Mediabunny was loaded twice.\` + " This will likely cause Mediabunny not to work
12845
12845
  </button>
12846
12846
  </div>
12847
12847
  </div>
12848
- `}function KT(e,t,n){return`
12849
- <style>${WT}</style>
12848
+ `}function QT(e,t,n){return`
12849
+ <style>${XT}</style>
12850
12850
  <div class="vidtreo-mobile-modal-overlay" role="dialog" aria-modal="true" aria-label="${e.t(`mobileOpenCameraTitle`)}">
12851
12851
  <div class="vidtreo-mobile-modal-header">
12852
12852
  <!-- Left: Recording Indicator -->
@@ -12881,8 +12881,8 @@ Mediabunny was loaded twice.\` + " This will likely cause Mediabunny not to work
12881
12881
  ${n}
12882
12882
  </div>
12883
12883
  </div>
12884
- `}function qT(e){return`
12885
- <style>${WT}</style>
12884
+ `}function $T(e){return`
12885
+ <style>${XT}</style>
12886
12886
  <div class="vidtreo-native-camera-container">
12887
12887
  <input
12888
12888
  type="file"
@@ -12941,7 +12941,7 @@ Mediabunny was loaded twice.\` + " This will likely cause Mediabunny not to work
12941
12941
  </div>
12942
12942
 
12943
12943
  </div>
12944
- `}function JT(e){return`
12944
+ `}function eE(e){return`
12945
12945
  <div class="vidtreo-mobile-recorder-content">
12946
12946
  <div class="vidtreo-preview-container vidtreo-mobile-preview">
12947
12947
 
@@ -13100,8 +13100,8 @@ Mediabunny was loaded twice.\` + " This will likely cause Mediabunny not to work
13100
13100
 
13101
13101
  </div>
13102
13102
  </div>
13103
- `}let YT=()=>`
13104
- <style>${WT}</style>
13103
+ `}let tE=()=>`
13104
+ <style>${XT}</style>
13105
13105
  <div class="vidtreo-camera-area vidtreo-active" id="cameraArea">
13106
13106
  <!-- Error Boundary / Preview Container -->
13107
13107
  <div class="vidtreo-preview-container">
@@ -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 XT(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 ZT=/^https?:\/\//i;function QT(e){return e?ZT.test(e)?e:`https://${e}`:`https://core.vidtreo.com`}function $T(e,t,n){let r=e.getAttribute(t);return r===null?n:r!==`false`}function eE(e,t){let n=e.getAttribute(t);if(!n)return;let r=Number.parseInt(n,10);if(!Number.isNaN(r))return r}function tE(e,t){let n=e.getAttribute(t);if(n!==null)return n}function nE(e){return{apiKey:e.getAttribute(`api-key`)||``,backendUrl:QT(e.getAttribute(`backend-url`)),demo:$T(e,`demo`,!1),enableSourceSwitching:$T(e,`enable-source-switching`,!0),enableMute:$T(e,`enable-mute`,!0),enablePause:$T(e,`enable-pause`,!0),enableDeviceChange:$T(e,`enable-device-change`,!0),enableTabVisibilityOverlay:$T(e,`enable-tab-visibility-overlay`,!1)}}function rE(e){let t={},n=eE(e,`countdown-duration`);n!==void 0&&(t.countdownDuration=n);let r=eE(e,`max-recording-time`);r!==void 0&&(t.maxRecordingTime=r);let i=eE(e,`min-time-record`);return i!==void 0&&(t.minTimeRecord=i),t}function iE(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 aE(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 oE(e,t,n){let r=nE(e),i=rE(e),a=tE(e,`tab-visibility-overlay-text`),o=iE(r.enableTabVisibilityOverlay===!0,a,n),s=aE(e,t),c={...r,...i};return o!==void 0&&(c={...c,tabVisibilityOverlayText:o}),s!==void 0&&(c={...c,userMetadata:s}),c}function sE(){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 cE=1e3,lE=/^\d+$/;function uE(e){return lE.test(e)}function dE(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(!uE(e))return 0;if(n.length===2){let e=Number.parseInt(n[0],10),t=Number.parseInt(n[1],10);return(e*60+t)*cE}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)*cE}function fE(e,t,n){return!n||e==null||Number.isFinite(e)===!1||e<=0?!1:dE(t)<e}function pE(){let e=Error(`Minimum recording time has not been reached yet`);return e.code=`recording.minimum-time-not-reached`,e}let mE={requiresAudio:!1,requiresWatermark:!1},hE={step:`idle`,permissions:{camera:`unknown`,microphone:`unknown`},denialType:`none`,isSecureContext:!0,isComplete:!1,canRetry:!0,shouldProbeUnknown:!0},gE={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 _E=class extends HTMLElement{constructor(...e){super(...e),this.controller=null,this.audioStatusUnsub=null,this.uploadService=null,this.state={...gE},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=hE,this.overlayPhase=`hidden`,this.overlayFadeTimeoutId=null,this.isStartingPreview=!1,this.i18n=new PT,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 gb(mE).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=dw();this.updateState({errorCode:Cw,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!==Cw)return;let n=dw(),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:Cw,canRetry:!1,browserName:r,browserVersion:i})}resolveBrowserErrorState(){let e=this.state.errorCode,t=this.state.browserName,n=this.state.browserVersion;if(e===Cw&&t===null){let e=dw();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(!uw()){this.innerHTML=YT(),this.init();return}if(e===`native`){this.initNativeCamera();return}if(e===`overlay`){this.mobileManager=new BT({getState:()=>({recordingState:this.state.recordingState,uploadProgress:this.state.uploadProgress,transcodingProgress:this.state.transcodingProgress}),isInitialized:()=>this.initialized,startPreview:()=>this.startPreview(),stopPreview:()=>this.stopPreview(),renderMobile:()=>this.renderMobile()}),this.renderMobile(),this.init();return}this.innerHTML=YT(),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 VT({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(),sE()}renderNativeCamera(){if(!this.nativeCameraManager)return;let e=this.nativeCameraManager.getState();this.innerHTML=qT(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 nE(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 rE=/^https?:\/\//i;function iE(e){return e?rE.test(e)?e:`https://${e}`:`https://core.vidtreo.com`}function aE(e,t,n){let r=e.getAttribute(t);return r===null?n:r!==`false`}function oE(e,t){let n=e.getAttribute(t);if(!n)return;let r=Number.parseInt(n,10);if(!Number.isNaN(r))return r}function sE(e,t){let n=e.getAttribute(t);if(n!==null)return n}function cE(e){return{apiKey:e.getAttribute(`api-key`)||``,backendUrl:iE(e.getAttribute(`backend-url`)),demo:aE(e,`demo`,!1),enableSourceSwitching:aE(e,`enable-source-switching`,!0),enableMute:aE(e,`enable-mute`,!0),enablePause:aE(e,`enable-pause`,!0),enableDeviceChange:aE(e,`enable-device-change`,!0),enableTabVisibilityOverlay:aE(e,`enable-tab-visibility-overlay`,!1)}}function lE(e){let t={},n=oE(e,`countdown-duration`);n!==void 0&&(t.countdownDuration=n);let r=oE(e,`max-recording-time`);r!==void 0&&(t.maxRecordingTime=r);let i=oE(e,`min-time-record`);return i!==void 0&&(t.minTimeRecord=i),t}function uE(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 dE(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 fE(e,t,n){let r=cE(e),i=lE(e),a=sE(e,`tab-visibility-overlay-text`),o=uE(r.enableTabVisibilityOverlay===!0,a,n),s=dE(e,t),c={...r,...i};return o!==void 0&&(c={...c,tabVisibilityOverlayText:o}),s!==void 0&&(c={...c,userMetadata:s}),c}function pE(){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 mE=1e3,hE=/^\d+$/;function gE(e){return hE.test(e)}function _E(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(!gE(e))return 0;if(n.length===2){let e=Number.parseInt(n[0],10),t=Number.parseInt(n[1],10);return(e*60+t)*mE}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)*mE}function vE(e,t,n){return!n||e==null||Number.isFinite(e)===!1||e<=0?!1:_E(t)<e}function yE(){let e=Error(`Minimum recording time has not been reached yet`);return e.code=`recording.minimum-time-not-reached`,e}let bE={requiresAudio:!1,requiresWatermark:!1},xE={step:`idle`,permissions:{camera:`unknown`,microphone:`unknown`},denialType:`none`,isSecureContext:!0,isComplete:!1,canRetry:!0,shouldProbeUnknown:!0},SE={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 CE=class extends HTMLElement{constructor(...e){super(...e),this.controller=null,this.audioStatusUnsub=null,this.uploadService=null,this.state={...SE},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=xE,this.overlayPhase=`hidden`,this.overlayFadeTimeoutId=null,this.isStartingPreview=!1,this.i18n=new BT,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 vb(bE).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=gw();this.updateState({errorCode:Ow,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,n=typeof t.code==`string`?t.code:null;if(n===null)return;if(n.startsWith(`camera.`)||n.startsWith(`audio.`)||n.startsWith(`recording.`)){this.updateState({errorCode:n,canRetry:!0,browserName:null,browserVersion:null});return}if(n!==Ow)return;let r=gw(),i=r.browserName;t.browserName&&t.browserName.length>0&&(i=t.browserName);let a=r.browserVersion;t.browserVersion&&t.browserVersion.length>0&&(a=t.browserVersion),this.updateState({errorCode:Ow,canRetry:!1,browserName:i,browserVersion:a})}resolveBrowserErrorState(){let e=this.state.errorCode,t=this.state.browserName,n=this.state.browserVersion;if(e===Ow&&t===null){let e=gw();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(!hw()){this.innerHTML=tE(),this.init();return}if(e===`native`){this.initNativeCamera();return}if(e===`overlay`){this.mobileManager=new KT({getState:()=>({recordingState:this.state.recordingState,uploadProgress:this.state.uploadProgress,transcodingProgress:this.state.transcodingProgress}),isInitialized:()=>this.initialized,startPreview:()=>this.startPreview(),stopPreview:()=>this.stopPreview(),renderMobile:()=>this.renderMobile()}),this.renderMobile(),this.init();return}this.innerHTML=tE(),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 qT({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(),pE()}renderNativeCamera(){if(!this.nativeCameraManager)return;let e=this.nativeCameraManager.getState();this.innerHTML=$T(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=oE(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 UT({apiKey:e,backendUrl:t})),this.controller=new QC(fw(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){sE();return}this.cacheUiElements(),this.renderPermissionFlow(),this.setupEventListeners(),sE(),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 oE(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={...gE},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===Sw&&(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&&Qw(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=ww,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=HT(e),n=this.state.recordingState===Sw||this.state.isPaused,r=this.isProcessingRecording(),a=fE(this.config.minTimeRecord,this.state.timer,n),o={enableDeviceChange:this.config.enableDeviceChange,enableMute:this.config.enableMute,enablePause:this.config.enablePause,enableSourceSwitching:this.config.enableSourceSwitching},s=XT(n,this.state.recordingState,this.state.isPaused,o),c=!1;this.isDemo&&!n&&!r&&this.state.recordingState===`idle`&&this.state.recordedBlob!==null&&(c=!0);let l={...s,showDownloadButton:c},u=bw;this.controller&&(u=this.controller.getCurrentSourceType());let{errorCode:d,browserName:f,browserVersion:p}=this.resolveBrowserErrorState();oT({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:d,browserName:f,browserVersion:p},isVideoLoaded:this.state.isVideoLoaded,isRecording:n,controller:this.controller,audioLevel:0,buttonVisibility:l,currentSourceType:u,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),gT(mT({stream:this.state.stream,buttonVisibility:l,currentSourceType:u,isMuted:this.state.isMuted,isAudioReady:this.state.isAudioReady,isProcessingRecording:r,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:a,stopLockedTooltip:t.buttons.minimumRecordingTimeNotReached,buttonTranslations:t.buttons}),this.recordingControlsElements),Tw({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}),Ew({transitionMessage:this.state.transitionMessage},{overlay:this.overlayElements.transitionOverlay,message:this.overlayElements.transitionMessage}),AT(kT({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=fS({errorCode:this.state.errorCode,hasAudioFailed:this.state.hasAudioFailed,error:this.state.error}),r=n.variant===`generic`;if(!(n.visible&&!this.isProcessingRecording()&&(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=fE(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 YT({apiKey:e,backendUrl:t})),this.controller=new rw(_w(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){pE();return}this.cacheUiElements(),this.renderPermissionFlow(),this.setupEventListeners(),pE(),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 fE(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={...SE},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===Dw&&(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&&iT(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=kw,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=JT(e),n=this.state.recordingState===Dw||this.state.isPaused,r=this.isProcessingRecording(),a=vE(this.config.minTimeRecord,this.state.timer,n),o={enableDeviceChange:this.config.enableDeviceChange,enableMute:this.config.enableMute,enablePause:this.config.enablePause,enableSourceSwitching:this.config.enableSourceSwitching},s=nE(n,this.state.recordingState,this.state.isPaused,o),c=!1;this.isDemo&&!n&&!r&&this.state.recordingState===`idle`&&this.state.recordedBlob!==null&&(c=!0);let l={...s,showDownloadButton:c},u=Tw;this.controller&&(u=this.controller.getCurrentSourceType());let{errorCode:d,browserName:f,browserVersion:p}=this.resolveBrowserErrorState();fT({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:d,browserName:f,browserVersion:p},isVideoLoaded:this.state.isVideoLoaded,isRecording:n,controller:this.controller,audioLevel:0,buttonVisibility:l,currentSourceType:u,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),ST(bT({stream:this.state.stream,buttonVisibility:l,currentSourceType:u,isMuted:this.state.isMuted,isAudioReady:this.state.isAudioReady,isProcessingRecording:r,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:a,stopLockedTooltip:t.buttons.minimumRecordingTimeNotReached,buttonTranslations:t.buttons}),this.recordingControlsElements),Aw({uploadProgress:this.state.transcodingProgress??this.state.uploadProgress,uploadingLabel:this.state.transcodingProgress===null?e.uploading:e.finishing,isTranscoding:this.state.transcodingProgress!==null},{overlay:this.overlayElements.uploadOverlay,fill:this.overlayElements.uploadFill,text:this.overlayElements.uploadText}),Mw({transitionMessage:this.state.transitionMessage},{overlay:this.overlayElements.transitionOverlay,message:this.overlayElements.transitionMessage}),IT(FT({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=gS({errorCode:this.state.errorCode,hasAudioFailed:this.state.hasAudioFailed,error:this.state.error}),r=n.variant===`generic`;if(!(n.visible&&!this.isProcessingRecording()&&(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"/>
@@ -13391,7 +13391,7 @@ Mediabunny was loaded twice.\` + " This will likely cause Mediabunny not to work
13391
13391
  <path d="M251.77,73a8,8,0,0,0-8.21.39L208,97.05V72a16,16,0,0,0-16-16H32A16,16,0,0,0,16,72V184a16,16,0,0,0,16,16H192a16,16,0,0,0,16-16V159l35.56,23.71A8,8,0,0,0,256,176V80A8,8,0,0,0,251.77,73ZM192,184H32V72H192V184Zm48-22.95-32-21.33V116.28l32-21.33Z"/>
13392
13392
  </svg>`;default:return`<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" fill="currentColor" viewBox="0 0 256 256">
13393
13393
  <path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm-8-80V80a8,8,0,0,1,16,0v56a8,8,0,0,1-16,0Zm20,36a12,12,0,1,1-12-12A12,12,0,0,1,140,172Z"/>
13394
- </svg>`}}getDeviceErrorTitle(e){switch(e){case`audio`:return this.i18n.t(`audioErrorTitle`);case`camera`:return this.i18n.t(`cameraErrorTitle`);case`browser`:return this.i18n.t(`browserErrorTitle`);default:return this.i18n.t(`genericErrorTitle`)}}getDeviceErrorMessage(e){switch(e){case`audio`:return this.i18n.t(`audioErrorMessage`);case`camera`:return this.i18n.t(`cameraErrorMessage`);case`browser`:return this.i18n.t(`browserErrorMessage`);default:return this.i18n.t(`genericErrorMessage`)}}resolveAudioOverlayCopy(e){switch(e){case`audio.in-use`:return{title:this.i18n.t(`audioErrorTitle`),message:this.i18n.t(`audioInUse`),retryLabel:this.i18n.t(`audioErrorRetry`)};case`audio.not-found`:case`audio.overconstrained`:return{title:this.i18n.t(`audioErrorTitle`),message:this.i18n.t(`audioNotFound`),retryLabel:this.i18n.t(`audioErrorRetry`)};case`audio.permission-denied`:return{title:this.i18n.t(`audioErrorTitle`),message:this.i18n.t(`audioPermissionDenied`),retryLabel:this.i18n.t(`audioErrorRetry`)};case`audio.timeout`:return{title:this.i18n.t(`audioErrorTitle`),message:this.i18n.t(`audioTimeout`),retryLabel:this.i18n.t(`audioErrorRetry`)};default:break}let t=new Set([`recording.audio-no-chunks`,`recording.audio-track-ended`,`recording.no-audio-track`,`recording.no-audio-frames`]),n=new Set([`recording.audio-silent`]),r=new Set([`recording.audio-zero-channels`,`recording.audio-invalid-sample-rate`]);return e&&t.has(e)?{title:this.i18n.t(`audioMissingTitle`),message:this.i18n.t(`audioMissingMessage`),retryLabel:this.i18n.t(`audioMissingRetry`)}:e&&n.has(e)?{title:this.i18n.t(`audioSilentTitle`),message:this.i18n.t(`audioSilentMessage`),retryLabel:this.i18n.t(`audioMissingRetry`)}:e&&r.has(e)?{title:this.i18n.t(`audioProcessingErrorTitle`),message:this.i18n.t(`audioProcessingErrorMessage`),retryLabel:this.i18n.t(`audioMissingRetry`)}:{title:this.i18n.t(`audioErrorTitle`),message:this.i18n.t(`audioErrorMessage`),retryLabel:this.i18n.t(`audioErrorRetry`)}}resolveCameraOverlayCopy(e){switch(e){case`camera.in-use`:return{title:this.i18n.t(`cameraErrorTitle`),message:this.i18n.t(`cameraInUse`),retryLabel:this.i18n.t(`errorRetry`)};case`camera.not-found`:case`camera.overconstrained`:return{title:this.i18n.t(`cameraErrorTitle`),message:this.i18n.t(`cameraNotFound`),retryLabel:this.i18n.t(`errorRetry`)};case`camera.permission-denied`:return{title:this.i18n.t(`cameraErrorTitle`),message:this.i18n.t(`cameraPermissionDenied`),retryLabel:this.i18n.t(`errorRetry`)};case`camera.timeout`:return{title:this.i18n.t(`cameraErrorTitle`),message:this.i18n.t(`cameraTimeout`),retryLabel:this.i18n.t(`errorRetry`)};default:return{title:this.i18n.t(`cameraErrorTitle`),message:this.i18n.t(`cameraErrorMessage`),retryLabel:this.i18n.t(`errorRetry`)}}}resolveRecordingOverlayCopy(e){switch(e){case`recording.codec-unsupported`:return{title:this.i18n.t(`recordingCodecUnsupportedTitle`),message:this.i18n.t(`recordingCodecUnsupportedMessage`),retryLabel:this.i18n.t(`recordingPipelineRetry`)};case`recording.post-recording-transcode-fallback`:return{title:this.i18n.t(`recordingServerTranscodeFallbackTitle`),message:this.i18n.t(`recordingServerTranscodeFallbackMessage`),retryLabel:this.i18n.t(`recordingPipelineRetry`)};case`recording.track-ended`:return{title:this.i18n.t(`recordingTrackEndedTitle`),message:this.i18n.t(`recordingTrackEndedMessage`),retryLabel:this.i18n.t(`recordingPipelineRetry`)};case`recording.finalize-timeout-low-resource`:return{title:this.i18n.t(`recordingFinalizeTimeoutTitle`),message:this.i18n.t(`recordingFinalizeTimeoutMessage`),retryLabel:this.i18n.t(`recordingPipelineRetry`)};case`recording.not-started-state-race`:return{title:this.i18n.t(`recordingStateRaceTitle`),message:this.i18n.t(`recordingStateRaceMessage`),retryLabel:this.i18n.t(`recordingPipelineRetry`)};case`recording.no-video-frames`:return{title:this.i18n.t(`recordingNoFramesTitle`),message:this.i18n.t(`recordingNoFramesMessage`),retryLabel:this.i18n.t(`recordingPipelineRetry`)};case`recording.unsupported-device`:return{title:this.i18n.t(`recordingUnsupportedTitle`),message:this.i18n.t(`recordingUnsupportedMessage`),retryLabel:this.i18n.t(`recordingPipelineRetry`)};default:return{title:this.i18n.t(`genericErrorTitle`),message:this.i18n.t(`genericErrorMessage`),retryLabel:this.i18n.t(`errorRetry`)}}}renderMobileIndicators(e){this.mobileManager?.isModalOpen&&(this.toggleDisplay(`#mobileRecIndicator`,e),this.toggleDisplay(`#mobileTimerBadge`,e),this.setText(`#mobileTimer`,this.state.timer))}toggleDisplay(e,t){let n=this.queryMobileElement(e);if(!n)return;if(!t){n.style.display=`none`;return}let r=n.tagName===`BUTTON`,i=e.includes(`row`)||e.includes(`controls`)||e.includes(`Overlay`)||e.includes(`Indicator`)||e.includes(`Timer`)||e.includes(`Bars`),a=`block`;r&&(a=`inline-flex`),!r&&i&&(a=`flex`),n.style.display=a}setText(e,t){let n=this.queryMobileElement(e);n&&(n.textContent=t)}async startPreview(){if(this.controller&&!this.isStartingPreview){this.isStartingPreview=!0;try{if(!await this.resolveCanStartStreamFromPermissionFlow())return;await this.controller.startStream(),this.updateState({stream:this.controller.getStream(),isAudioReady:this.controller.isAudioReady()}),this.clearBrowserUnsupportedState(),this.audioStatusUnsub&&=(this.audioStatusUnsub(),null),this.audioStatusUnsub=this.controller.getStreamManager().on(`audiostatuschange`,({status:e})=>{this.updateState({isAudioReady:e===`acquired`,hasAudioFailed:e===`failed`})})}catch(e){this.applyBrowserUnsupportedStateFromError(e),this.updateState({error:i(e)}),this.overlayPhase=`hidden`,this.renderPermissionFlow()}finally{this.isStartingPreview=!1}}}getPermissionFlowTranslations(){return{title:this.i18n.t(`permissionFlowTitle`),cameraTitle:this.i18n.t(`permissionFlowCameraTitle`),microphoneTitle:this.i18n.t(`permissionFlowMicrophoneTitle`),cameraLabel:this.i18n.t(`permissionFlowCameraLabel`),microphoneLabel:this.i18n.t(`permissionFlowMicrophoneLabel`),statusPending:this.i18n.t(`permissionFlowStatusPending`),statusGranted:this.i18n.t(`permissionFlowStatusGranted`),statusDenied:this.i18n.t(`permissionFlowStatusDenied`),statusRequesting:this.i18n.t(`permissionFlowStatusRequesting`),allowCamera:this.i18n.t(`permissionFlowAllowCamera`),allowMicrophone:this.i18n.t(`permissionFlowAllowMicrophone`),retry:this.i18n.t(`permissionFlowRetry`),recoveryTitle:this.i18n.t(`permissionFlowRecoveryTitle`),recoveryInstructions:this.i18n.t(`permissionFlowRecoveryInstructions`),connecting:this.i18n.t(`permissionFlowConnecting`)}}updatePermissionFlowSnapshot(e){this.permissionFlowSnapshot=e,this.updateOverlayPhase(),this.renderPermissionFlow(),this.getCanStartStreamFromPermissionFlow(e)&&!this.state.stream&&!this.isStartingPreview&&!this.mobileManager&&setTimeout(()=>this.startPreview(),100)}updateOverlayPhase(){let e=this.permissionFlowSnapshot;if(e.step===`checking`||e.step===`awaiting-user`||e.step===`blocked`){this.overlayPhase=`active`;return}if(e.step===`ready`||e.isComplete){if(this.overlayPhase===`active`){this.state.isVideoLoaded?this.startOverlayFadeOut():this.overlayPhase=`loading`;return}this.overlayPhase===`loading`&&this.state.isVideoLoaded&&this.startOverlayFadeOut()}}startOverlayFadeOut(){this.overlayPhase=`fading`,this.renderPermissionFlow(),this.overlayFadeTimeoutId!==null&&clearTimeout(this.overlayFadeTimeoutId),this.overlayFadeTimeoutId=setTimeout(()=>{this.overlayPhase=`hidden`,this.overlayFadeTimeoutId=null,this.renderPermissionFlow()},600)}async initializePermissionFlow(){this.cleanupPermissionFlow();let e=`en`;this.lang===`es`&&(e=`es`),this.permissionFlowOrchestrator=new zn(Rn(),{callbacks:{onChange:e=>{this.updatePermissionFlowSnapshot(e)},onComplete:e=>{this.updatePermissionFlowSnapshot(e)}},language:e});let t=await this.permissionFlowOrchestrator.initialize();this.updatePermissionFlowSnapshot(t)}cleanupPermissionFlow(){this.overlayFadeTimeoutId!==null&&(clearTimeout(this.overlayFadeTimeoutId),this.overlayFadeTimeoutId=null),this.overlayPhase=`hidden`;let e=Vw(hE,this.getPermissionFlowTranslations(),!1);this.permissionFlowElements&&Jw(e,this.permissionFlowElements),this.permissionFlowOrchestrator&&=(this.permissionFlowOrchestrator.destroy(),null),this.permissionFlowSnapshot=hE,this.isStartingPreview=!1}async requestPermissionCurrentStep(){if(!this.permissionFlowOrchestrator)return;let e=await this.permissionFlowOrchestrator.requestCurrentStep();this.updatePermissionFlowSnapshot(e)}async retryPermissionCurrentStep(){if(!this.permissionFlowOrchestrator)return;let e=await this.permissionFlowOrchestrator.retryCurrentStep();this.updatePermissionFlowSnapshot(e)}getCanStartStreamFromPermissionFlow(e){return!(!e.isComplete||e.step!==`ready`)}async resolveCanStartStreamFromPermissionFlow(){if(this.permissionFlowOrchestrator||await this.initializePermissionFlow(),!this.permissionFlowOrchestrator)return!1;if(this.getCanStartStreamFromPermissionFlow(this.permissionFlowSnapshot))return!0;let e=await this.permissionFlowOrchestrator.requestCurrentStep();return this.updatePermissionFlowSnapshot(e),this.getCanStartStreamFromPermissionFlow(e)}renderPermissionFlow(){if(!this.permissionFlowElements)return;let e=this.overlayPhase===`fading`,t=Vw(this.permissionFlowSnapshot,this.getPermissionFlowTranslations(),e);this.overlayPhase===`hidden`&&(t.isVisible=!1),Jw(t,this.permissionFlowElements,{onAllow:()=>{this.requestPermissionCurrentStep().catch(e=>{this.updateState({error:i(e)})})},onRetry:()=>{this.retryPermissionCurrentStep().catch(e=>{this.updateState({error:i(e)})})}})}stopPreview(){if(!this.controller)return;this.stopAudioAnalysis();let e=this.controller.getStream();if(e)for(let t of e.getTracks())t.stop();this.controller.getStreamManager().stopStream(),this.updateState({stream:null,error:null,errorCode:null,canRetry:!1,browserName:null,browserVersion:null})}renderMobile(){if(!this.mobileManager)return;let e=this.mobileManager.portal;if(!this.mobileManager.isModalOpen){this.innerHTML=GT(this.i18n),this.setupMobileLandingListeners(),sE();return}let t=JT(this.i18n),n=KT(this.i18n,this.mobileManager.canCloseModal,t);e.render(n),this.setupMobileModalListeners(),this.setupEventListeners(),this.cacheUiElements(),this.handleStreamUpdate(this.state.stream),this.render(),sE()}queryMobileElement(e){return this.mobileManager?.isModalOpen&&this.mobileManager.portal.isActive?this.mobileManager.portal.querySelector(e):this.querySelector(e)}getQueryRoot(){return this.mobileManager?.isModalOpen&&this.mobileManager.portal.isActive?this.mobileManager.portal:this}cacheUiElements(){let e=this.getQueryRoot();this.previewContentElements=$w(e),this.recordingControlsElements=hT(e),this.videoPreviewElements={previewSkeleton:this.previewContentElements.previewSkeleton,videoPreview:this.previewContentElements.videoPreview},this.audioBarsContainer=this.previewContentElements.audioLevelBars,this.overlayElements={uploadOverlay:e.querySelector(`#uploadProgressOverlay`),uploadFill:e.querySelector(`#uploadProgressFill`),uploadText:e.querySelector(`#uploadProgressText`),transitionOverlay:e.querySelector(`#sourceTransitionOverlay`),transitionMessage:e.querySelector(`#transitionMessage`)},this.settingsPanelElement=e.querySelector(`#settingsPanel`),this.permissionFlowElements=Iw(e)}setupMobileLandingListeners(){this.querySelector(`#btnMobileOpenCamera`)?.addEventListener(`click`,()=>this.mobileManager?.openModal())}setupMobileModalListeners(){this.queryMobileElement(`#btnMobileCloseModal`)?.addEventListener(`click`,()=>this.mobileManager?.closeModal())}handleCameraChange(e){return this.handleDeviceChange(e,`camera`)}handleMicChange(e){return this.handleDeviceChange(e,`mic`)}async handleDeviceChange(e,t){if(!this.controller)return;let n=pw(this.controller,e);t===`mic`&&(n=mw(this.controller,e)),await n.then(e=>{this.updateState({stream:e})}).catch(e=>{this.updateState({error:i(e)})});let r=this.state.devices;t===`camera`&&(r={...this.state.devices,selectedCamera:e}),t===`mic`&&(r={...this.state.devices,selectedMic:e}),this.updateState({devices:r})}async handleRecord(){if(this.controller&&!this.isProcessingRecording())try{this.updateState({configError:null,audioWarning:null}),this.clearAudioWarningAutoDismiss(),await hw(this.controller,bw)}catch(e){this.applyBrowserUnsupportedStateFromError(e),this.updateState({configError:Error(i(e)),error:i(e)})}}async processRecordingBlob(e){if(!this.isProcessingBlob){this.isProcessingBlob=!0;try{if(this.isDemo){this.updateState({recordedBlob:e});return}if(!this.uploadService)throw Error(`Upload service not ready`);let t=`recording-${Date.now()}.mp4`;this.updateState({transcodingProgress:null,uploadProgress:0});try{let n=await this.uploadService.uploadVideo(e,{apiKey:this.config.apiKey||``,backendUrl:this.config.backendUrl||``,filename:t,userMetadata:this.config.userMetadata,onProgress:e=>{this.updateState({uploadProgress:e})}});this.updateState({uploadProgress:null,transcodingProgress:null}),this.dispatchEvent(new CustomEvent(`upload-complete`,{detail:n}))}catch(e){throw this.updateState({uploadProgress:null,transcodingProgress:null}),e}}finally{this.isProcessingBlob=!1}}}isProcessingRecording(){return this.isProcessingBlob||this.state.uploadProgress!==null||this.state.transcodingProgress!==null}isStopBlockedByMinimumTime(){let e=this.state.recordingState===Sw||this.state.isPaused;return fE(this.config.minTimeRecord,this.state.timer,e)}async stopRecording(){if(!this.controller)return null;if(this.isStopBlockedByMinimumTime())throw pE();let e=await gw(this.controller,this.isDemo,()=>{},()=>{});return e&&await this.processRecordingBlob(e),e}async handleStop(){if(!this.isStopBlockedByMinimumTime())try{await this.stopRecording()}catch(e){this.applyBrowserUnsupportedStateFromError(e),this.updateState({error:i(e)})}}handlePauseToggle(){this.controller&&(this.state.isPaused&&vw(this.controller),this.state.isPaused||_w(this.controller),this.updateState({isPaused:this.controller.isPaused()}))}handleDownload(){this.state.recordedBlob&&MT(this.state.recordedBlob)}handleMute(){this.controller&&(jT(this.controller),this.updateState({isMuted:this.controller.getIsMuted()}))}async handleSwitch(){if(!this.controller)return;let e=this.controller.getCurrentSourceType(),t=bw;e===bw&&(t=xw),e===xw&&(t=bw);try{await yw(this.controller,t)}catch(e){this.applyBrowserUnsupportedStateFromError(e),this.updateState({error:i(e)})}}setupEventListeners(){let e=(e,t)=>{let n=this.queryMobileElement(e);n&&n.addEventListener(`click`,t)};e(`#btnRecord`,()=>this.handleRecord()),e(`#btnStop`,()=>this.handleStop()),e(`#btnPause`,()=>this.handlePauseToggle()),e(`#btnDownload`,()=>this.handleDownload()),e(`#btnMute`,()=>this.handleMute()),e(`#btnSwitchSource`,()=>this.handleSwitch());let t=this.queryMobileElement(`#startCameraArea`);t&&t.addEventListener(`click`,()=>this.startPreview());let n=this.queryMobileElement(`#btnSettings`),r=this.queryMobileElement(`#settingsPanel`);n&&r&&n.addEventListener(`click`,()=>{let e=!this.state.showSettings;this.updateState({showSettings:e}),e&&this.populateSettings()});let i=this.queryMobileElement(`#btnSettingsBack`);i&&r&&i.addEventListener(`click`,()=>{}),this.setupSettingsListeners()}setupSettingsListeners(){let e=this.queryMobileElement(`#btnCameraMenu`);e&&e.addEventListener(`click`,()=>this.navigateSettings(`camera`));let t=this.queryMobileElement(`#btnMicMenu`);t&&t.addEventListener(`click`,()=>this.navigateSettings(`microphone`));let n=this.queryMobileElement(`#btnSettingsBack`);n&&n.addEventListener(`click`,e=>{e.stopPropagation(),this.settingsView!==`main`&&this.navigateSettings(`main`)})}navigateSettings(e){e===`main`?this.slideDirection=`left`:this.slideDirection=`right`,this.settingsView=e,this.renderSettings(),setTimeout(()=>{this.slideDirection=`none`,this.renderSettings()},300)}renderSettings(){this.updateSettingsContent(),this.renderSettingsView()}updateSettingsContent(){let e=this.queryMobileElement(`#settingsContent`);e&&(e.classList.remove(`vidtreo-slide-left`,`vidtreo-slide-right`,`vidtreo-slide-none`),this.slideDirection!==`none`&&e.classList.add(`vidtreo-slide-${this.slideDirection}`))}renderSettingsView(){let e=this.queryMobileElement(`#settingsMain`),t=this.queryMobileElement(`#cameraList`),n=this.queryMobileElement(`#micList`),r=this.queryMobileElement(`#btnSettingsBack`);e&&(e.style.display=`none`),t&&(t.style.display=`none`),n&&(n.style.display=`none`),r&&(r.style.display=`none`),this.settingsView===`main`&&this.renderSettingsMain(e,r),this.settingsView===`camera`&&this.renderSettingsCamera(t,r),this.settingsView===`microphone`&&this.renderSettingsMicrophone(n,r)}renderSettingsMain(e,t){e&&(e.style.display=`flex`),t&&(t.style.display=`none`),this.updateCurrentDeviceLabels()}updateCurrentDeviceLabels(){let e=this.state.devices.cameras.filter(e=>e.deviceId&&e.deviceId.trim()!==``),t=this.state.devices.microphones.filter(e=>e.deviceId&&e.deviceId.trim()!==``),n=e.find(e=>e.deviceId===this.state.devices.selectedCamera),r=t.find(e=>e.deviceId===this.state.devices.selectedMic),i=n?.label||e[0]?.label||`Camera`,a=r?.label||t[0]?.label||`Microphone`;this.setText(`#currentCameraName`,i),this.setText(`#currentMicName`,a)}renderSettingsCamera(e,t){e&&(e.style.display=`flex`,this.renderDeviceList(e,this.state.devices.cameras,this.state.devices.selectedCamera,`camera`));let n=this.queryMobileElement(`.vidtreo-settings-title`),r=this.queryMobileElement(`.vidtreo-settings-back-icon`);t&&(t.style.display=`flex`,t.style.cursor=`pointer`,t.onclick=()=>this.navigateSettings(`main`)),n&&(n.textContent=`Camera`),r&&(r.style.display=`flex`)}renderSettingsMicrophone(e,t){e&&(e.style.display=`flex`,this.renderDeviceList(e,this.state.devices.microphones,this.state.devices.selectedMic,`mic`));let n=this.queryMobileElement(`.vidtreo-settings-title`),r=this.queryMobileElement(`.vidtreo-settings-back-icon`);t&&(t.style.display=`flex`,t.style.cursor=`pointer`,t.onclick=()=>this.navigateSettings(`main`)),n&&(n.textContent=`Microphone`),r&&(r.style.display=`flex`)}renderDeviceList(e,t,n,r){if(!t||t.length===0){e.innerHTML=`<div class="vidtreo-device-empty">No devices found</div>`;return}e.innerHTML=``;for(let i of t){let t=document.createElement(`button`);t.className=`vidtreo-device-option`;let a=i.deviceId===n,o=`<span class="vidtreo-device-checkmark-placeholder"></span>`;a&&(o=`<i class="ph-fill ph-check vidtreo-device-checkmark" style="display: flex; font-size: 20px;"></i>`);let s=i.label;s||=`Device ${i.deviceId.slice(0,8)}`,t.innerHTML=`
13394
+ </svg>`}}getDeviceErrorTitle(e){switch(e){case`audio`:return this.i18n.t(`audioErrorTitle`);case`camera`:return this.i18n.t(`cameraErrorTitle`);case`browser`:return this.i18n.t(`browserErrorTitle`);default:return this.i18n.t(`genericErrorTitle`)}}getDeviceErrorMessage(e){switch(e){case`audio`:return this.i18n.t(`audioErrorMessage`);case`camera`:return this.i18n.t(`cameraErrorMessage`);case`browser`:return this.i18n.t(`browserErrorMessage`);default:return this.i18n.t(`genericErrorMessage`)}}resolveAudioOverlayCopy(e){switch(e){case`audio.in-use`:return{title:this.i18n.t(`audioErrorTitle`),message:this.i18n.t(`audioInUse`),retryLabel:this.i18n.t(`audioErrorRetry`)};case`audio.not-found`:case`audio.overconstrained`:return{title:this.i18n.t(`audioErrorTitle`),message:this.i18n.t(`audioNotFound`),retryLabel:this.i18n.t(`audioErrorRetry`)};case`audio.permission-denied`:return{title:this.i18n.t(`audioErrorTitle`),message:this.i18n.t(`audioPermissionDenied`),retryLabel:this.i18n.t(`audioErrorRetry`)};case`audio.timeout`:return{title:this.i18n.t(`audioErrorTitle`),message:this.i18n.t(`audioTimeout`),retryLabel:this.i18n.t(`audioErrorRetry`)};default:break}let t=new Set([`recording.audio-no-chunks`,`recording.audio-track-ended`,`recording.no-audio-track`,`recording.no-audio-frames`]),n=new Set([`recording.audio-silent`]),r=new Set([`recording.audio-zero-channels`,`recording.audio-invalid-sample-rate`]);return e&&t.has(e)?{title:this.i18n.t(`audioMissingTitle`),message:this.i18n.t(`audioMissingMessage`),retryLabel:this.i18n.t(`audioMissingRetry`)}:e&&n.has(e)?{title:this.i18n.t(`audioSilentTitle`),message:this.i18n.t(`audioSilentMessage`),retryLabel:this.i18n.t(`audioMissingRetry`)}:e&&r.has(e)?{title:this.i18n.t(`audioProcessingErrorTitle`),message:this.i18n.t(`audioProcessingErrorMessage`),retryLabel:this.i18n.t(`audioMissingRetry`)}:{title:this.i18n.t(`audioErrorTitle`),message:this.i18n.t(`audioErrorMessage`),retryLabel:this.i18n.t(`audioErrorRetry`)}}resolveCameraOverlayCopy(e){switch(e){case`camera.in-use`:return{title:this.i18n.t(`cameraErrorTitle`),message:this.i18n.t(`cameraInUse`),retryLabel:this.i18n.t(`errorRetry`)};case`camera.not-found`:case`camera.overconstrained`:return{title:this.i18n.t(`cameraErrorTitle`),message:this.i18n.t(`cameraNotFound`),retryLabel:this.i18n.t(`errorRetry`)};case`camera.permission-denied`:return{title:this.i18n.t(`cameraErrorTitle`),message:this.i18n.t(`cameraPermissionDenied`),retryLabel:this.i18n.t(`errorRetry`)};case`camera.timeout`:return{title:this.i18n.t(`cameraErrorTitle`),message:this.i18n.t(`cameraTimeout`),retryLabel:this.i18n.t(`errorRetry`)};default:return{title:this.i18n.t(`cameraErrorTitle`),message:this.i18n.t(`cameraErrorMessage`),retryLabel:this.i18n.t(`errorRetry`)}}}resolveRecordingOverlayCopy(e){switch(e){case`recording.codec-unsupported`:return{title:this.i18n.t(`recordingCodecUnsupportedTitle`),message:this.i18n.t(`recordingCodecUnsupportedMessage`),retryLabel:this.i18n.t(`recordingPipelineRetry`)};case`recording.post-recording-transcode-fallback`:return{title:this.i18n.t(`recordingServerTranscodeFallbackTitle`),message:this.i18n.t(`recordingServerTranscodeFallbackMessage`),retryLabel:this.i18n.t(`recordingPipelineRetry`)};case`recording.track-ended`:return{title:this.i18n.t(`recordingTrackEndedTitle`),message:this.i18n.t(`recordingTrackEndedMessage`),retryLabel:this.i18n.t(`recordingPipelineRetry`)};case`recording.finalize-timeout-low-resource`:return{title:this.i18n.t(`recordingFinalizeTimeoutTitle`),message:this.i18n.t(`recordingFinalizeTimeoutMessage`),retryLabel:this.i18n.t(`recordingPipelineRetry`)};case`recording.not-started-state-race`:return{title:this.i18n.t(`recordingStateRaceTitle`),message:this.i18n.t(`recordingStateRaceMessage`),retryLabel:this.i18n.t(`recordingPipelineRetry`)};case`recording.no-video-frames`:return{title:this.i18n.t(`recordingNoFramesTitle`),message:this.i18n.t(`recordingNoFramesMessage`),retryLabel:this.i18n.t(`recordingPipelineRetry`)};case`recording.unsupported-device`:return{title:this.i18n.t(`recordingUnsupportedTitle`),message:this.i18n.t(`recordingUnsupportedMessage`),retryLabel:this.i18n.t(`recordingPipelineRetry`)};default:return{title:this.i18n.t(`genericErrorTitle`),message:this.i18n.t(`genericErrorMessage`),retryLabel:this.i18n.t(`errorRetry`)}}}renderMobileIndicators(e){this.mobileManager?.isModalOpen&&(this.toggleDisplay(`#mobileRecIndicator`,e),this.toggleDisplay(`#mobileTimerBadge`,e),this.setText(`#mobileTimer`,this.state.timer))}toggleDisplay(e,t){let n=this.queryMobileElement(e);if(!n)return;if(!t){n.style.display=`none`;return}let r=n.tagName===`BUTTON`,i=e.includes(`row`)||e.includes(`controls`)||e.includes(`Overlay`)||e.includes(`Indicator`)||e.includes(`Timer`)||e.includes(`Bars`),a=`block`;r&&(a=`inline-flex`),!r&&i&&(a=`flex`),n.style.display=a}setText(e,t){let n=this.queryMobileElement(e);n&&(n.textContent=t)}async startPreview(){if(this.controller&&!this.isStartingPreview){this.isStartingPreview=!0;try{if(!await this.resolveCanStartStreamFromPermissionFlow())return;await this.controller.startStream(),this.updateState({stream:this.controller.getStream(),isAudioReady:this.controller.isAudioReady()}),this.clearBrowserUnsupportedState(),this.audioStatusUnsub&&=(this.audioStatusUnsub(),null),this.audioStatusUnsub=this.controller.getStreamManager().on(`audiostatuschange`,({status:e})=>{this.updateState({isAudioReady:e===`acquired`,hasAudioFailed:e===`failed`})})}catch(e){this.applyBrowserUnsupportedStateFromError(e),this.updateState({error:i(e)}),this.overlayPhase=`hidden`,this.renderPermissionFlow()}finally{this.isStartingPreview=!1}}}getPermissionFlowTranslations(){return{title:this.i18n.t(`permissionFlowTitle`),cameraTitle:this.i18n.t(`permissionFlowCameraTitle`),microphoneTitle:this.i18n.t(`permissionFlowMicrophoneTitle`),cameraLabel:this.i18n.t(`permissionFlowCameraLabel`),microphoneLabel:this.i18n.t(`permissionFlowMicrophoneLabel`),statusPending:this.i18n.t(`permissionFlowStatusPending`),statusGranted:this.i18n.t(`permissionFlowStatusGranted`),statusDenied:this.i18n.t(`permissionFlowStatusDenied`),statusRequesting:this.i18n.t(`permissionFlowStatusRequesting`),allowCamera:this.i18n.t(`permissionFlowAllowCamera`),allowMicrophone:this.i18n.t(`permissionFlowAllowMicrophone`),retry:this.i18n.t(`permissionFlowRetry`),recoveryTitle:this.i18n.t(`permissionFlowRecoveryTitle`),recoveryInstructions:this.i18n.t(`permissionFlowRecoveryInstructions`),connecting:this.i18n.t(`permissionFlowConnecting`)}}updatePermissionFlowSnapshot(e){this.permissionFlowSnapshot=e,this.updateOverlayPhase(),this.renderPermissionFlow(),this.getCanStartStreamFromPermissionFlow(e)&&!this.state.stream&&!this.isStartingPreview&&!this.mobileManager&&setTimeout(()=>this.startPreview(),100)}updateOverlayPhase(){let e=this.permissionFlowSnapshot;if(e.step===`checking`||e.step===`awaiting-user`||e.step===`blocked`){this.overlayPhase=`active`;return}if(e.step===`ready`||e.isComplete){if(this.overlayPhase===`active`){this.state.isVideoLoaded?this.startOverlayFadeOut():this.overlayPhase=`loading`;return}this.overlayPhase===`loading`&&this.state.isVideoLoaded&&this.startOverlayFadeOut()}}startOverlayFadeOut(){this.overlayPhase=`fading`,this.renderPermissionFlow(),this.overlayFadeTimeoutId!==null&&clearTimeout(this.overlayFadeTimeoutId),this.overlayFadeTimeoutId=setTimeout(()=>{this.overlayPhase=`hidden`,this.overlayFadeTimeoutId=null,this.renderPermissionFlow()},600)}async initializePermissionFlow(){this.cleanupPermissionFlow();let e=`en`;this.lang===`es`&&(e=`es`),this.permissionFlowOrchestrator=new zn(Rn(),{callbacks:{onChange:e=>{this.updatePermissionFlowSnapshot(e)},onComplete:e=>{this.updatePermissionFlowSnapshot(e)}},language:e});let t=await this.permissionFlowOrchestrator.initialize();this.updatePermissionFlowSnapshot(t)}cleanupPermissionFlow(){this.overlayFadeTimeoutId!==null&&(clearTimeout(this.overlayFadeTimeoutId),this.overlayFadeTimeoutId=null),this.overlayPhase=`hidden`;let e=qw(xE,this.getPermissionFlowTranslations(),!1);this.permissionFlowElements&&eT(e,this.permissionFlowElements),this.permissionFlowOrchestrator&&=(this.permissionFlowOrchestrator.destroy(),null),this.permissionFlowSnapshot=xE,this.isStartingPreview=!1}async requestPermissionCurrentStep(){if(!this.permissionFlowOrchestrator)return;let e=await this.permissionFlowOrchestrator.requestCurrentStep();this.updatePermissionFlowSnapshot(e)}async retryPermissionCurrentStep(){if(!this.permissionFlowOrchestrator)return;let e=await this.permissionFlowOrchestrator.retryCurrentStep();this.updatePermissionFlowSnapshot(e)}getCanStartStreamFromPermissionFlow(e){return!(!e.isComplete||e.step!==`ready`)}async resolveCanStartStreamFromPermissionFlow(){if(this.permissionFlowOrchestrator||await this.initializePermissionFlow(),!this.permissionFlowOrchestrator)return!1;if(this.getCanStartStreamFromPermissionFlow(this.permissionFlowSnapshot))return!0;let e=await this.permissionFlowOrchestrator.requestCurrentStep();return this.updatePermissionFlowSnapshot(e),this.getCanStartStreamFromPermissionFlow(e)}renderPermissionFlow(){if(!this.permissionFlowElements)return;let e=this.overlayPhase===`fading`,t=qw(this.permissionFlowSnapshot,this.getPermissionFlowTranslations(),e);this.overlayPhase===`hidden`&&(t.isVisible=!1),eT(t,this.permissionFlowElements,{onAllow:()=>{this.requestPermissionCurrentStep().catch(e=>{this.updateState({error:i(e)})})},onRetry:()=>{this.retryPermissionCurrentStep().catch(e=>{this.updateState({error:i(e)})})}})}stopPreview(){if(!this.controller)return;this.stopAudioAnalysis();let e=this.controller.getStream();if(e)for(let t of e.getTracks())t.stop();this.controller.getStreamManager().stopStream(),this.updateState({stream:null,error:null,errorCode:null,canRetry:!1,browserName:null,browserVersion:null})}renderMobile(){if(!this.mobileManager)return;let e=this.mobileManager.portal;if(!this.mobileManager.isModalOpen){this.innerHTML=ZT(this.i18n),this.setupMobileLandingListeners(),pE();return}let t=eE(this.i18n),n=QT(this.i18n,this.mobileManager.canCloseModal,t);e.render(n),this.setupMobileModalListeners(),this.setupEventListeners(),this.cacheUiElements(),this.handleStreamUpdate(this.state.stream),this.render(),pE()}queryMobileElement(e){return this.mobileManager?.isModalOpen&&this.mobileManager.portal.isActive?this.mobileManager.portal.querySelector(e):this.querySelector(e)}getQueryRoot(){return this.mobileManager?.isModalOpen&&this.mobileManager.portal.isActive?this.mobileManager.portal:this}cacheUiElements(){let e=this.getQueryRoot(),t=e.querySelector(`#uploadProgressOverlay`);t===null&&(t=e.querySelector(`#progressOverlay`)),this.previewContentElements=aT(e),this.recordingControlsElements=xT(e),this.videoPreviewElements={previewSkeleton:this.previewContentElements.previewSkeleton,videoPreview:this.previewContentElements.videoPreview},this.audioBarsContainer=this.previewContentElements.audioLevelBars,this.overlayElements={uploadOverlay:t,uploadFill:e.querySelector(`#uploadProgressFill`),uploadText:e.querySelector(`#uploadProgressText`),transitionOverlay:e.querySelector(`#sourceTransitionOverlay`),transitionMessage:e.querySelector(`#transitionMessage`)},this.settingsPanelElement=e.querySelector(`#settingsPanel`),this.permissionFlowElements=Hw(e)}setupMobileLandingListeners(){this.querySelector(`#btnMobileOpenCamera`)?.addEventListener(`click`,()=>this.mobileManager?.openModal())}setupMobileModalListeners(){this.queryMobileElement(`#btnMobileCloseModal`)?.addEventListener(`click`,()=>this.mobileManager?.closeModal())}handleCameraChange(e){return this.handleDeviceChange(e,`camera`)}handleMicChange(e){return this.handleDeviceChange(e,`mic`)}async handleDeviceChange(e,t){if(!this.controller)return;let n=vw(this.controller,e);t===`mic`&&(n=yw(this.controller,e)),await n.then(e=>{this.updateState({stream:e})}).catch(e=>{this.updateState({error:i(e)})});let r=this.state.devices;t===`camera`&&(r={...this.state.devices,selectedCamera:e}),t===`mic`&&(r={...this.state.devices,selectedMic:e}),this.updateState({devices:r})}async handleRecord(){if(this.controller&&!this.isProcessingRecording())try{this.updateState({configError:null,audioWarning:null}),this.clearAudioWarningAutoDismiss(),await bw(this.controller,Tw)}catch(e){this.applyBrowserUnsupportedStateFromError(e),this.updateState({configError:Error(i(e)),error:i(e)})}}async processRecordingBlob(e){if(!this.isProcessingBlob){this.isProcessingBlob=!0;try{if(this.isDemo){this.updateState({recordedBlob:e,transcodingProgress:null,uploadProgress:null});return}if(!this.uploadService)throw Error(`Upload service not ready`);let t=`recording-${Date.now()}.mp4`;this.updateState({transcodingProgress:null,uploadProgress:0});try{let n=await this.uploadService.uploadVideo(e,{apiKey:this.config.apiKey||``,backendUrl:this.config.backendUrl||``,filename:t,userMetadata:this.config.userMetadata,onProgress:e=>{this.updateState({uploadProgress:e})}});this.updateState({uploadProgress:null,transcodingProgress:null}),this.dispatchEvent(new CustomEvent(`upload-complete`,{detail:n}))}catch(e){throw this.updateState({uploadProgress:null,transcodingProgress:null}),e}}finally{this.isProcessingBlob=!1}}}isProcessingRecording(){return this.isProcessingBlob||this.state.uploadProgress!==null||this.state.transcodingProgress!==null}isStopBlockedByMinimumTime(){let e=this.state.recordingState===Dw||this.state.isPaused;return vE(this.config.minTimeRecord,this.state.timer,e)}async stopRecording(){if(!this.controller)return null;if(this.isStopBlockedByMinimumTime())throw yE();let e=await xw(this.controller,this.isDemo,()=>{},()=>{});return e&&await this.processRecordingBlob(e),e}async handleStop(){if(!this.isStopBlockedByMinimumTime())try{await this.stopRecording()}catch(e){this.applyBrowserUnsupportedStateFromError(e),this.updateState({error:i(e)})}}handlePauseToggle(){this.controller&&(this.state.isPaused&&Cw(this.controller),this.state.isPaused||Sw(this.controller),this.updateState({isPaused:this.controller.isPaused()}))}handleDownload(){this.state.recordedBlob&&RT(this.state.recordedBlob)}handleMute(){this.controller&&(LT(this.controller),this.updateState({isMuted:this.controller.getIsMuted()}))}async handleSwitch(){if(!this.controller)return;let e=this.controller.getCurrentSourceType(),t=Tw;e===Tw&&(t=Ew),e===Ew&&(t=Tw);try{await ww(this.controller,t)}catch(e){this.applyBrowserUnsupportedStateFromError(e),this.updateState({error:i(e)})}}setupEventListeners(){let e=(e,t)=>{let n=this.queryMobileElement(e);n&&n.addEventListener(`click`,t)};e(`#btnRecord`,()=>this.handleRecord()),e(`#btnStop`,()=>this.handleStop()),e(`#btnPause`,()=>this.handlePauseToggle()),e(`#btnDownload`,()=>this.handleDownload()),e(`#btnMute`,()=>this.handleMute()),e(`#btnSwitchSource`,()=>this.handleSwitch());let t=this.queryMobileElement(`#startCameraArea`);t&&t.addEventListener(`click`,()=>this.startPreview());let n=this.queryMobileElement(`#btnSettings`),r=this.queryMobileElement(`#settingsPanel`);n&&r&&n.addEventListener(`click`,()=>{let e=!this.state.showSettings;this.updateState({showSettings:e}),e&&this.populateSettings()});let i=this.queryMobileElement(`#btnSettingsBack`);i&&r&&i.addEventListener(`click`,()=>{}),this.setupSettingsListeners()}setupSettingsListeners(){let e=this.queryMobileElement(`#btnCameraMenu`);e&&e.addEventListener(`click`,()=>this.navigateSettings(`camera`));let t=this.queryMobileElement(`#btnMicMenu`);t&&t.addEventListener(`click`,()=>this.navigateSettings(`microphone`));let n=this.queryMobileElement(`#btnSettingsBack`);n&&n.addEventListener(`click`,e=>{e.stopPropagation(),this.settingsView!==`main`&&this.navigateSettings(`main`)})}navigateSettings(e){e===`main`?this.slideDirection=`left`:this.slideDirection=`right`,this.settingsView=e,this.renderSettings(),setTimeout(()=>{this.slideDirection=`none`,this.renderSettings()},300)}renderSettings(){this.updateSettingsContent(),this.renderSettingsView()}updateSettingsContent(){let e=this.queryMobileElement(`#settingsContent`);e&&(e.classList.remove(`vidtreo-slide-left`,`vidtreo-slide-right`,`vidtreo-slide-none`),this.slideDirection!==`none`&&e.classList.add(`vidtreo-slide-${this.slideDirection}`))}renderSettingsView(){let e=this.queryMobileElement(`#settingsMain`),t=this.queryMobileElement(`#cameraList`),n=this.queryMobileElement(`#micList`),r=this.queryMobileElement(`#btnSettingsBack`);e&&(e.style.display=`none`),t&&(t.style.display=`none`),n&&(n.style.display=`none`),r&&(r.style.display=`none`),this.settingsView===`main`&&this.renderSettingsMain(e,r),this.settingsView===`camera`&&this.renderSettingsCamera(t,r),this.settingsView===`microphone`&&this.renderSettingsMicrophone(n,r)}renderSettingsMain(e,t){e&&(e.style.display=`flex`),t&&(t.style.display=`none`),this.updateCurrentDeviceLabels()}updateCurrentDeviceLabels(){let e=this.state.devices.cameras.filter(e=>e.deviceId&&e.deviceId.trim()!==``),t=this.state.devices.microphones.filter(e=>e.deviceId&&e.deviceId.trim()!==``),n=e.find(e=>e.deviceId===this.state.devices.selectedCamera),r=t.find(e=>e.deviceId===this.state.devices.selectedMic),i=n?.label||e[0]?.label||`Camera`,a=r?.label||t[0]?.label||`Microphone`;this.setText(`#currentCameraName`,i),this.setText(`#currentMicName`,a)}renderSettingsCamera(e,t){e&&(e.style.display=`flex`,this.renderDeviceList(e,this.state.devices.cameras,this.state.devices.selectedCamera,`camera`));let n=this.queryMobileElement(`.vidtreo-settings-title`),r=this.queryMobileElement(`.vidtreo-settings-back-icon`);t&&(t.style.display=`flex`,t.style.cursor=`pointer`,t.onclick=()=>this.navigateSettings(`main`)),n&&(n.textContent=`Camera`),r&&(r.style.display=`flex`)}renderSettingsMicrophone(e,t){e&&(e.style.display=`flex`,this.renderDeviceList(e,this.state.devices.microphones,this.state.devices.selectedMic,`mic`));let n=this.queryMobileElement(`.vidtreo-settings-title`),r=this.queryMobileElement(`.vidtreo-settings-back-icon`);t&&(t.style.display=`flex`,t.style.cursor=`pointer`,t.onclick=()=>this.navigateSettings(`main`)),n&&(n.textContent=`Microphone`),r&&(r.style.display=`flex`)}renderDeviceList(e,t,n,r){if(!t||t.length===0){e.innerHTML=`<div class="vidtreo-device-empty">No devices found</div>`;return}e.innerHTML=``;for(let i of t){let t=document.createElement(`button`);t.className=`vidtreo-device-option`;let a=i.deviceId===n,o=`<span class="vidtreo-device-checkmark-placeholder"></span>`;a&&(o=`<i class="ph-fill ph-check vidtreo-device-checkmark" style="display: flex; font-size: 20px;"></i>`);let s=i.label;s||=`Device ${i.deviceId.slice(0,8)}`,t.innerHTML=`
13395
13395
  <div class="vidtreo-device-option-check-container">${o}</div>
13396
13396
  <span class="vidtreo-device-option-label">${s}</span>
13397
- `,t.onclick=()=>{r===`camera`&&this.handleCameraChange(i.deviceId),r===`mic`&&this.handleMicChange(i.deviceId),this.navigateSettings(`main`)},e.appendChild(t)}}populateSettings(){this.settingsView=`main`,this.slideDirection=`none`,this.renderSettings()}};return customElements.get(`vidtreo-recorder`)||customElements.define(`vidtreo-recorder`,_E),e.VidtreoRecorder=_E,e})({});
13397
+ `,t.onclick=()=>{r===`camera`&&this.handleCameraChange(i.deviceId),r===`mic`&&this.handleMicChange(i.deviceId),this.navigateSettings(`main`)},e.appendChild(t)}}populateSettings(){this.settingsView=`main`,this.slideDirection=`none`,this.renderSettings()}};return customElements.get(`vidtreo-recorder`)||customElements.define(`vidtreo-recorder`,CE),e.VidtreoRecorder=CE,e})({});