Your Name 1912bcd25b
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled
chore: sync all remaining local workspace changes
2026-05-08 11:26:57 +08:00

2621 lines
83 KiB
JavaScript

/*
* Extracted from browser-delivered Turbopack chunk: fd0220e4d10052af.701bdafa2d.js
* Module id: 169872
* For reading/searching only; this factory depends on the original Turbopack runtime.
*/
const moduleFactory = (e) => {
"use strict";
let t;
var n = e.i(462214),
i = e.i(358379);
function r(e, t, n, i) {
return new (n || (n = Promise))(function (r, a) {
function o(e) {
try {
c(i.next(e));
} catch (e) {
a(e);
}
}
function s(e) {
try {
c(i.throw(e));
} catch (e) {
a(e);
}
}
function c(e) {
var t;
e.done
? r(e.value)
: ((t = e.value) instanceof n
? t
: new n(function (e) {
e(t);
})
).then(o, s);
}
c((i = i.apply(e, t || [])).next());
});
}
"function" == typeof SuppressedError && SuppressedError;
class a {
constructor() {
this.listeners = {};
}
on(e, t, n) {
if (
(this.listeners[e] || (this.listeners[e] = new Set()),
null == n ? void 0 : n.once)
) {
let n = (...i) => {
this.un(e, n), t(...i);
};
return this.listeners[e].add(n), () => this.un(e, n);
}
return this.listeners[e].add(t), () => this.un(e, t);
}
un(e, t) {
var n;
null == (n = this.listeners[e]) || n.delete(t);
}
once(e, t) {
return this.on(e, t, { once: !0 });
}
unAll() {
this.listeners = {};
}
emit(e, ...t) {
this.listeners[e] && this.listeners[e].forEach((e) => e(...t));
}
}
let o = {
decode: function (e, t) {
return r(this, void 0, void 0, function* () {
let n = new AudioContext({ sampleRate: t });
try {
return yield n.decodeAudioData(e);
} finally {
n.close();
}
});
},
createBuffer: function (e, t) {
if (!e || 0 === e.length)
throw Error("channelData must be a non-empty array");
if (t <= 0) throw Error("duration must be greater than 0");
if (("number" == typeof e[0] && (e = [e]), !e[0] || 0 === e[0].length))
throw Error("channelData must contain non-empty channel arrays");
!(function (e) {
let t = e[0];
if (t.some((e) => e > 1 || e < -1)) {
let n = t.length,
i = 0;
for (let e = 0; e < n; e++) {
let n = Math.abs(t[e]);
n > i && (i = n);
}
for (let t of e) for (let e = 0; e < n; e++) t[e] /= i;
}
})(e);
let n = e.map((e) =>
e instanceof Float32Array ? e : Float32Array.from(e),
);
return {
duration: t,
length: n[0].length,
sampleRate: n[0].length / t,
numberOfChannels: n.length,
getChannelData: (e) => {
let t = n[e];
if (!t) throw Error(`Channel ${e} not found`);
return t;
},
copyFromChannel: AudioBuffer.prototype.copyFromChannel,
copyToChannel: AudioBuffer.prototype.copyToChannel,
};
},
};
function s(e, t, n) {
let i = (function e(t, n) {
let i = n.xmlns
? document.createElementNS(n.xmlns, t)
: document.createElement(t);
for (let [t, r] of Object.entries(n))
if ("children" === t && r)
for (let [t, n] of Object.entries(r))
n instanceof Node
? i.appendChild(n)
: "string" == typeof n
? i.appendChild(document.createTextNode(n))
: i.appendChild(e(t, n));
else
"style" === t
? Object.assign(i.style, r)
: "textContent" === t
? (i.textContent = r)
: i.setAttribute(t, r.toString());
return i;
})(e, t || {});
return null == n || n.appendChild(i), i;
}
var c = Object.freeze({ __proto__: null, createElement: s, default: s });
let l = {
fetchBlob: function (e, t, n) {
return r(this, void 0, void 0, function* () {
let i = yield fetch(e, n);
if (i.status >= 400)
throw Error(`Failed to fetch ${e}: ${i.status} (${i.statusText})`);
return (
(function (e, t) {
r(this, void 0, void 0, function* () {
if (!e.body || !e.headers) return;
let n = e.body.getReader(),
i = Number(e.headers.get("Content-Length")) || 0,
r = 0,
a = (e) => {
t(
Math.round(
((r += (null == e ? void 0 : e.length) || 0) / i) * 100,
),
);
};
try {
for (;;) {
let e = yield n.read();
if (e.done) break;
a(e.value);
}
} catch (e) {
console.warn("Progress tracking error:", e);
}
});
})(i.clone(), t),
i.blob()
);
});
},
};
function u(e) {
let t = e,
n = new Set();
return {
get value() {
return t;
},
set(e) {
Object.is(t, e) || ((t = e), n.forEach((e) => e(t)));
},
update(e) {
this.set(e(t));
},
subscribe: (e) => (n.add(e), () => n.delete(e)),
};
}
function h(e, t) {
let n = u(e());
return (
t.forEach((t) =>
t.subscribe(() => {
let t = e();
Object.is(n.value, t) || n.set(t);
}),
),
{
get value() {
return n.value;
},
subscribe: (e) => n.subscribe(e),
}
);
}
function f(e, t) {
let n,
i = () => {
n && (n(), (n = void 0)), (n = e());
},
r = t.map((e) => e.subscribe(i));
return (
i(),
() => {
n && (n(), (n = void 0)), r.forEach((e) => e());
}
);
}
class d extends a {
get isPlayingSignal() {
return this._isPlaying;
}
get currentTimeSignal() {
return this._currentTime;
}
get durationSignal() {
return this._duration;
}
get volumeSignal() {
return this._volume;
}
get mutedSignal() {
return this._muted;
}
get playbackRateSignal() {
return this._playbackRate;
}
get seekingSignal() {
return this._seeking;
}
constructor(e) {
super(),
(this.isExternalMedia = !1),
(this.reactiveMediaEventCleanups = []),
e.media
? ((this.media = e.media), (this.isExternalMedia = !0))
: (this.media = document.createElement("audio")),
(this._isPlaying = u(!1)),
(this._currentTime = u(0)),
(this._duration = u(0)),
(this._volume = u(this.media.volume)),
(this._muted = u(this.media.muted)),
(this._playbackRate = u(this.media.playbackRate || 1)),
(this._seeking = u(!1)),
this.setupReactiveMediaEvents(),
e.mediaControls && (this.media.controls = !0),
e.autoplay && (this.media.autoplay = !0),
null != e.playbackRate &&
this.onMediaEvent(
"canplay",
() => {
null != e.playbackRate &&
(this.media.playbackRate = e.playbackRate);
},
{ once: !0 },
);
}
setupReactiveMediaEvents() {
this.reactiveMediaEventCleanups.push(
this.onMediaEvent("play", () => {
this._isPlaying.set(!0);
}),
),
this.reactiveMediaEventCleanups.push(
this.onMediaEvent("pause", () => {
this._isPlaying.set(!1);
}),
),
this.reactiveMediaEventCleanups.push(
this.onMediaEvent("ended", () => {
this._isPlaying.set(!1);
}),
),
this.reactiveMediaEventCleanups.push(
this.onMediaEvent("timeupdate", () => {
this._currentTime.set(this.media.currentTime);
}),
),
this.reactiveMediaEventCleanups.push(
this.onMediaEvent("durationchange", () => {
this._duration.set(this.media.duration || 0);
}),
),
this.reactiveMediaEventCleanups.push(
this.onMediaEvent("loadedmetadata", () => {
this._duration.set(this.media.duration || 0);
}),
),
this.reactiveMediaEventCleanups.push(
this.onMediaEvent("seeking", () => {
this._seeking.set(!0);
}),
),
this.reactiveMediaEventCleanups.push(
this.onMediaEvent("seeked", () => {
this._seeking.set(!1);
}),
),
this.reactiveMediaEventCleanups.push(
this.onMediaEvent("volumechange", () => {
this._volume.set(this.media.volume),
this._muted.set(this.media.muted);
}),
),
this.reactiveMediaEventCleanups.push(
this.onMediaEvent("ratechange", () => {
this._playbackRate.set(this.media.playbackRate);
}),
);
}
onMediaEvent(e, t, n) {
return (
this.media.addEventListener(e, t, n),
() => this.media.removeEventListener(e, t, n)
);
}
getSrc() {
return this.media.currentSrc || this.media.src || "";
}
revokeSrc() {
let e = this.getSrc();
e.startsWith("blob:") && URL.revokeObjectURL(e);
}
canPlayType(e) {
return "" !== this.media.canPlayType(e);
}
setSrc(e, t) {
let n = this.getSrc();
if (e && n === e) return;
this.revokeSrc();
let i =
t instanceof Blob && (this.canPlayType(t.type) || !e)
? URL.createObjectURL(t)
: e;
if ((n && this.media.removeAttribute("src"), i || e))
try {
this.media.src = i;
} catch (t) {
this.media.src = e;
}
}
destroy() {
this.reactiveMediaEventCleanups.forEach((e) => e()),
(this.reactiveMediaEventCleanups = []),
this.isExternalMedia ||
(this.media.pause(),
this.revokeSrc(),
this.media.removeAttribute("src"),
this.media.load(),
this.media.remove());
}
setMediaElement(e) {
this.reactiveMediaEventCleanups.forEach((e) => e()),
(this.reactiveMediaEventCleanups = []),
(this.media = e),
this.setupReactiveMediaEvents();
}
play() {
return r(this, void 0, void 0, function* () {
try {
return yield this.media.play();
} catch (e) {
if (e instanceof DOMException && "AbortError" === e.name) return;
throw e;
}
});
}
pause() {
this.media.pause();
}
isPlaying() {
return !this.media.paused && !this.media.ended;
}
setTime(e) {
this.media.currentTime = Math.max(0, Math.min(e, this.getDuration()));
}
getDuration() {
return this.media.duration;
}
getCurrentTime() {
return this.media.currentTime;
}
getVolume() {
return this.media.volume;
}
setVolume(e) {
this.media.volume = e;
}
getMuted() {
return this.media.muted;
}
setMuted(e) {
this.media.muted = e;
}
getPlaybackRate() {
return this.media.playbackRate;
}
isSeeking() {
return this.media.seeking;
}
setPlaybackRate(e, t) {
null != t && (this.media.preservesPitch = t),
(this.media.playbackRate = e);
}
getMediaElement() {
return this.media;
}
setSinkId(e) {
return this.media.setSinkId(e);
}
}
function p(e, t, n) {
let i = t - e.left,
r = n - e.top;
return [i / e.width, r / e.height];
}
function g(e) {
return !!(e.barWidth || e.barGap || e.barAlign);
}
function b(e, t) {
if (!g(t)) return e;
let n = t.barWidth || 0.5,
i = n + (t.barGap || n / 2);
return 0 === i ? e : Math.floor(e / i) * i;
}
function m({ scrollLeft: e, totalWidth: t, numCanvases: n }) {
if (0 === t) return [0];
let i = Math.floor((e / t) * n);
return [i - 1, i, i + 1];
}
function w(e) {
let t = e._cleanup;
"function" == typeof t && t();
}
class v extends a {
constructor(e, t) {
super(),
(this.timeouts = []),
(this.isScrollable = !1),
(this.audioData = null),
(this.resizeObserver = null),
(this.lastContainerWidth = 0),
(this.isDragging = !1),
(this.subscriptions = []),
(this.unsubscribeOnScroll = []),
(this.dragStream = null),
(this.scrollStream = null),
(this.subscriptions = []),
(this.options = e);
const n = this.parentFromOptionsContainer(e.container);
this.parent = n;
const [i, r] = this.initHtml();
n.appendChild(i),
(this.container = i),
(this.scrollContainer = r.querySelector(".scroll")),
(this.wrapper = r.querySelector(".wrapper")),
(this.canvasWrapper = r.querySelector(".canvases")),
(this.progressWrapper = r.querySelector(".progress")),
(this.cursor = r.querySelector(".cursor")),
t && r.appendChild(t),
this.initEvents();
}
parentFromOptionsContainer(e) {
let t;
if (
("string" == typeof e
? (t = document.querySelector(e))
: e instanceof HTMLElement && (t = e),
!t)
)
throw Error("Container not found");
return t;
}
initEvents() {
var e;
let t, n, i, r;
this.wrapper.addEventListener("click", (e) => {
let [t, n] = p(
this.wrapper.getBoundingClientRect(),
e.clientX,
e.clientY,
);
this.emit("click", t, n);
}),
this.wrapper.addEventListener("dblclick", (e) => {
let [t, n] = p(
this.wrapper.getBoundingClientRect(),
e.clientX,
e.clientY,
);
this.emit("dblclick", t, n);
}),
(!0 !== this.options.dragToSeek &&
"object" != typeof this.options.dragToSeek) ||
this.initDrag(),
(this.scrollStream =
((n = h(
() =>
(function (e) {
let { scrollLeft: t, scrollWidth: n, clientWidth: i } = e;
return 0 === n
? { startX: 0, endX: 1 }
: {
startX: Math.max(0, Math.min(1, t / n)),
endX: Math.max(0, Math.min(1, (t + i) / n)),
};
})(t.value),
[
(t = u({
scrollLeft: (e = this.scrollContainer).scrollLeft,
scrollWidth: e.scrollWidth,
clientWidth: e.clientWidth,
})),
],
)),
(i = h(() => {
var e;
return {
left: (e = t.value).scrollLeft,
right: e.scrollLeft + e.clientWidth,
};
}, [t])),
(r = () => {
t.set({
scrollLeft: e.scrollLeft,
scrollWidth: e.scrollWidth,
clientWidth: e.clientWidth,
});
}),
e.addEventListener("scroll", r, { passive: !0 }),
{
scrollData: t,
percentages: n,
bounds: i,
cleanup: () => {
e.removeEventListener("scroll", r), w(t);
},
}));
let a = f(() => {
let { startX: e, endX: t } = this.scrollStream.percentages.value,
{ left: n, right: i } = this.scrollStream.bounds.value;
this.emit("scroll", e, t, n, i);
}, [this.scrollStream.percentages, this.scrollStream.bounds]);
if ((this.subscriptions.push(a), "function" == typeof ResizeObserver)) {
let e = this.createDelay(100);
(this.resizeObserver = new ResizeObserver(() => {
e()
.then(() => this.onContainerResize())
.catch(() => {});
})),
this.resizeObserver.observe(this.scrollContainer);
}
}
onContainerResize() {
let e = this.parent.clientWidth;
(e === this.lastContainerWidth && "auto" !== this.options.height) ||
((this.lastContainerWidth = e), this.reRender(), this.emit("resize"));
}
initDrag() {
if (this.dragStream) return;
this.dragStream = (function (e, t = {}) {
let { threshold: n = 3, mouseButton: i = 0, touchDelay: r = 100 } = t,
a = u(null),
o = new Map(),
s = matchMedia("(pointer: coarse)").matches,
c = () => {},
l = (t) => {
if (t.button !== i || (o.set(t.pointerId, t), o.size > 1)) return;
let l = t.clientX,
u = t.clientY,
h = !1,
f = Date.now(),
{ left: d, top: p } = e.getBoundingClientRect(),
g = (e) => {
if (
e.defaultPrevented ||
o.size > 1 ||
(s && Date.now() - f < r)
)
return;
let t = e.clientX,
i = e.clientY,
c = t - l,
g = i - u;
(h || Math.abs(c) > n || Math.abs(g) > n) &&
(e.preventDefault(),
e.stopPropagation(),
h ||
(a.set({ type: "start", x: l - d, y: u - p }), (h = !0)),
a.set({
type: "move",
x: t - d,
y: i - p,
deltaX: c,
deltaY: g,
}),
(l = t),
(u = i));
},
b = (e) => {
if ((o.delete(e.pointerId), h)) {
let t = e.clientX,
n = e.clientY;
a.set({ type: "end", x: t - d, y: n - p });
}
c();
},
m = (e) => {
o.delete(e.pointerId),
(e.relatedTarget &&
e.relatedTarget !== document.documentElement) ||
b(e);
},
w = (e) => {
h && (e.stopPropagation(), e.preventDefault());
},
v = (e) => {
e.defaultPrevented || o.size > 1 || (h && e.preventDefault());
};
document.addEventListener("pointermove", g),
document.addEventListener("pointerup", b),
document.addEventListener("pointerout", m),
document.addEventListener("pointercancel", m),
document.addEventListener("touchmove", v, { passive: !1 }),
document.addEventListener("click", w, { capture: !0 }),
(c = () => {
document.removeEventListener("pointermove", g),
document.removeEventListener("pointerup", b),
document.removeEventListener("pointerout", m),
document.removeEventListener("pointercancel", m),
document.removeEventListener("touchmove", v),
setTimeout(() => {
document.removeEventListener("click", w, { capture: !0 });
}, 10);
});
};
return (
e.addEventListener("pointerdown", l),
{
signal: a,
cleanup: () => {
c(), e.removeEventListener("pointerdown", l), o.clear(), w(a);
},
}
);
})(this.wrapper);
let e = f(() => {
var e;
let t = this.dragStream.signal.value;
if (!t) return;
let n = this.wrapper.getBoundingClientRect().width,
i = (e = t.x / n) < 0 ? 0 : e > 1 ? 1 : e;
"start" === t.type
? ((this.isDragging = !0), this.emit("dragstart", i))
: "move" === t.type
? this.emit("drag", i)
: "end" === t.type &&
((this.isDragging = !1), this.emit("dragend", i));
}, [this.dragStream.signal]);
this.subscriptions.push(e);
}
initHtml() {
let e = document.createElement("div"),
t = e.attachShadow({ mode: "open" }),
n =
this.options.cspNonce && "string" == typeof this.options.cspNonce
? this.options.cspNonce.replace(/"/g, "")
: "";
return (
(t.innerHTML = `
<style${n ? ` nonce="${n}"` : ""}>
:host {
user-select: none;
min-width: 1px;
}
:host audio {
display: block;
width: 100%;
}
:host .scroll {
overflow-x: auto;
overflow-y: hidden;
width: 100%;
position: relative;
}
:host .noScrollbar {
scrollbar-color: transparent;
scrollbar-width: none;
}
:host .noScrollbar::-webkit-scrollbar {
display: none;
-webkit-appearance: none;
}
:host .wrapper {
position: relative;
overflow: visible;
z-index: 2;
}
:host .canvases {
min-height: ${this.getHeight(this.options.height, this.options.splitChannels)}px;
pointer-events: none;
}
:host .canvases > div {
position: relative;
}
:host canvas {
display: block;
position: absolute;
top: 0;
image-rendering: pixelated;
}
:host .progress {
pointer-events: none;
position: absolute;
z-index: 2;
top: 0;
left: 0;
width: 0;
height: 100%;
overflow: hidden;
}
:host .progress > div {
position: relative;
}
:host .cursor {
pointer-events: none;
position: absolute;
z-index: 5;
top: 0;
left: 0;
height: 100%;
border-radius: 2px;
}
</style>
<div class="scroll" part="scroll">
<div class="wrapper" part="wrapper">
<div class="canvases" part="canvases"></div>
<div class="progress" part="progress"></div>
<div class="cursor" part="cursor"></div>
</div>
</div>
`),
[e, t]
);
}
setOptions(e) {
if (this.options.container !== e.container) {
let t = this.parentFromOptionsContainer(e.container);
t.appendChild(this.container), (this.parent = t);
}
(!0 !== e.dragToSeek && "object" != typeof this.options.dragToSeek) ||
this.initDrag(),
(this.options = e),
this.reRender();
}
getWrapper() {
return this.wrapper;
}
getWidth() {
return this.scrollContainer.clientWidth;
}
getScroll() {
return this.scrollContainer.scrollLeft;
}
setScroll(e) {
this.scrollContainer.scrollLeft = e;
}
setScrollPercentage(e) {
let { scrollWidth: t } = this.scrollContainer;
this.setScroll(t * e);
}
destroy() {
var e;
this.subscriptions.forEach((e) => e()),
this.container.remove(),
this.resizeObserver &&
(this.resizeObserver.disconnect(), (this.resizeObserver = null)),
null == (e = this.unsubscribeOnScroll) || e.forEach((e) => e()),
(this.unsubscribeOnScroll = []),
this.dragStream &&
(this.dragStream.cleanup(), (this.dragStream = null)),
this.scrollStream &&
(this.scrollStream.cleanup(), (this.scrollStream = null));
}
createDelay(e = 10) {
let t,
n,
i = () => {
t && (clearTimeout(t), (t = void 0)), n && (n(), (n = void 0));
};
return (
this.timeouts.push(i),
() =>
new Promise((r, a) => {
i(),
(n = a),
(t = setTimeout(() => {
(t = void 0), (n = void 0), r();
}, e));
})
);
}
getHeight(e, t) {
var n;
let i =
(null == (n = this.audioData) ? void 0 : n.numberOfChannels) || 1;
return (function ({
optionsHeight: e,
optionsSplitChannels: t,
parentHeight: n,
numberOfChannels: i,
defaultHeight: r = 128,
}) {
if (null == e) return r;
let a = Number(e);
if (!isNaN(a)) return a;
if ("auto" === e) {
let e = n || r;
return (null == t ? void 0 : t.every((e) => !e.overlay))
? e / i
: e;
}
return r;
})({
optionsHeight: e,
optionsSplitChannels: t,
parentHeight: this.parent.clientHeight,
numberOfChannels: i,
defaultHeight: 128,
});
}
convertColorValues(e, t) {
return (function (e, t, n) {
if (!Array.isArray(e)) return e || "";
if (0 === e.length) return "#999";
if (e.length < 2) return e[0] || "";
let i = document.createElement("canvas"),
r = i.getContext("2d"),
a = null != n ? n : i.height * t,
o = r.createLinearGradient(0, 0, 0, a || t),
s = 1 / (e.length - 1);
return (
e.forEach((e, t) => {
o.addColorStop(t * s, e);
}),
o
);
})(e, this.getPixelRatio(), null == t ? void 0 : t.canvas.height);
}
getPixelRatio() {
return Math.max(1, window.devicePixelRatio || 1);
}
renderBarWaveform(e, t, n, i) {
let { width: r, height: a } = n.canvas,
{
halfHeight: o,
barWidth: s,
barRadius: c,
barIndexScale: l,
barSpacing: u,
barMinHeight: h,
} = (function ({
width: e,
height: t,
length: n,
options: i,
pixelRatio: r,
}) {
let a = i.barWidth ? i.barWidth * r : 1,
o = i.barGap ? i.barGap * r : i.barWidth ? a / 2 : 0,
s = a + o || 1;
return {
halfHeight: t / 2,
barWidth: a,
barGap: o,
barRadius: i.barRadius || 0,
barMinHeight: i.barMinHeight ? i.barMinHeight * r : 0,
barIndexScale: n > 0 ? e / s / n : 0,
barSpacing: s,
};
})({
width: r,
height: a,
length: (e[0] || []).length,
options: t,
pixelRatio: this.getPixelRatio(),
}),
f = (function ({
channelData: e,
barIndexScale: t,
barSpacing: n,
barWidth: i,
halfHeight: r,
vScale: a,
canvasHeight: o,
barAlign: s,
barMinHeight: c,
}) {
let l = e[0] || [],
u = e[1] || l,
h = l.length,
f = [],
d = 0,
p = 0,
g = 0;
for (let e = 0; e <= h; e++) {
let h = Math.round(e * t);
if (h > d) {
let { topHeight: e, totalHeight: t } = (function ({
maxTop: e,
maxBottom: t,
halfHeight: n,
vScale: i,
barMinHeight: r = 0,
barAlign: a,
}) {
let o = Math.round(e * n * i),
s = o + Math.round(t * n * i) || 1;
return (
s < r && ((s = r), a || (o = s / 2)),
{ topHeight: o, totalHeight: s }
);
})({
maxTop: p,
maxBottom: g,
halfHeight: r,
vScale: a,
barMinHeight: c,
barAlign: s,
}),
l = (function ({
barAlign: e,
halfHeight: t,
topHeight: n,
totalHeight: i,
canvasHeight: r,
}) {
return "top" === e ? 0 : "bottom" === e ? r - i : t - n;
})({
barAlign: s,
halfHeight: r,
topHeight: e,
totalHeight: t,
canvasHeight: o,
});
f.push({ x: d * n, y: l, width: i, height: t }),
(d = h),
(p = 0),
(g = 0);
}
let b = Math.abs(l[e] || 0),
m = Math.abs(u[e] || 0);
b > p && (p = b), m > g && (g = m);
}
return f;
})({
channelData: e,
barIndexScale: l,
barSpacing: u,
barWidth: s,
halfHeight: o,
vScale: i,
canvasHeight: a,
barAlign: t.barAlign,
barMinHeight: h,
});
for (let e of (n.beginPath(), f))
c && "roundRect" in n
? n.roundRect(e.x, e.y, e.width, e.height, c)
: n.rect(e.x, e.y, e.width, e.height);
n.fill(), n.closePath();
}
renderLineWaveform(e, t, n, i) {
let { width: r, height: a } = n.canvas,
o = (function ({ channelData: e, width: t, height: n, vScale: i }) {
let r = n / 2,
a = e[0] || [];
return [a, e[1] || a].map((e, n) => {
let a = e.length,
o = a ? t / a : 0,
s = 0 === n ? -1 : 1,
c = [{ x: 0, y: r }],
l = 0,
u = 0;
for (let t = 0; t <= a; t++) {
let n = Math.round(t * o);
if (n > l) {
let e = r + (Math.round(u * r * i) || 1) * s;
c.push({ x: l, y: e }), (l = n), (u = 0);
}
let a = Math.abs(e[t] || 0);
a > u && (u = a);
}
return c.push({ x: l, y: r }), c;
});
})({ channelData: e, width: r, height: a, vScale: i });
for (let e of (n.beginPath(), o))
if (e.length) {
n.moveTo(e[0].x, e[0].y);
for (let t = 1; t < e.length; t++) {
let i = e[t];
n.lineTo(i.x, i.y);
}
}
n.fill(), n.closePath();
}
renderWaveform(e, t, n) {
if (
((n.fillStyle = this.convertColorValues(t.waveColor, n)),
t.renderFunction)
)
return void t.renderFunction(e, n);
let i = (function ({
channelData: e,
barHeight: t,
normalize: n,
maxPeak: i,
}) {
var r;
let a = t || 1;
if (!n) return a;
let o = e[0];
if (!o || 0 === o.length) return a;
let s = null != i ? i : 0;
if (!i)
for (let e = 0; e < o.length; e++) {
let t = Math.abs(null != (r = o[e]) ? r : 0);
t > s && (s = t);
}
return s ? a / s : a;
})({
channelData: e,
barHeight: t.barHeight,
normalize: t.normalize,
maxPeak: t.maxPeak,
});
g(t)
? this.renderBarWaveform(e, t, n, i)
: this.renderLineWaveform(e, t, n, i);
}
renderSingleCanvas(e, t, n, i, r, a, o) {
let s = this.getPixelRatio(),
c = document.createElement("canvas");
(c.width = Math.round(n * s)),
(c.height = Math.round(i * s)),
(c.style.width = `${n}px`),
(c.style.height = `${i}px`),
(c.style.left = `${Math.round(r)}px`),
a.appendChild(c);
let l = c.getContext("2d");
if (
(t.renderFunction
? ((l.fillStyle = this.convertColorValues(t.waveColor, l)),
t.renderFunction(e, l))
: this.renderWaveform(e, t, l),
c.width > 0 && c.height > 0)
) {
let e = c.cloneNode(),
n = e.getContext("2d");
n.drawImage(c, 0, 0),
(n.globalCompositeOperation = "source-in"),
(n.fillStyle = this.convertColorValues(t.progressColor, n)),
n.fillRect(0, 0, c.width, c.height),
o.appendChild(e);
}
}
renderMultiCanvas(e, t, n, i, r, a) {
let o = this.getPixelRatio(),
{ clientWidth: s } = this.scrollContainer,
c = n / o,
l = (function ({ clientWidth: e, totalWidth: t, options: n }) {
return b(Math.min(8e3, e, t), n);
})({ clientWidth: s, totalWidth: c, options: t }),
u = {};
if (0 === l) return;
let h = (n) => {
if (n < 0 || n >= f || u[n]) return;
u[n] = !0;
let o = n * l,
s = Math.min(c - o, l);
if ((s = b(s, t)) <= 0) return;
let h = (function ({
channelData: e,
offset: t,
clampedWidth: n,
totalWidth: i,
}) {
return e.map((e) => {
let r = Math.floor((t / i) * e.length),
a = Math.floor(((t + n) / i) * e.length);
return e.slice(r, a);
});
})({ channelData: e, offset: o, clampedWidth: s, totalWidth: c });
this.renderSingleCanvas(h, t, s, i, o, r, a);
},
f = Math.ceil(c / l);
if (!this.isScrollable) {
for (let e = 0; e < f; e++) h(e);
return;
}
if (
(m({
scrollLeft: this.scrollContainer.scrollLeft,
totalWidth: c,
numCanvases: f,
}).forEach((e) => h(e)),
f > 1)
) {
let e = this.on("scroll", () => {
let { scrollLeft: e } = this.scrollContainer;
Object.keys(u).length > 10 &&
((r.innerHTML = ""), (a.innerHTML = ""), (u = {})),
m({ scrollLeft: e, totalWidth: c, numCanvases: f }).forEach((e) =>
h(e),
);
});
this.unsubscribeOnScroll.push(e);
}
}
renderChannel(e, t, n, i) {
var { overlay: r } = t,
a = (function (e, t) {
var n = {};
for (var i in e)
Object.prototype.hasOwnProperty.call(e, i) &&
0 > t.indexOf(i) &&
(n[i] = e[i]);
if (
null != e &&
"function" == typeof Object.getOwnPropertySymbols
) {
var r = 0;
for (i = Object.getOwnPropertySymbols(e); r < i.length; r++)
0 > t.indexOf(i[r]) &&
Object.prototype.propertyIsEnumerable.call(e, i[r]) &&
(n[i[r]] = e[i[r]]);
}
return n;
})(t, ["overlay"]);
let o = document.createElement("div"),
s = this.getHeight(a.height, a.splitChannels);
(o.style.height = `${s}px`),
r && i > 0 && (o.style.marginTop = `-${s}px`),
(this.canvasWrapper.style.minHeight = `${s}px`),
this.canvasWrapper.appendChild(o);
let c = o.cloneNode();
this.progressWrapper.appendChild(c),
this.renderMultiCanvas(e, a, n, s, o, c);
}
render(e) {
return r(this, void 0, void 0, function* () {
var t;
this.timeouts.forEach((e) => e()),
(this.timeouts = []),
(this.canvasWrapper.innerHTML = ""),
(this.progressWrapper.innerHTML = ""),
null != this.options.width &&
(this.scrollContainer.style.width =
"number" == typeof this.options.width
? `${this.options.width}px`
: this.options.width);
let n = this.getPixelRatio(),
i = this.scrollContainer.clientWidth,
{
scrollWidth: r,
isScrollable: a,
useParentWidth: o,
width: s,
} = (function ({
duration: e,
minPxPerSec: t = 0,
parentWidth: n,
fillParent: i,
pixelRatio: r,
}) {
let a = Math.ceil(e * t),
o = a > n,
s = !!(i && !o);
return {
scrollWidth: a,
isScrollable: o,
useParentWidth: s,
width: (s ? n : a) * r,
};
})({
duration: e.duration,
minPxPerSec: this.options.minPxPerSec || 0,
parentWidth: i,
fillParent: this.options.fillParent,
pixelRatio: n,
});
if (
((this.isScrollable = a),
(this.wrapper.style.width = o ? "100%" : `${r}px`),
(this.scrollContainer.style.overflowX = this.isScrollable
? "auto"
: "hidden"),
this.scrollContainer.classList.toggle(
"noScrollbar",
!!this.options.hideScrollbar,
),
(this.cursor.style.backgroundColor = `${this.options.cursorColor || this.options.progressColor}`),
(this.cursor.style.width = `${this.options.cursorWidth}px`),
(this.audioData = e),
this.emit("render"),
this.options.splitChannels)
)
for (let n = 0; n < e.numberOfChannels; n++) {
let i = Object.assign(
Object.assign({}, this.options),
null == (t = this.options.splitChannels) ? void 0 : t[n],
);
this.renderChannel([e.getChannelData(n)], i, s, n);
}
else {
let t = [e.getChannelData(0)];
e.numberOfChannels > 1 && t.push(e.getChannelData(1)),
this.renderChannel(t, this.options, s, 0);
}
Promise.resolve().then(() => this.emit("rendered"));
});
}
reRender() {
if (
(this.unsubscribeOnScroll.forEach((e) => e()),
(this.unsubscribeOnScroll = []),
!this.audioData)
)
return;
let { scrollWidth: e } = this.scrollContainer,
{ right: t } = this.progressWrapper.getBoundingClientRect();
if (
(this.render(this.audioData),
this.isScrollable && e !== this.scrollContainer.scrollWidth)
) {
let e,
{ right: n } = this.progressWrapper.getBoundingClientRect(),
i = ((e = 2 * (n - t)) < 0 ? Math.floor(e) : Math.ceil(e)) / 2;
this.scrollContainer.scrollLeft += i;
}
}
zoom(e) {
(this.options.minPxPerSec = e), this.reRender();
}
scrollIntoView(e, t = !1) {
let {
scrollLeft: n,
scrollWidth: i,
clientWidth: r,
} = this.scrollContainer,
a = e * i,
o = n + r,
s = r / 2;
if (this.isDragging)
a + 30 > o
? (this.scrollContainer.scrollLeft += 30)
: a - 30 < n && (this.scrollContainer.scrollLeft -= 30);
else {
(a < n || a > o) &&
(this.scrollContainer.scrollLeft =
a - (this.options.autoCenter ? s : 0));
let e = a - n - s;
t &&
this.options.autoCenter &&
e > 0 &&
(this.scrollContainer.scrollLeft += e);
}
}
renderProgress(e, t) {
if (isNaN(e)) return;
let n = 100 * e;
(this.canvasWrapper.style.clipPath = `polygon(${n}% 0%, 100% 0%, 100% 100%, ${n}% 100%)`),
(this.progressWrapper.style.width = `${n}%`),
(this.cursor.style.left = `${n}%`),
(this.cursor.style.transform = this.options.cursorWidth
? `translateX(-${e * this.options.cursorWidth}px)`
: ""),
this.isScrollable &&
this.options.autoScroll &&
this.audioData &&
this.audioData.duration > 0 &&
this.scrollIntoView(e, t);
}
exportImage(e, t, n) {
return r(this, void 0, void 0, function* () {
let i = this.canvasWrapper.querySelectorAll("canvas");
if (!i.length) throw Error("No waveform data");
return "dataURL" === n
? Promise.resolve(Array.from(i).map((n) => n.toDataURL(e, t)))
: Promise.all(
Array.from(i).map(
(n) =>
new Promise((i, r) => {
n.toBlob(
(e) => {
e ? i(e) : r(Error("Could not export image"));
},
e,
t,
);
}),
),
);
});
}
}
class x extends a {
constructor() {
super(...arguments),
(this.animationFrameId = null),
(this.isRunning = !1);
}
start() {
if (this.isRunning) return;
this.isRunning = !0;
let e = () => {
this.isRunning &&
(this.emit("tick"),
(this.animationFrameId = requestAnimationFrame(e)));
};
e();
}
stop() {
(this.isRunning = !1),
null !== this.animationFrameId &&
(cancelAnimationFrame(this.animationFrameId),
(this.animationFrameId = null));
}
destroy() {
this.stop();
}
}
class y extends a {
constructor(e = new AudioContext()) {
super(),
(this.bufferNode = null),
(this.playStartTime = 0),
(this.playedDuration = 0),
(this._muted = !1),
(this._playbackRate = 1),
(this._duration = void 0),
(this.buffer = null),
(this.currentSrc = ""),
(this.paused = !0),
(this.crossOrigin = null),
(this.seeking = !1),
(this.autoplay = !1),
(this.addEventListener = this.on),
(this.removeEventListener = this.un),
(this.audioContext = e),
(this.gainNode = this.audioContext.createGain()),
this.gainNode.connect(this.audioContext.destination);
}
load() {
return r(this, void 0, void 0, function* () {});
}
get src() {
return this.currentSrc;
}
set src(e) {
((this.currentSrc = e), (this._duration = void 0), e)
? fetch(e)
.then((t) => {
if (t.status >= 400)
throw Error(
`Failed to fetch ${e}: ${t.status} (${t.statusText})`,
);
return t.arrayBuffer();
})
.then((t) =>
this.currentSrc !== e
? null
: this.audioContext.decodeAudioData(t),
)
.then((t) => {
this.currentSrc === e &&
((this.buffer = t),
this.emit("loadedmetadata"),
this.emit("canplay"),
this.autoplay && this.play());
})
.catch((e) => {
console.error("WebAudioPlayer load error:", e);
})
: ((this.buffer = null), this.emit("emptied"));
}
_play() {
if (!this.paused) return;
(this.paused = !1),
this.bufferNode &&
((this.bufferNode.onended = null), this.bufferNode.disconnect()),
(this.bufferNode = this.audioContext.createBufferSource()),
this.buffer && (this.bufferNode.buffer = this.buffer),
(this.bufferNode.playbackRate.value = this._playbackRate),
this.bufferNode.connect(this.gainNode);
let e = this.playedDuration * this._playbackRate;
(e >= this.duration || e < 0) && ((e = 0), (this.playedDuration = 0)),
this.bufferNode.start(this.audioContext.currentTime, e),
(this.playStartTime = this.audioContext.currentTime),
(this.bufferNode.onended = () => {
this.currentTime >= this.duration &&
(this.pause(), this.emit("ended"));
});
}
_pause() {
var e;
(this.paused = !0),
null == (e = this.bufferNode) || e.stop(),
(this.playedDuration +=
this.audioContext.currentTime - this.playStartTime);
}
play() {
return r(this, void 0, void 0, function* () {
this.paused && (this._play(), this.emit("play"));
});
}
pause() {
this.paused || (this._pause(), this.emit("pause"));
}
stopAt(e) {
let t = e - this.currentTime,
n = this.bufferNode;
null == n || n.stop(this.audioContext.currentTime + t),
null == n ||
n.addEventListener(
"ended",
() => {
n === this.bufferNode &&
((this.bufferNode = null), this.pause());
},
{ once: !0 },
);
}
setSinkId(e) {
return r(this, void 0, void 0, function* () {
return this.audioContext.setSinkId(e);
});
}
get playbackRate() {
return this._playbackRate;
}
set playbackRate(e) {
(this._playbackRate = e),
this.bufferNode && (this.bufferNode.playbackRate.value = e);
}
get currentTime() {
return (
(this.paused
? this.playedDuration
: this.playedDuration +
(this.audioContext.currentTime - this.playStartTime)) *
this._playbackRate
);
}
set currentTime(e) {
let t = !this.paused;
t && this._pause(),
(this.playedDuration = e / this._playbackRate),
t && this._play(),
this.emit("seeking"),
this.emit("timeupdate");
}
get duration() {
var e, t;
return null != (e = this._duration)
? e
: (null == (t = this.buffer) ? void 0 : t.duration) || 0;
}
set duration(e) {
this._duration = e;
}
get volume() {
return this.gainNode.gain.value;
}
set volume(e) {
(this.gainNode.gain.value = e), this.emit("volumechange");
}
get muted() {
return this._muted;
}
set muted(e) {
this._muted !== e &&
((this._muted = e),
this._muted
? this.gainNode.disconnect()
: this.gainNode.connect(this.audioContext.destination));
}
canPlayType(e) {
return /^(audio|video)\//.test(e);
}
getGainNode() {
return this.gainNode;
}
getChannelData() {
let e = [];
if (!this.buffer) return e;
let t = this.buffer.numberOfChannels;
for (let n = 0; n < t; n++) e.push(this.buffer.getChannelData(n));
return e;
}
removeAttribute(e) {
switch (e) {
case "src":
this.src = "";
break;
case "playbackRate":
this.playbackRate = 0;
break;
case "currentTime":
this.currentTime = 0;
break;
case "duration":
this.duration = 0;
break;
case "volume":
this.volume = 0;
break;
case "muted":
this.muted = !1;
}
}
}
let _ = {
waveColor: "#999",
progressColor: "#555",
cursorWidth: 1,
minPxPerSec: 0,
fillParent: !0,
interact: !0,
dragToSeek: !1,
autoScroll: !0,
autoCenter: !0,
sampleRate: 8e3,
};
class S extends d {
static create(e) {
return new S(e);
}
getState() {
return this.wavesurferState;
}
getRenderer() {
return this.renderer;
}
constructor(e) {
const t = e.media || ("WebAudio" === e.backend ? new y() : void 0);
super({
media: t,
mediaControls: e.mediaControls,
autoplay: e.autoplay,
playbackRate: e.audioRate,
}),
(this.plugins = []),
(this.decodedData = null),
(this.stopAtPosition = null),
(this.subscriptions = []),
(this.mediaSubscriptions = []),
(this.abortController = null),
(this.reactiveCleanups = []),
(this.options = Object.assign({}, _, e));
const { state: n, actions: i } = (function (e) {
var t, n, i, r, a, o;
let s = null != (t = null == e ? void 0 : e.currentTime) ? t : u(0),
c = null != (n = null == e ? void 0 : e.duration) ? n : u(0),
l = null != (i = null == e ? void 0 : e.isPlaying) ? i : u(!1),
f = null != (r = null == e ? void 0 : e.isSeeking) ? r : u(!1),
d = null != (a = null == e ? void 0 : e.volume) ? a : u(1),
p = null != (o = null == e ? void 0 : e.playbackRate) ? o : u(1),
g = u(null),
b = u(null),
m = u(""),
w = u(0),
v = u(0),
x = h(() => !l.value, [l]),
y = h(() => null !== g.value, [g]),
_ = h(() => y.value && c.value > 0, [y, c]),
S = h(() => s.value, [s]),
E = h(() => (c.value > 0 ? s.value / c.value : 0), [s, c]);
return {
state: {
currentTime: s,
duration: c,
isPlaying: l,
isPaused: x,
isSeeking: f,
volume: d,
playbackRate: p,
audioBuffer: g,
peaks: b,
url: m,
zoom: w,
scrollPosition: v,
canPlay: y,
isReady: _,
progress: S,
progressPercent: E,
},
actions: {
setCurrentTime: (e) => {
let t = Math.max(0, Math.min(c.value || 1 / 0, e));
s.set(t);
},
setDuration: (e) => {
c.set(Math.max(0, e));
},
setPlaying: (e) => {
l.set(e);
},
setSeeking: (e) => {
f.set(e);
},
setVolume: (e) => {
let t = Math.max(0, Math.min(1, e));
d.set(t);
},
setPlaybackRate: (e) => {
let t = Math.max(0.1, Math.min(16, e));
p.set(t);
},
setAudioBuffer: (e) => {
g.set(e), e && c.set(e.duration);
},
setPeaks: (e) => {
b.set(e);
},
setUrl: (e) => {
m.set(e);
},
setZoom: (e) => {
w.set(Math.max(0, e));
},
setScrollPosition: (e) => {
v.set(Math.max(0, e));
},
},
};
})({
isPlaying: this.isPlayingSignal,
currentTime: this.currentTimeSignal,
duration: this.durationSignal,
volume: this.volumeSignal,
playbackRate: this.playbackRateSignal,
isSeeking: this.seekingSignal,
});
(this.wavesurferState = n),
(this.wavesurferActions = i),
(this.timer = new x());
const r = t ? void 0 : this.getMediaElement();
(this.renderer = new v(this.options, r)),
this.initPlayerEvents(),
this.initRendererEvents(),
this.initTimerEvents(),
this.initReactiveState(),
this.initPlugins();
const a = this.options.url || this.getSrc() || "";
Promise.resolve().then(() => {
this.emit("init");
let { peaks: e, duration: t } = this.options;
(a || (e && t)) &&
this.load(a, e, t).catch((e) => {
this.emit("error", e instanceof Error ? e : Error(String(e)));
});
});
}
updateProgress(e = this.getCurrentTime()) {
return (
this.renderer.renderProgress(
e / this.getDuration(),
this.isPlaying(),
),
e
);
}
initTimerEvents() {
this.subscriptions.push(
this.timer.on("tick", () => {
if (!this.isSeeking()) {
let e = this.updateProgress();
this.emit("timeupdate", e),
this.emit("audioprocess", e),
null != this.stopAtPosition &&
this.isPlaying() &&
e >= this.stopAtPosition &&
this.pause();
}
}),
);
}
initReactiveState() {
var e, t;
let n, i, r;
this.reactiveCleanups.push(
((e = this.wavesurferState),
(t = { emit: this.emit.bind(this) }),
(n = []).push(
f(() => {
let n = e.isPlaying.value;
t.emit(n ? "play" : "pause");
}, [e.isPlaying]),
),
n.push(
f(() => {
let n = e.currentTime.value;
t.emit("timeupdate", n),
e.isPlaying.value && t.emit("audioprocess", n);
}, [e.currentTime, e.isPlaying]),
),
n.push(
f(() => {
e.isSeeking.value && t.emit("seeking", e.currentTime.value);
}, [e.isSeeking, e.currentTime]),
),
(i = !1),
n.push(
f(() => {
e.isReady.value &&
!i &&
((i = !0), t.emit("ready", e.duration.value));
}, [e.isReady, e.duration]),
),
(r = !1),
n.push(
f(() => {
let n = e.isPlaying.value,
i = e.currentTime.value,
a = e.duration.value,
o = a > 0 && i >= a;
r && !n && o && t.emit("finish"), (r = n && o);
}, [e.isPlaying, e.currentTime, e.duration]),
),
n.push(
f(() => {
let n = e.zoom.value;
n > 0 && t.emit("zoom", n);
}, [e.zoom]),
),
() => {
n.forEach((e) => e());
}),
);
}
initPlayerEvents() {
this.isPlaying() && (this.emit("play"), this.timer.start()),
this.mediaSubscriptions.push(
this.onMediaEvent("timeupdate", () => {
let e = this.updateProgress();
this.emit("timeupdate", e);
}),
this.onMediaEvent("play", () => {
this.emit("play"), this.timer.start();
}),
this.onMediaEvent("pause", () => {
this.emit("pause"),
this.timer.stop(),
(this.stopAtPosition = null);
}),
this.onMediaEvent("emptied", () => {
this.timer.stop(), (this.stopAtPosition = null);
}),
this.onMediaEvent("ended", () => {
this.emit("timeupdate", this.getDuration()),
this.emit("finish"),
(this.stopAtPosition = null);
}),
this.onMediaEvent("seeking", () => {
this.emit("seeking", this.getCurrentTime());
}),
this.onMediaEvent("error", () => {
var e;
this.emit(
"error",
null != (e = this.getMediaElement().error)
? e
: Error("Media error"),
),
(this.stopAtPosition = null);
}),
);
}
initRendererEvents() {
this.subscriptions.push(
this.renderer.on("click", (e, t) => {
this.options.interact &&
(this.seekTo(e),
this.emit("interaction", e * this.getDuration()),
this.emit("click", e, t));
}),
this.renderer.on("dblclick", (e, t) => {
this.emit("dblclick", e, t);
}),
this.renderer.on("scroll", (e, t, n, i) => {
let r = this.getDuration();
this.emit("scroll", e * r, t * r, n, i);
}),
this.renderer.on("render", () => {
this.emit("redraw");
}),
this.renderer.on("rendered", () => {
this.emit("redrawcomplete");
}),
this.renderer.on("dragstart", (e) => {
this.emit("dragstart", e);
}),
this.renderer.on("dragend", (e) => {
this.emit("dragend", e);
}),
this.renderer.on("resize", () => {
this.emit("resize");
}),
);
{
let e,
t = this.renderer.on("drag", (t) => {
var n;
if (!this.options.interact) return;
this.renderer.renderProgress(t), clearTimeout(e);
let i = 0,
r = this.options.dragToSeek;
this.isPlaying()
? (i = 0)
: !0 === r
? (i = 200)
: r &&
"object" == typeof r &&
(i = null != (n = r.debounceTime) ? n : 200),
(e = setTimeout(() => {
this.seekTo(t);
}, i)),
this.emit("interaction", t * this.getDuration()),
this.emit("drag", t);
});
this.subscriptions.push(() => {
clearTimeout(e), t();
});
}
}
initPlugins() {
var e;
(null == (e = this.options.plugins) ? void 0 : e.length) &&
this.options.plugins.forEach((e) => {
this.registerPlugin(e);
});
}
unsubscribePlayerEvents() {
this.mediaSubscriptions.forEach((e) => e()),
(this.mediaSubscriptions = []);
}
setOptions(e) {
(this.options = Object.assign({}, this.options, e)),
e.duration &&
!e.peaks &&
(this.decodedData = o.createBuffer(this.exportPeaks(), e.duration)),
e.peaks &&
e.duration &&
(this.decodedData = o.createBuffer(e.peaks, e.duration)),
this.renderer.setOptions(this.options),
e.audioRate && this.setPlaybackRate(e.audioRate),
null != e.mediaControls &&
(this.getMediaElement().controls = e.mediaControls);
}
registerPlugin(e) {
if (this.plugins.includes(e)) return e;
e._init(this), this.plugins.push(e);
let t = e.once("destroy", () => {
(this.plugins = this.plugins.filter((t) => t !== e)),
(this.subscriptions = this.subscriptions.filter((e) => e !== t));
});
return this.subscriptions.push(t), e;
}
unregisterPlugin(e) {
(this.plugins = this.plugins.filter((t) => t !== e)), e.destroy();
}
getWrapper() {
return this.renderer.getWrapper();
}
getWidth() {
return this.renderer.getWidth();
}
getScroll() {
return this.renderer.getScroll();
}
setScroll(e) {
return this.renderer.setScroll(e);
}
setScrollTime(e) {
let t = e / this.getDuration();
this.renderer.setScrollPercentage(t);
}
getActivePlugins() {
return this.plugins;
}
loadAudio(e, t, n, i) {
return r(this, void 0, void 0, function* () {
var r;
if (
(this.emit("load", e),
!this.options.media && this.isPlaying() && this.pause(),
(this.decodedData = null),
(this.stopAtPosition = null),
null == (r = this.abortController) || r.abort(),
(this.abortController = null),
!t && !n)
) {
let n = this.options.fetchParams || {};
window.AbortController &&
!n.signal &&
((this.abortController = new AbortController()),
(n.signal = this.abortController.signal));
let i = (e) => this.emit("loading", e);
t = yield l.fetchBlob(e, i, n);
let r = this.options.blobMimeType;
r && (t = new Blob([t], { type: r }));
}
this.setSrc(e, t);
let a = yield new Promise((e) => {
let t = i || this.getDuration();
t
? e(t)
: this.mediaSubscriptions.push(
this.onMediaEvent(
"loadedmetadata",
() => e(this.getDuration()),
{ once: !0 },
),
);
});
if (!e && !t) {
let e = this.getMediaElement();
e instanceof y && (e.duration = a);
}
if (n) this.decodedData = o.createBuffer(n, a || 0);
else if (t) {
let e = yield t.arrayBuffer();
this.decodedData = yield o.decode(e, this.options.sampleRate);
}
this.decodedData &&
(this.emit("decode", this.getDuration()),
this.renderer.render(this.decodedData)),
this.emit("ready", this.getDuration());
});
}
load(e, t, n) {
return r(this, void 0, void 0, function* () {
try {
return yield this.loadAudio(e, void 0, t, n);
} catch (e) {
throw (this.emit("error", e), e);
}
});
}
loadBlob(e, t, n) {
return r(this, void 0, void 0, function* () {
try {
return yield this.loadAudio("", e, t, n);
} catch (e) {
throw (this.emit("error", e), e);
}
});
}
zoom(e) {
if (!this.decodedData) throw Error("No audio loaded");
this.renderer.zoom(e), this.emit("zoom", e);
}
getDecodedData() {
return this.decodedData;
}
exportPeaks({
channels: e = 2,
maxLength: t = 8e3,
precision: n = 1e4,
} = {}) {
if (!this.decodedData)
throw Error("The audio has not been decoded yet");
let i = Math.min(e, this.decodedData.numberOfChannels),
r = [];
for (let e = 0; e < i; e++) {
let i = this.decodedData.getChannelData(e),
a = [],
o = i.length / t;
for (let e = 0; e < t; e++) {
let t = i.slice(Math.floor(e * o), Math.ceil((e + 1) * o)),
r = 0;
for (let e = 0; e < t.length; e++) {
let n = t[e];
Math.abs(n) > Math.abs(r) && (r = n);
}
a.push(Math.round(r * n) / n);
}
r.push(a);
}
return r;
}
getDuration() {
let e = super.getDuration() || 0;
return (
(0 === e || e === 1 / 0) &&
this.decodedData &&
(e = this.decodedData.duration),
e
);
}
toggleInteraction(e) {
this.options.interact = e;
}
setTime(e) {
(this.stopAtPosition = null),
super.setTime(e),
this.updateProgress(e),
this.emit("timeupdate", e);
}
seekTo(e) {
let t = this.getDuration() * e;
this.setTime(t);
}
play(e, t) {
let n = Object.create(null, { play: { get: () => super.play } });
return r(this, void 0, void 0, function* () {
null != e && this.setTime(e);
let i = yield n.play.call(this);
return (
null != t &&
(this.media instanceof y
? this.media.stopAt(t)
: (this.stopAtPosition = t)),
i
);
});
}
playPause() {
return r(this, void 0, void 0, function* () {
return this.isPlaying() ? this.pause() : this.play();
});
}
stop() {
this.pause(), this.setTime(0);
}
skip(e) {
this.setTime(this.getCurrentTime() + e);
}
empty() {
this.load("", [[0]], 0.001);
}
setMediaElement(e) {
this.unsubscribePlayerEvents(),
super.setMediaElement(e),
this.initPlayerEvents();
}
exportImage() {
return r(
this,
arguments,
void 0,
function* (e = "image/png", t = 1, n = "dataURL") {
return this.renderer.exportImage(e, t, n);
},
);
}
destroy() {
var e;
this.emit("destroy"),
null == (e = this.abortController) || e.abort(),
this.plugins.forEach((e) => e.destroy()),
this.subscriptions.forEach((e) => e()),
this.unsubscribePlayerEvents(),
this.reactiveCleanups.forEach((e) => e()),
(this.reactiveCleanups = []),
this.timer.destroy(),
this.renderer.destroy(),
super.destroy();
}
}
(S.BasePlugin = class extends a {
constructor(e) {
super(),
(this.subscriptions = []),
(this.isDestroyed = !1),
(this.options = e);
}
onInit() {}
_init(e) {
this.isDestroyed &&
((this.subscriptions = []), (this.isDestroyed = !1)),
(this.wavesurfer = e),
this.onInit();
}
destroy() {
this.emit("destroy"),
this.subscriptions.forEach((e) => e()),
(this.subscriptions = []),
(this.isDestroyed = !0),
(this.wavesurfer = void 0);
}
}),
(S.dom = c);
var E = e.i(41671);
function M({ onRetry: e }) {
return (0, n.jsxs)("div", {
className:
"nodrag nopan absolute inset-0 flex flex-col items-center justify-center gap-2",
style: { zIndex: 10, background: "rgba(0, 0, 0, 0.45)" },
children: [
(0, n.jsx)("button", {
type: "button",
onClick: (t) => {
t.stopPropagation(), e();
},
className:
"flex h-10 w-10 items-center justify-center rounded-full transition-colors hover:bg-white/20",
style: {
background: "rgba(255, 255, 255, 0.1)",
border: "1px solid rgba(255, 255, 255, 0.2)",
},
children: (0, n.jsx)(E.Icons.Refresh, {
width: 20,
height: 20,
style: { color: "rgba(255, 255, 255, 0.8)" },
}),
}),
(0, n.jsx)("span", {
className: "text-xs",
style: { color: "rgba(255, 255, 255, 0.6)" },
children: "加载失败,点击重试",
}),
],
});
}
function T(e, t) {
let { maxAutoRetry: n = 1, autoRetryDelay: r = 1500 } = t ?? {},
[a, o] = (0, i.useState)(0),
[s, c] = (0, i.useState)("idle"),
l = (0, i.useRef)(0),
u = (0, i.useRef)(!1),
h = (0, i.useRef)(!1),
f = (0, i.useRef)();
(0, i.useEffect)(() => {
(l.current = 0),
(u.current = !1),
(h.current = !1),
o(0),
c("idle"),
f.current && (clearTimeout(f.current), (f.current = void 0));
}, [e]),
(0, i.useEffect)(
() => () => {
f.current && clearTimeout(f.current);
},
[],
);
let d = (0, i.useCallback)(() => {
h.current ||
(!u.current && l.current < n
? ((h.current = !0),
c("retrying"),
(l.current += 1),
(f.current = setTimeout(() => {
(h.current = !1), o((e) => e + 1), (f.current = void 0);
}, r)))
: ((u.current = !1), c("failed")));
}, [n, r]);
return {
retryKey: a,
status: s,
showRetryButton: "failed" === s,
handleLoadError: d,
handleLoadSuccess: (0, i.useCallback)(() => {
f.current && (clearTimeout(f.current), (f.current = void 0)),
(h.current = !1),
(u.current = !1),
c("loaded");
}, []),
triggerManualRetry: (0, i.useCallback)(() => {
f.current && (clearTimeout(f.current), (f.current = void 0)),
(h.current = !1),
(u.current = !0),
c("retrying"),
o((e) => e + 1);
}, []),
};
}
e.s(["ResourceRetryOverlay", () => M], 45523),
e.s(["useResourceRetry", () => T], 606095);
var k = e.i(41114);
let C = "peaks",
A = new Map(),
N = null;
function I() {
return (
N ||
(N = new Promise((e, t) => {
let n = indexedDB.open("libtv-audio-peaks", 1);
(n.onupgradeneeded = () => {
let e = n.result;
e.objectStoreNames.contains(C) ||
e
.createObjectStore(C, { keyPath: "url" })
.createIndex("capturedAt", "capturedAt", { unique: !1 });
}),
(n.onsuccess = () => {
let t = n.result;
(t.onclose = () => {
N = null;
}),
e(t);
}),
(n.onerror = () => {
(N = null), t(n.error ?? Error("IndexedDB open failed"));
});
}))
);
}
async function P(e, t, n) {
try {
let i = (await I()).transaction(C, "readwrite"),
r = i.objectStore(C),
a = { url: e, peaks: t, duration: n, capturedAt: Date.now() };
r.put(a),
await new Promise((e, t) => {
(i.oncomplete = () => e()),
(i.onerror = () =>
t(i.error ?? Error("saveToDB transaction failed")));
});
} catch {}
}
async function R(e) {
try {
let t = (await I()).transaction(C, "readwrite");
t.objectStore(C).delete(e),
await new Promise((e, n) => {
(t.oncomplete = () => e()),
(t.onerror = () =>
n(t.error ?? Error("deleteFromDB transaction failed")));
});
} catch {}
}
async function L() {
try {
let e = (await I()).transaction(C, "readwrite"),
t = e.objectStore(C),
n = Date.now(),
i = await new Promise((e, n) => {
let i = t.getAll();
(i.onsuccess = () => e(i.result)),
(i.onerror = () =>
n(i.error ?? Error("purgeStaleEntries query failed")));
});
for (let e of i.filter((e) => n - e.capturedAt > 2592e6))
t.delete(e.url);
let r = i.filter((e) => n - e.capturedAt <= 2592e6);
if (r.length > 300)
for (let e of (r.sort((e, t) => e.capturedAt - t.capturedAt),
r.slice(0, r.length - 300)))
t.delete(e.url);
await new Promise((t, n) => {
(e.oncomplete = () => t()),
(e.onerror = () =>
n(e.error ?? Error("purgeStaleEntries transaction failed")));
});
} catch {}
}
function D(e, t, n) {
!e ||
0 === t.length ||
n <= 0 ||
(A.set(e, { peaks: t, duration: n }),
e.startsWith("blob:") || e.startsWith("data:") || P(e, t, n));
}
function j(e) {
if (e) return A.get(e);
}
function O(e) {
return !!e && A.has(e);
}
let F =
"function" == typeof requestIdleCallback
? (e) => requestIdleCallback(e, { timeout: 5e3 })
: (e) => setTimeout(e, 0);
async function U() {
try {
let e = (await I()).transaction(C, "readonly").objectStore(C),
t = Date.now();
await new Promise((n, i) => {
let r = e.openCursor(),
a = 0;
(r.onerror = () =>
i(r.error ?? Error("warmUpAudioCache cursor failed"))),
(r.onsuccess = () => {
let e = r.result;
if (!e) return void n();
let i = e.value;
i &&
t - i.capturedAt <= 2592e6 &&
A.set(i.url, { peaks: i.peaks, duration: i.duration }),
++a % 80 == 0
? F(() => {
e.continue();
})
: e.continue();
});
}),
L();
} catch {}
}
function B(e) {
!e ||
(A.delete(e), e.startsWith("blob:") || e.startsWith("data:") || R(e));
}
e.s(
[
"cachePeaks",
() => D,
"getCachedPeaks",
() => j,
"hasCachedPeaks",
() => O,
"invalidatePeaks",
() => B,
"warmUpAudioCache",
() => U,
],
979138,
);
let H = {
MIN_SIZE: 3,
MAX_CAP:
"number" == typeof (t = navigator.deviceMemory) && t <= 4 ? 8 : 15,
RATIO: 0.5,
EVICT_BATCH: 3,
SHRINK_COOLDOWN_MS: 3e4,
},
z = H.MIN_SIZE,
G = 0,
$ = new Map(),
V = new Map();
function W(e) {
let t = Math.min(Math.max(Math.ceil(e * H.RATIO), H.MIN_SIZE), H.MAX_CAP);
t >= z
? (z = t)
: Date.now() - G > H.SHRINK_COOLDOWN_MS &&
((z = t),
(G = Date.now()),
(function e() {
if (V.size <= z) return;
let t = [...V.entries()].sort(
(e, t) => e[1].returnedAt - t[1].returnedAt,
),
n = 0;
for (; V.size > z && t.length > 0 && n < H.EVICT_BATCH; ) {
let e = t.shift();
if (!e) break;
let [i, r] = e;
try {
r.ws.destroy();
} catch {}
V.delete(i), n++;
}
V.size > z && setTimeout(e, 500);
})());
}
function K(e) {
let t = $.get(e);
if (t) return { ws: t, url: "" };
let n = V.get(e);
return n ? (V.delete(e), $.set(e, n.ws), { ws: n.ws, url: n.url }) : null;
}
function q(e) {
e > 0 && e < 1 && (e = 1);
let t = Math.floor(e / 60),
n = Math.floor(e % 60);
return `${t.toString().padStart(2, "0")}:${n.toString().padStart(2, "0")}`;
}
function X({
url: e,
playbackRate: t = 1,
nodeId: r,
onDurationReady: a,
chromeVariant: o = "default",
}) {
let s = "canvasLight" === o,
c = (0, i.useRef)(null),
l = (0, i.useRef)(null),
[u, h] = (0, i.useState)(!1),
[f, d] = (0, i.useState)(0),
[p, g] = (0, i.useState)(() => {
let t = e ? j(e) : void 0;
return t ? t.duration : 0;
}),
[b, m] = (0, i.useState)(() => !!e && !!j(e)),
[w, v] = (0, i.useState)(0),
[x, y] = (0, i.useState)(!1),
_ = (0, i.useRef)(a);
_.current = a;
let {
retryKey: C,
showRetryButton: A,
handleLoadError: N,
handleLoadSuccess: I,
triggerManualRetry: P,
} = T(e);
(0, i.useEffect)(() => {
if (!c.current || !e) return;
let t = !1;
if ((y(!1), d(0), v(0), h(!1), m(!1), g(0), r)) {
let t = K(r);
if (t) {
if (!j(e) && t.url === e)
try {
let n = t.ws.exportPeaks({ maxLength: 512, precision: 4 }),
i = t.ws.getDuration();
n && i > 0 && D(e, n, i);
} catch {}
try {
t.ws.destroy();
} catch {}
}
}
let n = j(e),
i = new Audio();
(i.crossOrigin = "anonymous"), n && ((i.src = e), (i.preload = "auto"));
let a = S.create({
container: c.current,
media: i,
waveColor: s ? "#b3b3b3" : "#525252",
progressColor: s ? "#262626" : "#FFFFFF",
cursorColor: "transparent",
cursorWidth: 0,
barWidth: 2,
barGap: 3,
barRadius: 2,
height: 64,
barHeight: 0.8,
normalize: !0,
...(n ? { peaks: n.peaks, duration: n.duration } : {}),
});
return (
n
? (m(!0),
g(n.duration),
I(),
n.duration > 0 && _.current?.(n.duration))
: a.load(e).catch((e) => {
t ||
(e &&
"object" == typeof e &&
"name" in e &&
"AbortError" === e.name) ||
(console.error("[AudioWavePlayer] 音频加载失败:", e),
y(!0),
N());
}),
a.on("ready", () => {
if (t) return;
let n = a.getDuration();
if ((g(n), m(!0), I(), n > 0 && _.current?.(n), !j(e)))
try {
let t = a.exportPeaks({ maxLength: 512, precision: 4 });
D(e, t, a.getDuration());
} catch {}
}),
a.on("error", (e) => {
t ||
(console.error("[AudioWavePlayer] WaveSurfer 错误:", e),
y(!0),
N());
}),
a.on("audioprocess", () => {
if (t) return;
let e = a.getCurrentTime(),
n = a.getDuration();
d(e), v(n > 0 ? (e / n) * 100 : 0);
}),
a.on("seeking", () => {
if (t) return;
let e = a.getCurrentTime(),
n = a.getDuration();
d(e), v(n > 0 ? (e / n) * 100 : 0);
}),
a.on("play", () => !t && h(!0)),
a.on("pause", () => !t && h(!1)),
a.on("finish", () => !t && h(!1)),
(l.current = a),
() => {
(t = !0),
(l.current = null),
a.destroy(),
i.pause(),
i.removeAttribute("src"),
i.load();
}
);
}, [e, r, C, s]),
(0, i.useEffect)(() => {
let e = l.current;
if (!e || !b) return;
let n = e.getCurrentTime();
e.setPlaybackRate(t), e.setTime(n);
}, [t, b]);
let R = (0, i.useCallback)(() => {
l.current && l.current.playPause();
}, []);
return (0, n.jsxs)("div", {
className: "flex h-full flex-col p-2",
children: [
(0, n.jsxs)("div", {
className:
"relative flex min-h-0 flex-1 items-center justify-center overflow-hidden",
style: {
background: s
? "var(--bg-surface-secondary, #fafafa)"
: "#363636",
borderRadius: "8px",
padding: "38px 0",
...(s
? { border: "1px solid var(--border-muted, #f5f5f5)" }
: {}),
},
children: [
(0, n.jsx)("div", { ref: c, className: "w-full px-2" }),
(0, n.jsx)("div", {
className:
"pointer-events-none absolute bottom-[3.5px] top-[3.5px] z-[100]",
style: {
left: `calc(8px + ${w}% * (100% - 16px) / 100%)`,
width: "2px",
background: "#F54848",
},
}),
A && (0, n.jsx)(M, { onRetry: P }),
!b &&
!A &&
(0, n.jsx)("div", {
className:
"absolute inset-0 flex items-center justify-center",
children: (0, n.jsx)(E.Icons.loader2, {
width: 24,
height: 24,
className: (0, k.cn)(
"animate-spin",
s ? "text-fg-muted" : "text-white/50",
),
}),
}),
],
}),
(0, n.jsxs)("div", {
className: "mt-2 flex items-center",
children: [
(0, n.jsxs)("div", {
className: (0, k.cn)(
"text-sm",
s ? "text-fg-muted" : "text-white/70",
),
children: [q(f), " / ", q(p)],
}),
(0, n.jsx)("div", {
className: "flex flex-1 justify-center",
children: (0, n.jsx)("button", {
type: "button",
onClick: R,
disabled: !b,
className: (0, k.cn)(
"flex items-center justify-center gap-0.5 transition-opacity disabled:opacity-50",
s &&
"border-canvas-controls-border bg-canvas-controls-bg text-canvas-controls-text border border-solid shadow-[0_4px_10px_rgba(0,0,0,0.08)] backdrop-blur-md",
),
style: s
? {
width: 24,
height: 24,
padding: 0,
borderRadius: "100%",
}
: {
width: 24,
height: 24,
padding: 0,
borderRadius: "100%",
border: "0.5px solid #525252",
background: "rgba(31, 31, 31, 0.9)",
boxShadow:
"0 4px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px 0 rgba(0, 0, 0, 0.2)",
backdropFilter: "blur(16px)",
color: "rgba(255, 255, 255, 0.9)",
},
children: u
? (0, n.jsx)(E.Icons.lucidePause, { width: 14, height: 14 })
: (0, n.jsx)(E.Icons.lucidePlay, { width: 14, height: 14 }),
}),
}),
(0, n.jsxs)("div", {
className: "text-sm opacity-0",
children: [q(f), " / ", q(p)],
}),
],
}),
],
});
}
e.s(["acquireWaveSurfer", () => K, "updateAudioPoolSize", () => W], 169872),
e.s(["default", () => X], 736317);
};
export default moduleFactory;