@diffusionstudio/core
Version:
2D motion graphics and video rendering engine
1,712 lines (1,709 loc) • 526 kB
JavaScript
/*!
* @diffusionstudio/core v3.8.3
* (c) 2025 Diffusion Studio Inc.
*
* Licensed under the Diffusion Studio Non-Commercial License.
* You may NOT use this software for any commercial purposes.
*
* For commercial licensing, visit:
* https://diffusion.studio
*/
let na = class Hs {
data;
format;
numberOfChannels;
numberOfFrames;
sampleRate;
timestamp;
duration;
constructor(e) {
this.data = e.data, this.format = e.format, this.numberOfChannels = e.numberOfChannels, this.numberOfFrames = e.numberOfFrames, this.sampleRate = e.sampleRate, this.timestamp = e.timestamp || 0, this.duration = this.numberOfFrames / this.sampleRate * 1e6;
}
copyTo(e, i) {
if (!i?.format || i.format !== "s16")
throw new Error("Only s16 format is supported for copyTo");
for (let s = 0; s < this.numberOfFrames; s++)
for (let r = 0; r < this.numberOfChannels; r++) {
const a = r * this.numberOfFrames + s, n = s * this.numberOfChannels + r, o = Math.max(-1, Math.min(1, this.data[a]));
e[n] = Math.round(o * 32767);
}
}
clone() {
return new Hs({
data: new Float32Array(this.data),
format: this.format,
numberOfChannels: this.numberOfChannels,
numberOfFrames: this.numberOfFrames,
sampleRate: this.sampleRate,
timestamp: this.timestamp
});
}
close() {
this.data = new Float32Array(0);
}
};
"AudioData" in window || Object.assign(window, { AudioData: na });
const Yl = 0.2, Rt = 30, oa = 1;
class lt extends Error {
message;
code;
constructor({ message: e = "", code: i = "" }, ...s) {
super(e, ...s), console.error(e), this.code = i, this.message = e;
}
}
class Ee extends lt {
}
class ee extends lt {
}
class at extends lt {
}
class Jl extends lt {
}
class Bt extends lt {
}
function ca(t, e = Rt) {
if (e < 1) throw new ee({
code: "invalidArgument",
message: "FPS must be greater or equal to 1"
});
return Math.round(t * e);
}
function Zl(t, e = Rt) {
if (e < 1) throw new ee({
code: "invalidArgument",
message: "FPS must be greater or equal to 1"
});
return Math.round(t / e * 1e3) / 1e3;
}
function jt(t, e = Rt) {
if (e < 1) throw new ee({
code: "invalidArgument",
message: "FPS must be greater or equal to 1"
});
return Math.round(t / e * 1e3);
}
function ed(t) {
return Math.floor(t * 255).toString(16).padStart(2, "0").toUpperCase();
}
function td(t, e) {
return t.reduce(
(i, s) => {
const r = s[e];
return i[r] || (i[r] = []), i[r].push(s), i;
},
// @ts-ignore
{}
);
}
function Ct(t, e) {
return [t.slice(0, e), t.slice(e)].filter((i) => i.length > 0);
}
function vt(t, e) {
return e ? Math.floor(Math.random() * (e - t + 1) + t) : t;
}
async function id(t) {
t <= 0 || await new Promise((e) => setTimeout(e, t));
}
function B(t, e) {
if (!t)
throw new Error(e || `Assertion failed: ${String(t)}`);
}
function sd(t, e = 300) {
let i;
return (...s) => {
clearTimeout(i), i = setTimeout(() => {
t.apply(t, s);
}, e);
};
}
function la(t, e, i) {
i < 0 && (i = 0);
const s = t[e];
t.splice(e, 1), t.splice(i, 0, s);
}
function rd() {
return typeof crypto < "u" ? crypto.randomUUID().split("-").at(0) : Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
}
function ad(t) {
return t.charAt(0).toUpperCase() + t.slice(1);
}
function da(t, e, i) {
return Math.max(e, Math.min(i, t));
}
function nd(t) {
throw new Error("This should not run!");
}
function ha(t) {
if (t.numberOfChannels === 1)
return t.getChannelData(0);
const e = [];
for (let n = 0; n < t.numberOfChannels; n++)
e.push(t.getChannelData(n));
const i = Math.max(...e.map((n) => n.length)), s = new Float32Array(i * t.numberOfChannels);
let r = 0, a = 0;
for (; a < i; )
e.forEach((n) => {
s[r++] = n[a] !== void 0 ? n[a] : 0;
}), a++;
return s;
}
function wt(t, e, i) {
for (let s = 0; s < i.length; s++)
t.setUint8(e + s, i.charCodeAt(s));
}
function ua(t, e, i) {
for (let s = 0; s < e.length; s++, i += 2) {
const r = Math.max(-1, Math.min(1, e[s]));
t.setInt16(i, r < 0 ? r * 32768 : r * 32767, !0);
}
return t;
}
function fa(t, e, i) {
const a = e * 2, n = 8, o = 36, c = t.length * 2, l = o + c, d = new ArrayBuffer(n + l), h = new DataView(d);
return wt(h, 0, "RIFF"), h.setUint32(4, l, !0), wt(h, 8, "WAVE"), wt(h, 12, "fmt "), h.setUint32(16, 16, !0), h.setUint16(20, 1, !0), h.setUint16(22, e, !0), h.setUint32(24, i, !0), h.setUint32(28, i * a, !0), h.setUint16(32, a, !0), h.setUint16(34, 16, !0), wt(h, 36, "data"), h.setUint32(40, c, !0), ua(h, t, n + o);
}
function od(t, e = "audio/wav") {
const i = ha(t), s = fa(i, t.numberOfChannels, t.sampleRate);
return new Blob([s], { type: e });
}
function cd(t) {
const e = new Float32Array(t.length * t.numberOfChannels);
let i = 0;
for (let s = 0; s < t.numberOfChannels; s++) {
const r = t.getChannelData(s);
e.set(r, i), i += r.length;
}
return e;
}
function ld(t) {
const e = t.numberOfChannels, i = t.length, s = new Int16Array(i * e);
for (let r = 0; r < i; r++)
for (let a = 0; a < e; a++) {
let n = t.getChannelData(a)[r] * 32767;
n > 32767 && (n = 32767), n < -32767 && (n = -32767), s[r * e + a] = n;
}
return s;
}
async function dd(t, e = 22050, i = Math.sqrt(2)) {
const s = await t.arrayBuffer(), r = new OfflineAudioContext({ sampleRate: e, length: 1 }), a = await r.decodeAudioData(s), n = r.createBuffer(1, a.length, e);
if (a.numberOfChannels >= 2) {
const o = a.getChannelData(0), c = a.getChannelData(1), l = n.getChannelData(0);
for (let d = 0; d < a.length; ++d)
l[d] = i * (o[d] + c[d]) / 2;
return n;
}
return a;
}
function hd(t, e = 44100, i = 2) {
if (t.sampleRate == e && t.numberOfChannels == i)
return t;
const s = Math.floor(t.duration * e), a = new OfflineAudioContext(i, 1, e).createBuffer(i, s, e);
for (let n = 0; n < t.numberOfChannels; n++) {
const o = t.getChannelData(n), c = a.getChannelData(n), l = t.sampleRate / e;
for (let d = 0; d < c.length; d++) {
const h = d * l, u = Math.floor(h), m = Math.ceil(h);
if (m >= o.length)
c[d] = o[u];
else {
const p = h - u;
c[d] = o[u] * (1 - p) + o[m] * p;
}
}
}
return a;
}
async function $s(t, e) {
const i = document.createElement("a");
if (document.head.appendChild(i), i.target = "_blank", e ? i.download = e : t instanceof File ? i.download = t.name : t instanceof Blob ? i.download = "untitled" : typeof t == "string" && (i.download = t.split("/").pop() ?? "untitled"), typeof t == "string" && t.startsWith("data:image/svg+xml;base64,")) {
const s = t.split(",")[1], r = atob(s), a = new Array(r.length);
for (let c = 0; c < r.length; c++)
a[c] = r.charCodeAt(c);
const n = new Uint8Array(a), o = new Blob([n], { type: "image/svg+xml" });
i.href = URL.createObjectURL(o), i.download = e?.split(".")[0] + ".svg";
} else typeof t == "string" ? i.href = t : t instanceof Blob ? i.href = URL.createObjectURL(t) : i.href = URL.createObjectURL(await t.getFile());
i.click(), i.remove();
}
async function ud(t, e = !0) {
return new Promise((i) => {
const s = document.createElement("input");
s.type = "file", s.accept = t, s.multiple = e, s.onchange = (r) => {
const a = Array.from(r.target?.files ?? []);
i(a);
}, s.click();
});
}
function O(t) {
if (!t) return new E(0);
if (typeof t == "number")
return E.fromFrames(t);
if (t instanceof E)
return t;
const e = t.split(":");
if (e.length === 3) {
const [i, s, r] = e.map(Number);
if (isNaN(i) || isNaN(s) || isNaN(r))
throw new Error(`Invalid time format: ${t}`);
return new E(0, r, s, i);
}
if (e.length === 2) {
const [i, s] = e.map(Number);
if (isNaN(i) || isNaN(s))
throw new Error(`Invalid time format: ${t}`);
return new E(0, s, i);
}
if (typeof t == "string") {
const i = parseFloat(t);
if (isNaN(i))
throw new Error(`Invalid time format: ${t}`);
if (t.endsWith("ms"))
return new E(i);
if (t.endsWith("s"))
return new E(0, i);
if (t.endsWith("f"))
return E.fromFrames(i);
if (t.endsWith("min"))
return new E(0, 0, i);
throw new Error(`Invalid time format: ${t}`);
}
throw new Error(`Invalid time format: ${t}`);
}
async function fd(t) {
const { fps: e, height: i, width: s, bitrate: r } = t, a = [
"avc1.640033",
"avc1.4d4033",
"avc1.424033",
"avc1.640029",
"avc1.4d4029",
"avc1.424029"
], n = ["prefer-hardware", "prefer-software"], o = [];
for (const l of a)
for (const d of n)
o.push({
codec: l,
hardwareAcceleration: d,
width: s,
height: i,
bitrate: r,
framerate: e
});
const c = [];
if ("VideoEncoder" in window) {
for (const l of o) {
const d = await VideoEncoder.isConfigSupported(l);
d.supported && c.push(d.config ?? l);
}
return c.sort(ma)[0].codec;
}
}
function ma(t, e) {
const i = t.hardwareAcceleration ?? "", s = e.hardwareAcceleration ?? "";
return i < s ? -1 : i > s ? 1 : 0;
}
const Ot = {
fromJSON: (t) => new Date(t)
};
class E {
/**
* Time state in **milliseconds**
*/
time;
/**
* Create a new timestamp from various time units
* @param millis - Time in milliseconds
* @param seconds - Time in seconds
* @param minutes - Time in minutes
* @param hours - Time in hours
*/
constructor(e = 0, i = 0, s = 0, r = 0) {
this.time = Math.round(e + i * 1e3 + s * 6e4 + r * 36e5);
}
/**
* Base unit of the timestamp
*/
get millis() {
return this.time;
}
set millis(e) {
this.time = Math.round(e);
}
/**
* Defines the time in frames at the
* current frame rate
*/
get frames() {
return ca(this.millis / 1e3);
}
set frames(e) {
this.millis = jt(e);
}
/**
* Convert the timestamp to seconds
*/
get seconds() {
return this.millis / 1e3;
}
set seconds(e) {
this.millis = e * 1e3;
}
/**
* Equivalent to millis += x
*/
addMillis(e) {
return this.millis = this.millis + e, this;
}
/**
* Equivalent to frames += x
*/
addFrames(e) {
const i = jt(e);
return this.millis = this.millis + i, this;
}
/**
* add two timestamps the timestamp being added will adapt
* its fps to the current fps
* @returns A new Timestamp instance with the added frames
*/
add(e) {
return new E(e.millis + this.millis);
}
/**
* subtract two timestamps timestamp being subtracted
* will adapt its fps to the current fps
* @returns A new Timestamp instance with the added frames
*/
subtract(e) {
return new E(this.millis - e.millis);
}
/**
* Create a new timestamp from frames
*/
static fromFrames(e, i) {
const s = new E();
return s.millis = jt(e, i), s;
}
/**
* get a copy of the object
*/
copy() {
return new E(this.millis);
}
toJSON() {
return this.millis;
}
fromJSON(e) {
return B(typeof e == "number"), this.millis = e, this;
}
static fromJSON(e) {
return B(typeof e == "number"), new E(e);
}
}
function Ki(t) {
return `${t.hours.toString().padStart(2, "0")}:${t.minutes.toString().padStart(2, "0")}:${t.seconds.toString().padStart(2, "0")},` + t.milliseconds.toString().padStart(3, "0");
}
function Gi(t) {
const e = new Date(1970, 0, 1);
return e.setSeconds(t), e.setMilliseconds(Math.round(t % 1 * 1e3)), {
hours: e.getHours(),
minutes: e.getMinutes(),
seconds: e.getSeconds(),
milliseconds: e.getMilliseconds()
};
}
class Le {
words = [];
constructor(e) {
e && (this.words = e);
}
get duration() {
return this.stop.subtract(this.start);
}
get text() {
return this.words.map(({ text: e }) => e).join(" ");
}
get start() {
return this.words.at(0)?.start ?? new E();
}
get stop() {
return this.words.at(-1)?.stop ?? new E();
}
}
var ai = /* @__PURE__ */ ((t) => (t.en = "en", t.de = "de", t))(ai || {});
class Tt {
/**
* A unique identifier for the word
*/
id = crypto.randomUUID();
/**
* Defines the text to be displayed
*/
text;
/**
* Defines the time stamp at
* which the text is spoken
*/
start;
/**
* Defines the time stamp at
* which the text was spoken
*/
stop;
/**
* Defines the confidence of
* the predicition
*/
confidence;
/**
* Create a new Word object
* @param text The string contents of the word
* @param start Start in **milliseconds**
* @param stop Stop in **milliseconds**
* @param confidence Predicition confidence
*/
constructor(e, i, s, r) {
this.text = e, this.start = new E(i), this.stop = new E(s), this.confidence = r;
}
/**
* Defines the time between start
* and stop returned as a timestamp
*/
get duration() {
return this.stop.subtract(this.start);
}
}
class se {
id = crypto.randomUUID();
language = ai.en;
groups = [];
get text() {
return this.groups.map(({ text: e }) => e).join(" ");
}
get words() {
return this.groups.flatMap(({ words: e }) => e);
}
constructor(e = [], i = ai.en) {
this.groups = e, this.language = i;
}
/**
* Iterate over all words in groups
*/
*iter({ count: e, duration: i, length: s }) {
for (const r of this.groups) {
let a;
for (const [n, o] of r.words.entries())
a && (e && a.words.length >= vt(...e) ? (yield a, a = void 0) : i && a?.duration.seconds >= vt(...i) ? (yield a, a = void 0) : s && a.text.length >= vt(...s) && (yield a, a = void 0)), a ? a.words.push(o) : a = new Le([o]), n == r.words.length - 1 && (yield a);
}
}
/**
* This method will optimize the transcipt for display
*/
optimize() {
const e = this.groups.flatMap((i) => i.words);
for (let i = 0; i < e.length - 1; i++) {
const s = e[i], r = e[i + 1];
r.start.millis - s.stop.millis < 0 ? r.start.millis = s.stop.millis + 1 : s.stop.millis = r.start.millis - 1;
}
return this;
}
/**
* Convert the transcript into a SRT compatible
* string and downloadable blob
*/
toSRT(e = {}) {
let i = 1, s = "";
for (const r of this.iter(e)) {
const a = Gi(r.start.seconds), n = Gi(r.stop.seconds);
s += `${i}
` + Ki(a) + " --> " + Ki(n) + `
${r.text}
`, i += 1;
}
return {
text: s,
blob: new Blob([s], { type: "text/plain;charset=utf8" })
};
}
toJSON() {
return this.groups.map(
(e) => e.words.map((i) => ({
token: i.text,
start: i.start.millis,
stop: i.stop.millis
}))
);
}
/**
* Create a new Transcript containing the
* first `{count}` words
* @param count Defines the number of words required
* @param startAtZero Defines if the first word should start at 0 milliseconds
* @returns A new Transcript instance
*/
slice(e, i = !0) {
let s = 0;
const r = [];
for (const a of this.groups)
for (const n of a.words)
if (r.length == 0 && i && (s = n.start.millis), r.push(new Tt(n.text, n.start.millis - s, n.stop.millis - s)), r.length == e)
return new se([new Le(r)]);
return new se([new Le(r)]);
}
/**
* Create a deep copy of the transcript
* @returns A new Transcript instance
*/
copy() {
return se.fromJSON(this.toJSON());
}
static fromJSON(e) {
const i = new se();
for (const s of e) {
const r = new Le();
for (const a of s)
r.words.push(new Tt(a.token, a.start, a.stop));
i.groups.push(r);
}
return i;
}
/**
* Create a Transcript from an input medium of the form:
* `{ token: string; start: number; stop: number; }[][]`
* @param input The input medium, can be a URL, Blob, or an array of captions
* @returns A Transcript with processed captions
*/
static async from(e) {
if (Array.isArray(e))
return se.fromJSON(e);
if (e instanceof FileSystemFileHandle) {
const s = await e.getFile();
return se.fromJSON(JSON.parse(await s.text()));
}
if (e instanceof Blob)
return se.fromJSON(JSON.parse(await e.text()));
const i = await fetch(e);
if (!i.ok)
throw new Ee({
code: "unexpectedIOError",
message: "An unexpected error occurred while fetching the file"
});
return se.fromJSON(await i.json());
}
fromJSON(e) {
B(typeof e == "object"), B(Array.isArray(e)), this.groups = [];
for (const i of e) {
const s = new Le();
for (const r of i)
s.words.push(new Tt(r.token, r.start, r.stop));
this.groups.push(s);
}
return this;
}
}
class Te {
toJSON(e) {
const i = {}, s = this.constructor.__serializableProperties || [], r = (a) => {
if (a == null || a instanceof Blob || a instanceof FileSystemFileHandle)
return a;
if (Array.isArray(a))
return a.map((n) => r(n)).filter((n) => n !== void 0);
if (typeof a == "object" && "toJSON" in a)
return a.toJSON();
if (typeof a == "object") {
const n = {};
for (const o in a) {
const c = r(a[o]);
c !== void 0 && (n[o] = c);
}
return n;
}
return a;
};
return s.forEach(({ propertyKey: a, mapTo: n }) => {
if (e?.includes(a))
return;
const o = this[a], c = n ?? a, l = r(o);
l !== void 0 && (i[c] = l);
}), i;
}
fromJSON(e) {
return (this.constructor.__serializableProperties || []).forEach(({ propertyKey: s, deserializer: r, mapTo: a }) => {
const n = a ?? s, o = r.fromJSON?.bind(r) ?? ((c) => c);
e.hasOwnProperty(n) && (this[s] = o(e[n]));
}), this;
}
static fromJSON(e) {
return new this().fromJSON(e);
}
}
function v(t = {}, e) {
return function(i, s) {
const r = i.constructor;
r.__serializableProperties || (r.__serializableProperties = []), r.__serializableProperties = [
...r.__serializableProperties.filter((a) => a.propertyKey !== s),
{
propertyKey: s,
deserializer: t,
mapTo: e
}
];
};
}
function dt(t) {
return class extends t {
_handlers = {};
on(i, s) {
if (typeof s != "function")
throw new Error("The callback of an event listener needs to be a function.");
const r = crypto.randomUUID();
return this._handlers[i] ? this._handlers[i][r] = s : this._handlers[i] = { [r]: s }, r;
}
off(i, ...s) {
if (i) {
if (i === "*") {
this._handlers = {};
return;
}
for (const r of Object.values(this._handlers))
i in r && delete r[i];
for (const r of s)
this.off(r);
}
}
emit(i, s) {
const r = new CustomEvent(i, {
detail: s
});
Object.defineProperty(r, "currentTarget", { writable: !1, value: this });
for (const a in this._handlers[i] ?? {})
this._handlers[i]?.[a](r);
for (const a in this._handlers["*"] ?? {})
this._handlers["*"]?.[a](r);
}
bubble(i) {
return this.on("*", (s) => {
i.emit(s.type, s.detail);
});
}
resolve(i) {
return (s, r) => {
this.on("error", r), this.on(i, s);
};
}
};
}
class qt extends dt(Te) {
_key;
_value;
_store;
loaded = !1;
constructor(e, i, s) {
super(), this._store = e, this._key = i, this.initValue(s);
}
get key() {
return this._key;
}
get value() {
return this._value;
}
set value(e) {
this._value = e, this._store.set(this._key, e), this.emit("update", void 0);
}
async initValue(e) {
e instanceof Promise ? this._value = await e : this._value = e, this.loaded = !0, this.emit("update", void 0);
}
}
class pd {
storageEngine;
namespace;
constructor(e, i = localStorage) {
this.storageEngine = i, this.namespace = e;
}
define(e, i, s) {
const r = this.get(e);
return r === null ? (this.set(e, i), new qt(this, e, i)) : s && r != null ? new qt(this, e, s(r)) : new qt(this, e, r);
}
set(e, i) {
this.storageEngine.setItem(
this.getStorageId(e),
JSON.stringify({
value: i
})
);
}
get(e) {
const i = this.storageEngine.getItem(this.getStorageId(e));
return i ? JSON.parse(i).value : null;
}
remove(e) {
this.storageEngine.removeItem(this.getStorageId(e));
}
getStorageId(e) {
return this.namespace ? `${this.namespace}.${e}` : e;
}
}
function js() {
return class extends dt(class {
}) {
};
}
function gd(t, e) {
return e == "lower" ? t.toLocaleLowerCase() : e == "upper" ? t.toUpperCase() : t;
}
function $e(t = "#000000", e = 100) {
return `${t}${Math.round(e / 100 * 255).toString(16)}`;
}
function _(t, e) {
return typeof t == "number" ? t : Number.parseFloat(t.replace("%", "")) * e / 100;
}
function pa(t) {
const e = t.startsWith("#") ? t.slice(1) : t, i = parseInt(e, 16), s = i >> 16 & 255, r = i >> 8 & 255, a = i & 255;
return { r: s, g: r, b: a };
}
function ga(t, e, i) {
return `#${((1 << 24) + (Math.round(t) << 16) + (Math.round(e) << 8) + Math.round(i)).toString(16).slice(1)}`;
}
function Ii(t, e) {
switch (e) {
case "ease-in":
return t * t;
case "ease-out":
return t * (2 - t);
case "ease-in-out":
return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
case "ease-out-in":
if (t < 0.5) {
const i = t * 2;
return i * (2 - i) / 2;
} else {
const i = (t - 0.5) * 2;
return i * i / 2 + 0.5;
}
default:
return t;
}
}
function nt(t, e, i) {
return t + (e - t) * i;
}
function Yi(t) {
const e = pa(t);
return wa(e.r, e.g, e.b);
}
function wa(t, e, i) {
t /= 255, e /= 255, i /= 255;
const s = Math.max(t, e, i), r = Math.min(t, e, i);
let a = 0, n = 0;
const o = (s + r) / 2;
if (s !== r) {
const c = s - r;
switch (n = o > 0.5 ? c / (2 - s - r) : c / (s + r), s) {
case t:
a = (e - i) / c + (e < i ? 6 : 0);
break;
case e:
a = (i - t) / c + 2;
break;
case i:
a = (t - e) / c + 4;
break;
}
a /= 6;
}
return { h: Math.round(a * 360), s: Math.round(n * 100), l: Math.round(o * 100) };
}
function ya(t, e, i) {
e /= 100, i /= 100, t = (t + 360) % 360;
function s(l, d, h) {
return h < 0 && (h += 1), h > 1 && (h -= 1), h < 1 / 6 ? l + (d - l) * 6 * h : h < 1 / 2 ? d : h < 2 / 3 ? l + (d - l) * (2 / 3 - h) * 6 : l;
}
const r = i < 0.5 ? i * (1 + e) : i + e - i * e, a = 2 * i - r, n = s(a, r, t / 360 + 1 / 3), o = s(a, r, t / 360), c = s(a, r, t / 360 - 1 / 3);
return ga(
Math.round(n * 255),
Math.round(o * 255),
Math.round(c * 255)
);
}
function ba(t, e) {
const { frames: i, extrapolate: s = "clamp", easing: r } = t;
if (e.millis <= O(i[0].time).millis)
return i[0].value;
if (e.millis >= O(i[i.length - 1].time).millis)
return i[i.length - 1].value;
let a, n;
for (let m = 0; m < i.length - 1; m++)
if (e.millis >= O(i[m].time).millis && e.millis <= O(i[m + 1].time).millis) {
a = i[m], n = i[m + 1];
break;
}
if (!a || !n)
throw new Error("Unexpected error in keyframe interpolation");
const o = (e.millis - O(a.time).millis) / (O(n.time).millis - O(a.time).millis), c = Ii(o, a.easing ?? r), l = Yi(a.value), d = Yi(n.value);
let h = l.h, u = d.h;
return Math.abs(u - h) > 180 && (h < u ? h += 360 : u += 360), ya(
nt(h, u, c),
nt(l.s, d.s, c),
nt(l.l, d.l, c)
);
}
function qs(t, e) {
const { frames: i, extrapolate: s = "clamp", easing: r } = t;
if (e.millis <= O(i[0].time).millis)
return i[0].value;
if (e.millis >= O(i[i.length - 1].time).millis)
return i[i.length - 1].value;
let a, n;
for (let l = 0; l < i.length - 1; l++)
if (e.millis >= O(i[l].time).millis && e.millis <= O(i[l + 1].time).millis) {
a = i[l], n = i[l + 1];
break;
}
if (!a || !n)
throw new Error("Unexpected error in keyframe interpolation");
const o = (e.millis - O(a.time).millis) / (O(n.time).millis - O(a.time).millis), c = Ii(o, a.easing ?? r);
return typeof a.value == "number" && typeof n.value == "number" ? nt(a.value, n.value, c) : `${nt(Ji(a.value), Ji(n.value), c)}%`;
}
function Ji(t) {
return typeof t == "number" ? t : Number(t.replace("%", ""));
}
function ka(t, e) {
const { frames: i, extrapolate: s = "clamp" } = t;
if (e.millis <= O(i[0].time).millis)
return i[0].value;
if (e.millis >= O(i[i.length - 1].time).millis)
return i[i.length - 1].value;
let r, a;
for (let h = 0; h < i.length - 1; h++)
if (e.millis >= O(i[h].time).millis && e.millis <= O(i[h + 1].time).millis) {
r = i[h], a = i[h + 1];
break;
}
if (!r || !a)
throw new Error("Unexpected error in keyframe interpolation");
const n = (e.millis - O(r.time).millis) / (O(a.time).millis - O(r.time).millis), o = Ii(n, r.easing), c = a.value, l = c.length, d = Math.floor(o * l);
return c.slice(0, d);
}
var Sa = Object.defineProperty, ht = (t, e, i, s) => {
for (var r = void 0, a = t.length - 1, n; a >= 0; a--)
(n = t[a]) && (r = n(e, i, r) || r);
return r && Sa(e, i, r), r;
};
class we extends Te {
/**
* Unique identifier of the mask
*/
id = crypto.randomUUID();
type = "base";
width;
height;
fillRule;
animations = [];
clip;
renderer;
constructor({ width: e = 100, height: i = 100 } = {}) {
super(), this.width = e, this.height = i;
}
connect(e) {
return this.clip = e, this;
}
draw(e) {
return this.renderer = e, new Path2D();
}
animate(e) {
for (const i of this.animations) {
const s = i?.frames[0].value;
(typeof s == "number" || typeof s == "string" && s.match(/^[0-9]+(\.[0-9]+)?%$/)) && (this[i.key] = qs(i, e.subtract(this.start)));
}
return this;
}
get start() {
return this.clip?.start ?? new E();
}
get stop() {
return this.clip?.stop ?? new E();
}
get size() {
return {
width: _(this.width, this.renderer?.width ?? 0),
height: _(this.height, this.renderer?.height ?? 0)
};
}
get bounds() {
const { width: e, height: i } = this.size;
return [
{ x: 0, y: 0 },
{ x: e, y: 0 },
{ x: e, y: i },
{ x: 0, y: i }
];
}
detach() {
return this.clip && (this.clip.mask = void 0, this.clip = void 0), this;
}
}
ht([
v()
], we.prototype, "type");
ht([
v()
], we.prototype, "width");
ht([
v()
], we.prototype, "height");
ht([
v()
], we.prototype, "fillRule");
ht([
v()
], we.prototype, "animations");
var va = Object.defineProperty, Mt = (t, e, i, s) => {
for (var r = void 0, a = t.length - 1, n; a >= 0; a--)
(n = t[a]) && (r = n(e, i, r) || r);
return r && va(e, i, r), r;
};
class ut extends we {
type = "rectangle";
x;
y;
radius;
constructor({ x: e = 0, y: i = 0, radius: s = 0, animations: r, ...a } = {}) {
super(a), this.x = e, this.y = i, this.radius = s, this.animations = r ?? [];
}
draw(e) {
const i = super.draw(e);
if (this.radius) {
const s = _(this.width, e.width), r = _(this.height, e.height), a = _(this.radius, Math.min(s, r));
i.roundRect(
_(this.x, e.width) * e.resolution,
_(this.y, e.height) * e.resolution,
s * e.resolution,
r * e.resolution,
a * e.resolution
);
} else
i.rect(
_(this.x, e.width) * e.resolution,
_(this.y, e.height) * e.resolution,
_(this.width, e.width) * e.resolution,
_(this.height, e.height) * e.resolution
);
return i;
}
get bounds() {
return super.bounds.map((e) => ({
x: e.x + _(this.x, this.renderer?.width ?? 0),
y: e.y + _(this.y, this.renderer?.height ?? 0)
}));
}
}
Mt([
v()
], ut.prototype, "type");
Mt([
v()
], ut.prototype, "x");
Mt([
v()
], ut.prototype, "y");
Mt([
v()
], ut.prototype, "radius");
class Ta {
static fromJSON(e) {
switch (B(typeof e == "object"), B(e != null), B("type" in e), e.type) {
case "rectangle":
return ut.fromJSON(e);
case "circle":
return At.fromJSON(e);
default:
return we.fromJSON(e);
}
}
}
var xa = Object.defineProperty, Ei = (t, e, i, s) => {
for (var r = void 0, a = t.length - 1, n; a >= 0; a--)
(n = t[a]) && (r = n(e, i, r) || r);
return r && xa(e, i, r), r;
};
class At extends we {
type = "circle";
cx;
cy;
constructor({ cx: e, cy: i, x: s = 0, y: r = 0, radius: a, animations: n, ...o } = {}) {
super(o), this.cx = e ?? s, this.cy = i ?? r, a && (this.radius = a), this.animations = n ?? [];
}
set x(e) {
this.cx = e;
}
set y(e) {
this.cy = e;
}
get x() {
return this.cx;
}
get y() {
return this.cy;
}
get radius() {
const e = this.size;
return Math.min(e.width, e.height) * 0.5;
}
set radius(e) {
typeof e == "number" ? (this.height = e * 2, this.width = e * 2) : (this.height = `${Number(e.replace("%", "")) * 2}%`, this.width = `${Number(e.replace("%", "")) * 2}%`);
}
draw(e) {
const i = super.draw(e);
return i.ellipse(
_(this.cx, e.width) * e.resolution,
_(this.cy, e.height) * e.resolution,
_(this.width, e.width) * e.resolution * 0.5,
_(this.height, e.height) * e.resolution * 0.5,
0,
0,
2 * Math.PI
), i;
}
get bounds() {
const { width: e, height: i } = this.size, { cx: s, cy: r } = this, a = _(s, this.renderer?.width ?? 0) - e * 0.5, n = _(r, this.renderer?.height ?? 0) - i * 0.5;
return [
{ x: a, y: n },
{ x: a + e, y: n },
{ x: a + e, y: n + i },
{ x: a, y: n + i }
];
}
}
Ei([
v()
], At.prototype, "type");
Ei([
v()
], At.prototype, "cx");
Ei([
v()
], At.prototype, "cy");
var Ca = Object.defineProperty, _a = Object.getOwnPropertyDescriptor, zt = (t, e, i, s) => {
for (var r = s > 1 ? void 0 : s ? _a(e, i) : e, a = t.length - 1, n; a >= 0; a--)
(n = t[a]) && (r = (s ? n(e, i, r) : n(r)) || r);
return s && r && Ca(e, i, r), r;
};
class Xe extends Te {
_background = "#000000";
/**
* The canvas element
*/
canvas = document.createElement("canvas");
/**
* The main 2d context of the canvas
*/
context = this.canvas.getContext("2d");
resolution = 1;
width = 0;
height = 0;
constructor({
width: e = 1920,
height: i = 1080,
background: s = "#000000",
resolution: r = 1
} = {}) {
super(), this.resolution = r, this.background = s, this.resize(e, i);
}
get background() {
return this._background;
}
set background(e) {
this.background != e && (this.canvas.style.background = e, this._background = e);
}
/**
* Resize the canvas
*/
resize(e = this.width, i = this.height, s = this.resolution) {
const r = Math.round(e / 2) * 2, a = Math.round(i / 2) * 2;
return (r !== this.width || a !== this.height || s !== this.resolution) && (this.width = r, this.height = a, this.resolution = s, this.canvas.width = Math.round(r * this.resolution / 2) * 2, this.canvas.height = Math.round(a * this.resolution / 2) * 2, this.context.imageSmoothingEnabled = !1), this;
}
clear(e) {
let i = 0, s = 0, r = this.width * this.resolution, a = this.height * this.resolution;
return this.context.fillStyle = this._background, e && (i = _(e.x ?? 0, this.width) * this.resolution, s = _(e.y ?? 0, this.height) * this.resolution, r = _(e.width, this.width) * this.resolution, a = _(e.height, this.height) * this.resolution), this.context.clearRect(i, s, r, a), this.context.fillRect(i, s, r, a), this;
}
rect(e) {
if (this.context.beginPath(), e.radius) {
const i = _(e.width, this.width), s = _(e.height, this.height), r = Math.max(_(e.radius, Math.min(i, s)), 0);
this.context.roundRect(
_(e.x ?? 0, this.width) * this.resolution | 0,
_(e.y ?? 0, this.height) * this.resolution | 0,
i * this.resolution | 0,
s * this.resolution | 0,
r * this.resolution | 0
);
} else
this.context.rect(
_(e.x ?? 0, this.width) * this.resolution | 0,
_(e.y ?? 0, this.height) * this.resolution | 0,
_(e.width, this.width) * this.resolution | 0,
_(e.height, this.height) * this.resolution | 0
);
return this.context.closePath(), this;
}
circle(e) {
return this.context.beginPath(), "height" in e ? this.context.ellipse(
_(e.cx, this.width) * this.resolution | 0,
_(e.cy, this.height) * this.resolution | 0,
_(e.width, this.width) * this.resolution | 0,
_(e.height, this.height) * this.resolution | 0,
0,
0,
Math.PI * 2
) : this.context.arc(
_(e.cx, this.width) * this.resolution | 0,
_(e.cy, this.height) * this.resolution | 0,
_(e.radius, Math.min(this.width, this.height) * 0.5) * this.resolution | 0,
0,
Math.PI * 2
), this.context.closePath(), this;
}
image(e, i) {
const { x: s = 0, y: r = 0, width: a, height: n, rotation: o } = i, c = _(s, this.width) * this.resolution | 0, l = _(r, this.height) * this.resolution | 0, d = _(a, this.width) * this.resolution | 0, h = _(n, this.height) * this.resolution | 0;
if (o !== void 0 && o !== 0) {
this.context.save(), this.context.translate(c + d / 2, l + h / 2);
const u = o * Math.PI / 180;
this.context.rotate(u);
const m = Math.abs(o % 180) === 90;
this.context.drawImage(
e,
(m ? -h / 2 : -d / 2) | 0,
(m ? -d / 2 : -h / 2) | 0,
(m ? h : d) | 0,
(m ? d : h) | 0
), this.context.restore();
} else
this.context.drawImage(e, c, l, d, h);
return this;
}
clip(e, i) {
return e instanceof we ? this.context.clip(e.draw(this), e.fillRule) : e && this.context.clip(e, i), this;
}
opacity(e) {
return this.context.globalAlpha *= e / 100, this;
}
transform(e) {
return e ? (e.translate && this.context.translate(
_(e.translate.x, this.width) * this.resolution | 0,
_(e.translate.y, this.height) * this.resolution | 0
), e.rotate && this.context.rotate(e.rotate * Math.PI / 180), e.scale && this.context.scale(
_(e.scale.x, this.width),
_(e.scale.y, this.height)
), this) : (this.context.setTransform(1, 0, 0, 1, 0, 0), this);
}
blendMode(e) {
return e && (this.context.globalCompositeOperation = e), this;
}
save() {
return this.context.save(), this;
}
restore() {
return this.context.restore(), this;
}
filter(e) {
return e ? (this.context.filter = e, this) : this;
}
fill(e, i = !1) {
if (!e)
return this.context.fillStyle = "transparent", this;
if (typeof e.color == "string")
this.context.fillStyle = $e(e.color, e.opacity);
else if ("type" in e.color) {
const s = this.createGradient(e.color);
this.context.fillStyle = s;
} else if ("image" in e.color) {
const s = this.context.createPattern(e.color.image, e.color.repetition);
this.context.fillStyle = s ?? "";
}
return i && this.context.fill(), this;
}
shadow(e) {
return e ? (this.context.fillStyle = this.context.shadowColor = $e(e.color, e.opacity), this.context.shadowOffsetX = (e.offsetX ?? 0) * this.resolution * this.textScale, this.context.shadowOffsetY = (e.offsetY ?? 0) * this.resolution * this.textScale, this.context.shadowBlur = (e.blur ?? 24) * this.resolution * this.textScale, this) : (this.context.shadowColor = "transparent", this.context.shadowBlur = 0, this.context.shadowOffsetX = 0, this.context.shadowOffsetY = 0, this);
}
stroke(e, i = !1) {
return e ? (this.context.strokeStyle = $e(e.color, e.opacity), this.context.lineWidth = (e.width ?? 1) * this.resolution * this.textScale, e.lineCap && (this.context.lineCap = e.lineCap), e.lineJoin && (this.context.lineJoin = e.lineJoin), e.miterLimit && (this.context.miterLimit = e.miterLimit), i && this.context.stroke(), this) : (this.context.strokeStyle = "transparent", this.context.lineWidth = 0, this.context.lineCap = "butt", this.context.lineJoin = "miter", this.context.miterLimit = 10, this);
}
/**
* Add the renderer to the dom
*/
mount(e) {
e.appendChild(this.canvas);
}
/**
* Remove the renderer from the dom
*/
unmount() {
this.canvas.parentElement?.removeChild(this.canvas);
}
createGradient(e) {
let i;
return e.type === "linear" ? i = this.context.createLinearGradient(0, 0, this.canvas.width, 0) : i = this.context.createRadialGradient(
this.canvas.width / 2,
this.canvas.height / 2,
0,
this.canvas.width / 2,
this.canvas.height / 2,
this.canvas.width / 2
), e.stops.forEach((s) => {
i.addColorStop(s.offset, s.color);
}), i;
}
/**
* Draw a watermark on the canvas
*/
watermark(e) {
!e || !e.length || (this.context.save(), this.context.font = `${46 * this.resolution}px Verdana`, this.context.fillStyle = "#ffffff", this.context.textAlign = "center", this.context.textBaseline = "middle", this.context.strokeStyle = "#000000", this.context.lineWidth = 8 * this.resolution, this.context.strokeText(e, this.width * this.resolution * 0.5, this.height * this.resolution * 0.9), this.context.fillText(e, this.width * this.resolution * 0.5, this.height * this.resolution * 0.9), this.context.restore());
}
/**
* The scale of the text
* @deprecated
*/
textScale = 4;
/**
* @deprecated use Text node instead
*/
text(e) {
return e.font && (this.context.font = this.createFontString(
e.font.style,
e.font.weight,
e.font.size * this.resolution,
e.font.family
)), e.color && (this.context.fillStyle = e.color), e.alignment && (this.context.textAlign = e.alignment), e.baseline && (this.context.textBaseline = e.baseline), this;
}
/**
* @deprecated use Text node instead
*/
strokeText(e, i) {
return this.context.strokeText(
e,
_(i.x, this.width) * this.resolution,
_(i.y, this.height) * this.resolution
), this;
}
/**
* @deprecated use Text node instead
*/
fillText(e, i) {
return this.context.fillText(
e,
_(i.x, this.width) * this.resolution,
_(i.y, this.height) * this.resolution
), this;
}
/**
* @deprecated use Text node instead
*/
measureText(e, i) {
return this.context.font = this.createFontString(
i.style,
i.weight,
i.size,
i.family
), this.context.measureText(e);
}
/**
* @deprecated use Text node instead
*/
createFontString(e, i, s, r) {
return `${e ?? "normal"} ${i ?? "400"} ${(s ?? 16) * this.textScale}px ${r ?? "Arial"}`.trim();
}
}
zt([
v()
], Xe.prototype, "resolution", 2);
zt([
v()
], Xe.prototype, "width", 2);
zt([
v()
], Xe.prototype, "height", 2);
zt([
v()
], Xe.prototype, "background", 1);
class Qs {
context;
/**
* Offset in **seconds** relative to the hardware time when the playback started
*/
hardwareOffset = 0;
/**
* Offset in **seconds** relative to 0 when the playback started
*/
playbackOffset = 0;
/**
* Defines the fps used for rendering.
*/
playbackFps = Rt;
/**
* The fps used when the ticker is inactive (not playing)
*/
inactiveFps = oa;
/**
* Defines the current state of the ticker
*/
playing = !1;
/**
* Defines if the ticker is active
*/
stopped = !0;
/**
* User defined fixed duration
*
* @deprecated Use markers.stop instead
*/
duration;
/**
* The last time the timer was updated
*/
lastFrameTime = 0;
/**
* Creates a new ticker
* @param callback - The function to call when the ticker is updated
*/
constructor(e = {}) {
this.callback = e.callback, this.context = e.context ?? new AudioContext(), this.playbackFps = e.fps ?? 30;
}
/**
* The current time of the hardware in seconds
*/
get hardwareTime() {
return this.context.currentTime;
}
/**
* The current time of the playback in **seconds** relative to 0
*/
get playbackTime() {
return this.playing ? this.hardwareTime - this.hardwareOffset + this.playbackOffset : this.playbackOffset;
}
get playbackTimestamp() {
return new E(0, this.playbackTime);
}
/**
* The current frame that the playback is set to
*/
get playbackFrame() {
return Math.floor(this.playbackTime * this.playbackFps);
}
/**
* Starts the animation loop
*/
start() {
this.stopped && (this.stopped = !1, this.timer());
}
/**
* Stops the animation loop
*/
stop() {
this.stopped = !0;
}
/**
* Starts the frame incrementation
*/
async play() {
this.playing || this.stopped || (this.resumeAudioContext(), this.hardwareOffset = this.hardwareTime, this.playing = !0);
}
/**
* Pauses the frame incrementation
*/
async pause() {
this.playing && (this.playbackOffset = this.playbackTime, this.playing = !1);
}
/**
* The animation loop
*/
async timer(e = 0) {
if (this.stopped) return;
const s = 1e3 / (this.playing ? this.playbackFps : this.inactiveFps);
e - this.lastFrameTime >= s && (this.lastFrameTime = e, await this.callback?.()), requestAnimationFrame(this.timer.bind(this));
}
async resumeAudioContext() {
this.context.state === "suspended" && await this.context.resume();
}
}
const Ia = {
fromJSON: (t) => {
B(typeof t == "object"), B(t != null);
const e = {};
for (const [i, s] of Object.entries(t))
B(typeof s == "number"), e[i] = new E(s);
return e;
}
};
function Ea(t) {
const e = new E();
for (const i of t)
i.disabled || i.stop.frames > e.frames && (e.frames = i.stop.frames);
return e;
}
var Pa = Object.defineProperty, Fe = (t, e, i, s) => {
for (var r = void 0, a = t.length - 1, n; a >= 0; a--)
(n = t[a]) && (r = n(e, i, r) || r);
return r && Pa(e, i, r), r;
};
class le extends Te {
id = crypto.randomUUID();
data = {};
type = "base";
mimeType;
input;
name;
createdAt = /* @__PURE__ */ new Date();
constructor(e) {
super(), this.input = e.input, this.mimeType = e.mimeType, e.name ? this.name = e.name : typeof this.input == "string" ? this.name = this.input.split("/").at(-1) ?? "" : this.input instanceof File ? this.name = this.input.name : this.input instanceof FileSystemFileHandle ? this.name = this.input.name : this.name = "UNTITLED_BLOB";
}
async init(e = {}) {
}
/**
* Get the source as an array buffer
*/
async arrayBuffer() {
return typeof this.input == "string" ? await (await fetch(this.input)).arrayBuffer() : this.input instanceof Blob ? await this.input.arrayBuffer() : await (await this.input.getFile()).arrayBuffer();
}
/**
* Downloads the file
*/
async download() {
$s(this.input, this.name);
}
/**
* Get a visulization of the source
* as an html element
* @deprecated
*/
async thumbnail() {
return document.createElement("div");
}
/**
* Create a checkpoint of the source. May include Blob or FileSystemFileHandle.
* @param middleware A function to modify the checkpoint data
* @returns A serialized representation of the source
*/
async createCheckpoint() {
return this.toJSON();
}
}
Fe([
v()
], le.prototype, "id");
Fe([
v()
], le.prototype, "data");
Fe([
v()
], le.prototype, "type");
Fe([
v()
], le.prototype, "mimeType");
Fe([
v()
], le.prototype, "input");
Fe([
v()
], le.prototype, "name");
Fe([
v(Ot)
], le.prototype, "createdAt");
function Pi(t) {
class e extends t {
/**
* The height of the source
*/
height = 1080;
/**
* The width of the source
*/
width = 1920;
/**
* The aspect ratio of the source
*/
get aspectRatio() {
return this.width / this.height;
}
}
return e;
}
async function Fa(t) {
if (t instanceof FileSystemFileHandle)
return (await t.getFile()).type;
if (t instanceof Blob)
return t.type;
if (t.startsWith("<html>"))
return "text/html";
let e;
try {
e = await fetch(t, { method: "HEAD" });
} catch {
console.info("Using AbortController fallback");
const r = new AbortController();
e = await fetch(t, { signal: r.signal }), r.abort();
}
if (!e.ok)
throw new Error(`HTTP error! Status: ${e.status}`);
const i = e.headers.get("Content-Type");
if (!i)
throw new Ee({
message: "No content type found",
code: "no_content_type_found"
});
return i;
}
function f(t) {
if (!t)
throw new Error("Assertion failed.");
}
var Fi = (t) => {
const e = (t % 360 + 360) % 360;
if (e === 0 || e === 90 || e === 180 || e === 270)
return e;
throw new Error(`Invalid rotation ${t}.`);
}, H = (t) => t && t[t.length - 1], Qe = (t) => t >= 0 && t < 2 ** 32, Se = class Xs {
constructor(e) {
this.bytes = e, this.pos = 0;
}
seekToByte(e) {
this.pos = 8 * e;
}
readBit() {
const e = Math.floor(this.pos / 8), i = this.bytes[e] ?? 0, s = 7 - (this.pos & 7), r = (i & 1 << s) >> s;
return this.pos++, r;
}
readBits(e) {
let i = 0;
for (let s = 0; s < e; s++)
i <<= 1, i |= this.readBit();
return i;
}
readAlignedByte() {
if (this.pos % 8 !== 0)
throw new Error("Bitstream is not byte-aligned.");
const e = this.pos / 8, i = this.bytes[e] ?? 0;
return this.pos += 8, i;
}
skipBits(e) {
this.pos += e;
}
getBitsLeft() {
return this.bytes.length * 8 - this.pos;
}
clone() {
const e = new Xs(this.bytes);
return e.pos = this.pos, e;
}
}, I = (t) => {
let e = 0;
for (; t.readBit() === 0 && e < 32; )
e++;
if (e >= 32)
throw new Error("Invalid exponential-Golomb code.");
return (1 << e) - 1 + t.readBits(e);
}, ot = (t) => {
const e = I(t);
return e & 1 ? e + 1 >> 1 : -(e >> 1);
}, Ra = (t, e, i, s) => {
for (let r = e; r < i; r++) {
const a = Math.floor(r / 8);
let n = t[a];
const o = 7 - (r & 7);
n &= ~(1 << o), n |= (s & 1 << i - r - 1) >> i - r - 1 << o, t[a] = n;
}
}, te = (t) => t instanceof ArrayBuffer ? new Uint8Array(t) : new Uint8Array(t.buffer, t.byteOffset, t.byteLength), Re = (t) => t instanceof ArrayBuffer ? new DataView(t) : new DataView(t.buffer, t.byteOffset, t.byteLength), he = new TextEncoder(), Ri = (t) => Object.fromEntries(Object.entries(t).map(([e, i]) => [i, e])), Ke = {
bt709: 1,
// ITU-R BT.709
bt470bg: 5,
// ITU-R BT.470BG
smpte170m: 6,
// ITU-R BT.601 525 - SMPTE 170M
bt2020: 9,
// ITU-R BT.202
smpte432: 12
// SMPTE EG 432-1
}, Ks = Ri(Ke), Ge = {
bt709: 1,
// ITU-R BT.709
smpte170m: 6,
// SMPTE 170M
linear: 8,
// Linear transfer characteristics
"iec61966-2-1": 13,
// IEC 61966-2-1
pg: 16,
// Rec. ITU-R BT.2100-2 perceptual quantization (PQ) system
hlg: 18
// Rec. ITU-R BT.2100-2 hybrid loggamma (HLG) system
}, Gs = Ri(Ge), Ye = {
rgb: 0,
// Identity
bt709: 1,
// ITU-R BT.709
bt470bg: 5,
// ITU-R BT.470BG
smpte170m: 6,
// SMPTE 170M
"bt2020-ncl": 9
// ITU-R BT.2020-2 (non-constant luminance)
}, Ys = Ri(Ye), Js = (t) => !!t && !!t.primaries && !!t.transfer && !!t.matrix && t.fullRange !== void 0, Ut = (t) => t instanceof ArrayBuffer || typeof SharedArrayBuffer < "u" && t instanceof SharedArrayBuffer || ArrayBuffer.isView(t) && !(t instanceof DataView), ft = class {
constructor() {
this.currentPromise = Promise.resolve();
}
async acquire() {
let t;
const e = new Promise((s) => {
t = s;
}), i = this.currentPromise;
return this.currentPromise = e, await i, t;
}
}, Zi = (t) => [...t].map((e) => e.toString(16).padStart(2, "0")).join(""), es = (t) => (t = t >> 1 & 1431655765 | (t & 1431655765) << 1, t = t >> 2 & 858993459 | (t & 858993459) << 2, t = t >> 4 & 252645135 | (t & 252645135) << 4, t = t >> 8 & 16711935 | (t & 16711935) << 8, t = t >> 16 & 65535 | (t & 65535) << 16, t >>> 0), X = (t, e, i) => {
let s = 0, r = t.length - 1, a = -1;
for (; s <= r; ) {
const n = s + r >> 1, o = i(t[n]);
o === e ? (a = n, r = n - 1) : o < e ? s = n + 1 : r = n - 1;
}
return a;
}, N = (t, e, i) => {
let s = -1, r = 0, a = t.length - 1;
for (; r <= a; ) {
const n = r + (a - r + 1) / 2 | 0;
i(t[n]) <= e ? (s = n, r = n + 1) : a = n - 1;
}
return s;
}, Z = () => {
let t, e;
return { promise: new Promise((s, r) => {
t = s, e = r;
}), resolve: t, reject: e };
}, Ba = (t, e) => {
const i = t.indexOf(e);
i !== -1 && t.splice(i, 1);
}, Zs = (t, e) => {
for (let i = t.length - 1; i >= 0; i--)
if (e(t[i]))
return t[i];
}, er = (t, e) => {
for (let i = t.length - 1; i >= 0; i--)
if (e(t[i]))
return i;
return -1;
}, Oa = async function* (t) {
Symbol.iterator in t ? yield* t[Symbol.iterator]() : yield* t[Symbol.asyncIterator]();
}, Ma = (t) => {
if (!(Symbol.iterator in t) && !(Symbol.asyncIterator in t))
throw new TypeError("Argument must be an iterable or async iterable.");
}, tr = (t, e, i) => {
const s = t.getUint8(e), r = t.getUint8(e + 1), a = t.getUint8(e + 2);
return i ? s | r << 8 | a << 16 : s << 16 | r << 8 | a;
}, Aa = (t, e, i) => tr(t, e, i) << 8 >> 8, ir = (t, e, i, s) => {
i = i >>> 0, i = i & 16777215, s ? (t.setUint8(e, i & 255), t.setUint8(e + 1, i >>> 8 & 255), t.setUint8(e + 2, i >>> 16 & 255)) : (t.setUint8(e, i >>> 16 & 255), t.setUint8(e + 1, i >>> 8 & 255), t.setUint8(e + 2, i & 255));
}, za = (t, e, i, s) => {
i = J(i, -8388608, 8388607), i < 0 && (i = i + 16777216 & 16777215), ir(t, e, i, s);
}, Ua = (t, e, i, s) => {
t.setUint32(e + 0, i, !0), t.setInt32(e + 4, Math.floor(i / 2 ** 32), !0);
}, _t = (t, e) => ({
async next() {
const i = await t.next();
return i.done ? { value: void 0, done: !0 } : { value: e(i.value), done: !1 };
},
return() {
return t.return();
},
th