@arraypress/waveform-player 1.11.0 → 1.12.0

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.
@@ -79,6 +79,7 @@
79
79
  setBool("showTime");
80
80
  setBool("showHoverTime");
81
81
  setBool("showBPM", "showBpm");
82
+ setNum("bpm");
82
83
  setBool("singlePlay");
83
84
  setBool("playOnSeek");
84
85
  if (element.dataset.title) options.title = element.dataset.title;
@@ -709,6 +710,9 @@
709
710
  showTime: true,
710
711
  showHoverTime: false,
711
712
  showBPM: false,
713
+ // Known BPM to display in the badge (with showBPM). Wins over auto-detection
714
+ // — set it when peaks are pre-generated so the tempo still shows. null = auto.
715
+ bpm: null,
712
716
  singlePlay: true,
713
717
  playOnSeek: true,
714
718
  enableMediaSession: true,
@@ -993,6 +997,7 @@
993
997
  this.speedBtn = this.container.querySelector(".speed-btn");
994
998
  this.speedMenu = this.container.querySelector(".speed-menu");
995
999
  this.resizeCanvas();
1000
+ this.updateBPMDisplay();
996
1001
  }
997
1002
  /**
998
1003
  * Create audio element
@@ -1798,8 +1803,9 @@
1798
1803
  * @private
1799
1804
  */
