synxed-sdk 0.3.18 → 0.3.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -133,12 +133,12 @@ message SdkServerEnvelope {
|
|
|
133
133
|
SdkServerVoiceAudio voiceAudio = 5;
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
|
-
`,$=j__namespace.parse(me).root,D=$.lookupType("SdkClientEnvelope"),H=$.lookupType("SdkServerEnvelope"),R=(r=>(r[r.UNSPECIFIED=0]="UNSPECIFIED",r[r.SONG=1]="SONG",r[r.PLAYLIST=2]="PLAYLIST",r[r.CATEGORY=3]="CATEGORY",r[r.RADIO=4]="RADIO",r[r.VOICE=5]="VOICE",r))(R||{}),B=(o=>(o[o.VOICE_UNSPECIFIED=0]="VOICE_UNSPECIFIED",o[o.VOICE_START=1]="VOICE_START",o[o.VOICE_CHUNK=2]="VOICE_CHUNK",o[o.VOICE_END=3]="VOICE_END",o[o.VOICE_CANCEL=4]="VOICE_CANCEL",o))(B||{}),Y=(a=>(a[a.UNSPECIFIED=0]="UNSPECIFIED",a[a.UNAUTHORIZED=1]="UNAUTHORIZED",a[a.VALIDATION_ERROR=2]="VALIDATION_ERROR",a[a.NOT_FOUND=3]="NOT_FOUND",a[a.PROCESSING=4]="PROCESSING",a[a.SERVICE_UNAVAILABLE=5]="SERVICE_UNAVAILABLE",a[a.BAD_PROTOBUF=6]="BAD_PROTOBUF",a))(Y||{});var S=class{static encodeClientEnvelope(t){let e=D.create(t);return D.encode(e).finish()}static decodeServerEnvelope(t){let e=H.decode(t);return H.toObject(e,{enums:String,longs:String,bytes:String,defaults:true,oneofs:true})}};var m=class{constructor(){this.listeners=new Map;}on(t,e){this.listeners.has(t)||this.listeners.set(t,new Set),this.listeners.get(t).add(e);}off(t,e){let i=this.listeners.get(t);i&&i.delete(e);}once(t,e){let i=((...n)=>{e(...n),this.off(t,i);});this.on(t,i);}emit(t,...e){let i=this.listeners.get(t);i&&i.forEach(n=>n(...e));}removeAllListeners(){this.listeners.clear();}};var G=false;function X(s){G=s;}function v(...s){G&&console.debug("[Synxed]",...s);}function u(...s){console.warn("[Synxed]",...s);}function J(s,t){let i=(s.endsWith("/")?s.slice(0,-1):s).replace(/^http:/,"ws:").replace(/^https:/,"wss:"),n=new URL(`${i}/sdk`);return n.searchParams.set("apiKey",t),n.toString()}var w=class extends m{constructor(){super(...arguments);this.ws=null;this.connectPromise=null;this.keepaliveTimer=null;}startKeepalive(){this.stopKeepalive(),this.keepaliveTimer=setInterval(()=>{this.sendAnalytics({eventType:"sdk_keepalive",positionMs:0});},25e3);}stopKeepalive(){this.keepaliveTimer!==null&&(clearInterval(this.keepaliveTimer),this.keepaliveTimer=null);}connect(e,i){if(this.ws&&(this.ws.readyState===WebSocket.OPEN||this.ws.readyState===WebSocket.CONNECTING))return;let n=J(i,e);v("Opening native WebSocket",n.replace(/apiKey=[^&]+/,"apiKey=***")),this.ws=new WebSocket(n),this.ws.binaryType="arraybuffer",this.ws.onopen=()=>{this.connectPromise=null,this.startKeepalive(),this.emit("connected");},this.ws.onclose=o=>{let r=o.reason||`code ${o.code}`;this.stopKeepalive(),this.ws=null,this.connectPromise=null,this.emit("disconnected",r);},this.ws.onerror=()=>{this.emit("error",new Error("WebSocket connection error"));},this.ws.onmessage=o=>{try{let{data:r}=o;if(!(r instanceof ArrayBuffer))return;let a=S.decodeServerEnvelope(new Uint8Array(r));this.emit("message",a);}catch(r){this.emit("error",new Error(`Failed to decode message: ${r}`));}};}async waitForConnection(){if(v("Waiting for connection\u2026"),this.ws?.readyState===WebSocket.OPEN){v("Already connected");return}if(!this.ws)throw new Error("WebSocket not initialized. Call connect() first.");return this.connectPromise?this.connectPromise:(this.connectPromise=new Promise((e,i)=>{let n=this.ws;if(n.readyState===WebSocket.OPEN){e();return}let o=()=>{v("WebSocket connected"),l(),e();},r=()=>{u("WebSocket connection error"),l(),i(new Error("WebSocket connection failed"));},a=()=>{l(),i(new Error("WebSocket closed before connection was established"));},l=()=>{n.removeEventListener("open",o),n.removeEventListener("error",r),n.removeEventListener("close",a);};n.addEventListener("open",o),n.addEventListener("error",r),n.addEventListener("close",a);}),this.connectPromise)}disconnect(){this.ws&&(this.ws.onclose=null,this.ws.close(),this.ws=null,this.connectPromise=null,this.stopKeepalive());}sendInit(e){if(!this.isConnected)throw new Error("WebSocket not connected");v("Sending init packet",e),this.sendBytes(S.encodeClientEnvelope({init:e}));}sendControl(e){this.isConnected&&this.sendBytes(S.encodeClientEnvelope({control:e}));}sendAnalytics(e){this.isConnected&&this.sendBytes(S.encodeClientEnvelope({analytics:e}));}sendVoice(e){this.isConnected&&this.sendBytes(S.encodeClientEnvelope({voice:e}));}get isConnected(){return this.ws?.readyState===WebSocket.OPEN}sendBytes(e){if(!this.ws||this.ws.readyState!==WebSocket.OPEN)throw new Error("WebSocket not connected");this.ws.send(e);}};var V=class extends m{constructor(){super();this.howl=null;this.hls=null;this.audioEl=null;this.updateTimer=null;this.loadGeneration=0;}async load(e,i){let n=++this.loadGeneration;this.teardownPlayback(),this.emit("loading"),v("AudioEngine loading",{url:e,isHls:i});let o=/^((?!chrome|android).)*safari/i.test(navigator.userAgent);if(i&&!o)try{let{default:r}=await import('hls.js');if(r.isSupported()){v("Using Hls.js for playback");let a=new r({xhrSetup:c=>{c.setRequestHeader("ngrok-skip-browser-warning","true");}}),l=new Audio;return new Promise((c,h)=>{let p=()=>n!==this.loadGeneration,g=()=>{p()||(this.emit("playing"),this.startTimeUpdateLoop());},b=()=>{p()||(this.emit("paused"),this.stopTimeUpdateLoop());},T=()=>{p()||(this.emit("ended"),this.stopTimeUpdateLoop());},I=()=>{p()||this.emit("loaded");},ve=()=>{p()||(u("HLS audio element error"),this.emit("error",new Error("HLS playback failed")));};l.addEventListener("play",g),l.addEventListener("pause",b),l.addEventListener("ended",T),l.addEventListener("loadedmetadata",I),l.addEventListener("error",ve),a.on(r.Events.MANIFEST_PARSED,()=>{p()||(this.emit("loaded"),c());}),a.on(r.Events.ERROR,(Ee,U)=>{p()||U.fatal&&(u("Fatal HLS error",U),h(U));}),a.loadSource(e),a.attachMedia(l),this.hls=a,this.audioEl=l;})}}catch(r){u("hls.js not available, falling back to native playback",r);}return new Promise((r,a)=>{let l=()=>n!==this.loadGeneration;this.howl=new howler.Howl({src:[e],html5:true,format:i?["m3u8"]:void 0,onload:()=>{l()||(v("AudioEngine loaded"),this.emit("loaded"),r());},onloaderror:(c,h)=>{l()||(u("AudioEngine load error",h),a(h));},onplay:()=>{l()||(this.emit("playing"),this.startTimeUpdateLoop());},onpause:()=>{l()||(this.emit("paused"),this.stopTimeUpdateLoop());},onstop:()=>{l()||(this.emit("stopped"),this.stopTimeUpdateLoop());},onend:()=>{l()||(this.emit("ended"),this.stopTimeUpdateLoop());}});})}play(){this.audioEl?this.audioEl.play().catch(e=>u("Play failed",e)):this.howl?.play();}pause(){this.audioEl?this.audioEl.pause():this.howl?.pause();}stop(){this.loadGeneration+=1,this.teardownPlayback(),this.emit("stopped");}seek(e){this.audioEl?this.audioEl.currentTime=e/1e3:this.howl?.seek(e/1e3);}setVolume(e){this.audioEl&&(this.audioEl.volume=e),this.howl&&this.howl.volume(e);}get duration(){return this.audioEl?this.audioEl.duration*1e3:(this.howl?.duration()||0)*1e3}get currentTime(){return this.audioEl?this.audioEl.currentTime*1e3:(this.howl?.seek()||0)*1e3}teardownPlayback(){if(this.hls){try{this.hls.destroy();}catch{}this.hls=null;}this.audioEl&&(this.audioEl.pause(),this.audioEl.removeAttribute("src"),this.audioEl.load(),this.audioEl=null),this.howl&&(this.howl.stop(),this.howl.unload(),this.howl=null),this.stopTimeUpdateLoop();}startTimeUpdateLoop(){this.stopTimeUpdateLoop();let e=()=>{(this.audioEl?!this.audioEl.paused:this.howl?.playing())&&(this.emit("timeupdate",{currentTime:this.currentTime,duration:this.duration}),this.updateTimer=requestAnimationFrame(e));};this.updateTimer=requestAnimationFrame(e);}stopTimeUpdateLoop(){this.updateTimer!==null&&(cancelAnimationFrame(this.updateTimer),this.updateTimer=null);}};var _=class extends m{constructor(){super();this.queue=[];this.currentIndex=-1;}setQueue(e,i){this.queue=e,this.currentIndex=typeof i=="number"&&i>=0&&i<e.length?i:e.length>0?0:-1,this.emit("queueUpdated",this.queue),this.getCurrentTrack()&&this.emit("trackChanged",this.getCurrentTrack());}getCurrentTrack(){return this.currentIndex>=0&&this.currentIndex<this.queue.length?this.queue[this.currentIndex]:null}next(){if(this.currentIndex<this.queue.length-1){this.currentIndex++;let e=this.getCurrentTrack();return this.emit("trackChanged",e),e}return null}previous(){if(this.currentIndex>0){this.currentIndex--;let e=this.getCurrentTrack();return this.emit("trackChanged",e),e}return null}skipTo(e){if(e>=0&&e<this.queue.length){this.currentIndex=e;let i=this.getCurrentTrack();return this.emit("trackChanged",i),i}return null}reset(){this.queue=[],this.currentIndex=-1,this.emit("queueUpdated",[]);}get hasNext(){return this.currentIndex<this.queue.length-1}get hasPrevious(){return this.currentIndex>0}get queueSnapshot(){return [...this.queue]}get currentIndexSnapshot(){return this.currentIndex}};var x=class extends Error{constructor(e,i){super(e);this.code=i;this.name="SynxedError";}},O=class extends x{constructor(t){super(t),this.name="SynxedConnectionError";}},C=class extends x{constructor(t){super(typeof t=="string"?t:"Playback failed"),this.name="SynxedPlaybackError";}},Q=class extends x{constructor(t){super(t),this.name="SynxedProtocolError";}};function W(s,...t){for(let e of t){let i=s[e];if(typeof i=="string"&&i.length>0)return i}}function ye(s,...t){for(let e of t){let i=s[e];if(typeof i=="number"&&Number.isFinite(i))return i;if(typeof i=="string"&&i!==""&&!Number.isNaN(Number(i)))return Number(i)}}function Z(s){let t=s.initAck??s.init_ack;if(!t||typeof t!="object")return null;let e=t,i=W(e,"playbackUrl","playback_url");return i?{sessionId:W(e,"sessionId","session_id")??"",playbackUrl:i,isHls:!!(e.isHls??e.is_hls),heartbeatIntervalMs:ye(e,"heartbeatIntervalMs","heartbeat_interval_ms")??0,contentSummary:W(e,"contentSummary","content_summary")}:null}function ge(s){if(!s||typeof s!="object")return null;let t=s,e=t.id;if(typeof e!="string"||!e.trim())return null;let i=t.kind==="internal"?"internal":"catalog",n=t.albumArt??t.album_art;return {id:e.trim(),kind:i,title:typeof t.title=="string"?t.title:void 0,artist:typeof t.artist=="string"?t.artist:void 0,duration:typeof t.duration=="number"?t.duration:void 0,albumArt:typeof n=="string"?n:void 0}}function ee(s,t){if(!s?.trim())return null;let e;try{e=JSON.parse(s);}catch{return null}if(!e||typeof e!="object")return null;let i=e;if(i.type==="live_radio"||t===4)return {tracks:[{id:"synxed-radio",kind:"catalog",title:typeof i.station=="string"&&i.station.trim()?i.station.trim():"Synxed Radio",artist:""}],currentIndex:0};let o=i.tracks;if(!Array.isArray(o)||o.length===0)return null;let r=[];for(let c of o){let h=ge(c);h&&r.push(h);}if(r.length===0)return null;let a=typeof i.currentIndex=="number"?i.currentIndex:typeof i.current_index=="number"?i.current_index:0,l=Math.max(0,Math.min(Math.floor(a),r.length-1));return {tracks:r,currentIndex:l}}function f(s,...t){for(let e of t){let i=s[e];if(typeof i=="string")return i}return ""}function te(s,...t){for(let e of t){let i=s[e];if(typeof i=="boolean")return i}return false}function ie(s,...t){for(let e of t){let i=s[e];if(typeof i=="number"&&Number.isFinite(i))return i;if(typeof i=="string"&&i.trim()){let n=Number(i);if(Number.isFinite(n))return n}}return 0}function ne(s){let t=s.ad;if(!t||typeof t!="object")return null;let e=t,i=f(e,"playbackUrl","playback_url");return i?{adId:f(e,"adId","ad_id"),campaignId:f(e,"campaignId","campaign_id"),playbackUrl:i,isHls:te(e,"isHls","is_hls")||i.includes(".m3u8"),durationSeconds:ie(e,"durationSeconds","duration_seconds")||15,isSkippable:te(e,"isSkippable","is_skippable"),skipAfterSeconds:ie(e,"skipAfterSeconds","skip_after_seconds"),ctaType:f(e,"ctaType","cta_type"),ctaValue:f(e,"ctaValue","cta_value"),brandName:f(e,"brandName","brand_name"),creativeName:f(e,"creativeName","creative_name"),companionBannerUrl:f(e,"companionBannerUrl","companion_banner_url"),campaignName:f(e,"campaignName","campaign_name")}:null}var N="audio/pcm;rate=16000",k="audio/mpeg";function se(s,t){let e=/rate=(\d+)/i.exec(s);if(!e)return t;let i=Number(e[1]);return Number.isFinite(i)&&i>0?i:t}function P(s,...t){for(let e of t){let i=s[e];if(typeof i=="string")return i}return ""}function re(s){let t=s.voiceAck??s.voice_ack;if(!t||typeof t!="object")return null;let e=t,i=P(e,"status");return i?{status:i,transcript:P(e,"transcript")||void 0,playlistCode:P(e,"playlistCode","playlist_code")||void 0,playlistName:P(e,"playlistName","playlist_name")||void 0}:null}function ae(s){let t=s.voiceAudio??s.voice_audio;if(!t||typeof t!="object")return null;let e=t,i=e.audioData??e.audio_data,n=P(e,"mimeType","mime_type")||k,o=!!(e.isFinal??e.is_final),r;if(typeof i=="string"){let a=atob(i),l=a.length;r=new Uint8Array(l);for(let c=0;c<l;c++)r[c]=a.charCodeAt(c);}else if(i instanceof Uint8Array)r=i;else return null;return {audioData:r,mimeType:n,isFinal:o}}var M=class{constructor(){this.audioContext=null;this.nextStartTime=0;this.defaultSampleRate=24e3;this.encodedChunks=[];this.encodedMimeType=k;this.activeSource=null;this.playbackPromise=null;}initContext(t){this.audioContext||(this.audioContext=new(window.AudioContext||window.webkitAudioContext)({sampleRate:t}),this.nextStartTime=this.audioContext.currentTime);}enqueueChunk(t,e=k){if(!e.startsWith("audio/pcm")){this.encodedMimeType=e,this.encodedChunks.push(new Uint8Array(t));return}try{let i=se(e,this.defaultSampleRate);if(this.initContext(i),!this.audioContext)return;let n=new Int16Array(t.buffer,t.byteOffset,t.byteLength/2),o=new Float32Array(n.length);for(let c=0;c<n.length;c++)o[c]=n[c]/32768;let r=this.audioContext.createBuffer(1,o.length,i);r.getChannelData(0).set(o);let a=this.audioContext.createBufferSource();this.activeSource=a,a.buffer=r,a.connect(this.audioContext.destination);let l=this.audioContext.currentTime;this.nextStartTime<l&&(this.nextStartTime=l+.05),a.start(this.nextStartTime),this.nextStartTime+=r.duration;}catch(i){u("VoiceResponsePlayer failed to enqueue chunk",i);}}finish(t=this.encodedMimeType){if(!this.encodedChunks.length)return this.playbackPromise??Promise.resolve();let e=this.encodedChunks.splice(0);return this.encodedMimeType=t||k,this.playbackPromise=this.playEncoded(e,this.encodedMimeType).finally(()=>{this.playbackPromise=null;}),this.playbackPromise}async playEncoded(t,e){if(this.initContext(this.defaultSampleRate),!this.audioContext)return;this.audioContext.state==="suspended"&&await this.audioContext.resume().catch(()=>{});let i=t.map(r=>{let a=new Uint8Array(r.byteLength);return a.set(r),a.buffer}),n=new Blob(i,{type:e}),o=await this.audioContext.decodeAudioData(await n.arrayBuffer());await new Promise((r,a)=>{if(!this.audioContext){r();return}let l=this.audioContext.createBufferSource();this.activeSource=l,l.buffer=o,l.connect(this.audioContext.destination),l.onended=()=>{this.activeSource===l&&(this.activeSource=null),r();};try{l.start();}catch(c){this.activeSource===l&&(this.activeSource=null),a(c);}});}stop(){if(this.activeSource){try{this.activeSource.stop();}catch{}this.activeSource=null;}this.encodedChunks=[],this.playbackPromise=null,this.audioContext&&(this.audioContext.close().catch(()=>{}),this.audioContext=null),this.nextStartTime=0;}};var be="https://cdn.jsdelivr.net/npm/@ricky0123/vad-web@0.0.29/dist/",Se="https://cdn.jsdelivr.net/npm/onnxruntime-web@1.22.0/dist/";async function xe(){let s=await import('@ricky0123/vad-web'),t=s.MicVAD??s.default?.MicVAD;if(!t)throw new Error("MicVAD export missing from @ricky0123/vad-web \u2014 check bundler resolves the package");return t}var A=class extends m{constructor(){super(...arguments);this.capturing=false;this.mimeType=N;this.micVad=null;this.vadBaseAssetPath=be;this.onnxWasmBasePath=Se;this.userSpeaking=false;this.chunkSequence=0;}get isCapturing(){return this.capturing}get isUserSpeaking(){return this.userSpeaking}async preloadModels(e={}){this.applyOptions(e),await this.ensureMicVad();}applyOptions(e){e.vadBaseAssetPath&&(this.vadBaseAssetPath=e.vadBaseAssetPath),e.onnxWasmBasePath&&(this.onnxWasmBasePath=e.onnxWasmBasePath);}setUserSpeaking(e){this.userSpeaking!==e&&(this.userSpeaking=e,this.emit("userSpeakingChange",e));}async ensureMicVad(){if(this.micVad)return;let i=await(await xe()).new({baseAssetPath:this.vadBaseAssetPath,onnxWASMBasePath:this.onnxWasmBasePath,positiveSpeechThreshold:.5,negativeSpeechThreshold:.35,redemptionMs:500,minSpeechMs:250,onFrameProcessed:(n,o)=>{if(!this.capturing)return;let r=new Int16Array(o.length);for(let a=0;a<o.length;a++){let l=Math.max(-1,Math.min(1,o[a]));r[a]=l<0?l*32768:l*32767;}this.chunkSequence+=1,this.emit("chunk",new Uint8Array(r.buffer),this.chunkSequence);},onSpeechStart:()=>{this.capturing&&(this.setUserSpeaking(true),this.emit("speechStart"));},onSpeechEnd:()=>{this.capturing&&(this.setUserSpeaking(false),this.emit("speechEnd"));}});i.pause(),this.micVad=i;}async start(e={}){if(this.capturing)return this.mimeType;this.applyOptions(e),this.chunkSequence=0,this.setUserSpeaking(false);try{await this.ensureMicVad(),this.capturing=!0,this.micVad.start();}catch(i){this.capturing=false;let n=i instanceof Error?i:new Error(String(i));u("Voice capture failed to start",n),this.emit("error",n);}return this.mimeType}async stop(){this.capturing=false,this.setUserSpeaking(false),this.micVad&&this.micVad.pause();}cancel(){this.capturing=false,this.setUserSpeaking(false),this.micVad&&this.micVad.pause();}};var L=class extends m{constructor(e){super();this.status="idle";this.volume=.8;this.activeContentKind=0;this.heartbeatTimer=null;this.adPlaying=false;this._currentAd=null;this._voiceState="idle";this.voiceMimeType="audio/webm";this.pendingPlaybackLoad=null;this.voiceAutoEndOnSilence=true;this.pausedForVoice=false;this._voiceUserSpeaking=false;this.voiceResponseDismissed=false;this.voicePlaybackPromise=null;this.config=e,X(!!e.debug),this.transport=new w,this.audio=new V,this.playlist=new _,this.voiceCapture=new A,this.voiceResponsePlayer=new M,this.setupListeners(),this.voiceCapture.preloadModels(this.config.voice),e.autoConnect&&this.connect();}get currentTrack(){return this.playlist.getCurrentTrack()}get contentKind(){return this.activeContentKind}get currentAd(){return this._currentAd}get isAdPlaying(){return this.adPlaying}canSkipAd(){return !this.adPlaying||!this._currentAd?.isSkippable?false:Math.floor(this.audio.currentTime*1e3)>=this._currentAd.skipAfterSeconds*1e3}getAdSkipCountdownSeconds(){if(!this.adPlaying||!this._currentAd?.isSkippable)return null;let e=Math.floor(this.audio.currentTime*1e3),i=this._currentAd.skipAfterSeconds*1e3;return e>=i?0:Math.ceil((i-e)/1e3)}get voiceState(){return this._voiceState}get voiceUserSpeaking(){return this._voiceUserSpeaking}controlPositionMs(){return this.activeContentKind===4?0:this.positionMsForAnalytics()}setupListeners(){this.transport.on("connected",()=>this.emit("connected")),this.transport.on("disconnected",e=>this.emit("disconnected",e)),this.transport.on("error",e=>this.emit("error",new O(e.message))),this.transport.on("message",e=>this.handleServerMessage(e)),this.audio.on("playing",()=>this.updateStatus("playing")),this.audio.on("paused",()=>this.updateStatus("paused")),this.audio.on("stopped",()=>{!this.adPlaying&&this._voiceState==="idle"&&this.updateStatus("idle");}),this.audio.on("loading",()=>this.updateStatus("loading")),this.audio.on("error",e=>{if(this.adPlaying){u("Ad playback error \u2014 waiting for next track",e);return}this.emit("error",new C(e));}),this.audio.on("timeupdate",e=>{this.emit("timeUpdate",e),this.adPlaying&&this._currentAd&&this.emitAdSkipUpdate(e.currentTime);}),this.audio.on("ended",()=>this.handleTrackEnded()),this.playlist.on("trackChanged",e=>this.emit("trackChange",e)),this.playlist.on("queueUpdated",e=>this.emit("queueUpdated",e)),this.voiceCapture.on("chunk",(e,i)=>{this.transport.sendVoice({action:2,audioData:e,mimeType:this.voiceMimeType,sequence:i,listenerId:this.voiceListenerId,deviceType:this.config.deviceType,gameContext:this.config.gameContext});}),this.voiceCapture.on("error",e=>{this.setVoiceState("error"),this.emit("error",new x(e.message,"VOICE_CAPTURE_FAILED"));}),this.voiceCapture.on("speechStart",()=>{this.emit("voiceSpeechStart");}),this.voiceCapture.on("speechEnd",()=>{this.emit("voiceSpeechEnd"),this.voiceAutoEndOnSilence&&this._voiceState==="listening"&&this.endVoiceHold();}),this.voiceCapture.on("userSpeakingChange",e=>{this._voiceUserSpeaking=e,this.emit("voiceUserSpeakingChange",e);});}resolveVoiceOptions(e={}){return {...this.config.voice,...e}}connect(){this.transport.connect(this.config.apiKey,this.config.serverUrl);}buildInitExtras(){let e={};return this.config.gameContext?.trim()&&(e.gameContext=this.config.gameContext.trim()),this.config.deviceType?.trim()&&(e.deviceType=this.config.deviceType.trim()),e}async playSong(e){this.transport.isConnected||this.connect(),await this.transport.waitForConnection(),this.voiceResponseDismissed=false,this.activeContentKind=1,this.transport.sendInit({contentKind:1,catalogTrackId:e.catalogTrackId,internalTrackId:e.internalTrackId,listenerId:e.listenerId,...this.buildInitExtras()});}async playPlaylist(e){this.transport.isConnected||this.connect(),await this.transport.waitForConnection(),this.voiceResponseDismissed=false,this.activeContentKind=2,this.transport.sendInit({contentKind:2,playlistCode:e.playlistCode,listenerId:e.listenerId,...this.buildInitExtras()});}async playRadio(e={}){this.transport.isConnected||this.connect(),await this.transport.waitForConnection(),this.voiceResponseDismissed=false,this.activeContentKind=4,this.transport.sendInit({contentKind:4,listenerId:e.listenerId,...this.buildInitExtras()});}async beginVoiceHold(e={}){if(this._voiceState==="listening"||this._voiceState==="processing"||this._voiceState==="responding")return;let i=this.resolveVoiceOptions(e);this.voiceAutoEndOnSilence=i.autoEndOnSilence!==false,this._voiceUserSpeaking=false,this.voiceResponseDismissed=false,this.transport.isConnected||this.connect(),await this.transport.waitForConnection(),this.voiceListenerId=i.listenerId?.trim()||void 0,this.pausedForVoice=this.status==="playing",this.pausedForVoice&&this.pause(),this.voiceResponsePlayer.stop(),this.setVoiceState("listening"),this.voiceMimeType=await this.voiceCapture.start({maxDurationMs:i.maxDurationMs}),this.transport.sendVoice({action:1,mimeType:this.voiceMimeType||N,listenerId:this.voiceListenerId,...this.buildInitExtras()});}async endVoiceHold(){this._voiceState==="listening"&&(this._voiceUserSpeaking=false,this.emit("voiceUserSpeakingChange",false),this.setVoiceState("processing"),await this.voiceCapture.stop(),this.transport.sendVoice({action:3,mimeType:this.voiceMimeType,listenerId:this.voiceListenerId,...this.buildInitExtras()}));}cancelVoiceHold(){this._voiceState==="listening"&&(this._voiceUserSpeaking=false,this.voiceCapture.cancel(),this.transport.sendVoice({action:4,mimeType:this.voiceMimeType,listenerId:this.voiceListenerId,...this.buildInitExtras()}),this.setVoiceState("idle"));}dismissVoiceAndResume(){this.voiceResponseDismissed=true,this.voiceResponsePlayer.stop(),this._voiceState==="listening"?this.cancelVoiceHold():(this._voiceState==="processing"||this._voiceState==="responding")&&(this.transport.sendVoice({action:4,mimeType:this.voiceMimeType,listenerId:this.voiceListenerId,...this.buildInitExtras()}),this.setVoiceState("idle")),this.pausedForVoice&&(this.resume(),this.pausedForVoice=false);}get isVoiceUiActive(){return this._voiceState==="listening"||this._voiceState==="processing"||this._voiceState==="responding"}pause(){this.audio.pause(),this.transport.sendControl({action:2,positionMs:this.controlPositionMs()});}resume(){this.audio.play(),this.transport.sendControl({action:1,positionMs:this.controlPositionMs()});}stop(){this.audio.stop(),this.transport.sendControl({action:3,positionMs:this.controlPositionMs()});}skip(){if(this.activeContentKind===4)return;if(this.adPlaying){this.skipAd();return}if(this.playlist.queueSnapshot.length>1){this.transport.sendControl({action:5,positionMs:this.controlPositionMs()}),this.updateStatus("loading");return}let e=this.playlist.next();e&&this.playSong(e.kind==="internal"?{internalTrackId:e.id}:{catalogTrackId:e.id});}previous(){if(this.activeContentKind===4)return;if(this.playlist.queueSnapshot.length>1){this.transport.sendControl({action:6,positionMs:this.controlPositionMs()}),this.updateStatus("loading");return}let e=this.playlist.previous();e&&this.playSong(e.kind==="internal"?{internalTrackId:e.id}:{catalogTrackId:e.id});}skipTo(e){if(this.activeContentKind===4)return;let i=this.playlist.skipTo(e);i&&this.playSong(i.kind==="internal"?{internalTrackId:i.id}:{catalogTrackId:i.id});}seek(e){this.activeContentKind===4||this.adPlaying||(this.audio.seek(e),this.transport.sendControl({action:4,positionMs:e}));}setVolume(e){this.volume=Math.max(0,Math.min(1,e)),this.audio.setVolume(this.volume);}positionMsForAnalytics(e){return typeof e=="number"?Math.max(0,Math.min(4294967295,Math.floor(e))):Math.max(0,Math.min(4294967295,Math.floor(this.audio.currentTime)))}emitAnalytics(e,i,n){this.transport.sendAnalytics({eventType:e,positionMs:this.positionMsForAnalytics(i),extraJson:n?JSON.stringify(n):void 0});}clearHeartbeat(){this.heartbeatTimer!==null&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null);}startHeartbeat(e){this.clearHeartbeat();let i=Number(e);!i||i<1e3||(this.heartbeatTimer=setInterval(()=>{let n=this.activeContentKind===4?0:this.positionMsForAnalytics();this.emitAnalytics("heartbeat",n);},i));}applyContentSummary(e){let i=ee(e,this.activeContentKind);if(i){this.playlist.setQueue(i.tracks,i.currentIndex);return}e?.trim()&&u("Could not parse contentSummary; queue metadata unavailable.");}emitAdSkipUpdate(e){if(!this._currentAd)return;let i=this._currentAd.skipAfterSeconds*1e3,n=this._currentAd.isSkippable&&e>=i,o=n?0:Math.ceil((i-e)/1e3),r={ad:this._currentAd,canSkip:n,countdownSeconds:o};this.emit("adSkipUpdate",r);}setVoiceState(e){this._voiceState=e,this.emit("voiceStateChange",e);}handleVoiceAck(e){let i=e.status;if(i==="cancelled"){this._voiceState!=="idle"&&this.setVoiceState("idle");return}if(!this.voiceResponseDismissed){if(i==="listening"){this._voiceState==="idle"&&this.setVoiceState("listening");return}if(i==="processing"){(this._voiceState==="listening"||this._voiceState==="idle")&&this.setVoiceState("processing");return}if(i==="ready"){this.activeContentKind=2;let n={status:i,transcript:e.transcript,playlistCode:e.playlistCode,playlistName:e.playlistName};this.setVoiceState("ready"),this.emit("voiceResult",n);return}this.emit("voiceResult",{status:i,transcript:e.transcript,playlistCode:e.playlistCode,playlistName:e.playlistName});}}async handleServerMessage(e){v("Received server message",e);let i=re(e);if(i){this.handleVoiceAck(i);return}let n=ae(e);if(n){if(this.voiceResponseDismissed)return;this._voiceState==="processing"&&this.setVoiceState("responding"),n.audioData.length>0&&this.voiceResponsePlayer.enqueueChunk(n.audioData,n.mimeType),n.isFinal&&(this.voicePlaybackPromise=this.voiceResponsePlayer.finish(n.mimeType).catch(l=>{u("Voice response playback failed",l);}).finally(()=>{this.voicePlaybackPromise=null;}));return}let o=ne(e);if(o){await this.handleAdPlayback(o);return}let r=Z(e);if(r){if(this.voiceResponseDismissed)return;await this.startContentPlayback(r);return}let a=e.error;if(a&&typeof a=="object"){let l=a,c=typeof l.message=="string"?l.message:"Unknown server error",h=typeof l.code=="string"?l.code:void 0;(this._voiceState==="processing"||this._voiceState==="listening"||this._voiceState==="responding")&&this.setVoiceState("error"),this.emit("error",new x(c,h));}}async startContentPlayback(e){if(this.adPlaying&&this._currentAd){let n=this._currentAd;this.adPlaying=false,this._currentAd=null,this.emit("adEnd",n);}else this.adPlaying=false,this._currentAd=null;this.voicePlaybackPromise&&!this.voiceResponseDismissed&&await this.voicePlaybackPromise,(this._voiceState==="ready"||this._voiceState==="processing"||this._voiceState==="responding")&&this.setVoiceState("idle"),this.pausedForVoice=false,this.voiceResponsePlayer.stop(),v("Loading playback",{url:e.playbackUrl,isHls:e.isHls});let i=this.audio.load(e.playbackUrl,e.isHls);this.pendingPlaybackLoad=i;try{if(await i,this.pendingPlaybackLoad!==i)return;this.audio.play(),this.emitAnalytics("stream_start",this.activeContentKind===4?0:void 0),this.startHeartbeat(e.heartbeatIntervalMs),this.applyContentSummary(e.contentSummary);}catch(n){if(this.pendingPlaybackLoad!==i)return;this.emit("error",new C(n));}finally{this.pendingPlaybackLoad===i&&(this.pendingPlaybackLoad=null);}}async handleAdPlayback(e){this.pendingPlaybackLoad&&await this.pendingPlaybackLoad.catch(()=>{}),this.audio.stop(),this.adPlaying=true,this._currentAd={adId:e.adId,campaignId:e.campaignId,brandName:e.brandName,creativeName:e.creativeName,durationSeconds:e.durationSeconds,isSkippable:e.isSkippable,skipAfterSeconds:e.skipAfterSeconds,ctaType:e.ctaType,ctaValue:e.ctaValue,companionBannerUrl:e.companionBannerUrl,campaignName:e.campaignName},v("Loading ad playback",{url:e.playbackUrl,isHls:e.isHls});try{await this.audio.load(e.playbackUrl,e.isHls),this.audio.play(),this.emit("adStart",this._currentAd),this.emitAdSkipUpdate(0);}catch(i){let n=this._currentAd;this.adPlaying=false,this._currentAd=null,n&&this.emit("adEnd",n),u("Ad load failed",i),this.updateStatus("loading");}}skipAd(){if(!this.adPlaying||!this._currentAd||!this._currentAd.isSkippable)return;let e=Math.floor(this.audio.currentTime*1e3);if(e<this._currentAd.skipAfterSeconds*1e3)return;let i=this._currentAd;this.adPlaying=false,this._currentAd=null,this.audio.stop(),this.emit("adEnd",i),this.emitAnalytics("ad_skip",e),this.updateStatus("loading");}clickAd(){if(!this.adPlaying||!this._currentAd)return;let e=Math.floor(this.audio.currentTime*1e3);this.emitAnalytics("ad_cta_click",e),this._currentAd.ctaValue&&window.open(this._currentAd.ctaValue,"_blank");}handleTrackEnded(){if(this.activeContentKind!==4){if(this.adPlaying&&this._currentAd){let e=this._currentAd;this.audio.stop(),this.emitAnalytics("ad_complete",Math.floor(this.audio.currentTime*1e3)),this.emit("adEnd",e),this.adPlaying=false,this._currentAd=null,this.updateStatus("loading");return}if(this.playlist.queueSnapshot.length>1){this.emitAnalytics("track_complete",Math.floor(this.audio.duration*1e3)),this.updateStatus("loading");return}if(this.activeContentKind===1||this.activeContentKind===2){this.emitAnalytics("track_complete",Math.floor(this.audio.duration*1e3)),this.updateStatus("loading");return}this.updateStatus("idle");}}updateStatus(e){this.status=e,this.emit("stateChange",{status:e,currentTrack:this.playlist.getCurrentTrack(),currentTime:this.audio.currentTime,duration:this.audio.duration,volume:this.volume});}destroy(){this.clearHeartbeat(),this.cancelVoiceHold(),this.voiceResponsePlayer.stop(),this.audio.stop(),this.transport.disconnect(),this.playlist.reset(),this.removeAllListeners();}};async function K(s,t){let i=`${s.replace(/\/$/,"")}/radio/now-playing`;try{let n=await fetch(i,{...t,headers:{Accept:"application/json",...t?.headers}});if(!n.ok)return null;let r=(await n.json())?.data;return !r?.title||typeof r.title!="string"?null:{title:r.title,station:typeof r.station=="string"?r.station:void 0,isLive:typeof r.isLive=="boolean"?r.isLive:void 0}}catch{return null}}function d(s,t){let e=document.createElement(s);if(t?.className&&(e.className=t.className),t?.attrs)for(let[i,n]of Object.entries(t.attrs))e.setAttribute(i,n);return t?.style&&Object.assign(e.style,t.style),t?.text&&(e.textContent=t.text),t?.html&&(e.innerHTML=t.html),t?.onClick&&e.addEventListener("click",t.onClick),t?.children&&t.children.forEach(i=>e.appendChild(i)),e}function y(s,t=20){let e=document.createElementNS("http://www.w3.org/2000/svg","svg");e.setAttribute("width",String(t)),e.setAttribute("height",String(t)),e.setAttribute("viewBox","0 0 24 24"),e.setAttribute("fill","currentColor"),e.setAttribute("aria-hidden","true");let i=document.createElementNS("http://www.w3.org/2000/svg","path");return i.setAttribute("d",s),e.appendChild(i),e}var F="M8 5v14l11-7L8 5z",oe="M6 5h4v14H6V5zm8 0h4v14h-4V5z",E="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z",le="M6 6h2v12H6V6zm11.5 12L9 12l8.5-6v12z";function de(){let s="synxed-web-player-styles";if(document.getElementById(s))return;let t=document.createElement("style");t.id=s,t.textContent=`
|
|
136
|
+
`,$=j__namespace.parse(me).root,D=$.lookupType("SdkClientEnvelope"),H=$.lookupType("SdkServerEnvelope"),R=(r=>(r[r.UNSPECIFIED=0]="UNSPECIFIED",r[r.SONG=1]="SONG",r[r.PLAYLIST=2]="PLAYLIST",r[r.CATEGORY=3]="CATEGORY",r[r.RADIO=4]="RADIO",r[r.VOICE=5]="VOICE",r))(R||{}),B=(o=>(o[o.VOICE_UNSPECIFIED=0]="VOICE_UNSPECIFIED",o[o.VOICE_START=1]="VOICE_START",o[o.VOICE_CHUNK=2]="VOICE_CHUNK",o[o.VOICE_END=3]="VOICE_END",o[o.VOICE_CANCEL=4]="VOICE_CANCEL",o))(B||{}),Y=(a=>(a[a.UNSPECIFIED=0]="UNSPECIFIED",a[a.UNAUTHORIZED=1]="UNAUTHORIZED",a[a.VALIDATION_ERROR=2]="VALIDATION_ERROR",a[a.NOT_FOUND=3]="NOT_FOUND",a[a.PROCESSING=4]="PROCESSING",a[a.SERVICE_UNAVAILABLE=5]="SERVICE_UNAVAILABLE",a[a.BAD_PROTOBUF=6]="BAD_PROTOBUF",a))(Y||{});var S=class{static encodeClientEnvelope(t){let e=D.create(t);return D.encode(e).finish()}static decodeServerEnvelope(t){let e=H.decode(t);return H.toObject(e,{enums:String,longs:String,bytes:String,defaults:true,oneofs:true})}};var m=class{constructor(){this.listeners=new Map;}on(t,e){this.listeners.has(t)||this.listeners.set(t,new Set),this.listeners.get(t).add(e);}off(t,e){let i=this.listeners.get(t);i&&i.delete(e);}once(t,e){let i=((...n)=>{e(...n),this.off(t,i);});this.on(t,i);}emit(t,...e){let i=this.listeners.get(t);i&&i.forEach(n=>n(...e));}removeAllListeners(){this.listeners.clear();}};var G=false;function X(s){G=s;}function v(...s){G&&console.debug("[Synxed]",...s);}function h(...s){console.warn("[Synxed]",...s);}function J(s,t){let i=(s.endsWith("/")?s.slice(0,-1):s).replace(/^http:/,"ws:").replace(/^https:/,"wss:"),n=new URL(`${i}/sdk`);return n.searchParams.set("apiKey",t),n.toString()}var w=class extends m{constructor(){super(...arguments);this.ws=null;this.connectPromise=null;this.keepaliveTimer=null;}startKeepalive(){this.stopKeepalive();let e=()=>{try{this.sendAnalytics({eventType:"sdk_keepalive",positionMs:0});}catch(i){h("SDK WebSocket keepalive failed",i);}};e(),this.keepaliveTimer=setInterval(e,15e3);}stopKeepalive(){this.keepaliveTimer!==null&&(clearInterval(this.keepaliveTimer),this.keepaliveTimer=null);}connect(e,i){if(this.ws&&(this.ws.readyState===WebSocket.OPEN||this.ws.readyState===WebSocket.CONNECTING))return;let n=J(i,e);v("Opening native WebSocket",n.replace(/apiKey=[^&]+/,"apiKey=***")),this.ws=new WebSocket(n),this.ws.binaryType="arraybuffer",this.ws.onopen=()=>{this.connectPromise=null,this.startKeepalive(),this.emit("connected");},this.ws.onclose=o=>{let r=o.reason||`code ${o.code}`;this.stopKeepalive(),this.ws=null,this.connectPromise=null,this.emit("disconnected",r);},this.ws.onerror=()=>{this.emit("error",new Error("WebSocket connection error"));},this.ws.onmessage=o=>{try{let{data:r}=o;if(!(r instanceof ArrayBuffer))return;let a=S.decodeServerEnvelope(new Uint8Array(r));this.emit("message",a);}catch(r){this.emit("error",new Error(`Failed to decode message: ${r}`));}};}async waitForConnection(){if(v("Waiting for connection\u2026"),this.ws?.readyState===WebSocket.OPEN){v("Already connected");return}if(!this.ws)throw new Error("WebSocket not initialized. Call connect() first.");return this.connectPromise?this.connectPromise:(this.connectPromise=new Promise((e,i)=>{let n=this.ws;if(n.readyState===WebSocket.OPEN){e();return}let o=()=>{v("WebSocket connected"),l(),e();},r=()=>{h("WebSocket connection error"),l(),i(new Error("WebSocket connection failed"));},a=()=>{l(),i(new Error("WebSocket closed before connection was established"));},l=()=>{n.removeEventListener("open",o),n.removeEventListener("error",r),n.removeEventListener("close",a);};n.addEventListener("open",o),n.addEventListener("error",r),n.addEventListener("close",a);}),this.connectPromise)}disconnect(){this.ws&&(this.ws.onclose=null,this.ws.close(),this.ws=null,this.connectPromise=null,this.stopKeepalive());}sendInit(e){if(!this.isConnected)throw new Error("WebSocket not connected");v("Sending init packet",e),this.sendBytes(S.encodeClientEnvelope({init:e}));}sendControl(e){this.isConnected&&this.sendBytes(S.encodeClientEnvelope({control:e}));}sendAnalytics(e){this.isConnected&&this.sendBytes(S.encodeClientEnvelope({analytics:e}));}sendVoice(e){this.isConnected&&this.sendBytes(S.encodeClientEnvelope({voice:e}));}get isConnected(){return this.ws?.readyState===WebSocket.OPEN}sendBytes(e){if(!this.ws||this.ws.readyState!==WebSocket.OPEN)throw new Error("WebSocket not connected");this.ws.send(e);}};var V=class extends m{constructor(){super();this.howl=null;this.hls=null;this.audioEl=null;this.updateTimer=null;this.loadGeneration=0;}async load(e,i){let n=++this.loadGeneration;this.teardownPlayback(),this.emit("loading"),v("AudioEngine loading",{url:e,isHls:i});let o=/^((?!chrome|android).)*safari/i.test(navigator.userAgent);if(i&&!o)try{let{default:r}=await import('hls.js');if(r.isSupported()){v("Using Hls.js for playback");let a=new r({xhrSetup:c=>{c.setRequestHeader("ngrok-skip-browser-warning","true");}}),l=new Audio;return new Promise((c,u)=>{let p=()=>n!==this.loadGeneration,g=()=>{p()||(this.emit("playing"),this.startTimeUpdateLoop());},b=()=>{p()||(this.emit("paused"),this.stopTimeUpdateLoop());},T=()=>{p()||(this.emit("ended"),this.stopTimeUpdateLoop());},I=()=>{p()||this.emit("loaded");},ve=()=>{p()||(h("HLS audio element error"),this.emit("error",new Error("HLS playback failed")));};l.addEventListener("play",g),l.addEventListener("pause",b),l.addEventListener("ended",T),l.addEventListener("loadedmetadata",I),l.addEventListener("error",ve),a.on(r.Events.MANIFEST_PARSED,()=>{p()||(this.emit("loaded"),c());}),a.on(r.Events.ERROR,(Ee,U)=>{p()||U.fatal&&(h("Fatal HLS error",U),u(U));}),a.loadSource(e),a.attachMedia(l),this.hls=a,this.audioEl=l;})}}catch(r){h("hls.js not available, falling back to native playback",r);}return new Promise((r,a)=>{let l=()=>n!==this.loadGeneration;this.howl=new howler.Howl({src:[e],html5:true,format:i?["m3u8"]:void 0,onload:()=>{l()||(v("AudioEngine loaded"),this.emit("loaded"),r());},onloaderror:(c,u)=>{l()||(h("AudioEngine load error",u),a(u));},onplay:()=>{l()||(this.emit("playing"),this.startTimeUpdateLoop());},onpause:()=>{l()||(this.emit("paused"),this.stopTimeUpdateLoop());},onstop:()=>{l()||(this.emit("stopped"),this.stopTimeUpdateLoop());},onend:()=>{l()||(this.emit("ended"),this.stopTimeUpdateLoop());}});})}play(){this.audioEl?this.audioEl.play().catch(e=>h("Play failed",e)):this.howl?.play();}pause(){this.audioEl?this.audioEl.pause():this.howl?.pause();}stop(){this.loadGeneration+=1,this.teardownPlayback(),this.emit("stopped");}seek(e){this.audioEl?this.audioEl.currentTime=e/1e3:this.howl?.seek(e/1e3);}setVolume(e){this.audioEl&&(this.audioEl.volume=e),this.howl&&this.howl.volume(e);}get duration(){return this.audioEl?this.audioEl.duration*1e3:(this.howl?.duration()||0)*1e3}get currentTime(){return this.audioEl?this.audioEl.currentTime*1e3:(this.howl?.seek()||0)*1e3}teardownPlayback(){if(this.hls){try{this.hls.destroy();}catch{}this.hls=null;}this.audioEl&&(this.audioEl.pause(),this.audioEl.removeAttribute("src"),this.audioEl.load(),this.audioEl=null),this.howl&&(this.howl.stop(),this.howl.unload(),this.howl=null),this.stopTimeUpdateLoop();}startTimeUpdateLoop(){this.stopTimeUpdateLoop();let e=()=>{(this.audioEl?!this.audioEl.paused:this.howl?.playing())&&(this.emit("timeupdate",{currentTime:this.currentTime,duration:this.duration}),this.updateTimer=requestAnimationFrame(e));};this.updateTimer=requestAnimationFrame(e);}stopTimeUpdateLoop(){this.updateTimer!==null&&(cancelAnimationFrame(this.updateTimer),this.updateTimer=null);}};var _=class extends m{constructor(){super();this.queue=[];this.currentIndex=-1;}setQueue(e,i){this.queue=e,this.currentIndex=typeof i=="number"&&i>=0&&i<e.length?i:e.length>0?0:-1,this.emit("queueUpdated",this.queue),this.getCurrentTrack()&&this.emit("trackChanged",this.getCurrentTrack());}getCurrentTrack(){return this.currentIndex>=0&&this.currentIndex<this.queue.length?this.queue[this.currentIndex]:null}next(){if(this.currentIndex<this.queue.length-1){this.currentIndex++;let e=this.getCurrentTrack();return this.emit("trackChanged",e),e}return null}previous(){if(this.currentIndex>0){this.currentIndex--;let e=this.getCurrentTrack();return this.emit("trackChanged",e),e}return null}skipTo(e){if(e>=0&&e<this.queue.length){this.currentIndex=e;let i=this.getCurrentTrack();return this.emit("trackChanged",i),i}return null}reset(){this.queue=[],this.currentIndex=-1,this.emit("queueUpdated",[]);}get hasNext(){return this.currentIndex<this.queue.length-1}get hasPrevious(){return this.currentIndex>0}get queueSnapshot(){return [...this.queue]}get currentIndexSnapshot(){return this.currentIndex}};var x=class extends Error{constructor(e,i){super(e);this.code=i;this.name="SynxedError";}},O=class extends x{constructor(t){super(t),this.name="SynxedConnectionError";}},C=class extends x{constructor(t){super(typeof t=="string"?t:"Playback failed"),this.name="SynxedPlaybackError";}},Q=class extends x{constructor(t){super(t),this.name="SynxedProtocolError";}};function W(s,...t){for(let e of t){let i=s[e];if(typeof i=="string"&&i.length>0)return i}}function ye(s,...t){for(let e of t){let i=s[e];if(typeof i=="number"&&Number.isFinite(i))return i;if(typeof i=="string"&&i!==""&&!Number.isNaN(Number(i)))return Number(i)}}function Z(s){let t=s.initAck??s.init_ack;if(!t||typeof t!="object")return null;let e=t,i=W(e,"playbackUrl","playback_url");return i?{sessionId:W(e,"sessionId","session_id")??"",playbackUrl:i,isHls:!!(e.isHls??e.is_hls),heartbeatIntervalMs:ye(e,"heartbeatIntervalMs","heartbeat_interval_ms")??0,contentSummary:W(e,"contentSummary","content_summary")}:null}function ge(s){if(!s||typeof s!="object")return null;let t=s,e=t.id;if(typeof e!="string"||!e.trim())return null;let i=t.kind==="internal"?"internal":"catalog",n=t.albumArt??t.album_art;return {id:e.trim(),kind:i,title:typeof t.title=="string"?t.title:void 0,artist:typeof t.artist=="string"?t.artist:void 0,duration:typeof t.duration=="number"?t.duration:void 0,albumArt:typeof n=="string"?n:void 0}}function ee(s,t){if(!s?.trim())return null;let e;try{e=JSON.parse(s);}catch{return null}if(!e||typeof e!="object")return null;let i=e;if(i.type==="live_radio"||t===4)return {tracks:[{id:"synxed-radio",kind:"catalog",title:typeof i.station=="string"&&i.station.trim()?i.station.trim():"Synxed Radio",artist:""}],currentIndex:0};let o=i.tracks;if(!Array.isArray(o)||o.length===0)return null;let r=[];for(let c of o){let u=ge(c);u&&r.push(u);}if(r.length===0)return null;let a=typeof i.currentIndex=="number"?i.currentIndex:typeof i.current_index=="number"?i.current_index:0,l=Math.max(0,Math.min(Math.floor(a),r.length-1));return {tracks:r,currentIndex:l}}function f(s,...t){for(let e of t){let i=s[e];if(typeof i=="string")return i}return ""}function te(s,...t){for(let e of t){let i=s[e];if(typeof i=="boolean")return i}return false}function ie(s,...t){for(let e of t){let i=s[e];if(typeof i=="number"&&Number.isFinite(i))return i;if(typeof i=="string"&&i.trim()){let n=Number(i);if(Number.isFinite(n))return n}}return 0}function ne(s){let t=s.ad;if(!t||typeof t!="object")return null;let e=t,i=f(e,"playbackUrl","playback_url");return i?{adId:f(e,"adId","ad_id"),campaignId:f(e,"campaignId","campaign_id"),playbackUrl:i,isHls:te(e,"isHls","is_hls")||i.includes(".m3u8"),durationSeconds:ie(e,"durationSeconds","duration_seconds")||15,isSkippable:te(e,"isSkippable","is_skippable"),skipAfterSeconds:ie(e,"skipAfterSeconds","skip_after_seconds"),ctaType:f(e,"ctaType","cta_type"),ctaValue:f(e,"ctaValue","cta_value"),brandName:f(e,"brandName","brand_name"),creativeName:f(e,"creativeName","creative_name"),companionBannerUrl:f(e,"companionBannerUrl","companion_banner_url"),campaignName:f(e,"campaignName","campaign_name")}:null}var N="audio/pcm;rate=16000",k="audio/mpeg";function se(s,t){let e=/rate=(\d+)/i.exec(s);if(!e)return t;let i=Number(e[1]);return Number.isFinite(i)&&i>0?i:t}function P(s,...t){for(let e of t){let i=s[e];if(typeof i=="string")return i}return ""}function re(s){let t=s.voiceAck??s.voice_ack;if(!t||typeof t!="object")return null;let e=t,i=P(e,"status");return i?{status:i,transcript:P(e,"transcript")||void 0,playlistCode:P(e,"playlistCode","playlist_code")||void 0,playlistName:P(e,"playlistName","playlist_name")||void 0}:null}function ae(s){let t=s.voiceAudio??s.voice_audio;if(!t||typeof t!="object")return null;let e=t,i=e.audioData??e.audio_data,n=P(e,"mimeType","mime_type")||k,o=!!(e.isFinal??e.is_final),r;if(typeof i=="string"){let a=atob(i),l=a.length;r=new Uint8Array(l);for(let c=0;c<l;c++)r[c]=a.charCodeAt(c);}else if(i instanceof Uint8Array)r=i;else return null;return {audioData:r,mimeType:n,isFinal:o}}var M=class{constructor(){this.audioContext=null;this.nextStartTime=0;this.defaultSampleRate=24e3;this.encodedChunks=[];this.encodedMimeType=k;this.activeSource=null;this.playbackPromise=null;}initContext(t){this.audioContext||(this.audioContext=new(window.AudioContext||window.webkitAudioContext)({sampleRate:t}),this.nextStartTime=this.audioContext.currentTime);}enqueueChunk(t,e=k){if(!e.startsWith("audio/pcm")){this.encodedMimeType=e,this.encodedChunks.push(new Uint8Array(t));return}try{let i=se(e,this.defaultSampleRate);if(this.initContext(i),!this.audioContext)return;let n=new Int16Array(t.buffer,t.byteOffset,t.byteLength/2),o=new Float32Array(n.length);for(let c=0;c<n.length;c++)o[c]=n[c]/32768;let r=this.audioContext.createBuffer(1,o.length,i);r.getChannelData(0).set(o);let a=this.audioContext.createBufferSource();this.activeSource=a,a.buffer=r,a.connect(this.audioContext.destination);let l=this.audioContext.currentTime;this.nextStartTime<l&&(this.nextStartTime=l+.05),a.start(this.nextStartTime),this.nextStartTime+=r.duration;}catch(i){h("VoiceResponsePlayer failed to enqueue chunk",i);}}finish(t=this.encodedMimeType){if(!this.encodedChunks.length)return this.playbackPromise??Promise.resolve();let e=this.encodedChunks.splice(0);return this.encodedMimeType=t||k,this.playbackPromise=this.playEncoded(e,this.encodedMimeType).finally(()=>{this.playbackPromise=null;}),this.playbackPromise}async playEncoded(t,e){if(this.initContext(this.defaultSampleRate),!this.audioContext)return;this.audioContext.state==="suspended"&&await this.audioContext.resume().catch(()=>{});let i=t.map(r=>{let a=new Uint8Array(r.byteLength);return a.set(r),a.buffer}),n=new Blob(i,{type:e}),o=await this.audioContext.decodeAudioData(await n.arrayBuffer());await new Promise((r,a)=>{if(!this.audioContext){r();return}let l=this.audioContext.createBufferSource();this.activeSource=l,l.buffer=o,l.connect(this.audioContext.destination),l.onended=()=>{this.activeSource===l&&(this.activeSource=null),r();};try{l.start();}catch(c){this.activeSource===l&&(this.activeSource=null),a(c);}});}stop(){if(this.activeSource){try{this.activeSource.stop();}catch{}this.activeSource=null;}this.encodedChunks=[],this.playbackPromise=null,this.audioContext&&(this.audioContext.close().catch(()=>{}),this.audioContext=null),this.nextStartTime=0;}};var be="https://cdn.jsdelivr.net/npm/@ricky0123/vad-web@0.0.29/dist/",Se="https://cdn.jsdelivr.net/npm/onnxruntime-web@1.22.0/dist/";async function xe(){let s=await import('@ricky0123/vad-web'),t=s.MicVAD??s.default?.MicVAD;if(!t)throw new Error("MicVAD export missing from @ricky0123/vad-web \u2014 check bundler resolves the package");return t}var A=class extends m{constructor(){super(...arguments);this.capturing=false;this.mimeType=N;this.micVad=null;this.vadBaseAssetPath=be;this.onnxWasmBasePath=Se;this.userSpeaking=false;this.chunkSequence=0;}get isCapturing(){return this.capturing}get isUserSpeaking(){return this.userSpeaking}async preloadModels(e={}){this.applyOptions(e),await this.ensureMicVad();}applyOptions(e){e.vadBaseAssetPath&&(this.vadBaseAssetPath=e.vadBaseAssetPath),e.onnxWasmBasePath&&(this.onnxWasmBasePath=e.onnxWasmBasePath);}setUserSpeaking(e){this.userSpeaking!==e&&(this.userSpeaking=e,this.emit("userSpeakingChange",e));}async ensureMicVad(){if(this.micVad)return;let i=await(await xe()).new({baseAssetPath:this.vadBaseAssetPath,onnxWASMBasePath:this.onnxWasmBasePath,positiveSpeechThreshold:.5,negativeSpeechThreshold:.35,redemptionMs:500,minSpeechMs:250,onFrameProcessed:(n,o)=>{if(!this.capturing)return;let r=new Int16Array(o.length);for(let a=0;a<o.length;a++){let l=Math.max(-1,Math.min(1,o[a]));r[a]=l<0?l*32768:l*32767;}this.chunkSequence+=1,this.emit("chunk",new Uint8Array(r.buffer),this.chunkSequence);},onSpeechStart:()=>{this.capturing&&(this.setUserSpeaking(true),this.emit("speechStart"));},onSpeechEnd:()=>{this.capturing&&(this.setUserSpeaking(false),this.emit("speechEnd"));}});i.pause(),this.micVad=i;}async start(e={}){if(this.capturing)return this.mimeType;this.applyOptions(e),this.chunkSequence=0,this.setUserSpeaking(false);try{await this.ensureMicVad(),this.capturing=!0,this.micVad.start();}catch(i){this.capturing=false;let n=i instanceof Error?i:new Error(String(i));h("Voice capture failed to start",n),this.emit("error",n);}return this.mimeType}async stop(){this.capturing=false,this.setUserSpeaking(false),this.micVad&&this.micVad.pause();}cancel(){this.capturing=false,this.setUserSpeaking(false),this.micVad&&this.micVad.pause();}};var L=class extends m{constructor(e){super();this.status="idle";this.volume=.8;this.activeContentKind=0;this.heartbeatTimer=null;this.adPlaying=false;this._currentAd=null;this._voiceState="idle";this.voiceMimeType="audio/webm";this.pendingPlaybackLoad=null;this.voiceAutoEndOnSilence=true;this.pausedForVoice=false;this._voiceUserSpeaking=false;this.voiceResponseDismissed=false;this.voicePlaybackPromise=null;this.config=e,X(!!e.debug),this.transport=new w,this.audio=new V,this.playlist=new _,this.voiceCapture=new A,this.voiceResponsePlayer=new M,this.setupListeners(),this.voiceCapture.preloadModels(this.config.voice),e.autoConnect&&this.connect();}get currentTrack(){return this.playlist.getCurrentTrack()}get contentKind(){return this.activeContentKind}get currentAd(){return this._currentAd}get isAdPlaying(){return this.adPlaying}canSkipAd(){return !this.adPlaying||!this._currentAd?.isSkippable?false:Math.floor(this.audio.currentTime*1e3)>=this._currentAd.skipAfterSeconds*1e3}getAdSkipCountdownSeconds(){if(!this.adPlaying||!this._currentAd?.isSkippable)return null;let e=Math.floor(this.audio.currentTime*1e3),i=this._currentAd.skipAfterSeconds*1e3;return e>=i?0:Math.ceil((i-e)/1e3)}get voiceState(){return this._voiceState}get voiceUserSpeaking(){return this._voiceUserSpeaking}controlPositionMs(){return this.activeContentKind===4?0:this.positionMsForAnalytics()}setupListeners(){this.transport.on("connected",()=>this.emit("connected")),this.transport.on("disconnected",e=>this.emit("disconnected",e)),this.transport.on("error",e=>this.emit("error",new O(e.message))),this.transport.on("message",e=>this.handleServerMessage(e)),this.audio.on("playing",()=>this.updateStatus("playing")),this.audio.on("paused",()=>this.updateStatus("paused")),this.audio.on("stopped",()=>{!this.adPlaying&&this._voiceState==="idle"&&this.updateStatus("idle");}),this.audio.on("loading",()=>this.updateStatus("loading")),this.audio.on("error",e=>{if(this.adPlaying){h("Ad playback error \u2014 waiting for next track",e);return}this.emit("error",new C(e));}),this.audio.on("timeupdate",e=>{this.emit("timeUpdate",e),this.adPlaying&&this._currentAd&&this.emitAdSkipUpdate(e.currentTime);}),this.audio.on("ended",()=>this.handleTrackEnded()),this.playlist.on("trackChanged",e=>this.emit("trackChange",e)),this.playlist.on("queueUpdated",e=>this.emit("queueUpdated",e)),this.voiceCapture.on("chunk",(e,i)=>{this.transport.sendVoice({action:2,audioData:e,mimeType:this.voiceMimeType,sequence:i,listenerId:this.voiceListenerId,deviceType:this.config.deviceType,gameContext:this.config.gameContext});}),this.voiceCapture.on("error",e=>{this.setVoiceState("error"),this.emit("error",new x(e.message,"VOICE_CAPTURE_FAILED"));}),this.voiceCapture.on("speechStart",()=>{this.emit("voiceSpeechStart");}),this.voiceCapture.on("speechEnd",()=>{this.emit("voiceSpeechEnd"),this.voiceAutoEndOnSilence&&this._voiceState==="listening"&&this.endVoiceHold();}),this.voiceCapture.on("userSpeakingChange",e=>{this._voiceUserSpeaking=e,this.emit("voiceUserSpeakingChange",e);});}resolveVoiceOptions(e={}){return {...this.config.voice,...e}}connect(){this.transport.connect(this.config.apiKey,this.config.serverUrl);}buildInitExtras(){let e={};return this.config.gameContext?.trim()&&(e.gameContext=this.config.gameContext.trim()),this.config.deviceType?.trim()&&(e.deviceType=this.config.deviceType.trim()),e}async playSong(e){this.transport.isConnected||this.connect(),await this.transport.waitForConnection(),this.voiceResponseDismissed=false,this.activeContentKind=1,this.transport.sendInit({contentKind:1,catalogTrackId:e.catalogTrackId,internalTrackId:e.internalTrackId,listenerId:e.listenerId,...this.buildInitExtras()});}async playPlaylist(e){this.transport.isConnected||this.connect(),await this.transport.waitForConnection(),this.voiceResponseDismissed=false,this.activeContentKind=2,this.transport.sendInit({contentKind:2,playlistCode:e.playlistCode,listenerId:e.listenerId,...this.buildInitExtras()});}async playRadio(e={}){this.transport.isConnected||this.connect(),await this.transport.waitForConnection(),this.voiceResponseDismissed=false,this.activeContentKind=4,this.transport.sendInit({contentKind:4,listenerId:e.listenerId,...this.buildInitExtras()});}async beginVoiceHold(e={}){if(this._voiceState==="listening"||this._voiceState==="processing"||this._voiceState==="responding")return;let i=this.resolveVoiceOptions(e);this.voiceAutoEndOnSilence=i.autoEndOnSilence!==false,this._voiceUserSpeaking=false,this.voiceResponseDismissed=false,this.transport.isConnected||this.connect(),await this.transport.waitForConnection(),this.voiceListenerId=i.listenerId?.trim()||void 0,this.pausedForVoice=this.status==="playing",this.pausedForVoice&&this.pause(),this.voiceResponsePlayer.stop(),this.setVoiceState("listening"),this.voiceMimeType=await this.voiceCapture.start({maxDurationMs:i.maxDurationMs}),this.transport.sendVoice({action:1,mimeType:this.voiceMimeType||N,listenerId:this.voiceListenerId,...this.buildInitExtras()});}async endVoiceHold(){this._voiceState==="listening"&&(this._voiceUserSpeaking=false,this.emit("voiceUserSpeakingChange",false),this.setVoiceState("processing"),await this.voiceCapture.stop(),this.transport.sendVoice({action:3,mimeType:this.voiceMimeType,listenerId:this.voiceListenerId,...this.buildInitExtras()}));}cancelVoiceHold(){this._voiceState==="listening"&&(this._voiceUserSpeaking=false,this.voiceCapture.cancel(),this.transport.sendVoice({action:4,mimeType:this.voiceMimeType,listenerId:this.voiceListenerId,...this.buildInitExtras()}),this.setVoiceState("idle"));}dismissVoiceAndResume(){this.voiceResponseDismissed=true,this.voiceResponsePlayer.stop(),this._voiceState==="listening"?this.cancelVoiceHold():(this._voiceState==="processing"||this._voiceState==="responding")&&(this.transport.sendVoice({action:4,mimeType:this.voiceMimeType,listenerId:this.voiceListenerId,...this.buildInitExtras()}),this.setVoiceState("idle")),this.pausedForVoice&&(this.resume(),this.pausedForVoice=false);}get isVoiceUiActive(){return this._voiceState==="listening"||this._voiceState==="processing"||this._voiceState==="responding"}pause(){this.audio.pause(),this.transport.sendControl({action:2,positionMs:this.controlPositionMs()});}resume(){this.audio.play(),this.transport.sendControl({action:1,positionMs:this.controlPositionMs()});}stop(){this.audio.stop(),this.transport.sendControl({action:3,positionMs:this.controlPositionMs()});}skip(){if(this.activeContentKind===4)return;if(this.adPlaying){this.skipAd();return}if(this.playlist.queueSnapshot.length>1){this.transport.sendControl({action:5,positionMs:this.controlPositionMs()}),this.updateStatus("loading");return}let e=this.playlist.next();e&&this.playSong(e.kind==="internal"?{internalTrackId:e.id}:{catalogTrackId:e.id});}previous(){if(this.activeContentKind===4)return;if(this.playlist.queueSnapshot.length>1){this.transport.sendControl({action:6,positionMs:this.controlPositionMs()}),this.updateStatus("loading");return}let e=this.playlist.previous();e&&this.playSong(e.kind==="internal"?{internalTrackId:e.id}:{catalogTrackId:e.id});}skipTo(e){if(this.activeContentKind===4)return;let i=this.playlist.skipTo(e);i&&this.playSong(i.kind==="internal"?{internalTrackId:i.id}:{catalogTrackId:i.id});}seek(e){this.activeContentKind===4||this.adPlaying||(this.audio.seek(e),this.transport.sendControl({action:4,positionMs:e}));}setVolume(e){this.volume=Math.max(0,Math.min(1,e)),this.audio.setVolume(this.volume);}positionMsForAnalytics(e){return typeof e=="number"?Math.max(0,Math.min(4294967295,Math.floor(e))):Math.max(0,Math.min(4294967295,Math.floor(this.audio.currentTime)))}emitAnalytics(e,i,n){this.transport.sendAnalytics({eventType:e,positionMs:this.positionMsForAnalytics(i),extraJson:n?JSON.stringify(n):void 0});}clearHeartbeat(){this.heartbeatTimer!==null&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null);}startHeartbeat(e){this.clearHeartbeat();let i=Number(e);!i||i<1e3||(this.heartbeatTimer=setInterval(()=>{let n=this.activeContentKind===4?0:this.positionMsForAnalytics();this.emitAnalytics("heartbeat",n);},i));}applyContentSummary(e){let i=ee(e,this.activeContentKind);if(i){this.playlist.setQueue(i.tracks,i.currentIndex);return}e?.trim()&&h("Could not parse contentSummary; queue metadata unavailable.");}emitAdSkipUpdate(e){if(!this._currentAd)return;let i=this._currentAd.skipAfterSeconds*1e3,n=this._currentAd.isSkippable&&e>=i,o=n?0:Math.ceil((i-e)/1e3),r={ad:this._currentAd,canSkip:n,countdownSeconds:o};this.emit("adSkipUpdate",r);}setVoiceState(e){this._voiceState=e,this.emit("voiceStateChange",e);}handleVoiceAck(e){let i=e.status;if(i==="cancelled"){this._voiceState!=="idle"&&this.setVoiceState("idle");return}if(!this.voiceResponseDismissed){if(i==="listening"){this._voiceState==="idle"&&this.setVoiceState("listening");return}if(i==="processing"){(this._voiceState==="listening"||this._voiceState==="idle")&&this.setVoiceState("processing");return}if(i==="ready"){this.activeContentKind=2;let n={status:i,transcript:e.transcript,playlistCode:e.playlistCode,playlistName:e.playlistName};this.setVoiceState("ready"),this.emit("voiceResult",n);return}this.emit("voiceResult",{status:i,transcript:e.transcript,playlistCode:e.playlistCode,playlistName:e.playlistName});}}async handleServerMessage(e){v("Received server message",e);let i=re(e);if(i){this.handleVoiceAck(i);return}let n=ae(e);if(n){if(this.voiceResponseDismissed)return;this._voiceState==="processing"&&this.setVoiceState("responding"),n.audioData.length>0&&this.voiceResponsePlayer.enqueueChunk(n.audioData,n.mimeType),n.isFinal&&(this.voicePlaybackPromise=this.voiceResponsePlayer.finish(n.mimeType).catch(l=>{h("Voice response playback failed",l);}).finally(()=>{this.voicePlaybackPromise=null;}));return}let o=ne(e);if(o){await this.handleAdPlayback(o);return}let r=Z(e);if(r){if(this.voiceResponseDismissed)return;await this.startContentPlayback(r);return}let a=e.error;if(a&&typeof a=="object"){let l=a,c=typeof l.message=="string"?l.message:"Unknown server error",u=typeof l.code=="string"?l.code:void 0;(this._voiceState==="processing"||this._voiceState==="listening"||this._voiceState==="responding")&&this.setVoiceState("error"),this.emit("error",new x(c,u));}}async startContentPlayback(e){if(this.adPlaying&&this._currentAd){let n=this._currentAd;this.adPlaying=false,this._currentAd=null,this.emit("adEnd",n);}else this.adPlaying=false,this._currentAd=null;this.voicePlaybackPromise&&!this.voiceResponseDismissed&&await this.voicePlaybackPromise,(this._voiceState==="ready"||this._voiceState==="processing"||this._voiceState==="responding")&&this.setVoiceState("idle"),this.pausedForVoice=false,this.voiceResponsePlayer.stop(),v("Loading playback",{url:e.playbackUrl,isHls:e.isHls});let i=this.audio.load(e.playbackUrl,e.isHls);this.pendingPlaybackLoad=i;try{if(await i,this.pendingPlaybackLoad!==i)return;this.audio.play(),this.emitAnalytics("stream_start",this.activeContentKind===4?0:void 0),this.startHeartbeat(e.heartbeatIntervalMs),this.applyContentSummary(e.contentSummary);}catch(n){if(this.pendingPlaybackLoad!==i)return;this.emit("error",new C(n));}finally{this.pendingPlaybackLoad===i&&(this.pendingPlaybackLoad=null);}}async handleAdPlayback(e){this.pendingPlaybackLoad&&await this.pendingPlaybackLoad.catch(()=>{}),this.audio.stop(),this.adPlaying=true,this._currentAd={adId:e.adId,campaignId:e.campaignId,brandName:e.brandName,creativeName:e.creativeName,durationSeconds:e.durationSeconds,isSkippable:e.isSkippable,skipAfterSeconds:e.skipAfterSeconds,ctaType:e.ctaType,ctaValue:e.ctaValue,companionBannerUrl:e.companionBannerUrl,campaignName:e.campaignName},v("Loading ad playback",{url:e.playbackUrl,isHls:e.isHls});try{await this.audio.load(e.playbackUrl,e.isHls),this.audio.play(),this.emit("adStart",this._currentAd),this.emitAdSkipUpdate(0);}catch(i){let n=this._currentAd;this.adPlaying=false,this._currentAd=null,n&&this.emit("adEnd",n),h("Ad load failed",i),this.updateStatus("loading");}}skipAd(){if(!this.adPlaying||!this._currentAd||!this._currentAd.isSkippable)return;let e=Math.floor(this.audio.currentTime*1e3);if(e<this._currentAd.skipAfterSeconds*1e3)return;let i=this._currentAd;this.adPlaying=false,this._currentAd=null,this.audio.stop(),this.emit("adEnd",i),this.emitAnalytics("ad_skip",e),this.updateStatus("loading");}clickAd(){if(!this.adPlaying||!this._currentAd)return;let e=Math.floor(this.audio.currentTime*1e3);this.emitAnalytics("ad_cta_click",e),this._currentAd.ctaValue&&window.open(this._currentAd.ctaValue,"_blank");}handleTrackEnded(){if(this.activeContentKind!==4){if(this.adPlaying&&this._currentAd){let e=this._currentAd;this.audio.stop(),this.emitAnalytics("ad_complete",Math.floor(this.audio.currentTime*1e3)),this.emit("adEnd",e),this.adPlaying=false,this._currentAd=null,this.updateStatus("loading");return}if(this.playlist.queueSnapshot.length>1){this.emitAnalytics("track_complete",Math.floor(this.audio.duration*1e3)),this.updateStatus("loading");return}if(this.activeContentKind===1||this.activeContentKind===2){this.emitAnalytics("track_complete",Math.floor(this.audio.duration*1e3)),this.updateStatus("loading");return}this.updateStatus("idle");}}updateStatus(e){this.status=e,this.emit("stateChange",{status:e,currentTrack:this.playlist.getCurrentTrack(),currentTime:this.audio.currentTime,duration:this.audio.duration,volume:this.volume});}destroy(){this.clearHeartbeat(),this.cancelVoiceHold(),this.voiceResponsePlayer.stop(),this.audio.stop(),this.transport.disconnect(),this.playlist.reset(),this.removeAllListeners();}};async function K(s,t){let i=`${s.replace(/\/$/,"")}/radio/now-playing`;try{let n=await fetch(i,{...t,headers:{Accept:"application/json",...t?.headers}});if(!n.ok)return null;let r=(await n.json())?.data;return !r?.title||typeof r.title!="string"?null:{title:r.title,station:typeof r.station=="string"?r.station:void 0,isLive:typeof r.isLive=="boolean"?r.isLive:void 0}}catch{return null}}function d(s,t){let e=document.createElement(s);if(t?.className&&(e.className=t.className),t?.attrs)for(let[i,n]of Object.entries(t.attrs))e.setAttribute(i,n);return t?.style&&Object.assign(e.style,t.style),t?.text&&(e.textContent=t.text),t?.html&&(e.innerHTML=t.html),t?.onClick&&e.addEventListener("click",t.onClick),t?.children&&t.children.forEach(i=>e.appendChild(i)),e}function y(s,t=20){let e=document.createElementNS("http://www.w3.org/2000/svg","svg");e.setAttribute("width",String(t)),e.setAttribute("height",String(t)),e.setAttribute("viewBox","0 0 24 24"),e.setAttribute("fill","currentColor"),e.setAttribute("aria-hidden","true");let i=document.createElementNS("http://www.w3.org/2000/svg","path");return i.setAttribute("d",s),e.appendChild(i),e}var F="M8 5v14l11-7L8 5z",oe="M6 5h4v14H6V5zm8 0h4v14h-4V5z",E="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z",le="M6 6h2v12H6V6zm11.5 12L9 12l8.5-6v12z";function de(){let s="synxed-web-player-styles";if(document.getElementById(s))return;let t=document.createElement("style");t.id=s,t.textContent=`
|
|
137
137
|
@keyframes synxed-wp-spin { from { transform: rotate(0); } to { transform: rotate(360deg); } }
|
|
138
138
|
@keyframes synxed-wp-vbar {
|
|
139
139
|
0%, 100% { transform: scaleY(0.28); opacity: 0.45; }
|
|
140
140
|
50% { transform: scaleY(1); opacity: 1; }
|
|
141
141
|
}
|
|
142
|
-
`,document.head.appendChild(t);}function ce(s){let t=[" \u2014 "," \u2013 "," - "," \u2014"," \u2013"," -"];for(let e of t){let i=s.indexOf(e);if(i>0)return {title:s.slice(0,i).trim(),artist:s.slice(i+e.length).trim()}}return {title:s.trim()}}function pe(s="bottom-center",t=16,e=16){let i={position:"fixed",zIndex:"50"};switch(s){case "top-left":return {...i,top:`${e}px`,left:`${t}px`};case "top-right":return {...i,top:`${e}px`,right:`${t}px`};case "bottom-left":return {...i,bottom:`${e}px`,left:`${t}px`};case "bottom-right":return {...i,bottom:`${e}px`,right:`${t}px`};default:return {...i,bottom:`${e}px`,left:"50%",transform:"translateX(-50%)"}}}function he(s={}){return {accent:s.accent??"#22c55e",accentMuted:s.accentMuted??s.accent??"#22c55e",background:s.background??"#051107",backgroundInner:s.backgroundInner??"#0a1f10",border:s.border??"rgba(34, 197, 94, 0.35)",text:s.text??"#ffffff",textMuted:s.textMuted??"rgba(255,255,255,0.35)",stationText:s.stationText??"rgba(34, 197, 94, 0.85)",liveDot:s.liveDot??"#CCFF00",glow:s.glow??"rgba(34, 197, 94, 0.35)"}}function ue(s,t){s.style.setProperty("--sw-accent",t.accent),s.style.setProperty("--sw-accent-muted",t.accentMuted),s.style.setProperty("--sw-bg",t.background),s.style.setProperty("--sw-bg-inner",t.backgroundInner),s.style.setProperty("--sw-border",t.border),s.style.setProperty("--sw-text",t.text),s.style.setProperty("--sw-text-muted",t.textMuted),s.style.setProperty("--sw-station",t.stationText),s.style.setProperty("--sw-live",t.liveDot),s.style.setProperty("--sw-glow",t.glow);}var z="https://cdn.synxed.com/avater-image/avatar.svg",ke="https://cdn.synxed.com/avater-image/AI%20Star%20UI%20animation.gif",q=class s{constructor(t){this.engine=null;this.pollTimer=null;this.destroyed=false;this.isPlaying=false;this.currentTrack=null;this.nowPlaying=null;this.currentAd=null;this.skipBtn=null;this.avatarImgEl=null;this.avatarTextEl=null;this.avatarRing=null;this.titleEl=null;this.artistInlineEl=null;this.artistBlockEl=null;this.footerEl=null;this.playBtn=null;this.avatarVoiceHolding=false;this.suppressMiniClick=false;this.voiceAvatarPreview=false;this.voiceHoldActivated=false;this.voiceUiDismissed=false;this.voiceUserSpeaking=false;this.voiceHadSpeech=false;this.voiceHoldTimer=null;this.defaultVoiceHoldMs=450;this.options={mode:"wide",attribution:"Synxed",nowPlayingPollMs:12e3,powerByLabel:"Powered by Synxed",enableVoice:true,...t},this.theme=he(this.options.theme),this.ownsRoot=!t.container,this.root=t.container??document.createElement("div"),this.ownsRoot&&document.body.appendChild(this.root),de(),this.mountShell(),this.initEngine(),this.options.source.type==="radio"&&this.startNowPlayingPoll();}static mount(t){return new s(t)}get player(){return this.engine}get element(){return this.root}destroy(){this.destroyed||(this.destroyed=true,this.stopNowPlayingPoll(),this.engine?.destroy(),this.engine=null,this.ownsRoot&&this.root.remove());}get voiceEnabled(){return this.options.enableVoice!==false}get isRadio(){return this.options.source.type==="radio"}get mode(){return this.options.mode??"wide"}mountShell(){let{position:t={},className:e,style:i}=this.options,n=t.placement??"bottom-center",o=t.offsetX??16,r=t.offsetY??(n==="bottom-center"?24:16);this.root.className=e??"",this.root.dataset.synxedWebPlayer=this.mode,ue(this.root,this.theme),Object.assign(this.root.style,pe(n,o,r)),i&&Object.assign(this.root.style,i),this.root.replaceChildren(),this.mode==="mini"?this.buildMini():this.mode==="large"?this.buildLarge():this.buildWide(),this.refreshLabels(),this.setPlayingVisual(this.isPlaying),this.options.draggable&&this.ownsRoot&&this.makeDraggable();}makeDraggable(){let t=false,e=false,i=0,n=0,o=0,r=0,a=h=>{let p=h,g=p.target;if(g.closest("[data-synxed-avatar-ring]")||this.avatarVoiceHolding||this.mode!=="mini"&&g.closest("button, a, input"))return;t=true,e=false;let b=this.root.getBoundingClientRect();o=b.left,r=b.top,this.root.style.bottom="auto",this.root.style.right="auto",this.root.style.transform="none",this.root.style.margin="0",this.root.style.left=`${o}px`,this.root.style.top=`${r}px`,"touches"in p?(i=p.touches[0].clientX,n=p.touches[0].clientY):(i=p.clientX,n=p.clientY),document.addEventListener("mousemove",l,{passive:false}),document.addEventListener("mouseup",c),document.addEventListener("touchmove",l,{passive:false}),document.addEventListener("touchend",c);},l=h=>{if(!t)return;h.preventDefault();let p=h,g,b;"touches"in p?(g=p.touches[0].clientX,b=p.touches[0].clientY):(g=p.clientX,b=p.clientY);let T=g-i,I=b-n;(Math.abs(T)>3||Math.abs(I)>3)&&(e=true),this.root.style.left=`${o+T}px`,this.root.style.top=`${r+I}px`;},c=()=>{t=false,document.removeEventListener("mousemove",l),document.removeEventListener("mouseup",c),document.removeEventListener("touchmove",l),document.removeEventListener("touchend",c),setTimeout(()=>{e=false;},0);};this.root.style.cursor="grab",this.root.addEventListener("mousedown",a),this.root.addEventListener("touchstart",a,{passive:false}),this.root.addEventListener("click",h=>{e&&(h.stopPropagation(),h.preventDefault());},true);}buildAvatar(t,e=false){let i=d("div",{style:{position:"relative",flexShrink:"0"}});this.avatarRing=d("div",{attrs:{"data-synxed-avatar-ring":"true"},style:{width:`${t}px`,height:`${t}px`,borderRadius:"50%",border:"3px solid var(--sw-accent)",padding:"3px",boxShadow:"0 0 24px var(--sw-glow), 0 0 48px rgba(0,0,0,0.25)",background:"var(--sw-bg)",boxSizing:"border-box",userSelect:"none",webkitUserSelect:"none"}}),this.avatarRing.style.setProperty("-webkit-touch-callout","none");let n=d("div",{style:{width:"100%",height:"100%",borderRadius:"50%",background:"var(--sw-bg-inner)",overflow:"hidden",userSelect:"none",webkitUserSelect:"none"}});return n.style.setProperty("-webkit-touch-callout","none"),this.avatarImgEl=d("img",{attrs:{src:z,alt:"Synxed DJ",draggable:"false"},style:{width:"100%",height:"100%",objectFit:"cover",objectPosition:"top",transform:this.mode==="wide"?"scale(1.15)":"scale(1.12)",display:"block",pointerEvents:"none",userSelect:"none",webkitUserSelect:"none"}}),this.avatarImgEl.style.setProperty("-webkit-touch-callout","none"),this.avatarTextEl=d("div",{text:"S",style:{width:"100%",height:"100%",display:"none",alignItems:"center",justifyContent:"center",color:"var(--sw-accent)",fontWeight:"900",fontSize:`${Math.round(t*.28)}px`}}),n.appendChild(this.avatarImgEl),n.appendChild(this.avatarTextEl),n.style.cursor=this.voiceEnabled?"pointer":"default",n.addEventListener("click",o=>{if(this.isVoiceUiOpen()){o.stopPropagation(),this.dismissVoiceUi();return}this.currentAd&&this.engine&&(o.stopPropagation(),this.engine.clickAd());}),n.addEventListener("contextmenu",o=>o.preventDefault()),n.addEventListener("dragstart",o=>o.preventDefault()),n.addEventListener("selectstart",o=>o.preventDefault()),this.voiceEnabled&&(this.avatarRing.style.touchAction="none",this.avatarRing.addEventListener("contextmenu",o=>o.preventDefault()),this.avatarRing.addEventListener("dragstart",o=>o.preventDefault()),this.avatarRing.addEventListener("selectstart",o=>o.preventDefault()),this.avatarRing.setAttribute("aria-label","Hold to speak to DJ")),this.avatarRing.appendChild(n),i.appendChild(this.avatarRing),i.appendChild(d("span",{style:{position:"absolute",...e?{top:"4px",left:"4px"}:{bottom:"6px",left:"6px"},width:e?"10px":"12px",height:e?"10px":"12px",borderRadius:"50%",background:"var(--sw-live)",border:"2px solid var(--sw-bg)",boxShadow:"0 0 8px var(--sw-live)"}})),i}buildMini(){let e=d("div",{attrs:{role:"button",tabindex:"0","aria-label":"Synxed mini player \u2014 tap to play, hold to speak","data-synxed-mini-shell":"true"},style:{position:"relative",padding:"0",cursor:"pointer",background:"transparent"}});e.addEventListener("keydown",i=>{i.key!=="Enter"&&i.key!==" "||(i.preventDefault(),!this.suppressMiniClick&&!this.avatarVoiceHolding&&this.handleMiniActivate());}),e.addEventListener("click",()=>{if(!this.suppressMiniClick){if(this.isVoiceUiOpen()){this.dismissVoiceUi();return}this.avatarVoiceHolding||this.handleMiniActivate();}}),e.appendChild(this.buildAvatar(72)),this.root.appendChild(e);}handleMiniActivate(){if(this.isVoiceUiOpen()){this.dismissVoiceUi();return}this.options.onMiniClick?this.options.onMiniClick():this.togglePlay();}buildWide(){let e="0 8px 40px var(--sw-glow), 0 0 0 1px var(--sw-border)";this.root.style.width="min(calc(100vw - 20px), 560px)";let i=d("div",{style:{position:"relative",display:"flex",alignItems:"center",width:"100%"}}),n=Math.max(90*.42,40);i.appendChild(d("div",{style:{position:"absolute",top:"8px",bottom:"8px",left:`${n}px`,right:"0",background:"var(--sw-bg)",border:"1px solid var(--sw-border)",borderRadius:"28px 20px 20px 28px",boxShadow:e,overflow:"hidden"},children:[d("div",{style:{position:"absolute",inset:"0",background:"linear-gradient(90deg, color-mix(in srgb, var(--sw-accent) 12%, transparent), transparent)",pointerEvents:"none"}})]}));let o=this.buildAvatar(90);Object.assign(o.style,{position:"relative",zIndex:"1",marginLeft:"-2px"}),i.appendChild(o);let r=d("div",{style:{position:"relative",zIndex:"1",flex:"1",minWidth:"0",marginLeft:"14px",padding:"18px 8px"}}),a=d("div",{style:{display:"flex",alignItems:"baseline",gap:"8px",overflow:"hidden"}});this.titleEl=d("h3",{style:{margin:"0",fontSize:"clamp(15px, 2.8vw, 20px)",fontWeight:"900",color:"var(--sw-text)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}),a.appendChild(this.titleEl),this.artistInlineEl=d("span",{style:{fontSize:"clamp(12px, 2.4vw, 15px)",fontWeight:"300",color:"var(--sw-text-muted)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",display:"none"}}),a.appendChild(this.artistInlineEl),r.appendChild(a),this.footerEl=d("p",{style:{margin:"8px 0 0",fontSize:"9px",fontWeight:"700",color:"var(--sw-text-muted)",letterSpacing:"0.18em",textTransform:"uppercase",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}),r.appendChild(this.footerEl),i.appendChild(r);let l=d("div",{style:{position:"relative",zIndex:"1",flexShrink:"0",display:"flex",alignItems:"center",gap:"14px",paddingRight:"16px"}});this.playBtn=this.createPlayButton(52),l.appendChild(this.playBtn),this.isRadio||(this.skipBtn=d("button",{attrs:{type:"button","aria-label":"Skip"},style:{border:"none",background:"transparent",color:"var(--sw-text-muted)",display:"flex",cursor:"pointer",fontSize:"13px",fontWeight:"bold"},onClick:()=>this.handleSkipClick(),children:[y(E,22)]}),l.appendChild(this.skipBtn)),l.appendChild(this.decoLines()),i.appendChild(l),this.root.appendChild(i);}buildLarge(){this.root.style.width="min(calc(100vw - 24px), 380px)";let e=d("div",{style:{borderRadius:"24px",border:"1px solid var(--sw-border)",background:"var(--sw-bg)",boxShadow:"0 8px 40px var(--sw-glow), 0 0 0 1px var(--sw-border)",padding:"16px",display:"flex",flexDirection:"column",gap:"14px",fontFamily:"system-ui, -apple-system, Segoe UI, Roboto, sans-serif"}}),i=d("div",{style:{display:"flex",gap:"12px",alignItems:"center",minWidth:"0"}});i.appendChild(this.buildAvatar(96,true));let n=d("div",{style:{minWidth:"0",flex:"1"}});this.titleEl=d("h3",{style:{margin:"0",fontSize:"18px",fontWeight:"900",color:"var(--sw-text)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}),n.appendChild(this.titleEl),this.artistBlockEl=d("p",{style:{margin:"6px 0 0",fontSize:"13px",fontWeight:"700",color:"var(--sw-accent-muted)",letterSpacing:"0.08em",textTransform:"uppercase",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",display:"none"}}),n.appendChild(this.artistBlockEl),this.footerEl=d("p",{style:{margin:"6px 0 0",fontSize:"10px",fontWeight:"700",color:"var(--sw-station)",letterSpacing:"0.18em",textTransform:"uppercase",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}),n.appendChild(this.footerEl),i.appendChild(n),e.appendChild(i),e.appendChild(this.buildVisualizer()),e.appendChild(d("p",{text:this.options.powerByLabel??"Powered by Synxed",style:{margin:"0",fontSize:"9px",fontWeight:"600",color:"var(--sw-text-muted)",letterSpacing:"0.12em",textTransform:"uppercase",textAlign:"center"}}));let o=d("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",gap:"18px"}});this.isRadio||o.appendChild(d("button",{attrs:{type:"button","aria-label":"Previous"},style:this.roundControlStyle(),onClick:()=>this.engine?.previous(),children:[y(le,22)]})),this.playBtn=this.createPlayButton(56),o.appendChild(this.playBtn),this.isRadio||(this.skipBtn=d("button",{attrs:{type:"button","aria-label":"Skip"},style:{...this.roundControlStyle(),fontSize:"12px",fontWeight:"bold"},onClick:()=>this.handleSkipClick(),children:[y(E,22)]}),o.appendChild(this.skipBtn)),e.appendChild(o),this.root.appendChild(e);}roundControlStyle(){return {width:"46px",height:"46px",borderRadius:"50%",border:"1px solid var(--sw-border)",background:"rgba(255,255,255,0.04)",color:"var(--sw-text)",display:"flex",alignItems:"center",justifyContent:"center",cursor:"pointer"}}createPlayButton(t){return d("button",{attrs:{type:"button","aria-label":"Play"},style:{width:`${t}px`,height:`${t}px`,borderRadius:"50%",border:"none",background:"var(--sw-accent)",color:"#0a0a0a",display:"flex",alignItems:"center",justifyContent:"center",cursor:"pointer",boxShadow:"0 0 18px var(--sw-glow)",flexShrink:"0"},onClick:()=>this.togglePlay(),children:[y(F,t>=56?22:20)]})}buildVisualizer(){let t=d("div",{style:{display:"flex",alignItems:"flex-end",gap:"4px",height:"52px",padding:"8px 4px",borderRadius:"14px",border:"1px solid var(--sw-border)",overflow:"hidden"}});for(let e=0;e<24;e++)t.appendChild(d("span",{style:{flex:"1",minWidth:"3px",height:"100%",borderRadius:"4px",background:"linear-gradient(180deg, var(--sw-accent), transparent)",transformOrigin:"center bottom",animation:`synxed-wp-vbar ${1+e%5*.12}s ease-in-out infinite`,animationDelay:`${e*.04}s`,opacity:"0.85"}}));return t}decoLines(){let t=d("div",{style:{display:"flex",flexDirection:"column",gap:"3px",opacity:"0.22"}});return t.appendChild(d("span",{style:{display:"block",width:"16px",height:"2px",borderRadius:"999px",background:"var(--sw-text)",transform:"translateX(3px)"}})),t.appendChild(d("span",{style:{display:"block",width:"16px",height:"2px",borderRadius:"999px",background:"var(--sw-text)"}})),t}initEngine(){let{apiKey:t,serverUrl:e,source:i}=this.options,n=new L({apiKey:t,serverUrl:e,autoConnect:true,debug:this.options.debug,voice:this.options.voice});this.engine=n;let o=a=>{this.isPlaying=a.status==="playing",a.currentTrack&&(this.currentTrack=a.currentTrack),this.setPlayingVisual(this.isPlaying),this.refreshLabels(),!this.currentAd&&!this.engine?.isAdPlaying&&(this.restoreTrackSkipButton(),this.refreshAvatarImage());};n.on("stateChange",o),n.on("trackChange",a=>{this.currentTrack=a,this.avatarImageBeforeAd=void 0,this.refreshLabels(),!this.currentAd&&!this.engine?.isAdPlaying&&(this.restoreTrackSkipButton(),this.refreshAvatarImage());}),n.on("adStart",a=>{this.avatarImageBeforeAd=this.getContentAvatarUrl(),this.voiceAvatarPreview=false,this.voiceHoldActivated=false,this.currentAd=a,this.refreshLabels(),this.updateAvatar();}),n.on("adSkipUpdate",a=>this.applyAdSkipUi(a)),n.on("adEnd",()=>{this.currentAd=null,this.voiceAvatarPreview=false,this.refreshLabels(),this.updateAvatar(),this.restoreTrackSkipButton();}),n.on("voiceStateChange",a=>this.applyVoiceVisual(a)),n.on("voiceUserSpeakingChange",a=>{this.voiceUserSpeaking=a,a&&(this.voiceHadSpeech=true),this.applyVoiceRing();}),(i.type==="radio"?()=>n.playRadio():()=>n.playPlaylist({playlistCode:i.playlistCode}))().catch(()=>{}),this.voiceEnabled&&this.wireAvatarVoiceHold();}wireAvatarVoiceHold(){if(!this.avatarRing)return;let t=this.avatarRing,e=this.options.voiceHoldMs??this.defaultVoiceHoldMs,i=()=>{this.voiceHoldTimer!==null&&(clearTimeout(this.voiceHoldTimer),this.voiceHoldTimer=null);},n=a=>{if(!(this.currentAd||!this.engine)){if(this.isVoiceUiOpen()){a.preventDefault(),a.stopPropagation(),this.dismissVoiceUi();return}a.preventDefault(),a.stopPropagation(),t.setPointerCapture(a.pointerId),this.avatarVoiceHolding=true,this.voiceHoldActivated=false,i(),this.voiceHoldTimer=setTimeout(()=>{this.voiceHoldTimer=null,!(!this.avatarVoiceHolding||!this.engine)&&(this.voiceHoldActivated=true,this.voiceUiDismissed=false,this.voiceAvatarPreview=true,this.voiceUserSpeaking=false,this.voiceHadSpeech=false,this.applyVoiceRing(),this.refreshAvatarImage(),this.engine.beginVoiceHold({listenerId:this.options.listenerId}).catch(()=>{this.resetVoiceHoldState();}));},e);}},o=a=>{this.currentAd||a.stopPropagation();};t.addEventListener("mousedown",o),t.addEventListener("touchstart",o,{passive:false});let r=()=>{i(),this.avatarVoiceHolding&&(this.avatarVoiceHolding=false,this.voiceHoldActivated&&this.mode==="mini"&&(this.suppressMiniClick=true,setTimeout(()=>{this.suppressMiniClick=false;},320)));};t.addEventListener("pointerdown",n),t.addEventListener("pointerup",r),t.addEventListener("pointerleave",r),t.addEventListener("pointercancel",r);}isVoiceUiOpen(){return !this.voiceEnabled||this.currentAd||this.voiceUiDismissed?false:this.voiceHoldActivated||this.voiceAvatarPreview?true:!!this.engine?.isVoiceUiActive}dismissVoiceUi(){this.engine?.dismissVoiceAndResume(),this.resetVoiceHoldState(),this.voiceUiDismissed=true,this.applyVoiceRing(),this.refreshAvatarImage();}resetVoiceHoldState(){this.voiceHoldTimer!==null&&(clearTimeout(this.voiceHoldTimer),this.voiceHoldTimer=null),this.avatarVoiceHolding=false,this.voiceHoldActivated=false,this.voiceAvatarPreview=false,this.voiceUserSpeaking=false,this.voiceHadSpeech=false;}applyVoiceRing(){if(!this.avatarRing)return;if(this.voiceUiDismissed){this.avatarRing.style.borderColor="",this.avatarRing.style.boxShadow="0 0 24px var(--sw-glow), 0 0 48px rgba(0,0,0,0.25)",this.setPlayingVisual(this.isPlaying);return}let t=this.engine?.voiceState??"idle";if(t==="processing"){this.avatarRing.style.animation="",this.avatarRing.style.borderColor="#ef4444",this.avatarRing.style.boxShadow="0 0 20px rgba(239,68,68,0.5), 0 0 40px rgba(239,68,68,0.2)";return}if(t==="responding"){this.avatarRing.style.animation="",this.avatarRing.style.borderColor="#06b6d4",this.avatarRing.style.boxShadow="0 0 20px rgba(6,182,212,0.5), 0 0 40px rgba(6,182,212,0.2)";return}if(t==="listening"){this.voiceHadSpeech&&!this.voiceUserSpeaking?(this.avatarRing.style.animation="",this.avatarRing.style.borderColor="#ef4444",this.avatarRing.style.boxShadow="0 0 20px rgba(239,68,68,0.5), 0 0 40px rgba(239,68,68,0.2)"):(this.avatarRing.style.animation="",this.avatarRing.style.borderColor="#3b82f6",this.avatarRing.style.boxShadow="0 0 20px rgba(59,130,246,0.55), 0 0 40px rgba(59,130,246,0.25)");return}this.avatarRing.style.borderColor="",this.avatarRing.style.boxShadow="0 0 24px var(--sw-glow), 0 0 48px rgba(0,0,0,0.25)",this.setPlayingVisual(this.isPlaying);}applyVoiceVisual(t){this.avatarRing&&((t==="idle"||t==="ready"||t==="error")&&(this.avatarVoiceHolding||(this.voiceAvatarPreview=false),(t==="ready"||t==="idle")&&(this.voiceUiDismissed=false,this.voiceUserSpeaking=false,this.voiceHadSpeech=false)),t==="listening"&&(this.voiceUiDismissed=false),this.applyVoiceRing(),this.refreshAvatarImage());}isVoiceAvatarActive(){if(!this.voiceEnabled||this.currentAd||this.voiceUiDismissed)return false;if(this.voiceAvatarPreview)return true;let t=this.engine?.voiceState;return t==="listening"||t==="processing"||t==="responding"}getContentAvatarUrl(){return z}getAvatarImageUrl(){return this.currentAd?.companionBannerUrl?this.currentAd.companionBannerUrl:this.isVoiceAvatarActive()?ke:this.avatarImageBeforeAd?this.avatarImageBeforeAd:z}refreshAvatarImage(){let t=this.getAvatarImageUrl(),e=this.isVoiceAvatarActive();t&&this.avatarImgEl?(this.avatarImgEl.getAttribute("src")!==t&&this.avatarImgEl.setAttribute("src",t),this.avatarImgEl.style.display="block",e?(this.avatarImgEl.style.objectFit="cover",this.avatarImgEl.style.objectPosition="center",this.avatarImgEl.style.transform="scale(1)",this.avatarImgEl.style.padding="",this.avatarImgEl.style.background="var(--sw-bg-inner)"):(this.avatarImgEl.style.objectFit="cover",this.avatarImgEl.style.objectPosition="top",this.avatarImgEl.style.transform=this.mode==="wide"?"scale(1.15)":"scale(1.12)",this.avatarImgEl.style.padding="",this.avatarImgEl.style.background=""),this.avatarTextEl&&(this.avatarTextEl.style.display="none")):(this.avatarImgEl&&(this.avatarImgEl.style.display="none"),this.avatarTextEl&&(this.avatarTextEl.style.display="flex"));}startNowPlayingPoll(){let t=async()=>{let e=await K(this.options.serverUrl);!this.destroyed&&e&&(this.nowPlaying=e,this.refreshLabels());};t(),this.pollTimer=setInterval(t,this.options.nowPlayingPollMs??12e3);}stopNowPlayingPoll(){this.pollTimer!==null&&(clearInterval(this.pollTimer),this.pollTimer=null);}handleSkipClick(){let t=this.engine;if(t){if(this.currentAd){t.canSkipAd()&&t.skipAd();return}t.skip();}}applyAdSkipUi(t){if(!this.skipBtn)return;let{ad:e,canSkip:i,countdownSeconds:n}=t;if(!e.isSkippable){this.skipBtn.disabled=true,this.skipBtn.textContent="",this.skipBtn.replaceChildren(y(E,22));return}if(!i){this.skipBtn.disabled=true,this.skipBtn.replaceChildren(),this.skipBtn.textContent=`${n}s`;return}this.skipBtn.disabled=false,this.skipBtn.textContent="",this.skipBtn.replaceChildren(y(E,22));}restoreTrackSkipButton(){this.skipBtn&&(this.skipBtn.disabled=false,this.skipBtn.textContent="",this.skipBtn.replaceChildren(y(E,22)),this.skipBtn.setAttribute("aria-label","Skip"));}displayLine(){return this.currentAd?{title:this.currentAd.campaignName||"Advertisement",artist:this.currentAd.creativeName}:this.isRadio&&this.nowPlaying?.title?ce(this.nowPlaying.title):this.currentTrack?.title?{title:this.currentTrack.title,artist:this.currentTrack.artist}:{title:"Loading\u2026"}}refreshLabels(){let t=this.displayLine();if(this.titleEl&&(this.titleEl.textContent=t.title),this.artistInlineEl){let e=!!t.artist;this.artistInlineEl.style.display=e?"inline":"none",e&&(this.artistInlineEl.textContent=t.artist);}if(this.artistBlockEl){let e=!!t.artist;this.artistBlockEl.style.display=e?"block":"none",e&&(this.artistBlockEl.textContent=t.artist);}if(this.footerEl)if(this.currentAd)this.footerEl.textContent="Advertisement \xB7 Synxed Player";else {let e=this.isRadio&&(this.nowPlaying?.station??this.currentTrack?.title??"Synxed Radio");this.footerEl.textContent=e&&this.isRadio?`${e} \xB7 Synxed Player`:"Synxed Player";}}updateAvatar(){if(this.refreshAvatarImage(),this.avatarRing){let t=this.avatarRing.firstChild;t&&(t.style.cursor=this.currentAd||this.voiceEnabled?"pointer":"default");}}setPlayingVisual(t){this.avatarRing&&(this.avatarRing.style.animation=t?"synxed-wp-spin 4s linear infinite":""),this.playBtn&&(this.playBtn.replaceChildren(y(t?oe:F,20)),this.playBtn.setAttribute("aria-label",t?"Pause":"Play"));}togglePlay(){this.engine&&(this.isPlaying?this.engine.pause():this.engine.resume());}};
|
|
142
|
+
`,document.head.appendChild(t);}function ce(s){let t=[" \u2014 "," \u2013 "," - "," \u2014"," \u2013"," -"];for(let e of t){let i=s.indexOf(e);if(i>0)return {title:s.slice(0,i).trim(),artist:s.slice(i+e.length).trim()}}return {title:s.trim()}}function pe(s="bottom-center",t=16,e=16){let i={position:"fixed",zIndex:"50"};switch(s){case "top-left":return {...i,top:`${e}px`,left:`${t}px`};case "top-right":return {...i,top:`${e}px`,right:`${t}px`};case "bottom-left":return {...i,bottom:`${e}px`,left:`${t}px`};case "bottom-right":return {...i,bottom:`${e}px`,right:`${t}px`};default:return {...i,bottom:`${e}px`,left:"50%",transform:"translateX(-50%)"}}}function he(s={}){return {accent:s.accent??"#22c55e",accentMuted:s.accentMuted??s.accent??"#22c55e",background:s.background??"#051107",backgroundInner:s.backgroundInner??"#0a1f10",border:s.border??"rgba(34, 197, 94, 0.35)",text:s.text??"#ffffff",textMuted:s.textMuted??"rgba(255,255,255,0.35)",stationText:s.stationText??"rgba(34, 197, 94, 0.85)",liveDot:s.liveDot??"#CCFF00",glow:s.glow??"rgba(34, 197, 94, 0.35)"}}function ue(s,t){s.style.setProperty("--sw-accent",t.accent),s.style.setProperty("--sw-accent-muted",t.accentMuted),s.style.setProperty("--sw-bg",t.background),s.style.setProperty("--sw-bg-inner",t.backgroundInner),s.style.setProperty("--sw-border",t.border),s.style.setProperty("--sw-text",t.text),s.style.setProperty("--sw-text-muted",t.textMuted),s.style.setProperty("--sw-station",t.stationText),s.style.setProperty("--sw-live",t.liveDot),s.style.setProperty("--sw-glow",t.glow);}var z="https://cdn.synxed.com/avater-image/avatar.svg",ke="https://cdn.synxed.com/avater-image/AI%20Star%20UI%20animation.gif",q=class s{constructor(t){this.engine=null;this.pollTimer=null;this.destroyed=false;this.isPlaying=false;this.currentTrack=null;this.nowPlaying=null;this.currentAd=null;this.skipBtn=null;this.avatarImgEl=null;this.avatarTextEl=null;this.avatarRing=null;this.titleEl=null;this.artistInlineEl=null;this.artistBlockEl=null;this.footerEl=null;this.playBtn=null;this.avatarVoiceHolding=false;this.suppressMiniClick=false;this.voiceAvatarPreview=false;this.voiceHoldActivated=false;this.voiceUiDismissed=false;this.voiceUserSpeaking=false;this.voiceHadSpeech=false;this.voiceHoldTimer=null;this.defaultVoiceHoldMs=450;this.options={mode:"wide",attribution:"Synxed",nowPlayingPollMs:12e3,powerByLabel:"Powered by Synxed",enableVoice:true,...t},this.theme=he(this.options.theme),this.ownsRoot=!t.container,this.root=t.container??document.createElement("div"),this.ownsRoot&&document.body.appendChild(this.root),de(),this.mountShell(),this.initEngine(),this.options.source.type==="radio"&&this.startNowPlayingPoll();}static mount(t){return new s(t)}get player(){return this.engine}get element(){return this.root}destroy(){this.destroyed||(this.destroyed=true,this.stopNowPlayingPoll(),this.engine?.destroy(),this.engine=null,this.ownsRoot&&this.root.remove());}get voiceEnabled(){return this.options.enableVoice!==false}get isRadio(){return this.options.source.type==="radio"}get mode(){return this.options.mode??"wide"}mountShell(){let{position:t={},className:e,style:i}=this.options,n=t.placement??"bottom-center",o=t.offsetX??16,r=t.offsetY??(n==="bottom-center"?24:16);this.root.className=e??"",this.root.dataset.synxedWebPlayer=this.mode,ue(this.root,this.theme),Object.assign(this.root.style,pe(n,o,r)),i&&Object.assign(this.root.style,i),this.root.replaceChildren(),this.mode==="mini"?this.buildMini():this.mode==="large"?this.buildLarge():this.buildWide(),this.refreshLabels(),this.setPlayingVisual(this.isPlaying),this.options.draggable&&this.ownsRoot&&this.makeDraggable();}makeDraggable(){let t=false,e=false,i=0,n=0,o=0,r=0,a=u=>{let p=u,g=p.target;if(g.closest("[data-synxed-avatar-ring]")||this.avatarVoiceHolding||this.mode!=="mini"&&g.closest("button, a, input"))return;t=true,e=false;let b=this.root.getBoundingClientRect();o=b.left,r=b.top,this.root.style.bottom="auto",this.root.style.right="auto",this.root.style.transform="none",this.root.style.margin="0",this.root.style.left=`${o}px`,this.root.style.top=`${r}px`,"touches"in p?(i=p.touches[0].clientX,n=p.touches[0].clientY):(i=p.clientX,n=p.clientY),document.addEventListener("mousemove",l,{passive:false}),document.addEventListener("mouseup",c),document.addEventListener("touchmove",l,{passive:false}),document.addEventListener("touchend",c);},l=u=>{if(!t)return;u.preventDefault();let p=u,g,b;"touches"in p?(g=p.touches[0].clientX,b=p.touches[0].clientY):(g=p.clientX,b=p.clientY);let T=g-i,I=b-n;(Math.abs(T)>3||Math.abs(I)>3)&&(e=true),this.root.style.left=`${o+T}px`,this.root.style.top=`${r+I}px`;},c=()=>{t=false,document.removeEventListener("mousemove",l),document.removeEventListener("mouseup",c),document.removeEventListener("touchmove",l),document.removeEventListener("touchend",c),setTimeout(()=>{e=false;},0);};this.root.style.cursor="grab",this.root.addEventListener("mousedown",a),this.root.addEventListener("touchstart",a,{passive:false}),this.root.addEventListener("click",u=>{e&&(u.stopPropagation(),u.preventDefault());},true);}buildAvatar(t,e=false){let i=d("div",{style:{position:"relative",flexShrink:"0"}});this.avatarRing=d("div",{attrs:{"data-synxed-avatar-ring":"true"},style:{width:`${t}px`,height:`${t}px`,borderRadius:"50%",border:"3px solid var(--sw-accent)",padding:"3px",boxShadow:"0 0 24px var(--sw-glow), 0 0 48px rgba(0,0,0,0.25)",background:"var(--sw-bg)",boxSizing:"border-box",userSelect:"none",webkitUserSelect:"none"}}),this.avatarRing.style.setProperty("-webkit-touch-callout","none");let n=d("div",{style:{width:"100%",height:"100%",borderRadius:"50%",background:"var(--sw-bg-inner)",overflow:"hidden",userSelect:"none",webkitUserSelect:"none"}});return n.style.setProperty("-webkit-touch-callout","none"),this.avatarImgEl=d("img",{attrs:{src:z,alt:"Synxed DJ",draggable:"false"},style:{width:"100%",height:"100%",objectFit:"cover",objectPosition:"top",transform:this.mode==="wide"?"scale(1.15)":"scale(1.12)",display:"block",pointerEvents:"none",userSelect:"none",webkitUserSelect:"none"}}),this.avatarImgEl.style.setProperty("-webkit-touch-callout","none"),this.avatarTextEl=d("div",{text:"S",style:{width:"100%",height:"100%",display:"none",alignItems:"center",justifyContent:"center",color:"var(--sw-accent)",fontWeight:"900",fontSize:`${Math.round(t*.28)}px`}}),n.appendChild(this.avatarImgEl),n.appendChild(this.avatarTextEl),n.style.cursor=this.voiceEnabled?"pointer":"default",n.addEventListener("click",o=>{if(this.isVoiceUiOpen()){o.stopPropagation(),this.dismissVoiceUi();return}this.currentAd&&this.engine&&(o.stopPropagation(),this.engine.clickAd());}),n.addEventListener("contextmenu",o=>o.preventDefault()),n.addEventListener("dragstart",o=>o.preventDefault()),n.addEventListener("selectstart",o=>o.preventDefault()),this.voiceEnabled&&(this.avatarRing.style.touchAction="none",this.avatarRing.addEventListener("contextmenu",o=>o.preventDefault()),this.avatarRing.addEventListener("dragstart",o=>o.preventDefault()),this.avatarRing.addEventListener("selectstart",o=>o.preventDefault()),this.avatarRing.setAttribute("aria-label","Hold to speak to DJ")),this.avatarRing.appendChild(n),i.appendChild(this.avatarRing),i.appendChild(d("span",{style:{position:"absolute",...e?{top:"4px",left:"4px"}:{bottom:"6px",left:"6px"},width:e?"10px":"12px",height:e?"10px":"12px",borderRadius:"50%",background:"var(--sw-live)",border:"2px solid var(--sw-bg)",boxShadow:"0 0 8px var(--sw-live)"}})),i}buildMini(){let e=d("div",{attrs:{role:"button",tabindex:"0","aria-label":"Synxed mini player \u2014 tap to play, hold to speak","data-synxed-mini-shell":"true"},style:{position:"relative",padding:"0",cursor:"pointer",background:"transparent"}});e.addEventListener("keydown",i=>{i.key!=="Enter"&&i.key!==" "||(i.preventDefault(),!this.suppressMiniClick&&!this.avatarVoiceHolding&&this.handleMiniActivate());}),e.addEventListener("click",()=>{if(!this.suppressMiniClick){if(this.isVoiceUiOpen()){this.dismissVoiceUi();return}this.avatarVoiceHolding||this.handleMiniActivate();}}),e.appendChild(this.buildAvatar(72)),this.root.appendChild(e);}handleMiniActivate(){if(this.isVoiceUiOpen()){this.dismissVoiceUi();return}this.options.onMiniClick?this.options.onMiniClick():this.togglePlay();}buildWide(){let e="0 8px 40px var(--sw-glow), 0 0 0 1px var(--sw-border)";this.root.style.width="min(calc(100vw - 20px), 560px)";let i=d("div",{style:{position:"relative",display:"flex",alignItems:"center",width:"100%"}}),n=Math.max(90*.42,40);i.appendChild(d("div",{style:{position:"absolute",top:"8px",bottom:"8px",left:`${n}px`,right:"0",background:"var(--sw-bg)",border:"1px solid var(--sw-border)",borderRadius:"28px 20px 20px 28px",boxShadow:e,overflow:"hidden"},children:[d("div",{style:{position:"absolute",inset:"0",background:"linear-gradient(90deg, color-mix(in srgb, var(--sw-accent) 12%, transparent), transparent)",pointerEvents:"none"}})]}));let o=this.buildAvatar(90);Object.assign(o.style,{position:"relative",zIndex:"1",marginLeft:"-2px"}),i.appendChild(o);let r=d("div",{style:{position:"relative",zIndex:"1",flex:"1",minWidth:"0",marginLeft:"14px",padding:"18px 8px"}}),a=d("div",{style:{display:"flex",alignItems:"baseline",gap:"8px",overflow:"hidden"}});this.titleEl=d("h3",{style:{margin:"0",fontSize:"clamp(15px, 2.8vw, 20px)",fontWeight:"900",color:"var(--sw-text)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}),a.appendChild(this.titleEl),this.artistInlineEl=d("span",{style:{fontSize:"clamp(12px, 2.4vw, 15px)",fontWeight:"300",color:"var(--sw-text-muted)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",display:"none"}}),a.appendChild(this.artistInlineEl),r.appendChild(a),this.footerEl=d("p",{style:{margin:"8px 0 0",fontSize:"9px",fontWeight:"700",color:"var(--sw-text-muted)",letterSpacing:"0.18em",textTransform:"uppercase",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}),r.appendChild(this.footerEl),i.appendChild(r);let l=d("div",{style:{position:"relative",zIndex:"1",flexShrink:"0",display:"flex",alignItems:"center",gap:"14px",paddingRight:"16px"}});this.playBtn=this.createPlayButton(52),l.appendChild(this.playBtn),this.isRadio||(this.skipBtn=d("button",{attrs:{type:"button","aria-label":"Skip"},style:{border:"none",background:"transparent",color:"var(--sw-text-muted)",display:"flex",cursor:"pointer",fontSize:"13px",fontWeight:"bold"},onClick:()=>this.handleSkipClick(),children:[y(E,22)]}),l.appendChild(this.skipBtn)),l.appendChild(this.decoLines()),i.appendChild(l),this.root.appendChild(i);}buildLarge(){this.root.style.width="min(calc(100vw - 24px), 380px)";let e=d("div",{style:{borderRadius:"24px",border:"1px solid var(--sw-border)",background:"var(--sw-bg)",boxShadow:"0 8px 40px var(--sw-glow), 0 0 0 1px var(--sw-border)",padding:"16px",display:"flex",flexDirection:"column",gap:"14px",fontFamily:"system-ui, -apple-system, Segoe UI, Roboto, sans-serif"}}),i=d("div",{style:{display:"flex",gap:"12px",alignItems:"center",minWidth:"0"}});i.appendChild(this.buildAvatar(96,true));let n=d("div",{style:{minWidth:"0",flex:"1"}});this.titleEl=d("h3",{style:{margin:"0",fontSize:"18px",fontWeight:"900",color:"var(--sw-text)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}),n.appendChild(this.titleEl),this.artistBlockEl=d("p",{style:{margin:"6px 0 0",fontSize:"13px",fontWeight:"700",color:"var(--sw-accent-muted)",letterSpacing:"0.08em",textTransform:"uppercase",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",display:"none"}}),n.appendChild(this.artistBlockEl),this.footerEl=d("p",{style:{margin:"6px 0 0",fontSize:"10px",fontWeight:"700",color:"var(--sw-station)",letterSpacing:"0.18em",textTransform:"uppercase",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}),n.appendChild(this.footerEl),i.appendChild(n),e.appendChild(i),e.appendChild(this.buildVisualizer()),e.appendChild(d("p",{text:this.options.powerByLabel??"Powered by Synxed",style:{margin:"0",fontSize:"9px",fontWeight:"600",color:"var(--sw-text-muted)",letterSpacing:"0.12em",textTransform:"uppercase",textAlign:"center"}}));let o=d("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",gap:"18px"}});this.isRadio||o.appendChild(d("button",{attrs:{type:"button","aria-label":"Previous"},style:this.roundControlStyle(),onClick:()=>this.engine?.previous(),children:[y(le,22)]})),this.playBtn=this.createPlayButton(56),o.appendChild(this.playBtn),this.isRadio||(this.skipBtn=d("button",{attrs:{type:"button","aria-label":"Skip"},style:{...this.roundControlStyle(),fontSize:"12px",fontWeight:"bold"},onClick:()=>this.handleSkipClick(),children:[y(E,22)]}),o.appendChild(this.skipBtn)),e.appendChild(o),this.root.appendChild(e);}roundControlStyle(){return {width:"46px",height:"46px",borderRadius:"50%",border:"1px solid var(--sw-border)",background:"rgba(255,255,255,0.04)",color:"var(--sw-text)",display:"flex",alignItems:"center",justifyContent:"center",cursor:"pointer"}}createPlayButton(t){return d("button",{attrs:{type:"button","aria-label":"Play"},style:{width:`${t}px`,height:`${t}px`,borderRadius:"50%",border:"none",background:"var(--sw-accent)",color:"#0a0a0a",display:"flex",alignItems:"center",justifyContent:"center",cursor:"pointer",boxShadow:"0 0 18px var(--sw-glow)",flexShrink:"0"},onClick:()=>this.togglePlay(),children:[y(F,t>=56?22:20)]})}buildVisualizer(){let t=d("div",{style:{display:"flex",alignItems:"flex-end",gap:"4px",height:"52px",padding:"8px 4px",borderRadius:"14px",border:"1px solid var(--sw-border)",overflow:"hidden"}});for(let e=0;e<24;e++)t.appendChild(d("span",{style:{flex:"1",minWidth:"3px",height:"100%",borderRadius:"4px",background:"linear-gradient(180deg, var(--sw-accent), transparent)",transformOrigin:"center bottom",animation:`synxed-wp-vbar ${1+e%5*.12}s ease-in-out infinite`,animationDelay:`${e*.04}s`,opacity:"0.85"}}));return t}decoLines(){let t=d("div",{style:{display:"flex",flexDirection:"column",gap:"3px",opacity:"0.22"}});return t.appendChild(d("span",{style:{display:"block",width:"16px",height:"2px",borderRadius:"999px",background:"var(--sw-text)",transform:"translateX(3px)"}})),t.appendChild(d("span",{style:{display:"block",width:"16px",height:"2px",borderRadius:"999px",background:"var(--sw-text)"}})),t}initEngine(){let{apiKey:t,serverUrl:e,source:i}=this.options,n=new L({apiKey:t,serverUrl:e,autoConnect:true,debug:this.options.debug,voice:this.options.voice});this.engine=n;let o=a=>{this.isPlaying=a.status==="playing",a.currentTrack&&(this.currentTrack=a.currentTrack),this.setPlayingVisual(this.isPlaying),this.refreshLabels(),!this.currentAd&&!this.engine?.isAdPlaying&&(this.restoreTrackSkipButton(),this.refreshAvatarImage());};n.on("stateChange",o),n.on("trackChange",a=>{this.currentTrack=a,this.avatarImageBeforeAd=void 0,this.refreshLabels(),!this.currentAd&&!this.engine?.isAdPlaying&&(this.restoreTrackSkipButton(),this.refreshAvatarImage());}),n.on("adStart",a=>{this.avatarImageBeforeAd=this.getContentAvatarUrl(),this.voiceAvatarPreview=false,this.voiceHoldActivated=false,this.currentAd=a,this.refreshLabels(),this.updateAvatar();}),n.on("adSkipUpdate",a=>this.applyAdSkipUi(a)),n.on("adEnd",()=>{this.currentAd=null,this.voiceAvatarPreview=false,this.refreshLabels(),this.updateAvatar(),this.restoreTrackSkipButton();}),n.on("voiceStateChange",a=>this.applyVoiceVisual(a)),n.on("voiceUserSpeakingChange",a=>{this.voiceUserSpeaking=a,a&&(this.voiceHadSpeech=true),this.applyVoiceRing();}),(i.type==="radio"?()=>n.playRadio():()=>n.playPlaylist({playlistCode:i.playlistCode}))().catch(()=>{}),this.voiceEnabled&&this.wireAvatarVoiceHold();}wireAvatarVoiceHold(){if(!this.avatarRing)return;let t=this.avatarRing,e=this.options.voiceHoldMs??this.defaultVoiceHoldMs,i=()=>{this.voiceHoldTimer!==null&&(clearTimeout(this.voiceHoldTimer),this.voiceHoldTimer=null);},n=a=>{if(!(this.currentAd||!this.engine)){if(this.isVoiceUiOpen()){a.preventDefault(),a.stopPropagation(),this.dismissVoiceUi();return}a.preventDefault(),a.stopPropagation(),t.setPointerCapture(a.pointerId),this.avatarVoiceHolding=true,this.voiceHoldActivated=false,i(),this.voiceHoldTimer=setTimeout(()=>{this.voiceHoldTimer=null,!(!this.avatarVoiceHolding||!this.engine)&&(this.voiceHoldActivated=true,this.voiceUiDismissed=false,this.voiceAvatarPreview=true,this.voiceUserSpeaking=false,this.voiceHadSpeech=false,this.applyVoiceRing(),this.refreshAvatarImage(),this.engine.beginVoiceHold({listenerId:this.options.listenerId}).catch(()=>{this.resetVoiceHoldState();}));},e);}},o=a=>{this.currentAd||a.stopPropagation();};t.addEventListener("mousedown",o),t.addEventListener("touchstart",o,{passive:false});let r=()=>{i(),this.avatarVoiceHolding&&(this.avatarVoiceHolding=false,this.voiceHoldActivated&&this.mode==="mini"&&(this.suppressMiniClick=true,setTimeout(()=>{this.suppressMiniClick=false;},320)));};t.addEventListener("pointerdown",n),t.addEventListener("pointerup",r),t.addEventListener("pointerleave",r),t.addEventListener("pointercancel",r);}isVoiceUiOpen(){return !this.voiceEnabled||this.currentAd||this.voiceUiDismissed?false:this.voiceHoldActivated||this.voiceAvatarPreview?true:!!this.engine?.isVoiceUiActive}dismissVoiceUi(){this.engine?.dismissVoiceAndResume(),this.resetVoiceHoldState(),this.voiceUiDismissed=true,this.applyVoiceRing(),this.refreshAvatarImage();}resetVoiceHoldState(){this.voiceHoldTimer!==null&&(clearTimeout(this.voiceHoldTimer),this.voiceHoldTimer=null),this.avatarVoiceHolding=false,this.voiceHoldActivated=false,this.voiceAvatarPreview=false,this.voiceUserSpeaking=false,this.voiceHadSpeech=false;}applyVoiceRing(){if(!this.avatarRing)return;if(this.voiceUiDismissed){this.avatarRing.style.borderColor="",this.avatarRing.style.boxShadow="0 0 24px var(--sw-glow), 0 0 48px rgba(0,0,0,0.25)",this.setPlayingVisual(this.isPlaying);return}let t=this.engine?.voiceState??"idle";if(t==="processing"){this.avatarRing.style.animation="",this.avatarRing.style.borderColor="#ef4444",this.avatarRing.style.boxShadow="0 0 20px rgba(239,68,68,0.5), 0 0 40px rgba(239,68,68,0.2)";return}if(t==="responding"){this.avatarRing.style.animation="",this.avatarRing.style.borderColor="#06b6d4",this.avatarRing.style.boxShadow="0 0 20px rgba(6,182,212,0.5), 0 0 40px rgba(6,182,212,0.2)";return}if(t==="listening"){this.voiceHadSpeech&&!this.voiceUserSpeaking?(this.avatarRing.style.animation="",this.avatarRing.style.borderColor="#ef4444",this.avatarRing.style.boxShadow="0 0 20px rgba(239,68,68,0.5), 0 0 40px rgba(239,68,68,0.2)"):(this.avatarRing.style.animation="",this.avatarRing.style.borderColor="#3b82f6",this.avatarRing.style.boxShadow="0 0 20px rgba(59,130,246,0.55), 0 0 40px rgba(59,130,246,0.25)");return}this.avatarRing.style.borderColor="",this.avatarRing.style.boxShadow="0 0 24px var(--sw-glow), 0 0 48px rgba(0,0,0,0.25)",this.setPlayingVisual(this.isPlaying);}applyVoiceVisual(t){this.avatarRing&&((t==="idle"||t==="ready"||t==="error")&&(this.avatarVoiceHolding||(this.voiceAvatarPreview=false),(t==="ready"||t==="idle")&&(this.voiceUiDismissed=false,this.voiceUserSpeaking=false,this.voiceHadSpeech=false)),t==="listening"&&(this.voiceUiDismissed=false),this.applyVoiceRing(),this.refreshAvatarImage());}isVoiceAvatarActive(){if(!this.voiceEnabled||this.currentAd||this.voiceUiDismissed)return false;if(this.voiceAvatarPreview)return true;let t=this.engine?.voiceState;return t==="listening"||t==="processing"||t==="responding"}getContentAvatarUrl(){return z}getAvatarImageUrl(){return this.currentAd?.companionBannerUrl?this.currentAd.companionBannerUrl:this.isVoiceAvatarActive()?ke:this.avatarImageBeforeAd?this.avatarImageBeforeAd:z}refreshAvatarImage(){let t=this.getAvatarImageUrl(),e=this.isVoiceAvatarActive();t&&this.avatarImgEl?(this.avatarImgEl.getAttribute("src")!==t&&this.avatarImgEl.setAttribute("src",t),this.avatarImgEl.style.display="block",e?(this.avatarImgEl.style.objectFit="cover",this.avatarImgEl.style.objectPosition="center",this.avatarImgEl.style.transform="scale(1)",this.avatarImgEl.style.padding="",this.avatarImgEl.style.background="var(--sw-bg-inner)"):(this.avatarImgEl.style.objectFit="cover",this.avatarImgEl.style.objectPosition="top",this.avatarImgEl.style.transform=this.mode==="wide"?"scale(1.15)":"scale(1.12)",this.avatarImgEl.style.padding="",this.avatarImgEl.style.background=""),this.avatarTextEl&&(this.avatarTextEl.style.display="none")):(this.avatarImgEl&&(this.avatarImgEl.style.display="none"),this.avatarTextEl&&(this.avatarTextEl.style.display="flex"));}startNowPlayingPoll(){let t=async()=>{let e=await K(this.options.serverUrl);!this.destroyed&&e&&(this.nowPlaying=e,this.refreshLabels());};t(),this.pollTimer=setInterval(t,this.options.nowPlayingPollMs??12e3);}stopNowPlayingPoll(){this.pollTimer!==null&&(clearInterval(this.pollTimer),this.pollTimer=null);}handleSkipClick(){let t=this.engine;if(t){if(this.currentAd){t.canSkipAd()&&t.skipAd();return}t.skip();}}applyAdSkipUi(t){if(!this.skipBtn)return;let{ad:e,canSkip:i,countdownSeconds:n}=t;if(!e.isSkippable){this.skipBtn.disabled=true,this.skipBtn.textContent="",this.skipBtn.replaceChildren(y(E,22));return}if(!i){this.skipBtn.disabled=true,this.skipBtn.replaceChildren(),this.skipBtn.textContent=`${n}s`;return}this.skipBtn.disabled=false,this.skipBtn.textContent="",this.skipBtn.replaceChildren(y(E,22));}restoreTrackSkipButton(){this.skipBtn&&(this.skipBtn.disabled=false,this.skipBtn.textContent="",this.skipBtn.replaceChildren(y(E,22)),this.skipBtn.setAttribute("aria-label","Skip"));}displayLine(){return this.currentAd?{title:this.currentAd.campaignName||"Advertisement",artist:this.currentAd.creativeName}:this.isRadio&&this.nowPlaying?.title?ce(this.nowPlaying.title):this.currentTrack?.title?{title:this.currentTrack.title,artist:this.currentTrack.artist}:{title:"Loading\u2026"}}refreshLabels(){let t=this.displayLine();if(this.titleEl&&(this.titleEl.textContent=t.title),this.artistInlineEl){let e=!!t.artist;this.artistInlineEl.style.display=e?"inline":"none",e&&(this.artistInlineEl.textContent=t.artist);}if(this.artistBlockEl){let e=!!t.artist;this.artistBlockEl.style.display=e?"block":"none",e&&(this.artistBlockEl.textContent=t.artist);}if(this.footerEl)if(this.currentAd)this.footerEl.textContent="Advertisement \xB7 Synxed Player";else {let e=this.isRadio&&(this.nowPlaying?.station??this.currentTrack?.title??"Synxed Radio");this.footerEl.textContent=e&&this.isRadio?`${e} \xB7 Synxed Player`:"Synxed Player";}}updateAvatar(){if(this.refreshAvatarImage(),this.avatarRing){let t=this.avatarRing.firstChild;t&&(t.style.cursor=this.currentAd||this.voiceEnabled?"pointer":"default");}}setPlayingVisual(t){this.avatarRing&&(this.avatarRing.style.animation=t?"synxed-wp-spin 4s linear infinite":""),this.playBtn&&(this.playBtn.replaceChildren(y(t?oe:F,20)),this.playBtn.setAttribute("aria-label",t?"Pause":"Play"));}togglePlay(){this.engine&&(this.isPlaying?this.engine.pause():this.engine.resume());}};
|
|
143
143
|
exports.ContentKind=R;exports.ErrorCode=Y;exports.SdkVoiceAction=B;exports.SynxedConnectionError=O;exports.SynxedError=x;exports.SynxedPlaybackError=C;exports.SynxedPlayer=L;exports.SynxedProtocolError=Q;exports.SynxedWebPlayer=q;exports.TransportManager=w;exports.VoiceCaptureManager=A;exports.buildSdkWebSocketUrl=J;exports.fetchRadioNowPlaying=K;//# sourceMappingURL=index.js.map
|
|
144
144
|
//# sourceMappingURL=index.js.map
|