function assert(condition, message) { if (!condition) { throw new Error(message || "Assertion failed"); } } function toString(s) { return Object.prototype.toString.call(s); } function getTypeName(s) { return s === null ? "null" : typeof s === "object" || typeof s === "function" ? toString(s).slice(8, -1).toLowerCase() : typeof s; } function isDef(v) { return typeof v !== "undefined"; } function isPrimitive(v) { return v === null || typeof v !== "object" && typeof v !== "function"; } function isBoolean(v) { return typeof v === "boolean"; } function isFunction(v) { return typeof v === "function"; } function isNumber(v) { return typeof v === "number"; } function isString(v) { return typeof v === "string"; } function isSymbol(v) { return typeof v === "symbol"; } function isPlainObject(v) { return getTypeName(v) === "object"; } function isArray(v) { return Array.isArray(v); } function isUndefined(v) { return typeof v === "undefined"; } function isNull(v) { return getTypeName(v) === "null"; } function isRegexp(v) { return getTypeName(v) === "regexp"; } function isDate(v) { return getTypeName(v) === "date"; } function isEmptyObject(v) { if (!isPlainObject(v)) return false; for (const _ in v) return false; return true; } function isBlob(v) { /* istanbul ignore if -- @preserve */ if (typeof Blob === "undefined") return false; return v instanceof Blob; } function isTypedArray(v) { return ArrayBuffer.isView(v) && !(v instanceof DataView); } function isWindow(v) { /* istanbul ignore next -- @preserve */ return typeof v !== "undefined" && getTypeName(v) === "window"; } function isBrowser() { /* istanbul ignore next -- @preserve */ return typeof window !== "undefined"; } function isJSONObject(obj) { if (!isPlainObject(obj)) { return false; } const keys = Reflect.ownKeys(obj); for (let i = 0; i < keys.length; i++) { const key = keys[i]; const value = obj[key]; /* istanbul ignore if -- @preserve */ if (typeof key !== "string") { return false; } if (!isJSONValue(value)) { return false; } } return true; } function isJSONArray(value) { if (!Array.isArray(value)) { return false; } return value.every((item) => isJSONValue(item)); } function isJSONValue(value) { switch (typeof value) { case "object": { return value === null || isJSONArray(value) || isJSONObject(value); } case "string": case "number": case "boolean": return true; default: return false; } } function toArray(v) { if (v === null || v === void 0) return []; if (isArray(v)) return v; return [v]; } function uniq(v) { return Array.from(new Set(v)); } function uniqueBy(array, equalFn) { return array.reduce((acc, cur) => { const index = acc.findIndex((item) => equalFn(cur, item)); if (index === -1) acc.push(cur); return acc; }, []); } function remove(array, value) { if (!isArray(array)) return false; const index = array.indexOf(value); if (index !== -1) { array.splice(index, 1); return true; } return false; } function range(...args) { let start, stop, step; if (args.length === 1) { start = 0; stop = args[0]; step = 1; } else { [start, stop, step = 1] = args; } const arr = []; let current = start; while (current < stop) { arr.push(current); current += step || 1; } return arr; } function move(arr, from, to) { if (!isArray(arr) || arr.length === 0) { return arr; } arr.splice(to, 0, arr.splice(from, 1)[0]); return arr; } function shuffle(array) { for (let i = array.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [array[i], array[j]] = [array[j], array[i]]; } return array; } function sortBy(array, cb) { if (array.length === 0) return []; return array.sort((a, b) => { const s1 = cb(a); const s2 = cb(b); return s1 > s2 ? 1 : s2 > s1 ? -1 : 0; }); } function chunk(input, size = 1) { const chunks = []; for (let i = 0; i < input.length; i += size) chunks.push(input.slice(i, i + size)); return chunks; } function union(a, b) { return [.../* @__PURE__ */ new Set([...a, ...b])]; } function intersection(firstArr, secondArr) { const secondSet = new Set(secondArr); return firstArr.filter((item) => { return secondSet.has(item); }); } function isTruthy(val) { return Boolean(val); } function notUndefined(val) { return typeof val !== "undefined"; } function notNullish(val) { return val != null; } function hasOwn(obj, key) { return obj === null ? false : Object.prototype.hasOwnProperty.call(obj, key); } function deepFreeze(obj) { if (isArray(obj)) { for (let i = 0; i < obj.length; i++) { deepFreeze(obj[i]); } } else if (isPlainObject(obj)) { Object.freeze(obj); const keys = Object.keys(obj); for (let i = 0; i < keys.length; i++) { deepFreeze(obj[keys[i]]); } } return obj; } function isKeyof(obj, key) { return key in obj; } function objectGet(source, path) { const keys = path.replace(/\[['"]?(.+?)['"]?\]/g, ".$1").split("."); let res = source; for (const k of keys) res = res?.[k]; return res; } function objectMap(obj, fn) { return Object.fromEntries( Object.entries(obj).map(([k, v]) => fn(k, v)).filter(notNullish) ); } function objectKeys(obj) { return Object.keys(obj); } function objectEntries(obj) { return Object.entries(obj); } function omit(obj, keys) { const res = { ...obj }; for (const key of keys) { if (isKeyof(obj, key)) delete res[key]; } return res; } function pick(obj, keys) { const res = {}; for (const key of keys) { if (isKeyof(obj, key)) res[key] = obj[key]; } return res; } function deepMerge(target, ...sources) { if (!sources.length) return target; const source = sources.shift(); if (source === void 0) return target; if (isMergableObject(target) && isMergableObject(source)) { const keys = Object.keys(source); for (let i = 0; i < keys.length; i++) { const key = keys[i]; if (key === "__proto__" || key === "constructor" || key === "prototype") continue; if (isMergableObject(source[key])) { if (!target[key]) target[key] = {}; deepMerge(target[key], source[key]); } else { target[key] = source[key]; } } } return deepMerge(target, ...sources); } function deepMergeWithArray(target, ...sources) { if (!sources.length) return target; const source = sources.shift(); if (source === void 0) return target; if (Array.isArray(target) && Array.isArray(source)) target.push(...source); if (isMergableObject(target) && isMergableObject(source)) { const keys = Object.keys(source); for (let i = 0; i < keys.length; i++) { const key = keys[i]; if (key === "__proto__" || key === "constructor" || key === "prototype") continue; if (Array.isArray(source[key])) { if (!target[key]) target[key] = []; deepMergeWithArray(target[key], source[key]); } else if (isMergableObject(source[key])) { if (!target[key]) target[key] = {}; deepMergeWithArray(target[key], source[key]); } else { target[key] = source[key]; } } } return deepMergeWithArray(target, ...sources); } function isMergableObject(item) { return isPlainObject(item) && !Array.isArray(item); } function deepCloneImpl(valueToClone, objectToClone, stack = /* @__PURE__ */ new Map()) { if (isPrimitive(valueToClone)) { return valueToClone; } /* istanbul ignore if -- @preserve */ if (stack.has(valueToClone)) { return stack.get(valueToClone); } if (Array.isArray(valueToClone)) { const result = Array.from({ length: valueToClone.length }); stack.set(valueToClone, result); for (let i = 0; i < valueToClone.length; i++) { result[i] = deepCloneImpl(valueToClone[i], objectToClone, stack); } if (Object.hasOwn(valueToClone, "index")) { result.index = valueToClone.index; } if (Object.hasOwn(valueToClone, "input")) { result.input = valueToClone.input; } return result; } if (valueToClone instanceof Date) { return new Date(valueToClone.getTime()); } if (valueToClone instanceof RegExp) { const result = new RegExp(valueToClone.source, valueToClone.flags); result.lastIndex = valueToClone.lastIndex; return result; } if (valueToClone instanceof Map) { const result = /* @__PURE__ */ new Map(); stack.set(valueToClone, result); for (const [key, value] of valueToClone) { result.set(key, deepCloneImpl(value, objectToClone, stack)); } return result; } if (valueToClone instanceof Set) { const result = /* @__PURE__ */ new Set(); stack.set(valueToClone, result); for (const value of valueToClone) { result.add(deepCloneImpl(value, objectToClone, stack)); } return result; } if (typeof Buffer !== "undefined" && Buffer.isBuffer(valueToClone)) { return valueToClone.subarray(); } if (isTypedArray(valueToClone)) { const result = new (Object.getPrototypeOf(valueToClone)).constructor(valueToClone.length); stack.set(valueToClone, result); for (let i = 0; i < valueToClone.length; i++) { result[i] = deepCloneImpl(valueToClone[i], objectToClone, stack); } return result; } if (valueToClone instanceof ArrayBuffer || typeof SharedArrayBuffer !== "undefined" && valueToClone instanceof SharedArrayBuffer) { return valueToClone.slice(0); } if (valueToClone instanceof DataView) { const result = new DataView(valueToClone.buffer.slice(0), valueToClone.byteOffset, valueToClone.byteLength); stack.set(valueToClone, result); copyProperties(result, valueToClone, objectToClone, stack); return result; } if (typeof File !== "undefined" && valueToClone instanceof File) { const result = new File([valueToClone], valueToClone.name, { type: valueToClone.type }); stack.set(valueToClone, result); copyProperties(result, valueToClone, objectToClone, stack); return result; } if (valueToClone instanceof Blob) { const result = new Blob([valueToClone], { type: valueToClone.type }); stack.set(valueToClone, result); copyProperties(result, valueToClone, objectToClone, stack); return result; } if (valueToClone instanceof Error) { const result = new valueToClone.constructor(valueToClone.message, { cause: valueToClone.cause }); stack.set(valueToClone, result); if (hasOwn(valueToClone, "name")) result.name = valueToClone.name; result.stack = valueToClone.stack; copyProperties(result, valueToClone, objectToClone, stack); return result; } /* istanbul ignore if -- @preserve */ if (typeof valueToClone === "object" && valueToClone !== null) { const result = Object.create(Object.getPrototypeOf(valueToClone)); stack.set(valueToClone, result); copyProperties(result, valueToClone, objectToClone, stack); return result; } /* istanbul ignore next -- @preserve */ return valueToClone; } function copyProperties(target, source, objectToClone = target, stack) { const keys = [...Object.keys(source), ...getSymbols(source)]; for (let i = 0; i < keys.length; i++) { const key = keys[i]; const descriptor = Object.getOwnPropertyDescriptor(target, key); if (descriptor == null || descriptor.writable) { target[key] = deepCloneImpl(source[key], objectToClone, stack); } } } function getSymbols(object) { return Object.getOwnPropertySymbols(object).filter( (symbol) => Object.prototype.propertyIsEnumerable.call(object, symbol) ); } function simpleClone(source) { return JSON.parse(JSON.stringify(source)); } function shallowClone(source) { if (isPrimitive(source)) return source; if (isArray(source) || isTypedArray(source) || source instanceof ArrayBuffer || typeof SharedArrayBuffer !== "undefined" && source instanceof SharedArrayBuffer) { return source.slice(0); } const prototype = Object.getPrototypeOf(source); const Constructor = prototype.constructor; if (source instanceof Date || source instanceof Map || source instanceof Set) { return new Constructor(source); } if (source instanceof RegExp) { const newRegExp = new Constructor(source); newRegExp.lastIndex = source.lastIndex; return newRegExp; } if (source instanceof DataView) { return new Constructor(source.buffer.slice(0)); } if (source instanceof Error) { const newError = new Constructor(source.message, { cause: source.cause }); if (hasOwn(source, "name")) newError.name = source.name; newError.stack = source.stack; return newError; } if (typeof File !== "undefined" && source instanceof File) { const newFile = new Constructor([source], source.name, { type: source.type, lastModified: source.lastModified }); return newFile; } /* istanbul ignore if -- @preserve */ if (isPlainObject(source)) { return Object.assign(Object.create(prototype), source); } /* istanbul ignore next -- @preserve */ return source; } function deepClone(source) { return deepCloneImpl(source, source, /* @__PURE__ */ new Map()); } function deepEqual(v1, v2) { const type1 = getTypeName(v1); const type2 = getTypeName(v2); if (type1 !== type2) return false; if (type1 === "array") { if (v1.length !== v2.length) return false; return v1.every((item, index) => deepEqual(item, v2[index])); } if (type1 === "object") { const keys1 = Object.keys(v1); if (keys1.length !== Object.keys(v2).length) return false; return keys1.every((key) => deepEqual(v1[key], v2[key])); } return Object.is(v1, v2); } class BaseEvent { _listeners; constructor() { this._listeners = /* @__PURE__ */ new Map(); } /** * Adds a listener to the specified event. * * @param event - the event to listen for * @param listener - the listener function to be called when the event is triggered * @return */ on(event, listener) { if (!this._listeners.has(event)) this._listeners.set(event, []); this._listeners.get(event).push(listener); } /** * Emits the specified event with the given arguments to all registered listeners. * * @param event - the name of the event to emit * @param args - the arguments to pass to the event listeners * @return */ emit(event, ...args) { if (this._listeners.has(event)) this._listeners.get(event).forEach((listener) => listener(...args)); } /** * Turn off the specified event listener. * * @param event - the name of the event to turn off * @param listener - (optional) the listener function to turn off */ off(event, listener) { if (this._listeners.has(event)) { listener ? this._listeners.get(event).splice(this._listeners.get(event).indexOf(listener), 1) : this._listeners.delete(event); } } /** * Execute the listener at most once for a particular event. * * @param event - the event to listen for * @param listener - the function to be executed once for the event */ once(event, listener) { this.on(event, (...args) => { this.off(event, listener); listener(...args); }); } } function noop() { } function once(func) { let called = false; let res; return (...args) => { if (!called) { called = true; res = func(...args); return res; } return res; }; } function invoke(fns) { if (Array.isArray(fns)) fns.forEach((fn) => fn && fn()); else return fns(); } function compose(...fns) { return function(...args) { const len = fns.length; if (len === 0) return args; if (len === 1) return fns[0](...args); return fns.slice(0, -1).reduceRight((acc, fn) => fn(acc), fns[len - 1](...args)); }; } function clamp(n, min, max) { return Math.min(max, Math.max(n, min)); } function inRange(n, min, max) { if (max === void 0) { max = min; min = 0; } return n >= Math.min(min, max) && n <= Math.max(min, max); } function random(...args) { let min, max, float; if (args.length === 1) { min = 0; max = args[0]; float = false; } else { if (typeof args[1] === "number") { min = args[0]; max = args[1]; float = !!args[2]; } else { min = 0; max = args[0]; float = !!args[1]; } } const num = Math.random() * (max - min) + min; return float ? num : Math.floor(num); } async function sleep(ms, callback) { return new Promise( (resolve) => setTimeout(async () => { await callback?.(); resolve(); }, ms) ); } function promiseParallel(promises, concurrency = Number.POSITIVE_INFINITY) { promises = Array.from(promises); let current = 0; const result = []; let resolvedCount = 0; const len = promises.length; return new Promise((resolve, reject) => { function next() { const index = current++; const promise = promises[index]; Promise.resolve(isFunction(promise) ? promise() : promise).then((res) => { result[index] = res; if (++resolvedCount === len) resolve(result); if (current < len) next(); }).catch((reason) => reject(reason)); } for (let i = 0; i < concurrency && i < len; i++) next(); }); } function promiseParallelSettled(promises, concurrency = Number.POSITIVE_INFINITY) { promises = Array.from(promises); let current = 0; const result = []; let resolvedCount = 0; const len = promises.length; return new Promise((resolve) => { function resolved() { if (++resolvedCount === len) resolve(result); if (current < len) next(); } function next() { const index = current++; const promise = promises[index]; Promise.resolve(isFunction(promise) ? promise() : promise).then((value) => { result[index] = { status: "fulfilled", value }; resolved(); }).catch((reason) => { result[index] = { status: "rejected", reason }; resolved(); }); } for (let i = 0; i < concurrency && i < len; i++) next(); }); } class TimeoutError extends Error { constructor(message = "The operation was timed out") { super(message); this.name = "TimeoutError"; } } async function timeout(ms) { await sleep(ms); throw new TimeoutError(); } async function withTimeout(run, ms) { return Promise.race([run(), timeout(ms)]); } function createSingletonPromise(fn) { let _promise; function wrapper() { if (!_promise) _promise = fn(); return _promise; } wrapper.reset = async () => { const _prev = _promise; _promise = void 0; if (_prev) await _prev; }; return wrapper; } function createPromiseLock() { const locks = []; return { async run(fn) { const p = fn(); locks.push(p); try { return await p; } finally { remove(locks, p); } }, async wait() { await Promise.allSettled(locks); }, isWaiting() { return Boolean(locks.length); }, clear() { locks.length = 0; } }; } function createControlledPromise() { let resolve, reject; const promise = new Promise((_resolve, _reject) => { resolve = _resolve; reject = _reject; }); promise.resolve = resolve; promise.reject = reject; return promise; } function ensurePrefix(prefix, str) { if (str.startsWith(prefix)) return str; return prefix + str; } function ensureSuffix(suffix, str) { if (str.endsWith(suffix)) return str; return str + suffix; } const CASE_SPLIT_PATTERN = /\p{Lu}?\p{Ll}+|\d+|\p{Lu}+(?!\p{Ll})|[\p{Emoji_Presentation}\p{Extended_Pictographic}]|\p{L}+/gu; function words(str) { return Array.from(str.match(CASE_SPLIT_PATTERN) ?? []); } function capitalize(s) { if (!s) return s; return s[0].toUpperCase() + s.slice(1).toLowerCase(); } function kebabCase(str) { const parts = words(str); if (parts.length === 0) return ""; return parts.map((word) => word.toLowerCase()).join("-"); } function snakeCase(str) { const parts = words(str); if (parts.length === 0) return ""; return parts.map((word) => word.toLowerCase()).join("_"); } function camelCase(str) { const parts = words(str); if (parts.length === 0) return ""; const [first, ...rest] = parts; return `${first.toLowerCase()}${rest.map((word) => capitalize(word)).join("")}`; } function lowerCase(str) { const parts = words(str); if (parts.length === 0) return ""; return parts.map((word) => word.toLowerCase()).join(" "); } function upperCase(str) { const parts = words(str); if (parts.length === 0) return ""; return parts.map((word) => word.toUpperCase()).join(" "); } function pascalCase(str) { const parts = words(str); if (parts.length === 0) return ""; return parts.map((word) => capitalize(word)).join(""); } const htmlEscapes = { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }; const RE_ESCAPE = /[&<>"']/g; function escape(str) { return str.replace(RE_ESCAPE, (match) => htmlEscapes[match]); } const RE_ESCAPE_REGEXP = /[\\^$.*+?()[\]{}|]/g; function escapeRegExp(str) { return str.replace(RE_ESCAPE_REGEXP, "\\$&"); } const htmlUnescapes = { "&": "&", "<": "<", ">": ">", """: '"', "'": "'" }; const RE_UNESCAPE = /&(?:amp|lt|gt|quot|#(0+)?39);/g; function unescape(str) { return str.replace(RE_UNESCAPE, (match) => htmlUnescapes[match] || "'"); } function throttle(delay, callback, options) { const { noTrailing = false, noLeading = false, debounceMode = void 0 } = options || {}; let timeoutID; let cancelled = false; let lastExec = 0; function clearExistingTimeout() { if (timeoutID) clearTimeout(timeoutID); } function cancel(options2 = {}) { const { upcomingOnly = false } = options2 || {}; clearExistingTimeout(); cancelled = !upcomingOnly; } function wrapper(...args) { const self = this; const elapsed = Date.now() - lastExec; if (cancelled) return; function exec() { lastExec = Date.now(); callback.apply(self, args); } function clear() { timeoutID = void 0; } if (!noLeading && debounceMode && !timeoutID) { exec(); } clearExistingTimeout(); if (debounceMode === void 0 && elapsed > delay) { if (noLeading) { lastExec = Date.now(); if (!noTrailing) timeoutID = setTimeout(debounceMode ? clear : exec, delay); } else { exec(); } } else if (noTrailing !== true) { timeoutID = setTimeout( debounceMode ? clear : exec, debounceMode === void 0 ? delay - elapsed : delay ); } } wrapper.cancel = cancel; return wrapper; } function debounce(delay, callback, options) { const { atBegin = false } = options || {}; return throttle(delay, callback, { debounceMode: atBegin !== false }); } function timestamp() { return +Date.now(); } function isSameDay(date1, date2) { if (!date2) return false; const v1 = new Date(date1); const v2 = new Date(date2); const y1 = v1.getFullYear(); const m1 = v1.getMonth(); const d1 = v1.getDate(); const y2 = v2.getFullYear(); const m2 = v2.getMonth(); const d2 = v2.getDate(); return y1 === y2 && m1 === m2 && d1 === d2; } function slash(s) { return s.replace(/\\/g, "/"); } function ensureLeadingSlash(str) { return ensurePrefix("/", slash(str)); } function ensureTrailingSlash(str) { return ensureSuffix("/", slash(str)); } function removeLeadingSlash(str) { if (!str) return str; str = slash(str); return str[0] === "/" ? str.slice(1) : str; } function removeTrailingSlash(str) { if (!str) return str; str = slash(str); return str[str.length - 1] === "/" ? str.slice(0, -1) : str; } const RE_HTTP = /^(?:https?:)?\/\//i; function isHttp(url) { return RE_HTTP.test(url); } function isUrl(url) { try { new URL(url); return true; } catch { return false; } } function combineURLs(baseUrl, ...urls) { if (urls.length === 0) return baseUrl; const url = removeLeadingSlash(urls.join("/").replace(/\/+/g, "/")); baseUrl = removeTrailingSlash(baseUrl); return `${baseUrl}/${url}`; } const RE_PROTOCOL_MATCH = /^([-+\w]{1,25})(?::?\/\/|:)/; function parseProtocol(url) { const match = RE_PROTOCOL_MATCH.exec(url); return match?.[1] || ""; } export { BaseEvent, CASE_SPLIT_PATTERN, TimeoutError, assert, camelCase, capitalize, chunk, clamp, combineURLs, compose, createControlledPromise, createPromiseLock, createSingletonPromise, debounce, deepClone, deepEqual, deepFreeze, deepMerge, deepMergeWithArray, ensureLeadingSlash, ensurePrefix, ensureSuffix, ensureTrailingSlash, escape, escapeRegExp, getTypeName, hasOwn, inRange, intersection, invoke, isArray, isBlob, isBoolean, isBrowser, isDate, isDef, isEmptyObject, isFunction, isHttp, isJSONArray, isJSONObject, isJSONValue, isKeyof, isNull, isNumber, isPlainObject, isPrimitive, isRegexp, isSameDay, isString, isSymbol, isTruthy, isTypedArray, isUndefined, isUrl, isWindow, kebabCase, lowerCase, move, noop, notNullish, notUndefined, objectEntries, objectGet, objectKeys, objectMap, omit, once, parseProtocol, pascalCase, pick, promiseParallel, promiseParallelSettled, random, range, remove, removeLeadingSlash, removeTrailingSlash, shallowClone, shuffle, simpleClone, slash, sleep, snakeCase, sortBy, throttle, timeout, timestamp, toArray, toString, unescape, union, uniq, uniqueBy, upperCase, withTimeout, words };