rattail
Version:
A Vite+ oriented, AI Agent friendly front-end toolchain
1,425 lines (1,424 loc) • 40.8 kB
JavaScript
import { n as isArray, t as isString } from "./isString-eoLxw4CX.mjs";
import { n as isFunction, t as callOrReturn } from "./callOrReturn-MpTzoGlG.mjs";
import { v4 as uuid, v6 as uuidV6 } from "uuid";
import mitt from "mitt";
import Cookie from "js-cookie";
//#region src/array/at.ts
function at(arr, index) {
if (!arr.length) return;
if (index < 0) index += arr.length;
return arr[index];
}
//#endregion
//#region src/number/clamp.ts
function clamp(num, min, max) {
return Math.min(max, Math.max(min, num));
}
//#endregion
//#region src/number/clampArrayRange.ts
function clampArrayRange(index, arr) {
return clamp(index, 0, arr.length - 1);
}
//#endregion
//#region src/number/delay.ts
function delay(time) {
return new Promise((resolve) => {
setTimeout(resolve, time);
});
}
//#endregion
//#region src/number/randomNumber.ts
function randomNumber(min = 0, max = 100) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
//#endregion
//#region src/number/times.ts
function times(num, fn) {
return Array.from({ length: num }, (_, index) => fn(index));
}
//#endregion
//#region src/general/inBrowser.ts
function inBrowser() {
return typeof window !== "undefined";
}
//#endregion
//#region src/general/getGlobalThis.ts
function getGlobalThis() {
if (typeof globalThis !== "undefined") return globalThis;
if (inBrowser()) return window;
return typeof global !== "undefined" ? global : self;
}
//#endregion
//#region src/general/hasOwn.ts
const { hasOwnProperty } = Object.prototype;
function hasOwn(val, key) {
return hasOwnProperty.call(val, key);
}
//#endregion
//#region src/general/inMobile.ts
function inMobile() {
return inBrowser() && /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
}
//#endregion
//#region src/general/toTypeString.ts
const objectToString = Object.prototype.toString;
function toTypeString(value) {
return objectToString.call(value);
}
//#endregion
//#region src/general/toRawType.ts
function toRawType(value) {
return toTypeString(value).slice(8, -1);
}
//#endregion
//#region src/general/isArrayBuffer.ts
function isArrayBuffer(val) {
return toRawType(val) === "ArrayBuffer";
}
//#endregion
//#region src/general/isBoolean.ts
function isBoolean(val) {
return typeof val === "boolean";
}
//#endregion
//#region src/general/isDataView.ts
function isDataView(val) {
return toRawType(val) === "DataView";
}
//#endregion
//#region src/general/isDate.ts
function isDate(val) {
return toRawType(val) === "Date";
}
//#endregion
//#region src/general/isDOMException.ts
function isDOMException(val) {
return toRawType(val) === "DOMException";
}
//#endregion
//#region src/general/isEmpty.ts
function isEmpty(val) {
return val === void 0 || val === null || val === "" || isArray(val) && !val.length;
}
//#endregion
//#region src/general/isError.ts
function isError(val) {
return toRawType(val) === "Error";
}
//#endregion
//#region src/general/isMap.ts
function isMap(val) {
return toRawType(val) === "Map";
}
//#endregion
//#region src/general/isObject.ts
function isObject(val) {
return typeof val === "object" && val !== null;
}
//#endregion
//#region src/general/isPlainObject.ts
function isPlainObject(val) {
return toRawType(val) === "Object";
}
//#endregion
//#region src/general/isRegExp.ts
function isRegExp(val) {
return toRawType(val) === "RegExp";
}
//#endregion
//#region src/general/isSet.ts
function isSet(val) {
return toRawType(val) === "Set";
}
//#endregion
//#region src/general/isTypedArray.ts
function isTypedArray(val) {
return [
"Int8Array",
"Uint8Array",
"Uint8ClampedArray",
"Int16Array",
"Uint16Array",
"Int32Array",
"Uint32Array",
"Float32Array",
"Float64Array",
"BigInt64Array",
"BigUint64Array"
].includes(toRawType(val));
}
//#endregion
//#region src/general/isEqualWith.ts
function isEqualWith(value, other, fn) {
const valueStack = /* @__PURE__ */ new WeakMap();
const otherStack = /* @__PURE__ */ new WeakMap();
function baseIsEqual(value, other, valueStack, otherStack) {
if (fn(value, other) === true) return true;
if (value === other) return true;
if (value !== value && other !== other) return true;
if (!isObject(value) || !isObject(other)) return value === other;
if (value.constructor !== other.constructor) return false;
if (toRawType(value) === "String" && toRawType(other) === "String" || toRawType(value) === "Number" && toRawType(other) === "Number" || toRawType(value) === "Boolean" && toRawType(other) === "Boolean" || toRawType(value) === "BigInt" && toRawType(other) === "BigInt" || toRawType(value) === "Symbol" && toRawType(other) === "Symbol") return value.valueOf() === other.valueOf();
if (isDate(value) && isDate(other)) return value.getTime() === other.getTime();
if (isRegExp(value) && isRegExp(other)) return value.source === other.source && value.flags === other.flags;
if (isError(value) && isError(other)) return value.name === other.name && value.message === other.message && value.cause === other.cause;
if (isDOMException(value) && isDOMException(other)) return value.name === other.name && value.message === other.message;
if (isTypedArray(value) && isTypedArray(other) || isDataView(value) && isDataView(other)) {
if (value.byteLength !== other.byteLength) return false;
const valueTypedArray = new Uint8Array(value.buffer);
const otherTypedArray = new Uint8Array(other.buffer);
return valueTypedArray.every((v, i) => v === otherTypedArray[i]);
}
if (isArrayBuffer(value) && isArrayBuffer(other)) {
if (value.byteLength !== other.byteLength) return false;
const valueTypedArray = new Uint8Array(value);
const otherTypedArray = new Uint8Array(other);
return valueTypedArray.every((v, i) => v === otherTypedArray[i]);
}
if (valueStack.get(value) === other && otherStack.get(other) === value) return true;
valueStack.set(value, other);
otherStack.set(other, value);
if (isMap(value) && isMap(other) || isSet(value) && isSet(other)) {
if (value.size !== other.size) return false;
const valueArray = [...value];
const otherArray = [...other];
const result = valueArray.every((v, i) => baseIsEqual(v, otherArray[i], valueStack, otherStack));
valueStack.delete(value);
otherStack.delete(other);
return result;
}
if (isArray(value) && isArray(other)) {
if (value.length !== other.length) return false;
const result = value.every((v, i) => baseIsEqual(v, other[i], valueStack, otherStack));
valueStack.delete(value);
otherStack.delete(other);
return result;
}
if (isPlainObject(value) && isPlainObject(other)) {
const valueOwnKeys = [...Object.keys(value), ...Object.getOwnPropertySymbols(value)];
const otherOwnKeys = [...Object.keys(other), ...Object.getOwnPropertySymbols(other)];
if (valueOwnKeys.length !== otherOwnKeys.length) return false;
const result = valueOwnKeys.every((k) => baseIsEqual(value[k], other[k], valueStack, otherStack));
valueStack.delete(value);
otherStack.delete(other);
return result;
}
return false;
}
return baseIsEqual(value, other, valueStack, otherStack);
}
//#endregion
//#region src/general/isEqual.ts
function isEqual(value, other) {
return isEqualWith(value, other, () => void 0);
}
//#endregion
//#region src/general/isNonEmptyArray.ts
function isNonEmptyArray(val) {
return isArray(val) && !!val.length;
}
//#endregion
//#region src/general/isNullish.ts
function isNullish(val) {
return val == null;
}
//#endregion
//#region src/general/isNumber.ts
function isNumber(val) {
return typeof val === "number";
}
//#endregion
//#region src/general/isNumeric.ts
function isNumeric(val) {
return isNumber(val) || isString(val) && /^[-+]?\d+$/.test(val);
}
//#endregion
//#region src/general/isPromise.ts
function isPromise(val) {
return isObject(val) && isFunction(val.then) && isFunction(val.catch);
}
//#endregion
//#region src/general/isSymbol.ts
function isSymbol(val) {
return typeof val === "symbol";
}
//#endregion
//#region src/general/isTruthy.ts
function isTruthy(v) {
return Boolean(v);
}
//#endregion
//#region src/general/isWeakMap.ts
function isWeakMap(val) {
return toRawType(val) === "WeakMap";
}
//#endregion
//#region src/general/isWeakSet.ts
function isWeakSet(val) {
return toRawType(val) === "WeakSet";
}
//#endregion
//#region src/general/isWindow.ts
function isWindow(val) {
return val === window;
}
//#endregion
//#region src/general/supportTouch.ts
function supportTouch() {
return inBrowser() && "ontouchstart" in window;
}
//#endregion
//#region src/general/isFile.ts
function isFile(val) {
return toRawType(val) === "File";
}
//#endregion
//#region src/general/isBlob.ts
function isBlob(val) {
return toRawType(val) === "Blob";
}
//#endregion
//#region src/general/isPrimitive.ts
function isPrimitive(val) {
return val == null || typeof val !== "object" && typeof val !== "function";
}
//#endregion
//#region src/general/isEmptyPlainObject.ts
function isEmptyPlainObject(val) {
return isPlainObject(val) && Object.keys(val).length === 0 && Object.getOwnPropertySymbols(val).length === 0;
}
//#endregion
//#region src/general/assert.ts
function assert(condition, message) {
if (!condition) throw new Error(message);
}
//#endregion
//#region src/general/hasDuplicates.ts
function hasDuplicates(arr) {
return uniq(arr).length !== arr.length;
}
//#endregion
//#region src/general/hasDuplicatesBy.ts
function hasDuplicatesBy(arr, fn) {
return uniqBy(arr, fn).length !== arr.length;
}
//#endregion
//#region src/number/toNumber.ts
function toNumber(val) {
if (val == null) return 0;
if (isString(val)) {
val = parseFloat(val);
val = Number.isNaN(val) ? 0 : val;
return val;
}
if (isBoolean(val)) return Number(val);
return val;
}
//#endregion
//#region src/number/genNumberKey.ts
let key$1 = 0;
function genNumberKey() {
return key$1++;
}
//#endregion
//#region src/array/chunk.ts
function chunk(arr, size = 1) {
size = clamp(size, 1, arr.length);
const result = [];
let index = 0;
while (index < arr.length) {
result.push(arr.slice(index, index + size));
index += size;
}
return result;
}
//#endregion
//#region src/array/removeItem.ts
function removeItem(arr, item) {
if (arr.length) {
const index = arr.indexOf(item);
if (index > -1) return arr.splice(index, 1);
}
}
//#endregion
//#region src/array/removeItemBy.ts
function removeItemBy(arr, fn) {
if (arr.length) {
const index = arr.findIndex((v) => fn(v));
if (index > -1) return arr.splice(index, 1);
}
}
//#endregion
//#region src/array/removeItemsBy.ts
function removeItemsBy(arr, fn) {
let i = 0;
const removedItems = [];
while (i < arr.length) if (fn(arr[i])) removedItems.push(...arr.splice(i, 1));
else i++;
return removedItems;
}
//#endregion
//#region src/array/toggleItem.ts
function toggleItem(arr, item) {
arr.includes(item) ? removeItem(arr, item) : arr.push(item);
return arr;
}
//#endregion
//#region src/array/uniq.ts
function uniq(arr) {
return [...new Set(arr)];
}
//#endregion
//#region src/array/uniqBy.ts
function uniqBy(arr, fn) {
return arr.reduce((ret, i) => {
if (ret.findIndex((j) => fn(i, j)) === -1) ret.push(i);
return ret;
}, []);
}
//#endregion
//#region src/array/find.ts
function find(arr, fn, from = "start") {
let i = from === "start" ? 0 : arr.length - 1;
while (arr.length > 0 && i >= 0 && i <= arr.length - 1) {
if (fn(arr[i], i, arr)) return [arr[i], i];
from === "start" ? i++ : i--;
}
return [null, -1];
}
//#endregion
//#region src/array/shuffle.ts
function shuffle(arr) {
for (let i = arr.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[arr[i], arr[j]] = [arr[j], arr[i]];
}
return arr;
}
//#endregion
//#region src/array/removeArrayBlank.ts
function removeArrayBlank(arr) {
return arr.filter((item) => item != null);
}
//#endregion
//#region src/array/removeArrayEmpty.ts
function removeArrayEmpty(arr) {
return arr.filter((item) => item != null && item !== "");
}
//#endregion
//#region src/array/normalizeToArray.ts
function normalizeToArray(value) {
return isArray(value) ? value : [value];
}
//#endregion
//#region src/array/differenceWith.ts
function differenceWith(arr, ...values) {
const fn = at(values, -1);
const targets = values.slice(0, -1).reduce((targets, value) => [...targets, ...value], []);
return arr.filter((item) => !targets.some((value) => fn(item, value)));
}
//#endregion
//#region src/array/difference.ts
function difference(arr, ...values) {
return differenceWith(arr, ...values, (a, b) => a === b);
}
//#endregion
//#region src/array/intersectionWith.ts
function intersectionWith(...values) {
const fn = at(values, -1);
const targets = values.slice(0, -1);
if (targets.length === 0) return [];
if (targets.length === 1) return uniqBy(targets[0], fn);
function baseIntersectionWith(arr1, arr2) {
return arr1.filter((item) => arr2.some((value) => fn(item, value)));
}
return uniqBy(targets.reduce((result, target) => baseIntersectionWith(result, target)), fn);
}
//#endregion
//#region src/array/intersection.ts
function intersection(...values) {
return intersectionWith(...values, (a, b) => a === b);
}
//#endregion
//#region src/array/groupBy.ts
function groupBy(arr, fn) {
return arr.reduce((result, item) => {
const key = fn(item);
(result[key] ??= []).push(item);
return result;
}, {});
}
//#endregion
//#region src/array/xorWith.ts
function xorWith(...values) {
const fn = at(values, -1);
return uniqBy(values.slice(0, -1).reduce((result, target) => {
return [...differenceWith(result, target, fn), ...differenceWith(target, result, fn)];
}), fn);
}
//#endregion
//#region src/array/xor.ts
function xor(...values) {
return xorWith(...values, (a, b) => a === b);
}
//#endregion
//#region src/object/pick.ts
function pick(object, keys) {
return keys.reduce((result, key) => {
result[key] = object[key];
return result;
}, {});
}
//#endregion
//#region src/object/pickBy.ts
function pickBy(object, fn) {
return [...Object.keys(object), ...Object.getOwnPropertySymbols(object)].reduce((result, key) => {
const value = object[key];
if (fn(value, key)) result[key] = value;
return result;
}, {});
}
//#endregion
//#region src/object/omit.ts
function omit(object, keys) {
return [...Object.keys(object), ...Object.getOwnPropertySymbols(object)].reduce((result, key) => {
if (!keys.includes(key)) result[key] = object[key];
return result;
}, {});
}
//#endregion
//#region src/object/omitBy.ts
function omitBy(object, fn) {
return [...Object.keys(object), ...Object.getOwnPropertySymbols(object)].reduce((result, key) => {
const value = object[key];
if (!fn(value, key)) result[key] = value;
return result;
}, {});
}
//#endregion
//#region src/object/deriveKey.ts
function deriveKey(object, mapping) {
const result = [...Object.keys(object), ...Object.getOwnPropertySymbols(object)].reduce((result, key) => {
result[key] = object[key];
return result;
}, {});
[...Object.keys(mapping), ...Object.getOwnPropertySymbols(mapping)].forEach((key) => {
if (!hasOwn(object, key)) return;
const nextKey = mapping[key];
result[nextKey] = object[key];
});
return result;
}
//#endregion
//#region src/object/rekey.ts
function rekey(object, mapping) {
return [...Object.keys(object), ...Object.getOwnPropertySymbols(object)].reduce((result, key) => {
const nextKey = hasOwn(mapping, key) ? mapping[key] : key;
result[nextKey] = object[key];
return result;
}, {});
}
//#endregion
//#region src/object/mapObject.ts
function mapObject(object, fn) {
return Object.entries(object).reduce((result, [key, value]) => {
const entry = fn(key, value);
if (isArray(entry)) {
const [newKey, newValue] = entry;
result[newKey] = newValue;
}
return result;
}, {});
}
//#endregion
//#region src/object/promiseWithResolvers.ts
function promiseWithResolvers() {
let resolve;
let reject;
return {
promise: new Promise((_resolver, _reject) => {
resolve = _resolver;
reject = _reject;
}),
resolve,
reject
};
}
//#endregion
//#region src/object/set.ts
function set(object, path, value) {
if (!isObject(object)) return;
const keys = [...path];
if (keys.length === 0) return;
let target = object;
while (keys.length > 1) {
const key = keys.shift();
const nextKey = keys[0];
if (!isObject(target[key])) target[key] = isNumber(nextKey) ? [] : {};
target = target[key];
}
target[keys[0]] = value;
}
//#endregion
//#region src/object/objectKeys.ts
function objectKeys(object) {
return Object.keys(object);
}
//#endregion
//#region src/object/objectEntries.ts
function objectEntries(object) {
return Object.entries(object);
}
//#endregion
//#region src/util/cancelAnimationFrame.ts
function cancelAnimationFrame(handle) {
const globalThis = getGlobalThis();
globalThis.cancelAnimationFrame ? globalThis.cancelAnimationFrame(handle) : globalThis.clearTimeout(handle);
}
//#endregion
//#region src/util/classes.ts
function classes(...classes) {
return classes.map((className) => {
if (isArray(className)) {
const [condition, truthy, falsy = null] = className;
return condition ? truthy : falsy;
}
return className;
});
}
//#endregion
//#region src/util/copyText.ts
function copyText(value) {
if (!value) return;
const textArea = document.createElement("textarea");
textArea.value = value;
textArea.style.position = "fixed";
textArea.style.opacity = "0";
document.body.appendChild(textArea);
textArea.select();
document.execCommand("copy");
document.body.removeChild(textArea);
}
//#endregion
//#region src/string/maskString.ts
function maskString(text, { prefix = 2, suffix = 2, mask = "*", maskLength } = {}) {
if (text.length <= 1) return text;
const effectivePrefix = Math.min(prefix, text.length - 1);
const effectiveSuffix = Math.min(suffix, Math.max(text.length - effectivePrefix - 1, 0));
const count = maskLength ?? text.length - effectivePrefix - effectiveSuffix;
const suffixPart = effectiveSuffix > 0 ? text.slice(-effectiveSuffix) : "";
return text.slice(0, effectivePrefix) + mask.repeat(count) + suffixPart;
}
//#endregion
//#region src/string/camelize.ts
function camelize(s) {
s = s.replace(/[-_](\w)/g, (_, p) => p.toUpperCase());
return s.replace(s.charAt(0), s.charAt(0).toLowerCase());
}
//#endregion
//#region src/string/ensurePrefix.ts
function ensurePrefix(s, prefix) {
return s.startsWith(prefix) ? s : prefix + s;
}
//#endregion
//#region src/string/ensureSuffix.ts
function ensureSuffix(s, suffix) {
return s.endsWith(suffix) ? s : s + suffix;
}
//#endregion
//#region src/string/genStringKey.ts
let key = 0;
function genStringKey() {
return `generated-key-${key++}`;
}
//#endregion
//#region src/string/kebabCase.ts
function kebabCase(s) {
return s.replace(/([A-Z])/g, " $1").replace(/[_\s]+/g, "-").trim().replace(/^-/, "").toLowerCase();
}
//#endregion
//#region src/string/pascalCase.ts
function pascalCase(s) {
const ret = camelize(s);
return ret.replace(ret.charAt(0), ret.charAt(0).toUpperCase());
}
//#endregion
//#region src/string/lowerFirst.ts
function lowerFirst(s) {
return s.charAt(0).toLowerCase() + s.slice(1);
}
//#endregion
//#region src/string/upperFirst.ts
function upperFirst(s) {
return s.charAt(0).toUpperCase() + s.slice(1);
}
//#endregion
//#region src/string/randomColor.ts
function randomColor() {
const letters = "0123456789abcdef";
let color = "#";
for (let i = 0; i < 6; i++) color += letters[Math.floor(Math.random() * 16)];
return color;
}
//#endregion
//#region src/string/randomString.ts
function randomString(length = 10) {
let str = baseRandomString();
while (str.length < length) str += baseRandomString();
function baseRandomString() {
return Math.random().toString(36).slice(2);
}
return str.slice(0, length);
}
//#endregion
//#region src/string/slash.ts
function slash(path) {
if (path.startsWith("\\\\?\\")) return path;
return path.replace(/\\/g, "/");
}
//#endregion
//#region src/util/createNamespaceFn.ts
function createNamespaceFn(namespace) {
return (name) => {
const componentName = `${namespace}-${name}`;
const createBEM = (suffix) => {
if (!suffix) return componentName;
if (suffix[0] === "$") return suffix.replace("$", namespace);
return suffix.startsWith("--") ? `${componentName}${suffix}` : `${componentName}__${suffix}`;
};
return {
name: pascalCase(componentName),
n: createBEM,
classes
};
};
}
//#endregion
//#region src/util/requestAnimationFrame.ts
function requestAnimationFrame(fn) {
const globalThis = getGlobalThis();
return globalThis.requestAnimationFrame ? globalThis.requestAnimationFrame(fn) : globalThis.setTimeout(fn);
}
//#endregion
//#region src/util/doubleRaf.ts
function doubleRaf() {
return new Promise((resolve) => {
requestAnimationFrame(() => {
requestAnimationFrame(resolve);
});
});
}
//#endregion
//#region src/util/getStyle.ts
function getStyle(element) {
return window.getComputedStyle(element);
}
//#endregion
//#region src/util/getParentScroller.ts
function getParentScroller(el) {
let element = el;
while (element) {
if (!element.parentNode) break;
element = element.parentNode;
if (element === document.body || element === document.documentElement) break;
const scrollRE = /(scroll|auto)/;
const { overflowY, overflow } = getStyle(element);
if (scrollRE.test(overflowY) || scrollRE.test(overflow)) return element;
}
return window;
}
//#endregion
//#region src/util/getAllParentScroller.ts
function getAllParentScroller(el) {
const allParentScroller = [];
let element = el;
while (!isWindow(element)) {
element = getParentScroller(element);
allParentScroller.push(element);
}
return allParentScroller;
}
//#endregion
//#region src/util/getRect.ts
function getRect(element) {
if (isWindow(element)) {
const width = element.innerWidth;
const height = element.innerHeight;
const rect = {
x: 0,
y: 0,
top: 0,
left: 0,
right: width,
bottom: height,
width,
height
};
return {
...rect,
toJSON: () => rect
};
}
return element.getBoundingClientRect();
}
//#endregion
//#region src/util/getScrollLeft.ts
function getScrollLeft(element) {
const left = "scrollLeft" in element ? element.scrollLeft : element.scrollX;
return Math.max(left, 0);
}
//#endregion
//#region src/util/getScrollTop.ts
function getScrollTop(element) {
const top = "scrollTop" in element ? element.scrollTop : element.scrollY;
return Math.max(top, 0);
}
//#endregion
//#region src/util/inViewport.ts
function inViewport(element) {
const { top, bottom, left, right } = getRect(element);
const { width, height } = getRect(window);
return left <= width && right >= 0 && top <= height && bottom >= 0;
}
//#endregion
//#region src/util/prettyJSONObject.ts
function prettyJSONObject(jsonObject) {
return JSON.stringify(jsonObject, null, 2);
}
//#endregion
//#region src/util/preventDefault.ts
function preventDefault(event) {
if (event.cancelable === false) return;
event.preventDefault();
}
//#endregion
//#region src/util/raf.ts
function raf() {
return new Promise((resolve) => {
requestAnimationFrame(resolve);
});
}
//#endregion
//#region src/util/storage.ts
function createStorage(storage) {
return {
...storage,
set(key, value) {
if (value == null) return;
if (!isString(value)) value = JSON.stringify(value);
storage.setItem(key, value);
},
get(key) {
const data = storage.getItem(key);
try {
return JSON.parse(data);
} catch (err) {
return data;
}
},
remove(key) {
storage.removeItem(key);
}
};
}
function createCookieStorage(options = {}) {
const defaultOptions = options;
return {
set(key, value, options = {}) {
if (value == null) return;
if (!isString(value)) value = JSON.stringify(value);
Cookie.set(key, value, {
...defaultOptions,
...options
});
},
get(key) {
const data = Cookie.get(key);
try {
return JSON.parse(data);
} catch (err) {
return data;
}
},
remove(key, options = {}) {
Cookie.remove(key, {
...defaultOptions,
...options
});
}
};
}
const sessionStorage = createStorage(getGlobalThis().sessionStorage);
const localStorage = createStorage(getGlobalThis().localStorage);
//#endregion
//#region src/util/tryParseJSON.ts
function tryParseJSON(json) {
try {
return JSON.parse(json);
} catch {
return;
}
}
//#endregion
//#region src/util/download.ts
function download(val, filename = "file") {
const a = document.createElement("a");
a.style.display = "none";
a.href = isString(val) ? val : URL.createObjectURL(val);
a.download = filename;
document.body.appendChild(a);
a.click();
URL.revokeObjectURL(a.href);
document.body.removeChild(a);
}
//#endregion
//#region src/function/call.ts
function call(fn, ...args) {
if (isArray(fn)) return fn.map((f) => f(...args));
if (fn) return fn(...args);
}
//#endregion
//#region src/function/tryCall.ts
function tryCall(fn, ...args) {
try {
return [void 0, fn(...args)];
} catch (e) {
return [e, void 0];
}
}
//#endregion
//#region src/function/tryAsyncCall.ts
async function tryAsyncCall(fn, ...args) {
try {
return [void 0, await fn(...args)];
} catch (e) {
return [e, void 0];
}
}
//#endregion
//#region src/function/once.ts
function once(fn) {
let called = false;
let result;
return function(...args) {
if (called) return result;
called = true;
result = fn.apply(this, args);
return result;
};
}
//#endregion
//#region src/function/debounce.ts
function debounce(fn, delay = 0) {
let timer;
return function(...args) {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}
//#endregion
//#region src/function/throttle.ts
function throttle(fn, delay = 200) {
let timer;
let start = 0;
return function loop(...args) {
const now = performance.now();
const elapsed = now - start;
if (!start) start = now;
if (timer) clearTimeout(timer);
if (elapsed >= delay) {
fn.apply(this, args);
start = now;
} else timer = setTimeout(() => {
loop.apply(this, args);
}, delay - elapsed);
};
}
//#endregion
//#region src/function/NOOP.ts
function NOOP() {}
//#endregion
//#region src/util/enumOf.ts
function enumOf(config) {
const extractValues = Object.entries(config).reduce((result, [key, value]) => {
result[key] = isPlainObject(value) ? value.value : value;
return result;
}, {});
const configValues = Object.values(config);
function label(v) {
const valueObject = getValueObject(v);
return valueObject?.label ? callOrReturn(valueObject.label) : "";
}
function description(v) {
const valueObject = getValueObject(v);
return valueObject?.description ? callOrReturn(valueObject.description) : "";
}
function values() {
return configValues.map((option) => isPlainObject(option) ? option.value : option);
}
function labels() {
return configValues.map((option) => {
if (isPlainObject(option)) return option.label ? callOrReturn(option.label) : "";
return "";
});
}
function descriptions() {
return configValues.map((option) => {
if (isPlainObject(option)) return option.description ? callOrReturn(option.description) : "";
return "";
});
}
function resolveOption(option) {
const result = {};
for (const key of Object.keys(option)) result[key] = callOrReturn(option[key]);
return result;
}
function option(v) {
const valueObject = getValueObject(v);
if (valueObject) return resolveOption(valueObject);
return {
value: v,
label: "",
description: ""
};
}
function options() {
return configValues.map((option) => {
if (isPlainObject(option)) return resolveOption(option);
return {
value: option,
label: "",
description: ""
};
});
}
function getValueObject(v) {
return configValues.find((option) => isPlainObject(option) && option.value === v);
}
return {
...extractValues,
values,
label,
description,
labels,
descriptions,
option,
options
};
}
//#endregion
//#region src/util/motion.ts
function motion(options) {
const { from, to, duration = 300, frame = () => {}, timingFunction = (value) => value, onStateChange = () => {} } = options;
let state = "pending";
let value = from;
const distance = to - from;
let ticker = void 0;
let startTime = void 0;
let pausedTime = void 0;
let sleepTime = 0;
function start() {
if (state === "running" || state === "finished") return;
setState("running");
const now = performance.now();
startTime = startTime != null ? startTime : now;
sleepTime += pausedTime != null ? now - pausedTime : 0;
pausedTime = void 0;
tick();
function tick() {
ticker = requestAnimationFrame(() => {
const progress = clamp((performance.now() - startTime - sleepTime) / duration, 0, 1);
value = distance * timingFunction(progress) + from;
if (progress >= 1) {
setState("finished");
frame({
value: to,
done: true
});
return;
}
frame({
value,
done: false
});
tick();
});
}
}
function pause() {
if (state !== "running") return;
cancelAnimationFrame(ticker);
setState("paused");
pausedTime = performance.now();
}
function reset() {
cancelAnimationFrame(ticker);
setState("pending");
value = from;
ticker = void 0;
startTime = void 0;
pausedTime = void 0;
sleepTime = 0;
}
function getState() {
return state;
}
function setState(_state) {
state = _state;
onStateChange(_state);
}
return {
start,
pause,
reset,
getState
};
}
//#endregion
//#region src/util/duration.ts
function duration() {
const ctx = {
value: 0,
years,
months,
weeks,
days,
hours,
minutes,
seconds,
milliseconds,
valueOf
};
function years(value) {
ctx.value += value * 365 * 24 * 60 * 60 * 1e3;
return ctx;
}
function months(value) {
ctx.value += value * 30 * 24 * 60 * 60 * 1e3;
return ctx;
}
function weeks(value) {
ctx.value += value * 7 * 24 * 60 * 60 * 1e3;
return ctx;
}
function days(value) {
ctx.value += value * 24 * 60 * 60 * 1e3;
return ctx;
}
function hours(value) {
ctx.value += value * 60 * 60 * 1e3;
return ctx;
}
function minutes(value) {
ctx.value += value * 60 * 1e3;
return ctx;
}
function seconds(value) {
ctx.value += value * 1e3;
return ctx;
}
function milliseconds(value) {
ctx.value += value;
return ctx;
}
function valueOf(options = { milliseconds: true }) {
return options.milliseconds ? ctx.value : ctx.value / 1e3;
}
return ctx;
}
//#endregion
//#region src/util/createCacheManager.ts
function createCacheManager(options = {}) {
const cacheManager = /* @__PURE__ */ new Map();
const { ttl: defaultTtl = Infinity } = options;
function purgeStale() {
cacheManager.forEach((value, key) => {
if (performance.now() > value.expiredAt) remove(key);
});
}
function has(key) {
purgeStale();
return cacheManager.has(key);
}
function get(key) {
purgeStale();
return cacheManager.get(key)?.value;
}
function set(key, value, options) {
const ttl = options?.ttl ?? defaultTtl;
cacheManager.set(key, {
expiredAt: performance.now() + ttl,
value
});
}
function remove(key) {
return cacheManager.delete(key);
}
function clear() {
cacheManager.clear();
}
return {
has,
get,
set,
remove,
clear
};
}
//#endregion
//#region src/util/navigation.ts
function buildNavigationUrl(target) {
if (isString(target)) return target;
const { to, query, hash } = target;
const hashIndex = to.indexOf("#");
const toWithoutHash = hashIndex >= 0 ? to.slice(0, hashIndex) : to;
const existingHash = hashIndex >= 0 ? `#${to.slice(hashIndex + 1)}` : "";
const queryIndex = toWithoutHash.indexOf("?");
const base = queryIndex >= 0 ? toWithoutHash.slice(0, queryIndex) : toWithoutHash;
const existingQueryString = queryIndex >= 0 ? toWithoutHash.slice(queryIndex + 1) : "";
const params = new URLSearchParams(existingQueryString);
if (query) for (const [key, value] of Object.entries(query)) params.append(key, String(value));
const queryString = params.toString();
const finalHash = hash ?? existingHash;
let url = base;
if (queryString) url += `?${queryString}`;
if (finalHash) url += finalHash;
return url;
}
const navigation = {
push(target) {
window.location.assign(buildNavigationUrl(target));
},
replace(target) {
window.location.replace(buildNavigationUrl(target));
},
open(target) {
const url = buildNavigationUrl(target);
window.open(url);
},
back() {
window.history.back();
},
go(delta) {
window.history.go(delta);
}
};
//#endregion
//#region src/collection/cloneDeepWith.ts
function cloneDeepWith(value, fn) {
const cache = /* @__PURE__ */ new WeakMap();
function baseCloneDeep(value, cache) {
const customResult = fn(value);
if (customResult !== void 0) return customResult;
if (!isObject(value)) return value;
if (cache.has(value)) return cache.get(value);
if (isDate(value)) return new Date(value);
if (isRegExp(value)) return new RegExp(value);
if (isMap(value)) {
const result = /* @__PURE__ */ new Map();
cache.set(value, result);
value.forEach((val, key) => {
result.set(baseCloneDeep(key, cache), baseCloneDeep(val, cache));
});
return result;
}
if (isSet(value)) {
const result = /* @__PURE__ */ new Set();
cache.set(value, result);
value.forEach((val) => {
result.add(baseCloneDeep(val, cache));
});
return result;
}
if (toRawType(value) === "String" || toRawType(value) === "Number" || toRawType(value) === "Boolean") return newConstructor(value, value.valueOf());
if (isWeakMap(value) || isWeakSet(value) || isError(value) || isDOMException(value)) return {};
if (isTypedArray(value)) return newConstructor(value, baseCloneArrayBuffer(value.buffer), value.byteOffset, value.length);
if (isDataView(value)) return newConstructor(value, baseCloneArrayBuffer(value.buffer), value.byteOffset, value.byteLength);
if (isArrayBuffer(value)) return baseCloneArrayBuffer(value);
if (isArray(value)) {
const result = [];
cache.set(value, result);
value.forEach((value, index) => {
result[index] = baseCloneDeep(value, cache);
});
return result;
}
if (isPlainObject(value)) {
const result = Object.create(Reflect.getPrototypeOf(value));
cache.set(value, result);
[...Object.keys(value), ...Object.getOwnPropertySymbols(value)].forEach((key) => {
result[key] = baseCloneDeep(value[key], cache);
});
return result;
}
return value;
}
function baseCloneArrayBuffer(value) {
const result = new ArrayBuffer(value.byteLength);
new Uint8Array(result).set(new Uint8Array(value));
return result;
}
function newConstructor(value, ...args) {
return new value.constructor(...args);
}
return baseCloneDeep(value, cache);
}
//#endregion
//#region src/collection/cloneDeep.ts
function cloneDeep(value) {
return cloneDeepWith(value, () => void 0);
}
//#endregion
//#region src/collection/mergeWith.ts
function mergeWith(object, ...sources) {
const fn = at(sources, -1);
const targets = [object, ...sources.slice(0, -1)];
let len = targets.length - 1;
let result = targets[len];
while (len) {
result = baseMergeWith(targets[len - 1], result, fn);
len--;
}
function baseMergeWith(object, source, fn) {
function baseMerge(target, src) {
for (const key in src) if (hasOwn(src, key)) {
const srcValue = src[key];
const targetValue = target[key];
const customResult = fn(targetValue, srcValue, key, object, source);
if (customResult !== void 0) target[key] = customResult;
else if (isObject(srcValue)) if (isObject(targetValue)) target[key] = baseMerge(targetValue, srcValue);
else target[key] = baseMerge(isArray(srcValue) ? [] : {}, srcValue);
else target[key] = srcValue;
}
return target;
}
return baseMerge(object, source);
}
return result;
}
//#endregion
//#region src/collection/merge.ts
function merge(object, ...sources) {
return mergeWith(object, ...sources, () => void 0);
}
//#endregion
//#region src/file/toArrayBuffer.ts
function toArrayBuffer(file) {
return new Promise((resolve) => {
const fileReader = new FileReader();
fileReader.onload = () => {
resolve(fileReader.result);
};
fileReader.readAsArrayBuffer(file);
});
}
//#endregion
//#region src/file/toDataURL.ts
function toDataURL(file) {
return new Promise((resolve) => {
const fileReader = new FileReader();
fileReader.onload = () => {
resolve(fileReader.result);
};
fileReader.readAsDataURL(file);
});
}
//#endregion
//#region src/file/toText.ts
function toText(file) {
return new Promise((resolve) => {
const fileReader = new FileReader();
fileReader.onload = () => {
resolve(fileReader.result);
};
fileReader.readAsText(file);
});
}
//#endregion
//#region src/math/maxBy.ts
function maxBy(arr, fn) {
return arr.reduce((result, item) => fn(result) > fn(item) ? result : item, arr[0]);
}
//#endregion
//#region src/math/minBy.ts
function minBy(arr, fn) {
return arr.reduce((result, item) => fn(result) < fn(item) ? result : item, arr[0]);
}
//#endregion
//#region src/math/sum.ts
function sum(arr) {
return arr.reduce((ret, val) => ret + val, 0);
}
//#endregion
//#region src/math/sumBy.ts
function sumBy(arr, fn) {
return arr.reduce((ret, val) => ret + fn(val), 0);
}
//#endregion
//#region src/math/sumHash.ts
function sumHash(value) {
function sum(hash, value) {
for (let i = 0; i < value.length; i++) {
const chr = value.charCodeAt(i);
hash = (hash << 5) - hash + chr;
hash |= 0;
}
return hash < 0 ? hash * -2 : hash;
}
function baseSumHash(hash, value, key, seen) {
hash = sum(hash, key);
hash = sum(hash, toTypeString(value));
hash = sum(hash, typeof value);
if (value === null) return sum(hash, "null");
if (value === void 0) return sum(hash, "undefined");
if (isObject(value) || isFunction(value)) {
if (seen.includes(value)) return sum(hash, `[Circular]${key}`);
seen.push(value);
hash = Object.keys(value).sort().reduce((hash, key) => baseSumHash(hash, value[key], key, seen), hash);
if (isFunction(value.valueOf)) return sum(hash, String(value.valueOf()));
return hash;
}
return sum(hash, value.toString());
}
return baseSumHash(0, value, "", []).toString(16).padStart(8, "0");
}
//#endregion
//#region src/math/mean.ts
function mean(arr) {
return sum(arr) / arr.length;
}
//#endregion
//#region src/math/meanBy.ts
function meanBy(arr, fn) {
return sumBy(arr, fn) / arr.length;
}
//#endregion
//#region src/math/sample.ts
function sample(arr) {
if (!arr.length) return;
return arr[randomNumber(0, arr.length - 1)];
}
//#endregion
//#region src/math/round.ts
function round(val, precision = 0) {
return baseRound(val, precision, Math.round);
}
function baseRound(val, precision, fn) {
precision = clamp(precision ?? 0, -292, 292);
if (!precision) return fn(val);
return +`${fn(`${val}e${precision}`)}e${-precision}`;
}
//#endregion
//#region src/math/floor.ts
function floor(val, precision = 0) {
return baseRound(val, precision, Math.floor);
}
//#endregion
//#region src/math/ceil.ts
function ceil(val, precision = 0) {
return baseRound(val, precision, Math.ceil);
}
//#endregion
export { NOOP, assert, at, baseRound, buildNavigationUrl, call, callOrReturn, camelize, cancelAnimationFrame, ceil, chunk, clamp, clampArrayRange, classes, cloneDeep, cloneDeepWith, copyText, createCacheManager, createCookieStorage, createNamespaceFn, createStorage, debounce, delay, deriveKey, difference, differenceWith, doubleRaf, download, duration, ensurePrefix, ensureSuffix, enumOf, find, floor, genNumberKey, genStringKey, getAllParentScroller, getGlobalThis, getParentScroller, getRect, getScrollLeft, getScrollTop, getStyle, groupBy, hasDuplicates, hasDuplicatesBy, hasOwn, inBrowser, inMobile, inViewport, intersection, intersectionWith, isArray, isArrayBuffer, isBlob, isBoolean, isDOMException, isDataView, isDate, isEmpty, isEmptyPlainObject, isEqual, isEqualWith, isError, isFile, isFunction, isMap, isNonEmptyArray, isNullish, isNumber, isNumeric, isObject, isPlainObject, isPrimitive, isPromise, isRegExp, isSet, isString, isSymbol, isTruthy, isTypedArray, isWeakMap, isWeakSet, isWindow, kebabCase, localStorage, lowerFirst, mapObject, maskString, maxBy, mean, meanBy, merge, mergeWith, minBy, mitt, motion, navigation, normalizeToArray, objectEntries, objectKeys, objectToString, omit, omitBy, once, pascalCase, pick, pickBy, prettyJSONObject, preventDefault, promiseWithResolvers, raf, randomColor, randomNumber, randomString, rekey, removeArrayBlank, removeArrayEmpty, removeItem, removeItemBy, removeItemsBy, requestAnimationFrame, round, sample, sessionStorage, set, shuffle, slash, sum, sumBy, sumHash, supportTouch, throttle, times, toArrayBuffer, toDataURL, toNumber, toRawType, toText, toTypeString, toggleItem, tryAsyncCall, tryCall, tryParseJSON, uniq, uniqBy, upperFirst, uuid, uuidV6, xor, xorWith };