1800
1805
  updateBPMDisplay() {
1801
- if (this.bpmEl && this.bpmValueEl && this.detectedBPM) {
1802
- this.bpmValueEl.textContent = Math.round(this.detectedBPM);
1806
+ const bpm = this.options.bpm || this.detectedBPM;
1807
+ if (this.bpmEl && this.bpmValueEl && bpm) {
1808
+ this.bpmValueEl.textContent = Math.round(bpm);
1803
1809
  this.bpmEl.style.display = "inline-flex";
1804
1810
  }
1805
1811
  }
@@ -1,4 +1,4 @@
1
- (()=>{function A(t){return String(t??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function _(t){if(typeof t!="string"||t==="")return!1;try{let e=new URL(t,"http://localhost/");return e.protocol==="http:"||e.protocol==="https:"}catch{return!1}}function w(t,e=0,i=1){return Math.max(e,Math.min(t,i))}function it(t){return t===void 0?void 0:t==="true"}function z(t){if(typeof t=="string"&&t.trim().startsWith("["))try{return JSON.parse(t)}catch{}return t}function L(t){let e={},i=(r,n=r)=>{let a=it(t.dataset[n]);a!==void 0&&(e[r]=a)},s=(r,n=r,a=!1)=>{let d=t.dataset[n];d&&(e[r]=a?parseFloat(d):parseInt(d,10))},o=(r,n=r)=>{let a=t.dataset[n];if(a)try{e[r]=JSON.parse(a)}catch(d){console.warn(`[WaveformPlayer] Invalid ${n} JSON:`,d)}};return t.dataset.src&&(e.url=t.dataset.src),t.dataset.url&&(e.url=t.dataset.url),s("height"),s("samples"),t.dataset.preload&&(e.preload=t.dataset.preload),t.dataset.audioMode&&(e.audioMode=t.dataset.audioMode),t.dataset.style&&(e.waveformStyle=t.dataset.style),t.dataset.waveformStyle&&(e.waveformStyle=t.dataset.waveformStyle),s("barWidth"),s("barSpacing"),s("barRadius"),t.dataset.buttonAlign&&(e.buttonAlign=t.dataset.buttonAlign),t.dataset.layout&&(e.layout=t.dataset.layout),t.dataset.buttonStyle&&(e.buttonStyle=t.dataset.buttonStyle),t.dataset.colorPreset&&(e.colorPreset=t.dataset.colorPreset),t.dataset.waveformColor&&(e.waveformColor=z(t.dataset.waveformColor)),t.dataset.progressColor&&(e.progressColor=z(t.dataset.progressColor)),t.dataset.buttonColor&&(e.buttonColor=t.dataset.buttonColor),t.dataset.buttonHoverColor&&(e.buttonHoverColor=t.dataset.buttonHoverColor),t.dataset.textColor&&(e.textColor=t.dataset.textColor),t.dataset.textSecondaryColor&&(e.textSecondaryColor=t.dataset.textSecondaryColor),t.dataset.backgroundColor&&(e.backgroundColor=t.dataset.backgroundColor),t.dataset.borderColor&&(e.borderColor=t.dataset.borderColor),t.dataset.color&&(e.waveformColor=t.dataset.color),t.dataset.theme&&(e.colorPreset=t.dataset.theme),i("autoplay"),i("showControls"),i("showInfo"),i("showTime"),i("showHoverTime"),i("showBPM","showBpm"),i("singlePlay"),i("playOnSeek"),t.dataset.title&&(e.title=t.dataset.title),t.dataset.subtitle&&(e.subtitle=t.dataset.subtitle),t.dataset.album&&(e.album=t.dataset.album),t.dataset.artwork&&(e.artwork=t.dataset.artwork),t.dataset.waveform&&(e.waveform=t.dataset.waveform),o("markers"),s("playbackRate","playbackRate",!0),i("showPlaybackSpeed"),o("playbackRates"),i("enableMediaSession"),i("showMarkers"),i("accessibleSeek"),t.dataset.seekLabel&&(e.seekLabel=t.dataset.seekLabel),t.dataset.errorText&&(e.errorText=t.dataset.errorText),t.dataset.playIcon&&(e.playIcon=t.dataset.playIcon),t.dataset.pauseIcon&&(e.pauseIcon=t.dataset.pauseIcon),e}function S(t){if(!t||isNaN(t)||t<0)return"0:00";let e=Math.floor(t/3600),i=Math.floor(t%3600/60),s=Math.floor(t%60);return e>0?`${e}:${i.toString().padStart(2,"0")}:${s.toString().padStart(2,"0")}`:`${i}:${s.toString().padStart(2,"0")}`}var st=0;function O(t){let e=t||"audio",i=5381;for(let s=0;s<e.length;s++)i=(i<<5)+i+e.charCodeAt(s)|0;return`wp_${(i>>>0).toString(36)}_${(st++).toString(36)}`}function x(t){if(!t)return"Audio";let e=t.split("/");return e[e.length-1].split(".")[0].replace(/[-_]/g," ").replace(/\b\w/g,o=>o.toUpperCase())}function q(t){let e=typeof t=="string"?t.match(/\d+/g):null;if(!e||e.length<3)return null;let[i,s,o]=e.map(Number);return(i*299+s*587+o*114)/1e3}function D(...t){let e={};for(let i of t)for(let s in i)i[s]!==null&&i[s]!==void 0&&(e[s]=i[s]);return e}function F(t,e){let i;return function(...o){let r=()=>{clearTimeout(i),t(...o)};clearTimeout(i),i=setTimeout(r,e)}}function T(t,e){if(t.length===e)return t;if(t.length===0||e===0)return[];let i=[];if(e>t.length){let s=(t.length-1)/(e-1);for(let o=0;o<e;o++){let r=o*s,n=Math.floor(r),a=Math.ceil(r),d=r-n;if(a>=t.length)i.push(t[t.length-1]);else if(n===a)i.push(t[n]);else{let l=t[n]*(1-d)+t[a]*d;i.push(l)}}}else{let s=t.length/e;for(let o=0;o<e;o++){let r=Math.floor(o*s),n=Math.floor((o+1)*s),a=0,d=0;for(let l=r;l<=n&&l<t.length;l++)t[l]>a&&(a=t[l]),d++;if(d===0){let l=Math.min(Math.round(o*s),t.length-1);a=t[l]}i.push(a)}}return i}function P(t,e,i){if(!Array.isArray(e))return e;if(e.length===1)return e[0];let s=t.createLinearGradient(0,0,0,i);return e.forEach((o,r)=>s.addColorStop(r/(e.length-1),o)),s}function E(t,e,i,s,o,r){if((Array.isArray(r)?r.some(a=>a>0):r>0)&&typeof t.roundRect=="function"){let a=Math.min(s/2,Math.abs(o)/2),d=l=>w(l,0,a);t.beginPath(),t.roundRect(e,i,s,o,Array.isArray(r)?r.map(d):d(r)),t.fill()}else t.fillRect(e,i,s,o)}function j(t,e){return(t.barRadius||0)*e}function ot(t,e){let i=j(t,e);return[i,i,0,0]}function U(t,e,i,s,o){let r=o/2;t.beginPath(),t.moveTo(e,s-r),t.lineTo(i-r,s-r),t.arc(i-r,s,r,-Math.PI/2,Math.PI/2),t.lineTo(e,s+r),t.arc(e,s,r,Math.PI/2,-Math.PI/2),t.closePath()}function R(t,e,i,s,o){let r=window.devicePixelRatio||1,n=o.barWidth*r,a=o.barSpacing*r,d=Math.floor(e.width/(n+a)),l=T(i,d),h=e.height,c=s*e.width,g=ot(o,r),b=P(t,o.color,h),p=P(t,o.progressColor,h);t.clearRect(0,0,e.width,e.height),t.fillStyle=b;for(let m=0;m<l.length;m++){let u=m*(n+a);if(u+n>e.width)break;let y=l[m]*h*.9,f=h-y;E(t,u,f,n,y,g)}t.save(),t.beginPath(),t.rect(0,0,c,h),t.clip(),t.fillStyle=p;for(let m=0;m<l.length;m++){let u=m*(n+a);if(u>c)break;let y=l[m]*h*.9,f=h-y;E(t,u,f,n,y,g)}t.restore()}function rt(t,e,i,s,o){let r=window.devicePixelRatio||1,n=o.barWidth*r,a=o.barSpacing*r,d=Math.floor(e.width/(n+a)),l=T(i,d),h=e.height,c=h/2,g=s*e.width,b=j(o,r),p=[b,b,0,0],m=[0,0,b,b],u=P(t,o.color,h),y=P(t,o.progressColor,h);t.clearRect(0,0,e.width,e.height),t.fillStyle=u;for(let f=0;f<l.length;f++){let v=f*(n+a);if(v+n>e.width)break;let k=l[f]*h*.45;E(t,v,c-k,n,k,p),E(t,v,c,n,k,m)}t.save(),t.beginPath(),t.rect(0,0,g,h),t.clip(),t.fillStyle=y;for(let f=0;f<l.length;f++){let v=f*(n+a);if(v>g)break;let k=l[f]*h*.45;E(t,v,c-k,n,k,p),E(t,v,c,n,k,m)}t.restore()}function at(t,e,i,s,o){let r=e.width,n=e.height,a=n/2,d=n*.35;t.clearRect(0,0,r,n);let l=(h,c,g=1,b=!1)=>{b&&(t.shadowBlur=12,t.shadowColor=h),t.strokeStyle=h,t.lineWidth=c,t.lineCap="round",t.lineJoin="round",t.beginPath(),t.moveTo(0,a);let p=[],m=Math.floor(i.length*g);for(let u=0;u<m;u++){let y=u/(i.length-1)*r,f=i[u],v=Math.sin(u*.1)*f,k=a+v*d;p.push({x:y,y:k})}for(let u=0;u<p.length-1;u++){let y=p[u].x+(p[u+1].x-p[u].x)*.5,f=p[u].y,v=p[u+1].x-(p[u+1].x-p[u].x)*.5,k=p[u+1].y;t.bezierCurveTo(y,f,v,k,p[u+1].x,p[u+1].y)}t.stroke(),b&&(t.shadowBlur=0)};t.strokeStyle="rgba(255, 255, 255, 0.03)",t.lineWidth=.5,t.beginPath(),t.moveTo(0,a),t.lineTo(r,a),t.stroke();for(let h=0;h<=10;h++){let c=r/10*h;t.beginPath(),t.moveTo(c,0),t.lineTo(c,n),t.stroke()}l(o.color,2,1,!1),s>0&&l(o.progressColor,3,s,!0)}function N(t,e,i,s,o){let r=window.devicePixelRatio||1,n=(o.barWidth||3)*r,a=(o.barSpacing||1)*r,d=Math.floor(e.width/(n+a)),l=T(i,d),h=e.height,c=4*r,g=2*r,b=s*e.width,p=h/2,m=P(t,o.color,h),u=P(t,o.progressColor,h);t.clearRect(0,0,e.width,e.height);for(let y=0;y<l.length;y++){let f=y*(n+a);if(f+n>e.width)break;let v=l[y]*h*.9,k=Math.floor(v/(c+g));t.fillStyle=f<b?u:m;for(let M=0;M<k;M++){let H=M*(c+g);t.fillRect(f,p-H-c,n,c),M>0&&t.fillRect(f,p+H,n,c)}}}function V(t,e,i,s,o){let r=window.devicePixelRatio||1,n=(o.barWidth||2)*r,a=(o.barSpacing||3)*r,d=Math.floor(e.width/(n+a)),l=T(i,d),h=e.height,c=Math.max(1.5*r,n/2),g=s*e.width,b=h/2,p=P(t,o.color,h),m=P(t,o.progressColor,h);t.clearRect(0,0,e.width,e.height);for(let u=0;u<l.length;u++){let y=u*(n+a)+n/2;if(y>e.width)break;let f=l[u]*h*.9;t.fillStyle=y<g?m:p,t.beginPath(),t.arc(y,b-f/2,c,0,Math.PI*2),t.fill(),t.beginPath(),t.arc(y,b+f/2,c,0,Math.PI*2),t.fill()}}function nt(t,e,i,s,o){let r=e.width,n=e.height,a=n/2,d=4,l=d/2;if(t.clearRect(0,0,r,n),t.fillStyle=o.color||"rgba(255, 255, 255, 0.2)",U(t,l,r,a,d),t.fill(),s>0){let h=Math.max(l*2,s*r);t.shadowBlur=8,t.shadowColor=o.progressColor,t.fillStyle=o.progressColor||"rgba(255, 255, 255, 0.9)",U(t,l,h,a,d),t.fill(),t.shadowBlur=0;let c=8,g=h;t.shadowBlur=4,t.shadowColor="rgba(0, 0, 0, 0.3)",t.shadowOffsetY=2,t.fillStyle="#ffffff",t.beginPath(),t.arc(g,a,c,0,Math.PI*2),t.fill(),t.shadowBlur=0,t.shadowOffsetY=0,t.fillStyle=o.progressColor||"rgba(255, 255, 255, 0.9)",t.beginPath(),t.arc(g,a,c*.4,0,Math.PI*2),t.fill()}}var lt={bars:R,bar:R,mirror:rt,line:at,blocks:N,block:N,dots:V,dot:V,seekbar:nt};function J(t,e,i,s,o){(lt[o.waveformStyle]||R)(t,e,i,s,o)}function Y(t){try{let e=t.getChannelData(0),i=t.sampleRate,s=ht(e,i);if(s.length<2)return 120;let o=[];for(let d=1;d<s.length;d++)o.push((s[d]-s[d-1])/i);let r={};o.forEach(d=>{let l=60/d,h=Math.round(l/3)*3;h>60&&h<200&&(r[h]=(r[h]||0)+1)});let n=0,a=120;for(let[d,l]of Object.entries(r))l>n&&(n=l,a=parseInt(d));return a<70&&r[a*2]?a*=2:a>160&&r[Math.round(a/2)]&&(a=Math.round(a/2)),a-1}catch(e){return console.warn("[WaveformPlayer] BPM detection failed:",e),null}}function ht(t,e){let o=[],r=0;for(let n=0;n<t.length-2048;n+=1024){let a=0;for(let h=n;h<n+2048;h++)a+=t[h]*t[h];a=a/2048;let d=a-r,l=r*1.8+.01;if(d>l&&a>.01){let h=o[o.length-1]||0,c=e*.15;n-h>c&&o.push(n)}r=a*.8+r*.2}return o}function dt(t,e=200){let i=t.length/e,s=~~(i/10)||1,o=t.numberOfChannels,r=[];for(let a=0;a<o;a++){let d=t.getChannelData(a);for(let l=0;l<e;l++){let h=~~(l*i),c=~~(h+i),g=0,b=0;for(let m=h;m<c;m+=s){let u=d[m];u>b&&(b=u),u<g&&(g=u)}let p=Math.max(Math.abs(b),Math.abs(g));(a===0||p>r[l])&&(r[l]=p)}}let n=Math.max(...r);return n>0?r.map(a=>a/n):r}async function B(t,e=200,i=!1){let s;try{let o=window.AudioContext||window.webkitAudioContext;s=new o;let n=await(await fetch(t)).arrayBuffer(),a=await s.decodeAudioData(n),d=dt(a,e);d=ut(d);let l=null;return i&&(l=Y(a)),{peaks:d,bpm:l}}finally{s&&s.close()}}function G(t=200){let e=[];for(let i=0;i<t;i++){let s=Math.random()*.5+.3,o=Math.sin(i/t*Math.PI*4)*.2;e.push(w(s+o,.1,1))}return e}function ut(t,e=.95){let i=Math.max(...t);if(i===0||i>e)return t;let s=e/i;return t.map(o=>o*s)}function K(t){let e=document.documentElement,i=document.body;return e.classList.contains(t)||e.classList.contains(`${t}-mode`)||e.classList.contains(`theme-${t}`)||e.getAttribute("data-theme")===t||e.getAttribute("data-color-scheme")===t||i.classList.contains(t)||i.classList.contains(`${t}-mode`)||i.getAttribute("data-theme")===t}function ct(){if(K("dark"))return"dark";if(K("light"))return"light";try{let t=getComputedStyle(document.body).backgroundColor,e=q(t);if(e!==null){if(e>128)return"light";if(e<128)return"dark"}}catch{}if(window.matchMedia){if(window.matchMedia("(prefers-color-scheme: dark)").matches)return"dark";if(window.matchMedia("(prefers-color-scheme: light)").matches)return"light"}return"dark"}var W={dark:{waveformColor:"rgba(255, 255, 255, 0.3)",progressColor:"rgba(255, 255, 255, 0.9)",buttonColor:"rgba(255, 255, 255, 0.9)",buttonHoverColor:"rgba(255, 255, 255, 1)",textColor:"#ffffff",textSecondaryColor:"rgba(255, 255, 255, 0.6)",backgroundColor:"rgba(255, 255, 255, 0.03)",borderColor:"rgba(255, 255, 255, 0.1)"},light:{waveformColor:"rgba(0, 0, 0, 0.2)",progressColor:"rgba(0, 0, 0, 0.8)",buttonColor:"rgba(0, 0, 0, 0.8)",buttonHoverColor:"rgba(0, 0, 0, 0.9)",textColor:"#333333",textSecondaryColor:"rgba(0, 0, 0, 0.6)",backgroundColor:"rgba(0, 0, 0, 0.02)",borderColor:"rgba(0, 0, 0, 0.1)"}};function Q(t){if(t&&W[t])return W[t];let e=ct();return W[e]}var Z={url:"",height:64,samples:256,preload:"metadata",audioMode:"self",playbackRate:1,showPlaybackSpeed:!1,playbackRates:[.5,.75,1,1.25,1.5,1.75,2],buttonAlign:"auto",layout:"default",buttonStyle:"circle",waveformStyle:"mirror",barWidth:2,barSpacing:0,barRadius:1,colorPreset:null,waveformColor:null,progressColor:null,buttonColor:null,buttonHoverColor:null,textColor:null,textSecondaryColor:null,backgroundColor:null,borderColor:null,autoplay:!1,showControls:!0,showInfo:!0,showTime:!0,showHoverTime:!1,showBPM:!1,singlePlay:!0,playOnSeek:!0,enableMediaSession:!0,markers:[],showMarkers:!0,accessibleSeek:!0,seekLabel:null,title:null,subtitle:null,artwork:null,album:"",errorText:"Unable to load audio",playIcon:'<svg viewBox="0 0 24 24" width="16" height="16"><path d="M8 5v14l11-7z"/></svg>',pauseIcon:'<svg viewBox="0 0 24 24" width="16" height="16"><path d="M6 4h4v16H6zM14 4h4v16h-4z"/></svg>',onLoad:null,onPlay:null,onPause:null,onEnd:null,onError:null,onTimeUpdate:null},X={bars:{barWidth:3,barSpacing:1},mirror:{barWidth:2,barSpacing:2},line:{barWidth:2,barSpacing:0},blocks:{barWidth:4,barSpacing:2},dots:{barWidth:3,barSpacing:3},seekbar:{barWidth:1,barSpacing:0}};var tt=5,et=10,C=class t{static instances=new Map;static currentlyPlaying=null;constructor(e,i={}){if(this.container=typeof e=="string"?document.querySelector(e):e,!this.container)throw new Error("[WaveformPlayer] Container element not found");let s=L(this.container),o={...i};o.style&&!o.waveformStyle&&(o.waveformStyle=o.style),o.src&&!o.url&&(o.url=o.src),this.options=D(Z,s,o);let r=Q(this.options.colorPreset);for(let[a,d]of Object.entries(r))(this.options[a]===null||this.options[a]===void 0)&&(this.options[a]=d);let n=X[this.options.waveformStyle];n&&(s.barWidth===void 0&&i.barWidth===void 0&&(this.options.barWidth=n.barWidth),s.barSpacing===void 0&&i.barSpacing===void 0&&(this.options.barSpacing=n.barSpacing)),this.audio=null,this.canvas=null,this.ctx=null,this.waveformData=[],this.progress=0,this.isPlaying=!1,this.isLoading=!1,this.hasError=!1,this.updateTimer=null,this.resizeObserver=null,this._ac=new AbortController,this.id=this.container.id||O(this.options.url),t.instances.set(this.id,this),this.init(),setTimeout(()=>{this._emit("waveformplayer:ready",{player:this,url:this.options.url})},100)}_emit(e,i,s=!1){let o=new CustomEvent(e,{bubbles:!0,cancelable:s,detail:i});return this.container.dispatchEvent(o),o}_requestSeek(e){this._emit("waveformplayer:request-seek",{...this._buildTrackDetail(),percent:e},!0).defaultPrevented||(this.progress=e,this.drawWaveform?.())}init(){this.createDOM(),this.createAudio(),this.initPlaybackSpeed(),this.initKeyboardControls(),this.initSeekControl(),this.bindEvents(),this.setupResizeObserver(),requestAnimationFrame(()=>{this.resizeCanvas(),this.options.url&&this.load(this.options.url).then(()=>{this.options.autoplay&&this.play()?.catch(()=>{})}).catch(e=>{console.error("[WaveformPlayer] Failed to load audio:",e)})})}createDOM(){this.container.innerHTML="",this.container.className="waveform-player";let e=this.options.buttonAlign;e==="auto"&&(this.options.waveformStyle==="bars"?e="bottom":e="center"),this.options.layout==="preview"&&this.container.classList.add("waveform-layout-preview");let s=this.options.showControls?`
1
+ (()=>{function A(e){return String(e??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function _(e){if(typeof e!="string"||e==="")return!1;try{let t=new URL(e,"http://localhost/");return t.protocol==="http:"||t.protocol==="https:"}catch{return!1}}function w(e,t=0,i=1){return Math.max(t,Math.min(e,i))}function it(e){return e===void 0?void 0:e==="true"}function z(e){if(typeof e=="string"&&e.trim().startsWith("["))try{return JSON.parse(e)}catch{}return e}function L(e){let t={},i=(r,n=r)=>{let a=it(e.dataset[n]);a!==void 0&&(t[r]=a)},s=(r,n=r,a=!1)=>{let d=e.dataset[n];d&&(t[r]=a?parseFloat(d):parseInt(d,10))},o=(r,n=r)=>{let a=e.dataset[n];if(a)try{t[r]=JSON.parse(a)}catch(d){console.warn(`[WaveformPlayer] Invalid ${n} JSON:`,d)}};return e.dataset.src&&(t.url=e.dataset.src),e.dataset.url&&(t.url=e.dataset.url),s("height"),s("samples"),e.dataset.preload&&(t.preload=e.dataset.preload),e.dataset.audioMode&&(t.audioMode=e.dataset.audioMode),e.dataset.style&&(t.waveformStyle=e.dataset.style),e.dataset.waveformStyle&&(t.waveformStyle=e.dataset.waveformStyle),s("barWidth"),s("barSpacing"),s("barRadius"),e.dataset.buttonAlign&&(t.buttonAlign=e.dataset.buttonAlign),e.dataset.layout&&(t.layout=e.dataset.layout),e.dataset.buttonStyle&&(t.buttonStyle=e.dataset.buttonStyle),e.dataset.colorPreset&&(t.colorPreset=e.dataset.colorPreset),e.dataset.waveformColor&&(t.waveformColor=z(e.dataset.waveformColor)),e.dataset.progressColor&&(t.progressColor=z(e.dataset.progressColor)),e.dataset.buttonColor&&(t.buttonColor=e.dataset.buttonColor),e.dataset.buttonHoverColor&&(t.buttonHoverColor=e.dataset.buttonHoverColor),e.dataset.textColor&&(t.textColor=e.dataset.textColor),e.dataset.textSecondaryColor&&(t.textSecondaryColor=e.dataset.textSecondaryColor),e.dataset.backgroundColor&&(t.backgroundColor=e.dataset.backgroundColor),e.dataset.borderColor&&(t.borderColor=e.dataset.borderColor),e.dataset.color&&(t.waveformColor=e.dataset.color),e.dataset.theme&&(t.colorPreset=e.dataset.theme),i("autoplay"),i("showControls"),i("showInfo"),i("showTime"),i("showHoverTime"),i("showBPM","showBpm"),s("bpm"),i("singlePlay"),i("playOnSeek"),e.dataset.title&&(t.title=e.dataset.title),e.dataset.subtitle&&(t.subtitle=e.dataset.subtitle),e.dataset.album&&(t.album=e.dataset.album),e.dataset.artwork&&(t.artwork=e.dataset.artwork),e.dataset.waveform&&(t.waveform=e.dataset.waveform),o("markers"),s("playbackRate","playbackRate",!0),i("showPlaybackSpeed"),o("playbackRates"),i("enableMediaSession"),i("showMarkers"),i("accessibleSeek"),e.dataset.seekLabel&&(t.seekLabel=e.dataset.seekLabel),e.dataset.errorText&&(t.errorText=e.dataset.errorText),e.dataset.playIcon&&(t.playIcon=e.dataset.playIcon),e.dataset.pauseIcon&&(t.pauseIcon=e.dataset.pauseIcon),t}function S(e){if(!e||isNaN(e)||e<0)return"0:00";let t=Math.floor(e/3600),i=Math.floor(e%3600/60),s=Math.floor(e%60);return t>0?`${t}:${i.toString().padStart(2,"0")}:${s.toString().padStart(2,"0")}`:`${i}:${s.toString().padStart(2,"0")}`}var st=0;function O(e){let t=e||"audio",i=5381;for(let s=0;s<t.length;s++)i=(i<<5)+i+t.charCodeAt(s)|0;return`wp_${(i>>>0).toString(36)}_${(st++).toString(36)}`}function x(e){if(!e)return"Audio";let t=e.split("/");return t[t.length-1].split(".")[0].replace(/[-_]/g," ").replace(/\b\w/g,o=>o.toUpperCase())}function q(e){let t=typeof e=="string"?e.match(/\d+/g):null;if(!t||t.length<3)return null;let[i,s,o]=t.map(Number);return(i*299+s*587+o*114)/1e3}function D(...e){let t={};for(let i of e)for(let s in i)i[s]!==null&&i[s]!==void 0&&(t[s]=i[s]);return t}function F(e,t){let i;return function(...o){let r=()=>{clearTimeout(i),e(...o)};clearTimeout(i),i=setTimeout(r,t)}}function T(e,t){if(e.length===t)return e;if(e.length===0||t===0)return[];let i=[];if(t>e.length){let s=(e.length-1)/(t-1);for(let o=0;o<t;o++){let r=o*s,n=Math.floor(r),a=Math.ceil(r),d=r-n;if(a>=e.length)i.push(e[e.length-1]);else if(n===a)i.push(e[n]);else{let l=e[n]*(1-d)+e[a]*d;i.push(l)}}}else{let s=e.length/t;for(let o=0;o<t;o++){let r=Math.floor(o*s),n=Math.floor((o+1)*s),a=0,d=0;for(let l=r;l<=n&&l<e.length;l++)e[l]>a&&(a=e[l]),d++;if(d===0){let l=Math.min(Math.round(o*s),e.length-1);a=e[l]}i.push(a)}}return i}function P(e,t,i){if(!Array.isArray(t))return t;if(t.length===1)return t[0];let s=e.createLinearGradient(0,0,0,i);return t.forEach((o,r)=>s.addColorStop(r/(t.length-1),o)),s}function E(e,t,i,s,o,r){if((Array.isArray(r)?r.some(a=>a>0):r>0)&&typeof e.roundRect=="function"){let a=Math.min(s/2,Math.abs(o)/2),d=l=>w(l,0,a);e.beginPath(),e.roundRect(t,i,s,o,Array.isArray(r)?r.map(d):d(r)),e.fill()}else e.fillRect(t,i,s,o)}function j(e,t){return(e.barRadius||0)*t}function ot(e,t){let i=j(e,t);return[i,i,0,0]}function U(e,t,i,s,o){let r=o/2;e.beginPath(),e.moveTo(t,s-r),e.lineTo(i-r,s-r),e.arc(i-r,s,r,-Math.PI/2,Math.PI/2),e.lineTo(t,s+r),e.arc(t,s,r,Math.PI/2,-Math.PI/2),e.closePath()}function R(e,t,i,s,o){let r=window.devicePixelRatio||1,n=o.barWidth*r,a=o.barSpacing*r,d=Math.floor(t.width/(n+a)),l=T(i,d),h=t.height,c=s*t.width,b=ot(o,r),g=P(e,o.color,h),p=P(e,o.progressColor,h);e.clearRect(0,0,t.width,t.height),e.fillStyle=g;for(let m=0;m<l.length;m++){let u=m*(n+a);if(u+n>t.width)break;let y=l[m]*h*.9,f=h-y;E(e,u,f,n,y,b)}e.save(),e.beginPath(),e.rect(0,0,c,h),e.clip(),e.fillStyle=p;for(let m=0;m<l.length;m++){let u=m*(n+a);if(u>c)break;let y=l[m]*h*.9,f=h-y;E(e,u,f,n,y,b)}e.restore()}function rt(e,t,i,s,o){let r=window.devicePixelRatio||1,n=o.barWidth*r,a=o.barSpacing*r,d=Math.floor(t.width/(n+a)),l=T(i,d),h=t.height,c=h/2,b=s*t.width,g=j(o,r),p=[g,g,0,0],m=[0,0,g,g],u=P(e,o.color,h),y=P(e,o.progressColor,h);e.clearRect(0,0,t.width,t.height),e.fillStyle=u;for(let f=0;f<l.length;f++){let v=f*(n+a);if(v+n>t.width)break;let k=l[f]*h*.45;E(e,v,c-k,n,k,p),E(e,v,c,n,k,m)}e.save(),e.beginPath(),e.rect(0,0,b,h),e.clip(),e.fillStyle=y;for(let f=0;f<l.length;f++){let v=f*(n+a);if(v>b)break;let k=l[f]*h*.45;E(e,v,c-k,n,k,p),E(e,v,c,n,k,m)}e.restore()}function at(e,t,i,s,o){let r=t.width,n=t.height,a=n/2,d=n*.35;e.clearRect(0,0,r,n);let l=(h,c,b=1,g=!1)=>{g&&(e.shadowBlur=12,e.shadowColor=h),e.strokeStyle=h,e.lineWidth=c,e.lineCap="round",e.lineJoin="round",e.beginPath(),e.moveTo(0,a);let p=[],m=Math.floor(i.length*b);for(let u=0;u<m;u++){let y=u/(i.length-1)*r,f=i[u],v=Math.sin(u*.1)*f,k=a+v*d;p.push({x:y,y:k})}for(let u=0;u<p.length-1;u++){let y=p[u].x+(p[u+1].x-p[u].x)*.5,f=p[u].y,v=p[u+1].x-(p[u+1].x-p[u].x)*.5,k=p[u+1].y;e.bezierCurveTo(y,f,v,k,p[u+1].x,p[u+1].y)}e.stroke(),g&&(e.shadowBlur=0)};e.strokeStyle="rgba(255, 255, 255, 0.03)",e.lineWidth=.5,e.beginPath(),e.moveTo(0,a),e.lineTo(r,a),e.stroke();for(let h=0;h<=10;h++){let c=r/10*h;e.beginPath(),e.moveTo(c,0),e.lineTo(c,n),e.stroke()}l(o.color,2,1,!1),s>0&&l(o.progressColor,3,s,!0)}function N(e,t,i,s,o){let r=window.devicePixelRatio||1,n=(o.barWidth||3)*r,a=(o.barSpacing||1)*r,d=Math.floor(t.width/(n+a)),l=T(i,d),h=t.height,c=4*r,b=2*r,g=s*t.width,p=h/2,m=P(e,o.color,h),u=P(e,o.progressColor,h);e.clearRect(0,0,t.width,t.height);for(let y=0;y<l.length;y++){let f=y*(n+a);if(f+n>t.width)break;let v=l[y]*h*.9,k=Math.floor(v/(c+b));e.fillStyle=f<g?u:m;for(let M=0;M<k;M++){let H=M*(c+b);e.fillRect(f,p-H-c,n,c),M>0&&e.fillRect(f,p+H,n,c)}}}function V(e,t,i,s,o){let r=window.devicePixelRatio||1,n=(o.barWidth||2)*r,a=(o.barSpacing||3)*r,d=Math.floor(t.width/(n+a)),l=T(i,d),h=t.height,c=Math.max(1.5*r,n/2),b=s*t.width,g=h/2,p=P(e,o.color,h),m=P(e,o.progressColor,h);e.clearRect(0,0,t.width,t.height);for(let u=0;u<l.length;u++){let y=u*(n+a)+n/2;if(y>t.width)break;let f=l[u]*h*.9;e.fillStyle=y<b?m:p,e.beginPath(),e.arc(y,g-f/2,c,0,Math.PI*2),e.fill(),e.beginPath(),e.arc(y,g+f/2,c,0,Math.PI*2),e.fill()}}function nt(e,t,i,s,o){let r=t.width,n=t.height,a=n/2,d=4,l=d/2;if(e.clearRect(0,0,r,n),e.fillStyle=o.color||"rgba(255, 255, 255, 0.2)",U(e,l,r,a,d),e.fill(),s>0){let h=Math.max(l*2,s*r);e.shadowBlur=8,e.shadowColor=o.progressColor,e.fillStyle=o.progressColor||"rgba(255, 255, 255, 0.9)",U(e,l,h,a,d),e.fill(),e.shadowBlur=0;let c=8,b=h;e.shadowBlur=4,e.shadowColor="rgba(0, 0, 0, 0.3)",e.shadowOffsetY=2,e.fillStyle="#ffffff",e.beginPath(),e.arc(b,a,c,0,Math.PI*2),e.fill(),e.shadowBlur=0,e.shadowOffsetY=0,e.fillStyle=o.progressColor||"rgba(255, 255, 255, 0.9)",e.beginPath(),e.arc(b,a,c*.4,0,Math.PI*2),e.fill()}}var lt={bars:R,bar:R,mirror:rt,line:at,blocks:N,block:N,dots:V,dot:V,seekbar:nt};function J(e,t,i,s,o){(lt[o.waveformStyle]||R)(e,t,i,s,o)}function Y(e){try{let t=e.getChannelData(0),i=e.sampleRate,s=ht(t,i);if(s.length<2)return 120;let o=[];for(let d=1;d<s.length;d++)o.push((s[d]-s[d-1])/i);let r={};o.forEach(d=>{let l=60/d,h=Math.round(l/3)*3;h>60&&h<200&&(r[h]=(r[h]||0)+1)});let n=0,a=120;for(let[d,l]of Object.entries(r))l>n&&(n=l,a=parseInt(d));return a<70&&r[a*2]?a*=2:a>160&&r[Math.round(a/2)]&&(a=Math.round(a/2)),a-1}catch(t){return console.warn("[WaveformPlayer] BPM detection failed:",t),null}}function ht(e,t){let o=[],r=0;for(let n=0;n<e.length-2048;n+=1024){let a=0;for(let h=n;h<n+2048;h++)a+=e[h]*e[h];a=a/2048;let d=a-r,l=r*1.8+.01;if(d>l&&a>.01){let h=o[o.length-1]||0,c=t*.15;n-h>c&&o.push(n)}r=a*.8+r*.2}return o}function dt(e,t=200){let i=e.length/t,s=~~(i/10)||1,o=e.numberOfChannels,r=[];for(let a=0;a<o;a++){let d=e.getChannelData(a);for(let l=0;l<t;l++){let h=~~(l*i),c=~~(h+i),b=0,g=0;for(let m=h;m<c;m+=s){let u=d[m];u>g&&(g=u),u<b&&(b=u)}let p=Math.max(Math.abs(g),Math.abs(b));(a===0||p>r[l])&&(r[l]=p)}}let n=Math.max(...r);return n>0?r.map(a=>a/n):r}async function B(e,t=200,i=!1){let s;try{let o=window.AudioContext||window.webkitAudioContext;s=new o;let n=await(await fetch(e)).arrayBuffer(),a=await s.decodeAudioData(n),d=dt(a,t);d=ut(d);let l=null;return i&&(l=Y(a)),{peaks:d,bpm:l}}finally{s&&s.close()}}function G(e=200){let t=[];for(let i=0;i<e;i++){let s=Math.random()*.5+.3,o=Math.sin(i/e*Math.PI*4)*.2;t.push(w(s+o,.1,1))}return t}function ut(e,t=.95){let i=Math.max(...e);if(i===0||i>t)return e;let s=t/i;return e.map(o=>o*s)}function K(e){let t=document.documentElement,i=document.body;return t.classList.contains(e)||t.classList.contains(`${e}-mode`)||t.classList.contains(`theme-${e}`)||t.getAttribute("data-theme")===e||t.getAttribute("data-color-scheme")===e||i.classList.contains(e)||i.classList.contains(`${e}-mode`)||i.getAttribute("data-theme")===e}function ct(){if(K("dark"))return"dark";if(K("light"))return"light";try{let e=getComputedStyle(document.body).backgroundColor,t=q(e);if(t!==null){if(t>128)return"light";if(t<128)return"dark"}}catch{}if(window.matchMedia){if(window.matchMedia("(prefers-color-scheme: dark)").matches)return"dark";if(window.matchMedia("(prefers-color-scheme: light)").matches)return"light"}return"dark"}var W={dark:{waveformColor:"rgba(255, 255, 255, 0.3)",progressColor:"rgba(255, 255, 255, 0.9)",buttonColor:"rgba(255, 255, 255, 0.9)",buttonHoverColor:"rgba(255, 255, 255, 1)",textColor:"#ffffff",textSecondaryColor:"rgba(255, 255, 255, 0.6)",backgroundColor:"rgba(255, 255, 255, 0.03)",borderColor:"rgba(255, 255, 255, 0.1)"},light:{waveformColor:"rgba(0, 0, 0, 0.2)",progressColor:"rgba(0, 0, 0, 0.8)",buttonColor:"rgba(0, 0, 0, 0.8)",buttonHoverColor:"rgba(0, 0, 0, 0.9)",textColor:"#333333",textSecondaryColor:"rgba(0, 0, 0, 0.6)",backgroundColor:"rgba(0, 0, 0, 0.02)",borderColor:"rgba(0, 0, 0, 0.1)"}};function Q(e){if(e&&W[e])return W[e];let t=ct();return W[t]}var Z={url:"",height:64,samples:256,preload:"metadata",audioMode:"self",playbackRate:1,showPlaybackSpeed:!1,playbackRates:[.5,.75,1,1.25,1.5,1.75,2],buttonAlign:"auto",layout:"default",buttonStyle:"circle",waveformStyle:"mirror",barWidth:2,barSpacing:0,barRadius:1,colorPreset:null,waveformColor:null,progressColor:null,buttonColor:null,buttonHoverColor:null,textColor:null,textSecondaryColor:null,backgroundColor:null,borderColor:null,autoplay:!1,showControls:!0,showInfo:!0,showTime:!0,showHoverTime:!1,showBPM:!1,bpm:null,singlePlay:!0,playOnSeek:!0,enableMediaSession:!0,markers:[],showMarkers:!0,accessibleSeek:!0,seekLabel:null,title:null,subtitle:null,artwork:null,album:"",errorText:"Unable to load audio",playIcon:'<svg viewBox="0 0 24 24" width="16" height="16"><path d="M8 5v14l11-7z"/></svg>',pauseIcon:'<svg viewBox="0 0 24 24" width="16" height="16"><path d="M6 4h4v16H6zM14 4h4v16h-4z"/></svg>',onLoad:null,onPlay:null,onPause:null,onEnd:null,onError:null,onTimeUpdate:null},X={bars:{barWidth:3,barSpacing:1},mirror:{barWidth:2,barSpacing:2},line:{barWidth:2,barSpacing:0},blocks:{barWidth:4,barSpacing:2},dots:{barWidth:3,barSpacing:3},seekbar:{barWidth:1,barSpacing:0}};var tt=5,et=10,C=class e{static instances=new Map;static currentlyPlaying=null;constructor(t,i={}){if(this.container=typeof t=="string"?document.querySelector(t):t,!this.container)throw new Error("[WaveformPlayer] Container element not found");let s=L(this.container),o={...i};o.style&&!o.waveformStyle&&(o.waveformStyle=o.style),o.src&&!o.url&&(o.url=o.src),this.options=D(Z,s,o);let r=Q(this.options.colorPreset);for(let[a,d]of Object.entries(r))(this.options[a]===null||this.options[a]===void 0)&&(this.options[a]=d);let n=X[this.options.waveformStyle];n&&(s.barWidth===void 0&&i.barWidth===void 0&&(this.options.barWidth=n.barWidth),s.barSpacing===void 0&&i.barSpacing===void 0&&(this.options.barSpacing=n.barSpacing)),this.audio=null,this.canvas=null,this.ctx=null,this.waveformData=[],this.progress=0,this.isPlaying=!1,this.isLoading=!1,this.hasError=!1,this.updateTimer=null,this.resizeObserver=null,this._ac=new AbortController,this.id=this.container.id||O(this.options.url),e.instances.set(this.id,this),this.init(),setTimeout(()=>{this._emit("waveformplayer:ready",{player:this,url:this.options.url})},100)}_emit(t,i,s=!1){let o=new CustomEvent(t,{bubbles:!0,cancelable:s,detail:i});return this.container.dispatchEvent(o),o}_requestSeek(t){this._emit("waveformplayer:request-seek",{...this._buildTrackDetail(),percent:t},!0).defaultPrevented||(this.progress=t,this.drawWaveform?.())}init(){this.createDOM(),this.createAudio(),this.initPlaybackSpeed(),this.initKeyboardControls(),this.initSeekControl(),this.bindEvents(),this.setupResizeObserver(),requestAnimationFrame(()=>{this.resizeCanvas(),this.options.url&&this.load(this.options.url).then(()=>{this.options.autoplay&&this.play()?.catch(()=>{})}).catch(t=>{console.error("[WaveformPlayer] Failed to load audio:",t)})})}createDOM(){this.container.innerHTML="",this.container.className="waveform-player";let t=this.options.buttonAlign;t==="auto"&&(this.options.waveformStyle==="bars"?t="bottom":t="center"),this.options.layout==="preview"&&this.container.classList.add("waveform-layout-preview");let s=this.options.showControls?`
2
2
  <button class="waveform-btn${this.options.buttonStyle==="minimal"?" waveform-btn-minimal":""}" aria-label="Play/Pause" style="
3
3
  border-color: ${this.options.buttonColor};
4
4
  color: ${this.options.buttonColor};
@@ -47,7 +47,7 @@
47
47
  `:"";this.container.innerHTML=`
48
48
  <div class="waveform-player-inner">
49
49
  <div class="waveform-body">
50
- <div class="waveform-track waveform-align-${e}">
50
+ <div class="waveform-track waveform-align-${t}">
51
51
  ${s}
52
52
 
53
53
  <div class="waveform-container">
@@ -63,4 +63,4 @@
63
63
  ${o}
64
64
  </div>
65
65
  </div>
66
- `,this.playBtn=this.container.querySelector(".waveform-btn"),this.canvas=this.container.querySelector("canvas"),this.ctx=this.canvas.getContext("2d"),this.titleEl=this.container.querySelector(".waveform-title"),this.subtitleEl=this.container.querySelector(".waveform-subtitle"),this.artworkEl=this.container.querySelector(".waveform-artwork"),this.currentTimeEl=this.container.querySelector(".time-current"),this.totalTimeEl=this.container.querySelector(".time-total"),this.bpmEl=this.container.querySelector(".waveform-bpm"),this.bpmValueEl=this.container.querySelector(".bpm-value"),this.loadingEl=this.container.querySelector(".waveform-loading"),this.errorEl=this.container.querySelector(".waveform-error"),this.markersContainer=this.container.querySelector(".waveform-markers"),this.speedBtn=this.container.querySelector(".speed-btn"),this.speedMenu=this.container.querySelector(".speed-menu"),this.resizeCanvas()}createAudio(){if(this.options.audioMode==="external"){this.audio=null;return}this.audio=new Audio,this.audio.preload=this.options.preload||"metadata",this.audio.crossOrigin="anonymous"}initPlaybackSpeed(){this.audio&&this.options.playbackRate&&this.options.playbackRate!==1&&(this.audio.playbackRate=this.options.playbackRate),this.options.showPlaybackSpeed&&this.initSpeedControls()}initSpeedControls(){let e=this.container.querySelector(".speed-btn"),i=this.container.querySelector(".speed-menu");!e||!i||(e.addEventListener("click",s=>{s.stopPropagation(),i.style.display=i.style.display==="none"?"block":"none"},{signal:this._ac.signal}),document.addEventListener("click",()=>{i.style.display="none"},{signal:this._ac.signal}),i.addEventListener("click",s=>{if(s.stopPropagation(),s.target.classList.contains("speed-option")){let o=parseFloat(s.target.dataset.rate);this.setPlaybackRate(o),i.style.display="none"}},{signal:this._ac.signal}),this.updateSpeedUI())}initKeyboardControls(){this.container.setAttribute("tabindex","-1"),this.container.addEventListener("click",()=>{t.getAllInstances().forEach(e=>{e!==this&&e.container.setAttribute("tabindex","-1")}),this.container.setAttribute("tabindex","0"),this.container.focus()},{signal:this._ac.signal}),this.container.addEventListener("keydown",e=>{if(document.activeElement!==this.container)return;let i=e.key,s=!!this.audio,o=s?this.audio.currentTime:0;if(s&&i>="0"&&i<="9"){e.preventDefault(),this.seekToPercent(parseInt(i)/10);return}let r={" ":()=>this.togglePlay()};s&&(r.ArrowLeft=()=>this.seekTo(w(o-5,0,this.audio.duration)),r.ArrowRight=()=>this.seekTo(w(o+5,0,this.audio.duration)),r.ArrowUp=()=>this.setVolume(w(this.audio.volume+.1)),r.ArrowDown=()=>this.setVolume(w(this.audio.volume-.1)),r.m=r.M=()=>this.audio.muted=!this.audio.muted),r[i]&&(e.preventDefault(),r[i]())},{signal:this._ac.signal})}initSeekControl(){this.options.accessibleSeek&&(this.seekEl=this.container.querySelector(".waveform-container"),this.seekEl&&(this.seekEl.setAttribute("role","slider"),this.seekEl.setAttribute("tabindex","0"),this.seekEl.setAttribute("aria-valuemin","0"),this.applySeekLabel(),this.updateSeekAccessibility(),this.seekEl.addEventListener("keydown",e=>{let i=this.getSeekDuration();if(!i)return;let s=this.getSeekCurrentTime(),o;switch(e.key){case"ArrowLeft":case"ArrowDown":o=s-tt;break;case"ArrowRight":case"ArrowUp":o=s+tt;break;case"PageDown":o=s-et;break;case"PageUp":o=s+et;break;case"Home":o=0;break;case"End":o=i;break;default:return}e.preventDefault(),e.stopPropagation(),this.seekToSeconds(o)},{signal:this._ac.signal})))}getSeekDuration(){return this.options.audioMode==="external"?this._extDuration||0:this.audio&&Number.isFinite(this.audio.duration)?this.audio.duration:0}getSeekCurrentTime(){return this.options.audioMode==="external"?this.progress*(this._extDuration||0):this.audio&&Number.isFinite(this.audio.currentTime)?this.audio.currentTime:0}seekToSeconds(e){let i=this.getSeekDuration();if(!i)return;let s=w(e,0,i);if(this.options.audioMode==="external"){this._requestSeek(s/i),this.updateSeekAccessibility();return}this.seekTo(s)}applySeekLabel(e=this.options.title){if(!this.seekEl)return;let i=this.options.seekLabel||e||"Seek";this.seekEl.setAttribute("aria-label",i)}updateSeekAccessibility(){if(!this.seekEl)return;let e=this.getSeekDuration(),i=Math.min(this.getSeekCurrentTime(),e);this.seekEl.setAttribute("aria-valuemax",String(Math.round(e))),this.seekEl.setAttribute("aria-valuenow",String(Math.round(i))),this.seekEl.setAttribute("aria-valuetext",`${S(i)} of ${S(e)}`)}initMediaSession(){!("mediaSession"in navigator)||!this.options.enableMediaSession||this.audio&&(navigator.mediaSession.metadata=new MediaMetadata({title:this.options.title||"Unknown Track",artist:this.options.subtitle||"",album:this.options.album||"",artwork:this.options.artwork?[{src:this.options.artwork,sizes:"512x512",type:"image/jpeg"}]:[]}),navigator.mediaSession.setActionHandler("play",()=>this.play()),navigator.mediaSession.setActionHandler("pause",()=>this.pause()),navigator.mediaSession.setActionHandler("seekbackward",()=>{this.seekTo(w(this.audio.currentTime-10,0,this.audio.duration))}),navigator.mediaSession.setActionHandler("seekforward",()=>{this.seekTo(w(this.audio.currentTime+10,0,this.audio.duration))}),navigator.mediaSession.setActionHandler("seekto",e=>{e.seekTime!==null&&this.seekTo(e.seekTime)}))}bindEvents(){this.playBtn&&this.playBtn.addEventListener("click",()=>this.togglePlay()),this.audio&&(this.audio.addEventListener("loadstart",()=>this.setLoading(!0)),this.audio.addEventListener("loadedmetadata",()=>this.onMetadataLoaded()),this.audio.addEventListener("canplay",()=>this.setLoading(!1)),this.audio.addEventListener("play",()=>this.onPlay()),this.audio.addEventListener("pause",()=>this.onPause()),this.audio.addEventListener("ended",()=>this.onEnded()),this.audio.addEventListener("error",e=>this.onError(e))),this.canvas.addEventListener("click",e=>this.handleCanvasClick(e)),this.resizeHandler=F(()=>this.resizeCanvas(),100),window.addEventListener("resize",this.resizeHandler)}setupResizeObserver(){"ResizeObserver"in window&&(this.resizeObserver=new ResizeObserver(()=>{this.resizeCanvas()}),this.canvas?.parentElement&&this.resizeObserver.observe(this.canvas.parentElement))}async load(e){try{this.setLoading(!0),this.progress=0,this.hasError=!1,this.audio&&(this.audio.src=e,await new Promise((s,o)=>{let r=()=>{this.audio.removeEventListener("loadedmetadata",r),this.audio.removeEventListener("error",n),s()},n=a=>{this.audio.removeEventListener("loadedmetadata",r),this.audio.removeEventListener("error",n),o(a)};this.audio.addEventListener("loadedmetadata",r),this.audio.addEventListener("error",n)}));let i=this.options.title||x(e);if(this.titleEl&&(this.titleEl.textContent=i),this.applySeekLabel(i),this.options.waveform)this.setWaveformData(this.options.waveform);else try{let s=await B(e,this.options.samples,this.options.showBPM);this.waveformData=s.peaks,s.bpm&&(this.detectedBPM=s.bpm,this.updateBPMDisplay())}catch(s){console.warn("[WaveformPlayer] Using placeholder waveform:",s),this.waveformData=G(this.options.samples)}this.drawWaveform(),this.renderMarkers(),this.initMediaSession(),this.options.onLoad&&this.options.onLoad(this)}catch(i){this.onError(i)}finally{this.setLoading(!1)}}async loadTrack(e,i=null,s=null,o={}){this.isPlaying&&this.pause(),this.audio&&(this.audio.src="",this.audio.load()),this.hasError=!1,this.errorEl&&(this.errorEl.style.display="none"),this.canvas&&(this.canvas.style.opacity="1"),this.playBtn&&(this.playBtn.disabled=!1),this.progress=0,this.waveformData=[],this.options=D(this.options,{url:e,title:i||this.options.title,subtitle:s||this.options.subtitle,...o}),o.preload&&this.audio&&(this.audio.preload=o.preload),this.subtitleEl&&(s?(this.subtitleEl.textContent=s,this.subtitleEl.style.display=""):s===""&&(this.subtitleEl.style.display="none")),o.artwork&&this.artworkEl&&(this.artworkEl.src=o.artwork),this.options.markers=o.markers||[],this.options.waveform=o.waveform||null,await this.load(e),o.autoplay!==!1&&this.play()?.catch(()=>{})}setWaveformData(e){if(typeof e=="string"&&e.trim().endsWith(".json")){fetch(e.trim()).then(i=>i.json()).then(i=>{this.waveformData=Array.isArray(i)?i:i.peaks||[],i.markers&&!this.options.markers?.length&&(this.options.markers=i.markers,this.renderMarkers()),this.drawWaveform()}).catch(()=>{});return}if(typeof e=="string")try{let i=JSON.parse(e);this.waveformData=Array.isArray(i)?i:[]}catch{this.waveformData=e.split(",").map(Number)}else this.waveformData=Array.isArray(e)?e:[];this.drawWaveform()}drawWaveform(){!this.ctx||this.waveformData.length===0||J(this.ctx,this.canvas,this.waveformData,this.progress,{...this.options,waveformStyle:this.options.waveformStyle||"bars",color:this.options.waveformColor,progressColor:this.options.progressColor})}resizeCanvas(){if(!this.canvas||this.isDestroying)return;let e=window.devicePixelRatio||1,i=this.canvas.parentElement.getBoundingClientRect();this.canvas.width=i.width*e,this.canvas.height=this.options.height*e,this.canvas.parentElement.style.height=this.options.height+"px",this.drawWaveform()}renderMarkers(){if(!this.markersContainer||(this.markersContainer.innerHTML="",!this.options.showMarkers||!this.options.markers?.length))return;let e=this.getSeekDuration();e&&this.options.markers.forEach((i,s)=>{if(i.time>e){console.warn(`[WaveformPlayer] Marker "${i.label}" at ${i.time}s exceeds audio duration of ${e}s`);return}let o=i.time/e*100,r=document.createElement("button");r.className="waveform-marker",r.style.left=`${o}%`,r.style.backgroundColor=i.color||"rgba(255, 255, 255, 0.5)",r.setAttribute("aria-label",i.label),r.setAttribute("data-time",i.time);let n=document.createElement("span");n.className="waveform-marker-tooltip",n.textContent=i.label,r.appendChild(n),r.addEventListener("click",a=>{a.stopPropagation(),this.seekTo(i.time),this.options.playOnSeek&&!this.isPlaying&&this.play()}),this.markersContainer.appendChild(r)})}setActiveMarker(e){if(!this.markersContainer)return;this.markersContainer.querySelectorAll(".waveform-marker").forEach((s,o)=>s.classList.toggle("active",o===e))}handleCanvasClick(e){let i=this.canvas.getBoundingClientRect(),s=e.clientX-i.left,o=w(s/i.width);if(this.options.audioMode==="external"){this._requestSeek(o);return}!this.audio||!this.audio.duration||this.seekToPercent(o)}setLoading(e){this.isLoading=e,this.loadingEl&&(this.loadingEl.style.display=e?"block":"none"),this.seekEl&&this.seekEl.setAttribute("aria-busy",e?"true":"false")}onMetadataLoaded(){this.isDestroying||(this.totalTimeEl&&(this.totalTimeEl.textContent=S(this.audio.duration)),this.renderMarkers(),this.updateSeekAccessibility())}setPlayButtonState(e){if(!this.playBtn)return;this.playBtn.classList.toggle("playing",e);let i=this.playBtn.querySelector(".waveform-icon-play"),s=this.playBtn.querySelector(".waveform-icon-pause");i&&(i.style.display=e?"none":"flex"),s&&(s.style.display=e?"flex":"none")}onPlay(){this.isDestroying||(this.isPlaying=!0,this.setPlayButtonState(!0),this.startSmoothUpdate(),this._emit("waveformplayer:play",{player:this,url:this.options.url}),this.options.onPlay&&this.options.onPlay(this))}onPause(){this.isDestroying||(this.isPlaying=!1,this.setPlayButtonState(!1),this.stopSmoothUpdate(),this._emit("waveformplayer:pause",{player:this,url:this.options.url}),this.options.onPause&&this.options.onPause(this))}onEnded(){if(this.isDestroying)return;let e=this.audio.duration;this.progress=0,this.audio.currentTime=0,this.drawWaveform(),this.currentTimeEl&&(this.currentTimeEl.textContent="0:00"),this._emit("waveformplayer:ended",{player:this,url:this.options.url,currentTime:e,duration:e}),this.onPause(),this.options.onEnd&&this.options.onEnd(this)}onError(e){this.isDestroying||(console.error("[WaveformPlayer] Audio error:",e),this.hasError=!0,this.setLoading(!1),this.errorEl&&(this.errorEl.style.display="flex"),this.canvas&&(this.canvas.style.opacity="0.2"),this.playBtn&&(this.playBtn.disabled=!0),this.options.onError&&this.options.onError(e,this))}startSmoothUpdate(){this.stopSmoothUpdate();let e=()=>{this.isPlaying&&this.audio&&this.audio.duration&&(this.updateProgress(),this.updateTimer=requestAnimationFrame(e))};this.updateTimer=requestAnimationFrame(e)}stopSmoothUpdate(){this.updateTimer&&(cancelAnimationFrame(this.updateTimer),this.updateTimer=null)}updateProgress(){if(!this.audio||!this.audio.duration)return;let e=this.audio.currentTime/this.audio.duration;Math.abs(e-this.progress)>.001&&(this.progress=e,this.drawWaveform()),this.currentTimeEl&&(this.currentTimeEl.textContent=S(this.audio.currentTime)),this._emit("waveformplayer:timeupdate",{player:this,currentTime:this.audio.currentTime,duration:this.audio.duration,progress:this.progress,url:this.options.url}),this.options.onTimeUpdate&&this.options.onTimeUpdate(this.audio.currentTime,this.audio.duration,this),this.updateSeekAccessibility()}updateBPMDisplay(){this.bpmEl&&this.bpmValueEl&&this.detectedBPM&&(this.bpmValueEl.textContent=Math.round(this.detectedBPM),this.bpmEl.style.display="inline-flex")}updateSpeedUI(){if(!this.audio)return;let e=this.container.querySelector(".speed-value");if(e){let i=this.audio.playbackRate;e.textContent=i===1?"1x":`${i}x`}this.container.querySelectorAll(".speed-option").forEach(i=>{i.classList.toggle("active",parseFloat(i.dataset.rate)===this.audio.playbackRate)})}play(){if(this.options.singlePlay&&t.currentlyPlaying&&t.currentlyPlaying!==this&&t.currentlyPlaying.pause(),this.options.audioMode==="external"){this._emit("waveformplayer:request-play",this._buildTrackDetail(),!0).defaultPrevented||(t.currentlyPlaying=this);return}return t.currentlyPlaying=this,this.audio.play()}pause(){if(t.currentlyPlaying===this&&(t.currentlyPlaying=null),this.options.audioMode==="external"){this._emit("waveformplayer:request-pause",this._buildTrackDetail(),!0);return}this.audio.pause()}_buildTrackDetail(){return{url:this.options.url,title:this.options.title,subtitle:this.options.subtitle,artist:this.options.artist||this.options.subtitle,artwork:this.options.artwork,markers:this.options.markers,waveform:this.options.waveform,id:this.id,player:this}}setPlayingState(e){let i=this.isPlaying;this.isPlaying=!!e,this.setPlayButtonState(this.isPlaying),this.isPlaying&&!i?(this.startSmoothUpdate?.(),this._emit("waveformplayer:play",{player:this,url:this.options.url}),this.options.onPlay&&this.options.onPlay(this)):!this.isPlaying&&i&&(this.stopSmoothUpdate?.(),this._emit("waveformplayer:pause",{player:this,url:this.options.url}),this.options.onPause&&this.options.onPause(this))}setProgress(e,i){!i||i<=0||(this.progress=w(e/i),this.currentTimeEl&&(this.currentTimeEl.textContent=S(e)),this._extDuration=i,this.totalTimeEl&&(!this.totalTimeEl.dataset._extSet||this.totalTimeEl.dataset._extDur!==String(i))&&(this.totalTimeEl.textContent=S(i),this.totalTimeEl.dataset._extSet="1",this.totalTimeEl.dataset._extDur=String(i)),this.drawWaveform?.(),this._emit("waveformplayer:timeupdate",{player:this,currentTime:e,duration:i,progress:this.progress,url:this.options.url}),this.options.onTimeUpdate&&this.options.onTimeUpdate(e,i,this),this.progress>=1?this._extEnded||(this._extEnded=!0,this._emit("waveformplayer:ended",{player:this,url:this.options.url,currentTime:i,duration:i}),this.options.onEnd&&this.options.onEnd(this)):this._extEnded=!1,this.updateSeekAccessibility())}togglePlay(){this.isPlaying?this.pause():this.play()}seekTo(e){this.audio&&this.audio.duration&&(this.audio.currentTime=w(e,0,this.audio.duration),this.updateProgress())}seekToPercent(e){this.audio&&this.audio.duration&&(this.audio.currentTime=this.audio.duration*w(e),this.updateProgress())}setVolume(e){let i=Number(e);this.audio&&Number.isFinite(i)&&(this.audio.volume=w(i))}setPlaybackRate(e){if(!this.audio)return;let i=w(e,.5,2);this.audio.playbackRate=i,this.options.playbackRate=i,this.updateSpeedUI()}destroy(){this.isDestroying=!0,this._emit("waveformplayer:destroy",{player:this,url:this.options.url}),this.pause(),this.stopSmoothUpdate(),this._ac?.abort(),this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null),this.resizeHandler&&(window.removeEventListener("resize",this.resizeHandler),this.resizeHandler=null),t.instances.delete(this.id),t.currentlyPlaying===this&&(t.currentlyPlaying=null),this.audio&&(this.audio.pause(),this.audio.src="",this.audio.load(),this.audio=null),this.container.innerHTML="",this.canvas=null,this.ctx=null,this.playBtn=null,this.waveformData=[]}static getInstance(e){if(typeof e=="string"){let i=this.instances.get(e);if(i)return i;let s=document.getElementById(e);if(s)return Array.from(this.instances.values()).find(o=>o.container===s)}if(e instanceof HTMLElement)return Array.from(this.instances.values()).find(i=>i.container===e)}static getAllInstances(){return Array.from(this.instances.values())}static destroyAll(){this.instances.forEach(e=>e.destroy()),this.instances.clear()}static async generateWaveformData(e,i=200){try{return(await B(e,i)).peaks}catch(s){throw console.error("[WaveformPlayer] Failed to generate waveform:",s),s}}static getPeaksUrl(e){if(!e)return;let i=e.replace(/\.(mp3|wav|ogg|flac|m4a|aac)(\?[^#]*)?(#.*)?$/i,".json$2$3");return i===e?void 0:i}};C.utils={formatTime:S,extractTitleFromUrl:x,escapeHtml:A,isSafeHref:_,parseDataAttributes:L};var $=()=>typeof window<"u"&&typeof document<"u";function I(){if(!$())return;document.querySelectorAll("[data-waveform-player]").forEach(e=>{if(e.dataset.waveformInitialized!=="true")try{new C(e),e.dataset.waveformInitialized="true"}catch(i){console.error("[WaveformPlayer] Failed to initialize:",i,e)}})}$()&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",I):I());C.init=I;$()&&(window.WaveformPlayer=C);var Lt=C;})();
66
+ `,this.playBtn=this.container.querySelector(".waveform-btn"),this.canvas=this.container.querySelector("canvas"),this.ctx=this.canvas.getContext("2d"),this.titleEl=this.container.querySelector(".waveform-title"),this.subtitleEl=this.container.querySelector(".waveform-subtitle"),this.artworkEl=this.container.querySelector(".waveform-artwork"),this.currentTimeEl=this.container.querySelector(".time-current"),this.totalTimeEl=this.container.querySelector(".time-total"),this.bpmEl=this.container.querySelector(".waveform-bpm"),this.bpmValueEl=this.container.querySelector(".bpm-value"),this.loadingEl=this.container.querySelector(".waveform-loading"),this.errorEl=this.container.querySelector(".waveform-error"),this.markersContainer=this.container.querySelector(".waveform-markers"),this.speedBtn=this.container.querySelector(".speed-btn"),this.speedMenu=this.container.querySelector(".speed-menu"),this.resizeCanvas(),this.updateBPMDisplay()}createAudio(){if(this.options.audioMode==="external"){this.audio=null;return}this.audio=new Audio,this.audio.preload=this.options.preload||"metadata",this.audio.crossOrigin="anonymous"}initPlaybackSpeed(){this.audio&&this.options.playbackRate&&this.options.playbackRate!==1&&(this.audio.playbackRate=this.options.playbackRate),this.options.showPlaybackSpeed&&this.initSpeedControls()}initSpeedControls(){let t=this.container.querySelector(".speed-btn"),i=this.container.querySelector(".speed-menu");!t||!i||(t.addEventListener("click",s=>{s.stopPropagation(),i.style.display=i.style.display==="none"?"block":"none"},{signal:this._ac.signal}),document.addEventListener("click",()=>{i.style.display="none"},{signal:this._ac.signal}),i.addEventListener("click",s=>{if(s.stopPropagation(),s.target.classList.contains("speed-option")){let o=parseFloat(s.target.dataset.rate);this.setPlaybackRate(o),i.style.display="none"}},{signal:this._ac.signal}),this.updateSpeedUI())}initKeyboardControls(){this.container.setAttribute("tabindex","-1"),this.container.addEventListener("click",()=>{e.getAllInstances().forEach(t=>{t!==this&&t.container.setAttribute("tabindex","-1")}),this.container.setAttribute("tabindex","0"),this.container.focus()},{signal:this._ac.signal}),this.container.addEventListener("keydown",t=>{if(document.activeElement!==this.container)return;let i=t.key,s=!!this.audio,o=s?this.audio.currentTime:0;if(s&&i>="0"&&i<="9"){t.preventDefault(),this.seekToPercent(parseInt(i)/10);return}let r={" ":()=>this.togglePlay()};s&&(r.ArrowLeft=()=>this.seekTo(w(o-5,0,this.audio.duration)),r.ArrowRight=()=>this.seekTo(w(o+5,0,this.audio.duration)),r.ArrowUp=()=>this.setVolume(w(this.audio.volume+.1)),r.ArrowDown=()=>this.setVolume(w(this.audio.volume-.1)),r.m=r.M=()=>this.audio.muted=!this.audio.muted),r[i]&&(t.preventDefault(),r[i]())},{signal:this._ac.signal})}initSeekControl(){this.options.accessibleSeek&&(this.seekEl=this.container.querySelector(".waveform-container"),this.seekEl&&(this.seekEl.setAttribute("role","slider"),this.seekEl.setAttribute("tabindex","0"),this.seekEl.setAttribute("aria-valuemin","0"),this.applySeekLabel(),this.updateSeekAccessibility(),this.seekEl.addEventListener("keydown",t=>{let i=this.getSeekDuration();if(!i)return;let s=this.getSeekCurrentTime(),o;switch(t.key){case"ArrowLeft":case"ArrowDown":o=s-tt;break;case"ArrowRight":case"ArrowUp":o=s+tt;break;case"PageDown":o=s-et;break;case"PageUp":o=s+et;break;case"Home":o=0;break;case"End":o=i;break;default:return}t.preventDefault(),t.stopPropagation(),this.seekToSeconds(o)},{signal:this._ac.signal})))}getSeekDuration(){return this.options.audioMode==="external"?this._extDuration||0:this.audio&&Number.isFinite(this.audio.duration)?this.audio.duration:0}getSeekCurrentTime(){return this.options.audioMode==="external"?this.progress*(this._extDuration||0):this.audio&&Number.isFinite(this.audio.currentTime)?this.audio.currentTime:0}seekToSeconds(t){let i=this.getSeekDuration();if(!i)return;let s=w(t,0,i);if(this.options.audioMode==="external"){this._requestSeek(s/i),this.updateSeekAccessibility();return}this.seekTo(s)}applySeekLabel(t=this.options.title){if(!this.seekEl)return;let i=this.options.seekLabel||t||"Seek";this.seekEl.setAttribute("aria-label",i)}updateSeekAccessibility(){if(!this.seekEl)return;let t=this.getSeekDuration(),i=Math.min(this.getSeekCurrentTime(),t);this.seekEl.setAttribute("aria-valuemax",String(Math.round(t))),this.seekEl.setAttribute("aria-valuenow",String(Math.round(i))),this.seekEl.setAttribute("aria-valuetext",`${S(i)} of ${S(t)}`)}initMediaSession(){!("mediaSession"in navigator)||!this.options.enableMediaSession||this.audio&&(navigator.mediaSession.metadata=new MediaMetadata({title:this.options.title||"Unknown Track",artist:this.options.subtitle||"",album:this.options.album||"",artwork:this.options.artwork?[{src:this.options.artwork,sizes:"512x512",type:"image/jpeg"}]:[]}),navigator.mediaSession.setActionHandler("play",()=>this.play()),navigator.mediaSession.setActionHandler("pause",()=>this.pause()),navigator.mediaSession.setActionHandler("seekbackward",()=>{this.seekTo(w(this.audio.currentTime-10,0,this.audio.duration))}),navigator.mediaSession.setActionHandler("seekforward",()=>{this.seekTo(w(this.audio.currentTime+10,0,this.audio.duration))}),navigator.mediaSession.setActionHandler("seekto",t=>{t.seekTime!==null&&this.seekTo(t.seekTime)}))}bindEvents(){this.playBtn&&this.playBtn.addEventListener("click",()=>this.togglePlay()),this.audio&&(this.audio.addEventListener("loadstart",()=>this.setLoading(!0)),this.audio.addEventListener("loadedmetadata",()=>this.onMetadataLoaded()),this.audio.addEventListener("canplay",()=>this.setLoading(!1)),this.audio.addEventListener("play",()=>this.onPlay()),this.audio.addEventListener("pause",()=>this.onPause()),this.audio.addEventListener("ended",()=>this.onEnded()),this.audio.addEventListener("error",t=>this.onError(t))),this.canvas.addEventListener("click",t=>this.handleCanvasClick(t)),this.resizeHandler=F(()=>this.resizeCanvas(),100),window.addEventListener("resize",this.resizeHandler)}setupResizeObserver(){"ResizeObserver"in window&&(this.resizeObserver=new ResizeObserver(()=>{this.resizeCanvas()}),this.canvas?.parentElement&&this.resizeObserver.observe(this.canvas.parentElement))}async load(t){try{this.setLoading(!0),this.progress=0,this.hasError=!1,this.audio&&(this.audio.src=t,await new Promise((s,o)=>{let r=()=>{this.audio.removeEventListener("loadedmetadata",r),this.audio.removeEventListener("error",n),s()},n=a=>{this.audio.removeEventListener("loadedmetadata",r),this.audio.removeEventListener("error",n),o(a)};this.audio.addEventListener("loadedmetadata",r),this.audio.addEventListener("error",n)}));let i=this.options.title||x(t);if(this.titleEl&&(this.titleEl.textContent=i),this.applySeekLabel(i),this.options.waveform)this.setWaveformData(this.options.waveform);else try{let s=await B(t,this.options.samples,this.options.showBPM);this.waveformData=s.peaks,s.bpm&&(this.detectedBPM=s.bpm,this.updateBPMDisplay())}catch(s){console.warn("[WaveformPlayer] Using placeholder waveform:",s),this.waveformData=G(this.options.samples)}this.drawWaveform(),this.renderMarkers(),this.initMediaSession(),this.options.onLoad&&this.options.onLoad(this)}catch(i){this.onError(i)}finally{this.setLoading(!1)}}async loadTrack(t,i=null,s=null,o={}){this.isPlaying&&this.pause(),this.audio&&(this.audio.src="",this.audio.load()),this.hasError=!1,this.errorEl&&(this.errorEl.style.display="none"),this.canvas&&(this.canvas.style.opacity="1"),this.playBtn&&(this.playBtn.disabled=!1),this.progress=0,this.waveformData=[],this.options=D(this.options,{url:t,title:i||this.options.title,subtitle:s||this.options.subtitle,...o}),o.preload&&this.audio&&(this.audio.preload=o.preload),this.subtitleEl&&(s?(this.subtitleEl.textContent=s,this.subtitleEl.style.display=""):s===""&&(this.subtitleEl.style.display="none")),o.artwork&&this.artworkEl&&(this.artworkEl.src=o.artwork),this.options.markers=o.markers||[],this.options.waveform=o.waveform||null,await this.load(t),o.autoplay!==!1&&this.play()?.catch(()=>{})}setWaveformData(t){if(typeof t=="string"&&t.trim().endsWith(".json")){fetch(t.trim()).then(i=>i.json()).then(i=>{this.waveformData=Array.isArray(i)?i:i.peaks||[],i.markers&&!this.options.markers?.length&&(this.options.markers=i.markers,this.renderMarkers()),this.drawWaveform()}).catch(()=>{});return}if(typeof t=="string")try{let i=JSON.parse(t);this.waveformData=Array.isArray(i)?i:[]}catch{this.waveformData=t.split(",").map(Number)}else this.waveformData=Array.isArray(t)?t:[];this.drawWaveform()}drawWaveform(){!this.ctx||this.waveformData.length===0||J(this.ctx,this.canvas,this.waveformData,this.progress,{...this.options,waveformStyle:this.options.waveformStyle||"bars",color:this.options.waveformColor,progressColor:this.options.progressColor})}resizeCanvas(){if(!this.canvas||this.isDestroying)return;let t=window.devicePixelRatio||1,i=this.canvas.parentElement.getBoundingClientRect();this.canvas.width=i.width*t,this.canvas.height=this.options.height*t,this.canvas.parentElement.style.height=this.options.height+"px",this.drawWaveform()}renderMarkers(){if(!this.markersContainer||(this.markersContainer.innerHTML="",!this.options.showMarkers||!this.options.markers?.length))return;let t=this.getSeekDuration();t&&this.options.markers.forEach((i,s)=>{if(i.time>t){console.warn(`[WaveformPlayer] Marker "${i.label}" at ${i.time}s exceeds audio duration of ${t}s`);return}let o=i.time/t*100,r=document.createElement("button");r.className="waveform-marker",r.style.left=`${o}%`,r.style.backgroundColor=i.color||"rgba(255, 255, 255, 0.5)",r.setAttribute("aria-label",i.label),r.setAttribute("data-time",i.time);let n=document.createElement("span");n.className="waveform-marker-tooltip",n.textContent=i.label,r.appendChild(n),r.addEventListener("click",a=>{a.stopPropagation(),this.seekTo(i.time),this.options.playOnSeek&&!this.isPlaying&&this.play()}),this.markersContainer.appendChild(r)})}setActiveMarker(t){if(!this.markersContainer)return;this.markersContainer.querySelectorAll(".waveform-marker").forEach((s,o)=>s.classList.toggle("active",o===t))}handleCanvasClick(t){let i=this.canvas.getBoundingClientRect(),s=t.clientX-i.left,o=w(s/i.width);if(this.options.audioMode==="external"){this._requestSeek(o);return}!this.audio||!this.audio.duration||this.seekToPercent(o)}setLoading(t){this.isLoading=t,this.loadingEl&&(this.loadingEl.style.display=t?"block":"none"),this.seekEl&&this.seekEl.setAttribute("aria-busy",t?"true":"false")}onMetadataLoaded(){this.isDestroying||(this.totalTimeEl&&(this.totalTimeEl.textContent=S(this.audio.duration)),this.renderMarkers(),this.updateSeekAccessibility())}setPlayButtonState(t){if(!this.playBtn)return;this.playBtn.classList.toggle("playing",t);let i=this.playBtn.querySelector(".waveform-icon-play"),s=this.playBtn.querySelector(".waveform-icon-pause");i&&(i.style.display=t?"none":"flex"),s&&(s.style.display=t?"flex":"none")}onPlay(){this.isDestroying||(this.isPlaying=!0,this.setPlayButtonState(!0),this.startSmoothUpdate(),this._emit("waveformplayer:play",{player:this,url:this.options.url}),this.options.onPlay&&this.options.onPlay(this))}onPause(){this.isDestroying||(this.isPlaying=!1,this.setPlayButtonState(!1),this.stopSmoothUpdate(),this._emit("waveformplayer:pause",{player:this,url:this.options.url}),this.options.onPause&&this.options.onPause(this))}onEnded(){if(this.isDestroying)return;let t=this.audio.duration;this.progress=0,this.audio.currentTime=0,this.drawWaveform(),this.currentTimeEl&&(this.currentTimeEl.textContent="0:00"),this._emit("waveformplayer:ended",{player:this,url:this.options.url,currentTime:t,duration:t}),this.onPause(),this.options.onEnd&&this.options.onEnd(this)}onError(t){this.isDestroying||(console.error("[WaveformPlayer] Audio error:",t),this.hasError=!0,this.setLoading(!1),this.errorEl&&(this.errorEl.style.display="flex"),this.canvas&&(this.canvas.style.opacity="0.2"),this.playBtn&&(this.playBtn.disabled=!0),this.options.onError&&this.options.onError(t,this))}startSmoothUpdate(){this.stopSmoothUpdate();let t=()=>{this.isPlaying&&this.audio&&this.audio.duration&&(this.updateProgress(),this.updateTimer=requestAnimationFrame(t))};this.updateTimer=requestAnimationFrame(t)}stopSmoothUpdate(){this.updateTimer&&(cancelAnimationFrame(this.updateTimer),this.updateTimer=null)}updateProgress(){if(!this.audio||!this.audio.duration)return;let t=this.audio.currentTime/this.audio.duration;Math.abs(t-this.progress)>.001&&(this.progress=t,this.drawWaveform()),this.currentTimeEl&&(this.currentTimeEl.textContent=S(this.audio.currentTime)),this._emit("waveformplayer:timeupdate",{player:this,currentTime:this.audio.currentTime,duration:this.audio.duration,progress:this.progress,url:this.options.url}),this.options.onTimeUpdate&&this.options.onTimeUpdate(this.audio.currentTime,this.audio.duration,this),this.updateSeekAccessibility()}updateBPMDisplay(){let t=this.options.bpm||this.detectedBPM;this.bpmEl&&this.bpmValueEl&&t&&(this.bpmValueEl.textContent=Math.round(t),this.bpmEl.style.display="inline-flex")}updateSpeedUI(){if(!this.audio)return;let t=this.container.querySelector(".speed-value");if(t){let i=this.audio.playbackRate;t.textContent=i===1?"1x":`${i}x`}this.container.querySelectorAll(".speed-option").forEach(i=>{i.classList.toggle("active",parseFloat(i.dataset.rate)===this.audio.playbackRate)})}play(){if(this.options.singlePlay&&e.currentlyPlaying&&e.currentlyPlaying!==this&&e.currentlyPlaying.pause(),this.options.audioMode==="external"){this._emit("waveformplayer:request-play",this._buildTrackDetail(),!0).defaultPrevented||(e.currentlyPlaying=this);return}return e.currentlyPlaying=this,this.audio.play()}pause(){if(e.currentlyPlaying===this&&(e.currentlyPlaying=null),this.options.audioMode==="external"){this._emit("waveformplayer:request-pause",this._buildTrackDetail(),!0);return}this.audio.pause()}_buildTrackDetail(){return{url:this.options.url,title:this.options.title,subtitle:this.options.subtitle,artist:this.options.artist||this.options.subtitle,artwork:this.options.artwork,markers:this.options.markers,waveform:this.options.waveform,id:this.id,player:this}}setPlayingState(t){let i=this.isPlaying;this.isPlaying=!!t,this.setPlayButtonState(this.isPlaying),this.isPlaying&&!i?(this.startSmoothUpdate?.(),this._emit("waveformplayer:play",{player:this,url:this.options.url}),this.options.onPlay&&this.options.onPlay(this)):!this.isPlaying&&i&&(this.stopSmoothUpdate?.(),this._emit("waveformplayer:pause",{player:this,url:this.options.url}),this.options.onPause&&this.options.onPause(this))}setProgress(t,i){!i||i<=0||(this.progress=w(t/i),this.currentTimeEl&&(this.currentTimeEl.textContent=S(t)),this._extDuration=i,this.totalTimeEl&&(!this.totalTimeEl.dataset._extSet||this.totalTimeEl.dataset._extDur!==String(i))&&(this.totalTimeEl.textContent=S(i),this.totalTimeEl.dataset._extSet="1",this.totalTimeEl.dataset._extDur=String(i)),this.drawWaveform?.(),this._emit("waveformplayer:timeupdate",{player:this,currentTime:t,duration:i,progress:this.progress,url:this.options.url}),this.options.onTimeUpdate&&this.options.onTimeUpdate(t,i,this),this.progress>=1?this._extEnded||(this._extEnded=!0,this._emit("waveformplayer:ended",{player:this,url:this.options.url,currentTime:i,duration:i}),this.options.onEnd&&this.options.onEnd(this)):this._extEnded=!1,this.updateSeekAccessibility())}togglePlay(){this.isPlaying?this.pause():this.play()}seekTo(t){this.audio&&this.audio.duration&&(this.audio.currentTime=w(t,0,this.audio.duration),this.updateProgress())}seekToPercent(t){this.audio&&this.audio.duration&&(this.audio.currentTime=this.audio.duration*w(t),this.updateProgress())}setVolume(t){let i=Number(t);this.audio&&Number.isFinite(i)&&(this.audio.volume=w(i))}setPlaybackRate(t){if(!this.audio)return;let i=w(t,.5,2);this.audio.playbackRate=i,this.options.playbackRate=i,this.updateSpeedUI()}destroy(){this.isDestroying=!0,this._emit("waveformplayer:destroy",{player:this,url:this.options.url}),this.pause(),this.stopSmoothUpdate(),this._ac?.abort(),this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null),this.resizeHandler&&(window.removeEventListener("resize",this.resizeHandler),this.resizeHandler=null),e.instances.delete(this.id),e.currentlyPlaying===this&&(e.currentlyPlaying=null),this.audio&&(this.audio.pause(),this.audio.src="",this.audio.load(),this.audio=null),this.container.innerHTML="",this.canvas=null,this.ctx=null,this.playBtn=null,this.waveformData=[]}static getInstance(t){if(typeof t=="string"){let i=this.instances.get(t);if(i)return i;let s=document.getElementById(t);if(s)return Array.from(this.instances.values()).find(o=>o.container===s)}if(t instanceof HTMLElement)return Array.from(this.instances.values()).find(i=>i.container===t)}static getAllInstances(){return Array.from(this.instances.values())}static destroyAll(){this.instances.forEach(t=>t.destroy()),this.instances.clear()}static async generateWaveformData(t,i=200){try{return(await B(t,i)).peaks}catch(s){throw console.error("[WaveformPlayer] Failed to generate waveform:",s),s}}static getPeaksUrl(t){if(!t)return;let i=t.replace(/\.(mp3|wav|ogg|flac|m4a|aac)(\?[^#]*)?(#.*)?$/i,".json$2$3");return i===t?void 0:i}};C.utils={formatTime:S,extractTitleFromUrl:x,escapeHtml:A,isSafeHref:_,parseDataAttributes:L};var $=()=>typeof window<"u"&&typeof document<"u";function I(){if(!$())return;document.querySelectorAll("[data-waveform-player]").forEach(t=>{if(t.dataset.waveformInitialized!=="true")try{new C(t),t.dataset.waveformInitialized="true"}catch(i){console.error("[WaveformPlayer] Failed to initialize:",i,t)}})}$()&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",I):I());C.init=I;$()&&(window.WaveformPlayer=C);var Lt=C;})();