fuc-new/doc/node_modules/@pengzhanbo/utils/dist/index.mjs
hellcat 6adbc04d4b 1
2025-10-03 17:17:08 +08:00

935 lines
25 KiB
JavaScript

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 = {
"&": "&amp;",
"<": "&lt;",
">": "&gt;",
'"': "&quot;",
"'": "&#39;"
};
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 = {
"&amp;": "&",
"&lt;": "<",
"&gt;": ">",
"&quot;": '"',
"&#39;": "'"
};
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 };