[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/js/dist/script-modules/block-library/playlist/ -> view.js (source)

   1  // packages/block-library/build-module/playlist/view.mjs
   2  import { store, getContext, getElement } from "@wordpress/interactivity";
   3  
   4  // node_modules/colord/index.mjs
   5  var r = { grad: 0.9, turn: 360, rad: 360 / (2 * Math.PI) };
   6  var t = function(r2) {
   7    return "string" == typeof r2 ? r2.length > 0 : "number" == typeof r2;
   8  };
   9  var n = function(r2, t2, n2) {
  10    return void 0 === t2 && (t2 = 0), void 0 === n2 && (n2 = Math.pow(10, t2)), Math.round(n2 * r2) / n2 + 0;
  11  };
  12  var e = function(r2, t2, n2) {
  13    return void 0 === t2 && (t2 = 0), void 0 === n2 && (n2 = 1), r2 > n2 ? n2 : r2 > t2 ? r2 : t2;
  14  };
  15  var u = function(r2) {
  16    return (r2 = isFinite(r2) ? r2 % 360 : 0) > 0 ? r2 : r2 + 360;
  17  };
  18  var a = function(r2) {
  19    return { r: e(r2.r, 0, 255), g: e(r2.g, 0, 255), b: e(r2.b, 0, 255), a: e(r2.a) };
  20  };
  21  var o = function(r2) {
  22    return { r: n(r2.r), g: n(r2.g), b: n(r2.b), a: n(r2.a, 3) };
  23  };
  24  var i = /^#([0-9a-f]{3,8})$/i;
  25  var s = function(r2) {
  26    var t2 = r2.toString(16);
  27    return t2.length < 2 ? "0" + t2 : t2;
  28  };
  29  var h = function(r2) {
  30    var t2 = r2.r, n2 = r2.g, e3 = r2.b, u2 = r2.a, a2 = Math.max(t2, n2, e3), o2 = a2 - Math.min(t2, n2, e3), i2 = o2 ? a2 === t2 ? (n2 - e3) / o2 : a2 === n2 ? 2 + (e3 - t2) / o2 : 4 + (t2 - n2) / o2 : 0;
  31    return { h: 60 * (i2 < 0 ? i2 + 6 : i2), s: a2 ? o2 / a2 * 100 : 0, v: a2 / 255 * 100, a: u2 };
  32  };
  33  var b = function(r2) {
  34    var t2 = r2.h, n2 = r2.s, e3 = r2.v, u2 = r2.a;
  35    t2 = t2 / 360 * 6, n2 /= 100, e3 /= 100;
  36    var a2 = Math.floor(t2), o2 = e3 * (1 - n2), i2 = e3 * (1 - (t2 - a2) * n2), s2 = e3 * (1 - (1 - t2 + a2) * n2), h2 = a2 % 6;
  37    return { r: 255 * [e3, i2, o2, o2, s2, e3][h2], g: 255 * [s2, e3, e3, i2, o2, o2][h2], b: 255 * [o2, o2, s2, e3, e3, i2][h2], a: u2 };
  38  };
  39  var g = function(r2) {
  40    return { h: u(r2.h), s: e(r2.s, 0, 100), l: e(r2.l, 0, 100), a: e(r2.a) };
  41  };
  42  var d = function(r2) {
  43    return { h: n(r2.h), s: n(r2.s), l: n(r2.l), a: n(r2.a, 3) };
  44  };
  45  var f = function(r2) {
  46    return b((n2 = (t2 = r2).s, { h: t2.h, s: (n2 *= ((e3 = t2.l) < 50 ? e3 : 100 - e3) / 100) > 0 ? 2 * n2 / (e3 + n2) * 100 : 0, v: e3 + n2, a: t2.a }));
  47    var t2, n2, e3;
  48  };
  49  var c = function(r2) {
  50    return { h: (t2 = h(r2)).h, s: (u2 = (200 - (n2 = t2.s)) * (e3 = t2.v) / 100) > 0 && u2 < 200 ? n2 * e3 / 100 / (u2 <= 100 ? u2 : 200 - u2) * 100 : 0, l: u2 / 2, a: t2.a };
  51    var t2, n2, e3, u2;
  52  };
  53  var l = /^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s*,\s*([+-]?\d*\.?\d+)%\s*,\s*([+-]?\d*\.?\d+)%\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i;
  54  var p = /^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s+([+-]?\d*\.?\d+)%\s+([+-]?\d*\.?\d+)%\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i;
  55  var v = /^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i;
  56  var m = /^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i;
  57  var y = { string: [[function(r2) {
  58    var t2 = i.exec(r2);
  59    return t2 ? (r2 = t2[1]).length <= 4 ? { r: parseInt(r2[0] + r2[0], 16), g: parseInt(r2[1] + r2[1], 16), b: parseInt(r2[2] + r2[2], 16), a: 4 === r2.length ? n(parseInt(r2[3] + r2[3], 16) / 255, 2) : 1 } : 6 === r2.length || 8 === r2.length ? { r: parseInt(r2.substr(0, 2), 16), g: parseInt(r2.substr(2, 2), 16), b: parseInt(r2.substr(4, 2), 16), a: 8 === r2.length ? n(parseInt(r2.substr(6, 2), 16) / 255, 2) : 1 } : null : null;
  60  }, "hex"], [function(r2) {
  61    var t2 = v.exec(r2) || m.exec(r2);
  62    return t2 ? t2[2] !== t2[4] || t2[4] !== t2[6] ? null : a({ r: Number(t2[1]) / (t2[2] ? 100 / 255 : 1), g: Number(t2[3]) / (t2[4] ? 100 / 255 : 1), b: Number(t2[5]) / (t2[6] ? 100 / 255 : 1), a: void 0 === t2[7] ? 1 : Number(t2[7]) / (t2[8] ? 100 : 1) }) : null;
  63  }, "rgb"], [function(t2) {
  64    var n2 = l.exec(t2) || p.exec(t2);
  65    if (!n2) return null;
  66    var e3, u2, a2 = g({ h: (e3 = n2[1], u2 = n2[2], void 0 === u2 && (u2 = "deg"), Number(e3) * (r[u2] || 1)), s: Number(n2[3]), l: Number(n2[4]), a: void 0 === n2[5] ? 1 : Number(n2[5]) / (n2[6] ? 100 : 1) });
  67    return f(a2);
  68  }, "hsl"]], object: [[function(r2) {
  69    var n2 = r2.r, e3 = r2.g, u2 = r2.b, o2 = r2.a, i2 = void 0 === o2 ? 1 : o2;
  70    return t(n2) && t(e3) && t(u2) ? a({ r: Number(n2), g: Number(e3), b: Number(u2), a: Number(i2) }) : null;
  71  }, "rgb"], [function(r2) {
  72    var n2 = r2.h, e3 = r2.s, u2 = r2.l, a2 = r2.a, o2 = void 0 === a2 ? 1 : a2;
  73    if (!t(n2) || !t(e3) || !t(u2)) return null;
  74    var i2 = g({ h: Number(n2), s: Number(e3), l: Number(u2), a: Number(o2) });
  75    return f(i2);
  76  }, "hsl"], [function(r2) {
  77    var n2 = r2.h, a2 = r2.s, o2 = r2.v, i2 = r2.a, s2 = void 0 === i2 ? 1 : i2;
  78    if (!t(n2) || !t(a2) || !t(o2)) return null;
  79    var h2 = (function(r3) {
  80      return { h: u(r3.h), s: e(r3.s, 0, 100), v: e(r3.v, 0, 100), a: e(r3.a) };
  81    })({ h: Number(n2), s: Number(a2), v: Number(o2), a: Number(s2) });
  82    return b(h2);
  83  }, "hsv"]] };
  84  var N = function(r2, t2) {
  85    for (var n2 = 0; n2 < t2.length; n2++) {
  86      var e3 = t2[n2][0](r2);
  87      if (e3) return [e3, t2[n2][1]];
  88    }
  89    return [null, void 0];
  90  };
  91  var x = function(r2) {
  92    return "string" == typeof r2 ? N(r2.trim(), y.string) : "object" == typeof r2 && null !== r2 ? N(r2, y.object) : [null, void 0];
  93  };
  94  var M = function(r2, t2) {
  95    var n2 = c(r2);
  96    return { h: n2.h, s: e(n2.s + 100 * t2, 0, 100), l: n2.l, a: n2.a };
  97  };
  98  var H = function(r2) {
  99    return (299 * r2.r + 587 * r2.g + 114 * r2.b) / 1e3 / 255;
 100  };
 101  var $ = function(r2, t2) {
 102    var n2 = c(r2);
 103    return { h: n2.h, s: n2.s, l: e(n2.l + 100 * t2, 0, 100), a: n2.a };
 104  };
 105  var j = (function() {
 106    function r2(r3) {
 107      this.parsed = x(r3)[0], this.rgba = this.parsed || { r: 0, g: 0, b: 0, a: 1 };
 108    }
 109    return r2.prototype.isValid = function() {
 110      return null !== this.parsed;
 111    }, r2.prototype.brightness = function() {
 112      return n(H(this.rgba), 2);
 113    }, r2.prototype.isDark = function() {
 114      return H(this.rgba) < 0.5;
 115    }, r2.prototype.isLight = function() {
 116      return H(this.rgba) >= 0.5;
 117    }, r2.prototype.toHex = function() {
 118      return r3 = o(this.rgba), t2 = r3.r, e3 = r3.g, u2 = r3.b, i2 = (a2 = r3.a) < 1 ? s(n(255 * a2)) : "", "#" + s(t2) + s(e3) + s(u2) + i2;
 119      var r3, t2, e3, u2, a2, i2;
 120    }, r2.prototype.toRgb = function() {
 121      return o(this.rgba);
 122    }, r2.prototype.toRgbString = function() {
 123      return r3 = o(this.rgba), t2 = r3.r, n2 = r3.g, e3 = r3.b, (u2 = r3.a) < 1 ? "rgba(" + t2 + ", " + n2 + ", " + e3 + ", " + u2 + ")" : "rgb(" + t2 + ", " + n2 + ", " + e3 + ")";
 124      var r3, t2, n2, e3, u2;
 125    }, r2.prototype.toHsl = function() {
 126      return d(c(this.rgba));
 127    }, r2.prototype.toHslString = function() {
 128      return r3 = d(c(this.rgba)), t2 = r3.h, n2 = r3.s, e3 = r3.l, (u2 = r3.a) < 1 ? "hsla(" + t2 + ", " + n2 + "%, " + e3 + "%, " + u2 + ")" : "hsl(" + t2 + ", " + n2 + "%, " + e3 + "%)";
 129      var r3, t2, n2, e3, u2;
 130    }, r2.prototype.toHsv = function() {
 131      return r3 = h(this.rgba), { h: n(r3.h), s: n(r3.s), v: n(r3.v), a: n(r3.a, 3) };
 132      var r3;
 133    }, r2.prototype.invert = function() {
 134      return w({ r: 255 - (r3 = this.rgba).r, g: 255 - r3.g, b: 255 - r3.b, a: r3.a });
 135      var r3;
 136    }, r2.prototype.saturate = function(r3) {
 137      return void 0 === r3 && (r3 = 0.1), w(M(this.rgba, r3));
 138    }, r2.prototype.desaturate = function(r3) {
 139      return void 0 === r3 && (r3 = 0.1), w(M(this.rgba, -r3));
 140    }, r2.prototype.grayscale = function() {
 141      return w(M(this.rgba, -1));
 142    }, r2.prototype.lighten = function(r3) {
 143      return void 0 === r3 && (r3 = 0.1), w($(this.rgba, r3));
 144    }, r2.prototype.darken = function(r3) {
 145      return void 0 === r3 && (r3 = 0.1), w($(this.rgba, -r3));
 146    }, r2.prototype.rotate = function(r3) {
 147      return void 0 === r3 && (r3 = 15), this.hue(this.hue() + r3);
 148    }, r2.prototype.alpha = function(r3) {
 149      return "number" == typeof r3 ? w({ r: (t2 = this.rgba).r, g: t2.g, b: t2.b, a: r3 }) : n(this.rgba.a, 3);
 150      var t2;
 151    }, r2.prototype.hue = function(r3) {
 152      var t2 = c(this.rgba);
 153      return "number" == typeof r3 ? w({ h: r3, s: t2.s, l: t2.l, a: t2.a }) : n(t2.h);
 154    }, r2.prototype.isEqual = function(r3) {
 155      return this.toHex() === w(r3).toHex();
 156    }, r2;
 157  })();
 158  var w = function(r2) {
 159    return r2 instanceof j ? r2 : new j(r2);
 160  };
 161  
 162  // node_modules/@arraypress/waveform-player/dist/waveform-player.esm.js
 163  function $2(e3) {
 164    let t2 = -1 / 0;
 165    for (let i2 = 0; i2 < e3.length; i2++) e3[i2] > t2 && (t2 = e3[i2]);
 166    return t2;
 167  }
 168  function S(e3) {
 169    return String(e3 ?? "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
 170  }
 171  function q(e3) {
 172    return S(typeof e3 == "number" ? `$e3}px` : e3);
 173  }
 174  function st(e3) {
 175    if (typeof e3 != "string" || e3 === "") return false;
 176    try {
 177      let t2 = new URL(e3, "http://localhost/");
 178      return t2.protocol === "http:" || t2.protocol === "https:";
 179    } catch {
 180      return false;
 181    }
 182  }
 183  function m2(e3, t2 = 0, i2 = 1) {
 184    return Math.max(t2, Math.min(e3, i2));
 185  }
 186  function _(e3, t2 = null, i2 = {}) {
 187    let { min: s2 = -1 / 0, max: r2 = 1 / 0, integer: a2 = false } = i2, o2 = typeof e3 == "number" ? e3 : typeof e3 == "string" && e3.trim() !== "" ? Number(e3) : NaN;
 188    if (!Number.isFinite(o2)) return t2;
 189    let n2 = m2(o2, s2, r2);
 190    return a2 ? Math.round(n2) : n2;
 191  }
 192  function H2(e3, t2 = null) {
 193    if (Array.isArray(e3)) return e3;
 194    if (typeof e3 == "string" && e3.trim().startsWith("[")) try {
 195      let i2 = JSON.parse(e3);
 196      if (Array.isArray(i2)) return i2;
 197    } catch {
 198    }
 199    return t2;
 200  }
 201  function D(e3, t2 = {}) {
 202    let { min: i2 = -1 / 0, max: s2 = 1 / 0, fallback: r2 = null } = t2, a2 = H2(e3);
 203    if (!a2 && typeof e3 == "string" && e3.trim() !== "" && (a2 = e3.split(/[,\s]+/)), !a2) return r2;
 204    let o2 = a2.map((n2) => _(n2)).filter((n2) => n2 !== null && n2 >= i2 && n2 <= s2);
 205    return o2.length ? o2 : r2;
 206  }
 207  function rt(e3, t2, i2 = null) {
 208    return t2.includes(e3) ? e3 : i2;
 209  }
 210  function at(e3) {
 211    if (typeof e3 == "string") {
 212      let t2 = e3.trim().toLowerCase();
 213      return t2 !== "" && t2 !== "false" && t2 !== "0";
 214    }
 215    return !!e3;
 216  }
 217  function vt(e3) {
 218    return e3 === void 0 ? void 0 : e3 === "true";
 219  }
 220  function it(e3) {
 221    if (typeof e3 == "string" && e3.trim().startsWith("[")) try {
 222      return JSON.parse(e3);
 223    } catch {
 224    }
 225    return e3;
 226  }
 227  function O(e3) {
 228    let t2 = {}, i2 = (o2, n2 = o2) => {
 229      let l2 = vt(e3.dataset[n2]);
 230      l2 !== void 0 && (t2[o2] = l2);
 231    }, s2 = (o2, n2 = o2, l2 = false) => {
 232      let h2 = e3.dataset[n2];
 233      h2 && (t2[o2] = l2 ? parseFloat(h2) : parseInt(h2, 10));
 234    }, r2 = (o2, n2 = o2) => {
 235      let l2 = e3.dataset[n2];
 236      l2 && (t2[o2] = /^\d+(\.\d+)?$/.test(l2.trim()) ? parseFloat(l2) : l2);
 237    }, a2 = (o2, n2 = o2) => {
 238      let l2 = e3.dataset[n2];
 239      if (!l2) return;
 240      let h2 = H2(l2);
 241      h2 ? t2[o2] = h2 : console.warn(`[WaveformPlayer] Invalid $n2} attribute, expected a JSON array:`, l2);
 242    };
 243    if (e3.dataset.src && (t2.url = e3.dataset.src), e3.dataset.url && (t2.url = e3.dataset.url), s2("height"), s2("samples"), e3.dataset.preload && (t2.preload = e3.dataset.preload), e3.dataset.crossOrigin && (t2.crossOrigin = e3.dataset.crossOrigin), e3.dataset.audioMode && (t2.audioMode = e3.dataset.audioMode), e3.dataset.style && (t2.waveformStyle = e3.dataset.style), e3.dataset.waveformStyle && (t2.waveformStyle = e3.dataset.waveformStyle), e3.dataset.waveformGradient && (t2.waveformGradient = e3.dataset.waveformGradient), s2("barWidth"), s2("barSpacing"), s2("barRadius"), e3.dataset.buttonAlign && (t2.buttonAlign = e3.dataset.buttonAlign), e3.dataset.layout && (t2.layout = e3.dataset.layout), e3.dataset.buttonStyle && (t2.buttonStyle = e3.dataset.buttonStyle), r2("buttonSize"), r2("buttonRadius"), e3.dataset.colorPreset && (t2.colorPreset = e3.dataset.colorPreset), e3.dataset.waveformColor && (t2.waveformColor = it(e3.dataset.waveformColor)), e3.dataset.progressColor && (t2.progressColor = it(e3.dataset.progressColor)), e3.dataset.color && (t2.waveformColor = e3.dataset.color), e3.dataset.theme && (t2.colorPreset = e3.dataset.theme), i2("autoplay"), i2("showControls"), i2("showInfo"), i2("showTime"), i2("showHoverTime"), i2("seekHandle"), i2("showBPM", "showBpm"), s2("bpm"), i2("singlePlay"), i2("playOnSeek"), e3.dataset.title && (t2.title = e3.dataset.title), e3.dataset.artist && (t2.artist = e3.dataset.artist), e3.dataset.album && (t2.album = e3.dataset.album), e3.dataset.artwork && (t2.artwork = e3.dataset.artwork), e3.dataset.artworkPosition && (t2.artworkPosition = e3.dataset.artworkPosition), e3.dataset.waveform && (t2.waveform = e3.dataset.waveform), a2("markers"), s2("playbackRate", "playbackRate", true), i2("showPlaybackSpeed"), e3.dataset.playbackRates) {
 244      let o2 = D(e3.dataset.playbackRates);
 245      o2 ? t2.playbackRates = o2 : console.warn("[WaveformPlayer] Invalid playbackRates attribute:", e3.dataset.playbackRates);
 246    }
 247    return i2("enableMediaSession"), i2("showMarkers"), i2("accessibleSeek"), e3.dataset.seekLabel && (t2.seekLabel = e3.dataset.seekLabel), e3.dataset.seekValueText && (t2.seekValueText = e3.dataset.seekValueText), e3.dataset.errorText && (t2.errorText = e3.dataset.errorText), e3.dataset.playPauseLabel && (t2.playPauseLabel = e3.dataset.playPauseLabel), e3.dataset.speedLabel && (t2.speedLabel = e3.dataset.speedLabel), e3.dataset.artworkAlt && (t2.artworkAlt = e3.dataset.artworkAlt), e3.dataset.unknownTrackText && (t2.unknownTrackText = e3.dataset.unknownTrackText), t2;
 248  }
 249  function ot(e3, ...t2) {
 250    let i2 = 0;
 251    return e3.replace(/%(?:(\d+)\$)?s/g, (s2, r2) => {
 252      let a2 = r2 ? Number(r2) - 1 : i2++;
 253      return t2[a2] ?? s2;
 254    });
 255  }
 256  function E(e3) {
 257    let t2 = Number(e3);
 258    if (!t2 || !Number.isFinite(t2) || t2 < 0) return "0:00";
 259    let i2 = Math.floor(t2 / 3600), s2 = Math.floor(t2 % 3600 / 60), r2 = Math.floor(t2 % 60);
 260    return i2 > 0 ? `$i2}:$s2.toString().padStart(2, "0")}:$r2.toString().padStart(2, "0")}` : `$s2}:$r2.toString().padStart(2, "0")}`;
 261  }
 262  var St = 0;
 263  function nt(e3) {
 264    let t2 = e3 || "audio", i2 = 5381;
 265    for (let s2 = 0; s2 < t2.length; s2++) i2 = (i2 << 5) + i2 + t2.charCodeAt(s2) | 0;
 266    return `wp_${(i2 >>> 0).toString(36)}_${(St++).toString(36)}`;
 267  }
 268  function I(e3) {
 269    if (!e3) return "Audio";
 270    let t2 = e3.split("/");
 271    return t2[t2.length - 1].split(".")[0].replace(/[-_]/g, " ").replace(/\b\w/g, (r2) => r2.toUpperCase());
 272  }
 273  function U(e3) {
 274    if (typeof e3 != "string") return null;
 275    let t2 = e3.match(/rgba?\(\s*([\d.]+)\s*[,\s]\s*([\d.]+)\s*[,\s]\s*([\d.]+)\s*(?:[,/]\s*([\d.]+)(%?))?/i);
 276    if (!t2) return null;
 277    let i2 = Number(t2[1]), s2 = Number(t2[2]), r2 = Number(t2[3]);
 278    if (!Number.isFinite(i2) || !Number.isFinite(s2) || !Number.isFinite(r2)) return null;
 279    let a2 = t2[4] === void 0 ? 1 : Number(t2[4]);
 280    return Number.isFinite(a2) ? (t2[5] === "%" && (a2 /= 100), { r: i2, g: s2, b: r2, a: m2(a2, 0, 1) }) : null;
 281  }
 282  function lt(e3) {
 283    let t2 = U(e3);
 284    return !t2 || t2.a <= 0 ? null : (t2.r * 299 + t2.g * 587 + t2.b * 114) / 1e3;
 285  }
 286  function j2(...e3) {
 287    let t2 = {};
 288    for (let i2 of e3) for (let s2 in i2) i2[s2] !== null && i2[s2] !== void 0 && (t2[s2] = i2[s2]);
 289    return t2;
 290  }
 291  function ht(e3, t2) {
 292    let i2;
 293    return function(...r2) {
 294      let a2 = () => {
 295        clearTimeout(i2), e3(...r2);
 296      };
 297      clearTimeout(i2), i2 = setTimeout(a2, t2);
 298    };
 299  }
 300  function B(e3, t2) {
 301    if (e3.length === t2) return e3;
 302    if (e3.length === 0 || t2 === 0) return [];
 303    let i2 = [];
 304    if (t2 > e3.length) {
 305      let s2 = (e3.length - 1) / (t2 - 1);
 306      for (let r2 = 0; r2 < t2; r2++) {
 307        let a2 = r2 * s2, o2 = Math.floor(a2), n2 = Math.ceil(a2), l2 = a2 - o2;
 308        if (n2 >= e3.length) i2.push(e3[e3.length - 1]);
 309        else if (o2 === n2) i2.push(e3[o2]);
 310        else {
 311          let h2 = e3[o2] * (1 - l2) + e3[n2] * l2;
 312          i2.push(h2);
 313        }
 314      }
 315    } else {
 316      let s2 = e3.length / t2;
 317      for (let r2 = 0; r2 < t2; r2++) {
 318        let a2 = Math.floor(r2 * s2), o2 = Math.floor((r2 + 1) * s2), n2 = 0, l2 = 0;
 319        for (let h2 = a2; h2 <= o2 && h2 < e3.length; h2++) e3[h2] > n2 && (n2 = e3[h2]), l2++;
 320        if (l2 === 0) {
 321          let h2 = Math.min(Math.round(r2 * s2), e3.length - 1);
 322          n2 = e3[h2];
 323        }
 324        i2.push(n2);
 325      }
 326    }
 327    return i2;
 328  }
 329  function P(e3, t2, i2, s2) {
 330    if (!Array.isArray(t2)) return t2;
 331    if (t2.length < 2) return t2[0];
 332    let r2 = i2.width, a2 = i2.height, o2 = s2 && s2.waveformGradient, [n2, l2, h2, c2] = o2 === "horizontal" ? [0, 0, r2, 0] : o2 === "diagonal" ? [0, 0, r2, a2] : [0, 0, 0, a2];
 333    try {
 334      let d2 = e3.createLinearGradient(n2, l2, h2, c2);
 335      return t2.forEach((b2, y2) => d2.addColorStop(y2 / (t2.length - 1), b2)), d2;
 336    } catch {
 337      return t2[0];
 338    }
 339  }
 340  function x2(e3, t2, i2, s2, r2, a2) {
 341    if ((Array.isArray(a2) ? a2.some((n2) => n2 > 0) : a2 > 0) && typeof e3.roundRect == "function") {
 342      let n2 = Math.min(s2 / 2, Math.abs(r2) / 2), l2 = (h2) => m2(h2, 0, n2);
 343      e3.beginPath(), e3.roundRect(t2, i2, s2, r2, Array.isArray(a2) ? a2.map(l2) : l2(a2)), e3.fill();
 344    } else e3.fillRect(t2, i2, s2, r2);
 345  }
 346  function pt(e3, t2) {
 347    return (e3.barRadius || 0) * t2;
 348  }
 349  function Et(e3, t2) {
 350    let i2 = pt(e3, t2);
 351    return [i2, i2, 0, 0];
 352  }
 353  function ct(e3, t2, i2, s2, r2) {
 354    let a2 = r2 / 2;
 355    e3.beginPath(), e3.moveTo(t2, s2 - a2), e3.lineTo(i2 - a2, s2 - a2), e3.arc(i2 - a2, s2, a2, -Math.PI / 2, Math.PI / 2), e3.lineTo(t2, s2 + a2), e3.arc(t2, s2, a2, Math.PI / 2, -Math.PI / 2), e3.closePath();
 356  }
 357  function V(e3, t2, i2, s2, r2) {
 358    let a2 = window.devicePixelRatio || 1, o2 = r2.barWidth * a2, n2 = r2.barSpacing * a2, l2 = Math.floor(t2.width / (o2 + n2)), h2 = B(i2, l2), c2 = t2.height, d2 = s2 * t2.width, b2 = Et(r2, a2), y2 = P(e3, r2.color, t2, r2), w2 = P(e3, r2.progressColor, t2, r2);
 359    e3.clearRect(0, 0, t2.width, t2.height), e3.fillStyle = y2;
 360    for (let f2 = 0; f2 < h2.length; f2++) {
 361      let p2 = f2 * (o2 + n2);
 362      if (p2 + o2 > t2.width) break;
 363      let g2 = h2[f2] * c2 * 0.9, u2 = c2 - g2;
 364      x2(e3, p2, u2, o2, g2, b2);
 365    }
 366    e3.save(), e3.beginPath(), e3.rect(0, 0, d2, c2), e3.clip(), e3.fillStyle = w2;
 367    for (let f2 = 0; f2 < h2.length; f2++) {
 368      let p2 = f2 * (o2 + n2);
 369      if (p2 > d2) break;
 370      let g2 = h2[f2] * c2 * 0.9, u2 = c2 - g2;
 371      x2(e3, p2, u2, o2, g2, b2);
 372    }
 373    e3.restore();
 374  }
 375  function Pt(e3, t2, i2, s2, r2) {
 376    let a2 = window.devicePixelRatio || 1, o2 = r2.barWidth * a2, n2 = r2.barSpacing * a2, l2 = Math.floor(t2.width / (o2 + n2)), h2 = B(i2, l2), c2 = t2.height, d2 = c2 / 2, b2 = s2 * t2.width, y2 = pt(r2, a2), w2 = [y2, y2, 0, 0], f2 = [0, 0, y2, y2], p2 = P(e3, r2.color, t2, r2), g2 = P(e3, r2.progressColor, t2, r2);
 377    e3.clearRect(0, 0, t2.width, t2.height), e3.fillStyle = p2;
 378    for (let u2 = 0; u2 < h2.length; u2++) {
 379      let k = u2 * (o2 + n2);
 380      if (k + o2 > t2.width) break;
 381      let v2 = h2[u2] * c2 * 0.45;
 382      x2(e3, k, d2 - v2, o2, v2, w2), x2(e3, k, d2, o2, v2, f2);
 383    }
 384    e3.save(), e3.beginPath(), e3.rect(0, 0, b2, c2), e3.clip(), e3.fillStyle = g2;
 385    for (let u2 = 0; u2 < h2.length; u2++) {
 386      let k = u2 * (o2 + n2);
 387      if (k > b2) break;
 388      let v2 = h2[u2] * c2 * 0.45;
 389      x2(e3, k, d2 - v2, o2, v2, w2), x2(e3, k, d2, o2, v2, f2);
 390    }
 391    e3.restore();
 392  }
 393  function Tt(e3, t2, i2, s2, r2) {
 394    let a2 = t2.width, o2 = t2.height, n2 = o2 / 2, l2 = o2 * 0.35;
 395    e3.clearRect(0, 0, a2, o2);
 396    let h2 = (c2, d2, b2 = 1, y2 = false) => {
 397      let w2 = P(e3, c2, t2, r2), f2 = Array.isArray(c2) ? c2[c2.length - 1] : c2;
 398      y2 && (e3.shadowBlur = 12, e3.shadowColor = f2), e3.strokeStyle = w2, e3.lineWidth = d2, e3.lineCap = "round", e3.lineJoin = "round", e3.beginPath(), e3.moveTo(0, n2);
 399      let p2 = [], g2 = Math.floor(i2.length * b2);
 400      for (let u2 = 0; u2 < g2; u2++) {
 401        let k = u2 / (i2.length - 1) * a2, v2 = i2[u2], A = Math.sin(u2 * 0.1) * v2, L = n2 + A * l2;
 402        p2.push({ x: k, y: L });
 403      }
 404      for (let u2 = 0; u2 < p2.length - 1; u2++) {
 405        let k = p2[u2].x + (p2[u2 + 1].x - p2[u2].x) * 0.5, v2 = p2[u2].y, A = p2[u2 + 1].x - (p2[u2 + 1].x - p2[u2].x) * 0.5, L = p2[u2 + 1].y;
 406        e3.bezierCurveTo(k, v2, A, L, p2[u2 + 1].x, p2[u2 + 1].y);
 407      }
 408      e3.stroke(), y2 && (e3.shadowBlur = 0);
 409    };
 410    e3.strokeStyle = "rgba(255, 255, 255, 0.03)", e3.lineWidth = 0.5, e3.beginPath(), e3.moveTo(0, n2), e3.lineTo(a2, n2), e3.stroke();
 411    for (let c2 = 0; c2 <= 10; c2++) {
 412      let d2 = a2 / 10 * c2;
 413      e3.beginPath(), e3.moveTo(d2, 0), e3.lineTo(d2, o2), e3.stroke();
 414    }
 415    h2(r2.color, 2, 1, false), s2 > 0 && h2(r2.progressColor, 3, s2, true);
 416  }
 417  function ut(e3, t2, i2, s2, r2) {
 418    let a2 = window.devicePixelRatio || 1, o2 = (r2.barWidth || 3) * a2, n2 = (r2.barSpacing || 1) * a2, l2 = Math.floor(t2.width / (o2 + n2)), h2 = B(i2, l2), c2 = t2.height, d2 = 4 * a2, b2 = 2 * a2, y2 = s2 * t2.width, w2 = c2 / 2, f2 = P(e3, r2.color, t2, r2), p2 = P(e3, r2.progressColor, t2, r2);
 419    e3.clearRect(0, 0, t2.width, t2.height);
 420    for (let g2 = 0; g2 < h2.length; g2++) {
 421      let u2 = g2 * (o2 + n2);
 422      if (u2 + o2 > t2.width) break;
 423      let k = h2[g2] * c2 * 0.9, v2 = Math.floor(k / (d2 + b2));
 424      e3.fillStyle = u2 < y2 ? p2 : f2;
 425      for (let A = 0; A < v2; A++) {
 426        let L = A * (d2 + b2);
 427        e3.fillRect(u2, w2 - L - d2, o2, d2), A > 0 && e3.fillRect(u2, w2 + L, o2, d2);
 428      }
 429    }
 430  }
 431  function dt(e3, t2, i2, s2, r2) {
 432    let a2 = window.devicePixelRatio || 1, o2 = (r2.barWidth || 2) * a2, n2 = (r2.barSpacing || 3) * a2, l2 = Math.floor(t2.width / (o2 + n2)), h2 = B(i2, l2), c2 = t2.height, d2 = Math.max(1.5 * a2, o2 / 2), b2 = s2 * t2.width, y2 = c2 / 2, w2 = P(e3, r2.color, t2, r2), f2 = P(e3, r2.progressColor, t2, r2);
 433    e3.clearRect(0, 0, t2.width, t2.height);
 434    for (let p2 = 0; p2 < h2.length; p2++) {
 435      let g2 = p2 * (o2 + n2) + o2 / 2;
 436      if (g2 > t2.width) break;
 437      let u2 = h2[p2] * c2 * 0.9;
 438      e3.fillStyle = g2 < b2 ? f2 : w2, e3.beginPath(), e3.arc(g2, y2 - u2 / 2, d2, 0, Math.PI * 2), e3.fill(), e3.beginPath(), e3.arc(g2, y2 + u2 / 2, d2, 0, Math.PI * 2), e3.fill();
 439    }
 440  }
 441  function At(e3, t2, i2, s2, r2) {
 442    let a2 = t2.width, o2 = t2.height, n2 = o2 / 2, l2 = 4, h2 = l2 / 2, c2 = !!r2.seekActive;
 443    if (e3.clearRect(0, 0, a2, o2), e3.fillStyle = P(e3, r2.color, t2, r2) || "rgba(255, 255, 255, 0.2)", ct(e3, h2, a2, n2, l2), e3.fill(), s2 > 0) {
 444      let d2 = Math.max(h2 * 2, s2 * a2);
 445      e3.save(), e3.globalAlpha = r2.seekHandle && !c2 ? 0.7 : 1, e3.fillStyle = P(e3, r2.progressColor, t2, r2) || "rgba(255, 255, 255, 0.9)", ct(e3, h2, d2, n2, l2), e3.fill(), e3.restore();
 446    }
 447  }
 448  var Mt = { bars: V, bar: V, mirror: Pt, line: Tt, blocks: ut, block: ut, dots: dt, dot: dt, seekbar: At };
 449  function ft(e3, t2, i2, s2, r2) {
 450    (Mt[r2.waveformStyle] || V)(e3, t2, i2, s2, r2);
 451  }
 452  function mt(e3) {
 453    try {
 454      let t2 = e3.getChannelData(0), i2 = e3.sampleRate, s2 = Ct(t2, i2);
 455      if (s2.length < 2) return 120;
 456      let r2 = [];
 457      for (let l2 = 1; l2 < s2.length; l2++) r2.push((s2[l2] - s2[l2 - 1]) / i2);
 458      let a2 = {};
 459      r2.forEach((l2) => {
 460        let h2 = 60 / l2, c2 = Math.round(h2 / 3) * 3;
 461        c2 > 60 && c2 < 200 && (a2[c2] = (a2[c2] || 0) + 1);
 462      });
 463      let o2 = 0, n2 = 120;
 464      for (let [l2, h2] of Object.entries(a2)) h2 > o2 && (o2 = h2, n2 = parseInt(l2));
 465      return n2 < 70 && a2[n2 * 2] ? n2 *= 2 : n2 > 160 && a2[Math.round(n2 / 2)] && (n2 = Math.round(n2 / 2)), n2 - 1;
 466    } catch (t2) {
 467      return console.warn("[WaveformPlayer] BPM detection failed:", t2), null;
 468    }
 469  }
 470  function Ct(e3, t2) {
 471    let r2 = [], a2 = 0;
 472    for (let o2 = 0; o2 < e3.length - 2048; o2 += 1024) {
 473      let n2 = 0;
 474      for (let c2 = o2; c2 < o2 + 2048; c2++) n2 += e3[c2] * e3[c2];
 475      n2 = n2 / 2048;
 476      let l2 = n2 - a2, h2 = a2 * 1.8 + 0.01;
 477      if (l2 > h2 && n2 > 0.01) {
 478        let c2 = r2[r2.length - 1] || 0, d2 = t2 * 0.15;
 479        o2 - c2 > d2 && r2.push(o2);
 480      }
 481      a2 = n2 * 0.8 + a2 * 0.2;
 482    }
 483    return r2;
 484  }
 485  function Lt(e3, t2 = 1800) {
 486    let i2 = e3.length / t2, s2 = e3.numberOfChannels, r2 = [];
 487    for (let o2 = 0; o2 < s2; o2++) {
 488      let n2 = e3.getChannelData(o2);
 489      for (let l2 = 0; l2 < t2; l2++) {
 490        let h2 = ~~(l2 * i2), c2 = ~~(h2 + i2), d2 = 0, b2 = 0;
 491        for (let w2 = h2; w2 < c2; w2++) {
 492          let f2 = n2[w2];
 493          f2 > b2 && (b2 = f2), f2 < d2 && (d2 = f2);
 494        }
 495        let y2 = Math.max(Math.abs(b2), Math.abs(d2));
 496        (o2 === 0 || y2 > r2[l2]) && (r2[l2] = y2);
 497      }
 498    }
 499    let a2 = $2(r2);
 500    return a2 > 0 ? r2.map((o2) => o2 / a2) : r2;
 501  }
 502  async function G(e3, t2 = 1800, i2 = false) {
 503    let s2;
 504    try {
 505      let r2 = window.AudioContext || window.webkitAudioContext;
 506      s2 = new r2();
 507      let o2 = await (await fetch(e3)).arrayBuffer(), n2 = await s2.decodeAudioData(o2), l2 = Lt(n2, t2);
 508      l2 = _t(l2);
 509      let h2 = null;
 510      return i2 && (h2 = mt(n2)), { peaks: l2, bpm: h2 };
 511    } finally {
 512      s2 && s2.close();
 513    }
 514  }
 515  function yt(e3 = 1800) {
 516    let t2 = [];
 517    for (let i2 = 0; i2 < e3; i2++) {
 518      let s2 = Math.random() * 0.5 + 0.3, r2 = Math.sin(i2 / e3 * Math.PI * 4) * 0.2;
 519      t2.push(m2(s2 + r2, 0.1, 1));
 520    }
 521    return t2;
 522  }
 523  function _t(e3, t2 = 0.95) {
 524    let i2 = $2(e3);
 525    if (i2 === 0 || i2 > t2) return e3;
 526    let s2 = t2 / i2;
 527    return e3.map((r2) => r2 * s2);
 528  }
 529  var K = 128;
 530  function gt(e3) {
 531    let t2 = document.documentElement, i2 = document.body;
 532    return t2.classList.contains(e3) || t2.classList.contains(`$e3}-mode`) || t2.classList.contains(`theme-$e3}`) || t2.getAttribute("data-theme") === e3 || t2.getAttribute("data-color-scheme") === e3 || i2.classList.contains(e3) || i2.classList.contains(`$e3}-mode`) || i2.getAttribute("data-theme") === e3;
 533  }
 534  function xt(e3) {
 535    let t2 = 0, i2 = 0;
 536    for (let s2 = e3; s2 && s2.nodeType === 1 && i2 < 0.995; s2 = s2.parentElement) {
 537      let r2 = U(getComputedStyle(s2).backgroundColor);
 538      if (!r2 || r2.a <= 0) continue;
 539      let a2 = r2.a * (1 - i2);
 540      t2 += (r2.r * 299 + r2.g * 587 + r2.b * 114) / 1e3 * a2, i2 += a2;
 541    }
 542    return { sum: t2, alpha: i2 };
 543  }
 544  function Rt() {
 545    let e3 = lt(getComputedStyle(document.body).color);
 546    if (e3 !== null) return e3 > K ? "dark" : "light";
 547    if (window.matchMedia) {
 548      if (window.matchMedia("(prefers-color-scheme: dark)").matches) return "dark";
 549      if (window.matchMedia("(prefers-color-scheme: light)").matches) return "light";
 550    }
 551    return "dark";
 552  }
 553  function R(e3) {
 554    if (gt("dark")) return "dark";
 555    if (gt("light")) return "light";
 556    try {
 557      let t2 = e3 && e3.nodeType === 1 ? e3 : document.body, { sum: i2, alpha: s2 } = xt(t2), r2 = Rt(), a2 = i2 + (r2 === "dark" ? 0 : 255) * (1 - s2);
 558      return a2 > K ? "light" : a2 < K ? "dark" : r2;
 559    } catch {
 560      return "dark";
 561    }
 562  }
 563  var C = { dark: { waveformColor: "rgba(255, 255, 255, 0.3)", progressColor: "rgba(255, 255, 255, 0.9)" }, light: { waveformColor: "rgba(0, 0, 0, 0.2)", progressColor: "rgba(0, 0, 0, 0.8)" } };
 564  function J(e3, t2) {
 565    if (e3 && C[e3]) return C[e3];
 566    let i2 = R(t2);
 567    return C[i2];
 568  }
 569  var W = { url: "", height: 64, samples: 1800, preload: "metadata", crossOrigin: null, audioMode: "self", playbackRate: 1, showPlaybackSpeed: false, playbackRates: [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2], buttonAlign: "auto", layout: "default", buttonStyle: "circle", buttonSize: null, buttonRadius: null, waveformStyle: "mirror", barWidth: 2, barSpacing: 0, barRadius: 1, waveformGradient: "vertical", colorPreset: null, waveformColor: null, progressColor: null, autoplay: false, showControls: true, showInfo: true, showTime: true, showHoverTime: false, seekHandle: false, showBPM: false, bpm: null, singlePlay: true, playOnSeek: true, enableMediaSession: true, markers: [], showMarkers: true, accessibleSeek: true, seekLabel: null, seekValueText: null, title: null, artist: null, artwork: null, artworkPosition: "info", album: "", errorText: "Unable to load audio", playPauseLabel: "Play/Pause", speedLabel: "Playback speed", artworkAlt: "Album artwork", unknownTrackText: "Unknown Track", 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, onNextTrack: null, onPreviousTrack: null };
 570  var 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 } };
 571  var Q = ["auto", "top", "center", "bottom"];
 572  var N2 = 0.25;
 573  var F = 4;
 574  var Dt = { buttonAlign: Q, layout: ["default", "preview"], buttonStyle: ["circle", "minimal"], artworkPosition: ["info", "button"], waveformStyle: Object.keys(X), waveformGradient: ["vertical", "horizontal", "diagonal"], audioMode: ["self", "external"], preload: ["none", "metadata", "auto"], colorPreset: Object.keys(C), crossOrigin: ["anonymous", "use-credentials"] };
 575  var Bt = { height: { min: 1, integer: true }, samples: { min: 1, integer: true }, barWidth: { min: 0 }, barSpacing: { min: 0 }, barRadius: { min: 0 }, bpm: { min: 1 }, playbackRate: { min: N2, max: F } };
 576  var Ht = ["autoplay", "showControls", "showInfo", "showTime", "showHoverTime", "seekHandle", "showBPM", "singlePlay", "playOnSeek", "enableMediaSession", "showMarkers", "accessibleSeek", "showPlaybackSpeed"];
 577  var Ot = ["onLoad", "onPlay", "onPause", "onEnd", "onError", "onTimeUpdate", "onNextTrack", "onPreviousTrack"];
 578  function Y(e3, t2) {
 579    console.warn(`[WaveformPlayer] Invalid $e3} option, using default:`, t2);
 580  }
 581  function z(e3) {
 582    let t2 = H2(e3);
 583    return t2 ? t2.reduce((i2, s2) => {
 584      let r2 = s2 && typeof s2 == "object" ? _(s2.time, null, { min: 0 }) : null;
 585      return r2 === null ? (Y("marker", s2), i2) : (i2.push({ ...s2, time: r2, label: s2.label == null ? "" : s2.label }), i2);
 586    }, []) : (e3 != null && Y("markers", e3), []);
 587  }
 588  function Z(e3) {
 589    let t2 = (s2) => e3[s2] != null, i2 = (s2) => {
 590      Y(s2, e3[s2]), e3[s2] = W[s2];
 591    };
 592    for (let [s2, r2] of Object.entries(Bt)) {
 593      if (!t2(s2)) continue;
 594      let a2 = _(e3[s2], null, r2);
 595      a2 === null ? i2(s2) : e3[s2] = a2;
 596    }
 597    for (let [s2, r2] of Object.entries(Dt)) t2(s2) && rt(e3[s2], r2) === null && i2(s2);
 598    for (let s2 of Ht) e3[s2] = at(e3[s2]);
 599    for (let s2 of Ot) t2(s2) && typeof e3[s2] != "function" && i2(s2);
 600    if (t2("playbackRates")) {
 601      let s2 = D(e3.playbackRates, { min: N2, max: F, fallback: null });
 602      s2 === null ? i2("playbackRates") : e3.playbackRates = s2;
 603    }
 604    e3.markers = z(e3.markers);
 605    for (let s2 of ["buttonSize", "buttonRadius"]) {
 606      if (!t2(s2)) continue;
 607      let r2 = e3[s2];
 608      (typeof r2 == "number" ? Number.isFinite(r2) : typeof r2 == "string" && r2.trim() !== "") || i2(s2);
 609    }
 610    for (let s2 of ["waveformColor", "progressColor"]) {
 611      if (!t2(s2)) continue;
 612      let r2 = e3[s2];
 613      !(typeof r2 == "string" && r2.trim() !== "") && !Array.isArray(r2) && i2(s2);
 614    }
 615    return e3;
 616  }
 617  var It = "data:image/svg+xml," + encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><rect width="24" height="24" rx="4" fill="#71717a" fill-opacity="0.15"/><g fill="none" stroke="#a1a1aa" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="17" r="2.2"/><circle cx="17" cy="15" r="2.2"/><path d="M10.2 17V7l9-1.6v9"/></g></svg>');
 618  var bt = 5;
 619  var wt = 10;
 620  var Wt = 'button, a[href], input, [role="slider"]';
 621  var T = class e2 {
 622    static instances = /* @__PURE__ */ new Map();
 623    static currentlyPlaying = null;
 624    constructor(t2, i2 = {}) {
 625      if (this.container = typeof t2 == "string" ? document.querySelector(t2) : t2, !this.container) throw new Error("[WaveformPlayer] Container element not found");
 626      let s2 = O(this.container), r2 = { ...i2 };
 627      r2.style && !r2.waveformStyle && (r2.waveformStyle = r2.style), r2.src && !r2.url && (r2.url = r2.src), this.options = Z(j2(W, s2, r2));
 628      let a2 = J(this.options.colorPreset, this.container);
 629      this._autoTheme = this.options.colorPreset == null || !C[this.options.colorPreset], this._presetKeys = [], this._scheme = this.options.colorPreset && C[this.options.colorPreset] ? this.options.colorPreset : R(this.container);
 630      for (let [n2, l2] of Object.entries(a2)) (this.options[n2] === null || this.options[n2] === void 0) && (this.options[n2] = l2, this._presetKeys.push(n2));
 631      let o2 = X[this.options.waveformStyle];
 632      o2 && (s2.barWidth === void 0 && i2.barWidth === void 0 && (this.options.barWidth = o2.barWidth), s2.barSpacing === void 0 && i2.barSpacing === void 0 && (this.options.barSpacing = o2.barSpacing)), this.audio = null, this.canvas = null, this.ctx = null, this.waveformData = [], this.progress = 0, this._activeMarkerIndex = -1, this._markerLabelTimer = null, this.isPlaying = false, this.isLoading = false, this.hasError = false, this.updateTimer = null, this.resizeObserver = null, this._ac = new AbortController(), this.id = this.container.id || nt(this.options.url), e2.instances.set(this.id, this), e2._watchTheme();
 633      try {
 634        this.init();
 635      } catch (n2) {
 636        throw e2.instances.delete(this.id), this._ac.abort(), n2;
 637      }
 638      setTimeout(() => {
 639        this._emit("waveformplayer:ready", { player: this, url: this.options.url });
 640      }, 100);
 641    }
 642    _emit(t2, i2, s2 = false) {
 643      let r2 = new CustomEvent(t2, { bubbles: true, cancelable: s2, detail: i2 });
 644      return this.container.dispatchEvent(r2), r2;
 645    }
 646    _requestSeek(t2) {
 647      this._emit("waveformplayer:request-seek", { ...this._buildTrackDetail(), percent: t2 }, true).defaultPrevented || (this.progress = t2, this.drawWaveform?.());
 648    }
 649    init() {
 650      this.createDOM(), this.createAudio(), this.initPlaybackSpeed(), this.initKeyboardControls(), this.initSeekControl(), this.bindEvents(), this.setupResizeObserver(), requestAnimationFrame(() => {
 651        this.resizeCanvas(), this.options.url && this.load(this.options.url).then(() => {
 652          this.options.autoplay && this.play()?.catch(() => {
 653          });
 654        }).catch((t2) => {
 655          console.error("[WaveformPlayer] Failed to load audio:", t2);
 656        });
 657      });
 658    }
 659    createDOM() {
 660      this.container.innerHTML = "", this.container.className = "waveform-player";
 661      let t2 = Q.includes(this.options.buttonAlign) ? this.options.buttonAlign : "auto";
 662      t2 === "auto" && (this.options.waveformStyle === "bars" ? t2 = "bottom" : t2 = "center"), this.options.layout === "preview" && this.container.classList.add("waveform-layout-preview"), this.container.classList.toggle("waveform-theme-light", this._scheme === "light");
 663      let s2 = [];
 664      this.options.buttonSize != null && s2.push(`--wfp-btn-size: $q(this.options.buttonSize)}`), this.options.buttonRadius != null && s2.push(`--wfp-btn-radius: $q(this.options.buttonRadius)}`);
 665      let r2 = s2.length ? ` style="$s2.join("; ")};"` : "", a2 = this.options.artworkPosition === "button" && this.options.artwork, o2 = a2 ? `<img class="waveform-btn-artwork" src="$S(this.options.artwork)}" alt="" aria-hidden="true">` : "", n2 = this.options.showControls ? `
 666          <button class="waveform-btn$this.options.buttonStyle === "minimal" ? " waveform-btn-minimal" : ""}$a2 ? " waveform-btn-has-artwork" : ""}" aria-label="$S(this.options.playPauseLabel)}"$r2}>
 667            $o2}
 668            <span class="waveform-icon-play">$this.options.playIcon}</span>
 669            <span class="waveform-icon-pause" style="display:none;">$this.options.pauseIcon}</span>
 670          </button>
 671          ` : "", l2 = this.options.showInfo ? `
 672        <div class="waveform-info">
 673          $this.options.artworkPosition !== "button" && this.options.artwork ? `
 674            <img class="waveform-artwork" src="$S(this.options.artwork)}" alt="$S(this.options.artworkAlt)}" style="
 675              width: 40px;
 676              height: 40px;
 677              border-radius: 4px;
 678              object-fit: cover;
 679              flex-shrink: 0;
 680            ">
 681          ` : ""}
 682          <div class="waveform-text">
 683            <span class="waveform-title"></span>
 684            $this.options.artist ? `<span class="waveform-artist">$S(this.options.artist)}</span>` : ""}
 685          </div>
 686          <div class="waveform-meta" style="display: flex; align-items: center; gap: 1rem;">
 687            $this.options.showBPM ? `
 688              <span class="waveform-bpm" style="display: none;">
 689                <span class="bpm-value">--</span> BPM
 690              </span>
 691            ` : ""}
 692            $this.options.showPlaybackSpeed ? `
 693              <div class="waveform-speed">
 694                <button class="speed-btn" aria-label="$S(this.options.speedLabel)}" aria-haspopup="menu" aria-expanded="false">
 695                  <span class="speed-value">1x</span>
 696                </button>
 697                <div class="speed-menu" role="menu" aria-label="$S(this.options.speedLabel)}" style="display: none;">
 698                  $this.options.playbackRates.map((h2) => `<button class="speed-option" role="menuitemradio" tabindex="-1" aria-checked="false" data-rate="$h2}">$h2}x</button>`).join("")}
 699                </div>
 700              </div>
 701            ` : ""}
 702            $this.options.showTime ? `
 703              <span class="waveform-time">
 704                <span class="time-current">0:00</span> / <span class="time-total">0:00</span>
 705              </span>
 706            ` : ""}
 707          </div>
 708        </div>
 709          ` : "";
 710      this.container.innerHTML = `
 711    <div class="waveform-player-inner">
 712      <div class="waveform-body">
 713        <div class="waveform-track waveform-align-$t2}">
 714          $n2}
 715          
 716          <div class="waveform-container">
 717            <canvas></canvas>
 718            <div class="waveform-markers"></div>
 719            <div class="waveform-loading" style="display:none;"></div>
 720            <div class="waveform-error" style="display:none;" role="alert">
 721              <span class="waveform-error-text">$S(this.options.errorText)}</span>
 722            </div>
 723          </div>
 724        </div>
 725        
 726        $l2}
 727      </div>
 728    </div>
 729  `, 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.artistEl = this.container.querySelector(".waveform-artist"), this.artworkEl = this.container.querySelector(".waveform-artwork, .waveform-btn-artwork"), this.bindArtworkFallback(this.artworkEl), 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();
 730    }
 731    bindArtworkFallback(t2) {
 732      t2 && t2.addEventListener("error", () => {
 733        t2.src.startsWith("data:") || (t2.src = It);
 734      }, { signal: this._ac.signal });
 735    }
 736    createArtworkElement() {
 737      let t2 = document.createElement("img");
 738      return t2.className = "waveform-artwork", t2.style.width = "40px", t2.style.height = "40px", t2.style.borderRadius = "4px", t2.style.objectFit = "cover", t2.style.flexShrink = "0", this.bindArtworkFallback(t2), t2;
 739    }
 740    createButtonArtworkElement() {
 741      let t2 = document.createElement("img");
 742      return t2.className = "waveform-btn-artwork", t2.alt = "", t2.setAttribute("aria-hidden", "true"), this.bindArtworkFallback(t2), t2;
 743    }
 744    createArtistElement() {
 745      let t2 = document.createElement("span");
 746      return t2.className = "waveform-artist", t2;
 747    }
 748    syncArtist(t2) {
 749      if (this.options.artist = t2 || null, !!this.options.showInfo) {
 750        if (!t2) {
 751          this.artistEl?.remove(), this.artistEl = null;
 752          return;
 753        }
 754        if (!this.artistEl) {
 755          let i2 = this.container.querySelector(".waveform-title");
 756          if (!i2) return;
 757          this.artistEl = this.createArtistElement(), i2.after(this.artistEl);
 758        }
 759        this.artistEl.textContent = t2, this.artistEl.style.display = "";
 760      }
 761    }
 762    syncButtonArtwork(t2) {
 763      if (this.playBtn) {
 764        if (!t2) {
 765          this.artworkEl?.remove(), this.artworkEl = null, this.playBtn.classList.remove("waveform-btn-has-artwork");
 766          return;
 767        }
 768        this.artworkEl || (this.artworkEl = this.createButtonArtworkElement(), this.playBtn.prepend(this.artworkEl)), this.artworkEl.src = t2, this.playBtn.classList.add("waveform-btn-has-artwork");
 769      }
 770    }
 771    syncArtwork(t2, i2 = "") {
 772      if (this.options.artwork = t2 || null, this.options.artworkAlt = i2 || "", this.options.artworkPosition === "button") {
 773        this.syncButtonArtwork(this.options.artwork);
 774        return;
 775      }
 776      if (this.options.showInfo) {
 777        if (!t2) {
 778          this.artworkEl?.remove(), this.artworkEl = null;
 779          return;
 780        }
 781        if (!this.artworkEl) {
 782          let s2 = this.container.querySelector(".waveform-text");
 783          if (!s2) return;
 784          this.artworkEl = this.createArtworkElement(), s2.before(this.artworkEl);
 785        }
 786        this.artworkEl.src = t2, this.artworkEl.alt = i2 || "";
 787      }
 788    }
 789    createAudio() {
 790      if (this.options.audioMode === "external") {
 791        this.audio = null;
 792        return;
 793      }
 794      this.audio = new Audio(), this.audio.preload = this.options.preload || "metadata", this.options.crossOrigin && (this.audio.crossOrigin = this.options.crossOrigin);
 795    }
 796    initPlaybackSpeed() {
 797      this.audio && this.options.playbackRate && this.options.playbackRate !== 1 && (this.audio.playbackRate = this.options.playbackRate), this.options.showPlaybackSpeed && this.initSpeedControls();
 798    }
 799    initSpeedControls() {
 800      let t2 = this.container.querySelector(".speed-btn"), i2 = this.container.querySelector(".speed-menu");
 801      if (!t2 || !i2) return;
 802      let s2 = () => Array.from(i2.querySelectorAll(".speed-option")), r2 = () => i2.style.display !== "none", a2 = (l2) => {
 803        if (i2.style.display = l2 ? "block" : "none", t2.setAttribute("aria-expanded", l2 ? "true" : "false"), l2) {
 804          let h2 = s2();
 805          (h2.find((c2) => c2.getAttribute("aria-checked") === "true") || h2[0])?.focus();
 806        }
 807      }, o2 = (l2) => {
 808        let h2 = s2();
 809        h2.length && h2[(l2 + h2.length) % h2.length].focus();
 810      }, n2 = (l2) => {
 811        this.setPlaybackRate(parseFloat(l2.dataset.rate)), a2(false), t2.focus();
 812      };
 813      t2.addEventListener("click", (l2) => {
 814        l2.stopPropagation(), a2(!r2());
 815      }, { signal: this._ac.signal }), document.addEventListener("click", () => a2(false), { signal: this._ac.signal }), i2.addEventListener("click", (l2) => {
 816        l2.stopPropagation();
 817        let h2 = l2.target.closest(".speed-option");
 818        h2 && n2(h2);
 819      }, { signal: this._ac.signal }), t2.closest(".waveform-speed")?.addEventListener("keydown", (l2) => {
 820        let h2 = s2(), c2 = h2.indexOf(document.activeElement);
 821        if (!r2()) {
 822          (l2.key === "ArrowDown" || l2.key === "ArrowUp") && document.activeElement === t2 && (l2.preventDefault(), a2(true));
 823          return;
 824        }
 825        switch (l2.key) {
 826          case "ArrowDown":
 827            l2.preventDefault(), o2(c2 < 0 ? 0 : c2 + 1);
 828            break;
 829          case "ArrowUp":
 830            l2.preventDefault(), o2(c2 < 0 ? h2.length - 1 : c2 - 1);
 831            break;
 832          case "Home":
 833            l2.preventDefault(), o2(0);
 834            break;
 835          case "End":
 836            l2.preventDefault(), o2(h2.length - 1);
 837            break;
 838          case "Escape":
 839            l2.preventDefault(), a2(false), t2.focus();
 840            break;
 841          case "Tab":
 842            a2(false);
 843            break;
 844        }
 845      }, { signal: this._ac.signal }), this.updateSpeedUI();
 846    }
 847    initKeyboardControls() {
 848      this.container.setAttribute("tabindex", "-1"), this.container.addEventListener("click", (t2) => {
 849        t2.target.closest(Wt) || (e2.getAllInstances().forEach((i2) => {
 850          i2 !== this && i2.container.setAttribute("tabindex", "-1");
 851        }), this.container.setAttribute("tabindex", "0"), this.container.focus());
 852      }, { signal: this._ac.signal }), this.container.addEventListener("keydown", (t2) => {
 853        if (document.activeElement !== this.container) return;
 854        let i2 = t2.key, s2 = !!this.audio, r2 = s2 ? this.audio.currentTime : 0;
 855        if (s2 && i2 >= "0" && i2 <= "9") {
 856          t2.preventDefault(), this.seekToPercent(parseInt(i2) / 10);
 857          return;
 858        }
 859        let a2 = { " ": () => this.togglePlay() };
 860        s2 && (a2.ArrowLeft = () => this.seekTo(m2(r2 - 5, 0, this.audio.duration)), a2.ArrowRight = () => this.seekTo(m2(r2 + 5, 0, this.audio.duration)), a2.ArrowUp = () => this.setVolume(m2(this.audio.volume + 0.1)), a2.ArrowDown = () => this.setVolume(m2(this.audio.volume - 0.1)), a2.m = a2.M = () => this.audio.muted = !this.audio.muted), a2[i2] && (t2.preventDefault(), a2[i2]());
 861      }, { signal: this._ac.signal });
 862    }
 863    initSeekControl() {
 864      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", (t2) => {
 865        if (t2.key === " " || t2.key === "Spacebar") {
 866          t2.preventDefault(), t2.stopPropagation(), this.togglePlay();
 867          return;
 868        }
 869        let i2 = this.getSeekDuration();
 870        if (!i2) return;
 871        let s2 = this.getSeekCurrentTime(), r2;
 872        switch (t2.key) {
 873          case "ArrowLeft":
 874          case "ArrowDown":
 875            r2 = s2 - bt;
 876            break;
 877          case "ArrowRight":
 878          case "ArrowUp":
 879            r2 = s2 + bt;
 880            break;
 881          case "PageDown":
 882            r2 = s2 - wt;
 883            break;
 884          case "PageUp":
 885            r2 = s2 + wt;
 886            break;
 887          case "Home":
 888            r2 = 0;
 889            break;
 890          case "End":
 891            r2 = i2;
 892            break;
 893          default:
 894            return;
 895        }
 896        t2.preventDefault(), t2.stopPropagation(), this.seekToSeconds(r2);
 897      }, { signal: this._ac.signal })));
 898    }
 899    getSeekDuration() {
 900      return this.options.audioMode === "external" ? this._extDuration || 0 : this.audio && Number.isFinite(this.audio.duration) ? this.audio.duration : 0;
 901    }
 902    getSeekCurrentTime() {
 903      return this.options.audioMode === "external" ? this.progress * (this._extDuration || 0) : this.audio && Number.isFinite(this.audio.currentTime) ? this.audio.currentTime : 0;
 904    }
 905    seekToSeconds(t2) {
 906      let i2 = this.getSeekDuration();
 907      if (!i2) return;
 908      let s2 = m2(t2, 0, i2);
 909      if (this.options.audioMode === "external") {
 910        this._requestSeek(s2 / i2), this.updateSeekAccessibility();
 911        return;
 912      }
 913      this.seekTo(s2);
 914    }
 915    applySeekLabel(t2 = this.options.title) {
 916      if (!this.seekEl) return;
 917      let i2 = this.options.seekLabel || t2 || "Seek";
 918      this.seekEl.setAttribute("aria-label", i2);
 919    }
 920    updateSeekAccessibility() {
 921      if (!this.seekEl) return;
 922      let t2 = this.getSeekDuration(), i2 = Math.min(this.getSeekCurrentTime(), t2);
 923      this.seekEl.setAttribute("aria-valuemax", String(Math.round(t2))), this.seekEl.setAttribute("aria-valuenow", String(Math.round(i2))), this.seekEl.setAttribute("aria-valuetext", ot(this.options.seekValueText || "%1$s of %2$s", E(i2), E(t2)));
 924    }
 925    initMediaSession() {
 926      if (!("mediaSession" in navigator) || !this.options.enableMediaSession || !this.audio) return;
 927      this._applyMediaMetadata(), navigator.mediaSession.setActionHandler("play", () => this.play()), navigator.mediaSession.setActionHandler("pause", () => this.pause()), navigator.mediaSession.setActionHandler("seekbackward", () => {
 928        this.seekTo(m2(this.audio.currentTime - 10, 0, this.audio.duration));
 929      }), navigator.mediaSession.setActionHandler("seekforward", () => {
 930        this.seekTo(m2(this.audio.currentTime + 10, 0, this.audio.duration));
 931      }), navigator.mediaSession.setActionHandler("seekto", (s2) => {
 932        s2.seekTime !== null && this.seekTo(s2.seekTime);
 933      });
 934      let t2 = this.options.onNextTrack, i2 = this.options.onPreviousTrack;
 935      try {
 936        navigator.mediaSession.setActionHandler("nexttrack", typeof t2 == "function" ? () => t2(this) : null);
 937      } catch {
 938      }
 939      try {
 940        navigator.mediaSession.setActionHandler("previoustrack", typeof i2 == "function" ? () => i2(this) : null);
 941      } catch {
 942      }
 943    }
 944    _applyMediaMetadata() {
 945      !("mediaSession" in navigator) || !this.options.enableMediaSession || (navigator.mediaSession.metadata = new MediaMetadata({ title: this.options.title || this.options.unknownTrackText, artist: this.options.artist || "", album: this.options.album || "", artwork: this.options.artwork ? [{ src: this.options.artwork, sizes: "512x512", type: "image/jpeg" }] : [] }));
 946    }
 947    _updateMediaSession(t2) {
 948      if (!(!("mediaSession" in navigator) || !this.options.enableMediaSession || !this.audio)) try {
 949        t2 === "playing" && this.initMediaSession(), navigator.mediaSession.playbackState = t2;
 950        let i2 = this.audio.duration;
 951        navigator.mediaSession.setPositionState && i2 && isFinite(i2) && navigator.mediaSession.setPositionState({ duration: i2, playbackRate: this.audio.playbackRate || 1, position: m2(this.audio.currentTime, 0, i2) });
 952      } catch {
 953      }
 954    }
 955    bindEvents() {
 956      this.playBtn && this.playBtn.addEventListener("click", () => this.togglePlay()), this.audio && (this.audio.addEventListener("loadstart", () => this.setLoading(true)), this.audio.addEventListener("loadedmetadata", () => this.onMetadataLoaded()), this.audio.addEventListener("canplay", () => this.setLoading(false)), this.audio.addEventListener("play", () => this.onPlay()), this.audio.addEventListener("pause", () => this.onPause()), this.audio.addEventListener("ended", () => this.onEnded()), this.audio.addEventListener("error", (i2) => this.onError(i2))), this.canvas.addEventListener("click", (i2) => this.handleCanvasClick(i2)), this._dragging = false, this._seekHover = false, this._handleNear = false, this.canvas.addEventListener("pointerenter", () => {
 957        this._seekHover = true, this.drawWaveform(), this._updateSeekHandle();
 958      }), this.canvas.addEventListener("pointerleave", () => {
 959        this._seekHover = false, this._handleNear = false, this._dragging || this._hideHoverTip(), this.drawWaveform(), this._updateSeekHandle();
 960      }), this.canvas.addEventListener("pointerdown", (i2) => {
 961        if (!(i2.pointerType === "mouse" && i2.button !== 0)) {
 962          this._dragging = true;
 963          try {
 964            this.canvas.setPointerCapture(i2.pointerId);
 965          } catch {
 966          }
 967          this._scrubTo(i2.clientX);
 968        }
 969      }), this.canvas.addEventListener("pointermove", (i2) => {
 970        if (this._dragging) {
 971          this._scrubTo(i2.clientX);
 972          return;
 973        }
 974        let s2 = this.canvas.getBoundingClientRect();
 975        s2.width && (this._handleNear = Math.abs(i2.clientX - s2.left - this.progress * s2.width) <= 10, this._updateSeekHandle());
 976      });
 977      let t2 = (i2) => {
 978        if (this._dragging) {
 979          this._dragging = false, this._suppressClick = true;
 980          try {
 981            this.canvas.releasePointerCapture(i2.pointerId);
 982          } catch {
 983          }
 984          this._seekFromPointer(i2.clientX), !this._seekHover && !this.options.showHoverTime && this._hideHoverTip(), this._updateSeekHandle();
 985        }
 986      };
 987      this.canvas.addEventListener("pointerup", t2), this.canvas.addEventListener("pointercancel", t2), this.setupHoverTime(), this.setupSeekHandle(), this.resizeHandler = ht(() => this.resizeCanvas(), 100), window.addEventListener("resize", this.resizeHandler);
 988    }
 989    setupResizeObserver() {
 990      "ResizeObserver" in window && (this.resizeObserver = new ResizeObserver(() => {
 991        this.resizeCanvas();
 992      }), this.canvas?.parentElement && this.resizeObserver.observe(this.canvas.parentElement));
 993    }
 994    async load(t2) {
 995      try {
 996        this.setLoading(true), this.progress = 0, this.hasError = false, this.container.classList.remove("waveform-is-placeholder");
 997        let i2 = !!this.options.waveform;
 998        i2 && this.setWaveformData(this.options.waveform);
 999        let s2 = this.options.title || I(t2);
1000        if (this.titleEl && (this.titleEl.textContent = s2), this.applySeekLabel(s2), this.audio && (this.audio.src = t2, this.audio.preload !== "none" && await new Promise((r2, a2) => {
1001          let o2 = () => {
1002            this.audio.removeEventListener("loadedmetadata", o2), this.audio.removeEventListener("error", n2), r2();
1003          }, n2 = (l2) => {
1004            this.audio.removeEventListener("loadedmetadata", o2), this.audio.removeEventListener("error", n2), a2(l2);
1005          };
1006          this.audio.addEventListener("loadedmetadata", o2), this.audio.addEventListener("error", n2);
1007        })), !i2) try {
1008          let r2 = await G(t2, this.options.samples, this.options.showBPM);
1009          this.waveformData = r2.peaks, r2.bpm && (this.detectedBPM = r2.bpm, this.updateBPMDisplay());
1010        } catch (r2) {
1011          console.warn("[WaveformPlayer] Using placeholder waveform:", r2), this.waveformData = yt(this.options.samples), this.container.classList.add("waveform-is-placeholder");
1012        }
1013        this.drawWaveform(), this.renderMarkers(), this.options.onLoad && this.options.onLoad(this);
1014      } catch (i2) {
1015        this.onError(i2);
1016      } finally {
1017        this.setLoading(false);
1018      }
1019    }
1020    async loadTrack(t2, i2 = null, s2 = null, r2 = {}) {
1021      let a2 = Object.prototype.hasOwnProperty.call(r2, "artwork"), o2 = Object.prototype.hasOwnProperty.call(r2, "artworkAlt");
1022      this.isPlaying && this.pause(), this.audio && (this.audio.src = "", this.audio.load()), this.hasError = false, this.errorEl && (this.errorEl.style.display = "none"), this.canvas && (this.canvas.style.opacity = "1"), this.playBtn && (this.playBtn.disabled = false), this.progress = 0, this.waveformData = [], this.options = Z(j2(this.options, { url: t2, title: i2 === null ? this.options.title : i2, artist: s2 === null ? this.options.artist : s2, ...r2 })), a2 && (this.options.artwork = r2.artwork || null), o2 ? this.options.artworkAlt = r2.artworkAlt || "" : a2 && (this.options.artworkAlt = this.options.artwork ? W.artworkAlt : ""), r2.preload && this.audio && (this.audio.preload = this.options.preload), r2.crossOrigin && this.audio && (this.audio.crossOrigin = this.options.crossOrigin), s2 !== null && this.syncArtist(s2), (a2 || o2) && this.syncArtwork(a2 ? r2.artwork : this.options.artwork, o2 ? r2.artworkAlt : this.options.artworkAlt), this.options.markers = r2.markers ? z(r2.markers) : [], this.options.waveform = r2.waveform || null, await this.load(t2), r2.autoplay !== false && this.play()?.catch(() => {
1023      });
1024    }
1025    setWaveformData(t2) {
1026      if (typeof t2 == "string" && t2.trim().endsWith(".json")) {
1027        fetch(t2.trim()).then((i2) => i2.json()).then((i2) => {
1028          this.waveformData = Array.isArray(i2) ? i2 : i2.peaks || [], i2.markers && !this.options.markers?.length && (this.options.markers = z(i2.markers), this.renderMarkers()), this.drawWaveform();
1029        }).catch(() => {
1030        });
1031        return;
1032      }
1033      this.waveformData = D(t2, { fallback: [] }), this.drawWaveform();
1034    }
1035    drawWaveform() {
1036      !this.ctx || this.waveformData.length === 0 || ft(this.ctx, this.canvas, this.waveformData, this.progress, { ...this.options, waveformStyle: this.options.waveformStyle || "bars", color: this.options.waveformColor, progressColor: this.options.progressColor, seekActive: this._seekHover || this._dragging });
1037    }
1038    resizeCanvas() {
1039      if (!this.canvas || this.isDestroying) return;
1040      let t2 = window.devicePixelRatio || 1, i2 = this.canvas.parentElement.getBoundingClientRect();
1041      this.canvas.width = i2.width * t2, this.canvas.height = this.options.height * t2, this.canvas.parentElement.style.height = this.options.height + "px", this.drawWaveform();
1042    }
1043    renderMarkers() {
1044      if (!this.markersContainer || (this.markersContainer.innerHTML = "", this._activeMarkerIndex = -1, clearTimeout(this._markerLabelTimer), !this.options.showMarkers || !this.options.markers?.length)) return;
1045      let t2 = this.getSeekDuration();
1046      t2 && this.options.markers.forEach((i2, s2) => {
1047        if (i2.time > t2) {
1048          console.warn(`[WaveformPlayer] Marker "$i2.label}" at $i2.time}s exceeds audio duration of $t2}s`);
1049          return;
1050        }
1051        let r2 = i2.time / t2 * 100, a2 = document.createElement("button");
1052        a2.className = "waveform-marker", a2.style.left = `$r2}%`, a2.style.backgroundColor = i2.color || "rgba(255, 255, 255, 0.5)", a2.setAttribute("aria-label", i2.label), a2.setAttribute("data-time", i2.time);
1053        let o2 = document.createElement("span");
1054        o2.className = "waveform-marker-tooltip", o2.textContent = i2.label, a2.appendChild(o2), a2.addEventListener("click", (n2) => {
1055          n2.stopPropagation(), this.seekTo(i2.time), this.options.playOnSeek && !this.isPlaying && this.play();
1056        }), this.markersContainer.appendChild(a2);
1057      });
1058    }
1059    setActiveMarker(t2) {
1060      if (!this.markersContainer) return;
1061      this.markersContainer.querySelectorAll(".waveform-marker").forEach((s2, r2) => s2.classList.toggle("active", r2 === t2));
1062    }
1063    updateActiveMarker() {
1064      if (!this.markersContainer) return;
1065      let t2 = this.markersContainer.querySelectorAll(".waveform-marker");
1066      if (!t2.length) return;
1067      let i2 = this.getSeekDuration(), s2 = i2 ? this.progress * i2 : 0, r2 = -1, a2 = -1 / 0;
1068      t2.forEach((o2, n2) => {
1069        let l2 = parseFloat(o2.getAttribute("data-time"));
1070        Number.isFinite(l2) && l2 <= s2 + 0.05 && l2 > a2 && (a2 = l2, r2 = n2);
1071      }), r2 !== this._activeMarkerIndex && (this._activeMarkerIndex = r2, this.setActiveMarker(r2), clearTimeout(this._markerLabelTimer), t2.forEach((o2, n2) => o2.classList.toggle("show-label", n2 === r2)), r2 >= 0 && (this._markerLabelTimer = setTimeout(() => {
1072        this.markersContainer?.querySelectorAll(".waveform-marker").forEach((o2) => o2.classList.remove("show-label"));
1073      }, 2500)));
1074    }
1075    setupHoverTime() {
1076      if (!this.seekEl) return;
1077      let t2 = document.createElement("div");
1078      t2.className = "waveform-hover-time", t2.setAttribute("aria-hidden", "true"), this.seekEl.appendChild(t2), this.hoverTimeEl = t2, this.options.showHoverTime && (this.seekEl.addEventListener("pointermove", (i2) => {
1079        this._dragging || this._updateHoverTip(i2.clientX);
1080      }), this.seekEl.addEventListener("pointerleave", () => {
1081        this._dragging || this._hideHoverTip();
1082      }));
1083    }
1084    _updateHoverTip(t2) {
1085      let i2 = this.hoverTimeEl;
1086      if (!i2) return;
1087      let s2 = this.getSeekDuration();
1088      if (!s2) {
1089        i2.style.opacity = "0";
1090        return;
1091      }
1092      let r2 = this.canvas.getBoundingClientRect(), a2 = m2((t2 - r2.left) / r2.width);
1093      i2.textContent = E(a2 * s2), i2.style.left = a2 * 100 + "%", i2.style.opacity = "1";
1094    }
1095    _hideHoverTip() {
1096      this.hoverTimeEl && (this.hoverTimeEl.style.opacity = "0");
1097    }
1098    _scrubTo(t2) {
1099      let i2 = this.canvas.getBoundingClientRect();
1100      if (!i2.width) return;
1101      this.progress = m2((t2 - i2.left) / i2.width), this.drawWaveform(), this._updateSeekHandle();
1102      let s2 = this.getSeekDuration();
1103      s2 && this.currentTimeEl ? (this.currentTimeEl.textContent = E(this.progress * s2), this._hideHoverTip()) : this._updateHoverTip(t2);
1104    }
1105    setupSeekHandle() {
1106      if (!this.options.seekHandle || this.options.waveformStyle !== "seekbar" || !this.seekEl) return;
1107      let t2 = document.createElement("div");
1108      t2.className = "waveform-seek-handle", t2.setAttribute("aria-hidden", "true"), this.seekEl.appendChild(t2), this.seekHandleEl = t2;
1109    }
1110    _updateSeekHandle() {
1111      let t2 = this.seekHandleEl;
1112      t2 && (t2.style.left = this.progress * 100 + "%", t2.classList.toggle("is-visible", this._seekHover || this._dragging), t2.classList.toggle("is-active", this._dragging || this._handleNear));
1113    }
1114    handleCanvasClick(t2) {
1115      if (this._suppressClick) {
1116        this._suppressClick = false;
1117        return;
1118      }
1119      this._seekFromPointer(t2.clientX);
1120    }
1121    _seekFromPointer(t2) {
1122      let i2 = this.canvas.getBoundingClientRect();
1123      if (!i2.width) return;
1124      let s2 = m2((t2 - i2.left) / i2.width);
1125      if (this.options.audioMode === "external") {
1126        this._requestSeek(s2);
1127        return;
1128      }
1129      !this.audio || !this.audio.duration || this.seekToPercent(s2);
1130    }
1131    setLoading(t2) {
1132      if (this.isLoading = t2, this.loadingEl) {
1133        let i2 = t2 && this.waveformData.length === 0;
1134        this.loadingEl.style.display = i2 ? "block" : "none";
1135      }
1136      this.seekEl && this.seekEl.setAttribute("aria-busy", t2 ? "true" : "false");
1137    }
1138    onMetadataLoaded() {
1139      this.isDestroying || (this.totalTimeEl && (this.totalTimeEl.textContent = E(this.audio.duration)), this.renderMarkers(), this.updateSeekAccessibility());
1140    }
1141    setPlayButtonState(t2) {
1142      if (!this.playBtn) return;
1143      this.playBtn.classList.toggle("playing", t2);
1144      let i2 = this.playBtn.querySelector(".waveform-icon-play"), s2 = this.playBtn.querySelector(".waveform-icon-pause");
1145      i2 && (i2.style.display = t2 ? "none" : "flex"), s2 && (s2.style.display = t2 ? "flex" : "none");
1146    }
1147    onPlay() {
1148      this.isDestroying || (this.isPlaying = true, this.setPlayButtonState(true), this.startSmoothUpdate(), this._updateMediaSession("playing"), this._emit("waveformplayer:play", { player: this, url: this.options.url }), this.options.onPlay && this.options.onPlay(this));
1149    }
1150    onPause() {
1151      this.isDestroying || (this.isPlaying = false, this.setPlayButtonState(false), this.stopSmoothUpdate(), this._updateMediaSession("paused"), this._emit("waveformplayer:pause", { player: this, url: this.options.url }), this.options.onPause && this.options.onPause(this));
1152    }
1153    onEnded() {
1154      if (this.isDestroying) return;
1155      let t2 = this.audio.duration;
1156      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: t2, duration: t2 }), this.onPause(), this.options.onEnd && this.options.onEnd(this);
1157    }
1158    onError(t2) {
1159      this.isDestroying || (console.error("[WaveformPlayer] Audio error:", t2), this.hasError = true, this.setLoading(false), this.errorEl && (this.errorEl.style.display = "flex"), this.canvas && (this.canvas.style.opacity = "0.2"), this.playBtn && (this.playBtn.disabled = true), this.options.onError && this.options.onError(t2, this));
1160    }
1161    startSmoothUpdate() {
1162      this.stopSmoothUpdate();
1163      let t2 = () => {
1164        this.isPlaying && this.audio && this.audio.duration && (this.updateProgress(), this.updateTimer = requestAnimationFrame(t2));
1165      };
1166      this.updateTimer = requestAnimationFrame(t2);
1167    }
1168    stopSmoothUpdate() {
1169      this.updateTimer && (cancelAnimationFrame(this.updateTimer), this.updateTimer = null);
1170    }
1171    updateProgress() {
1172      if (!this.audio || !this.audio.duration || this._dragging) return;
1173      let t2 = this.audio.currentTime / this.audio.duration;
1174      Math.abs(t2 - this.progress) > 1e-3 && (this.progress = t2, this.drawWaveform(), this._updateSeekHandle()), this.currentTimeEl && (this.currentTimeEl.textContent = E(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.updateActiveMarker(), this.updateSeekAccessibility();
1175    }
1176    updateBPMDisplay() {
1177      let t2 = this.options.bpm || this.detectedBPM;
1178      this.bpmEl && this.bpmValueEl && t2 && (this.bpmValueEl.textContent = Math.round(t2), this.bpmEl.style.display = "inline-flex");
1179    }
1180    refreshTheme() {
1181      if (!this._autoTheme) return;
1182      this._scheme = R(this.container);
1183      let t2 = J(this.options.colorPreset, this.container);
1184      for (let i2 of this._presetKeys || []) i2 in t2 && (this.options[i2] = t2[i2]);
1185      this._applyThemeColors();
1186    }
1187    _applyThemeColors() {
1188      this.container.classList.toggle("waveform-theme-light", this._scheme === "light"), this.canvas && this.drawWaveform();
1189    }
1190    static _watchTheme() {
1191      if (e2._themeWatch || typeof document > "u") return;
1192      let t2 = () => requestAnimationFrame(() => {
1193        e2.instances.forEach((a2) => {
1194          try {
1195            a2.refreshTheme();
1196          } catch {
1197          }
1198        });
1199      }), i2 = { attributes: true, attributeFilter: ["class", "data-theme", "data-color-scheme", "style"] }, s2 = new MutationObserver(t2);
1200      s2.observe(document.documentElement, i2), document.body && s2.observe(document.body, i2);
1201      let r2 = null;
1202      try {
1203        r2 = window.matchMedia("(prefers-color-scheme: dark)"), r2.addEventListener("change", t2);
1204      } catch {
1205      }
1206      e2._themeWatch = { obs: s2, mq: r2, refresh: t2 };
1207    }
1208    updateSpeedUI() {
1209      if (!this.audio) return;
1210      let t2 = this.container.querySelector(".speed-value");
1211      if (t2) {
1212        let i2 = this.audio.playbackRate;
1213        t2.textContent = i2 === 1 ? "1x" : `$i2}x`;
1214      }
1215      this.container.querySelectorAll(".speed-option").forEach((i2) => {
1216        let s2 = parseFloat(i2.dataset.rate) === this.audio.playbackRate;
1217        i2.classList.toggle("active", s2), i2.setAttribute("aria-checked", s2 ? "true" : "false");
1218      });
1219    }
1220    play() {
1221      if (this.options.singlePlay && e2.currentlyPlaying && e2.currentlyPlaying !== this && e2.currentlyPlaying.pause(), this.options.audioMode === "external") {
1222        this._emit("waveformplayer:request-play", this._buildTrackDetail(), true).defaultPrevented || (e2.currentlyPlaying = this);
1223        return;
1224      }
1225      return e2.currentlyPlaying = this, this.audio.play();
1226    }
1227    pause() {
1228      if (e2.currentlyPlaying === this && (e2.currentlyPlaying = null), this.options.audioMode === "external") {
1229        this._emit("waveformplayer:request-pause", this._buildTrackDetail(), true);
1230        return;
1231      }
1232      this.audio.pause();
1233    }
1234    _buildTrackDetail() {
1235      return { url: this.options.url, title: this.options.title, artist: this.options.artist, artwork: this.options.artwork, markers: this.options.markers, waveform: this.options.waveform, id: this.id, player: this };
1236    }
1237    setPlayingState(t2) {
1238      let i2 = this.isPlaying;
1239      this.isPlaying = !!t2, this.setPlayButtonState(this.isPlaying), this.isPlaying && !i2 ? (this.startSmoothUpdate?.(), this._emit("waveformplayer:play", { player: this, url: this.options.url }), this.options.onPlay && this.options.onPlay(this)) : !this.isPlaying && i2 && (this.stopSmoothUpdate?.(), this._emit("waveformplayer:pause", { player: this, url: this.options.url }), this.options.onPause && this.options.onPause(this));
1240    }
1241    setProgress(t2, i2) {
1242      !i2 || i2 <= 0 || (this.progress = m2(t2 / i2), this.currentTimeEl && (this.currentTimeEl.textContent = E(t2)), this._extDuration = i2, this.totalTimeEl && (!this.totalTimeEl.dataset._extSet || this.totalTimeEl.dataset._extDur !== String(i2)) && (this.totalTimeEl.textContent = E(i2), this.totalTimeEl.dataset._extSet = "1", this.totalTimeEl.dataset._extDur = String(i2)), this.drawWaveform?.(), this.updateActiveMarker(), this._emit("waveformplayer:timeupdate", { player: this, currentTime: t2, duration: i2, progress: this.progress, url: this.options.url }), this.options.onTimeUpdate && this.options.onTimeUpdate(t2, i2, this), this.progress >= 1 ? this._extEnded || (this._extEnded = true, this._emit("waveformplayer:ended", { player: this, url: this.options.url, currentTime: i2, duration: i2 }), this.options.onEnd && this.options.onEnd(this)) : this._extEnded = false, this.updateSeekAccessibility());
1243    }
1244    togglePlay() {
1245      this.isPlaying ? this.pause() : this.play();
1246    }
1247    seekTo(t2) {
1248      this.audio && this.audio.duration && (this.audio.currentTime = m2(t2, 0, this.audio.duration), this.updateProgress());
1249    }
1250    seekToPercent(t2) {
1251      this.audio && this.audio.duration && (this.audio.currentTime = this.audio.duration * m2(t2), this.updateProgress());
1252    }
1253    setVolume(t2) {
1254      let i2 = Number(t2);
1255      this.audio && Number.isFinite(i2) && (this.audio.volume = m2(i2));
1256    }
1257    setPlaybackRate(t2) {
1258      if (!this.audio) return;
1259      let i2 = _(t2, null, { min: N2, max: F });
1260      i2 !== null && (this.audio.playbackRate = i2, this.options.playbackRate = i2, this.updateSpeedUI());
1261    }
1262    destroy() {
1263      this.isDestroying = true, this._emit("waveformplayer:destroy", { player: this, url: this.options.url }), this.pause(), this.stopSmoothUpdate(), clearTimeout(this._markerLabelTimer), this._ac?.abort(), this.resizeObserver && (this.resizeObserver.disconnect(), this.resizeObserver = null), this.resizeHandler && (window.removeEventListener("resize", this.resizeHandler), this.resizeHandler = null), e2.instances.delete(this.id), e2.currentlyPlaying === this && (e2.currentlyPlaying = null), this.audio && (this.audio.pause(), this.audio.src = "", this.audio.load(), this.audio = null), this.container.innerHTML = "", delete this.container.dataset.waveformInitialized, this.canvas = null, this.ctx = null, this.playBtn = null, this.waveformData = [];
1264    }
1265    static getInstance(t2) {
1266      if (typeof t2 == "string") {
1267        let i2 = this.instances.get(t2);
1268        if (i2) return i2;
1269        let s2 = document.getElementById(t2);
1270        if (s2) return Array.from(this.instances.values()).find((r2) => r2.container === s2);
1271      }
1272      if (t2 instanceof HTMLElement) return Array.from(this.instances.values()).find((i2) => i2.container === t2);
1273    }
1274    static getAllInstances() {
1275      return Array.from(this.instances.values());
1276    }
1277    static destroyAll() {
1278      this.instances.forEach((t2) => t2.destroy()), this.instances.clear();
1279    }
1280    static async generateWaveformData(t2, i2 = 1800) {
1281      try {
1282        return (await G(t2, i2)).peaks;
1283      } catch (s2) {
1284        throw console.error("[WaveformPlayer] Failed to generate waveform:", s2), s2;
1285      }
1286    }
1287    static getPeaksUrl(t2) {
1288      if (!t2) return;
1289      let i2 = t2.replace(/\.(mp3|wav|ogg|flac|m4a|aac)(\?[^#]*)?(#.*)?$/i, ".json$2$3");
1290      return i2 === t2 ? void 0 : i2;
1291    }
1292  };
1293  T.utils = { formatTime: E, extractTitleFromUrl: I, escapeHtml: S, isSafeHref: st, parseDataAttributes: O, detectColorScheme: R };
1294  var et = () => typeof window < "u" && typeof document < "u";
1295  var Nt = () => true;
1296  function kt(e3) {
1297    if (!(e3.dataset.waveformInitialized === "true" || T.getInstance(e3))) try {
1298      new T(e3), e3.dataset.waveformInitialized = "true";
1299    } catch (t2) {
1300      console.error("[WaveformPlayer] Failed to initialize:", t2, e3);
1301    }
1302  }
1303  function tt(e3 = document) {
1304    if (!et()) return;
1305    let t2 = e3 || document;
1306    t2.matches?.("[data-waveform-player]") && kt(t2), t2.querySelectorAll("[data-waveform-player]").forEach(kt);
1307  }
1308  et() && !Nt() && (document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", () => tt()) : tt());
1309  T.init = tt;
1310  et() && (window.WaveformPlayer = T);
1311  var se = T;
1312  
1313  // packages/block-library/build-module/utils/waveform-utils.mjs
1314  var DEFAULT_WAVEFORM_HEIGHT = 100;
1315  var DEFAULT_SEEK_LABEL = "Seek";
1316  function getComputedStyle2(element) {
1317    return element.ownerDocument.defaultView.getComputedStyle(element);
1318  }
1319  function getTopLevelGradientParts(gradientValue) {
1320    const match = gradientValue?.trim().match(/^[\w-]+-gradient\((.*)\)$/i);
1321    if (!match) {
1322      return [];
1323    }
1324    const parts = [];
1325    let depth = 0;
1326    let current = "";
1327    for (const character of match[1]) {
1328      if (character === "(") {
1329        ++depth;
1330      } else if (character === ")") {
1331        --depth;
1332      }
1333      if (character === "," && depth === 0) {
1334        parts.push(current.trim());
1335        current = "";
1336        continue;
1337      }
1338      current += character;
1339    }
1340    if (current.trim()) {
1341      parts.push(current.trim());
1342    }
1343    return parts;
1344  }
1345  function getLeadingColorFunction(value) {
1346    const match = value.match(/^([\w-]+)\(/);
1347    if (!match) {
1348      return;
1349    }
1350    const supportedFunctions = [
1351      "color",
1352      "color-mix",
1353      "hsl",
1354      "hsla",
1355      "hwb",
1356      "lab",
1357      "lch",
1358      "oklab",
1359      "oklch",
1360      "rgb",
1361      "rgba",
1362      "var"
1363    ];
1364    if (!supportedFunctions.includes(match[1].toLowerCase())) {
1365      return;
1366    }
1367    let depth = 0;
1368    let foundOpeningParenthesis = false;
1369    for (let index = 0; index < value.length; index++) {
1370      const character = value[index];
1371      if (character === "(") {
1372        foundOpeningParenthesis = true;
1373        ++depth;
1374      } else if (character === ")") {
1375        --depth;
1376      }
1377      if (foundOpeningParenthesis && depth === 0) {
1378        return value.slice(0, index + 1);
1379      }
1380    }
1381  }
1382  function getColorStopValue(gradientPart) {
1383    const colorFunction = getLeadingColorFunction(gradientPart);
1384    if (colorFunction) {
1385      return colorFunction;
1386    }
1387    const [possibleColor] = gradientPart.split(/\s+/);
1388    if (w(possibleColor).isValid()) {
1389      return possibleColor;
1390    }
1391  }
1392  function getWaveformGradientDirection(gradientValue) {
1393    const parts = getTopLevelGradientParts(gradientValue);
1394    const direction = parts[0];
1395    const angleMatch = direction?.match(/^(-?\d+(?:\.\d+)?)deg$/i);
1396    if (angleMatch) {
1397      const angle = (Number(angleMatch[1]) % 360 + 360) % 360;
1398      if (angle === 90 || angle === 270) {
1399        return "horizontal";
1400      }
1401      if (angle === 0 || angle === 180) {
1402        return "vertical";
1403      }
1404      return "diagonal";
1405    }
1406    if (!direction?.startsWith("to ")) {
1407      return void 0;
1408    }
1409    const sideOrCorner = direction.toLowerCase().replace(/^to\s+/, "");
1410    const hasHorizontalSide = sideOrCorner.includes("left") || sideOrCorner.includes("right");
1411    const hasVerticalSide = sideOrCorner.includes("top") || sideOrCorner.includes("bottom");
1412    if (hasHorizontalSide && hasVerticalSide) {
1413      return "diagonal";
1414    }
1415    if (hasHorizontalSide) {
1416      return "horizontal";
1417    }
1418    if (hasVerticalSide) {
1419      return "vertical";
1420    }
1421  }
1422  function resolveColorValue(element, colorValue) {
1423    if (!colorValue || w(colorValue).isValid()) {
1424      return colorValue;
1425    }
1426    const colorResolver = element.ownerDocument.createElement("span");
1427    colorResolver.style.color = colorValue;
1428    if (!colorResolver.style.color) {
1429      return colorValue;
1430    }
1431    element.appendChild(colorResolver);
1432    const resolvedColor = getComputedStyle2(colorResolver).color;
1433    colorResolver.remove();
1434    return resolvedColor && w(resolvedColor).isValid() ? resolvedColor : colorValue;
1435  }
1436  function getResolvedGradientStops(element, gradientValue) {
1437    const stops = getWaveformGradientStops(gradientValue)?.map((colorValue) => resolveColorValue(element, colorValue)).filter((colorValue) => w(colorValue).isValid());
1438    return stops?.length > 1 ? stops : void 0;
1439  }
1440  function applyAlpha(colorValue, alpha) {
1441    if (Array.isArray(colorValue)) {
1442      return colorValue.map(
1443        (color) => w(color).alpha(alpha).toRgbString()
1444      );
1445    }
1446    return w(colorValue).alpha(alpha).toRgbString();
1447  }
1448  function getRepresentativeColor(colorValue) {
1449    if (Array.isArray(colorValue)) {
1450      return colorValue[colorValue.length - 1];
1451    }
1452    return colorValue;
1453  }
1454  function getWaveformGradientStops(gradientValue) {
1455    const stops = getTopLevelGradientParts(gradientValue).map(getColorStopValue).filter(Boolean);
1456    return stops.length > 1 ? stops : void 0;
1457  }
1458  function serializeColorValue(colorValue) {
1459    return Array.isArray(colorValue) ? JSON.stringify(colorValue) : colorValue;
1460  }
1461  function getWaveformColors(element, waveformColorValue, textColorValue, waveformGradientValue) {
1462    const textColor = textColorValue || getComputedStyle2(element).color;
1463    const waveformGradientStops = getResolvedGradientStops(
1464      element,
1465      waveformGradientValue
1466    );
1467    const waveformBaseColor = waveformGradientStops || waveformColorValue || textColor;
1468    const waveformColor = applyAlpha(waveformBaseColor, 0.3);
1469    const progressColor = applyAlpha(waveformBaseColor, 0.6);
1470    const waveformGradient = waveformGradientStops ? getWaveformGradientDirection(waveformGradientValue) : void 0;
1471    return {
1472      textColor,
1473      waveformColor,
1474      progressColor,
1475      ...waveformGradient && { waveformGradient }
1476    };
1477  }
1478  function createWaveformContainer({
1479    url,
1480    title,
1481    artist,
1482    artwork,
1483    waveformColor,
1484    progressColor,
1485    waveformGradient,
1486    buttonColor,
1487    seekLabel,
1488    seekValueText,
1489    height = DEFAULT_WAVEFORM_HEIGHT,
1490    waveformStyle = "bars"
1491  }) {
1492    const container = document.createElement("div");
1493    container.setAttribute("data-waveform-player", "");
1494    container.setAttribute("data-url", url);
1495    container.setAttribute("data-height", String(height));
1496    container.setAttribute("data-waveform-style", waveformStyle);
1497    container.setAttribute(
1498      "data-waveform-color",
1499      serializeColorValue(waveformColor)
1500    );
1501    container.setAttribute(
1502      "data-progress-color",
1503      serializeColorValue(progressColor)
1504    );
1505    if (waveformGradient) {
1506      container.setAttribute("data-waveform-gradient", waveformGradient);
1507    }
1508    container.setAttribute("data-button-color", buttonColor);
1509    container.setAttribute(
1510      "data-seek-label",
1511      getSeekControlLabel(seekLabel)
1512    );
1513    if (seekValueText) {
1514      container.setAttribute("data-seek-value-text", seekValueText);
1515    }
1516    container.setAttribute("data-text-color", buttonColor);
1517    container.setAttribute("data-text-secondary-color", buttonColor);
1518    if (title) {
1519      container.setAttribute("data-title", title);
1520    }
1521    if (artist) {
1522      container.setAttribute("data-artist", artist);
1523    }
1524    if (artwork) {
1525      container.setAttribute("data-artwork", artwork);
1526    }
1527    return container;
1528  }
1529  function applyWaveformPlayerStyles(container, {
1530    backgroundColor,
1531    backgroundGradient,
1532    textColor,
1533    playButtonColor,
1534    playButtonGradient
1535  } = {}) {
1536    const waveformContainer = container.querySelector(".waveform-container");
1537    const playButton = container.querySelector(".waveform-btn");
1538    const playButtonBaseColor = getRepresentativeColor(
1539      getResolvedGradientStops(container, playButtonGradient) || playButtonColor
1540    );
1541    if (playButtonBaseColor) {
1542      container.style.setProperty(
1543        "--wfp-button-color",
1544        playButtonBaseColor
1545      );
1546    } else {
1547      container.style.removeProperty("--wfp-button-color");
1548    }
1549    if (textColor) {
1550      container.style.setProperty("--wfp-text-color", textColor);
1551      container.style.setProperty("--wfp-text-secondary-color", textColor);
1552    } else {
1553      container.style.removeProperty("--wfp-text-color");
1554      container.style.removeProperty("--wfp-text-secondary-color");
1555    }
1556    if (playButton) {
1557      if (playButtonGradient) {
1558        playButton.style.background = playButtonGradient;
1559      } else {
1560        playButton.style.removeProperty("background");
1561      }
1562    }
1563    if (waveformContainer) {
1564      if (backgroundGradient) {
1565        waveformContainer.style.background = backgroundGradient;
1566      } else if (backgroundColor) {
1567        waveformContainer.style.removeProperty("background");
1568        waveformContainer.style.backgroundColor = backgroundColor;
1569      } else {
1570        waveformContainer.style.removeProperty("background");
1571        waveformContainer.style.removeProperty("background-color");
1572      }
1573    }
1574  }
1575  function styleSvgIcons(container, buttonColor) {
1576    const isButtonDark = w(buttonColor).isDark();
1577    const iconColor = isButtonDark ? "#ffffff" : "#000000";
1578    const svgPaths = container.querySelectorAll("svg path");
1579    svgPaths.forEach((path) => {
1580      path.style.fill = iconColor;
1581    });
1582  }
1583  function setupPlayButtonAccessibility(container, { play: playLabel = "Play", pause: pauseLabel = "Pause" } = {}) {
1584    const playBtn = container.querySelector(".waveform-btn");
1585    if (!playBtn) {
1586      return;
1587    }
1588    playBtn.setAttribute("aria-label", playLabel);
1589    const onPlay = () => playBtn.setAttribute("aria-label", pauseLabel);
1590    const onPause = () => playBtn.setAttribute("aria-label", playLabel);
1591    container.addEventListener("waveformplayer:play", onPlay);
1592    container.addEventListener("waveformplayer:pause", onPause);
1593    container.addEventListener("waveformplayer:ended", onPause);
1594    return () => {
1595      container.removeEventListener("waveformplayer:play", onPlay);
1596      container.removeEventListener("waveformplayer:pause", onPause);
1597      container.removeEventListener("waveformplayer:ended", onPause);
1598    };
1599  }
1600  function getSeekControlLabel(label) {
1601    return label || DEFAULT_SEEK_LABEL;
1602  }
1603  function updateSeekControlLabel(instance, label) {
1604    const seekLabel = getSeekControlLabel(label);
1605    instance.options.seekLabel = seekLabel;
1606    instance.applySeekLabel?.(seekLabel);
1607    const seekControl = instance?.container?.querySelector(
1608      ".waveform-container"
1609    );
1610    if (seekControl) {
1611      seekControl.setAttribute("aria-label", seekLabel);
1612    }
1613  }
1614  function setupPlayButtonArtwork(container, artworkUrl) {
1615    if (!artworkUrl) {
1616      container.classList.remove("has-play-button-artwork");
1617      container.style.removeProperty("--wp--playlist--play-button-artwork");
1618      return;
1619    }
1620    container.classList.add("has-play-button-artwork");
1621    container.style.setProperty(
1622      "--wp--playlist--play-button-artwork",
1623      `url($JSON.stringify(artworkUrl)})`
1624    );
1625  }
1626  function logPlayError(error) {
1627    if (error.name === "AbortError") {
1628      return;
1629    }
1630    console.error("Playlist play error:", error);
1631  }
1632  function initWaveformPlayer(element, {
1633    src,
1634    title,
1635    artist,
1636    image,
1637    imageAlt,
1638    waveformColor: waveformColorValue,
1639    waveformGradient: waveformGradientValue,
1640    textColor: textColorValue,
1641    backgroundColor,
1642    backgroundGradient,
1643    autoPlay,
1644    onEnded,
1645    labels,
1646    waveformStyle,
1647    showPlayButtonArtwork = false
1648  }) {
1649    const playerArtwork = showPlayButtonArtwork ? void 0 : image;
1650    const { textColor, waveformColor, progressColor, waveformGradient } = getWaveformColors(
1651      element,
1652      waveformColorValue,
1653      textColorValue,
1654      waveformGradientValue
1655    );
1656    const waveformGradientStops = getResolvedGradientStops(
1657      element,
1658      waveformGradientValue
1659    );
1660    const waveformButtonColor = getRepresentativeColor(
1661      waveformGradientStops || waveformColorValue
1662    );
1663    const container = createWaveformContainer({
1664      url: src,
1665      title,
1666      artist,
1667      artwork: playerArtwork,
1668      waveformColor,
1669      progressColor,
1670      waveformGradient,
1671      buttonColor: textColor,
1672      seekLabel: title || labels?.seek,
1673      seekValueText: labels?.seekValueText,
1674      waveformStyle
1675    });
1676    element.appendChild(container);
1677    const instance = new se(container);
1678    if (instance.artworkEl) {
1679      instance.artworkEl.alt = imageAlt || "";
1680    }
1681    applyWaveformPlayerStyles(container, {
1682      backgroundColor,
1683      backgroundGradient,
1684      textColor,
1685      playButtonColor: showPlayButtonArtwork ? void 0 : waveformButtonColor,
1686      playButtonGradient: showPlayButtonArtwork ? void 0 : waveformGradientValue
1687    });
1688    let cleanupPlayButtonAccessibility;
1689    const handlers = {
1690      ready: () => {
1691        styleSvgIcons(container, waveformButtonColor || textColor);
1692        if (showPlayButtonArtwork) {
1693          setupPlayButtonArtwork(container, image);
1694        }
1695        cleanupPlayButtonAccessibility = setupPlayButtonAccessibility(
1696          container,
1697          labels
1698        );
1699        if (autoPlay) {
1700          instance.play()?.catch(logPlayError);
1701        }
1702      },
1703      ended: () => onEnded?.()
1704    };
1705    container.addEventListener("waveformplayer:ready", handlers.ready);
1706    container.addEventListener("waveformplayer:ended", handlers.ended);
1707    return {
1708      instance,
1709      container,
1710      destroy: () => {
1711        cleanupPlayButtonAccessibility?.();
1712        container.removeEventListener(
1713          "waveformplayer:ready",
1714          handlers.ready
1715        );
1716        container.removeEventListener(
1717          "waveformplayer:ended",
1718          handlers.ended
1719        );
1720        instance.destroy();
1721        container.remove();
1722      }
1723    };
1724  }
1725  
1726  // packages/block-library/build-module/playlist/view.mjs
1727  var playerState = /* @__PURE__ */ new WeakMap();
1728  var playlistPlayerState = /* @__PURE__ */ new Map();
1729  var { state } = store(
1730    "core/playlist",
1731    {
1732      state: {
1733        playlists: {},
1734        get isCurrentTrack() {
1735          const { currentId, trackId } = getContext();
1736          return currentId === trackId;
1737        },
1738        get isCurrentTrackPlaying() {
1739          const { currentId, isPlaying, trackId } = getContext();
1740          return currentId === trackId && !!isPlaying;
1741        },
1742        get trackButtonActionLabel() {
1743          const { labelPauseTrack, labelSelectTrack } = getContext();
1744          return state.isCurrentTrackPlaying ? labelPauseTrack : labelSelectTrack;
1745        }
1746      },
1747      actions: {
1748        changeTrack() {
1749          const context = getContext();
1750          if (context.currentId === context.trackId) {
1751            const player = playlistPlayerState.get(
1752              context.playlistId
1753            )?.instance;
1754            if (player?.isPlaying) {
1755              context.isPlaying = false;
1756              player.pause();
1757            } else {
1758              player?.play()?.catch(logPlayError);
1759            }
1760            return;
1761          }
1762          context.isPlaying = false;
1763          context.currentId = context.trackId;
1764        }
1765      },
1766      callbacks: {
1767        initWaveformPlayer() {
1768          const context = getContext();
1769          const { ref } = getElement();
1770          if (!context.currentId || !ref) {
1771            return;
1772          }
1773          const track = state.playlists[context.playlistId]?.tracks[context.currentId];
1774          if (!track?.url) {
1775            return;
1776          }
1777          const existing = playerState.get(ref);
1778          if (existing?.url === track.url) {
1779            return;
1780          }
1781          const shouldAutoPlay = !!existing?.url;
1782          initPlayer(ref, track, shouldAutoPlay, context);
1783        }
1784      }
1785    },
1786    { lock: true }
1787  );
1788  function initPlayer(ref, track, shouldAutoPlay, context) {
1789    const existing = playerState.get(ref);
1790    const showPlayButtonArtwork = context.showPlayButtonArtwork === true;
1791    const playerArtwork = showPlayButtonArtwork ? "" : track.image;
1792    if (existing?.instance) {
1793      const shouldRecreatePlayer = !!existing.instance.artworkEl !== !!playerArtwork;
1794      if (shouldRecreatePlayer) {
1795        existing.destroy?.();
1796        playerState.delete(ref);
1797      } else {
1798        playlistPlayerState.set(context.playlistId, existing);
1799        existing.instance.loadTrack(track.url, track.title, track.artist, {
1800          artwork: playerArtwork,
1801          artworkAlt: playerArtwork ? track.imageAlt : ""
1802        }).then(() => {
1803          existing.url = track.url;
1804          if (existing.instance.artworkEl) {
1805            existing.instance.artworkEl.alt = track.imageAlt || "";
1806          }
1807          updateSeekControlLabel(
1808            existing.instance,
1809            track.title || ref.dataset.labelSeek
1810          );
1811          if (showPlayButtonArtwork) {
1812            setupPlayButtonArtwork(
1813              existing.container,
1814              track.image
1815            );
1816          }
1817          if (shouldAutoPlay) {
1818            existing.instance.play()?.catch(logPlayError);
1819          }
1820        }).catch(logPlayError);
1821        return;
1822      }
1823    }
1824    const labels = {
1825      play: ref.dataset.labelPlay,
1826      pause: ref.dataset.labelPause,
1827      seek: ref.dataset.labelSeek,
1828      seekValueText: ref.dataset.labelSeekValue
1829    };
1830    const player = initWaveformPlayer(ref, {
1831      src: track.url,
1832      title: track.title,
1833      artist: track.artist,
1834      image: track.image,
1835      imageAlt: track.imageAlt,
1836      waveformColor: ref.dataset.waveformPlayerColor,
1837      waveformGradient: ref.dataset.waveformPlayerGradient,
1838      backgroundColor: ref.dataset.waveformPlayerBackgroundColor,
1839      backgroundGradient: ref.dataset.waveformPlayerBackgroundGradient,
1840      autoPlay: shouldAutoPlay,
1841      labels,
1842      waveformStyle: context.waveformStyle,
1843      showPlayButtonArtwork,
1844      onEnded: () => {
1845        const currentIndex = context.tracks.findIndex(
1846          (trackId) => trackId === context.currentId
1847        );
1848        const nextTrack = context.tracks[currentIndex + 1];
1849        if (nextTrack) {
1850          context.currentId = nextTrack;
1851        }
1852      }
1853    });
1854    const setIsPlaying = (isPlaying) => {
1855      context.isPlaying = isPlaying;
1856    };
1857    const onPlay = () => setIsPlaying(true);
1858    const onPause = () => setIsPlaying(false);
1859    player.container.addEventListener("waveformplayer:play", onPlay);
1860    player.container.addEventListener("waveformplayer:pause", onPause);
1861    player.container.addEventListener("waveformplayer:ended", onPause);
1862    const destroy = () => {
1863      player.container.removeEventListener("waveformplayer:play", onPlay);
1864      player.container.removeEventListener("waveformplayer:pause", onPause);
1865      player.container.removeEventListener("waveformplayer:ended", onPause);
1866      player.destroy();
1867    };
1868    const nextState = {
1869      url: track.url,
1870      instance: player.instance,
1871      container: player.container,
1872      destroy
1873    };
1874    playerState.set(ref, nextState);
1875    playlistPlayerState.set(context.playlistId, nextState);
1876  }


Generated : Tue Sep 22 08:20:31 2026 Cross-referenced by PHPXref