{"version":3,"file":"index.mjs","names":["TWEMOJI_REGEX","parseValue","defaultWindow","toError","number","buildFieldsInfo","EJSON","onError","#count","#value","EJSON","#listeners","#limit","#events","#cancelFns","#promise","#error","#isCancelled"],"sources":["../src/object/getTag/getTag.ts","../src/is.ts","../src/array/arrayable/arrayable.ts","../src/array/avg/avg.ts","../src/array/avgCircular/avgCircular.ts","../src/array/chunk/chunk.ts","../src/array/chunkSeries/chunkSeries.ts","../src/array/difference/difference.ts","../src/specialValue.ts","../src/array/filterMap/filterMap.ts","../src/array/groupBy/groupBy.ts","../src/array/intersection/intersection.ts","../src/array/intersectionBy/intersectionBy.ts","../src/array/keyBy/keyBy.ts","../src/array/orderBy/compareAscending.ts","../src/array/orderBy/orderBy.ts","../src/array/shuffle/shuffle.ts","../src/object/cleanEmpty/cleanEmpty.ts","../src/object/cleanObject/cleanObject.ts","../src/object/deepAssign/deepAssign.ts","../src/object/deepCloneWith/deepCloneWithImpl.ts","../src/object/deepClone/deepClone.ts","../src/object/def/def.ts","../src/object/deepCloneWith/deepCloneWith.ts","../src/object/deepCloneWith/createSecureCustomizer.ts","../src/object/deepDefaults/deepDefaults.ts","../src/object/deepFreeze/deepFreeze.ts","../src/object/flagsToMap/flagsToMap.ts","../src/object/flatten/flatten.ts","../src/str/capitalize/capitalize.ts","../src/str/getWords/getWords.ts","../src/str/camelCase/camelCase.ts","../src/str/convertToUnit/convertToUnit.ts","../src/str/escapeHtml/escapeHtml.ts","../src/str/escapeNumeric/escapeNumeric.ts","../src/str/escapeRegExp/escapeRegExp.ts","../src/str/twemojiRegex/twemojiRegex.ts","../src/str/isOneEmoji/isOneEmoji.ts","../src/str/getInitials/getInitials.ts","../src/str/hasProtocol/hasProtocol.ts","../src/str/hex/hex.ts","../src/str/isDeepKey/isDeepKey.ts","../src/str/isIndex/isIndex.ts","../src/str/isoToFlagEmoji/isoToFlagEmoji.ts","../src/str/kebabCase/kebabCase.ts","../src/str/lowerCase/lowerCase.ts","../src/str/maskingWords/maskingWords.ts","../src/str/maskingEmail/maskingEmail.ts","../src/str/maskingPhone/maskingPhone.ts","../src/date/timestamp/timestamp.ts","../src/str/objectId/objectId.ts","../src/str/randomString/randomString.ts","../src/str/snakeCase/snakeCase.ts","../src/str/sprintf/sprintf.ts","../src/str/startCase/startCase.ts","../src/str/strAssign/strAssign.ts","../src/str/text.ts","../src/str/toKey/toKey.ts","../src/str/toString/toString.ts","../src/str/toPath/toPath.ts","../src/str/truncate/truncate.ts","../src/str/wrapText/wrapText.ts","../src/str/isUnsafeProperty.ts","../src/object/get/get.ts","../src/object/has/has.ts","../src/object/hasOwn/hasOwn.ts","../src/object/omit/omit.ts","../src/object/omitPrefixed/omitPrefixed.ts","../src/object/pick/pick.ts","../src/object/pickPrefixed/pickPrefixed.ts","../src/object/updateWith/updateWith.ts","../src/object/set/set.ts","../src/object/toMap/toMap.ts","../src/object/unflatten/unflatten.ts","../src/object/unset/unset.ts","../src/array/SortedArray/SortedArray.ts","../src/array/sum/sum.ts","../src/array/uniq/uniq.ts","../src/array/union/union.ts","../src/array/uniqBy/uniqBy.ts","../src/errors/AssertionError.ts","../src/function/constant/constant.ts","../src/toError.ts","../src/function/createFunction.ts","../src/function/debounce/debounce.ts","../src/function/execResult.ts","../src/function/identity/identity.ts","../src/function/negate/negate.ts","../src/function/typeOf/typeOf.ts","../src/function/qs/qs.ts","../src/num/clamp/clamp.ts","../src/promise/defer/defer.ts","../src/promise/fastIdle/fastIdle.ts","../src/promise/delay/delay.ts","../src/function/retryOnError/retryOnError.ts","../src/function/throttle/throttle.ts","../src/assert/assert.ts","../src/array/weightedRoundRobin/weightedRoundRobin.ts","../src/binary/basex/basex.ts","../src/binary/base62/index.ts","../src/binary/base62Fast/base62Fast.ts","../src/binary/base64/Base64Encoding.ts","../src/binary/base64/index.ts","../src/binary/base64ToBytes/base64ToBytes.ts","../src/binary/bigIntBytes/bigIntBytes.ts","../src/binary/bigIntFromBytes/bigIntFromBytes.ts","../src/binary/bitPack/bitPack.ts","../src/binary/bitUnpack/bitUnpack.ts","../src/binary/bytesToBase64/bytesToBase64.ts","../src/binary/compareBytes/compareBytes.ts","../src/binary/concatenateBytes/concatenateBytes.ts","../src/binary/rleDecode/rleDecode.ts","../src/binary/rleEncode/rleEncode.ts","../src/binary/uint16ToUint8/uint16ToUint8.ts","../src/binary/uint32ToUint8/uint32ToUint8.ts","../src/binary/uint8ToUint16/uint8ToUint16.ts","../src/binary/uint8ToUint32/uint8ToUint32.ts","../src/ejson/types.ts","../src/ejson/EJSON.ts","../src/ejson/createEJSON.ts","../src/ejson/EJSONStream.ts","../src/ejson/instance.ts","../src/ejson/createEJSONStream.ts","../src/cache/createWithCache/utils.ts","../src/cache/createWithCache/createWithCache.ts","../src/cache/withCache/withCache.ts","../src/cache/FixedMap/utils.ts","../src/cache/FixedMap/FixedMap.ts","../src/cache/TimeBucket/TimeBucket.ts","../src/cache/withCacheBucket/withCacheBucket.ts","../src/cache/withCacheFixed/withCacheFixed.ts","../src/cache/LruCache/LruCache.ts","../src/cache/withCacheLRU/withCacheLRU.ts","../src/cache/dropCache/dropCache.ts","../src/cache/FixedWeakMap/FixedWeakMap.ts","../src/cache/isCached/isCached.ts","../src/cache/withCacheBucketBatch/withCacheBucketBatch.ts","../src/cache/withDeepClone/withDeepClone.ts","../src/cache/withPointerCache/withPointerCache.ts","../src/captureStackTrace.ts","../src/catchError.ts","../src/colors/parseAlpha/parseAlpha.ts","../src/colors/hexToChannels/parseHEX.ts","../src/num/parsePercentage/parsePercentage.ts","../src/colors/utils.ts","../src/colors/hslToChannels/parseHSL.ts","../src/num/checkBitmask/checkBitmask.ts","../src/num/getRandomInt/getRandomInt.ts","../src/num/createRandomizer/createRandomizer.ts","../src/num/findMean/findMean.ts","../src/num/formatNumber/formatNumber.ts","../src/num/round2digits/round2digits.ts","../src/num/formatMoney/formatMoney.ts","../src/num/humanize/humanize.ts","../src/num/parseAllNumbers/parseAllNumbers.ts","../src/num/percentOf/percentOf.ts","../src/colors/rgbToChannels/parseRGB.ts","../src/colors/buildCssColor/buildCssColor.ts","../src/colors/hexToChannels/hexToChannels.ts","../src/colors/hslToChannels/hslToChannels.ts","../src/colors/rgbToChannels/rgbToChannels.ts","../src/colors/colorToChannels/colorToChannels.ts","../src/colors/alpha/alpha.ts","../src/colors/blendColors/blendColors.ts","../src/colors/channelsToHex/channelsToHex.ts","../src/colors/channelsToHSL/channelsToHSL.ts","../src/colors/channelsToRGB/channelsToRGB.ts","../src/colors/contrastRatio/contrastRatio.ts","../src/colors/cssVariable/cssVariable.ts","../src/colors/interpolateColor/interpolateColor.ts","../src/colors/luminance/luminance.ts","../src/colors/tintedTextColor/tintedTextColor.ts","../src/colors/index.ts","../src/crypto/crc32/crc32.ts","../src/date/isDateObject/isDateObject.ts","../src/date/createDateObject/createDateObject.ts","../src/date/isTimeObject/isTimeObject.ts","../src/date/createTimeObject/createTimeObject.ts","../src/date/createTimeSpan/TimeSpan.ts","../src/date/createTimeSpan/createTimeSpan.ts","../src/date/timestampMs/timestampMs.ts","../src/date/dateInDays/dateInDays.ts","../src/date/dateInSeconds/dateInSeconds.ts","../src/date/getRandomTime/getRandomTime.ts","../src/date/hmToSeconds/hmToSeconds.ts","../src/date/isTimeString/isTimeString.ts","../src/date/isTimeValue/isTimeValue.ts","../src/date/isValidWeekDay/isValidWeekDay.ts","../src/date/secondsToHm/secondsToHm.ts","../src/date/timeFromMinutes/timeFromMinutes.ts","../src/date/timestampToDate/timestampToDate.ts","../src/date/timeStringify/timeStringify.ts","../src/date/timeToMinutes/timeToMinutes.ts","../src/date/weeksInYear/weeksInYear.ts","../src/env.ts","../src/errors/AppError.ts","../src/files/getFileExtension/getFileExtension.ts","../src/files/getFileName/getFileName.ts","../src/files/getMostSpecificPaths/getMostSpecificPaths.ts","../src/files/humanFileSize/humanFileSize.ts","../src/logger.ts","../src/promise/nextTickIteration/nextTickIteration.ts","../src/promise/asyncFilter/asyncFilter.ts","../src/promise/asyncFilterMap/asyncFilterMap.ts","../src/promise/asyncFind/asyncFind.ts","../src/promise/asyncForEach/asyncForEach.ts","../src/promise/SimpleEventEmitter/SimpleEventEmitter.ts","../src/promise/Queue/Queue.ts","../src/promise/AsyncIterableQueue/AsyncIterableQueue.ts","../src/promise/asyncMap/asyncMap.ts","../src/promise/CancellablePromise/CancellablePromise.ts","../src/promise/fastRaf/fastRaf.ts","../src/promise/ResourcePool/ResourcePool.ts","../src/promise/scheduler/scheduler.ts","../src/promise/timeout/timeout.ts","../src/promise/toPromise/toPromise.ts","../src/promise/withResolve/withResolve.ts"],"sourcesContent":["export var nullTag = '[object Null]';\nexport var undefinedTag = '[object Undefined]';\nexport var regexpTag = '[object RegExp]';\nexport var stringTag = '[object String]';\nexport var numberTag = '[object Number]';\nexport var booleanTag = '[object Boolean]';\nexport var argumentsTag = '[object Arguments]';\nexport var symbolTag = '[object Symbol]';\nexport var dateTag = '[object Date]';\nexport var bigintTag = '[object BigInt]';\nexport var mapTag = '[object Map]';\nexport var setTag = '[object Set]';\nexport var arrayTag = '[object Array]';\nexport var functionTag = '[object Function]';\nexport var arrayBufferTag = '[object ArrayBuffer]';\nexport var objectTag = '[object Object]';\nexport var weakmapTag = '[object WeakMap]';\nexport var weaksetTag = '[object WeakSet]';\nexport var errorTag = '[object Error]';\nexport var dataViewTag = '[object DataView]';\nexport var uint8ArrayTag = '[object Uint8Array]';\nexport var uint8ClampedArrayTag = '[object Uint8ClampedArray]';\nexport var uint16ArrayTag = '[object Uint16Array]';\nexport var uint32ArrayTag = '[object Uint32Array]';\nexport var bigUint64ArrayTag = '[object BigUint64Array]';\nexport var int8ArrayTag = '[object Int8Array]';\nexport var int16ArrayTag = '[object Int16Array]';\nexport var int32ArrayTag = '[object Int32Array]';\nexport var bigInt64ArrayTag = '[object BigInt64Array]';\nexport var float32ArrayTag = '[object Float32Array]';\nexport var float64ArrayTag = '[object Float64Array]';\n\n/**\n * Get object tag of value\n * @group Object\n */\nexport const getTag = function <T>(value: T): string {\n  if (value == null) {\n    return value === undefined ? undefinedTag : nullTag;\n  }\n  return Object.prototype.toString.call(value);\n};\n","import { getTag } from './object/getTag';\nimport type { Primitive } from './types';\n\n/**\n * Determines if the window object is available in the global scope\n *\n * @group Predicates\n */\nexport const isClient = typeof (globalThis as any)?.window !== 'undefined';\n\n/**\n * Returns `true` when value is not `undefined`\n * @group Predicates\n */\nexport const isDef = <T = any>(val?: T): val is T => typeof val !== 'undefined';\n\n/**\n * Checks if the given value is a `null` or `undefined`\n * @group Predicates\n */\nexport function isNullOrUndefined(value: unknown): value is undefined | null {\n  return value === null || value === undefined;\n}\n\n/**\n * Checks if the given value is a `bigint`\n * @group Predicates\n */\nexport const isBigInt = (val: any): val is bigint => typeof val === 'bigint';\n\n/**\n * Checks if the given value is a `boolean`\n * @group Predicates\n */\nexport const isBoolean = (val: any): val is boolean => typeof val === 'boolean';\n\n/**\n * Checks if the given value is a `function`\n * @group Predicates\n */\nexport const isFunction = <T extends Function>(val: any): val is T =>\n  typeof val === 'function';\n\n/**\n * Checks if the given value is a `number`\n *\n * @example\n * console.log(isNumber(123)); // true\n * console.log(isNumber('abc')); // false\n * console.log(isNumber(NaN)); // false\n *\n * @group Predicates\n */\nexport const isNumber = (val: any): val is number =>\n  typeof val === 'number' && !isNaN(val);\n\n/**\n * Checks if the given value is a `Infinity` number.\n *\n * @example\n * console.log(isInfinity(123)); // false\n * console.log(isNumber(Infinity)); // true\n * console.log(isNumber(-Infinity)); // true\n *\n * @group Predicates\n */\nexport const isInfinity = (val: any): val is number =>\n  val === Infinity || val === -Infinity;\n\n/**\n * Checks if the given value is a `string`\n * @group Predicates\n */\nexport const isString = (val: unknown): val is string =>\n  typeof val === 'string';\n\n/**\n * Checks if the given value is a `object`\n * @group Predicates\n */\nexport const isObject = (val: any): val is object =>\n  getTag(val) === '[object Object]';\n\n/**\n * Checks if the given value is a plain `object`\n * @group Predicates\n */\nexport const isPlainObject = (val: any): val is object => {\n  let ctor, prot;\n\n  if (!isObject(val)) return false;\n\n  // If it has modified constructor\n  ctor = val.constructor;\n  if (ctor === undefined) return true;\n\n  // If it has modified prototype\n  prot = ctor.prototype;\n  if (isObject(prot) === false) return false;\n\n  // If constructor does not have an Object-specific method\n  if (prot.hasOwnProperty('isPrototypeOf') === false) {\n    return false;\n  }\n\n  // Most likely a plain Object\n  return true;\n};\n\n/**\n * Checks if the given value is valid `Date`\n * @group Predicates\n */\nexport const isDate = (val: any): val is Date =>\n  val instanceof Date && !isNaN(val as any);\n\n/**\n * Function that does nothing\n * @group Utility Functions\n */\nexport const noop = () => {};\n\n/**\n * Checks if the given value is a `Error`\n * @group Predicates\n */\nexport const isError = (val: any): val is Error =>\n  val instanceof Error ||\n  //@ts-expect-error\n  (isObject(val) && isString(val.message) && isString(val.stack));\n\n/**\n * Checks if the given value is a `symbol`\n * @group Predicates\n */\nexport const isSymbol = (val: any): val is Symbol => typeof val == 'symbol';\n\n/**\n * Checks if the given value is a `Set`.\n * @group Predicates\n */\nexport const isSet = <T = any>(val: any): val is Set<T> => val instanceof Set;\n\n/**\n * Checks if the given value is a `RegExp`.\n * @group Predicates\n */\nexport const isRegExp = (val: any): val is RegExp => val instanceof RegExp;\n\n/**\n * Checks if the given value is a `WeekSet`.\n * @group Predicates\n */\nexport const isWeakSet = <T extends WeakKey = any>(\n  val: any,\n): val is WeakSet<T> => val instanceof WeakSet;\n\n/**\n * Checks if the given value is a `Map`.\n * @group Predicates\n */\nexport const isMap = <K = any, V = any>(val: any): val is Map<K, V> =>\n  val instanceof Map;\n\n/**\n * Checks if the given value is a `WeakMap`.\n * @group Predicates\n */\nexport const isWeakMap = <V = any>(val: any): val is WeakMap<WeakKey, V> =>\n  val instanceof WeakMap;\n\n/**\n * Checks if two values are equal, including support for `Date`, `RegExp`, and deep object comparison.\n *\n * @param {unknown} a - The first value to compare.\n * @param {unknown} b - The second value to compare.\n * @returns {boolean} `true` if the values are equal, otherwise `false`.\n *\n * @example\n * isEqual(1, 1); // true\n * isEqual({ a: 1 }, { a: 1 }); // true\n * isEqual(/abc/g, /abc/g); // true\n * isEqual(new Date('2020-01-01'), new Date('2020-01-01')); // true\n * isEqual([1, 2, 3], [1, 2, 3]); // true\n *\n * @group Predicates\n */\nexport function isEqual(a: unknown, b: unknown): boolean {\n  if (Object.is(a, b)) {\n    return true;\n  }\n\n  if (\n    typeof a !== 'object' ||\n    typeof b !== 'object' ||\n    a === null ||\n    b === null\n  ) {\n    return false;\n  }\n\n  if (a.constructor !== b.constructor) {\n    return false;\n  }\n\n  if (Array.isArray(a)) {\n    const { length } = a;\n    if (length !== (b as any[]).length) {\n      return false;\n    }\n\n    for (let i = length; i-- !== 0; ) {\n      if (!isEqual(a[i], (b as any[])[i])) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\n  if (a instanceof Date) {\n    return a.getTime() === (b as Date).getTime();\n  }\n\n  if (a instanceof RegExp) {\n    return a.source === (b as RegExp).source && a.flags === (b as RegExp).flags;\n  }\n\n  if (a instanceof Set) {\n    if (a.size !== (b as Set<any>).size) {\n      return false;\n    }\n\n    for (const value of a) {\n      if (!(b as Set<any>).has(value)) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\n  if (a instanceof Map) {\n    if (a.size !== (b as Map<any, any>).size) {\n      return false;\n    }\n\n    for (const entry of a) {\n      if (\n        !(b as Map<any, any>).has(entry[0]) ||\n        !isEqual(entry[1], (b as Map<any, any>).get(entry[0]))\n      ) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\n  if (a instanceof DataView) {\n    const { byteLength } = a;\n\n    if (byteLength !== (b as DataView).byteLength) {\n      return false;\n    }\n\n    for (let i = byteLength; i-- !== 0; ) {\n      if (a.getUint8(i) !== (b as DataView).getUint8(i)) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\n  if (a instanceof ArrayBuffer && b instanceof ArrayBuffer) {\n    a = new Uint8Array(a);\n    b = new Uint8Array(b);\n  }\n\n  if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) {\n    const { length } = a as Uint8Array;\n    if (length !== (b as Uint8Array).length) {\n      return false;\n    }\n\n    for (let i = length; i-- !== 0; ) {\n      if ((a as Uint8Array)[i] !== (b as Uint8Array)[i]) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\n  const aKeys = Object.keys(a as object);\n  const bKeys = Object.keys(b as object);\n\n  if (aKeys.length !== bKeys.length) {\n    return false;\n  }\n\n  let key: any;\n\n  for (let i = aKeys.length; i-- !== 0; ) {\n    key = aKeys[i];\n    if (\n      !Object.hasOwn(b as any, key) ||\n      !isEqual((a as any)[key], (b as any)[key])\n    ) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\n/**\n * Checks if a given value is empty.\n *\n * Support for `Array`, `Object`, `string` `Map`, `Set`.\n *\n * @example\n * isEmpty(); // true\n * isEmpty(null); // true\n * isEmpty(''); // true\n * isEmpty([]); // true\n * isEmpty({}); // true\n * isEmpty(new Map()); // true\n * isEmpty(new Set()); // true\n * isEmpty('hello'); // false\n * isEmpty([1, 2, 3]); // false\n * isEmpty({ a: 1 }); // false\n * isEmpty(new Map([['key', 'value']])); // false\n * isEmpty(new Set([1, 2, 3])); // false\n *\n * @group Predicates\n */\nexport const isEmpty = (obj: any): boolean => {\n  if (obj === null || obj === undefined) return true;\n\n  switch (obj?.constructor) {\n    case Object: {\n      for (const _ in obj) {\n        return false;\n      }\n\n      return true;\n    }\n\n    case Array: {\n      for (const _ in obj) {\n        return false;\n      }\n\n      return true;\n    }\n\n    case String: {\n      return !obj.length;\n    }\n\n    case Map: {\n      return !obj.size;\n    }\n\n    case Set: {\n      return !obj.size;\n    }\n  }\n\n  return false;\n};\n\n/**\n * Checks if the given value is a `Promise`\n * @group Predicates\n */\nexport function isPromise<T = void>(value: unknown): value is Promise<T> {\n  return (\n    value instanceof Promise ||\n    (!!value &&\n      typeof value === 'object' &&\n      'then' in value &&\n      'catch' in value &&\n      typeof value.then === 'function' &&\n      typeof value.catch === 'function')\n  );\n}\n\nvar primitiveTypeofSet = Object.freeze(\n  new Set(['string', 'number', 'boolean', 'bigint', 'symbol', 'undefined']),\n);\n\n/**\n * Checks whether a value is a JavaScript primitive.\n *\n * JavaScript primitives include null, undefined, strings, numbers, booleans, symbols, and bigints.\n * @group Predicates\n */\nexport const isPrimitive = (value: unknown): value is Primitive => {\n  return value === null || primitiveTypeofSet.has(typeof value);\n};\n\n/**\n * Checks if a value is a TypedArray.\n * @param x The value to check.\n * @returns Returns true if `x` is a TypedArray, false otherwise.\n *\n * @example\n * const arr = new Uint8Array([1, 2, 3]);\n * isTypedArray(arr); // true\n *\n * const regularArray = [1, 2, 3];\n * isTypedArray(regularArray); // false\n *\n * const buffer = new ArrayBuffer(16);\n * isTypedArray(buffer); // false\n *\n * @group Predicates\n */\nexport function isTypedArray(\n  x: unknown,\n): x is\n  | Uint8Array\n  | Uint8ClampedArray\n  | Uint16Array\n  | Uint32Array\n  | BigUint64Array\n  | Int8Array\n  | Int16Array\n  | Int32Array\n  | BigInt64Array\n  | Float32Array\n  | Float64Array {\n  return ArrayBuffer.isView(x) && !(x instanceof DataView);\n}\n\n/**\n * Checks if the given value is a Buffer instance.\n *\n * This function tests whether the provided value is an instance of Buffer.\n * It returns `true` if the value is a Buffer, and `false` otherwise.\n *\n * This function can also serve as a type predicate in TypeScript, narrowing the type of the argument to `Buffer`.\n *\n * @param x - The value to check if it is a Buffer.\n * @returns Returns `true` if `x` is a Buffer, else `false`.\n *\n * @example\n * const buffer = Buffer.from(\"test\");\n * console.log(isBuffer(buffer)); // true\n *\n * const notBuffer = \"not a buffer\";\n * console.log(isBuffer(notBuffer)); // false\n *\n * @group Predicates\n */\nexport const isBuffer = (value: unknown): value is globalThis.Buffer => {\n  // eslint-disable-next-line\n  // @ts-ignore\n  return (\n    typeof globalThis.Buffer !== 'undefined' &&\n    globalThis.Buffer.isBuffer(value)\n  );\n};\n\n/**\n * Checks if the current environment is Node.js.\n *\n * This function checks for the existence of the `process.versions.node` property,\n * which only exists in Node.js environments.\n *\n * @returns {boolean} `true` if the current environment is Node.js, otherwise `false`.\n *\n * @example\n * if (isNode()) {\n *   console.log('This is running in Node.js');\n *   const fs = import('node:fs');\n * }\n *\n * @group Predicates\n */\nexport function isNode(): boolean {\n  return (\n    typeof globalThis?.process !== 'undefined' &&\n    process?.versions?.node != null\n  );\n}\n","import { isString } from '@/is';\n\ntype ItemType<T> =\n  T extends Array<infer X>\n    ? X\n    : T extends string\n      ? string\n      : Exclude<T, null | undefined>;\n\ntype ArrayableValue<T> = T extends object ? Readonly<T> : T;\n\n/**\n * Converts a value into an array. This function handles different types of input,\n * converting them to arrays as follows:\n * - If the value is already an array, it returns it as-is.\n * - If the value is a string, it splits the string by commas and trims the elements.\n * - If the value is null or undefined, it returns an empty array.\n * - Otherwise, it wraps the value in an array.\n *\n * @example\n * arrayable(42); // [42]\n * arrayable('a, b, c'); // ['a', 'b', 'c']\n * arrayable([1, 2, 3]); // [1, 2, 3]\n * arrayable(null); // []\n * arrayable(undefined); // []\n *\n * @param value The value to convert into an array. It can be of any type.\n * @returns An array derived from the input value.\n *\n * @group Array\n */\nexport function arrayable<T>(value: ArrayableValue<T>): ItemType<T>[] {\n  const result: any = Array.isArray(value)\n    ? value\n    : value === null\n      ? []\n      : value === undefined\n        ? []\n        : isString(value)\n          ? value\n              .split(',')\n              .map(v => v.trim())\n              .filter(Boolean)\n          : [value];\n\n  return result;\n}\n","import { isNumber } from '@/is';\n\n/**\n * Calculates the average value from an array of numbers.\n *\n * The function sums up all valid numbers in the array and divides by the count of those valid numbers.\n * If the array is empty or contains no valid numbers, it returns `0`.\n *\n * @example\n * avg([5, 5, 5]); // 5\n * avg([10, 20, 30]); // 20\n * avg([1, 2, 'three', 4]); // 2.33 (ignores non-numeric values)\n * avg([]); // 0\n *\n * @param values An array of numbers (could include invalid values, which will be ignored).\n * @returns The average value of the valid numbers in the array, or `0` if no valid numbers exist.\n *\n * @group Array\n */\nexport const avg = (values: readonly number[]) => {\n  let sum = 0;\n  let amount = 0;\n\n  for (const item of values) {\n    if (!isNumber(item)) continue;\n    sum += item;\n    amount++;\n  }\n\n  if (amount === 0) return 0;\n\n  return sum / amount;\n};\n","/**\n * Computes the average of circular values using vector summation.\n *\n * This function calculates the circular mean of an array of values,\n * which is useful for cyclic data (e.g., time of day, angles).\n *\n * @param {readonly number[]} values - The array of numbers representing circular values.\n * @param {number} max - The maximum possible value in the cycle (e.g., 24 for hours, 360 for degrees).\n * @returns {number} - The computed circular mean, wrapped within the range [0, max).\n *\n * @example\n * // Averaging angles in degrees\n * avgCircular([350, 10, 20], 360); // Returns approximately 0\n *\n * @example\n * // Averaging times in hours (on a 24-hour clock)\n * avgCircular([23, 1, 2], 24); // Returns approximately 0\n *\n * @group Array\n */\nexport const avgCircular = (values: readonly number[], max: number) => {\n  const len = values.length;\n\n  if (!len) return 0;\n\n  let sumX = 0;\n  let sumY = 0;\n  let angle: number;\n  let value: number;\n\n  for (value of values) {\n    angle = (value / max) * 2 * Math.PI;\n    sumX += Math.cos(angle);\n    sumY += Math.sin(angle);\n  }\n\n  angle = Math.atan2(sumY / len, sumX / len);\n\n  return ((angle / (2 * Math.PI)) * max + max) % max;\n};\n","/**\n * Splits an array into smaller sub-arrays (chunks) of a specified size.\n *\n * If the array can't be evenly divided, the last chunk will contain the remaining elements.\n *\n * @example\n * const data = [1, 2, 3, 4, 5, 6, 7, 8, 9];\n * const chunkSize = 3;\n * const result = chunk(data, chunkSize);\n * console.log(result);\n * // [\n * //    [1, 2, 3],\n * //    [4, 5, 6],\n * //    [7, 8, 9]\n * // ]\n *\n * @example\n * const data = [1, 2, 3, 4, 5];\n * const chunkSize = 2;\n * const result = chunk(data, chunkSize);\n * console.log(result);\n * // [\n * //    [1, 2],\n * //    [3, 4],\n * //    [5]\n * // ]\n *\n * @param list The array to be split into chunks.\n * @param size The size of each chunk. Defaults to `1` if not specified.\n * @returns An array of arrays (chunks), each containing up to `size` elements from the original array.\n *\n * @group Array\n */\nexport function chunk<T>(list: readonly T[], size: number = 1): T[][] {\n  return list.reduce((res, item, index) => {\n    if (index % size === 0) {\n      res.push([]);\n    }\n    res[res.length - 1].push(item);\n    return res;\n  }, [] as T[][]);\n}\n","/**\n * Collapses a continuous series into a tuple of two elements.\n *\n * Where the first element is the beginning of the series.\n * Where the second element is the end of the series.\n *\n * ⚠️ Tuple may consist only one element if the series not started, like: [1, 3] => [[1], [3]]\n *\n * @example\n * const numbers = [1, 2, 3, 8, 9, 10, 15];\n *\n * chunkSeries(numbers); // [[1, 3], [8, 10], [15]]\n *\n * @group Array\n */\nexport function chunkSeries(list: readonly number[], step = 1): number[][] {\n  const result: number[][] = [];\n\n  if (!list.length) {\n    return result;\n  }\n\n  const sortedList = [...list].sort();\n\n  let currentRange = [list[0]];\n  let currentValue: number;\n\n  for (let idx = 1; idx < sortedList.length; idx++) {\n    currentValue = sortedList[idx];\n\n    if (currentValue - currentRange.at(-1)! > step) {\n      result.push(currentRange);\n      currentRange = [currentValue];\n    } else {\n      currentRange[1] = currentValue;\n    }\n  }\n\n  result.push(currentRange);\n\n  return result;\n}\n","/**\n * Computes the difference between arrays.\n *\n * This function takes arrays and returns a new array containing the elements\n * that are not present in any other arrays.\n *\n * @template T\n * @param arrays - The arrays from which to derive the difference.\n * @returns {T[]} A new array containing the elements that are not present in other arrays.\n *\n * @example\n * const array1 = [1, 2, 3, 4, 5];\n * const array2 = [2, 4];\n * const array3 = [1, 5];\n * const result = difference(array1, array2, array3);\n * // result will be [3] since 1, 2, 4 and 5 are in other arrays and are excluded from the result.\n *\n * @group Array\n */\nexport function difference<T>(...arrays: (readonly T[])[]): T[] {\n  if (arrays.length === 0) return [];\n  if (arrays.length === 1) return [...arrays[0]];\n\n  const [first, ...rest] = arrays;\n  const blacklist = new Set();\n  const set = new Set(first);\n\n  for (const items of rest) {\n    for (const item of items) {\n      if (blacklist.has(item)) continue;\n      if (set.has(item)) {\n        set.delete(item);\n        blacklist.add(item);\n        continue;\n      }\n\n      set.add(item);\n    }\n  }\n\n  return Array.from(set);\n}\n","import type { SpecialValue } from './types';\n\nexport var SPECIAL_VALUE = Symbol('toolkit.special.value') as SpecialValue;\nexport var SPECIAL_VALUE_2 = Symbol('toolkit.special.value_2') as SpecialValue;\nexport var SPECIAL_VALUE_3 = Symbol('toolkit.special.value_3') as SpecialValue;\nexport var SPECIAL_VALUE_4 = Symbol('toolkit.special.value_4') as SpecialValue;\n","import { SPECIAL_VALUE } from '@/specialValue';\nimport type { SpecialValue } from '@/types';\n\n/**\n * Filters and maps an array in a single pass.\n *\n * The callback receives a `skip` sentinel as its second argument. Return any\n * mapped value to keep it, or return `skip` to exclude the current element from\n * the result. This avoids the extra allocation of chaining `.filter().map()`.\n *\n * @param array - The source array to iterate over. It is not mutated.\n * @param callbackfn - Called for each element with `(value, skip, index, array)`.\n *   Return the mapped value to keep, or `skip` to drop the element.\n * @returns A new array of the mapped values, excluding any skipped elements.\n *\n * @example\n * ```ts\n * // Keep even numbers and double them, dropping the rest.\n * filterMap([1, 2, 3, 4], (value, skip) =>\n *   value % 2 === 0 ? value * 2 : skip,\n * );\n * // => [4, 8]\n * ```\n *\n * @example\n * ```ts\n * // Parse valid numbers, skipping entries that fail to parse.\n * filterMap(['1', 'x', '3'], (value, skip) => {\n *   const n = Number(value);\n *   return Number.isNaN(n) ? skip : n;\n * });\n * // => [1, 3]\n * ```\n *\n * @group Array\n */\nexport function filterMap<T, U>(\n  array: T[],\n  callbackfn: (\n    value: T,\n    skip: SpecialValue,\n    index: number,\n    array: T[],\n  ) => U | SpecialValue,\n): U[] {\n  var mapped: U[] = [];\n  var mappedValue: U | SpecialValue;\n\n  for (var index = 0; index < array.length; index++) {\n    mappedValue = callbackfn(array[index], SPECIAL_VALUE, index, array);\n\n    if (mappedValue !== SPECIAL_VALUE) {\n      mapped.push(mappedValue as U);\n    }\n  }\n\n  return mapped;\n}\n","import { isFunction } from '@/is';\nimport type { IsPropertyKey, ToPropertyKey } from '../keyBy/types';\n\nexport function groupBy<T, K extends keyof T>(\n  array: readonly T[],\n  keyBy: K,\n  objectMode?: false,\n): Map<IsPropertyKey<T, K, unknown>, T[]>;\n\nexport function groupBy<T, K extends PropertyKey>(\n  array: readonly T[],\n  keyBy: K,\n  objectMode?: false,\n): Map<IsPropertyKey<T, K, unknown>, T[]>;\n\nexport function groupBy<T, K>(\n  array: readonly T[],\n  keyBy: (item: T) => K,\n  objectMode?: false,\n): Map<K, T[]>;\n\nexport function groupBy<T, K extends keyof T>(\n  array: readonly T[],\n  keyBy: K,\n  objectMode: true,\n): Record<ToPropertyKey<T[K]>, T[]>;\n\nexport function groupBy<T, K extends PropertyKey>(\n  array: readonly T[],\n  keyBy: K,\n  objectMode?: true,\n): Record<ToPropertyKey<IsPropertyKey<T, K, unknown>>, T[]>;\n\nexport function groupBy<T, K>(\n  array: readonly T[],\n  keyBy: (item: T) => K,\n  objectMode: true,\n): Record<ToPropertyKey<K>, T[]>;\n\n/**\n * @group Array\n * @example\n * const arr = [\n *   { id: 1, name: 'a' },\n *   { id: 2, name: 'a' },\n *   { id: 3, name: 'b' },\n * ];\n * const grouped = groupBy(arr, 'name', true);\n *\n * console.log(grouped.a);\n * // [{ id: 1, name: 'a' }, { id: 2, name: 'a' }]\n */\nexport function groupBy(\n  array: readonly any[],\n  keyBy: unknown | ((item: any) => unknown),\n  objectMode?: boolean,\n): any {\n  const getItemKey = isFunction(keyBy)\n    ? keyBy\n    : (item: any) => item?.[keyBy as any];\n\n  let key;\n\n  if (objectMode === true) {\n    const result: Record<any, any> = {};\n\n    for (const item of array) {\n      key = getItemKey(item);\n      result[key] = result[key] || [];\n      result[key].push(item);\n    }\n\n    return result as any;\n  }\n\n  const result = new Map();\n\n  for (const item of array) {\n    key = getItemKey(item);\n\n    if (!result.has(key)) {\n      result.set(key, [item]);\n    } else {\n      result.get(key).push(item);\n    }\n  }\n\n  return result;\n}\n","/**\n * Returns the intersection of arrays.\n *\n * This function takes arrays and returns a new array containing the elements that are\n * present in all arrays.\n *\n * @template T - The type of elements in the array.\n * @returns {T[]} A new array containing the elements that are present in both arrays.\n *\n * @example\n * const array1 = [1, 2, 3, 4, 5];\n * const array2 = [3, 4, 5, 6, 7];\n * const result = intersection(array1, array2);\n * // result will be [3, 4, 5] since these elements are in both arrays.\n *\n * @group Array\n */\nexport function intersection<T>(...arrays: (readonly T[])[]): T[] {\n  if (arrays.length === 0) return [];\n  if (arrays.length === 1) return [...arrays[0]];\n\n  return arrays.reduce((acc, curr) => {\n    const set = new Set(curr);\n    return acc.filter(item => set.has(item));\n  }) as T[];\n}\n","import { isFunction } from '@/is';\n\nexport function intersectionBy<T>(\n  keyBy: keyof T,\n  ...arrays: (readonly T[])[]\n): T[];\n\nexport function intersectionBy<T>(\n  keyBy: PropertyKey,\n  ...arrays: (readonly T[])[]\n): T[];\n\nexport function intersectionBy<T>(\n  keyBy: (item: T) => unknown,\n  ...arrays: (readonly T[])[]\n): T[];\n\n/**\n * Returns the intersection of multiple arrays based on a specified key or iteratee function.\n *\n * This function compares elements across arrays using either a property key or a custom\n * function to extract comparison values. Only elements that appear in all arrays\n * (based on their key values) are included in the result.\n *\n * @returns {T[]} A new array containing elements in all arrays. (Deduplicated)\n *\n * @example\n * // Using a property key\n * const users1 = [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }];\n * const users2 = [{ id: 2, name: 'Bob' }, { id: 3, name: 'Charlie' }];\n * const result = intersectionBy('id', users1, users2);\n * // result will be [{ id: 2, name: 'Bob' }]\n *\n * @example\n * // Using an iteratee function\n * const array1 = [1.2, 2.3, 3.4];\n * const array2 = [3.5, 2.6, 1.8];\n * const result = intersectionBy(Math.floor, array1, array2);\n * // result will be [1.2, 2.3, 3.4] since floor values match\n *\n * @example\n * // With nested properties\n * const products1 = [{ info: { code: 'A1' } }, { info: { code: 'B2' } }];\n * const products2 = [{ info: { code: 'B2' } }, { info: { code: 'C3' } }];\n * const result = intersectionBy(item => item.info.code, products1, products2);\n * // result will be [{ info: { code: 'B2' } }]\n *\n * @group Array\n */\nexport function intersectionBy(\n  keyBy: unknown | ((item: any) => unknown),\n  ...arrays: any[]\n): any[] {\n  var arraysLength = arrays.length;\n\n  if (arraysLength === 0) return [];\n  if (arraysLength === 1) return [...arrays[0]];\n\n  var getItemKey = isFunction(keyBy)\n    ? keyBy\n    : (item: any) => item?.[keyBy as any];\n\n  arrays = arrays.toSorted((a, b) => a.length - b.length);\n\n  var arrayLengths: number[] = [arraysLength];\n  var arrayIndices: number[] = [0];\n  var arraySets: Set<any>[] = [new Set()];\n  var key1, key2;\n  var i: number;\n\n  for (i = 1; i < arraysLength; i++) {\n    arrayLengths[i] = arrays[i].length;\n    arrayIndices[i] = 0;\n    arraySets[i] = new Set();\n  }\n\n  return arrays[0].filter((item: any) => {\n    key1 = getItemKey(item);\n\n    if (arraySets[0].has(key1)) return false;\n\n    arraySets[0].add(key1);\n\n    loop: for (i = 1; i < arraysLength; i++) {\n      if (arraySets[i].has(key1)) {\n        continue loop;\n      }\n\n      for (; arrayIndices[i] < arrayLengths[i]; arrayIndices[i]++) {\n        key2 = getItemKey(arrays[i][arrayIndices[i]]);\n        arraySets[i].add(key2);\n\n        if (Object.is(key1, key2)) {\n          continue loop;\n        }\n      }\n\n      return false;\n    }\n\n    return true;\n  });\n}\n","import { isFunction } from '@/is';\nimport type { IsPropertyKey, ToPropertyKey } from './types';\n\nexport function keyBy<T, K extends keyof T>(\n  array: readonly T[],\n  keyBy: K,\n  objectMode?: false,\n): Map<IsPropertyKey<T, K, unknown>, T>;\n\nexport function keyBy<T, K extends PropertyKey>(\n  array: readonly T[],\n  keyBy: K,\n  objectMode?: false,\n): Map<IsPropertyKey<T, K, unknown>, T[]>;\n\nexport function keyBy<T, K>(\n  array: readonly T[],\n  keyBy: (item: T) => K,\n  objectMode?: false,\n): Map<K, T>;\n\nexport function keyBy<T, K extends keyof T>(\n  array: readonly T[],\n  keyBy: K,\n  objectMode: true,\n): Record<ToPropertyKey<T[K]>, T>;\n\nexport function keyBy<T, K extends PropertyKey>(\n  array: readonly T[],\n  keyBy: K,\n  objectMode?: true,\n): Record<ToPropertyKey<IsPropertyKey<T, K, unknown>>, T>;\n\nexport function keyBy<T, K>(\n  array: readonly T[],\n  keyBy: (item: T) => K,\n  objectMode: true,\n): Record<ToPropertyKey<K>, T>;\n\n/**\n * Maps each element of an array based on a provided key.\n *\n * @example\n * const data = [\n *     { id: 1, name: 'group 1' },\n *     { id: 2, name: 'group 2' },\n *     { id: 1, name: 'group 2' }\n * ];\n *\n * const result = keyBy(data, 'id');\n * console.log(Object.entries(result));\n * // [\n * //    [1, [{ id: 1, name: 'group 1' }, { id: 1, name: 'group 2' }],\n * //    [2, { id: 2, name: 'group 2' }],\n * // ]\n *\n * @group Array\n */\nexport function keyBy(\n  array: readonly any[],\n  keyBy: unknown | ((item: any) => unknown),\n  objectMode?: boolean,\n): any {\n  const getItemKey = isFunction(keyBy)\n    ? keyBy\n    : (item: any) => item?.[keyBy as any];\n\n  if (objectMode === true) {\n    const result: Record<any, any> = {};\n\n    for (const item of array) {\n      result[getItemKey(item)] = item;\n    }\n\n    return result as any;\n  }\n\n  const result = new Map();\n\n  for (const item of array) {\n    result.set(getItemKey(item), item);\n  }\n\n  return result as any;\n}\n","import { isSymbol } from '@/is';\n\nexport function compareAscending(value: any, other: any) {\n  if (value !== other) {\n    const valIsDefined = value !== undefined,\n      valIsNull = value === null,\n      valIsReflexive = value === value,\n      valIsSymbol = isSymbol(value);\n\n    const othIsDefined = other !== undefined,\n      othIsNull = other === null,\n      othIsReflexive = other === other,\n      othIsSymbol = isSymbol(other);\n\n    if (\n      (!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||\n      (valIsSymbol &&\n        othIsDefined &&\n        othIsReflexive &&\n        !othIsNull &&\n        !othIsSymbol) ||\n      (valIsNull && othIsDefined && othIsReflexive) ||\n      (!valIsDefined && othIsReflexive) ||\n      !valIsReflexive\n    ) {\n      return 1;\n    }\n    if (\n      (!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||\n      (othIsSymbol &&\n        valIsDefined &&\n        valIsReflexive &&\n        !valIsNull &&\n        !valIsSymbol) ||\n      (othIsNull && valIsDefined && valIsReflexive) ||\n      (!othIsDefined && valIsReflexive) ||\n      !othIsReflexive\n    ) {\n      return -1;\n    }\n  }\n  return 0;\n}\n","import { isFunction } from '@/is';\nimport { compareAscending } from './compareAscending';\n\n/**\n * Sort array by multiple fields\n *\n * @example\n * // Sample data: an array of objects representing users\n * const users = [\n *   { name: 'Alice', age: 30, score: 85 },\n *   { name: 'Bob', age: 25, score: 90 },\n *   { name: 'Charlie', age: 35, score: 90 },\n *   { name: 'Dave', age: 30, score: 70 },\n * ];\n *\n * // Sort users first by score in descending order, then by age in ascending order\n * const sortedUsers = orderBy(users, ['score', 'age'], ['desc', 'asc']);\n *\n * // Output the sorted array\n * console.log(sortedUsers);\n *\n * @group Array\n */\nexport function orderBy<T>(\n  array: readonly T[],\n  fields: (string | ((item: T) => any))[],\n  orders: ('asc' | 'desc')[],\n): readonly T[] {\n  return [...array].sort((a, b) => {\n    let index = -1,\n      length = fields.length,\n      ordersLength = orders.length;\n\n    while (++index < length) {\n      const field = fields[index];\n      const filedFn = isFunction(field);\n\n      const objCriteria = filedFn ? field(a) : (a as any)?.[field];\n      const othCriteria = filedFn ? field(b) : (b as any)?.[field];\n\n      const result = compareAscending(objCriteria, othCriteria);\n\n      if (result) {\n        if (index >= ordersLength) {\n          return result;\n        }\n        return result * (orders[index] === 'desc' ? -1 : 1);\n      }\n    }\n\n    return 0;\n  });\n}\n","/**\n * Randomizes the order of elements in an array using the Fisher-Yates algorithm.\n *\n * This function takes an array and returns a new array with its elements shuffled in a random order.\n *\n * @template T - The type of elements in the array.\n * @param {T[]} arr - The array to shuffle.\n * @returns {T[]} A new array with its elements shuffled in random order.\n *\n * @example\n * const array = [1, 2, 3, 4, 5];\n * const shuffledArray = shuffle(array);\n * // shuffledArray will be a new array with elements of array in random order, e.g., [3, 1, 4, 5, 2]\n *\n * @group Array\n */\nexport function shuffle<T>(arr: readonly T[]): T[] {\n  const result = arr.slice();\n\n  /**\n   * https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm\n   */\n  for (let i = result.length - 1; i >= 1; i--) {\n    const j = Math.floor(Math.random() * (i + 1));\n    [result[i], result[j]] = [result[j], result[i]];\n  }\n\n  return result;\n}\n","import { isEmpty } from '@/is';\n\n/**\n * Removes properties with empty values from an object.\n *\n * This function iterates over the object's keys and deletes any property whose value\n * is considered \"empty\" (e.g., `null`, `undefined`, `[]`, `{}`, `''`, `false`).\n *\n * ⚠️ **Mutates the original object**: The input object is directly modified, and properties\n * are removed from it.\n *\n * @param {Record<string, any>} obj - The object to clean up, where empty fields will be removed.\n * @returns {Record<string, any>} The cleaned object with empty fields removed.\n *\n * @example\n * const user = { id: 1, name: 'Andrew', roles: [], address: null };\n * cleanEmpty(user);\n *\n * console.log(user); // Outputs: { id: 1, name: 'Andrew' }\n *\n * @example\n * const product = { name: 'Laptop', description: '', price: 1000, tags: [] };\n * cleanEmpty(product);\n *\n * console.log(product); // Outputs: { name: 'Laptop', price: 1000 }\n *\n * @group Object\n */\nexport function cleanEmpty(obj: Record<any, any>): Record<any, any> {\n  let value;\n  for (const key of Object.keys(obj)) {\n    value = obj[key];\n\n    if (isEmpty(value)) {\n      delete obj[key];\n    }\n  }\n\n  return obj;\n}\n","/**\n * Removes all properties from the given object, including symbol keys.\n *\n * This function deletes all enumerable properties, both string and symbol keys, from the\n * input object. The object is directly mutated by this operation.\n *\n * ⚠️ **Mutates the original object**: The function modifies the input object in place.\n *\n * ⚠️ **Removes symbol keys**: Symbol-based keys are also deleted, unlike typical object\n * iteration methods.\n *\n * @param {Record<string, any>} input - The object to clean up. After execution, it will be empty.\n * @returns {void} This function does not return a value, as it mutates the input object directly.\n *\n * @example\n * const user = { id: 1, name: 'Andrew', roles: [], [Symbol('unique')]: 'symbolValue' };\n * cleanObject(user);\n *\n * console.log(user); // Outputs: {}\n *\n * @example\n * const settings = { theme: 'dark', [Symbol('private')]: 'secret' };\n * cleanObject(settings);\n *\n * console.log(settings); // Outputs: {}\n *\n * @group Object\n */\nexport const cleanObject = (input: Record<string, any>) => {\n  [...Object.keys(input), ...Object.getOwnPropertySymbols(input)].forEach(\n    (key: any) => {\n      delete input[key];\n    },\n  );\n};\n","import { isObject } from '@/is';\n\n/**\n * Performs a deep merge of the source object into the destination object.\n *\n * This function recursively copies properties from the source object to the destination object.\n * If a property is an object itself, it will recursively merge its properties. Otherwise,\n * the value will be directly assigned to the destination object.\n *\n * ⚠️ **Mutates the destination object**: The destination object is modified in place.\n *\n * @param {object} dest - The target object that will be modified with properties from the source.\n * @param {object} source - The source object whose properties will be copied to the destination.\n * @returns {void} This function does not return a value, as it mutates the destination object.\n *\n * @example\n * const user = {\n *   id: 1,\n *   name: 'Andrew',\n *   data: { a: 1, b: 2 },\n * };\n *\n * deepAssign(user, { data: { c: 3 } });\n *\n * console.log(user);\n * // Outputs: '{ id: 1, name: 'Andrew', data: { a: 1, b: 2, c: 3 } }'\n *\n * @example\n * const config = { theme: { dark: true }, version: '1.0' };\n * const updates = { theme: { light: false }, version: '2.0' };\n *\n * deepAssign(config, updates);\n *\n * console.log(config);\n * // Outputs: '{ theme: { dark: true, light: false }, version: '2.0' }'\n *\n * @group Object\n */\nexport const deepAssign = (dest: object, source: object): void => {\n  for (const key of Object.keys(source)) {\n    const destValue = (dest as any)[key];\n    const sourceValue = (source as any)[key];\n\n    if (isObject(destValue) && isObject(sourceValue)) {\n      deepAssign(destValue as any, sourceValue as any);\n    } else {\n      (dest as any)[key] = sourceValue;\n    }\n  }\n};\n","import { isBuffer, isPrimitive, isTypedArray } from '@/is';\nimport {\n  argumentsTag,\n  arrayBufferTag,\n  arrayTag,\n  booleanTag,\n  dataViewTag,\n  dateTag,\n  float32ArrayTag,\n  float64ArrayTag,\n  getTag,\n  int16ArrayTag,\n  int32ArrayTag,\n  int8ArrayTag,\n  mapTag,\n  numberTag,\n  objectTag,\n  regexpTag,\n  setTag,\n  stringTag,\n  symbolTag,\n  uint16ArrayTag,\n  uint32ArrayTag,\n  uint8ArrayTag,\n  uint8ClampedArrayTag,\n} from '../getTag';\nimport type { WithCustomizer } from './deepCloneWith';\n\nexport function deepCloneWithImpl<T>(\n  valueToClone: any,\n  keyToClone: PropertyKey | undefined,\n  objectToClone: T,\n  stack = new Map<any, any>(),\n  cloneValue: WithCustomizer<T> | undefined = undefined,\n): T {\n  const cloned = cloneValue?.(valueToClone, keyToClone, objectToClone, stack);\n\n  if (cloned !== undefined) {\n    return cloned;\n  }\n\n  if (isPrimitive(valueToClone)) {\n    return valueToClone as T;\n  }\n\n  if (stack.has(valueToClone)) {\n    return stack.get(valueToClone) as T;\n  }\n\n  if (Array.isArray(valueToClone)) {\n    const result: any = new Array(valueToClone.length);\n    stack.set(valueToClone, result);\n\n    for (let i = 0; i < valueToClone.length; i++) {\n      result[i] = deepCloneWithImpl(\n        valueToClone[i],\n        i,\n        objectToClone,\n        stack,\n        cloneValue,\n      );\n    }\n\n    // For RegExpArrays\n    if (Object.hasOwn(valueToClone, 'index')) {\n      result.index = (valueToClone as any).index;\n    }\n    if (Object.hasOwn(valueToClone, 'input')) {\n      result.input = (valueToClone as any).input;\n    }\n\n    return result as T;\n  }\n\n  if (valueToClone instanceof Date) {\n    return new Date(valueToClone.getTime()) as T;\n  }\n\n  if (valueToClone instanceof RegExp) {\n    const result = new RegExp(valueToClone.source, valueToClone.flags);\n\n    result.lastIndex = valueToClone.lastIndex;\n\n    return result as T;\n  }\n\n  if (valueToClone instanceof Map) {\n    const result = new Map();\n    stack.set(valueToClone, result);\n\n    for (const [key, value] of valueToClone) {\n      result.set(\n        key,\n        deepCloneWithImpl(value, key, objectToClone, stack, cloneValue),\n      );\n    }\n\n    return result as T;\n  }\n\n  if (valueToClone instanceof Set) {\n    const result = new Set();\n    stack.set(valueToClone, result);\n\n    for (const value of valueToClone) {\n      result.add(\n        deepCloneWithImpl(value, undefined, objectToClone, stack, cloneValue),\n      );\n    }\n\n    return result as T;\n  }\n\n  if (isBuffer(valueToClone)) {\n    return (valueToClone as any).subarray() as T;\n  }\n\n  if (isTypedArray(valueToClone)) {\n    const result = new (Object.getPrototypeOf(valueToClone).constructor)(\n      valueToClone.length,\n    );\n    stack.set(valueToClone, result);\n\n    for (let i = 0; i < valueToClone.length; i++) {\n      result[i] = deepCloneWithImpl(\n        valueToClone[i],\n        i,\n        objectToClone,\n        stack,\n        cloneValue,\n      );\n    }\n\n    return result as T;\n  }\n\n  if (\n    valueToClone instanceof ArrayBuffer ||\n    (typeof SharedArrayBuffer !== 'undefined' &&\n      valueToClone instanceof SharedArrayBuffer)\n  ) {\n    return valueToClone.slice(0) as T;\n  }\n\n  if (valueToClone instanceof DataView) {\n    const result = new DataView(\n      valueToClone.buffer.slice(0),\n      valueToClone.byteOffset,\n      valueToClone.byteLength,\n    );\n    stack.set(valueToClone, result);\n\n    copyProperties(result, valueToClone, objectToClone, stack, cloneValue);\n\n    return result as T;\n  }\n\n  // For legacy NodeJS support\n  if (typeof File !== 'undefined' && valueToClone instanceof File) {\n    const result = new File([valueToClone], valueToClone.name, {\n      type: valueToClone.type,\n    });\n    stack.set(valueToClone, result);\n\n    copyProperties(result, valueToClone, objectToClone, stack, cloneValue);\n\n    return result as T;\n  }\n\n  // For environments that don't support Blob, like mini-programs\n  if (typeof Blob !== 'undefined' && valueToClone instanceof Blob) {\n    const result = new Blob([valueToClone], { type: valueToClone.type });\n    stack.set(valueToClone, result);\n\n    copyProperties(result, valueToClone, objectToClone, stack, cloneValue);\n\n    return result as T;\n  }\n\n  if (valueToClone instanceof Error) {\n    const result = structuredClone(valueToClone) as Error;\n    stack.set(valueToClone, result);\n\n    result.message = valueToClone.message;\n    result.name = valueToClone.name;\n    result.stack = valueToClone.stack;\n    result.cause = valueToClone.cause;\n    result.constructor = valueToClone.constructor;\n\n    copyProperties(result, valueToClone, objectToClone, stack, cloneValue);\n\n    return result as T;\n  }\n\n  if (valueToClone instanceof Boolean) {\n    const result = new Boolean(valueToClone.valueOf()) as T;\n    stack.set(valueToClone, result);\n    copyProperties(result, valueToClone, objectToClone, stack, cloneValue);\n    return result;\n  }\n\n  if (valueToClone instanceof Number) {\n    const result = new Number(valueToClone.valueOf()) as T;\n    stack.set(valueToClone, result);\n    copyProperties(result, valueToClone, objectToClone, stack, cloneValue);\n    return result;\n  }\n\n  if (valueToClone instanceof String) {\n    const result = new String(valueToClone.valueOf()) as T;\n    stack.set(valueToClone, result);\n    copyProperties(result, valueToClone, objectToClone, stack, cloneValue);\n    return result;\n  }\n\n  if (typeof valueToClone === 'object' && isCloneableObject(valueToClone)) {\n    const result = Object.create(Object.getPrototypeOf(valueToClone));\n\n    stack.set(valueToClone, result);\n\n    copyProperties(result, valueToClone, objectToClone, stack, cloneValue);\n\n    return result as T;\n  }\n\n  return valueToClone;\n}\n\nfunction copyProperties<T>(\n  target: any,\n  source: any,\n  objectToClone: T = target,\n  stack?: Map<any, any> | undefined,\n  cloneValue?: WithCustomizer<T>,\n) {\n  const keys = [...Object.keys(source), ...getSymbols(source)];\n\n  for (let i = 0; i < keys.length; i++) {\n    const key = keys[i];\n    const descriptor = Object.getOwnPropertyDescriptor(target, key);\n\n    if (descriptor == null || descriptor.writable) {\n      target[key] = deepCloneWithImpl(\n        source[key],\n        key,\n        objectToClone,\n        stack,\n        cloneValue,\n      );\n    }\n  }\n}\n\nfunction isCloneableObject(object: object) {\n  switch (getTag(object)) {\n    case argumentsTag:\n    case arrayTag:\n    case arrayBufferTag:\n    case dataViewTag:\n    case booleanTag:\n    case dateTag:\n    case float32ArrayTag:\n    case float64ArrayTag:\n    case int8ArrayTag:\n    case int16ArrayTag:\n    case int32ArrayTag:\n    case mapTag:\n    case numberTag:\n    case objectTag:\n    case regexpTag:\n    case setTag:\n    case stringTag:\n    case symbolTag:\n    case uint8ArrayTag:\n    case uint8ClampedArrayTag:\n    case uint16ArrayTag:\n    case uint32ArrayTag: {\n      return true;\n    }\n    default: {\n      return false;\n    }\n  }\n}\nfunction getSymbols(object: any) {\n  return Object.getOwnPropertySymbols(object).filter(symbol =>\n    Object.prototype.propertyIsEnumerable.call(object, symbol),\n  );\n}\n","import { deepCloneWithImpl } from '../deepCloneWith/deepCloneWithImpl';\n\n/**\n * Recursively clones the provided value, creating a deep copy.\n *\n * This function performs a deep clone of the provided value. Any nested objects, arrays, or other complex types will be cloned recursively,\n * ensuring that the original value and the cloned value are completely independent.\n *\n * @param {T} value - The value to recursively clone. Can be any type (object, array, primitive, etc.).\n * @returns {T} Returns a new deeply cloned instance of the original value.\n *\n * @example\n * const original = { name: 'Alice', details: { age: 25, country: 'Wonderland' } };\n * const cloned = deepClone(original);\n *\n * cloned.details.age = 30;\n * console.log(original.details.age); // 25\n * console.log(cloned.details.age);   // 30\n *\n * @example\n * const arr = [1, [2, 3], 4];\n * const clonedArr = deepClone(arr);\n * clonedArr[1][0] = 99;\n * console.log(arr[1][0]); // 2\n * console.log(clonedArr[1][0]); // 99\n *\n * @group Object\n */\nexport const deepClone = <T>(value: T): T => {\n  return deepCloneWithImpl(value, undefined, value, new Map(), undefined);\n};\n","/**\n * Define not enumerable property in object.\n *\n * @example\n * const USER_SYM = Symbol();\n * const user = { id: 1, name: 'Andrew' };\n *\n * // define hidden marker\n * def(user, USER_SYM, true);\n *\n * console.log(user[USER_SYM] === true); // true\n *\n * @group Object\n */\nexport const def = (\n  obj: object,\n  key: string | symbol,\n  value: any,\n  writable = false,\n) => {\n  Object.defineProperty(obj, key, {\n    configurable: true,\n    enumerable: false,\n    writable,\n    value,\n  });\n};\n","import { arrayable } from '@/array/arrayable';\nimport { def } from '../def';\nimport { deepCloneWithImpl } from './deepCloneWithImpl';\n\nconst WITH_CUSTOMIZER_FACTORY_SYM = Symbol();\n\nexport type WithCustomizer<T = any> = (\n  value: any,\n  key: PropertyKey | undefined,\n  obj: T,\n  stack: Map<any, any>,\n) => any;\n\nexport type WithCustomizerFactory = () => WithCustomizer;\n\nexport type WithCustomizerValue =\n  | (WithCustomizer | WithCustomizerFactory)\n  | Readonly<(WithCustomizer | WithCustomizerFactory)[]>;\n\n/**\n * Recursively clones the provided value with a customizer function that allows for transformation of certain values during the cloning process.\n *\n * This function deep clones the value while providing a way to customize the cloning behavior of certain properties or elements.\n * The `customizer` function will be called for each value being cloned, and if the customizer function returns a value other than `undefined`,\n * the original value will be replaced with the returned value. This allows for specific modifications to parts of the structure being cloned.\n *\n * @param {T} value - The value to recursively clone. Can be any type (object, array, primitive, etc.).\n * @param {WithCustomizerValue} customizer - A function to customize the cloning process. It receives the current value and key, and must return\n *                                            either a modified value or `undefined` (to keep the original value).\n *\n * @returns {T} Returns a new deep clone of the original value, with customizations applied as per the `customizer` function.\n *\n * @example\n * const original = { name: 'Alice', age: 30, details: { country: 'Wonderland', city: 'London' } };\n *\n * const customizer = (value, key) => {\n *   if (key === 'city') return 'Paris';  // Customizing the 'city' field to 'Paris'.\n * };\n *\n * const cloned = deepCloneWith(original, customizer);\n * console.log(cloned.details.city);  // 'Paris'\n * console.log(original.details.city);  // 'London' (original is unchanged)\n *\n * @example\n * const arr = [1, [2, 3], 4];\n *\n * const customizer = (value) => {\n *   if (Array.isArray(value)) return value.map(item => item * 2);  // Doubling the numbers inside arrays.\n * };\n *\n * const clonedArr = deepCloneWith(arr, customizer);\n * console.log(clonedArr); // [1, [4, 6], 4]\n * console.log(arr); // [1, [2, 3], 4] (original is unchanged)\n *\n * @group Object\n */\nexport function deepCloneWith<T>(value: T, customizer: WithCustomizerValue): T {\n  const fns = prepareCustomizes(customizer);\n\n  return deepCloneWithImpl(\n    value,\n    undefined,\n    value,\n    new Map(),\n    (value, key, obj, stack) => {\n      var newValue;\n      var replaced = false;\n\n      for (const fn of fns) {\n        newValue = fn(value, key, obj, stack);\n\n        if (newValue !== undefined) {\n          value = newValue;\n          replaced = true;\n        }\n      }\n\n      if (replaced) return value;\n    },\n  );\n}\n\nexport function createDeepCloneWith(\n  customizer: WithCustomizerValue,\n): <T>(value: T) => T {\n  return value => {\n    return deepCloneWith(value, customizer);\n  };\n}\n\nfunction prepareCustomizes(value: WithCustomizerValue): WithCustomizer[] {\n  return arrayable(value).map(v =>\n    isCustomizerFactory(v) ? v() : v,\n  ) as WithCustomizer[];\n}\n\nexport function isCustomizerFactory(\n  value: unknown,\n): value is WithCustomizerFactory {\n  // @ts-expect-error\n  return value?.[WITH_CUSTOMIZER_FACTORY_SYM] === true;\n}\n\nexport function createCustomizer(fn: WithCustomizer): WithCustomizer {\n  return fn;\n}\n\nexport function createCustomizerFactory(\n  fn: (...args: any[]) => WithCustomizer,\n): WithCustomizerFactory {\n  def(fn, WITH_CUSTOMIZER_FACTORY_SYM, true);\n  return fn as WithCustomizerFactory;\n}\n","import { isError, isPrimitive, isString } from '@/is';\nimport {\n  type WithCustomizerFactory,\n  createCustomizerFactory,\n} from './deepCloneWith';\n\nvar SECURE_LABEL = `<** secure **>`;\nvar CIRCULAR_LABEL = `<** circular **>`;\n\nexport interface SecureCustomizerOptions {\n  /**\n   * @default true\n   */\n  normalizeError?: boolean;\n}\n\n/**\n * Creates a {@link WithCustomizerFactory} that redacts sensitive property values\n * and handles circular references when used with {@link deepCloneWith}.\n *\n * - **Primitive values** whose key matches one of `properties` are replaced with\n *   `<** secure **>` (key comparison is not case-insensitive).\n * - **Circular references** are replaced with `<** circular **>`.\n * - **Error objects** are normalised to a plain `{ message, stack, name, cause }`\n *   shape unless `normalizeError` is set to `false`.\n *\n * @param properties - Property keys to redact (case-insensitive for strings).\n * @param opts - Optional behaviour flags.\n *\n * @example\n * // Basic redaction\n * const customizer = createSecureCustomizer(['password', 'token']);\n * const result = deepCloneWith(\n *   { user: 'alice', password: 'secret', token: 'abc123' },\n *   customizer,\n * );\n * // → { user: 'alice', password: '<** secure **>', token: '<** secure **>' }\n *\n * @example\n * // Nested objects — redaction applies at any depth\n * const customizer = createSecureCustomizer(['apiKey']);\n * const result = deepCloneWith(\n *   { service: { apiKey: 'key-xyz', url: 'https://api.example.com' } },\n *   customizer,\n * );\n * // → { service: { apiKey: '<** secure **>', url: 'https://api.example.com' } }\n *\n * @example\n * // Error normalisation (on by default)\n * const customizer = createSecureCustomizer([]);\n * const result = deepCloneWith({ err: new Error('oops') }, customizer);\n * // → { err: { message: 'oops', name: 'Error', stack: '...', cause: undefined } }\n *\n * @example\n * // Disable Error normalisation\n * const customizer = createSecureCustomizer([], { normalizeError: false });\n * const result = deepCloneWith({ err: new Error('oops') }, customizer);\n * // → { err: Error('oops') }  — the Error instance is preserved\n *\n * @group Object\n */\nexport function createSecureCustomizer(\n  properties: PropertyKey[],\n  opts?: SecureCustomizerOptions,\n): WithCustomizerFactory {\n  var propertiesSet = Object.freeze(\n    new Set<PropertyKey>(\n      properties.map(v => (isString(v) ? v.toLocaleLowerCase() : v)),\n    ),\n  );\n\n  var withCustomizer = (\n    seenSet: WeakSet<any>,\n    value: any,\n    key?: PropertyKey,\n  ): any => {\n    if (isPrimitive(value)) {\n      if (key === undefined) return;\n\n      var normalizedKey: PropertyKey = isString(key)\n        ? key.toLocaleLowerCase()\n        : key;\n\n      if (!propertiesSet.has(normalizedKey)) return;\n\n      return SECURE_LABEL;\n    }\n\n    if (seenSet.has(value)) {\n      return CIRCULAR_LABEL;\n    }\n\n    seenSet.add(value);\n\n    if (isError(value) && opts?.normalizeError !== false) {\n      return {\n        message: value.message,\n        stack: value.stack,\n        name: value.name,\n        cause:\n          value.cause !== undefined\n            ? withCustomizer(seenSet, value.cause)\n            : undefined,\n      };\n    }\n  };\n\n  return createCustomizerFactory(() => {\n    return withCustomizer.bind(null, new WeakSet());\n  });\n}\n","import { isPlainObject } from '@/is';\n\n/**\n * Recursively assigns default properties.\n * @param object The destination object.\n * @param sources The source objects.\n * @return Returns object.\n *\n * @example\n * const obj = { name: 'Alice', age: 30 };\n * const defaults = { name: 'Bob', age: 25, country: 'Wonderland' };\n *\n * deepDefaults(obj, defaults);\n * console.log(obj);\n * // Output: { name: 'Alice', age: 30, country: 'Wonderland' }\n * // The 'name' and 'age' properties are not overwritten since they already exist.\n *\n * @example\n * const obj = { user: { name: 'Alice' } };\n * const defaults = { user: { age: 25 } };\n *\n * deepDefaults(obj, defaults);\n * console.log(obj);\n * // Output: { user: { name: 'Alice', age: 25 } }\n * // The 'age' property is added to 'user', while 'name' remains unchanged.\n *\n * @group Object\n */\nexport const deepDefaults = function <T = any>(\n  target: any,\n  ...sources: any[]\n): T {\n  target = Object(target);\n\n  for (let i = 0; i < sources.length; i++) {\n    const source = sources[i];\n    if (source != null) {\n      defaultsDeepRecursive(target, source, new WeakMap());\n    }\n  }\n\n  return target;\n};\n\nfunction defaultsDeepRecursive(\n  target: any,\n  source: any,\n  stack: WeakMap<any, any>,\n): void {\n  for (const key in source) {\n    const sourceValue = source[key];\n    const targetValue = target[key];\n\n    if (targetValue === undefined || !Object.hasOwn(target, key)) {\n      target[key] = handleMissingProperty(sourceValue, stack);\n      continue;\n    }\n\n    if (stack.get(sourceValue) === targetValue) {\n      // skipping circular reference\n      continue;\n    }\n\n    handleExistingProperty(targetValue, sourceValue, stack);\n  }\n}\n\nfunction handleMissingProperty(\n  sourceValue: any,\n  stack: WeakMap<any, any>,\n): any {\n  if (stack.has(sourceValue)) {\n    return stack.get(sourceValue);\n  }\n\n  if (Array.isArray(sourceValue)) {\n    const newArr: any[] = [];\n    stack.set(sourceValue, newArr);\n    mergeArrays(newArr, sourceValue, stack);\n    return newArr;\n  }\n\n  if (isPlainObject(sourceValue)) {\n    const newObj = {};\n    stack.set(sourceValue, newObj);\n    defaultsDeepRecursive(newObj, sourceValue, stack);\n    return newObj;\n  }\n\n  return sourceValue;\n}\n\nfunction handleExistingProperty(\n  targetValue: any,\n  sourceValue: any,\n  stack: WeakMap<any, any>,\n): void {\n  if (isPlainObject(targetValue) && isPlainObject(sourceValue)) {\n    stack.set(sourceValue, targetValue);\n    defaultsDeepRecursive(targetValue, sourceValue, stack);\n    return;\n  }\n\n  if (Array.isArray(targetValue) && Array.isArray(sourceValue)) {\n    stack.set(sourceValue, targetValue);\n    mergeArrays(targetValue, sourceValue, stack);\n  }\n}\n\nfunction mergeArrays(\n  targetArray: any[],\n  sourceArray: any[],\n  stack: WeakMap<any, any>,\n): void {\n  const minLength = Math.min(sourceArray.length, targetArray.length);\n\n  for (let i = 0; i < minLength; i++) {\n    if (isPlainObject(targetArray[i]) && isPlainObject(sourceArray[i])) {\n      defaultsDeepRecursive(targetArray[i], sourceArray[i], stack);\n    }\n  }\n  for (let i = minLength; i < sourceArray.length; i++) {\n    targetArray.push(handleMissingProperty(sourceArray[i], stack));\n  }\n}\n","/**\n * Recursively freezes an object or array, making it immutable at all levels.\n *\n * This function is similar to `Object.freeze()`, but instead of freezing only the top-level\n * properties of an object, it recursively freezes every nested object or array, ensuring\n * that no properties or elements can be modified at any depth.\n *\n * **Important**:\n * - Once frozen, attempting to modify any property or element of the object will result in an error in strict mode.\n * - If a property of an object or an element of an array is itself an object, it will also be frozen.\n *\n * @param {T} value - The object or array to freeze deeply.\n * @returns {T} The frozen object or array, which is also deeply immutable.\n *\n * @example\n * const config = deepFreeze({\n *   db: { uri: '' },\n * });\n *\n * config.db.uri = 'test'; // Error: Cannot assign to read-only property 'uri' of object\n *\n * @example\n * const arr = deepFreeze([ { name: 'Alice' }, { name: 'Bob' } ]);\n * arr[0].name = 'Charlie'; // Error: Cannot assign to read-only property 'name' of object\n *\n * @group Object\n */\nexport function deepFreeze<T extends object | unknown[]>(value: T): T {\n  let currentValue: any = value;\n\n  if (!currentValue || typeof currentValue !== 'object') return currentValue;\n\n  Object.freeze(currentValue);\n\n  if (Array.isArray(currentValue)) {\n    for (const item of currentValue) {\n      deepFreeze(item);\n    }\n\n    return currentValue as T;\n  } else {\n    for (const value of Object.values(currentValue)) {\n      deepFreeze(value as any);\n    }\n  }\n\n  return currentValue;\n}\n","/**\n * @example\n * const PERMISSIONS = {\n *   USER_CREATE: 1 << 0,\n *   USER_UPDATE: 1 << 1,\n *   USER_DELETE: 1 << 2,\n *   USER_LIST: 1 << 4,\n * } as const;\n *\n * const scope = PERMISSIONS.USER_CREATE | PERMISSIONS.USER_LIST;\n *\n * // { USER_CREATE: true, USER_UPDATE: false, USER_DELETE: false, USER_LIST: true }\n * const flags = flagsToMap(scope, PERMISSIONS);\n */\nexport function flagsToMap(\n  value: number,\n  bitmaskMap: Record<string, number>,\n): Record<string, boolean>;\n\nexport function flagsToMap(\n  value: bigint,\n  bitmaskMap: Record<string, bigint>,\n): Record<string, boolean>;\n\n/**\n * Converts bitmask into mapped object with true/false values\n *\n * @group Object\n */\nexport function flagsToMap(\n  value: number | bigint,\n  bitmaskMap: Record<string, number | bigint>,\n): Record<string, boolean> {\n  const result: Record<string, boolean> = {};\n\n  const compare = typeof value === 'bigint' ? 0n : 0;\n\n  for (const [key, mask] of Object.entries(bitmaskMap)) {\n    result[key] = ((value as number) & (mask as number)) !== compare;\n  }\n\n  return result;\n}\n","import { isObject } from '@/is';\n\ninterface FlattenOptions {\n  /**\n   * Character to separate the flattened keys\n   */\n  separator?: string;\n\n  /**\n   * Prefix to add to the flattened keys\n   */\n  initialPrefix?: string;\n\n  /**\n   * Whether to include arrays in the flattened result\n   */\n  withArrays?: boolean;\n\n  /**\n   * Custom function to check if a value is an object\n   */\n  isObjectCompare?: (value: unknown) => boolean;\n}\n\n/**\n * Flattens a nested object into a single-level object, converting nested properties\n * into key-value pairs with keys representing the property path.\n *\n * By default, nested objects are flattened with an underscore (`_`) separator.\n * Arrays can also be flattened into indexed keys. A custom function can be provided\n * to determine if a value should be treated as an object.\n *\n * **Important**:\n * - Nested objects are flattened with keys joined by the `separator` (default: `_`).\n * - Arrays are flattened by their indices (e.g., `array[0]` becomes `array_0`).\n * - A custom `isObjectCompare` function can be provided to determine whether a value\n *   should be treated as an object.\n *\n * @param {Record<string, unknown>} obj - The object to flatten.\n * @param {FlattenOptions} options - Optional configuration for flattening behavior.\n * @param {string} [options.separator='_'] - Separator for flattening object keys (default is '_').\n * @param {string} [options.initialPrefix=''] - Prefix to prepend to flattened keys (default is '').\n * @param {boolean} [options.withArrays=true] - Whether to include arrays in the flattened result (default is true).\n * @param {(value: unknown) => boolean} [options.isObjectCompare=isObject] - Custom function to check if a value is an object.\n * @returns {Record<string, unknown>} - The flattened object.\n *\n * @example\n * flatten({\n *   name: 'Andrew',\n *   config: {\n *     canReadPost: true,\n *     canUpdatePost: true,\n *   }\n * });\n * // Result:\n * // {\n * //   'name': 'Andrew',\n * //   'config_canReadPost': true,\n * //   'config_canUpdatePost': true,\n * // }\n *\n *  @example\n * flatten(\n *   { user: { name: 'Jane', profile: { age: 30 } } },\n *   { separator: '-', initialPrefix: 'root-' }\n * );\n * // Returns:\n * // { 'root-user-name': 'Jane', 'root-user-profile-age': 30 }\n *\n * @group Object\n * @author lukeed\n */\nexport function flatten(\n  obj: Record<string, unknown>,\n  {\n    separator = '_',\n    initialPrefix = '',\n    withArrays = true,\n    isObjectCompare = isObject,\n  }: FlattenOptions = {},\n): Record<string, unknown> {\n  const result: Record<string, unknown> = {};\n  const seen = new WeakSet();\n\n  if (isObjectCompare(obj)) {\n    iter(\n      result,\n      seen,\n      isObjectCompare,\n      separator,\n      withArrays,\n      obj,\n      initialPrefix,\n      true,\n    );\n  }\n\n  return result;\n}\n\nfunction iter(\n  output: Record<string, unknown>,\n  seen: WeakSet<any>,\n  isObjectCompare: Exclude<FlattenOptions['isObjectCompare'], undefined>,\n  separator: string,\n  withArrays: boolean,\n  val: any,\n  key: string,\n  initial?: boolean,\n) {\n  if (seen.has(val)) return;\n\n  let k,\n    pfx = key && !initial ? key + separator : key;\n\n  if (Array.isArray(val)) {\n    seen.add(val);\n\n    if (!withArrays) {\n      output[key] = val;\n      return;\n    }\n\n    for (k = 0; k < val.length; k++) {\n      iter(\n        output,\n        seen,\n        isObjectCompare,\n        separator,\n        withArrays,\n        val[k],\n        pfx + k,\n      );\n    }\n  } else if (isObjectCompare(val)) {\n    seen.add(val);\n\n    for (k in val) {\n      iter(\n        output,\n        seen,\n        isObjectCompare,\n        separator,\n        withArrays,\n        val[k],\n        pfx + k,\n      );\n    }\n  } else {\n    output[key] = val;\n  }\n}\n","/**\n * Converts the first character of string to upper case and the remaining to lower case.\n *\n * @template T - Literal type of the string.\n * @param {T} str - The string to be converted to uppercase.\n * @returns {Capitalize<T>} - The capitalized string.\n *\n * @example\n * const result = capitalize('fred') // returns 'Fred'\n * const result2 = capitalize('FRED') // returns 'Fred'\n *\n * @group Strings\n */\n\nexport function capitalize<T extends string>(str: T): Capitalize<T> {\n  return (str.charAt(0).toUpperCase() +\n    str.slice(1).toLowerCase()) as Capitalize<T>;\n}\n\ntype Capitalize<T extends string> = T extends `${infer F}${infer R}`\n  ? `${Uppercase<F>}${Lowercase<R>}`\n  : T;\n","import { isString } from '@/is';\n\n/**\n * Regular expression pattern to split strings into words for various case conversions\n *\n * This pattern matches sequences of characters in a string, considering the following cases:\n * - Sequences of two or more uppercase letters followed by an uppercase letter and lowercase letters or digits (for acronyms)\n * - Sequences of one uppercase letter optionally followed by lowercase letters and digits\n * - Single uppercase letters\n * - Sequences of digits\n * - Emojis and other Unicode characters\n *\n * The resulting match can be used to convert camelCase, snake_case, kebab-case, and other mixed formats into\n * a consistent format like snake case. It also supports emojis and other Unicode characters.\n *\n * @example\n * const matches = 'camelCaseHTTPRequest🚀'.match(CASE_SPLIT_PATTERN);\n * // matches: ['camel', 'Case', 'HTTP', 'Request', '🚀']\n *\n * @group Strings\n */\nconst CASE_SPLIT_PATTERN =\n  /\\p{Lu}?\\p{Ll}+|[0-9]+|\\p{Lu}+(?!\\p{Ll})|\\p{Emoji_Presentation}|\\p{Extended_Pictographic}|\\p{L}+/gu;\n\nexport function getWords(str?: string): string[] {\n  if (!isString(str)) return [];\n  return Array.from(str.match(CASE_SPLIT_PATTERN) ?? []);\n}\n","import { capitalize } from '../capitalize';\nimport { getWords } from '../getWords';\n\n/**\n * Converts a string to camel case.\n *\n * Camel case is the naming convention in which the first word is written in lowercase and\n * each subsequent word begins with a capital letter, concatenated without any separator characters.\n *\n * @param {string} str - The string that is to be changed to camel case.\n * @returns {string} - The converted string to camel case.\n *\n * @example\n * const convertedStr1 = camelCase('camelCase') // returns 'camelCase'\n * const convertedStr2 = camelCase('some whitespace') // returns 'someWhitespace'\n * const convertedStr3 = camelCase('hyphen-text') // returns 'hyphenText'\n * const convertedStr4 = camelCase('HTTPRequest') // returns 'httpRequest'\n * const convertedStr5 = camelCase('Keep unicode 😅') // returns 'keepUnicode😅'\n *\n * @group Strings\n */\nexport function camelCase(str: string): string {\n  const words = getWords(str);\n\n  if (words.length === 0) {\n    return '';\n  }\n\n  const [first, ...rest] = words;\n\n  return `${first.toLowerCase()}${rest.map(word => capitalize(word)).join('')}`;\n}\n","/**\n * Converts a value to a string and appends a specified unit to it.\n * If the value is already a string, it returns it as is, and if the value is a number,\n * it appends the specified unit (defaults to 'px'). If the value is null, undefined, or an empty string, it returns `undefined`.\n *\n * @example\n * // Adding 'px' unit to a number\n * convertToUnit(10, 'px'); // '10px';\n *\n * // Adding 'em' unit to a number\n * convertToUnit(5, 'em'); // '5em';\n *\n * // Returning a string as is if it's not a number\n * convertToUnit('100%', 'px'); // '100%';\n *\n * // Handling null, undefined, and empty string\n * convertToUnit(null); // undefined;\n * convertToUnit(''); // undefined;\n *\n * @param str - The value to convert, can be a number, string, null, or undefined.\n * @param unit - The unit to append to the value. Defaults to 'px'.\n * @returns The value with the unit appended, or `undefined` if the input is null, undefined, or an empty string.\n *\n * @group Strings\n */\nexport function convertToUnit(\n  str: string | number | null | undefined,\n  unit = 'px',\n): string | undefined {\n  if (str == null || str === '') {\n    return undefined;\n  } else if (isNaN(+str!)) {\n    return String(str);\n  } else {\n    return `${Number(str)}${unit}`;\n  }\n}\n","const htmlEscapes: Record<number, string> = Object.freeze({\n  38: '&amp;', // &\n  60: '&lt;', // <\n  62: '&gt;', // >\n  34: '&quot;', // \"\n  39: '&#39;', // '\n});\n\n/**\n * Sanitizes a string by escaping HTML syntax to prevent XSS (Cross-site scripting) attacks.\n * Converts special HTML characters like `<`, `>`, `&`, etc., into their corresponding HTML entities.\n *\n * @example\n * // Escaping HTML tags to prevent HTML injection\n * escapeHtml('<b>Strong</b> man.'); // '&lt;b&gt;Strong&lt;/b&gt; man.'\n *\n * // Escaping other HTML special characters\n * escapeHtml('<script>alert(\"XSS\")</script>'); // '&lt;script&gt;alert(&quot;XSS&quot;)&lt;/script&gt;'\n *\n * @param unsafe - The string to be sanitized (escaped).\n * @returns A sanitized string with HTML special characters replaced by their corresponding HTML entities.\n *\n * @group Strings\n */\nexport function escapeHtml(unsafe: string) {\n  if (typeof unsafe !== 'string') {\n    return '';\n  }\n\n  let result = '';\n  let strLen = unsafe.length;\n  let char: number;\n\n  for (let idx = 0; idx < strLen; idx++) {\n    char = unsafe.charCodeAt(idx);\n    result += htmlEscapes[char] || String.fromCharCode(char);\n  }\n\n  return result;\n}\n","/**\n * Sanitizes a string by removing all non-numeric characters, leaving only digits.\n * Useful for extracting numeric values from strings, such as when you want to\n * extract a number from a string containing units or other non-numeric text.\n *\n * @example\n * // Extracts numeric values from a string with units\n * escapeNumeric('use 320px'); // '320'\n *\n * // Strips out non-numeric characters from a string\n * escapeNumeric('USD 1,000.50'); // '100050'\n *\n * // Returns undefined if no numeric characters are found\n * escapeNumeric('No numbers here!'); // undefined\n *\n * @param str - The input string to be sanitized.\n * @returns A string containing only the numeric characters, or `undefined` if no numbers are found.\n *\n * @group Strings\n */\nexport function escapeNumeric(str: string) {\n  const result = String(str).replace(/\\D/g, '');\n\n  if (!result.length) {\n    return undefined;\n  }\n\n  return result;\n}\n","/**\n * Escapes special characters in a string to safely use it as a literal pattern in a regular expression.\n * This function ensures that any characters that would otherwise have a special meaning in a regex\n * (such as `*`, `+`, `?`, etc.) are properly escaped, allowing them to be used as normal characters\n * in the pattern.\n *\n * @example\n * // Escapes special characters in the string '[a|b]'\n * escapeRegExp('[a|b]'); // '\\\\[a\\\\|b\\\\]'\n *\n * @example\n * // Use the function to safely create a regex from user input\n * const searchTerms = 'Andrew L.';\n * const searchReg = new RegExp(escapeRegExp(searchTerms), 'i');\n * const searchResult = users.find(v => searchReg.test(v.name));\n *\n * @param str - The string to escape for use in a regular expression.\n * @returns The input string with all special regex characters escaped.\n *\n * @group Strings\n */\nexport function escapeRegExp(str: string) {\n  return str.replace(/[\\-\\[\\]\\/\\{\\}\\(\\)\\*\\+\\?\\.\\\\\\^\\$\\|]/g, '\\\\$&');\n}\n","// Copyright Twitter Inc. Licensed under MIT\n// https://github.com/twitter/twemoji-parser/blob/master/LICENSE.md\n// Version f8312f3 12.03.2022\n\nconst vs16RegExp = /\\uFE0F/g;\n// avoid using a string literal like '\\u200D' here because minifiers expand it inline\nconst zeroWidthJoiner = String.fromCharCode(0x200d);\n\nexport function removeVS16s(rawEmoji: string) {\n  return rawEmoji.indexOf(zeroWidthJoiner) < 0\n    ? rawEmoji.replace(vs16RegExp, '')\n    : rawEmoji;\n}\n\n// This file is generated by source/emoji/scripts/generate.sh\n\nexport default /(?:\\ud83d\\udc68\\ud83c\\udffb\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc8b\\u200d\\ud83d\\udc68\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc68\\ud83c\\udffc\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc8b\\u200d\\ud83d\\udc68\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc68\\ud83c\\udffd\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc8b\\u200d\\ud83d\\udc68\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc68\\ud83c\\udffe\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc8b\\u200d\\ud83d\\udc68\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc68\\ud83c\\udfff\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc8b\\u200d\\ud83d\\udc68\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc69\\ud83c\\udffb\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc8b\\u200d\\ud83d\\udc68\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc69\\ud83c\\udffb\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc8b\\u200d\\ud83d\\udc69\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc69\\ud83c\\udffc\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc8b\\u200d\\ud83d\\udc68\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc69\\ud83c\\udffc\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc8b\\u200d\\ud83d\\udc69\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc69\\ud83c\\udffd\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc8b\\u200d\\ud83d\\udc68\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc69\\ud83c\\udffd\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc8b\\u200d\\ud83d\\udc69\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc69\\ud83c\\udffe\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc8b\\u200d\\ud83d\\udc68\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc69\\ud83c\\udffe\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc8b\\u200d\\ud83d\\udc69\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc69\\ud83c\\udfff\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc8b\\u200d\\ud83d\\udc68\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc69\\ud83c\\udfff\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc8b\\u200d\\ud83d\\udc69\\ud83c[\\udffb-\\udfff]|\\ud83e\\uddd1\\ud83c\\udffb\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc8b\\u200d\\ud83e\\uddd1\\ud83c[\\udffc-\\udfff]|\\ud83e\\uddd1\\ud83c\\udffc\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc8b\\u200d\\ud83e\\uddd1\\ud83c[\\udffb\\udffd-\\udfff]|\\ud83e\\uddd1\\ud83c\\udffd\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc8b\\u200d\\ud83e\\uddd1\\ud83c[\\udffb\\udffc\\udffe\\udfff]|\\ud83e\\uddd1\\ud83c\\udffe\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc8b\\u200d\\ud83e\\uddd1\\ud83c[\\udffb-\\udffd\\udfff]|\\ud83e\\uddd1\\ud83c\\udfff\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc8b\\u200d\\ud83e\\uddd1\\ud83c[\\udffb-\\udffe]|\\ud83d\\udc68\\ud83c\\udffb\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc68\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc68\\ud83c\\udffb\\u200d\\ud83e\\udd1d\\u200d\\ud83d\\udc68\\ud83c[\\udffc-\\udfff]|\\ud83d\\udc68\\ud83c\\udffc\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc68\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc68\\ud83c\\udffc\\u200d\\ud83e\\udd1d\\u200d\\ud83d\\udc68\\ud83c[\\udffb\\udffd-\\udfff]|\\ud83d\\udc68\\ud83c\\udffd\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc68\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc68\\ud83c\\udffd\\u200d\\ud83e\\udd1d\\u200d\\ud83d\\udc68\\ud83c[\\udffb\\udffc\\udffe\\udfff]|\\ud83d\\udc68\\ud83c\\udffe\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc68\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc68\\ud83c\\udffe\\u200d\\ud83e\\udd1d\\u200d\\ud83d\\udc68\\ud83c[\\udffb-\\udffd\\udfff]|\\ud83d\\udc68\\ud83c\\udfff\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc68\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc68\\ud83c\\udfff\\u200d\\ud83e\\udd1d\\u200d\\ud83d\\udc68\\ud83c[\\udffb-\\udffe]|\\ud83d\\udc69\\ud83c\\udffb\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc68\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc69\\ud83c\\udffb\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc69\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc69\\ud83c\\udffb\\u200d\\ud83e\\udd1d\\u200d\\ud83d\\udc68\\ud83c[\\udffc-\\udfff]|\\ud83d\\udc69\\ud83c\\udffb\\u200d\\ud83e\\udd1d\\u200d\\ud83d\\udc69\\ud83c[\\udffc-\\udfff]|\\ud83d\\udc69\\ud83c\\udffc\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc68\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc69\\ud83c\\udffc\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc69\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc69\\ud83c\\udffc\\u200d\\ud83e\\udd1d\\u200d\\ud83d\\udc68\\ud83c[\\udffb\\udffd-\\udfff]|\\ud83d\\udc69\\ud83c\\udffc\\u200d\\ud83e\\udd1d\\u200d\\ud83d\\udc69\\ud83c[\\udffb\\udffd-\\udfff]|\\ud83d\\udc69\\ud83c\\udffd\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc68\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc69\\ud83c\\udffd\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc69\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc69\\ud83c\\udffd\\u200d\\ud83e\\udd1d\\u200d\\ud83d\\udc68\\ud83c[\\udffb\\udffc\\udffe\\udfff]|\\ud83d\\udc69\\ud83c\\udffd\\u200d\\ud83e\\udd1d\\u200d\\ud83d\\udc69\\ud83c[\\udffb\\udffc\\udffe\\udfff]|\\ud83d\\udc69\\ud83c\\udffe\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc68\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc69\\ud83c\\udffe\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc69\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc69\\ud83c\\udffe\\u200d\\ud83e\\udd1d\\u200d\\ud83d\\udc68\\ud83c[\\udffb-\\udffd\\udfff]|\\ud83d\\udc69\\ud83c\\udffe\\u200d\\ud83e\\udd1d\\u200d\\ud83d\\udc69\\ud83c[\\udffb-\\udffd\\udfff]|\\ud83d\\udc69\\ud83c\\udfff\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc68\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc69\\ud83c\\udfff\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc69\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc69\\ud83c\\udfff\\u200d\\ud83e\\udd1d\\u200d\\ud83d\\udc68\\ud83c[\\udffb-\\udffe]|\\ud83d\\udc69\\ud83c\\udfff\\u200d\\ud83e\\udd1d\\u200d\\ud83d\\udc69\\ud83c[\\udffb-\\udffe]|\\ud83e\\uddd1\\ud83c\\udffb\\u200d\\u2764\\ufe0f\\u200d\\ud83e\\uddd1\\ud83c[\\udffc-\\udfff]|\\ud83e\\uddd1\\ud83c\\udffb\\u200d\\ud83e\\udd1d\\u200d\\ud83e\\uddd1\\ud83c[\\udffb-\\udfff]|\\ud83e\\uddd1\\ud83c\\udffc\\u200d\\u2764\\ufe0f\\u200d\\ud83e\\uddd1\\ud83c[\\udffb\\udffd-\\udfff]|\\ud83e\\uddd1\\ud83c\\udffc\\u200d\\ud83e\\udd1d\\u200d\\ud83e\\uddd1\\ud83c[\\udffb-\\udfff]|\\ud83e\\uddd1\\ud83c\\udffd\\u200d\\u2764\\ufe0f\\u200d\\ud83e\\uddd1\\ud83c[\\udffb\\udffc\\udffe\\udfff]|\\ud83e\\uddd1\\ud83c\\udffd\\u200d\\ud83e\\udd1d\\u200d\\ud83e\\uddd1\\ud83c[\\udffb-\\udfff]|\\ud83e\\uddd1\\ud83c\\udffe\\u200d\\u2764\\ufe0f\\u200d\\ud83e\\uddd1\\ud83c[\\udffb-\\udffd\\udfff]|\\ud83e\\uddd1\\ud83c\\udffe\\u200d\\ud83e\\udd1d\\u200d\\ud83e\\uddd1\\ud83c[\\udffb-\\udfff]|\\ud83e\\uddd1\\ud83c\\udfff\\u200d\\u2764\\ufe0f\\u200d\\ud83e\\uddd1\\ud83c[\\udffb-\\udffe]|\\ud83e\\uddd1\\ud83c\\udfff\\u200d\\ud83e\\udd1d\\u200d\\ud83e\\uddd1\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc68\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc8b\\u200d\\ud83d\\udc68|\\ud83d\\udc69\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc8b\\u200d\\ud83d[\\udc68\\udc69]|\\ud83e\\udef1\\ud83c\\udffb\\u200d\\ud83e\\udef2\\ud83c[\\udffc-\\udfff]|\\ud83e\\udef1\\ud83c\\udffc\\u200d\\ud83e\\udef2\\ud83c[\\udffb\\udffd-\\udfff]|\\ud83e\\udef1\\ud83c\\udffd\\u200d\\ud83e\\udef2\\ud83c[\\udffb\\udffc\\udffe\\udfff]|\\ud83e\\udef1\\ud83c\\udffe\\u200d\\ud83e\\udef2\\ud83c[\\udffb-\\udffd\\udfff]|\\ud83e\\udef1\\ud83c\\udfff\\u200d\\ud83e\\udef2\\ud83c[\\udffb-\\udffe]|\\ud83d\\udc68\\u200d\\u2764\\ufe0f\\u200d\\ud83d\\udc68|\\ud83d\\udc69\\u200d\\u2764\\ufe0f\\u200d\\ud83d[\\udc68\\udc69]|\\ud83e\\uddd1\\u200d\\ud83e\\udd1d\\u200d\\ud83e\\uddd1|\\ud83d\\udc6b\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc6c\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc6d\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc8f\\ud83c[\\udffb-\\udfff]|\\ud83d\\udc91\\ud83c[\\udffb-\\udfff]|\\ud83e\\udd1d\\ud83c[\\udffb-\\udfff]|\\ud83d[\\udc6b-\\udc6d\\udc8f\\udc91]|\\ud83e\\udd1d)|(?:\\ud83d[\\udc68\\udc69]|\\ud83e\\uddd1)(?:\\ud83c[\\udffb-\\udfff])?\\u200d(?:\\u2695\\ufe0f|\\u2696\\ufe0f|\\u2708\\ufe0f|\\ud83c[\\udf3e\\udf73\\udf7c\\udf84\\udf93\\udfa4\\udfa8\\udfeb\\udfed]|\\ud83d[\\udcbb\\udcbc\\udd27\\udd2c\\ude80\\ude92]|\\ud83e[\\uddaf-\\uddb3\\uddbc\\uddbd])|(?:\\ud83c[\\udfcb\\udfcc]|\\ud83d[\\udd74\\udd75]|\\u26f9)((?:\\ud83c[\\udffb-\\udfff]|\\ufe0f)\\u200d[\\u2640\\u2642]\\ufe0f)|(?:\\ud83c[\\udfc3\\udfc4\\udfca]|\\ud83d[\\udc6e\\udc70\\udc71\\udc73\\udc77\\udc81\\udc82\\udc86\\udc87\\ude45-\\ude47\\ude4b\\ude4d\\ude4e\\udea3\\udeb4-\\udeb6]|\\ud83e[\\udd26\\udd35\\udd37-\\udd39\\udd3d\\udd3e\\uddb8\\uddb9\\uddcd-\\uddcf\\uddd4\\uddd6-\\udddd])(?:\\ud83c[\\udffb-\\udfff])?\\u200d[\\u2640\\u2642]\\ufe0f|(?:\\ud83d\\udc68\\u200d\\ud83d\\udc68\\u200d\\ud83d\\udc66\\u200d\\ud83d\\udc66|\\ud83d\\udc68\\u200d\\ud83d\\udc68\\u200d\\ud83d\\udc67\\u200d\\ud83d[\\udc66\\udc67]|\\ud83d\\udc68\\u200d\\ud83d\\udc69\\u200d\\ud83d\\udc66\\u200d\\ud83d\\udc66|\\ud83d\\udc68\\u200d\\ud83d\\udc69\\u200d\\ud83d\\udc67\\u200d\\ud83d[\\udc66\\udc67]|\\ud83d\\udc69\\u200d\\ud83d\\udc69\\u200d\\ud83d\\udc66\\u200d\\ud83d\\udc66|\\ud83d\\udc69\\u200d\\ud83d\\udc69\\u200d\\ud83d\\udc67\\u200d\\ud83d[\\udc66\\udc67]|\\ud83d\\udc68\\u200d\\ud83d\\udc66\\u200d\\ud83d\\udc66|\\ud83d\\udc68\\u200d\\ud83d\\udc67\\u200d\\ud83d[\\udc66\\udc67]|\\ud83d\\udc68\\u200d\\ud83d\\udc68\\u200d\\ud83d[\\udc66\\udc67]|\\ud83d\\udc68\\u200d\\ud83d\\udc69\\u200d\\ud83d[\\udc66\\udc67]|\\ud83d\\udc69\\u200d\\ud83d\\udc66\\u200d\\ud83d\\udc66|\\ud83d\\udc69\\u200d\\ud83d\\udc67\\u200d\\ud83d[\\udc66\\udc67]|\\ud83d\\udc69\\u200d\\ud83d\\udc69\\u200d\\ud83d[\\udc66\\udc67]|\\ud83c\\udff3\\ufe0f\\u200d\\u26a7\\ufe0f|\\ud83c\\udff3\\ufe0f\\u200d\\ud83c\\udf08|\\ud83d\\ude36\\u200d\\ud83c\\udf2b\\ufe0f|\\u2764\\ufe0f\\u200d\\ud83d\\udd25|\\u2764\\ufe0f\\u200d\\ud83e\\ude79|\\ud83c\\udff4\\u200d\\u2620\\ufe0f|\\ud83d\\udc15\\u200d\\ud83e\\uddba|\\ud83d\\udc3b\\u200d\\u2744\\ufe0f|\\ud83d\\udc41\\u200d\\ud83d\\udde8|\\ud83d\\udc68\\u200d\\ud83d[\\udc66\\udc67]|\\ud83d\\udc69\\u200d\\ud83d[\\udc66\\udc67]|\\ud83d\\udc6f\\u200d\\u2640\\ufe0f|\\ud83d\\udc6f\\u200d\\u2642\\ufe0f|\\ud83d\\ude2e\\u200d\\ud83d\\udca8|\\ud83d\\ude35\\u200d\\ud83d\\udcab|\\ud83e\\udd3c\\u200d\\u2640\\ufe0f|\\ud83e\\udd3c\\u200d\\u2642\\ufe0f|\\ud83e\\uddde\\u200d\\u2640\\ufe0f|\\ud83e\\uddde\\u200d\\u2642\\ufe0f|\\ud83e\\udddf\\u200d\\u2640\\ufe0f|\\ud83e\\udddf\\u200d\\u2642\\ufe0f|\\ud83d\\udc08\\u200d\\u2b1b)|[#*0-9]\\ufe0f?\\u20e3|(?:[©®\\u2122\\u265f]\\ufe0f)|(?:\\ud83c[\\udc04\\udd70\\udd71\\udd7e\\udd7f\\ude02\\ude1a\\ude2f\\ude37\\udf21\\udf24-\\udf2c\\udf36\\udf7d\\udf96\\udf97\\udf99-\\udf9b\\udf9e\\udf9f\\udfcd\\udfce\\udfd4-\\udfdf\\udff3\\udff5\\udff7]|\\ud83d[\\udc3f\\udc41\\udcfd\\udd49\\udd4a\\udd6f\\udd70\\udd73\\udd76-\\udd79\\udd87\\udd8a-\\udd8d\\udda5\\udda8\\uddb1\\uddb2\\uddbc\\uddc2-\\uddc4\\uddd1-\\uddd3\\udddc-\\uddde\\udde1\\udde3\\udde8\\uddef\\uddf3\\uddfa\\udecb\\udecd-\\udecf\\udee0-\\udee5\\udee9\\udef0\\udef3]|[\\u203c\\u2049\\u2139\\u2194-\\u2199\\u21a9\\u21aa\\u231a\\u231b\\u2328\\u23cf\\u23ed-\\u23ef\\u23f1\\u23f2\\u23f8-\\u23fa\\u24c2\\u25aa\\u25ab\\u25b6\\u25c0\\u25fb-\\u25fe\\u2600-\\u2604\\u260e\\u2611\\u2614\\u2615\\u2618\\u2620\\u2622\\u2623\\u2626\\u262a\\u262e\\u262f\\u2638-\\u263a\\u2640\\u2642\\u2648-\\u2653\\u2660\\u2663\\u2665\\u2666\\u2668\\u267b\\u267f\\u2692-\\u2697\\u2699\\u269b\\u269c\\u26a0\\u26a1\\u26a7\\u26aa\\u26ab\\u26b0\\u26b1\\u26bd\\u26be\\u26c4\\u26c5\\u26c8\\u26cf\\u26d1\\u26d3\\u26d4\\u26e9\\u26ea\\u26f0-\\u26f5\\u26f8\\u26fa\\u26fd\\u2702\\u2708\\u2709\\u270f\\u2712\\u2714\\u2716\\u271d\\u2721\\u2733\\u2734\\u2744\\u2747\\u2757\\u2763\\u2764\\u27a1\\u2934\\u2935\\u2b05-\\u2b07\\u2b1b\\u2b1c\\u2b50\\u2b55\\u3030\\u303d\\u3297\\u3299])(?:\\ufe0f|(?!\\ufe0e))|(?:(?:\\ud83c[\\udfcb\\udfcc]|\\ud83d[\\udd74\\udd75\\udd90]|[\\u261d\\u26f7\\u26f9\\u270c\\u270d])(?:\\ufe0f|(?!\\ufe0e))|(?:\\ud83c[\\udf85\\udfc2-\\udfc4\\udfc7\\udfca]|\\ud83d[\\udc42\\udc43\\udc46-\\udc50\\udc66-\\udc69\\udc6e\\udc70-\\udc78\\udc7c\\udc81-\\udc83\\udc85-\\udc87\\udcaa\\udd7a\\udd95\\udd96\\ude45-\\ude47\\ude4b-\\ude4f\\udea3\\udeb4-\\udeb6\\udec0\\udecc]|\\ud83e[\\udd0c\\udd0f\\udd18-\\udd1c\\udd1e\\udd1f\\udd26\\udd30-\\udd39\\udd3d\\udd3e\\udd77\\uddb5\\uddb6\\uddb8\\uddb9\\uddbb\\uddcd-\\uddcf\\uddd1-\\udddd\\udec3-\\udec5\\udef0-\\udef6]|[\\u270a\\u270b]))(?:\\ud83c[\\udffb-\\udfff])?|(?:\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40\\udc65\\udb40\\udc6e\\udb40\\udc67\\udb40\\udc7f|\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40\\udc73\\udb40\\udc63\\udb40\\udc74\\udb40\\udc7f|\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40\\udc77\\udb40\\udc6c\\udb40\\udc73\\udb40\\udc7f|\\ud83c\\udde6\\ud83c[\\udde8-\\uddec\\uddee\\uddf1\\uddf2\\uddf4\\uddf6-\\uddfa\\uddfc\\uddfd\\uddff]|\\ud83c\\udde7\\ud83c[\\udde6\\udde7\\udde9-\\uddef\\uddf1-\\uddf4\\uddf6-\\uddf9\\uddfb\\uddfc\\uddfe\\uddff]|\\ud83c\\udde8\\ud83c[\\udde6\\udde8\\udde9\\uddeb-\\uddee\\uddf0-\\uddf5\\uddf7\\uddfa-\\uddff]|\\ud83c\\udde9\\ud83c[\\uddea\\uddec\\uddef\\uddf0\\uddf2\\uddf4\\uddff]|\\ud83c\\uddea\\ud83c[\\udde6\\udde8\\uddea\\uddec\\udded\\uddf7-\\uddfa]|\\ud83c\\uddeb\\ud83c[\\uddee-\\uddf0\\uddf2\\uddf4\\uddf7]|\\ud83c\\uddec\\ud83c[\\udde6\\udde7\\udde9-\\uddee\\uddf1-\\uddf3\\uddf5-\\uddfa\\uddfc\\uddfe]|\\ud83c\\udded\\ud83c[\\uddf0\\uddf2\\uddf3\\uddf7\\uddf9\\uddfa]|\\ud83c\\uddee\\ud83c[\\udde8-\\uddea\\uddf1-\\uddf4\\uddf6-\\uddf9]|\\ud83c\\uddef\\ud83c[\\uddea\\uddf2\\uddf4\\uddf5]|\\ud83c\\uddf0\\ud83c[\\uddea\\uddec-\\uddee\\uddf2\\uddf3\\uddf5\\uddf7\\uddfc\\uddfe\\uddff]|\\ud83c\\uddf1\\ud83c[\\udde6-\\udde8\\uddee\\uddf0\\uddf7-\\uddfb\\uddfe]|\\ud83c\\uddf2\\ud83c[\\udde6\\udde8-\\udded\\uddf0-\\uddff]|\\ud83c\\uddf3\\ud83c[\\udde6\\udde8\\uddea-\\uddec\\uddee\\uddf1\\uddf4\\uddf5\\uddf7\\uddfa\\uddff]|\\ud83c\\uddf4\\ud83c\\uddf2|\\ud83c\\uddf5\\ud83c[\\udde6\\uddea-\\udded\\uddf0-\\uddf3\\uddf7-\\uddf9\\uddfc\\uddfe]|\\ud83c\\uddf6\\ud83c\\udde6|\\ud83c\\uddf7\\ud83c[\\uddea\\uddf4\\uddf8\\uddfa\\uddfc]|\\ud83c\\uddf8\\ud83c[\\udde6-\\uddea\\uddec-\\uddf4\\uddf7-\\uddf9\\uddfb\\uddfd-\\uddff]|\\ud83c\\uddf9\\ud83c[\\udde6\\udde8\\udde9\\uddeb-\\udded\\uddef-\\uddf4\\uddf7\\uddf9\\uddfb\\uddfc\\uddff]|\\ud83c\\uddfa\\ud83c[\\udde6\\uddec\\uddf2\\uddf3\\uddf8\\uddfe\\uddff]|\\ud83c\\uddfb\\ud83c[\\udde6\\udde8\\uddea\\uddec\\uddee\\uddf3\\uddfa]|\\ud83c\\uddfc\\ud83c[\\uddeb\\uddf8]|\\ud83c\\uddfd\\ud83c\\uddf0|\\ud83c\\uddfe\\ud83c[\\uddea\\uddf9]|\\ud83c\\uddff\\ud83c[\\udde6\\uddf2\\uddfc]|\\ud83c[\\udccf\\udd8e\\udd91-\\udd9a\\udde6-\\uddff\\ude01\\ude32-\\ude36\\ude38-\\ude3a\\ude50\\ude51\\udf00-\\udf20\\udf2d-\\udf35\\udf37-\\udf7c\\udf7e-\\udf84\\udf86-\\udf93\\udfa0-\\udfc1\\udfc5\\udfc6\\udfc8\\udfc9\\udfcf-\\udfd3\\udfe0-\\udff0\\udff4\\udff8-\\udfff]|\\ud83d[\\udc00-\\udc3e\\udc40\\udc44\\udc45\\udc51-\\udc65\\udc6a\\udc6f\\udc79-\\udc7b\\udc7d-\\udc80\\udc84\\udc88-\\udc8e\\udc90\\udc92-\\udca9\\udcab-\\udcfc\\udcff-\\udd3d\\udd4b-\\udd4e\\udd50-\\udd67\\udda4\\uddfb-\\ude44\\ude48-\\ude4a\\ude80-\\udea2\\udea4-\\udeb3\\udeb7-\\udebf\\udec1-\\udec5\\uded0-\\uded2\\uded5-\\uded7\\udedd-\\udedf\\udeeb\\udeec\\udef4-\\udefc\\udfe0-\\udfeb\\udff0]|\\ud83e[\\udd0d\\udd0e\\udd10-\\udd17\\udd20-\\udd25\\udd27-\\udd2f\\udd3a\\udd3c\\udd3f-\\udd45\\udd47-\\udd76\\udd78-\\uddb4\\uddb7\\uddba\\uddbc-\\uddcc\\uddd0\\uddde-\\uddff\\ude70-\\ude74\\ude78-\\ude7c\\ude80-\\ude86\\ude90-\\udeac\\udeb0-\\udeba\\udec0-\\udec2\\uded0-\\uded9\\udee0-\\udee7]|[\\u23e9-\\u23ec\\u23f0\\u23f3\\u267e\\u26ce\\u2705\\u2728\\u274c\\u274e\\u2753-\\u2755\\u2795-\\u2797\\u27b0\\u27bf\\ue50a])|\\ufe0f/g;\n","import { TWEMOJI_REGEX } from '../twemojiRegex';\n\n/**\n * Checks if the provided text is a single emoji.\n * The function uses a regular expression to match the emoji and ensures that the entire string is a valid single emoji.\n *\n * @param {unknown} text - The input value to check.\n * @returns {boolean} - Returns `true` if the input is a single emoji, otherwise `false`.\n *\n * @example\n * isOneEmoji(\"😊\"); // Returns: true\n * isOneEmoji(\"Hello 😊\"); // Returns: false\n * isOneEmoji(\"😎\"); // Returns: true\n * isOneEmoji(\"👨‍👩‍👧‍👦\"); // Returns: true (family emoji with multiple characters)\n * isOneEmoji(\"not an emoji\"); // Returns: false\n *\n * @group Strings\n */\nexport function isOneEmoji(text: unknown): text is string {\n  return !!(\n    typeof text === 'string' &&\n    text &&\n    (text.match(TWEMOJI_REGEX) || [])[0]?.length === text.length\n  );\n}\n","import { isString } from '@/is';\nimport { isOneEmoji } from '../isOneEmoji';\n\nconst IGNORED_TITLES = Object.freeze(\n  new Set([\n    'dr.',\n    'mr.',\n    'mrs.',\n    'miss',\n    'ms.',\n    'prof.',\n    'sir',\n    'rev.',\n    'hon.',\n  ]),\n);\n\n/**\n * Extracts the initials from a full name while ignoring titles or prefixes (e.g., Dr., Mr., Mrs.),\n * as well as any words starting with special characters (e.g., !, @, #).\n * Handles names with multiple words, ignores special characters, and ensures proper handling of Unicode characters.\n *\n * @param {string} fullName - The full name from which to extract initials.\n * @returns {string} - The extracted initials in uppercase, or an empty string if the input is invalid.\n *\n * @example\n * getInitials(\"John Doe\");\n * // Returns: \"JD\"\n *\n * @example\n * getInitials(\"Dr. Alice Wonderland\");\n * // Returns: \"AW\"\n *\n * @example\n * getInitials(\"José María de la Cruz\");\n * // Returns: \"JC\"\n *\n * @example\n * getInitials(\"Mr. Albert Einstein\");\n * // Returns: \"AE\"\n *\n * @example\n * getInitials(\"Invalid Name\");\n * // Returns: \"IN\"\n *\n * @example\n * getInitials(\"\");\n * // Returns: \"\"\n *\n * @group Strings\n */\nexport function getInitials(fullName: string) {\n  if (!isString(fullName)) return '';\n\n  let [first, ...rest] = fullName\n    .replace(/\\s{2,}/g, ' ')\n    .replace(/[,+/#!$@%^&*;:{}=\\-_`~()]/g, '')\n    .trim()\n    .split(' ')\n    .filter(word => !IGNORED_TITLES.has(word.toLowerCase()))\n    .map(v => v.replaceAll('.', '').trim())\n    .filter(Boolean);\n\n  let last = rest[rest.length - 1];\n\n  if (rest.length > 1) {\n    if (isOneEmoji(first)) {\n      first = rest[0];\n    } else if (isOneEmoji(last)) {\n      last = rest[0];\n    }\n  }\n\n  return [first, last]\n    .filter(Boolean)\n    .map((letter = '') => [...letter.toUpperCase()][0]) // We use the spread operator to support Unicode characters\n    .join('');\n}\n","import { isString } from '@/is';\n\nconst DEF_PROTOCOLS = ['http://', 'https://'];\n\n/**\n * Checks if the provided URL string has a protocol prefix, such as `http://` or `https://`.\n * The function checks whether the URL starts with any of the specified protocols (defaults to HTTP and HTTPS).\n *\n * This can be useful for validating URLs or ensuring a URL has a valid protocol before using it in network requests.\n *\n * @example\n * hasProtocol('https://google.com'); // true\n * hasProtocol('http://google.com'); // true\n * hasProtocol('google.com'); // false\n *\n * @param url - The URL string to check.\n * @param protocols - An array of protocol prefixes to check against (defaults to `['http://', 'https://']`).\n * @returns `true` if the URL starts with one of the provided protocols, `false` otherwise.\n *\n * @group Strings\n */\nexport function hasProtocol(url: string, protocols: string[] = DEF_PROTOCOLS) {\n  if (!isString(url)) return false;\n\n  return protocols.some(v => url.startsWith(v));\n}\n","const byteToHex: string[] = [];\n\nfor (let n = 0; n <= 0xff; ++n) {\n  const hexOctet = n.toString(16).padStart(2, '0');\n  byteToHex.push(hexOctet);\n}\n\n/**\n * Encodes a `Uint8Array` or a number array into a hexadecimal string.\n * Each byte of the array is converted to its corresponding two-character hex representation.\n *\n * This function is useful when you need to represent binary data as a string of hexadecimal characters.\n *\n * @example\n * console.log(hex(new Uint8Array([255]))); // 'ff'\n * console.log(hex([255, 0, 128])); // 'ff0080'\n *\n * @param value - The array to be converted, either a `Uint8Array` or a number array.\n * @returns A string of hexadecimal characters representing the array's byte values.\n *\n * @group Strings\n */\nexport function hex(value: Uint8Array | number[]) {\n  const buff = Array.isArray(value) ? new Uint8Array(value) : value;\n  const hexOctets = new Array(buff.length);\n\n  for (let i = 0; i < buff.length; ++i) {\n    hexOctets[i] = byteToHex[buff[i]];\n  }\n\n  return hexOctets.join('');\n}\n","/** Matches any deep property path. Examples: `a.b`, `a[0]`, `a[\"b\"]` */\nvar regexIsDeepProp = /\\.|(\\[(?:[^[\\]]*|([\"'])(?:(?!\\2)[^\\\\]|\\\\.)*?\\2)\\])/;\n\n/**\n * Checks if a given key is a deep key.\n *\n * A deep key is a string that contains a dot (.) or square brackets with a property accessor.\n *\n * @param {PropertyKey} key - The key to check.\n * @returns {boolean} - Returns true if the key is a deep key, otherwise false.\n *\n * Examples:\n *\n * isDeepKey('a.b') // true\n * isDeepKey('a[b]') // true\n * isDeepKey('a') // false\n * isDeepKey(123) // false\n * isDeepKey('a.b.c') // true\n * isDeepKey('a[b][c]') // true\n * isDeepKey('a.') // false\n * isDeepKey('.a') // false\n * isDeepKey('a[b') // false\n * isDeepKey('a]b]') // false\n * isDeepKey('a][b') // false\n * isDeepKey('') // false\n * isDeepKey('a[0]') // true\n *\n */\nexport function isDeepKey(key: PropertyKey): boolean {\n  switch (typeof key) {\n    case 'number':\n    case 'symbol': {\n      return false;\n    }\n    case 'string': {\n      if (key === '' || key.startsWith('.') || key.endsWith('.')) {\n        return false;\n      }\n\n      return regexIsDeepProp.test(key);\n    }\n    default: {\n      return false;\n    }\n  }\n}\n","var IS_UNSIGNED_INTEGER = /^(?:0|[1-9]\\d*)$/;\n\n/**\n * Returns true when value is property index\n * @group Strings\n */\nexport function isIndex(\n  value: PropertyKey,\n  length = Number.MAX_SAFE_INTEGER,\n): boolean {\n  switch (typeof value) {\n    case 'number': {\n      return Number.isInteger(value) && value >= 0 && value < length;\n    }\n    case 'symbol': {\n      return false;\n    }\n    case 'string': {\n      return IS_UNSIGNED_INTEGER.test(value);\n    }\n  }\n}\n","/**\n * Converts a two-letter ISO country code (e.g., 'US') to the corresponding flag emoji.\n * If the input is not a valid two-letter country code, it returns the original string.\n *\n * @param {string} iso - The two-letter ISO country code.\n * @returns {string} - The corresponding country flag emoji or the original input if it's invalid.\n *\n * @example\n * isoToFlagEmoji(\"US\"); // Returns: 🇺🇸\n * isoToFlagEmoji(\"GB\"); // Returns: 🇬🇧\n * isoToFlagEmoji(\"DE\"); // Returns: 🇩🇪\n * isoToFlagEmoji(\"xyz\"); // Returns: \"xyz\" (invalid code)\n *\n * @group Strings\n */\nexport function isoToFlagEmoji(iso: string) {\n  const code = iso.toUpperCase();\n\n  if (!/^[A-Z]{2}$/.test(code)) return iso;\n  const codePoints = [...code].map(c => c.codePointAt(0)! + 127397);\n  return String.fromCodePoint(...codePoints);\n}\n","import { getWords } from '../getWords';\n\n/**\n * Converts a string to kebab case.\n *\n * Kebab case is the naming convention in which each word is written in lowercase and separated by a dash (-) character.\n *\n * @param {string} str - The string that is to be changed to kebab case.\n * @returns {string} - The converted string to kebab case.\n *\n * @example\n * const convertedStr1 = kebabCase('camelCase') // returns 'camel-case'\n * const convertedStr2 = kebabCase('some whitespace') // returns 'some-whitespace'\n * const convertedStr3 = kebabCase('hyphen-text') // returns 'hyphen-text'\n * const convertedStr4 = kebabCase('HTTPRequest') // returns 'http-request'\n *\n * @group Strings\n */\nexport function kebabCase(str: string): string {\n  const words = getWords(str);\n  return words.map(word => word.toLowerCase()).join('-');\n}\n","import { getWords } from '../getWords';\n\n/**\n * Converts a string to lower case.\n *\n * Lower case is the naming convention in which each word is written in lowercase and separated by an space ( ) character.\n *\n * @param {string} str - The string that is to be changed to lower case.\n * @returns {string} - The converted string to lower case.\n *\n * @example\n * const convertedStr1 = lowerCase('camelCase') // returns 'camel case'\n * const convertedStr2 = lowerCase('some whitespace') // returns 'some whitespace'\n * const convertedStr3 = lowerCase('hyphen-text') // returns 'hyphen text'\n * const convertedStr4 = lowerCase('HTTPRequest') // returns 'http request'\n *\n * @group Strings\n */\nexport const lowerCase = (str?: string): string => {\n  return getWords(str)\n    .map(word => word.toLowerCase())\n    .join(' ');\n};\n","import { getWords } from '../getWords';\n\n/**\n * Masks the middle characters of each word in the given string, leaving the first and last characters intact.\n * The characters in the middle of each word are replaced by a specified masking character (default is `*`).\n *\n * ⚠️ If the provided value is not a valid string, the function returns an empty string.\n *\n * **Note**: This function does not perform any validation or checks for non-alphabetic characters within words.\n * It simply masks all characters between the first and last character of each word.\n *\n * @param {string} value - The input string containing words to be masked.\n * @param {string} [withChar='*'] - The character used to replace the middle characters of each word. Default is `*`.\n *\n * @returns {string} The input string with middle characters of words masked, or an empty string if the input is invalid.\n *\n * @example\n * maskingWords('hello world'); // 'h**o w**d'\n * maskingWords('John Doe');    // 'J**n D**e'\n * maskingWords('a b c');       // '* * *'\n *\n * @group Strings\n */\nexport function maskingWords(value: string, withChar = '*'): string {\n  return getWords(value)\n    .map(word => {\n      const len = word.length;\n\n      if (len < 2) {\n        return ''.padEnd(len, withChar);\n      } else if (len < 3) {\n        return word[0].padEnd(len, withChar);\n      } else {\n        return word[0].padEnd(len - 2, withChar) + word.at(-1);\n      }\n    })\n    .join(' ');\n}\n","import { isString } from '@/is';\nimport { maskingWords } from '../maskingWords';\n\n/**\n * Masks part of the email address to provide a simple level of privacy.\n * The username part is partially masked with asterisks, while the domain remains intact.\n *\n * ⚠️ Returns an empty string if the provided value is invalid.\n *\n * @example\n * maskingEmail('andrew@gmail.com'); // 'a****w@gmail.com'\n * maskingEmail('user@domain.com'); // 'u***r@domain.com'\n * maskingEmail('invalidemail'); // ''\n *\n * @param value - The email address to be masked.\n * @returns The masked email address or an empty string if the value is invalid.\n *\n * @group Strings\n */\nexport function maskingEmail(value: string): string {\n  if (!isString(value)) return '';\n\n  const [username, host] = value.split('@', 2);\n\n  if (!username || !host) return '';\n\n  return `${maskingWords(username)}@${host}`;\n}\n","import { isString } from '@/is';\n\n/**\n * Masks part of a phone number to provide a simple level of privacy.\n * The function replaces digits in a specified range with a given character.\n * Supports formatted phone numbers (e.g., `(000) 000-11-11`).\n *\n * ⚠️ Returns an empty string if the provided value is invalid.\n *\n * @example\n * maskingPhone('+18000551100'); // '+18XXXXX1100'\n * maskingPhone('+18000551100', 2, 4, '*'); // '+18*****1100'\n * maskingPhone('+1 800-055-1100'); // '+1 8XX-XXX-1100'\n * maskingPhone('+1234567890', 3, 5, 'X'); // '+1XXX567890'\n *\n * @param value - The phone number to be masked.\n * @param [fromPosition=2] - The starting position from left side where masking begins (default is 2).\n * @param [toPosition=4] - The position from right side where masking ends (default is 4).\n * @param [withChar='X'] - The character used to replace digits (default is 'X').\n * @returns The masked phone number or an empty string if the value is invalid.\n *\n * @group Strings\n */\nexport function maskingPhone(\n  value: string,\n  fromPosition = 2,\n  toPosition = 4,\n  withChar = 'X',\n): string {\n  if (!isString(value)) return '';\n\n  const numbersAmount = value.replace(/\\D/g, '').length;\n  const fromIdx = fromPosition - 1;\n\n  let toIdx = numbersAmount - toPosition;\n\n  if (toIdx <= 0) {\n    toIdx = numbersAmount;\n  }\n\n  let i = -1;\n\n  return value.replace(/\\d/g, char => {\n    i++;\n    return i > fromIdx && i < toIdx ? withChar : char;\n  });\n}\n","import { isDate } from '@/is';\n\n/**\n * Returns the number of seconds since the Unix epoch (January 1, 1970).\n *\n * This function accepts either a `Date` object or a timestamp in milliseconds (number).\n * If no argument is provided, it defaults to the current timestamp in seconds.\n *\n * @param {Date | number} [fromValue=Date.now()] - The date or timestamp to convert.\n * If not provided, the current date and time will be used.\n *\n * @returns {number} The number of seconds since the Unix epoch for the provided date or timestamp.\n *\n * @example\n * // Using a Date object\n * const date = new Date('2020-01-01T00:00:00Z');\n * console.log(timestamp(date)); // Returns 1577836800 (seconds since Unix epoch)\n *\n * // Using a timestamp in milliseconds\n * const timestampInMs = 1609459200000;\n * console.log(timestamp(timestampInMs)); // Returns 1609459200 (seconds since Unix epoch)\n *\n * // Using the current time\n * console.log(timestamp()); // Returns current seconds since Unix epoch\n *\n * @group Date\n */\nexport function timestamp(fromValue: Date | number = Date.now()) {\n  if (isDate(fromValue)) {\n    fromValue = fromValue.getTime();\n  }\n\n  return Math.floor(fromValue / 1000);\n}\n","import { timestamp } from '@/date/timestamp';\nimport { hex } from '../hex';\n\nlet index = Math.floor(Math.random() * 0xffffff);\n\nconst buffer = new Uint8Array(12);\n\n/**\n * Useful when you need to generate almost secure object id in browser\n *\n * Based on [bson](https://github.com/mongodb/js-bson/blob/main/src/objectid.ts)\n *\n * @example\n * const userId = objectId(); // '67350af7885ba34010c83859'\n *\n * @group Strings\n */\nexport function objectId(fromValue: number | Date = Date.now()): string {\n  const value = timestamp(fromValue);\n  const inc = getInc();\n\n  buffer[0] = value >> 24;\n  buffer[1] = value >> 16;\n  buffer[2] = value >> 8;\n  buffer[3] = value;\n\n  buffer[4] = Math.floor(Math.random() * 256);\n  buffer[5] = Math.floor(Math.random() * 256);\n  buffer[6] = Math.floor(Math.random() * 256);\n  buffer[7] = Math.floor(Math.random() * 256);\n  buffer[8] = Math.floor(Math.random() * 256);\n\n  buffer[11] = inc & 0xff;\n  buffer[10] = (inc >> 8) & 0xff;\n  buffer[9] = (inc >> 16) & 0xff;\n\n  return hex(buffer);\n}\n\nfunction getInc(): number {\n  return (index = (index + 1) % 0xffffff);\n}\n","import { isNumber } from '@/is';\n\nconst rndCharacters = 'abcdefghijklmnopqrstuvwxyz0123456789';\nconst charactersLength = rndCharacters.length;\n\n/**\n * Generates a random string of the specified length using characters from a predefined set.\n * The characters used in the generated string include lowercase letters (a-z) and digits (0-9).\n *\n * @param {number} length - The length of the random string to generate. Must be a positive integer.\n *\n * @returns {string} A random string of the specified length, composed of characters from 'a-z' and '0-9'.\n *\n * @example\n * randomString(8);  // e.g. 'a1b2c3d4'\n * randomString(12); // e.g. '3f6g7h8i9j0k'\n * randomString(5);  // e.g. '1a2b3'\n *\n * @group Strings\n */\nexport function randomString(length: number): string {\n  let str = '';\n  let num = isNumber(length) ? Math.max(0, length) : 0;\n  while (num--) {\n    str += rndCharacters[(charactersLength * Math.random()) | 0];\n  }\n  return str;\n}\n","import { getWords } from '../getWords';\n\n/**\n * Converts a string to snake case.\n *\n * Snake case is the naming convention in which each word is written in lowercase and separated by an underscore (_) character.\n *\n * @param {string} str - The string that is to be changed to snake case.\n * @returns {string} - The converted string to snake case.\n *\n * @example\n * const convertedStr1 = snakeCase('camelCase') // returns 'camel_case'\n * const convertedStr2 = snakeCase('some whitespace') // returns 'some_whitespace'\n * const convertedStr3 = snakeCase('hyphen-text') // returns 'hyphen_text'\n * const convertedStr4 = snakeCase('HTTPRequest') // returns 'http_request'\n *\n * @group Strings\n */\nexport const snakeCase = (str?: string): string => {\n  return getWords(str)\n    .map(word => word.toLowerCase())\n    .join('_');\n};\n","/**\n * Formats a string by replacing format specifiers with values from the provided arguments.\n * It supports a variety of format types, including strings, numbers, and objects.\n *\n * ⚠️ This function mutates the `unusedArgs` array, which will contain any arguments\n * that were not used in the formatting process.\n *\n * @param line - The format string containing placeholders to be replaced by arguments.\n *   Format specifiers are indicated by the `%` symbol, followed by a character indicating\n *   the type of argument to insert (e.g., `%s` for string, `%d` for integer, `%f` for float).\n * @param args - The array of arguments to replace the format specifiers in the string.\n *   The function will iterate over the arguments and substitute them into the format string\n *   in the order they appear.\n * @param [unusedArgs=[]] - The array that will collect any unused arguments\n *   that were not needed for formatting. This array is mutated by the function.\n *\n * @returns {string} The formatted string with placeholders replaced by corresponding arguments.\n *\n * @example\n * const unusedArgs: any[] = [];\n *\n * console.log(sprintf('Hello %s', ['World', 'Great'], unusedArgs));\n * // Output: 'Hello World'\n * console.log(unusedArgs);\n * // Output: ['Great']\n *\n * @example\n * console.log(sprintf('I have %d apples and %f.5 liters of water.', [5, 3.2], unusedArgs));\n * // Output: 'I have 5 apples and 3.2 liters of water.'\n * console.log(unusedArgs);\n * // Output: []\n *\n * @group Strings\n */\nexport function sprintf(line: string, args: any[], unusedArgs: any[] = []) {\n  let result = '';\n\n  const argsLen = args.length;\n  const lineLen = line.length;\n\n  let opened = false;\n  let currentChar = -1;\n  let lastPos = 0;\n  let argsIndex = 0;\n\n  for (let idx = 0; idx < lineLen; idx++) {\n    currentChar = line.charCodeAt(idx);\n\n    // \"%\" found\n    if (currentChar === 37) {\n      opened = true;\n      continue;\n    }\n\n    if (!opened) continue;\n\n    opened = false;\n\n    switch (currentChar) {\n      // 'd'\n      case 100:\n      // 'f'\n      case 102: {\n        result += line.slice(lastPos, idx - 1);\n        result += Number(args[argsIndex]);\n        lastPos = idx + 1;\n        argsIndex++;\n        break;\n      }\n\n      // 'i'\n      case 105: {\n        result += line.slice(lastPos, idx - 1);\n        result += Math.floor(Number(args[argsIndex]));\n        lastPos = idx + 1;\n        argsIndex++;\n        break;\n      }\n\n      // 'O'\n      case 79:\n      // 'o'\n      case 111:\n      // 'j'\n      case 106: {\n        result += line.slice(lastPos, idx - 1);\n        result += tryStringify(args[argsIndex]);\n        lastPos = idx + 1;\n        argsIndex++;\n        break;\n      }\n\n      // 's'\n      case 115: {\n        result += line.slice(lastPos, idx - 1);\n        result += String(args[argsIndex]);\n        lastPos = idx + 1;\n        argsIndex++;\n        break;\n      }\n    }\n\n    if (argsIndex >= argsLen) break;\n  }\n\n  if (lastPos < lineLen) {\n    result += line.slice(lastPos, lineLen);\n  }\n\n  if (argsIndex < argsLen) {\n    unusedArgs.push(...args.slice(argsIndex, argsLen));\n  }\n\n  return result;\n}\n\nfunction tryStringify(o: unknown) {\n  switch (typeof o) {\n    case 'function': {\n      return o.name || '<anonymous>';\n    }\n\n    case 'string': {\n      return \"'\" + o + \"'\";\n    }\n\n    default: {\n      try {\n        return JSON.stringify(o);\n      } catch (e) {\n        return '\"[Circular]\"';\n      }\n    }\n  }\n}\n","import { capitalize } from '../capitalize';\nimport { getWords } from '../getWords';\n\n/**\n * Converts the first character of each word in a string to uppercase and the remaining characters to lowercase.\n *\n * Start case is the naming convention in which each word is written with an initial capital letter.\n * @param {string} str - The string to convert.\n * @returns {string} The converted string.\n *\n * @example\n * const result1 = startCase('hello world');  // result will be 'Hello World'\n * const result2 = startCase('HELLO WORLD');  // result will be 'Hello World'\n * const result3 = startCase('hello-world');  // result will be 'Hello World'\n * const result4 = startCase('hello_world');  // result will be 'Hello World'\n *\n * @group Strings\n */\nexport const startCase = (value?: string): string => {\n  return getWords(value).map(capitalize).join(' ');\n};\n","const DEF_STR_ASSIGN_REGEXP = /\\{{([A-z-_. ]*)\\}}/g;\nconst DEF_STR_ASSIGN_METHOD = (obj: any, key: string) => obj[key];\n\n/**\n * Replaces placeholders in the input string with values from the provided object.\n * The placeholders are denoted by `{{ key }}` syntax, where `key` is a property name in the object.\n * The function optionally allows a custom method to handle how the values are retrieved from the object.\n *\n * @param {string} str - The string with placeholders to be replaced. Placeholders are in the form of `{{key}}`.\n * @param {T} obj - The object whose properties will be used to replace the placeholders in the string.\n * @param method - An optional custom method\n *   to retrieve values from the object. The default method retrieves\n *   the values by accessing the object property directly using the `key`.\n *\n * @returns {string} The string with placeholders replaced by the corresponding values from the object.\n *\n * @example\n * const context = { name: 'Andrew', age: 30 };\n * console.log(strAssign('Hey {{ name }}! You are {{ age }} years old.', context));\n * // Output: 'Hey Andrew! You are 30 years old.'\n *\n * @example\n * // Using a custom method\n * const context2 = { firstName: 'Andrew', lastName: 'L.' };\n * const customMethod = (obj, key) => {\n *   if (key === 'name') {\n *     return obj.firstName + ' ' + obj.lastName;\n *   }\n *   return obj[key];\n * };\n * console.log(strAssign('Hello {{ name }}!', context2, customMethod));\n * // Output: 'Hello Andrew L.!'\n *\n * @group Strings\n */\nexport function strAssign<T extends object>(\n  str: string,\n  obj: T,\n  method: (obj: T, key: string) => any = DEF_STR_ASSIGN_METHOD,\n): string {\n  return str.replace(DEF_STR_ASSIGN_REGEXP, (match, p1) => {\n    const key = p1.trim();\n    const value = method(obj, key);\n\n    if (value === undefined || value === null) {\n      return match;\n    }\n\n    return value;\n  });\n}\n","export var textEncoder = new TextEncoder();\nexport var textDecoder = new TextDecoder();\n","/**\n * Converts `value` to a string key if it's not a string or symbol.\n *\n * @param {*} value The value to inspect.\n * @group Strings\n */\nexport function toKey(value: any): string | symbol {\n  if (typeof value === 'string' || typeof value === 'symbol') {\n    return value;\n  }\n  if (Object.is(value?.valueOf?.(), -0)) {\n    return '-0';\n  }\n  return String(value);\n}\n","/**\n * Converts `value` to a string.\n *\n * An empty string is returned for `null` and `undefined` values.\n * The sign of `-0` is preserved.\n *\n * @param value - The value to convert.\n * @returns Returns the converted string.\n *\n * @example\n * toString(null) // returns ''\n * toString(undefined) // returns ''\n * toString(-0) // returns '-0'\n * toString([1, 2, -0]) // returns '1,2,-0'\n * toString([Symbol('a'), Symbol('b')]) // returns 'Symbol(a),Symbol(b)'\n *\n * @group Strings\n */\nexport function toString(value?: any): string {\n  if (value == null) {\n    return '';\n  }\n\n  if (typeof value === 'string') {\n    return value;\n  }\n\n  if (Array.isArray(value)) {\n    return value.map(toString).join(',');\n  }\n\n  const result = String(value);\n\n  if (result === '0' && Object.is(Number(value), -0)) {\n    return '-0';\n  }\n\n  return result;\n}\n","import { toKey } from '../toKey';\nimport { toString } from '../toString';\n\n/**\n * Converts a deep key string into an array of path segments.\n *\n * This function takes a string representing a deep key (e.g., 'a.b.c' or 'a[b][c]') and breaks it down into an array of strings, each representing a segment of the path.\n *\n * @param deepKey - The deep key string to convert.\n * @returns An array of strings, each representing a segment of the path.\n *\n * Examples:\n *\n * toPath('a.b.c') // Returns ['a', 'b', 'c']\n * toPath('a[b][c]') // Returns ['a', 'b', 'c']\n * toPath('.a.b.c') // Returns ['', 'a', 'b', 'c']\n * toPath('a[\"b.c\"].d') // Returns ['a', 'b.c', 'd']\n * toPath('') // Returns []\n * toPath('.a[b].c.d[e][\"f.g\"].h') // Returns ['', 'a', 'b', 'c', 'd', 'e', 'f.g', 'h']\n *\n * @group Strings\n */\nexport function toPath(deepKey: any): string[] {\n  if (Array.isArray(deepKey)) {\n    return deepKey.map(toKey) as string[];\n  }\n  if (typeof deepKey === 'symbol') {\n    return [deepKey as unknown as string];\n  }\n  deepKey = toString(deepKey);\n  const result: string[] = [];\n  const length = deepKey.length;\n\n  if (length === 0) {\n    return result;\n  }\n\n  let index = 0;\n  let key = '';\n  let quoteChar = '';\n  let bracket = false;\n\n  // Leading dot. Record the empty segment that precedes it, but leave the dot for the\n  // main loop so it is still treated as a separator (e.g. '..a' -> ['', '', 'a']).\n  if (deepKey.charCodeAt(0) === 46) {\n    result.push('');\n  }\n\n  while (index < length) {\n    const char = deepKey[index];\n\n    if (quoteChar) {\n      if (char === '\\\\' && index + 1 < length) {\n        // Escape character\n        index++;\n        key += deepKey[index];\n      } else if (char === quoteChar) {\n        // End of quote\n        quoteChar = '';\n      } else {\n        key += char;\n      }\n    } else if (bracket) {\n      if (char === '\"' || char === \"'\") {\n        // Start of quoted string inside brackets\n        quoteChar = char;\n      } else if (char === ']') {\n        // End of bracketed segment\n        bracket = false;\n        result.push(key);\n        key = '';\n      } else {\n        key += char;\n      }\n    } else {\n      if (char === '[') {\n        // Start of bracketed segment\n        bracket = true;\n        if (key) {\n          result.push(key);\n          key = '';\n        }\n      } else if (char === '.') {\n        if (key) {\n          result.push(key);\n          key = '';\n        }\n        // A dot that is directly followed by another dot or the end of the string\n        // separates an empty segment, matching lodash (e.g. 'a..b' -> ['a', '', 'b'],\n        // 'a.' -> ['a', '']).\n        const next = deepKey[index + 1];\n        if (next === undefined || next === '.') {\n          result.push('');\n        }\n      } else {\n        key += char;\n      }\n    }\n\n    index++;\n  }\n\n  if (key) {\n    result.push(key);\n  }\n\n  return result;\n}\n","/**\n * Truncates a string to the specified maximum length while preserving whole words\n * and appends ellipsis (`...`) if the string exceeds the maximum length.\n * Ensures that truncation does not occur if the difference is insignificant\n * (less than 5% of the original string length).\n *\n * @param {string} str - The input string to truncate.\n * @param {number} maxLength - The maximum allowed length for the string.\n * @param {number} insignificantThreshold - The insignificance threshold as a fraction of the original string length (default is 5%)\n * @returns {string} - The truncated string with ellipsis if applicable.\n *\n *\n * @example\n * // Basic truncation\n * truncate(\"This is a test string for truncation.\", 20);\n * // Returns: \"This is a test...\"\n *\n * @example\n * // No truncation needed as the string length is within the limit\n * truncate(\"Short string\", 20);\n * // Returns: \"Short string\"\n *\n * @example\n * // No truncation because the difference is insignificant\n * truncate(\"This string has an insignificant truncation.\", 40);\n * // Returns: \"This string has an insignificant truncation.\"\n *\n * @example\n * // Handles strings with no spaces gracefully\n * truncate(\"ThisStringHasNoSpacesButIsVeryLong\", 10);\n * // Returns: \"ThisString...\"\n *\n * @group Strings\n */\nexport function truncate(\n  value: string,\n  maxLength: number = 120,\n  insignificantThreshold: number = 0.05,\n): string {\n  if (!shouldTruncate(value, maxLength, insignificantThreshold)) {\n    return value;\n  }\n\n  let truncated = value.slice(0, maxLength).trim();\n  const lastSpace = truncated.lastIndexOf(' ');\n\n  if (lastSpace > 0) {\n    truncated = truncated.slice(0, lastSpace);\n  }\n\n  return `${truncated}...`;\n}\n\nfunction shouldTruncate(\n  text: string,\n  maxLength: number,\n  insignificantThreshold: number,\n) {\n  return text.length - maxLength > maxLength * insignificantThreshold;\n}\n","/**\n * Truncates the input string to the specified maximum length and appends an ellipsis (`...`)\n * if the string exceeds the maximum length. If the string is shorter than or equal to the\n * maximum length, it is returned unchanged.\n *\n * Unlike the `truncate` function, the result can be truncated in the middle of a word\n *\n * @param {string} value - The input string to truncate.\n * @param {number} maxLength - The maximum allowed length for the string (default is 30).\n * @returns {string} - The truncated string with ellipsis (`...`) if necessary.\n *\n * @example\n * wrapText(\"This is a long string\", 10); // Returns: \"This is a...\"\n * wrapText(\"Short text\", 20); // Returns: \"Short text\"\n * wrapText(\"Another long string example\", 15); // Returns: \"Another long...\"\n *\n * @group Strings\n */\nexport function wrapText(value: string, maxLength: number = 30) {\n  if (value.length > maxLength) {\n    return value.slice(0, maxLength) + '...';\n  }\n\n  return value;\n}\n","/**\n * Checks if a property key is unsafe to modify directly.\n *\n * This function is used in functions like `merge` to prevent prototype pollution attacks\n * by identifying property keys that could modify the object's prototype chain or constructor.\n *\n * @param key - The property key to check\n * @returns `true` if the property is unsafe to modify directly, `false` otherwise\n * @internal\n */\nexport function isUnsafeProperty(key: PropertyKey) {\n  return key === '__proto__';\n}\n","import { isDeepKey, toKey, toPath } from '@/str/index.ts';\nimport { isUnsafeProperty } from '@/str/isUnsafeProperty.ts';\nimport type { Arrayable } from '@/types/types.js';\nimport type { GetFieldType } from './GetFieldType.ts';\n\n/**\n * Gets the value at path of object. If the resolved value is undefined, the defaultValue is returned in its place.\n *\n * @template TObject\n * @template TKey\n * @param object - The object to query.\n * @param path - The path of the property to get.\n * @returns Returns the resolved value.\n *\n * @example\n * const object = { 'a': [{ 'b': { 'c': 3 } }] };\n * get(object, 'a[0].b.c');\n * // => 3\n *\n * @group Object\n */\nexport function get<TObject extends object, TKey extends keyof TObject>(\n  object: TObject,\n  path: TKey | [TKey],\n): TObject[TKey];\n\n/**\n * Gets the value at path of object. If the resolved value is undefined, the defaultValue is returned in its place.\n *\n * @template TObject\n * @template TKey\n * @param object - The object to query.\n * @param path - The path of the property to get.\n * @returns Returns the resolved value.\n *\n * @example\n * const object = { 'a': [{ 'b': { 'c': 3 } }] };\n * get(object, 'a[0].b.c');\n * // => 3\n *\n * @group Object\n */\nexport function get<TObject extends object, TKey extends keyof TObject>(\n  object: TObject | null | undefined,\n  path: TKey | [TKey],\n): TObject[TKey] | undefined;\n\n/**\n * Gets the value at path of object. If the resolved value is undefined, the defaultValue is returned in its place.\n *\n * @template TObject\n * @template TKey\n * @template TDefault\n * @param object - The object to query.\n * @param path - The path of the property to get.\n * @param defaultValue - The value returned if the resolved value is undefined.\n * @returns Returns the resolved value.\n *\n * @example\n * const object = { 'a': [{ 'b': { 'c': 3 } }] };\n * get(object, 'a[0].b.c', 'default');\n * // => 3\n *\n * @group Object\n */\nexport function get<\n  TObject extends object,\n  TKey extends keyof TObject,\n  TDefault,\n>(\n  object: TObject | null | undefined,\n  path: TKey | [TKey],\n  defaultValue: TDefault,\n): Exclude<TObject[TKey], undefined> | TDefault;\n\n/**\n * Gets the value at path of object. If the resolved value is undefined, the defaultValue is returned in its place.\n *\n * @template TObject\n * @template TKey1\n * @template TKey2\n * @param object - The object to query.\n * @param path - The path of the property to get.\n * @returns Returns the resolved value.\n *\n * @example\n * const object = { 'a': { 'b': 2 } };\n * get(object, ['a', 'b']);\n * // => 2\n *\n * @group Object\n */\nexport function get<\n  TObject extends object,\n  TKey1 extends keyof TObject,\n  TKey2 extends keyof TObject[TKey1],\n>(object: TObject, path: [TKey1, TKey2]): TObject[TKey1][TKey2];\n\n/**\n * Gets the value at path of object. If the resolved value is undefined, the defaultValue is returned in its place.\n *\n * @template TObject\n * @template TKey1\n * @template TKey2\n * @param object - The object to query.\n * @param path - The path of the property to get.\n * @returns Returns the resolved value.\n *\n * @example\n * const object = { 'a': { 'b': 2 } };\n * get(object, ['a', 'b']);\n * // => 2\n *\n * @group Object\n */\nexport function get<\n  TObject extends object,\n  TKey1 extends keyof TObject,\n  TKey2 extends keyof NonNullable<TObject[TKey1]>,\n>(\n  object: TObject | null | undefined,\n  path: [TKey1, TKey2],\n): NonNullable<TObject[TKey1]>[TKey2] | undefined;\n\n/**\n * Gets the value at path of object. If the resolved value is undefined, the defaultValue is returned in its place.\n *\n * @template TObject\n * @template TKey1\n * @template TKey2\n * @template TDefault\n * @param object - The object to query.\n * @param path - The path of the property to get.\n * @param defaultValue - The value returned if the resolved value is undefined.\n * @returns Returns the resolved value.\n *\n * @example\n * const object = { 'a': { 'b': 2 } };\n * get(object, ['a', 'b'], 'default');\n * // => 2\n *\n * @group Object\n */\nexport function get<\n  TObject extends object,\n  TKey1 extends keyof TObject,\n  TKey2 extends keyof NonNullable<TObject[TKey1]>,\n  TDefault,\n>(\n  object: TObject | null | undefined,\n  path: [TKey1, TKey2],\n  defaultValue: TDefault,\n): Exclude<NonNullable<TObject[TKey1]>[TKey2], undefined> | TDefault;\n\n/**\n * Gets the value at path of object. If the resolved value is undefined, the defaultValue is returned in its place.\n *\n * @template TObject\n * @template TKey1\n * @template TKey2\n * @template TKey3\n * @param object - The object to query.\n * @param path - The path of the property to get.\n * @returns Returns the resolved value.\n *\n * @example\n * const object = { 'a': { 'b': { 'c': 3 } } };\n * get(object, ['a', 'b', 'c']);\n * // => 3\n *\n * @group Object\n */\nexport function get<\n  TObject extends object,\n  TKey1 extends keyof TObject,\n  TKey2 extends keyof TObject[TKey1],\n  TKey3 extends keyof TObject[TKey1][TKey2],\n>(object: TObject, path: [TKey1, TKey2, TKey3]): TObject[TKey1][TKey2][TKey3];\n\n/**\n * Gets the value at path of object. If the resolved value is undefined, the defaultValue is returned in its place.\n *\n * @template TObject\n * @template TKey1\n * @template TKey2\n * @template TKey3\n * @param object - The object to query.\n * @param path - The path of the property to get.\n * @returns Returns the resolved value.\n *\n * @example\n * const object = { 'a': { 'b': { 'c': 3 } } };\n * get(object, ['a', 'b', 'c']);\n * // => 3\n *\n * @group Object\n */\nexport function get<\n  TObject extends object,\n  TKey1 extends keyof TObject,\n  TKey2 extends keyof NonNullable<TObject[TKey1]>,\n  TKey3 extends keyof NonNullable<NonNullable<TObject[TKey1]>[TKey2]>,\n>(\n  object: TObject | null | undefined,\n  path: [TKey1, TKey2, TKey3],\n): NonNullable<NonNullable<TObject[TKey1]>[TKey2]>[TKey3] | undefined;\n\n/**\n * Gets the value at path of object. If the resolved value is undefined, the defaultValue is returned in its place.\n *\n * @template TObject\n * @template TKey1\n * @template TKey2\n * @template TKey3\n * @template TDefault\n * @param object - The object to query.\n * @param path - The path of the property to get.\n * @param defaultValue - The value returned if the resolved value is undefined.\n * @returns Returns the resolved value.\n *\n * @example\n * const object = { 'a': { 'b': { 'c': 3 } } };\n * get(object, ['a', 'b', 'c'], 'default');\n * // => 3\n *\n * @group Object\n */\nexport function get<\n  TObject extends object,\n  TKey1 extends keyof TObject,\n  TKey2 extends keyof NonNullable<TObject[TKey1]>,\n  TKey3 extends keyof NonNullable<NonNullable<TObject[TKey1]>[TKey2]>,\n  TDefault,\n>(\n  object: TObject | null | undefined,\n  path: [TKey1, TKey2, TKey3],\n  defaultValue: TDefault,\n):\n  | Exclude<NonNullable<NonNullable<TObject[TKey1]>[TKey2]>[TKey3], undefined>\n  | TDefault;\n\n/**\n * Gets the value at path of object.\n *\n * @template TObject\n * @template TKey1\n * @template TKey2\n * @template TKey3\n * @template TKey4\n * @param object - The object to query.\n * @param path - The path of the property to get.\n * @returns Returns the resolved value.\n *\n * @example\n * const object = { 'a': { 'b': { 'c': { 'd': 4 } } } };\n * get(object, ['a', 'b', 'c', 'd']);\n * // => 4\n *\n * @group Object\n */\nexport function get<\n  TObject extends object,\n  TKey1 extends keyof TObject,\n  TKey2 extends keyof TObject[TKey1],\n  TKey3 extends keyof TObject[TKey1][TKey2],\n  TKey4 extends keyof TObject[TKey1][TKey2][TKey3],\n>(\n  object: TObject,\n  path: [TKey1, TKey2, TKey3, TKey4],\n): TObject[TKey1][TKey2][TKey3][TKey4];\n\n/**\n * Gets the value at path of object. If the resolved value is undefined, undefined is returned.\n *\n * @template TObject\n * @template TKey1\n * @template TKey2\n * @template TKey3\n * @template TKey4\n * @param object - The object to query.\n * @param path - The path of the property to get.\n * @returns Returns the resolved value.\n *\n * @example\n * const object = { 'a': { 'b': { 'c': { 'd': 4 } } } };\n * get(object, ['a', 'b', 'c', 'd']);\n * // => 4\n *\n * @group Object\n */\nexport function get<\n  TObject extends object,\n  TKey1 extends keyof TObject,\n  TKey2 extends keyof NonNullable<TObject[TKey1]>,\n  TKey3 extends keyof NonNullable<NonNullable<TObject[TKey1]>[TKey2]>,\n  TKey4 extends keyof NonNullable<\n    NonNullable<NonNullable<TObject[TKey1]>[TKey2]>[TKey3]\n  >,\n>(\n  object: TObject | null | undefined,\n  path: [TKey1, TKey2, TKey3, TKey4],\n):\n  | NonNullable<NonNullable<NonNullable<TObject[TKey1]>[TKey2]>[TKey3]>[TKey4]\n  | undefined;\n\n/**\n * Gets the value at path of object. If the resolved value is undefined, the defaultValue is returned in its place.\n *\n * @template TObject\n * @template TKey1\n * @template TKey2\n * @template TKey3\n * @template TKey4\n * @template TDefault\n * @param object - The object to query.\n * @param path - The path of the property to get.\n * @param defaultValue - The value returned if the resolved value is undefined.\n * @returns Returns the resolved value.\n *\n * @example\n * const object = { 'a': { 'b': { 'c': { 'd': 4 } } } };\n * get(object, ['a', 'b', 'c', 'd'], 'default');\n * // => 4\n *\n * @group Object\n */\nexport function get<\n  TObject extends object,\n  TKey1 extends keyof TObject,\n  TKey2 extends keyof NonNullable<TObject[TKey1]>,\n  TKey3 extends keyof NonNullable<NonNullable<TObject[TKey1]>[TKey2]>,\n  TKey4 extends keyof NonNullable<\n    NonNullable<NonNullable<TObject[TKey1]>[TKey2]>[TKey3]\n  >,\n  TDefault,\n>(\n  object: TObject | null | undefined,\n  path: [TKey1, TKey2, TKey3, TKey4],\n  defaultValue: TDefault,\n):\n  | Exclude<\n      NonNullable<\n        NonNullable<NonNullable<TObject[TKey1]>[TKey2]>[TKey3]\n      >[TKey4],\n      undefined\n    >\n  | TDefault;\n\n/**\n * Gets the value at path of object.\n *\n * @template T\n * @param object - The object to query.\n * @param path - The path of the property to get.\n * @returns Returns the resolved value.\n *\n * @example\n * const object = { 0: 'a', 1: 'b', 2: 'c' };\n * get(object, 1);\n * // => 'b'\n *\n * @group Object\n */\nexport function get<T>(object: Record<number, T>, path: number): T;\n\n/**\n * Gets the value at path of object. If the resolved value is undefined, undefined is returned.\n *\n * @template T\n * @param object - The object to query.\n * @param path - The path of the property to get.\n * @returns Returns the resolved value.\n *\n * @example\n * const object = { 0: 'a', 1: 'b', 2: 'c' };\n * get(object, 1);\n * // => 'b'\n *\n * @group Object\n */\nexport function get<T>(\n  object: Record<number, T> | null | undefined,\n  path: number,\n): T | undefined;\n\n/**\n * Gets the value at path of object. If the resolved value is undefined, the defaultValue is returned in its place.\n *\n * @template T\n * @template TDefault\n * @param object - The object to query.\n * @param path - The path of the property to get.\n * @param defaultValue - The value returned if the resolved value is undefined.\n * @returns Returns the resolved value.\n *\n * @example\n * const object = { 0: 'a', 1: 'b', 2: 'c' };\n * get(object, 1, 'default');\n * // => 'b'\n *\n * @group Object\n */\nexport function get<T, TDefault>(\n  object: Record<number, T> | null | undefined,\n  path: number,\n  defaultValue: TDefault,\n): T | TDefault;\n\n/**\n * Gets the value at path of object. If the resolved value is undefined, the defaultValue is returned in its place.\n *\n * @template TDefault\n * @param object - The object to query.\n * @param path - The path of the property to get.\n * @param defaultValue - The value returned if the resolved value is undefined.\n * @returns Returns the default value.\n *\n * @example\n * get(null, 'a.b.c', 'default');\n * // => 'default'\n *\n * @group Object\n */\nexport function get<TDefault>(\n  object: null | undefined,\n  path: Arrayable<PropertyKey>,\n  defaultValue: TDefault,\n): TDefault;\n\n/**\n * Gets the value at path of object. If the resolved value is undefined, undefined is returned.\n *\n * @param object - The object to query.\n * @param path - The path of the property to get.\n * @returns Returns undefined.\n *\n * @example\n * get(null, 'a.b.c');\n * // => undefined\n *\n * @group Object\n */\nexport function get(\n  object: null | undefined,\n  path: Arrayable<PropertyKey>,\n): undefined;\n\n/**\n * Gets the value at path of object using type-safe path.\n *\n * @template TObject\n * @template TPath\n * @param data - The object to query.\n * @param path - The path of the property to get.\n * @returns Returns the resolved value.\n *\n * @example\n * const object = { a: { b: { c: 1 } } };\n * get(object, 'a.b.c');\n * // => 1\n *\n * @group Object\n */\nexport function get<TObject, TPath extends string>(\n  data: TObject,\n  path: TPath,\n): string extends TPath ? any : GetFieldType<TObject, TPath>;\n\n/**\n * Gets the value at path of object using type-safe path. If the resolved value is undefined, the defaultValue is returned.\n *\n * @template TObject\n * @template TPath\n * @template TDefault\n * @param data - The object to query.\n * @param path - The path of the property to get.\n * @param defaultValue - The value returned if the resolved value is undefined.\n * @returns Returns the resolved value.\n *\n * @example\n * const object = { a: { b: { c: 1 } } };\n * get(object, 'a.b.d', 'default');\n * // => 'default'\n *\n * @group Object\n */\nexport function get<\n  TObject,\n  TPath extends string,\n  TDefault = GetFieldType<TObject, TPath>,\n>(\n  data: TObject,\n  path: TPath,\n  defaultValue: TDefault,\n): Exclude<GetFieldType<TObject, TPath>, null | undefined> | TDefault;\n\n/**\n * Gets the value at path of object. If the resolved value is undefined, the defaultValue is returned.\n *\n * @param object - The object to query.\n * @param path - The path of the property to get.\n * @param [defaultValue] - The value returned if the resolved value is undefined.\n * @returns Returns the resolved value.\n *\n * @example\n * const object = { a: { b: { c: 1 } } };\n * get(object, 'a.b.c', 'default');\n * // => 1\n *\n * @group Object\n */\nexport function get(\n  object: any,\n  path: Arrayable<PropertyKey>,\n  defaultValue?: any,\n): any;\n\n/**\n * Retrieves the value at a given path from an object. If the resolved value is undefined, the defaultValue is returned instead.\n *\n * @param object - The object to query.\n * @param path - The path of the property to get.\n * @param [defaultValue] - The value returned if the resolved value is undefined.\n * @returns Returns the resolved value.\n *\n * @example\n * const object = { a: { b: { c: 1 } } };\n * get(object, 'a.b.c');\n * // => 1\n *\n * get(object, ['a', 'b', 'c']);\n * // => 1\n *\n * get(object, 'a.b.d', 'default');\n * // => 'default'\n *\n * @group Object\n */\nexport function get(\n  object: any,\n  path: PropertyKey | readonly PropertyKey[],\n  defaultValue?: any,\n): any {\n  if (object == null) {\n    return defaultValue;\n  }\n\n  switch (typeof path) {\n    case 'string': {\n      if (isUnsafeProperty(path)) {\n        return defaultValue;\n      }\n\n      const result = object[path];\n\n      if (result === undefined) {\n        if (isDeepKey(path) && !Object.hasOwn(object, path)) {\n          return get(object, toPath(path), defaultValue);\n        } else {\n          return defaultValue;\n        }\n      }\n\n      return result;\n    }\n    case 'number':\n    case 'symbol': {\n      if (typeof path === 'number') {\n        path = toKey(path);\n      }\n\n      const result = object[path as PropertyKey];\n\n      if (result === undefined) {\n        return defaultValue;\n      }\n\n      return result;\n    }\n    default: {\n      if (Array.isArray(path)) {\n        return getWithPath(object, path, defaultValue);\n      }\n\n      if (Object.is(path?.valueOf(), -0)) {\n        path = '-0';\n      } else {\n        path = String(path);\n      }\n\n      if (isUnsafeProperty(path)) {\n        return defaultValue;\n      }\n\n      const result = object[path];\n\n      if (result === undefined) {\n        return defaultValue;\n      }\n\n      return result;\n    }\n  }\n}\n\nfunction getWithPath(\n  object: any,\n  path: readonly PropertyKey[],\n  defaultValue?: any,\n): any {\n  if (path.length === 0) {\n    return defaultValue;\n  }\n\n  let current = object;\n\n  for (let index = 0; index < path.length; index++) {\n    if (current == null) {\n      return defaultValue;\n    }\n\n    if (isUnsafeProperty(path[index])) {\n      return defaultValue;\n    }\n\n    current = current[path[index]];\n  }\n\n  if (current === undefined) {\n    return defaultValue;\n  }\n\n  return current;\n}\n","import { isObject } from '@/is';\n\n/**\n * Returns true when provided keys exists in target object\n *\n * @example\n * const user = { id: 1, name: 'Andrew' };\n *\n * has(user, ['roles']); // false\n * has(user, ['roles', 'name']); // false\n * has(user, ['name']); // true\n *\n * @group Object\n */\nexport function has<T extends PropertyKey>(\n  value: any,\n  keys: T[],\n): value is { [K in T]: any } {\n  if (!isObject(value)) return false;\n\n  for (let idx = 0; idx < keys.length; idx++) {\n    const element = keys[idx];\n\n    if (!(element in value)) return false;\n  }\n\n  return true;\n}\n","/**\n * Check if object has own property\n *\n * @group Object\n */\nexport const hasOwn = <T extends object, K extends keyof T>(\n  val: T,\n  key: K,\n): key is K => Object.prototype.hasOwnProperty.call(val, key);\n","import { isObject } from '@/is';\n\n/**\n * Creates a new object with specified keys omitted.\n *\n * This function takes an object and an array of keys, and returns a new object that\n * excludes the properties corresponding to the specified keys.\n *\n * @template T - The type of object.\n * @template K - The type of keys in object.\n * @param {T} obj - The object to omit keys from.\n * @param {K[]} keys - An array of keys to be omitted from the object.\n * @returns {Omit<T, K>} A new object with the specified keys omitted.\n *\n * @example\n * const obj = { a: 1, b: 2, c: 3 };\n * const result = omit(obj, ['b', 'c']);\n * // result will be { a: 1 }\n *\n * @group Object\n */\nexport function omit<T extends Record<string, any>, U extends keyof T>(\n  obj: T,\n  excludes: Readonly<Array<U> | Set<U> | Array<string> | Set<string>>,\n): Omit<T, U> {\n  const excludesSet = Array.isArray(excludes)\n    ? new Set(excludes)\n    : excludes instanceof Set\n      ? excludes\n      : undefined;\n\n  if (!excludesSet) {\n    return obj;\n  }\n\n  const result: any = {};\n\n  if (!isObject(obj)) {\n    return result;\n  }\n\n  for (const [key, value] of Object.entries(obj)) {\n    if (excludesSet.has(key)) continue;\n\n    result[key] = value;\n  }\n\n  return result;\n}\n","/**\n * Pick object keys with excluding prefix keys\n *\n * @example\n * const record = {\n *   id: 1,\n *   canRead: true,\n *   canWrite: true,\n * };\n *\n * omitPrefixed(record, 'can'); // { id: 1 }\n *\n * @group Object\n */\nexport function omitPrefixed(\n  obj: Record<string, unknown>,\n  prefix: string,\n): Record<string, unknown> {\n  const result: Record<string, unknown> = {};\n\n  for (const [key, value] of Object.entries(obj)) {\n    if (key.startsWith(prefix)) continue;\n    result[key] = value;\n  }\n\n  return result;\n}\n","import { isObject } from '@/is';\nimport { hasOwn } from '../hasOwn';\n\n/**\n * Creates a new object composed of the picked object properties.\n *\n * This function takes an object and an array of keys, and returns a new object that\n * includes only the properties corresponding to the specified keys.\n *\n * @template T - The type of object.\n * @template K - The type of keys in object.\n * @param {T} obj - The object to pick keys from.\n * @param {K[]} keys - An array of keys to be picked from the object.\n * @returns {Pick<T, K>} A new object with the specified keys picked.\n *\n * @example\n * const obj = { a: 1, b: 2, c: 3 };\n * const result = pick(obj, ['a', 'c']);\n * // result will be { a: 1, c: 3 }\n *\n * @group Object\n */\nexport function pick<T extends Record<string, any>, U extends keyof T>(\n  obj: T | null | undefined,\n  keys: Readonly<Array<U> | Set<U> | Array<string> | Set<string>>,\n): Pick<T, U> {\n  const keysSet = Array.isArray(keys)\n    ? new Set(keys)\n    : keys instanceof Set\n      ? keys\n      : undefined;\n\n  const result: any = {};\n\n  if (!keysSet || !isObject(obj)) {\n    return result;\n  }\n\n  for (const key of keysSet.values()) {\n    if (hasOwn(obj, key)) {\n      result[key] = (obj as any)[key];\n    }\n  }\n\n  return result;\n}\n","interface PrefixedValuesOptions {\n  /**\n   * Key prefix\n   */\n  prefix: string;\n\n  /**\n   * Remove prefix from resulted object\n   * @default false\n   */\n  prefixTrim?: boolean;\n}\n\n/**\n * Pick prefixed keys in target object\n *\n * @example\n * const record = {\n *   id: 1,\n *   canRead: true,\n *   canWrite: true,\n * };\n *\n *  // { canRead: true, canWrite: true }\n * pickPrefixed(record, 'can');\n *\n * // { Read: true, Write: true }\n * pickPrefixed(record, { prefix: 'can', prefixTrim: true });\n *\n * @group Object\n */\nexport function pickPrefixed(\n  obj: object,\n  options: PrefixedValuesOptions | string,\n) {\n  let prefix;\n  let prefixTrim = false;\n\n  if (typeof options === 'string') {\n    prefix = options;\n  } else {\n    prefix = options.prefix;\n    prefixTrim = options.prefixTrim === true;\n  }\n\n  const result = {};\n\n  for (let [key, value] of Object.entries(obj)) {\n    if (!key.startsWith(prefix!)) continue;\n    if (prefixTrim) key = key.substring(prefix!.length);\n\n    // @ts-expect-error\n    result[key] = value;\n  }\n\n  return result;\n}\n","import { isObject, isString } from '@/is';\nimport { isDeepKey, isIndex, toKey, toPath } from '@/str';\nimport { isUnsafeProperty } from '@/str/isUnsafeProperty';\nimport type { Arrayable } from '@/types';\nimport { get } from '../get';\n\n/**\n * Updates the value at the specified path of the given object using an updater function and a customizer.\n * If any part of the path does not exist, it will be created.\n *\n * @template T - The type of the object.\n * @param object - The object to modify.\n * @param path - The path of the property to update.\n * @param updater - The function to produce the updated value.\n * @param customizer - The function to customize the update process.\n * @returns The modified object.\n *\n * @example\n * const object = { 'a': [{ 'b': { 'c': 3 } }] };\n * updateWith(object, 'a[0].b.c', (n) => n * n);\n * // => { 'a': [{ 'b': { 'c': 9 } }] }\n *\n * @group Object\n */\nexport function updateWith<T extends object>(\n  object: T,\n  path: Arrayable<PropertyKey>,\n  updater: (oldValue: any) => any,\n  customizer?: (value: any, key: string, object: T) => any,\n): T;\n\n/**\n * Updates the value at the specified path of the given object using an updater function and a customizer.\n * If any part of the path does not exist, it will be created.\n *\n * @template T - The type of the object.\n * @template R - The type of the return value.\n * @param object - The object to modify.\n * @param path - The path of the property to update.\n * @param updater - The function to produce the updated value.\n * @param customizer - The function to customize the update process.\n * @returns The modified object.\n *\n * @example\n * const object = { 'a': [{ 'b': { 'c': 3 } }] };\n * updateWith(object, 'a[0].b.c', (n) => n * n);\n * // => { 'a': [{ 'b': { 'c': 9 } }] }\n *\n * @group Object\n */\nexport function updateWith<T extends object, R>(\n  object: T,\n  path: Arrayable<PropertyKey>,\n  updater: (oldValue: any) => any,\n  customizer?: (value: any, key: string, object: T) => any,\n): R;\n\n/**\n * Updates the value at the specified path of the given object using an updater function and a customizer.\n * If any part of the path does not exist, it will be created.\n *\n * @template T - The type of the object.\n * @template R - The type of the return value.\n * @param obj - The object to modify.\n * @param path - The path of the property to update.\n * @param updater - The function to produce the updated value.\n * @param customizer - The function to customize the update process.\n * @returns The modified object.\n *\n * @example\n * const object = { 'a': [{ 'b': { 'c': 3 } }] };\n * updateWith(object, 'a[0].b.c', (n) => n * n);\n * // => { 'a': [{ 'b': { 'c': 9 } }] }\n *\n * @group Object\n */\nexport function updateWith<T extends object, R>(\n  obj: T,\n  path: Arrayable<PropertyKey>,\n  updater: (value: any) => any,\n  customizer?: (value: any, key: string, object: T) => any,\n): T | R {\n  if (obj == null && !isObject(obj)) {\n    return obj;\n  }\n\n  let resolvedPath: PropertyKey[];\n  if (\n    isString(path) &&\n    (!isDeepKey(path) || (obj != null && Object.hasOwn(obj, path)))\n  ) {\n    resolvedPath = [path];\n  } else if (Array.isArray(path)) {\n    resolvedPath = path;\n  } else {\n    resolvedPath = toPath(path);\n  }\n\n  const updateValue = updater(get(obj, resolvedPath));\n\n  let current: any = obj;\n\n  for (let i = 0; i < resolvedPath.length && current != null; i++) {\n    const key = toKey(resolvedPath[i]);\n\n    if (isUnsafeProperty(key)) {\n      continue;\n    }\n\n    let newValue: unknown;\n\n    if (i === resolvedPath.length - 1) {\n      newValue = updateValue;\n    } else {\n      const objValue = current[key];\n      const customizerResult = customizer?.(objValue, key as string, obj);\n      newValue =\n        customizerResult !== undefined\n          ? customizerResult\n          : objValue !== null &&\n              (typeof objValue === 'object' || typeof objValue === 'function')\n            ? objValue\n            : isIndex(resolvedPath[i + 1])\n              ? []\n              : {};\n    }\n\n    assignValue(current, key, newValue);\n    current = current[key];\n  }\n\n  return obj;\n}\n\nconst assignValue = (object: any, key: PropertyKey, value: any): void => {\n  const objValue = object[key];\n  if (\n    !(Object.hasOwn(object, key) && Object.is(objValue, value)) ||\n    (value === undefined && !(key in object))\n  ) {\n    object[key] = value;\n  }\n};\n","import type { Arrayable } from '@/types/types.js';\nimport { updateWith } from '../updateWith';\n\n/**\n * Sets the value at the specified path of the given object. If any part of the path does not exist, it will be created.\n *\n * @template T - The type of the object.\n * @param object - The object to modify.\n * @param path - The path of the property to set.\n * @param value - The value to set.\n * @returns The modified object.\n *\n * @example\n * // Set a value in a nested object\n * const obj = { a: { b: { c: 3 } } };\n * set(obj, 'a.b.c', 4);\n * console.log(obj.a.b.c); // 4\n *\n * @example\n * // Set a value in an array\n * const arr = [1, 2, 3];\n * set(arr, 1, 4);\n * console.log(arr[1]); // 4\n *\n * @example\n * // Create non-existent path and set value\n * const obj = {};\n * set(obj, 'a.b.c', 4);\n * console.log(obj); // { a: { b: { c: 4 } } }\n *\n * @group Object\n */\nexport function set<T extends object>(\n  object: T,\n  path: Arrayable<PropertyKey>,\n  value: any,\n): T;\n\n/**\n * Sets the value at the specified path of the given object. If any part of the path does not exist, it will be created.\n *\n * @template R - The return type.\n * @param object - The object to modify.\n * @param path - The path of the property to set.\n * @param value - The value to set.\n * @returns The modified object.\n *\n * @example\n * // Set a value in a nested object\n * const obj = { a: { b: { c: 3 } } };\n * set(obj, 'a.b.c', 4);\n * console.log(obj.a.b.c); // 4\n *\n * @example\n * // Set a value in an array\n * const arr = [1, 2, 3];\n * set(arr, 1, 4);\n * console.log(arr[1]); // 4\n *\n * @example\n * // Create non-existent path and set value\n * const obj = {};\n * set(obj, 'a.b.c', 4);\n * console.log(obj); // { a: { b: { c: 4 } } }\n *\n * @group Object\n */\nexport function set<R>(\n  object: object,\n  path: Arrayable<PropertyKey>,\n  value: any,\n): R;\n\n/**\n * Sets the value at the specified path of the given object. If any part of the path does not exist, it will be created.\n *\n * @template T - The type of the object.\n * @param obj - The object to modify.\n * @param path - The path of the property to set.\n * @param value - The value to set.\n * @returns The modified object.\n *\n * @example\n * // Set a value in a nested object\n * const obj = { a: { b: { c: 3 } } };\n * set(obj, 'a.b.c', 4);\n * console.log(obj.a.b.c); // 4\n *\n * @example\n * // Set a value in an array\n * const arr = [1, 2, 3];\n * set(arr, 1, 4);\n * console.log(arr[1]); // 4\n *\n * @example\n * // Create non-existent path and set value\n * const obj = {};\n * set(obj, 'a.b.c', 4);\n * console.log(obj); // { a: { b: { c: 4 } } }\n *\n * @group Object\n */\nexport function set<T extends object>(\n  obj: T,\n  path: Arrayable<PropertyKey>,\n  value: any,\n): T {\n  return updateWith(\n    obj,\n    path,\n    () => value,\n    () => undefined,\n  );\n}\n","/**\n * Converts object into Map\n *\n * @example\n * const map = toMap({ user1: 'Andrew', user2: 'John' });\n *\n * map.get('user2'); // John\n *\n * @group Object\n */\nexport const toMap = <T extends object>(obj: T): Map<keyof T, T[keyof T]> => {\n  const map = new Map<any, any>(Object.entries(obj));\n\n  for (const symbol of Object.getOwnPropertySymbols(obj)) {\n    map.set(symbol, (obj as any)[symbol]);\n  }\n\n  return map;\n};\n","import { isObject } from '@/is';\n\nconst badKeys = Object.freeze(\n  new Set(['constructor', '__proto__', 'prototype']),\n);\n\n/**\n * Converts a flattened object back into a nested structure.\n *\n * Takes an object with dot-separated keys and converts it into a nested object,\n * where each dot-separated part of the key represents a deeper level in the object.\n *\n * @param {Object} obj - The object to unflatten.\n * @param {string} [separator='_'] - The separator used to split the keys into their nested form. Defaults to '_'.\n * @returns {Object} The unflattened object, with nested keys restored to their original structure.\n *\n * @example\n * const obj = {\n *   'name': 'Andrew',\n *   'config_canReadPost': true,\n *   'config_canUpdatePost': true,\n * };\n *\n * unflatten(obj);\n * // Returns:\n * // {\n * //   name: 'Andrew',\n * //   config: {\n * //     canReadPost: true,\n * //     canUpdatePost: true\n * //   },\n * // }\n *\n * @example\n * const flattenedObj = {\n *   'user.firstName': 'John',\n *   'user.lastName': 'Doe',\n *   'address.city': 'New York'\n * };\n *\n * unflatten(flattenedObj, '.');\n * // Returns:\n * // {\n * //   user: {\n * //     firstName: 'John',\n * //     lastName: 'Doe'\n * //   },\n * //   address: {\n * //     city: 'New York'\n * //   }\n * // }\n *\n * @group Object\n * @author lukeed\n */\nexport function unflatten(input: object, separator = '_') {\n  if (!isObject(input)) {\n    return {};\n  }\n\n  let arr, tmp: any, output;\n  let i = 0,\n    k,\n    key;\n\n  for (k in input) {\n    tmp = output;\n    arr = k.split(separator);\n\n    for (i = 0; i < arr.length; ) {\n      key = arr[i++];\n\n      if (tmp == null) {\n        tmp = empty(+key);\n        output = output || tmp;\n      }\n\n      if (badKeys.has(key)) break;\n\n      if (i < arr.length) {\n        if (key in tmp) {\n          tmp = tmp[key];\n        } else {\n          tmp = tmp[key] = empty(+arr[i]);\n        }\n      } else {\n        tmp[key] = (input as any)[k];\n      }\n    }\n  }\n\n  return output;\n}\n\nfunction empty(key: unknown): any {\n  return key === key ? [] : {};\n}\n","import { isDeepKey, toKey, toPath } from '@/str';\nimport { isUnsafeProperty } from '@/str/isUnsafeProperty';\nimport type { Arrayable } from '@/types';\nimport { get } from '../get';\n\n/**\n * Removes the property at the given path of the object.\n *\n * @param obj - The object to modify.\n * @param path - The path of the property to unset.\n * @returns Returns true if the property is deleted, else false.\n *\n * @example\n * const obj = { a: { b: { c: 42 } } };\n * unset(obj, 'a.b.c'); // true\n * console.log(obj); // { a: { b: {} } }\n *\n * @example\n * const obj = { a: { b: { c: 42 } } };\n * unset(obj, ['a', 'b', 'c']); // true\n * console.log(obj); // { a: { b: {} } }\n *\n * @group Object\n */\nexport function unset(obj: any, path: Arrayable<PropertyKey>): boolean {\n  if (obj == null) {\n    return true;\n  }\n\n  switch (typeof path) {\n    case 'symbol':\n    case 'number':\n    case 'object': {\n      if (Array.isArray(path)) {\n        return unsetWithPath(obj, path);\n      }\n\n      if (typeof path === 'number') {\n        path = toKey(path);\n      } else if (typeof path === 'object') {\n        if (Object.is((path as any)?.valueOf(), -0)) {\n          path = '-0';\n        } else {\n          path = String(path);\n        }\n      }\n\n      if (isUnsafeProperty(path as PropertyKey)) {\n        return false;\n      }\n\n      if (obj?.[path as PropertyKey] === undefined) {\n        return true;\n      }\n\n      try {\n        delete obj[path as PropertyKey];\n        return true;\n      } catch {\n        return false;\n      }\n    }\n    case 'string': {\n      if (\n        obj?.[path] === undefined &&\n        isDeepKey(path) &&\n        !Object.hasOwn(obj, path)\n      ) {\n        return unsetWithPath(obj, toPath(path));\n      }\n\n      if (isUnsafeProperty(path)) {\n        return false;\n      }\n\n      try {\n        delete obj[path];\n        return true;\n      } catch {\n        return false;\n      }\n    }\n  }\n}\n\nfunction unsetWithPath(obj: unknown, path: readonly PropertyKey[]): boolean {\n  const parent = path.length === 1 ? obj : get(obj, path.slice(0, -1));\n  const lastKey = path[path.length - 1];\n\n  if (parent?.[lastKey] === undefined) {\n    return true;\n  }\n\n  if (isUnsafeProperty(lastKey)) {\n    return false;\n  }\n\n  try {\n    delete parent[lastKey];\n    return true;\n  } catch {\n    return false;\n  }\n}\n","import { def } from '@/object';\n\n/**\n * Function that compares two elements and returns a number indicating their relative order.\n * - Negative number if a < b\n * - Zero if a equals b\n * - Positive number if a > b\n *\n * @template T The type of elements in the array\n */\nexport type SortedArrayCompareFn<T> = (a: T, b: T) => number;\n\nconst SYM_COMPARE_FN = Symbol('SYM_COMPARE_FN');\n\n/**\n * A self-sorting array that maintains elements in a sorted order based on a comparison function.\n * All mutating operations preserve the sorted order of elements.\n *\n * @template T The type of elements in the array\n *\n * @example\n * // Create a numerically sorted array\n * const arr = new SortedArray((a, b) => a - b);\n * arr.push(3, 2, 1);\n * console.log(arr); // [1, 2, 3]\n *\n * @example\n * // Create a sorted array with initial values\n * const names = new SortedArray((a, b) => a.localeCompare(b), [\"Charlie\", \"Alice\", \"Bob\"]);\n * console.log(names); // [\"Alice\", \"Bob\", \"Charlie\"]\n *\n * @example\n * // Create a sorted array with a custom comparator\n * const people = new SortedArray(\n *   (a, b) => a.age - b.age || a.name.localeCompare(b.name),\n *   [{ name: \"Alice\", age: 30 }, { name: \"Bob\", age: 25 }]\n * );\n *\n * @group Array\n */\nexport class SortedArray<T> extends Array<T> {\n  // @ts-expect-error\n  private [SYM_COMPARE_FN]: SortedArrayCompareFn<T>;\n\n  /**\n   * Creates a new SortedArray instance.\n   *\n   * @param compareFn The comparison function to determine the sort order\n   * @param items Optional initial items to add to the array (will be sorted immediately)\n   */\n  constructor(compareFn: SortedArrayCompareFn<T>, items: T[] = []) {\n    super();\n\n    def(this, SYM_COMPARE_FN, compareFn);\n\n    // Add initial items in sorted order if provided\n    if (items.length > 0) {\n      super.push.apply(this, items.toSorted(compareFn));\n    }\n  }\n\n  /**\n   * Inserts multiple items while maintaining sort order\n   * @param items The items to insert\n   * @returns The new length of the array\n   */\n  push(...items: T[]): number {\n    // For large batches, first sort the new items\n    var newItems = items.toSorted(this[SYM_COMPARE_FN]);\n    var newItemsLen = newItems.length;\n    var originalLen = this.length;\n\n    // Calculate final array size and prepare space\n    var result = new Array<T>(originalLen + newItemsLen);\n\n    // Merge the two sorted arrays with minimal comparisons\n    var i = 0,\n      j = 0,\n      k = 0;\n\n    // Main merge loop - stops when either array is exhausted\n    while (i < originalLen && j < newItemsLen) {\n      if (this[SYM_COMPARE_FN](this[i], newItems[j]) <= 0) {\n        result[k++] = this[i++];\n      } else {\n        result[k++] = newItems[j++];\n      }\n    }\n\n    // Copy remaining elements (only one of these loops will execute)\n    while (i < originalLen) {\n      result[k++] = this[i++];\n    }\n\n    while (j < newItemsLen) {\n      result[k++] = newItems[j++];\n    }\n\n    // Fastest way to replace content: clear and use super.push with spread\n    this.length = 0;\n    super.push.apply(this, result);\n\n    return this.length;\n  }\n\n  /**\n   * Override Array methods that would break the sorted order\n   */\n  unshift(...items: T[]): number {\n    return this.push(...items);\n  }\n\n  /**\n   * Creates a new SortedArray with the same comparison function\n   * @returns A new SortedArray instance\n   */\n  slice(start?: number, end?: number): SortedArray<T> {\n    var result = new SortedArray<T>(this[SYM_COMPARE_FN]);\n    var sliced = super.slice(start, end);\n    super.push.apply(result, sliced);\n    return result;\n  }\n\n  /**\n   * Concatenates arrays or values while maintaining sort order\n   * @param items Arrays or values to concatenate\n   * @returns A new SortedArray with the concatenated elements\n   */\n  concat(...items: (T | ConcatArray<T>)[]): SortedArray<T> {\n    var result = new SortedArray<T>(this[SYM_COMPARE_FN], this);\n\n    for (const item of items) {\n      if (Array.isArray(item)) {\n        result.push.apply(result, item);\n      } else {\n        result.push(item as T);\n      }\n    }\n\n    return result;\n  }\n}\n\n// Wrap original array methods to return regular array instead of sorted array\n['map', 'filter', 'flatMap', 'flat', 'reverse', 'sort'].forEach((key: any) => {\n  SortedArray.prototype[key] = function () {\n    const arr = Array.prototype[key].apply(this, arguments);\n    Object.setPrototypeOf(arr, Array.prototype);\n    return arr;\n  };\n});\n","import { isNumber } from '@/is';\n\n/**\n * Sums the values in an array of numbers, ignoring non-numeric values.\n *\n * This function adds all valid numbers in the array and returns the sum.\n * Non-numeric values (e.g., `null`, `undefined`, `NaN` are ignored in the sum.\n *\n * @example\n * sum([2, 2]); // 4\n * sum([1, 'a', 3, 4]); // 8 (non-numeric 'a' is ignored)\n * sum([5, null, 10]); // 15 (null is ignored)\n * sum([]); // 0 (empty array returns 0)\n *\n * @param values The array of numbers to be summed.\n * @returns The sum of the numbers in the array.\n *\n * @group Array\n */\nexport const sum = (values: readonly number[]) => {\n  return values.reduce((a, b) => a + (isNumber(b) ? b : 0), 0);\n};\n","/**\n * Returns a new array with duplicates removed.\n *\n * This function creates a new array that contains only unique values,\n * preserving the order of the original elements.\n *\n * @example\n * uniq([1, 2, 3, 4, 1, 3]); // [1, 2, 3, 4]\n * uniq([5, 5, 5, 5, 5]); // [5]\n * uniq(['a', 'b', 'a', 'c']); // ['a', 'b', 'c']\n * uniq([]); // [] (returns an empty array for empty input)\n *\n * @param value The array from which duplicates will be removed.\n * @returns A new array containing only the unique values from the input array.\n *\n * @group Array\n */\nexport function uniq<T>(value: readonly T[]): T[] {\n  if (!Array.isArray(value)) {\n    return [] as any;\n  }\n\n  return [...new Set(value)];\n}\n","import { uniq } from '../uniq';\n\n/**\n * Creates an array of unique values from all given arrays.\n *\n * This function takes two arrays, merges them into a single array, and returns a new array\n * containing only the unique values from the merged array.\n *\n * @template T - The type of elements in the array.\n * @param {T[]} arr1 - The first array to merge and filter for unique values.\n * @param {T[]} arr2 - The second array to merge and filter for unique values.\n * @returns {T[]} A new array of unique values.\n *\n * @example\n * const array1 = [1, 2, 3];\n * const array2 = [3, 4, 5];\n * const result = union(array1, array2);\n * // result will be [1, 2, 3, 4, 5]\n *\n * @group Array\n */\nexport function union<T>(...arrays: (readonly T[])[]): T[] {\n  if (arrays.length === 0) return [];\n  if (arrays.length === 1) return [...arrays[0]];\n\n  const [first, ...rest] = arrays;\n  return uniq(first.concat(...rest));\n}\n","import { isFunction } from '@/is';\nimport { get } from '@/object/get';\n\n/**\n * Extracts unique elements from an array based on a comparator function or property key.\n *\n * This function allows you to determine uniqueness based on custom criteria by passing\n * a comparator function or a property key. The function will return a new array containing\n * only the first occurrence of elements that are unique according to the specified comparator.\n * If the comparator is a property key, uniqueness will be determined based on the value\n * of that property.\n *\n * @example\n * const users = [\n *     { id: 1, role: 'admin' },\n *     { id: 2, role: 'admin' },\n *     { id: 3, role: 'user' },\n *     { id: 4, role: 'user' },\n * ];\n *\n * const uniqRoles = uniqBy(users, (v) => v.role);\n * // [\n * //     { id: 1, role: 'admin' },\n * //     { id: 3, role: 'user' },\n * // ]\n *\n * @example\n * const products = [\n *     { id: 1, category: 'electronics', name: 'Phone' },\n *     { id: 2, category: 'electronics', name: 'Laptop' },\n *     { id: 3, category: 'furniture', name: 'Sofa' },\n * ];\n *\n * const uniqCategories = uniqBy(products, 'category');\n * // [\n * //     { id: 1, category: 'electronics', name: 'Phone' },\n * //     { id: 3, category: 'furniture', name: 'Sofa' },\n * // ]\n *\n * @param array The array to extract unique elements from.\n * @param comparator A function that computes the value to determine uniqueness or a property key.\n *                  If a string is passed, it is treated as a property key, and uniqueness is\n *                  determined based on the value of that property.\n * @returns A new array containing only the first occurrence of each unique element based on the comparator.\n *\n * @group Array\n */\nexport function uniqBy<T>(\n  array: readonly T[],\n  comparator: ((value: T) => any) | PropertyKey,\n): T[] {\n  const seen = new Set();\n\n  if (!isFunction(comparator)) {\n    const key = comparator;\n    comparator = value => get(value, key);\n  }\n\n  return array.filter(value => {\n    const computed = (comparator as any)(value);\n    const hasSeen = seen.has(computed);\n    if (!hasSeen) {\n      seen.add(computed);\n    }\n    return !hasSeen;\n  });\n}\n","/**\n * @group Errors\n */\nexport class AssertionError extends Error {\n  /**\n   * Set to the `actual` argument for methods such as {@link assert.strictEqual()}.\n   */\n  actual: unknown;\n  /**\n   * Set to the `expected` argument for methods such as {@link assert.strictEqual()}.\n   */\n  expected: unknown;\n  /**\n   * Set to the passed in operator value.\n   */\n  operator: string;\n  /**\n   * Indicates if the message was auto-generated (`true`) or not.\n   */\n  generatedMessage: boolean;\n  /**\n   * Value is always `ERR_ASSERTION` to show that the error is an assertion error.\n   */\n  code: 'ERR_ASSERTION';\n\n  constructor(options?: {\n    /** If provided, the error message is set to this value. */\n    message?: string | undefined;\n    /** The `actual` property on the error instance. */\n    actual?: unknown | undefined;\n    /** The `expected` property on the error instance. */\n    expected?: unknown | undefined;\n    /** The `operator` property on the error instance. */\n    operator?: string | undefined;\n    /** If provided, the generated stack trace omits frames before this function. */\n    stackStartFn?: Function | undefined;\n  }) {\n    super(options?.message);\n    this.actual = options?.actual;\n    this.expected = options?.expected;\n    this.operator = options?.operator ?? 'none';\n    this.generatedMessage = false;\n    this.code = 'ERR_ASSERTION';\n  }\n}\n","/**\n * Creates a new function that always returns `value`.\n *\n * @template T - The type of the value to return.\n * @param value - The value to return from the new function.\n * @returns Returns the new constant function.\n *\n * @group Utility Functions\n */\nexport function constant<T>(value: T): () => T;\n\n/**\n * Creates a new function that always returns `undefined`.\n *\n * @returns Returns the new constant function.\n *\n * @group Utility Functions\n */\nexport function constant(): () => undefined;\n\n/**\n * Creates a new function that always returns `value`.\n *\n * @template T - The type of the value to return.\n * @param value - The value to return from the new function.\n * @returns Returns the new constant function.\n *\n * @example\n * const object = { a: 1 };\n * const returnsObject = constant(object);\n *\n * returnsObject(); // => { a: 1 }\n * returnsObject() === object; // => true\n *\n * @group Utility Functions\n */\nexport function constant<T>(value?: T): () => T | undefined {\n  return () => value;\n}\n","import { isError } from './is.js';\n\n/**\n * Transform value to error object\n * @group Errors\n */\nexport function toError<T>(\n  value: T,\n  unknownMessage = 'Unknown error',\n): T extends Error ? T : Error {\n  if (isError(value)) {\n    return value as any;\n  }\n\n  const error = new Error(unknownMessage, { cause: value });\n\n  Error.captureStackTrace(error, toError);\n\n  return error as any;\n}\n","import { toError } from '@/toError';\nimport type { AnyFunction } from '@/types';\n\nexport type WithCode<T extends AnyFunction> = T & { code: string };\n\nexport function createFunction<T extends AnyFunction>(\n  fnName: string,\n  code: string,\n  ...args: any[]\n): WithCode<T> {\n  try {\n    const fn = new Function(...args, code) as WithCode<T>;\n    fn.code = code;\n    return fn;\n  } catch (err) {\n    throw new Error(\n      `failed to create bitPack.${fnName}()\\nError: ${toError(err).message}\\n-- CODE START --\\n${code}\\n-- CODE END--`,\n    );\n  }\n}\n","interface DebounceOptions {\n  /**\n   * An optional AbortSignal to cancel the debounced function.\n   */\n  signal?: AbortSignal;\n\n  /**\n   * An optional array specifying whether the function should be invoked on the leading edge, trailing edge, or both.\n   * If `edges` includes \"leading\", the function will be invoked at the start of the delay period.\n   * If `edges` includes \"trailing\", the function will be invoked at the end of the delay period.\n   * If both \"leading\" and \"trailing\" are included, the function will be invoked at both the start and end of the delay period.\n   * @default [\"trailing\"]\n   */\n  edges?: Array<'leading' | 'trailing'>;\n}\n\nexport interface DebouncedFunction<F extends (...args: any[]) => void> {\n  (...args: Parameters<F>): void;\n\n  /**\n   * Schedules the execution of the debounced function after the specified debounce delay.\n   * This method resets any existing timer, ensuring that the function is only invoked\n   * after the delay has elapsed since the last call to the debounced function.\n   * It is typically called internally whenever the debounced function is invoked.\n   *\n   * @returns {void}\n   */\n  schedule: () => void;\n\n  /**\n   * Cancels any pending execution of the debounced function.\n   * This method clears the active timer and resets any stored context or arguments.\n   */\n  cancel: () => void;\n\n  /**\n   * Immediately invokes the debounced function if there is a pending execution.\n   * This method also cancels the current timer, ensuring that the function executes right away.\n   */\n  flush: () => void;\n}\n\n/**\n * Creates a debounced function that delays invoking the provided function until after `debounceMs` milliseconds\n * have elapsed since the last time the debounced function was invoked. The debounced function also has a `cancel`\n * method to cancel any pending execution.\n *\n * @template F - The type of function.\n * @param {F} func - The function to debounce.\n * @param {number} debounceMs - The number of milliseconds to delay.\n * @param {DebounceOptions} options - The options object\n * @param {AbortSignal} options.signal - An optional AbortSignal to cancel the debounced function.\n * @returns A new debounced function with a `cancel` method.\n *\n * @example\n * const debouncedFunction = debounce(() => {\n *   console.log('Function executed');\n * }, 1000);\n *\n * // Will log 'Function executed' after 1 second if not called again in that time\n * debouncedFunction();\n *\n * // Will not log anything as the previous call is canceled\n * debouncedFunction.cancel();\n *\n * // With AbortSignal\n * const controller = new AbortController();\n * const signal = controller.signal;\n * const debouncedWithSignal = debounce(() => {\n *  console.log('Function executed');\n * }, 1000, { signal });\n *\n * debouncedWithSignal();\n *\n * // Will cancel the debounced function call\n * controller.abort();\n *\n * @author es-toolkit\n * @group Utility Functions\n */\nexport function debounce<F extends (...args: any[]) => void>(\n  func: F,\n  debounceMs: number,\n  { signal, edges }: DebounceOptions = {},\n): DebouncedFunction<F> {\n  let pendingThis: any = undefined;\n  let pendingArgs: Parameters<F> | null = null;\n\n  const leading = edges != null && edges.includes('leading');\n  const trailing = edges == null || edges.includes('trailing');\n\n  const invoke = () => {\n    if (pendingArgs !== null) {\n      func.apply(pendingThis, pendingArgs);\n      pendingThis = undefined;\n      pendingArgs = null;\n    }\n  };\n\n  const onTimerEnd = () => {\n    if (trailing) {\n      invoke();\n    }\n\n    cancel();\n  };\n\n  let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n  const schedule = () => {\n    if (timeoutId != null) {\n      clearTimeout(timeoutId);\n    }\n\n    timeoutId = setTimeout(() => {\n      timeoutId = null;\n\n      onTimerEnd();\n    }, debounceMs);\n  };\n\n  const cancelTimer = () => {\n    if (timeoutId !== null) {\n      clearTimeout(timeoutId);\n      timeoutId = null;\n    }\n  };\n\n  const cancel = () => {\n    cancelTimer();\n    pendingThis = undefined;\n    pendingArgs = null;\n  };\n\n  const flush = () => {\n    cancelTimer();\n    invoke();\n  };\n\n  const debounced = function (this: any, ...args: Parameters<F>) {\n    if (signal?.aborted) {\n      return;\n    }\n\n    pendingThis = this;\n    pendingArgs = args;\n\n    const isFirstCall = timeoutId == null;\n\n    schedule();\n\n    if (leading && isFirstCall) {\n      invoke();\n    }\n  };\n\n  debounced.schedule = schedule;\n  debounced.cancel = cancel;\n  debounced.flush = flush;\n\n  signal?.addEventListener('abort', cancel, { once: true });\n\n  return debounced;\n}\n","import { isObject, isString } from '@/is';\nimport type {\n  ExecResult,\n  ExecResultToSkip,\n  ExecResultToSuccess,\n} from '../types';\n\n/**\n * @group Utility Functions\n */\nexport function isSuccess<T>(\n  value: T,\n  // @ts-expect-error\n): value is ExecResultToSuccess<T> {\n  return (\n    isObject(value) &&\n    'success' in value &&\n    'code' in value &&\n    value.success === true &&\n    isString(value.code) &&\n    (!('reason' in value) || isString(value.reason))\n  );\n}\n\n/**\n * @group Utility Functions\n */\nexport function isSkip<T>(\n  value: T,\n  // @ts-expect-error\n): value is ExecResultToSkip<T> {\n  return (\n    isObject(value) &&\n    'skip' in value &&\n    'code' in value &&\n    value.skip === true &&\n    isString(value.code) &&\n    (!('reason' in value) || isString(value.reason))\n  );\n}\n\n/**\n * @group Utility Functions\n */\nexport function stringifyExecResult(value: ExecResult) {\n  if (value.success) {\n    return `ExecSuccess(code=${value.code}, reason=\"${value.reason || 'no reason'}\")`;\n  }\n\n  return `ExecSkip(code=${value.code}, reason=\"${value.reason || 'no reason'}\")`;\n}\n","/**\n * Returns the input value unchanged.\n *\n * @template T - The type of the input value.\n * @param x - The value to be returned.\n * @returns The input value.\n *\n * @example\n * // Returns 5\n * identity(5);\n *\n * @example\n * // Returns 'hello'\n * identity('hello');\n *\n * @example\n * // Returns { key: 'value' }\n * identity({ key: 'value' });\n *\n * @group Utility Functions\n */\nexport function identity<T>(x: T): T {\n  return x;\n}\n","/**\n * Creates a function that negates the result of the predicate function.\n *\n * @template F - The type of the function to negate.\n * @param func - The function to negate.\n * @returns The new negated function, which negates the boolean result of `func`.\n *\n * @example\n * const array = [1, 2, 3, 4, 5, 6];\n * const isEven = (n: number) => n % 2 === 0;\n * const result = array.filter(negate(isEven));\n * // result will be [1, 3, 5]\n *\n * @group Utility Functions\n */\nexport function negate<F extends (...args: any[]) => boolean>(func: F): F {\n  return function (this: unknown, ...args: any[]) {\n    return !func.apply(this, args);\n  } as F;\n}\n","import { isDate, isFunction, isNumber } from '@/is';\nimport {\n  arrayTag,\n  bigintTag,\n  booleanTag,\n  dateTag,\n  functionTag,\n  getTag,\n  mapTag,\n  nullTag,\n  numberTag,\n  objectTag,\n  setTag,\n  stringTag,\n  symbolTag,\n  undefinedTag,\n  weakmapTag,\n  weaksetTag,\n} from '@/object/getTag';\nimport type { AnyFunction } from '../../types';\n\nexport type TypeOf = keyof TypeOfMap;\n\nexport type TypeOfMap = {\n  null: null;\n  undefined: undefined;\n  object: Record<PropertyKey, any>;\n  string: string;\n  number: number;\n  function: AnyFunction;\n  bigint: bigint;\n  boolean: boolean;\n  symbol: symbol;\n  date: Date;\n  array: any[];\n  map: Map<any, any>;\n  weakmap: WeakMap<WeakKey, any>;\n  set: Set<any>;\n  weakset: WeakSet<WeakKey>;\n  unknown: unknown;\n};\n\nvar tagToType: Record<string, TypeOf | ((value: unknown) => TypeOf)> = {\n  [nullTag]: 'null',\n  [undefinedTag]: 'undefined',\n  [stringTag]: 'string',\n  [functionTag]: 'function',\n  [arrayTag]: 'array',\n  [setTag]: 'set',\n  [mapTag]: 'map',\n  [dateTag]: v => (isDate(v) ? 'date' : 'unknown'),\n  [objectTag]: 'object',\n  [symbolTag]: 'symbol',\n  [bigintTag]: 'bigint',\n  [booleanTag]: 'boolean',\n  [weakmapTag]: 'weakmap',\n  [weaksetTag]: 'weakset',\n  [numberTag]: v => (isNumber(v) ? 'number' : 'unknown'),\n};\n\n/**\n * Typeof that you deserve\n * @group Utility Functions\n */\nexport function typeOf(value: unknown): TypeOf {\n  var typeOrGetter = tagToType[getTag(value)] || 'unknown';\n\n  if (isFunction(typeOrGetter)) {\n    return typeOrGetter(value);\n  }\n\n  return typeOrGetter;\n}\n","import {\n  isDate,\n  isEmpty,\n  isEqual,\n  isFunction,\n  isNumber,\n  isObject,\n  isString,\n} from '@/is.js';\nimport { deepAssign } from '@/object/index.js';\nimport { type TypeOf, type TypeOfMap, typeOf } from '../typeOf';\n\ntype StringifyOptions = {\n  /**\n   * Exclude empty values, checking by `isEmpty`\n   * @default true\n   */\n  excludeEmpty?: boolean;\n\n  /**\n   * Exclude values when equals with defaults\n   */\n  excludeDefaults?: Record<string, any>;\n};\n\n/**\n * Simple query stringy interface that supports encoding/decoding of `Array`, `Set`, `Map`, `Object`, `BigInt`\n *\n * @example\n * // encode\n * qs.stringify({ page: 1, limit: 10 }); // 'page=1&limit=10'\n *\n * // decode\n * const defaults = { page: 1, limit: 10 };\n * const params = qs.parse('page=5&limit=abc', defaults); // { page: 5, limit: 10 }\n *\n * @group Utility Functions\n */\nexport const qs = {\n  toParams,\n  stringify,\n  stringifyValue,\n  parse,\n  parseValue,\n  merge,\n};\n\n/**\n * Merge first level values\n */\nfunction merge(...values: Record<string, any>[]): Record<string, any> {\n  const result: Record<string, any> = {};\n\n  for (const filter of values) {\n    for (const [key, value] of Object.entries(filter)) {\n      const currentValue = result[key];\n      const currentType = typeOf(currentValue);\n      const filterType = typeOf(value);\n\n      // overwrite with new value when type mismatch\n      if (currentType !== filterType) {\n        result[key] = value;\n        continue;\n      }\n\n      switch (currentType) {\n        case 'array': {\n          result[key] = Array.from(new Set([...currentValue, ...value]));\n          break;\n        }\n\n        case 'object': {\n          result[key] = {};\n          deepAssign(result[key], currentValue);\n          deepAssign(result[key], value);\n          break;\n        }\n\n        case 'map': {\n          result[key] = new Map([\n            ...(Array.from(currentValue.entries()) as any[]),\n            ...(Array.from(value.entries()) as any[]),\n          ]);\n          break;\n        }\n\n        case 'set': {\n          result[key] = new Set([\n            ...Array.from(currentValue),\n            ...Array.from(value),\n          ]);\n          break;\n        }\n\n        default: {\n          result[key] = value;\n        }\n      }\n    }\n  }\n\n  return result;\n}\n\n/**\n * Simple function to transform object into query string (not standards)\n */\nfunction stringify(\n  obj: Record<string, any>,\n  options?: StringifyOptions,\n): string {\n  return new URLSearchParams(toParams(obj, options)).toString();\n}\n\n/**\n * Prepare search params object\n */\nfunction toParams(\n  obj: Record<string, any>,\n  options?: StringifyOptions,\n): Record<string, string> {\n  const result: Record<string, string> = {};\n  const excludeEmpty = options?.excludeEmpty !== false;\n  const excludeDefaults = options?.excludeDefaults;\n\n  for (const [key, value] of Object.entries(obj)) {\n    if (excludeEmpty && isEmpty(value)) continue;\n\n    if (excludeDefaults && key in excludeDefaults) {\n      const defValue = excludeDefaults[key];\n      if (isEqual(value, defValue)) continue;\n    }\n\n    const strValue = stringifyValue(value);\n\n    if (excludeEmpty && strValue === '') {\n      continue;\n    }\n\n    result[key] = strValue;\n  }\n\n  return result;\n}\n\n/**\n * Parse query string as is without type casting\n */\nfunction parse(value: string): Record<string, string>;\n\n/**\n * Parse query string and use default object as type cast schema\n */\nfunction parse<T extends Record<string, any>>(\n  value: string,\n  defaults: Partial<T>,\n): T;\n\n/**\n * Parse query params and use default object as type cast schema\n */\nfunction parse<T extends Record<string, any>>(\n  value: Record<string, any>,\n  defaults: T,\n): Partial<T>;\n\nfunction parse(\n  value: string | Record<string, any>,\n  defaults?: Record<string, any>,\n): any {\n  const objValue = isString(value)\n    ? Object.fromEntries(new URLSearchParams(value).entries())\n    : value;\n\n  if (!defaults) {\n    return { ...objValue };\n  }\n\n  const result: Record<string, any> = {};\n\n  for (const [key, defValue] of Object.entries(defaults)) {\n    const defType = typeOf(defValue);\n\n    let parsedValue = parseValue(objValue[key], defType);\n\n    if (parsedValue !== undefined || defType === 'undefined') {\n      if (defType === 'array' && defValue[0] !== undefined) {\n        const itemValue = typeOf(defValue[0]);\n        parsedValue = (parsedValue as any[]).map(v => parseValue(v, itemValue));\n      }\n\n      result[key] = parsedValue;\n    } else {\n      result[key] = defValue;\n    }\n  }\n\n  return result;\n}\n\n/**\n * Stringify value to use as query parameter\n */\nfunction stringifyValue(value: unknown): string {\n  const valueType = typeOf(value);\n\n  switch (valueType) {\n    case 'undefined': {\n      return '';\n    }\n\n    case 'null': {\n      return '';\n    }\n\n    case 'array': {\n      let result = '';\n      let sep = '';\n\n      for (const item of value as any[]) {\n        if (item === undefined) continue;\n\n        if (\n          isObject(item) ||\n          Array.isArray(item) ||\n          (isString(item) && item.includes(','))\n        ) {\n          result = JSON.stringify(value);\n          break;\n        } else {\n          result += sep + stringifyValue(item);\n          sep = ',';\n        }\n      }\n\n      return result;\n    }\n\n    case 'date': {\n      return (value as Date).toISOString();\n    }\n\n    case 'map': {\n      return JSON.stringify(Array.from((value as Map<any, any>).entries()));\n    }\n\n    case 'set': {\n      return JSON.stringify(Array.from((value as Set<any>).values()));\n    }\n\n    case 'boolean':\n    case 'number':\n    case 'string':\n    case 'bigint': {\n      return String(value);\n    }\n\n    case 'object': {\n      return JSON.stringify(value);\n    }\n\n    case 'unknown': {\n      if (isFunction(value?.toString)) {\n        return value.toString();\n      }\n    }\n\n    default: {\n      throw new Error('Attempt to stringify unsupported type: ' + valueType);\n    }\n  }\n}\n\n/**\n * Parse string query value as a type\n */\nfunction parseValue<T extends TypeOf>(\n  value: any,\n  asType: T,\n): TypeOfMap[T] | undefined {\n  const type = typeOf(value);\n\n  if (type === asType) {\n    return value;\n  } else if (type !== 'string') {\n    return undefined;\n  }\n\n  try {\n    switch (asType) {\n      case 'undefined': {\n        return undefined;\n      }\n\n      case 'array': {\n        if (value.startsWith('[') && value.endsWith(']')) {\n          return JSON.parse(value);\n        }\n\n        return value.split(',') as any;\n      }\n\n      case 'boolean': {\n        return (value === 'true') as any;\n      }\n\n      case 'date': {\n        const parsed = new Date(value) as any;\n        return (isDate(parsed) ? parsed : undefined) as any;\n      }\n\n      case 'map': {\n        return new Map(JSON.parse(value)) as any;\n      }\n\n      case 'number': {\n        const parsed = parseFloat(value);\n        return (isNumber(parsed) ? parsed : undefined) as any;\n      }\n\n      case 'object': {\n        return JSON.parse(value);\n      }\n\n      case 'set': {\n        return new Set(JSON.parse(value)) as any;\n      }\n\n      case 'null': {\n        return (value === '' || value === undefined ? null : undefined) as any;\n      }\n\n      case 'string': {\n        return value as any;\n      }\n\n      case 'bigint': {\n        return BigInt(value) as any;\n      }\n    }\n  } catch (_) {}\n\n  return undefined;\n}\n","import { isNumber } from '@/is';\n\n/**\n * Rounds the given value to a specified range. If the value is less than the minimum,\n * it returns the minimum. If the value is greater than the maximum, it returns the maximum.\n * If the value is within the range, it returns the original value.\n *\n * @param {number} num - The number to be clamped.\n * @param {number} min - The minimum value of the range.\n * @param {number} max - The maximum value of the range.\n * @returns {number} - The clamped value within the specified range.\n *\n * @example\n * const min = 5;\n * const max = 10;\n *\n * // Returns: 7 (within range)\n * clamp(7, min, max);\n *\n * // Returns: 10 (clamped to max)\n * clamp(15, min, max);\n *\n * // Returns: 5 (clamped to min)\n * clamp(3, min, max);\n *\n * @group Numbers\n */\nexport const clamp = (num: number, min: number, max: number) => {\n  if (!isNumber(num)) return min;\n  return Math.min(max, Math.max(min, num));\n};\n","export interface Defer<T = unknown> {\n  promise: Promise<T>;\n  resolve: (value: T) => void;\n  reject: (value: any) => void;\n}\n\n/**\n * Old known defer :)\n *\n * @example\n * function loadModule() {\n *   const q = defer<void>();\n *\n *   setTimeout(() => q.resolve(), 5000);\n *\n *   return q.promise;\n * }\n *\n * await loadModule();\n *\n * @group Promise\n */\nexport function defer<T = void>(): Defer<T> {\n  let resolve: any;\n  let reject: any;\n\n  const promise = new Promise<T>((_resolve, _reject) => {\n    resolve = _resolve;\n    reject = _reject;\n  });\n\n  return {\n    resolve: resolve,\n    reject: reject,\n    promise: promise,\n  };\n}\n","import { isFunction } from '@/is';\nimport type { AnyFunction, Fn } from '@/types';\n\nconst defaultWindow = (globalThis as any)?.window as Window | undefined;\n\nconst idle: (fn: AnyFunction) => void = (() => {\n  if (defaultWindow?.requestIdleCallback) {\n    return defaultWindow.requestIdleCallback;\n  } else if (defaultWindow?.requestAnimationFrame) {\n    return defaultWindow.requestAnimationFrame;\n  } else if (isFunction(process?.nextTick)) {\n    return process.nextTick;\n  } else {\n    return fn => setTimeout(fn, 0);\n  }\n})();\n\n/**\n * Executes the provided callback as soon as the event loop is idle.\n * This function allows you to run tasks at the earliest available opportunity\n * without blocking the main execution flow, making it ideal for tasks that can\n * be deferred until the browser is idle or the process is idle.\n *\n * It uses `requestIdleCallback` if available, otherwise it falls back to\n * `requestAnimationFrame`, `process.nextTick`, or `setTimeout` depending on the environment.\n *\n * @example\n * fastIdle(() => {\n *   console.log('1');\n * });\n *\n * console.log('2');\n *\n * // Output:\n * // 2\n * // 1\n *\n * @param callback - The callback function to be executed when the event loop is idle.\n *\n * @group Promise\n */\nexport function fastIdle(callback: Fn) {\n  return idle(callback);\n}\n\n/**\n * Same as `fastIdle` but promisified\n *\n * @example\n * fastIdlePromise().then(() => {\n *   console.log('1');\n * });\n *\n * console.log('2');\n *\n * // 2\n * // 1\n *\n * @group Promise\n */\nexport function fastIdlePromise() {\n  return new Promise<void>(resolve => idle(resolve));\n}\n","import { defer } from '../defer';\nimport { fastIdle } from '../fastIdle';\n\n/**\n * Returns a promise that resolves after the provided delay.\n *\n * If the delay is specified as `'tick'`, the promise resolves after the next event loop tick.\n *\n * If a numeric delay is provided, the promise resolves after the specified time in milliseconds.\n *\n * This is useful for introducing delays in asynchronous code, such as for throttling or rate-limiting,\n * or simply pausing execution between iterations.\n *\n * @param amount - The delay duration in milliseconds, or `'tick'` for a resolution after the next event loop tick.\n * @returns A promise that resolves after the specified delay.\n *\n * @example\n * let seconds = 0;\n *\n * // This will print numbers 1, 2, 3... every second\n * while (true) {\n *   await delay(1000);\n *   console.log(++seconds);\n * }\n *\n * @example\n * // This will wait until the next event loop tick before resolving\n * await delay('tick');\n *\n * @group Promise\n */\nexport function delay(amount: 'tick' | number = 'tick') {\n  const d = defer<void>();\n\n  if (amount === 'tick') {\n    fastIdle(d.resolve);\n  } else {\n    setTimeout(d.resolve, amount);\n  }\n\n  return d.promise;\n}\n","import { isNumber, noop } from '@/is';\nimport { clamp } from '@/num/clamp';\nimport { delay } from '@/promise/delay';\nimport type { AnyFunction } from '@/types';\n\nvar NOOP_SHOULD_RETRY_BASED_ON_ERROR = () => true;\n\nexport type RetryOnErrorConfig = {\n  /**\n   * The function to execute before retry attempt; Allows to update parameters for the main function by returning then in an array\n   */\n  beforeRetryCallback?: (\n    attempt: number,\n    lastAttempt: boolean,\n  ) => Promise<unknown[] | void>;\n  /**\n   * Error validation function. If returns true, the main callback's considered ready to be executed again\n   */\n  shouldRetryBasedOnError?: (error: unknown, attempt: number) => boolean;\n\n  /**\n   * Number of attempts to execute a function\n   */\n  maxAttempts?: number;\n\n  /**\n   * Number of retries until the execution fails (initial + retries)\n   * @deprecated use `maxAttempts`\n   */\n  maxRetriesNumber?: number;\n\n  /**\n   * Delay multiply factor\n   */\n  delayFactor?: number;\n\n  /**\n   * Delay min milliseconds\n   */\n  delayMinMs?: number;\n\n  /**\n   * Delay max milliseconds\n   */\n  delayMaxMs?: number;\n};\n\n/**\n * Wraps a function with retry logic.\n *\n * @example\n * const fn = await retryOnError({\n *   maxRetriesNumber: 10,\n *   delayFactor: 2,\n *   delayMinMs: 1000,\n *   delayMaxMs: 3000,\n *   shouldRetryBasedOnError(error, attemptNumber) {\n *     return error.code !== 'RECORD_EXISTS';\n *   }\n * }, async () => {\n *   await db.transactions.insert(doc);\n * });\n *\n * await fn();\n *\n * @group Utility Functions\n */\nexport function retryOnError<T extends AnyFunction>(\n  {\n    beforeRetryCallback = noop as AnyFunction,\n    shouldRetryBasedOnError = NOOP_SHOULD_RETRY_BASED_ON_ERROR,\n    maxAttempts,\n    maxRetriesNumber = 1,\n    delayFactor = 0,\n    delayMaxMs = 1000,\n    delayMinMs = 100,\n  }: RetryOnErrorConfig,\n  fn: T,\n): (...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>> {\n  delayMinMs = Math.max(delayMinMs, 1);\n  delayMaxMs = Math.max(delayMaxMs, 1);\n\n  return function (this: any, ...args) {\n    var delayMs = 0;\n    var currentAttempt = 0;\n    var leftAttempts = isNumber(maxAttempts)\n      ? maxAttempts\n      : maxRetriesNumber + 1;\n\n    var run = (): Promise<any> => {\n      currentAttempt++;\n      leftAttempts--;\n\n      return Promise.resolve()\n        .then(() => fn.apply(this, args))\n        .catch(e => {\n          if (leftAttempts < 1 || !shouldRetryBasedOnError(e, currentAttempt)) {\n            return Promise.reject(e);\n          }\n\n          delayMs = clamp(delayMs * delayFactor, delayMinMs, delayMaxMs);\n\n          return Promise.resolve()\n            .then(() => beforeRetryCallback(currentAttempt, leftAttempts <= 1))\n            .then(newParams => {\n              if (Array.isArray(newParams)) {\n                args = newParams as Parameters<T>;\n              }\n\n              return delay(delayMs).then(() => run());\n            });\n        });\n    };\n\n    return run();\n  };\n}\n","import { debounce } from '../debounce';\n\ninterface ThrottleOptions {\n  /**\n   * An optional AbortSignal to cancel the debounced function.\n   */\n  signal?: AbortSignal;\n\n  /**\n   * An optional array specifying whether the function should be invoked on the leading edge, trailing edge, or both.\n   * If `edges` includes \"leading\", the function will be invoked at the start of the delay period.\n   * If `edges` includes \"trailing\", the function will be invoked at the end of the delay period.\n   * If both \"leading\" and \"trailing\" are included, the function will be invoked at both the start and end of the delay period.\n   * @default [\"leading\", \"trailing\"]\n   */\n  edges?: Array<'leading' | 'trailing'>;\n}\n\nexport interface ThrottledFunction<F extends (...args: any[]) => void> {\n  (...args: Parameters<F>): void;\n  cancel: () => void;\n  flush: () => void;\n}\n\n/**\n * Creates a throttled function that only invokes the provided function at most once\n * per every `throttleMs` milliseconds. Subsequent calls to the throttled function\n * within the wait time will not trigger the execution of the original function.\n *\n * @template F - The type of function.\n * @param {F} func - The function to throttle.\n * @param {number} throttleMs - The number of milliseconds to throttle executions to.\n * @returns {(...args: Parameters<F>) => void} A new throttled function that accepts the same parameters as the original function.\n *\n * @example\n * const throttledFunction = throttle(() => {\n *   console.log('Function executed');\n * }, 1000);\n *\n * // Will log 'Function executed' immediately\n * throttledFunction();\n *\n * // Will not log anything as it is within the throttle time\n * throttledFunction();\n *\n * // After 1 second\n * setTimeout(() => {\n *   throttledFunction(); // Will log 'Function executed'\n * }, 1000);\n *\n * @author es-toolkit\n * @group Utility Functions\n */\nexport function throttle<F extends (...args: any[]) => void>(\n  func: F,\n  throttleMs: number,\n  { signal, edges = ['leading', 'trailing'] }: ThrottleOptions = {},\n): ThrottledFunction<F> {\n  let pendingAt: number | null = null;\n\n  const debounced = debounce(func, throttleMs, { signal, edges });\n\n  const throttled = function (...args: Parameters<F>) {\n    if (pendingAt == null) {\n      pendingAt = Date.now();\n    } else {\n      if (Date.now() - pendingAt >= throttleMs) {\n        pendingAt = Date.now();\n        debounced.cancel();\n        debounced(...args);\n      }\n    }\n\n    debounced(...args);\n  };\n\n  throttled.cancel = debounced.cancel;\n  throttled.flush = debounced.flush;\n\n  return throttled;\n}\n","/* eslint-env node */\nimport { AssertionError } from '@/errors/AssertionError';\nimport { isSkip, isSuccess, stringifyExecResult } from '@/function';\nimport type { ExecSkip, ExecSuccess } from '@/types';\nimport {\n  isBigInt,\n  isBoolean,\n  isDate,\n  isEmpty,\n  isError,\n  isFunction,\n  isNumber,\n  isObject,\n  isString,\n} from '../is';\n\nexport function ok(value: unknown, message?: string | Error): asserts value {\n  if (!value) {\n    throw toError(\n      ok,\n      value,\n      message,\n      'The expression evaluated to a falsy value.',\n    );\n  }\n}\n\nexport function equal<T>(\n  actual: unknown,\n  expected: T,\n  message?: string | Error,\n): asserts actual is T {\n  if (actual !== expected) {\n    throw new AssertionError({\n      actual,\n      expected,\n      message: isString(message)\n        ? message\n        : 'The actual value not as expected.',\n      operator: 'equal',\n      stackStartFn: equal,\n    });\n  }\n}\n\nexport function notEmpty(\n  value: unknown,\n  message?: string | Error,\n): asserts value {\n  if (isEmpty(value)) {\n    throw toError(notEmpty, value, message, 'Expected not empty value.');\n  }\n}\n\nexport function object(\n  value: unknown,\n  message?: string | Error,\n): asserts value is object {\n  if (!isObject(value)) {\n    throw toError(object, value, message, 'Expected object value.');\n  }\n}\n\nexport function string(\n  value: unknown,\n  message?: string | Error,\n): asserts value is string {\n  if (!isString(value)) {\n    throw toError(string, value, message, 'Expected string value.');\n  }\n}\n\nexport function boolean(\n  value: unknown,\n  message?: string | Error,\n): asserts value is boolean {\n  if (!isBoolean(value)) {\n    throw toError(boolean, value, message, 'Expected boolean value.');\n  }\n}\n\nexport function notEmptyString(\n  value: unknown,\n  message?: string | Error,\n): asserts value is string {\n  if (!isString(value) || !(value as any).trim()) {\n    throw toError(\n      notEmptyString,\n      value,\n      message,\n      'Expected not empty string value.',\n    );\n  }\n}\n\nexport function number(\n  value: unknown,\n  message?: string | Error,\n): asserts value is number {\n  if (!isNumber(value)) {\n    throw toError(number, value, message, 'Expected number value.');\n  }\n}\n\nexport function bigint(\n  value: unknown,\n  message?: string | Error,\n): asserts value is bigint {\n  if (!isBigInt(value)) {\n    throw toError(bigint, value, message, 'Expected bigint value.');\n  }\n}\n\nexport function date(\n  value: unknown,\n  message?: string | Error,\n): asserts value is Date {\n  if (!isDate(value)) {\n    throw toError(date, value, message, 'Expected date value.');\n  }\n}\n\nexport function fn(\n  value: unknown,\n  message?: string | Error,\n): asserts value is Function {\n  if (!isFunction(value)) {\n    throw toError(fn, value, message, 'Expected function value.');\n  }\n}\n\nexport function greaterThan(\n  value: unknown,\n  target: number,\n  message?: string | Error,\n): asserts value is number {\n  if (!isNumber(value) || value <= target) {\n    throw toError(\n      greaterThan,\n      value,\n      message,\n      'Expected number value greater then ' + target + '.',\n    );\n  }\n}\n\nexport function lessThan(\n  value: unknown,\n  target: number,\n  message?: string | Error,\n): asserts value is number {\n  if (!isNumber(value) || value > target) {\n    throw toError(\n      lessThan,\n      value,\n      message,\n      'Expected number value less then ' + target + '.',\n    );\n  }\n}\n\nexport function array(\n  value: unknown,\n  message?: string | Error,\n): asserts value is unknown[] {\n  if (!Array.isArray(value)) {\n    throw toError(array, value, message, 'Expected array value.');\n  }\n}\n\nexport function arrayStrings(\n  value: unknown,\n  message?: string | Error,\n): asserts value is string[] {\n  if (!Array.isArray(value) || !value.every(isString)) {\n    throw toError(arrayStrings, value, message, 'Expected strings list value.');\n  }\n}\n\nexport function arrayNumbers(\n  value: unknown,\n  message?: string | Error,\n): asserts value is number[] {\n  if (!Array.isArray(value) || !value.every(isNumber)) {\n    throw toError(arrayNumbers, value, message, 'Expected numbers list value.');\n  }\n}\n\nexport function execSuccess(\n  value: unknown,\n  message?: string | Error,\n): asserts value is ExecSuccess {\n  if (isSkip(value)) {\n    throw toError(\n      execSuccess,\n      value,\n      message,\n      `Unexpected ${stringifyExecResult(value)}`,\n    );\n  }\n\n  if (!isSuccess(value)) {\n    throw toError(execSuccess, value, message, 'Expected ExecSuccess value.');\n  }\n}\n\nexport function execSkip(\n  value: unknown,\n  message?: string | Error,\n): asserts value is ExecSkip {\n  if (isSuccess(value)) {\n    throw toError(\n      execSkip,\n      value,\n      message,\n      `Unexpected ${stringifyExecResult(value)}`,\n    );\n  }\n\n  if (!isSkip(value)) {\n    throw toError(execSkip, value, message, 'Expected ExecSkip value.');\n  }\n}\n\n/**\n * Transform value to error object\n */\nfunction toError(\n  operator: Function,\n  actual: unknown,\n  message?: string | Error,\n  unknownMessage: string = 'Unknown error',\n): Error {\n  if (isError(message)) {\n    return message as any;\n  }\n\n  return new AssertionError({\n    actual,\n    message: isString(message) ? message : unknownMessage,\n    operator: operator.name,\n    stackStartFn: operator,\n  });\n}\n","import { assert } from '@/assert';\n\nexport type WrrItem<T> = {\n  item: T;\n  weight?: number;\n};\n\ntype WrrItemWeighted = {\n  item: any;\n  weight: number;\n};\n\n/**\n * Creates a function that returns a weighted round-robin item from the provided array.\n *\n * The input array should contain objects with an `item` property and a `weight` property.\n * The `weight` determines the relative likelihood of selecting an item.\n * Items with higher weights will appear more frequently in the selection.\n *\n * If the `weight` property is missing or falsy, it defaults to `1`.\n * An empty array will result in a function that always returns `undefined`.\n *\n * @example\n * const getItem = weightedRoundRobin([\n *   { item: 'a', weight: 2 },\n *   { item: 'b', weight: 3 },\n *   { item: 'c' },\n * ]);\n *\n * console.log(getItem()); // 'a', 'b', or 'c'\n *\n * @group Array\n */\nexport function weightedRoundRobin<T = unknown>(arr: WrrItem<T>[]): () => T {\n  assert.ok(arr.length > 0, 'Array must contain at least one item.');\n\n  const instance = new WeightedRoundRobin(\n    arr.map(v => ({\n      item: v.item,\n      weight: Math.min(v.weight ?? 1, 1),\n    })),\n  );\n\n  return () => instance.nextItem();\n}\n\nconst gcd = (a: number, b: number): number => (!b ? a : gcd(b, a % b));\n\nclass WeightedRoundRobin {\n  currentIndex = -1;\n  currentWeight = 0;\n  maxWeight: number;\n  gcdWeight: number;\n\n  constructor(public items: WrrItemWeighted[]) {\n    this.maxWeight = this._calculateMaxWeight();\n    this.gcdWeight = this._calculateGCD();\n  }\n\n  _calculateGCD(): number {\n    return this.items.reduce(\n      (acc, curr) => gcd(acc, curr.weight),\n      this.items[0].weight,\n    );\n  }\n\n  _calculateMaxWeight(): number {\n    return Math.max(...this.items.map(s => s.weight));\n  }\n\n  nextItem(): any {\n    const n = this.items.length;\n    while (true) {\n      this.currentIndex = (this.currentIndex + 1) % n;\n      if (this.currentIndex === 0) {\n        this.currentWeight -= this.gcdWeight;\n        if (this.currentWeight <= 0) {\n          this.currentWeight = this.maxWeight;\n        }\n      }\n      if (this.items[this.currentIndex].weight >= this.currentWeight) {\n        return this.items[this.currentIndex].item;\n      }\n    }\n  }\n}\n","export interface BaseX {\n  /**\n   * Base alphabet\n   */\n  alphabet: string;\n\n  /**\n   * Base padding chars\n   */\n  padding: string;\n\n  /**\n   * Encodes binary data into a BaseX string representation\n   *\n   * @param input - The binary data to encode\n   * @returns The encoded string\n   */\n  encode(input: Uint8Array): string;\n\n  /**\n   * Decodes a baseX string back into binary data\n   *\n   * @param input - The encoded string to decode\n   * @returns The decoded binary data\n   * @throws {Error} When the input contains invalid characters or format\n   */\n  decode(input: string): Uint8Array;\n}\n\n/**\n * Create custom base alphabet encoding.\n *\n * @example\n * ```typescript\n * const base16 = basex('0123456789abcdef')\n * const data = new Uint8Array([255, 255]);\n * console.log(base16.encode(data));\n * ```\n *\n * @example\n * ```typescript\n * const base16 = basex('0123456789abcdef')\n * const encoded = \"16FA\";\n * console.log(base16.decode(encoded));\n * ```\n *\n * @group Binary\n */\nexport function basex(alphabet: string): BaseX {\n  var BASE = BigInt(alphabet.length);\n  var ZERO_CHAR = alphabet[0];\n  var CHAR_INDEX: Record<string, number> = {};\n\n  for (let idx = 0; idx < alphabet.length; idx++) {\n    CHAR_INDEX[alphabet[idx]] = idx;\n  }\n\n  return {\n    alphabet,\n    padding: '',\n    encode: encode,\n    decode: decode,\n  };\n\n  function encode(input: Uint8Array): string {\n    var value = 0n;\n    var i = 0;\n    var result: string[] = new Array((((input.length * 8) / 5) | 0) + 1);\n    var pos = result.length;\n    var leadingZeros = 0;\n    var rem = 0n;\n\n    for (i = 0; i < input.length; i++) {\n      value = (value << 8n) + BigInt(input[i]);\n    }\n\n    while (value > 0) {\n      rem = value % BASE;\n      result[--pos] = alphabet[Number(rem)];\n      value = value / BASE;\n    }\n\n    while (leadingZeros < input.length && input[leadingZeros] === 0) {\n      result[--pos] = ZERO_CHAR;\n      leadingZeros++;\n    }\n\n    return result.slice(pos).join('');\n  }\n\n  function decode(input: string): Uint8Array {\n    var value = 0n;\n    var leadingZeros = 0;\n    var i = 0;\n    var char = '';\n    var index = 0;\n    var bytes = new Uint8Array((input.length * 1.25) | 0);\n    var pos = bytes.length;\n\n    while (leadingZeros < input.length && input[leadingZeros] === ZERO_CHAR) {\n      leadingZeros++;\n    }\n\n    for (i = leadingZeros; i < input.length; i++) {\n      char = input[i];\n      index = CHAR_INDEX[char];\n      if (index === undefined) throw new Error('Invalid base62 character');\n      value = value * BASE + BigInt(index);\n    }\n\n    while (value > 0) {\n      bytes[--pos] = Number(value & 0xffn);\n      value >>= 8n;\n    }\n\n    return bytes.subarray(pos - leadingZeros);\n  }\n}\n","import { basex } from '../basex';\n\n/**\n * Base62 encoder/decoder for binary data.\n *\n * @example Basic usage\n * ```typescript\n * const data = new Uint8Array([255, 128, 64]);\n * const encoded = base62.encode(data);\n * console.log(encoded);\n *\n * const decoded = base62.decode(encoded);\n * console.log(decoded); // Uint8Array [255, 128, 64]\n * ```\n *\n * @example Text encoding\n * ```typescript\n * const text = \"Hello World!\";\n * const bytes = new TextEncoder().encode(text);\n * const encoded = base62.encode(bytes);\n * const decoded = base62.decode(encoded);\n * const result = new TextDecoder().decode(decoded);\n * console.log(result); // \"Hello World!\"\n * ```\n *\n * @group Binary\n */\nexport const base62 = basex(\n  '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',\n);\n","import { textDecoder } from '@/str';\nimport type { BaseX } from '../basex';\n\nvar ALPHABET = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';\nvar ENCODE_TABLE = new TextEncoder().encode(ALPHABET);\nvar DECODE_TABLE = new Uint8Array(128);\nfor (let i = 0; i < ENCODE_TABLE.length; ++i) {\n  DECODE_TABLE[ENCODE_TABLE[i]] = i;\n}\n\nvar LOG2_TABLE = new Uint8Array(62);\nLOG2_TABLE[0] = 1;\nfor (let i = 1; i < 62; ++i) {\n  LOG2_TABLE[i] = Math.ceil(Math.log2(i + 1));\n}\n\nvar allocEncode = createAllocator();\n\n/**\n * Base62-like encoder/decoder for binary data but **super fast**. Useful for human readable tokens generation\n *\n * **Warning!** Not RFC standard\n *\n * @example Basic usage\n * ```typescript\n * const data = new Uint8Array([255, 128, 64]);\n * const encoded = base62.encode(data);\n * console.log(encoded);\n *\n * const decoded = base62.decode(encoded);\n * console.log(decoded); // Uint8Array [255, 128, 64]\n * ```\n *\n * @example Text encoding\n * ```typescript\n * const text = \"Hello World!\";\n * const bytes = new TextEncoder().encode(text);\n * const encoded = base62.encode(bytes);\n * const decoded = base62.decode(encoded);\n * const result = new TextDecoder().decode(decoded);\n * console.log(result); // \"Hello World!\"\n * ```\n *\n * @group Binary\n */\nexport const base62Fast: BaseX = {\n  alphabet: ALPHABET,\n  padding: '',\n\n  /**\n   * Encodes a Uint8Array into a Base62 string using a custom 5/6-bit variable length scheme.\n   * Processes bits from left to right maintaining correct order.\n   * @param input The Uint8Array to encode.\n   * @returns The encoded Base62 string.\n   */\n  encode(input: Uint8Array): string {\n    var totalBits = input.length * 8;\n    var output: Uint8Array = allocEncode(((totalBits / 5) | 0) + 1);\n    var outputIndex = 0;\n\n    var bitPosition = 0;\n    var buffer = 0;\n    var inputIndex = 0;\n    var chunkSize;\n    var value;\n\n    // Fill buffer with first byte if available\n    if (input.length > 0) {\n      buffer = input[0];\n      inputIndex = 1;\n      bitPosition = 8;\n    }\n\n    while (bitPosition > 0 || inputIndex < input.length) {\n      // Ensure we have enough bits in buffer\n      while (bitPosition < 6 && inputIndex < input.length) {\n        buffer |= input[inputIndex] << bitPosition;\n        inputIndex++;\n        bitPosition += 8;\n      }\n\n      if (bitPosition === 0) break;\n\n      // Extract value (take from least significant bits)\n      value = buffer & 0x3f;\n      chunkSize = 6; // Default to 6 bits\n\n      // Custom 5-bit encoding logic\n      if ((value & 0x1e) === 0x1e) {\n        // Check if we should use 5 bits instead\n        var remainingBits = bitPosition + (input.length - inputIndex) * 8;\n        if (remainingBits > 6 || value > 0x1f) {\n          chunkSize = 5;\n          value &= 0x1f;\n        }\n      }\n\n      // Store the character for the current value\n      output[outputIndex] = ENCODE_TABLE[value];\n      outputIndex++;\n\n      // Remove processed bits from buffer\n      buffer >>= chunkSize;\n      bitPosition -= chunkSize;\n    }\n\n    return textDecoder.decode(output.subarray(0, outputIndex));\n  },\n\n  /**\n   * Decodes a Base62 string generated by the custom encoder back into a Uint8Array.\n   * @param input The Base62 string to decode.\n   * @returns The decoded Uint8Array.\n   */\n  decode(input: string): Uint8Array {\n    var inputLength = input.length;\n\n    var maxOutputLength = ((inputLength * 6) / 8) | 0;\n    var output = new Uint8Array(maxOutputLength + 1);\n\n    var writeIndex = 0;\n    var bitPosition = 0;\n    var buffer = 0;\n    var charCode = 0;\n    var value = 0;\n    var bitsToAdd = 0;\n\n    // Process characters from left to right (same as original)\n    for (var readIndex = 0; readIndex < inputLength; readIndex++) {\n      charCode = input.charCodeAt(readIndex);\n      value = DECODE_TABLE[charCode];\n\n      // Validate character: must be in the alphabet\n      if (isNaN(charCode) || value === undefined) {\n        throw new Error(\n          'Invalid Base62 input: contains non-alphabet characters. Index: ' +\n            readIndex,\n        );\n      }\n\n      // Determine how many bits this character represents\n      if (readIndex === inputLength - 1) {\n        // If it's the very last character\n        if (LOG2_TABLE[value] === undefined) {\n          throw new Error(\n            'Invalid Base62 input: unexpected value for last character.',\n          );\n        }\n        bitsToAdd = LOG2_TABLE[value];\n      } else if ((value & 0x1e) === 0x1e) {\n        bitsToAdd = 5; // Consume 5 bits\n      } else {\n        bitsToAdd = 6; // Consume 6 bits\n      }\n\n      // Add the decoded value to the buffer\n      buffer |= value << bitPosition;\n      bitPosition += bitsToAdd;\n\n      // If we have accumulated 8 or more bits, write complete bytes to output\n      while (bitPosition >= 8) {\n        output[writeIndex] = buffer & 0xff;\n        writeIndex++;\n        buffer >>= 8;\n        bitPosition -= 8;\n      }\n    }\n\n    // After loop, if there are remaining bits in the buffer, write the last partial byte\n    if (bitPosition > 0) {\n      output[writeIndex] = buffer & 0xff;\n      writeIndex++;\n    }\n\n    // Return the relevant part of the output array (from 0 to writeIndex)\n    return output.subarray(0, writeIndex);\n  },\n};\n\nfunction createAllocator(): (size: number) => Uint8Array {\n  var currentBuffer = new Uint8Array(256);\n  var currentSize = 256;\n\n  return (size: number) => {\n    if (currentSize < size) {\n      currentBuffer = new Uint8Array(size);\n      currentSize = size;\n    }\n    return currentBuffer;\n  };\n}\n","import { assert } from '@/assert';\nimport type { BaseX } from '../basex';\n\nexport class Base64Encoding implements BaseX {\n  public alphabet: string;\n  public padding: string;\n\n  private decodeMap = new Map<string, number>();\n\n  constructor(\n    alphabet: string,\n    options?: {\n      padding?: string;\n    },\n  ) {\n    if (alphabet.length !== 64) {\n      throw new Error('Invalid alphabet');\n    }\n    this.alphabet = alphabet;\n    this.padding = options?.padding ?? '=';\n\n    if (this.padding) {\n      assert.ok(\n        !this.alphabet.includes(this.padding),\n        'Padding cannot be a part of alphabet',\n      );\n      assert.ok(this.padding.length === 1, 'Padding length must be a 1');\n    }\n\n    for (let i = 0; i < alphabet.length; i++) {\n      this.decodeMap.set(alphabet[i]!, i);\n    }\n  }\n\n  /**\n   * Encodes binary data into a base64 string representation\n   *\n   * @param input - The binary data to encode\n   * @returns The encoded string\n   *\n   * @example\n   * ```typescript\n   * const data = new Uint8Array([255, 255]);\n   * console.log(base64.encode(data));\n   * ```\n   */\n  public encode(\n    data: Uint8Array,\n    options?: {\n      includePadding?: boolean;\n    },\n  ): string {\n    const includePadding = options?.includePadding ?? true;\n    let result = '';\n    let buffer = 0;\n    let shift = 0;\n\n    for (const byte of data) {\n      buffer = (buffer << 8) | byte;\n      shift += 8;\n      while (shift >= 6) {\n        shift -= 6;\n        result += this.alphabet[(buffer >> shift) & 0x3f];\n      }\n    }\n\n    if (shift > 0) {\n      result += this.alphabet[(buffer << (6 - shift)) & 0x3f];\n    }\n\n    if (includePadding && this.padding) {\n      const padCount = (4 - (result.length % 4)) % 4;\n      result += '='.repeat(padCount);\n    }\n\n    return result;\n  }\n\n  /**\n   * Decodes a base64 string back into binary data\n   *\n   * @param input - The encoded string to decode\n   * @returns The decoded binary data\n   * @throws {Error} When the input contains invalid characters or format\n   *\n   * @example\n   * ```typescript\n   * const encoded = \"AA==\";\n   * console.log(base64.decode(encoded)); // Uint8Array [255, 255]\n   * ```\n   */\n  public decode(\n    data: string,\n    options?: {\n      strict?: boolean;\n    },\n  ): Uint8Array {\n    const strict = options?.strict ?? true;\n    const result: number[] = [];\n    let buffer = 0;\n    let bitsCollected = 0;\n\n    if (this.padding && strict) {\n      assert.ok(data.length % 4 === 0, 'Invalid Base64 data');\n    }\n\n    for (const char of data) {\n      if (char === this.padding) break;\n      const value = this.decodeMap.get(char);\n      if (value === undefined) {\n        throw new Error(`Invalid Base64 character: ${char}`);\n      }\n      buffer = (buffer << 6) | value;\n      bitsCollected += 6;\n\n      if (bitsCollected >= 8) {\n        bitsCollected -= 8;\n        result.push((buffer >> bitsCollected) & 0xff);\n      }\n    }\n\n    return Uint8Array.from(result);\n  }\n}\n","import { Base64Encoding } from './Base64Encoding';\n\n/**\n * Base64 encoder/decoder for binary data\n *\n * @example Basic usage\n * ```typescript\n * const data = new Uint8Array([255, 128, 64]);\n * const encoded = base64.encode(data);\n * console.log(encoded);\n *\n * const decoded = base64.decode(encoded);\n * console.log(decoded); // Uint8Array [255, 128, 64]\n * ```\n *\n * @example Text encoding\n * ```typescript\n * const text = \"Hello World!\";\n * const bytes = new TextEncoder().encode(text);\n * const encoded = base64.encode(bytes);\n * const decoded = base64.decode(encoded);\n * const result = new TextDecoder().decode(decoded);\n * console.log(result); // \"Hello World!\"\n * ```\n *\n * @group Binary\n */\nexport const base64 = new Base64Encoding(\n  'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',\n);\n\n/**\n * Base64 encoder/decoder for binary data\n *\n * @example Basic usage\n * ```typescript\n * const data = new Uint8Array([255, 128, 64]);\n * const encoded = base64url.encode(data);\n * console.log(encoded);\n *\n * const decoded = base64url.decode(encoded);\n * console.log(decoded); // Uint8Array [255, 128, 64]\n * ```\n *\n * @example Text encoding\n * ```typescript\n * const text = \"Hello World!\";\n * const bytes = new TextEncoder().encode(text);\n * const encoded = base64url.encode(bytes);\n * const decoded = base64url.decode(encoded);\n * const result = new TextDecoder().decode(decoded);\n * console.log(result); // \"Hello World!\"\n * ```\n *\n * @group Binary\n */\nexport const base64url = new Base64Encoding(\n  'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_',\n);\n","import { assert } from '@/assert';\nimport { isFunction } from '@/is';\nimport { base64, base64url } from '../base64';\n\nexport type Base64ToBytesOptions = {\n  /**\n   * Encoding type\n   */\n  encoding?: 'base64' | 'base64url';\n\n  /**\n   * Whether to enforce strict Base64 decoding.\n   */\n  strict?: boolean;\n\n  /**\n   * Prefer to use native `Uint8Array.fromBase64` and `Uint8Array.fromBase64` when possible\n   * @default true\n   */\n  native?: boolean;\n};\n\n/**\n * Decodes a Base64 or Base64URL encoded string into a `Uint8Array`.\n *\n * This function supports decoding data from both standard Base64 and Base64URL formats.\n *\n * @param {string} data - The encoded string to decode. Must be a valid Base64 or Base64URL encoded string.\n * @param {Base64ToBytesOptions} [options] - Optional configuration options for decoding.\n * @returns {Uint8Array} - The decoded byte array.\n *\n * @example\n * // Example 1: Decoding a Base64 string\n * const base64String = 'SGVsbG8gd29ybGQ='; // \"Hello world\"\n * const decodedBytes = base64ToBytes(base64String);\n * console.log(decodedBytes); // Output: Uint8Array [ 72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100 ]\n *\n * @example\n * // Example 2: Decoding a Base64URL encoded string\n * const base64urlString = 'SGVsbG8gd29ybGQ'; // \"Hello world\"\n * const decodedBytes2 = base64ToBytes(base64urlString, { encoding: 'base64url' });\n * console.log(decodedBytes2); // Output: Uint8Array [ 72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100 ]\n *\n * @example\n * // Example 3: Strict decoding with Base64\n * const base64StringStrict = 'SGVsbG8gd29ybGQ=';\n * const decodedStrict = base64ToBytes(base64StringStrict, { strict: true });\n * console.log(decodedStrict); // Output: Uint8Array [ 72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100 ]\n *\n * @group Binary\n */\nexport function base64ToBytes(\n  data: string,\n  { encoding = 'base64', strict, native = true }: Base64ToBytesOptions = {},\n): Uint8Array {\n  if (encoding === 'base64') {\n    if (native && isFunction((Uint8Array as any).fromBase64)) {\n      return (Uint8Array as any).fromBase64(data, {\n        alphabet: 'base64',\n        lastChunkHandling: (strict ?? true) ? 'strict' : 'loose',\n      });\n    }\n\n    return base64.decode(data, { strict: strict ?? true });\n  } else if (encoding === 'base64url') {\n    if (native && isFunction((Uint8Array as any).fromBase64)) {\n      return (Uint8Array as any).fromBase64(data, {\n        alphabet: 'base64url',\n        lastChunkHandling: (strict ?? false) ? 'strict' : 'loose',\n      });\n    }\n\n    return base64url.decode(data, { strict: strict ?? false });\n  }\n\n  assert.ok(false, 'Invalid encoding options: ' + encoding);\n}\n","/**\n * Converts a `bigint` value into a byte array (`Uint8Array`) in big-endian order.\n *\n * This function encodes the absolute value of the provided `bigint` into a minimal byte array,\n * ensuring that the bytes represent the value in big-endian format.\n *\n * @param {bigint} value - The input `bigint` value to convert into bytes.\n * @returns {Uint8Array} - The byte array (`Uint8Array`) representing the provided `bigint`.\n *\n * @example\n * // Example 1: Convert a positive bigint to bytes\n * const value = 1234567890123456789n;\n * const bytes = bigIntBytes(value);\n * console.log(bytes); // Output: Uint8Array representing the bytes in big-endian\n *\n * @example\n * // Example 2: Convert a negative bigint to bytes\n * const valueNegative = -1234567890123456789n;\n * const bytesNegative = bigIntBytes(valueNegative);\n * console.log(bytesNegative); // Output: Uint8Array representing the absolute value in big-endian\n *\n * @example\n * // Example 3: Handle very small bigints\n * const smallValue = 42n;\n * const bytesSmall = bigIntBytes(smallValue);\n * console.log(bytesSmall); // Output: Uint8Array [ 42 ]\n *\n * @example\n * // Example 4: Convert zero value\n * const zeroValue = 0n;\n * const bytesZero = bigIntBytes(zeroValue);\n * console.log(bytesZero); // Output: Uint8Array [ 0 ]\n *\n * @group Binary\n */\nexport function bigIntBytes(value: bigint): Uint8Array {\n  if (value < 0n) {\n    value = value * -1n;\n  }\n  let byteLength = 1;\n  while (value > 2n ** BigInt(byteLength * 8) - 1n) {\n    byteLength++;\n  }\n  const encoded = new Uint8Array(byteLength);\n  for (let i = 0; i < encoded.byteLength; i++) {\n    encoded[i] = Number(\n      (value >> BigInt((encoded.byteLength - i - 1) * 8)) & 0xffn,\n    );\n  }\n  return encoded;\n}\n","import { assert } from '@/assert';\n\n/**\n * Converts a byte array (`Uint8Array`) into a `bigint`. The byte array is interpreted in big-endian order.\n *\n * This function takes a byte array and decodes it into its corresponding `bigint` value by treating\n * the byte array as a big-endian encoded number.\n *\n * @param {Uint8Array} bytes - The byte array to decode into a `bigint`. Must have at least one byte.\n * @returns {bigint} - The decoded `bigint` value.\n *\n * @throws {Error} Will throw an error if the input byte array is empty.\n *\n * @example\n * // Example 1: Decode a simple byte array\n * const byteArray = new Uint8Array([0, 0, 0, 42]); // Represents the number 42 in big-endian\n * const decodedValue = bigIntFromBytes(byteArray);\n * console.log(decodedValue); // Output: 42n\n *\n * @example\n * // Example 2: Decode a multi-byte number\n * const byteArrayMulti = new Uint8Array([0x12, 0x34, 0x56, 0x78]); // Represents the number 305419896\n * const decodedMulti = bigIntFromBytes(byteArrayMulti);\n * console.log(decodedMulti); // Output: 305419896n\n *\n * @example\n * // Example 3: Decode a single byte number\n * const byteArraySingle = new Uint8Array([255]); // Represents the number 255\n * const decodedSingle = bigIntFromBytes(byteArraySingle);\n * console.log(decodedSingle); // Output: 255n\n *\n * @example\n * // Example 4: Attempt decoding an invalid empty array\n * try {\n *   const emptyArray = new Uint8Array([]);\n *   const decodedEmpty = bigIntFromBytes(emptyArray);\n * } catch (error) {\n *   console.error(error); // Output: Error: Empty Uint8Array\n * }\n *\n * @group Binary\n */\nexport function bigIntFromBytes(bytes: Uint8Array): bigint {\n  assert.ok(bytes.byteLength > 0, 'Empty Uint8Array');\n\n  let decoded = 0n;\n  for (let i = 0; i < bytes.byteLength; i++) {\n    decoded += BigInt(bytes[i]) << BigInt((bytes.byteLength - 1 - i) * 8);\n  }\n  return decoded;\n}\n","import { assert } from '@/assert';\nimport { createFunction } from '@/function/createFunction';\nimport { def } from '@/object';\nimport type { AnyFunction } from '@/types';\n\nexport namespace BitPack {\n  export type Field = {\n    name: string;\n    bits: number;\n    take: Take;\n  };\n\n  export type Options<TFields extends Field[]> = {\n    totalBits: number;\n    fields: TFields;\n    debug?: boolean;\n    optimize?: boolean;\n  };\n\n  export type Take = 'low' | 'high';\n\n  export type API<TFields extends string = string> = {\n    buffer: Fn.Buffer<TFields>;\n    number: Fn.Number<TFields>;\n    bigint: Fn.BigInt<TFields>;\n    bits: Fn.Bits<TFields>;\n    plan?: Plan[];\n  };\n\n  export namespace Fn {\n    export type Buffer<TFields extends string = string> = WithDebug<\n      (data: FieldOptions<TFields>) => Uint8Array\n    >;\n\n    export type Number<TFields extends string = string> = WithDebug<\n      (data: FieldOptions<TFields>) => number\n    >;\n\n    export type BigInt<TFields extends string = string> = WithDebug<\n      (data: FieldOptions<TFields>) => bigint\n    >;\n\n    export type Bits<TFields extends string = string> = WithDebug<\n      (data: FieldOptions<TFields>) => string\n    >;\n  }\n\n  export type WithDebug<T extends AnyFunction> = T & { code?: string };\n\n  export type ExtractFieldNames<T extends Field[]> = T[number]['name'];\n\n  export type FieldOptions<T extends string> = {\n    [P in T]: number;\n  };\n}\n\ntype FieldInfo = BitPack.Field & {\n  id: string;\n  startBit: number;\n  endBit: number;\n  mask: number;\n};\n\ntype Plan = {\n  object: 'set' | 'value';\n  container?: number;\n  bits?: number;\n  offset?: number;\n  value?: unknown;\n  child?: Plan;\n};\n\n/**\n * Define compact packed structure\n * @group Binary\n *\n * @example\n * ```typescript\n * const snowflake = bitPack({\n *   totalBits: 64,\n *   fields: [\n *     { name: 'timestamp', bits: 42, take: 'low' },\n *     { name: 'workerId', bits: 5, take: 'low' },\n *     { name: 'processId', bits: 5, take: 'low' },\n *     { name: 'increment', bits: 12, take: 'low' },\n *   ],\n *   optimize: true,\n * });\n *\n * const userId = snowflake.bigint({\n *   timestamp: 1781295314562,\n *   workerId: 1,\n *   processId: 0,\n *   increment: 0\n * }); // 7471294063048785920n\n * ```\n */\nexport function bitPack<\n  const TFields extends BitPack.Field[],\n  TFieldNames extends string = BitPack.ExtractFieldNames<TFields>,\n>(options: BitPack.Options<TFields>): BitPack.API<TFieldNames> {\n  assert.notEmpty(options.fields, 'fields cannot be empty');\n  assert.greaterThan(options.totalBits, 0, 'totalBits must be greater than 0');\n\n  const fields = buildFieldsInfo(options.fields, options.totalBits);\n  const plan = buildPlan(fields);\n  const containersCount = Math.ceil(options.totalBits / 32);\n\n  const buf = new Uint8Array(containersCount * 4);\n\n  const baseCode = [\n    '\\n// Field init',\n    initFields(fields),\n    '\\n// Plan',\n    compilePlan(plan, options.optimize),\n  ];\n\n  // FN: Buffer\n  const fnBufferCode = [\n    ...baseCode,\n    '\\n// Return result',\n    buildBufferResult(containersCount),\n  ].join('\\n');\n\n  const fnBuffer: BitPack.Fn.Buffer = createFunction(\n    'buffer',\n    fnBufferCode,\n    'data',\n  );\n\n  // FN: BigInt\n  const fnBigIntCode = [\n    ...baseCode,\n    '\\n// Return result',\n    buildBigIntResult(containersCount),\n  ].join('\\n');\n\n  const fnBigInt = createFunction<BitPack.Fn.BigInt>(\n    'bigint',\n    fnBigIntCode,\n    'data',\n  );\n\n  // FN: Number\n  const fnNumberCode = [\n    ...baseCode,\n    '\\n// Return result',\n    buildNumberResult(containersCount),\n  ].join('\\n');\n\n  const fnNumber = createFunction<BitPack.Fn.Number>(\n    'number',\n    fnNumberCode,\n    'data',\n  );\n\n  // FN: Bits\n  const fnBitsCode = [\n    ...baseCode,\n    '\\n// Return result',\n    buildBitsResult(containersCount, options.totalBits),\n  ].join('\\n');\n\n  const fnBits = createFunction<BitPack.Fn.Bits>('bits', fnBitsCode, 'data');\n\n  if (!options.debug) {\n    def(fnBuffer, 'code', undefined);\n    def(fnBigInt, 'code', undefined);\n    def(fnNumber, 'code', undefined);\n    def(fnBits, 'code', undefined);\n  }\n\n  return {\n    buffer: fnBuffer,\n    bigint: fnBigInt,\n    number: fnNumber,\n    bits: fnBits,\n    plan: options.debug ? plan : undefined,\n    __buf: buf,\n  } as BitPack.API<TFieldNames>;\n}\n\nfunction initFields(fields: FieldInfo[]): string {\n  return fields\n    .map(field => {\n      if (field.bits > 32) {\n        assert.ok(\n          field.take === 'low',\n          `Fields more than 32 bits with take 'high' not yet supported`,\n        );\n\n        const highMask = Math.pow(2, field.bits - 32) - 1;\n        return [\n          `var ${field.id}_high = ((data['${field.name}'] / 0x100000000) | 0) & 0x${highMask.toString(16)};`,\n          `var ${field.id}_low = (data['${field.name}'] >>> 0);`,\n        ].join('\\n');\n      }\n\n      if (field.take === 'high') {\n        return `var ${field.id} = (data['${field.name}'] / 0x100000000) | 0;`;\n      }\n\n      return `var ${field.id} = (data['${field.name}'] & 0x${field.mask.toString(16)}) >>> 0;`;\n    })\n    .join('\\n');\n}\n\nfunction buildBufferResult(containersCount: number): string {\n  const lines: string[] = [`var buf = this.__buf;`];\n  for (let i = 0; i < containersCount; i++) {\n    const containerIndex = containersCount - 1 - i; // Big-endian order\n    lines.push(\n      `buf[${i * 4}] = c_${containerIndex} >>> 24;`,\n      `buf[${i * 4 + 1}] = c_${containerIndex} >>> 16;`,\n      `buf[${i * 4 + 2}] = c_${containerIndex} >>> 8;`,\n      `buf[${i * 4 + 3}] = c_${containerIndex};`,\n    );\n  }\n  lines.push('return buf;');\n  return lines.join('\\n');\n}\n\nfunction buildBigIntResult(containersCount: number): string {\n  const parts: string[] = [];\n\n  for (let i = 0; i < containersCount; i++) {\n    const containerIndex = containersCount - 1 - i; // Big-endian order\n\n    if (containerIndex > 0) {\n      parts.push(\n        `(BigInt(c_${containerIndex} >>> 0) << ${containerIndex * 32}n)`,\n      );\n    } else {\n      parts.push(`BigInt(c_${containerIndex} >>> 0)`);\n    }\n  }\n\n  return `return (\\n  ${parts.join(' |\\n  ')}\\n);`;\n}\n\nfunction buildNumberResult(containersCount: number): string {\n  return `return c_0;`;\n}\n\nfunction buildBitsResult(containersCount: number, totalBits: number): string {\n  const parts: string[] = [];\n\n  for (let i = 0; i < containersCount; i++) {\n    const containerIndex = containersCount - 1 - i; // Big-endian order\n\n    if (containerIndex > 0) {\n      parts.push(\n        `(BigInt(c_${containerIndex} >>> 0) << ${containerIndex * 32}n)`,\n      );\n    } else {\n      parts.push(`BigInt(c_${containerIndex} >>> 0)`);\n    }\n  }\n\n  return `return (\\n  ${parts.join(' |\\n  ')}\\n).toString(2).padStart(${totalBits}, '0');`;\n}\n\nfunction compilePlan(plan: Plan[], optimize?: boolean): string {\n  if (optimize) {\n    plan = optimizePlan(plan);\n  }\n\n  const assigned = new Set<number>();\n  return plan.map(item => compilePlanItem(item, assigned)).join('\\n');\n}\n\nfunction optimizePlan(plan: Plan[]): Plan[] {\n  return plan.reduce<Plan[]>((result, item) => {\n    const prev = result.at(-1);\n\n    if (canMergeSetOperations(prev, item)) {\n      result.pop();\n      result.push({\n        object: 'set',\n        container: item.container,\n        child: {\n          object: 'value',\n          value: [\n            compilePlanItem(prev!.child!),\n            compilePlanItem(item.child!),\n          ].join(' |\\n  '),\n        },\n      });\n    } else {\n      result.push(item);\n    }\n\n    return result;\n  }, []);\n}\n\nfunction canMergeSetOperations(prev: Plan | undefined, current: Plan): boolean {\n  return (\n    prev?.object === 'set' &&\n    current.object === 'set' &&\n    prev.container === current.container\n  );\n}\n\nfunction compilePlanItem(plan: Plan, assigned?: Set<number>): string {\n  switch (plan.object) {\n    case 'set':\n      if (assigned && !assigned.has(plan.container!)) {\n        assigned.add(plan.container!);\n        return `var c_${plan.container} = ${compilePlanItem(plan.child!)};`;\n      }\n      return `c_${plan.container} |= ${compilePlanItem(plan.child!)};`;\n\n    case 'value':\n      const offset = plan.offset ?? 0;\n      return offset > 0 ? `(${plan.value}) << ${offset}` : `(${plan.value})`;\n\n    default:\n      throw new Error(`Unknown plan object: ${plan.object}`);\n  }\n}\n\nfunction buildPlan(fields: FieldInfo[]): Plan[] {\n  const result: Plan[] = [];\n\n  for (const field of fields) {\n    const startContainer = Math.floor(field.startBit / 32);\n    const endContainer = Math.floor(field.endBit / 32);\n\n    if (startContainer === endContainer) {\n      addSingleContainerField(field, result);\n    } else if (field.bits <= 32) {\n      addSpanningField(field, result);\n    } else {\n      addLargeField(field, result);\n    }\n  }\n\n  return result;\n}\n\nfunction addSingleContainerField(field: FieldInfo, result: Plan[]): void {\n  result.push({\n    object: 'set',\n    container: Math.floor(field.startBit / 32),\n    child: {\n      object: 'value',\n      offset: field.startBit % 32,\n      value: field.id,\n    },\n  });\n}\n\nfunction addSpanningField(field: FieldInfo, result: Plan[]): void {\n  const startContainer = Math.floor(field.startBit / 32);\n  const endContainer = Math.floor(field.endBit / 32);\n  const firstContainerBits = 32 - (field.startBit % 32);\n\n  // First part\n  result.push({\n    object: 'set',\n    container: startContainer,\n    child: {\n      object: 'value',\n      offset: field.startBit % 32,\n      value: `(${field.id}) & ${(1 << firstContainerBits) - 1}`,\n    },\n  });\n\n  // Second part\n  result.push({\n    object: 'set',\n    container: endContainer,\n    child: {\n      object: 'value',\n      value: `(${field.id}) >>> ${firstContainerBits}`,\n    },\n  });\n}\n\nfunction addLargeField(field: FieldInfo, result: Plan[]): void {\n  const startContainer = Math.floor(field.startBit / 32);\n  const endContainer = Math.floor(field.endBit / 32);\n  const startOffset = field.startBit % 32;\n\n  assert.ok(\n    startContainer !== endContainer,\n    `Large field ${field.name} fits in single container - logic error`,\n  );\n\n  assert.ok(\n    endContainer - startContainer === 1,\n    `Fields spanning more than 2 containers (${field.bits} bits) not yet supported`,\n  );\n\n  const bitsInLowerContainer = 32 - startOffset;\n\n  // Add high bits to lower container\n  result.push({\n    object: 'set',\n    container: endContainer,\n    child: {\n      object: 'value',\n      offset: startOffset,\n      value: `${field.id}_high`,\n    },\n  });\n\n  // Add low bits if needed\n  if (bitsInLowerContainer < 32) {\n    result.push({\n      object: 'set',\n      container: endContainer,\n      child: {\n        object: 'value',\n        value: `${field.id}_low >>> ${bitsInLowerContainer}`,\n      },\n    });\n  }\n\n  // Add remaining low bits to upper container\n  if (field.bits > 32) {\n    result.push({\n      object: 'set',\n      container: startContainer,\n      child: {\n        object: 'value',\n        offset: startOffset,\n        value: `${field.id}_low`,\n      },\n    });\n  }\n}\n\nfunction buildFieldsInfo(\n  fields: BitPack.Field[],\n  totalBits: number,\n): FieldInfo[] {\n  const result: FieldInfo[] = [];\n  let currentBitPosition = totalBits;\n\n  fields.forEach((field, idx) => {\n    const startBit = currentBitPosition - field.bits;\n    const endBit = currentBitPosition - 1;\n\n    result.push({\n      id: `f_${idx}`,\n      ...field,\n      startBit,\n      endBit,\n      mask: Math.pow(2, field.bits) - 1,\n    });\n\n    currentBitPosition -= field.bits;\n  });\n\n  return result;\n}\n","import { assert } from '@/assert';\nimport { createFunction } from '@/function/createFunction';\nimport { def } from '@/object';\nimport type { AnyFunction } from '@/types';\n\nexport namespace BitUnpack {\n  export type Field = {\n    name: string;\n    bits: number;\n  };\n\n  export type Options<TFields extends Field[]> = {\n    totalBits: number;\n    fields: TFields;\n    debug?: boolean;\n  };\n\n  export type API<TFields extends string = string> = {\n    buffer: Fn.Buffer<TFields>;\n    number: Fn.Number<TFields>;\n    bigint: Fn.BigInt<TFields>;\n    bits: Fn.Bits<TFields>;\n  };\n\n  export namespace Fn {\n    export type Buffer<TFields extends string = string> = WithDebug<\n      (data: Uint8Array) => FieldResult<TFields>\n    >;\n\n    export type Number<TFields extends string = string> = WithDebug<\n      (data: number) => FieldResult<TFields>\n    >;\n\n    export type BigInt<TFields extends string = string> = WithDebug<\n      (data: bigint) => FieldResult<TFields>\n    >;\n\n    export type Bits<TFields extends string = string> = WithDebug<\n      (data: string) => FieldResult<TFields>\n    >;\n  }\n\n  export type WithDebug<T extends AnyFunction> = T & { code?: string };\n\n  export type ExtractFieldNames<T extends Field[]> = T[number]['name'];\n\n  export type FieldResult<T extends string> = {\n    [P in T]: number;\n  };\n}\n\ntype FieldInfo = BitUnpack.Field & {\n  id: string;\n  mask: bigint;\n  startBit: number;\n  endBit: number;\n};\n\n/**\n * Define compact unpacked structure\n * @group Binary\n *\n * @example\n * ```typescript\n * const snowflake = bitUnpack({\n *   totalBits: 64,\n *   fields: [\n *     { name: 'timestamp', bits: 42, take: 'low' },\n *     { name: 'workerId', bits: 5, take: 'low' },\n *     { name: 'processId', bits: 5, take: 'low' },\n *     { name: 'increment', bits: 12, take: 'low' },\n *   ],\n * });\n *\n * console.log(\n *   snowflake.bigint(7471294063048785920n)\n * ); // { timestamp: 1781295314562, workerId: 1, processId: 0, increment: 0 }\n * ```\n */\nexport function bitUnpack<\n  const TFields extends BitUnpack.Field[],\n  TFieldNames extends string = BitUnpack.ExtractFieldNames<TFields>,\n>(options: BitUnpack.Options<TFields>): BitUnpack.API<TFieldNames> {\n  assert.notEmpty(options.fields, 'fields cannot be empty');\n  assert.greaterThan(options.totalBits, 0, 'totalBits must be greater than 0');\n\n  const fields = buildFieldsInfo(options.fields, options.totalBits);\n\n  // FN: BigInt - direct BigInt bit operations\n  const fnBigIntCode = [`return ${compileFields(fields)};`].join('\\n');\n\n  const fnBigInt = createFunction<BitUnpack.Fn.BigInt>(\n    'bigint',\n    fnBigIntCode,\n    'data',\n  );\n\n  // FN: Number\n  const fnNumberCode = [\n    '\\n// Extract container from number',\n    'data = BigInt(data);',\n    '\\n// Return result',\n    `return ${compileFields(fields)};`,\n  ].join('\\n');\n\n  const fnNumber = createFunction<BitUnpack.Fn.Number>(\n    'number',\n    fnNumberCode,\n    'data',\n  );\n\n  // FN: Buffer\n  const fnBufferCode = [\n    '\\n// Extract bytes from buffer (big-endian)',\n    extractBigIntFromBuffer(options.totalBits),\n    '\\n// Return result',\n    `return ${compileFields(fields)};`,\n  ].join('\\n');\n\n  const fnBuffer = createFunction<BitUnpack.Fn.Buffer>(\n    'buffer',\n    fnBufferCode,\n    'data',\n  );\n\n  // FN: Bits - convert to bigint then use direct operations\n  const fnBitsCode = [\n    '\\n// Convert bits string to bigint',\n    'var data = BigInt(\"0b\" + bits);',\n    '\\n// Return result',\n    `return ${compileFields(fields)};`,\n  ].join('\\n');\n\n  const fnBits = createFunction<BitUnpack.Fn.Bits>('bits', fnBitsCode, 'bits');\n\n  if (!options.debug) {\n    def(fnBuffer, 'code', undefined);\n    def(fnBigInt, 'code', undefined);\n    def(fnNumber, 'code', undefined);\n    def(fnBits, 'code', undefined);\n  }\n\n  return {\n    buffer: fnBuffer,\n    bigint: fnBigInt,\n    number: fnNumber,\n    bits: fnBits,\n  } as BitUnpack.API<TFieldNames>;\n}\n\nfunction compileFields(fields: FieldInfo[]): string {\n  const lines: string[] = ['{'];\n\n  for (const field of fields) {\n    if (field.startBit === 0) {\n      lines.push(\n        `  ['${field.name}']: Number(data & 0x${field.mask.toString(16)}n),`,\n      );\n    } else {\n      lines.push(\n        `  ['${field.name}']: Number((data >> ${field.startBit}n) & 0x${field.mask.toString(16)}n),`,\n      );\n    }\n  }\n\n  lines.push('}');\n\n  return lines.join('\\n');\n}\n\nfunction extractBigIntFromBuffer(totalBits: number): string {\n  const totalBytes = Math.ceil(totalBits / 8);\n  const chunks: string[] = [];\n\n  let byteIndex = 0;\n  let remainingBytes = totalBytes;\n\n  while (remainingBytes > 0) {\n    if (remainingBytes >= 4) {\n      // Full 32-bit chunk\n      const shift = (remainingBytes - 4) * 8;\n      const chunk = `((data[${byteIndex}] << 24) | (data[${byteIndex + 1}] << 16) | (data[${byteIndex + 2}] << 8) | data[${byteIndex + 3}]) >>> 0`;\n      if (shift === 0) {\n        chunks.push(`BigInt(${chunk})`);\n      } else {\n        chunks.push(`(BigInt(${chunk}) << ${shift}n)`);\n      }\n      byteIndex += 4;\n      remainingBytes -= 4;\n    } else {\n      // Remaining bytes (1-3)\n      let chunk: string;\n      if (remainingBytes === 3) {\n        chunk = `(data[${byteIndex}] << 16) | (data[${byteIndex + 1}] << 8) | data[${byteIndex + 2}]`;\n      } else if (remainingBytes === 2) {\n        chunk = `(data[${byteIndex}] << 8) | data[${byteIndex + 1}]`;\n      } else {\n        chunk = `data[${byteIndex}]`;\n      }\n      chunks.push(`BigInt(${chunk})`);\n      remainingBytes = 0;\n    }\n  }\n\n  return `data =\\n    ${chunks.join('\\n  | ')};`;\n}\n\nfunction buildFieldsInfo(\n  fields: BitUnpack.Field[],\n  totalBits: number,\n): FieldInfo[] {\n  const result: FieldInfo[] = [];\n  let currentBitPosition = totalBits;\n\n  fields.forEach((field, idx) => {\n    const startBit = currentBitPosition - field.bits;\n    const endBit = currentBitPosition - 1;\n\n    result.push({\n      id: `f_${idx}`,\n      ...field,\n      mask: (1n << BigInt(field.bits)) - 1n,\n      startBit,\n      endBit,\n    });\n\n    currentBitPosition -= field.bits;\n  });\n\n  return result;\n}\n","import { assert } from '@/assert';\nimport { isFunction } from '@/is';\nimport { base64, base64url } from '../base64';\n\nexport type BytesToBase64Options = {\n  /**\n   * Specifies the encoding type.\n   */\n  encoding?: 'base64' | 'base64url';\n\n  /**\n   * Whether or not to include padding (`=`) in the encoded result. Defaults to `true` for Base64, `false` for Base64URL.\n   */\n  padding?: boolean;\n\n  /**\n   * Prefer to use native `Uint8Array.toBase64` and `Uint8Array.toBase64` when possible\n   * @default true\n   */\n  native?: boolean;\n};\n\n/**\n * Encodes a byte array (`Uint8Array`) into a Base64 or Base64URL encoded string.\n *\n * The function can encode bytes in either the standard Base64 format or Base64URL format,\n * depending on the specified options. It also allows control over whether padding is included.\n *\n * @param {Uint8Array} data - The byte array to encode into Base64 or Base64URL.\n * @param {BytesToBase64Options} [options] - Optional configuration options.\n * @returns {string} - The encoded Base64 or Base64URL string.\n *\n * @example\n * // Example 1: Encoding with Base64 with default padding\n * const byteArray = new Uint8Array([72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]); // \"Hello world\"\n * const encodedBase64 = bytesToBase64(byteArray);\n * console.log(encodedBase64); // Output: 'SGVsbG8gd29ybGQ='\n *\n * @example\n * // Example 2: Encoding with Base64URL without padding\n * const byteArray2 = new Uint8Array([72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]); // \"Hello world\"\n * const encodedBase64URL = bytesToBase64(byteArray2, { encoding: 'base64url', padding: false });\n * console.log(encodedBase64URL); // Output: 'SGVsbG8gd29ybGQ'\n *\n * @example\n * // Example 3: Encoding with Base64 with no padding\n * const byteArray3 = new Uint8Array([1, 2, 3, 4]);\n * const encodedNoPadding = bytesToBase64(byteArray3, { encoding: 'base64', padding: false });\n * console.log(encodedNoPadding); // Output: 'AQIDBA'\n *\n * @example\n * // Example 4: Handling invalid encoding options\n * try {\n *   const invalidEncoding = bytesToBase64(byteArray3, { encoding: 'invalid' });\n * } catch (error) {\n *   console.error(error); // Output: Error: Invalid encoding options: invalid\n * }\n *\n * @group Binary\n */\nexport function bytesToBase64(\n  data: Uint8Array,\n  { encoding = 'base64', padding, native = true }: BytesToBase64Options = {},\n): string {\n  if (encoding === 'base64') {\n    if (native && isFunction((data as any).toBase64)) {\n      return (data as any).toBase64({\n        alphabet: 'base64',\n        omitPadding: !(padding ?? true),\n      });\n    }\n\n    return base64.encode(data, { includePadding: padding ?? true });\n  } else if (encoding === 'base64url') {\n    if (native && isFunction((data as any).toBase64)) {\n      return (data as any).toBase64({\n        alphabet: 'base64url',\n        omitPadding: !(padding ?? false),\n      });\n    }\n\n    return base64url.encode(data, { includePadding: padding ?? false });\n  }\n\n  assert.ok(false, 'Invalid encoding options: ' + encoding);\n}\n","/**\n * Compares two `Uint8Array` instances to check if their contents are identical.\n *\n * This function compares each byte of the two provided byte arrays. It returns `true`\n * only if both byte arrays are of the same length **and** contain identical byte values\n * at every index. Otherwise, it returns `false`.\n *\n * @param {Uint8Array} a - The first byte array to compare.\n * @param {Uint8Array} b - The second byte array to compare.\n * @returns {boolean} `true` if the byte arrays are identical; otherwise, `false`.\n *\n * @example\n * // Example with identical byte arrays\n * const a = new Uint8Array([1, 2, 3]);\n * const b = new Uint8Array([1, 2, 3]);\n * console.log(compareBytes(a, b)); // Output: true\n *\n * @example\n * // Example with different contents\n * const a = new Uint8Array([1, 2, 3]);\n * const b = new Uint8Array([1, 2, 4]);\n * console.log(compareBytes(a, b)); // Output: false\n *\n * @example\n * // Example with different lengths\n * const a = new Uint8Array([1, 2]);\n * const b = new Uint8Array([1, 2, 3]);\n * console.log(compareBytes(a, b)); // Output: false\n *\n * @example\n * // Example with both arrays empty\n * const a = new Uint8Array([]);\n * const b = new Uint8Array([]);\n * console.log(compareBytes(a, b)); // Output: true\n *\n * @group Binary\n */\nexport function compareBytes(a: Uint8Array, b: Uint8Array): boolean {\n  if (a.byteLength !== b.byteLength) {\n    return false;\n  }\n  for (let i = 0; i < b.byteLength; i++) {\n    if (a[i] !== b[i]) {\n      return false;\n    }\n  }\n  return true;\n}\n","/**\n * Concatenates two `Uint8Array` instances into a single new `Uint8Array`.\n *\n * This function takes two byte arrays, `a` and `b`, and creates a new `Uint8Array`\n * that combines their contents in order. The result will have a length equal to the\n * sum of the lengths of `a` and `b`.\n *\n * @param {Uint8Array} a - The first byte array to concatenate.\n * @param {Uint8Array} b - The second byte array to concatenate.\n * @returns {Uint8Array} A new `Uint8Array` containing the concatenation of `a` and `b`.\n *\n * @example\n * // Example with simple byte arrays\n * const a = new Uint8Array([1, 2, 3]);\n * const b = new Uint8Array([4, 5, 6]);\n * const result = concatenateBytes(a, b);\n * console.log(result); // Output: Uint8Array(6) [1, 2, 3, 4, 5, 6]\n *\n * @example\n * // Example with empty arrays\n * const a = new Uint8Array([]);\n * const b = new Uint8Array([1, 2, 3]);\n * const result = concatenateBytes(a, b);\n * console.log(result); // Output: Uint8Array(3) [1, 2, 3]\n *\n * @example\n * // Example with reversed order\n * const a = new Uint8Array([10, 20]);\n * const b = new Uint8Array([30, 40]);\n * const result = concatenateBytes(a, b);\n * console.log(result); // Output: Uint8Array(4) [10, 20, 30, 40]\n *\n * @group Binary\n */\nexport function concatenateBytes(a: Uint8Array, b: Uint8Array): Uint8Array {\n  const result = new Uint8Array(a.byteLength + b.byteLength);\n  result.set(a);\n  result.set(b, a.byteLength);\n  return result;\n}\n","/**\n * Decode a run-length encoded buffer.\n *\n * Decodes `[value, count]` pairs back into runs of `value`.\n * All other bytes pass through unchanged.\n *\n * @param buf - RLE-encoded buffer to decode\n * @param value - Byte value that was compressed (default: 0)\n * @returns Decoded buffer\n * @group Binary\n */\nexport function rleDecode(buf: Uint8Array, value = 0): Uint8Array {\n  const result: number[] = [];\n  let i = 0;\n\n  while (i < buf.length) {\n    if (buf[i] === value) {\n      const count = buf[i + 1];\n      for (let j = 0; j < count; j++) {\n        result.push(value);\n      }\n      i += 2;\n    } else {\n      result.push(buf[i]);\n      i++;\n    }\n  }\n\n  return new Uint8Array(result);\n}\n","/**\n * Run-length encode a buffer, compressing runs of a specific byte value.\n *\n * Runs of `value` are encoded as [value, count] pairs (count ≤ 255).\n * All other bytes pass through unchanged.\n *\n * @param buf - Input buffer to encode\n * @param value - Byte value to compress runs of (default: 0)\n * @returns RLE-encoded buffer\n * @group Binary\n */\nexport function rleEncode(buf: Uint8Array, value = 0): Uint8Array {\n  const result: number[] = [];\n  let i = 0;\n\n  while (i < buf.length) {\n    if (buf[i] === value) {\n      const runStart = i;\n      while (i < buf.length && buf[i] === value) {\n        i++;\n      }\n      let runLength = i - runStart;\n\n      // Encode runs in chunks of 255 (max single-byte count)\n      while (runLength > 0) {\n        const chunk = Math.min(runLength, 255);\n        result.push(value, chunk);\n        runLength -= chunk;\n      }\n    } else {\n      result.push(buf[i]);\n      i++;\n    }\n  }\n\n  return new Uint8Array(result);\n}\n","/**\n * Converts a `Uint16Array` into a `Uint8Array`.\n *\n * @param {Uint16Array} value - The input `Uint16Array` to convert.\n * @returns {Uint8Array} - The resulting `Uint8Array`, with length twice that of the input `Uint16Array`.\n *\n * @example\n * // Example 1: Converting a valid Uint16Array into a Uint8Array\n * const uint16Array = new Uint16Array([0x1234, 0x5678]);\n * const uint8Array = uint16ToUint8(uint16Array);\n * console.log(uint8Array); // Output: Uint8Array [ 0x34, 0x12, 0x78, 0x56 ]\n *\n * @example\n * // Example 2: Another conversion example\n * const uint16Array2 = new Uint16Array([0xabcd, 0x1234, 0x5678]);\n * const uint8Array2 = uint16ToUint8(uint16Array2);\n * console.log(uint8Array2); // Output: Uint8Array [ 0xcd, 0xab, 0x34, 0x12, 0x78, 0x56 ]\n *\n * @group Binary\n */\nexport function uint16ToUint8(value: Uint16Array): Uint8Array {\n  const uint8Array = new Uint8Array(value.length * 2);\n  for (let i = 0; i < value.length; i++) {\n    uint8Array[i * 2] = value[i] & 0xff; // Lower 8 bits\n    uint8Array[i * 2 + 1] = value[i] >> 8; // Upper 8 bits\n  }\n  return uint8Array;\n}\n","/**\n * Converts a `Uint32Array` into a `Uint8Array`.\n *\n * @param {Uint32Array} value - The input `Uint32Array` to convert.\n * @returns {Uint8Array} - The resulting `Uint8Array`, with length four times that of the input `Uint32Array`.\n *\n * @example\n * // Example 1: Converting a valid Uint32Array into a Uint8Array\n * const uint32Array = new Uint32Array([0x12345678, 0x9abcdef0]);\n * const uint8Array = uint32ToUint8(uint32Array);\n * console.log(uint8Array); // Output: Uint8Array [ 0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a ]\n *\n * @example\n * // Example 2: Another conversion example with different numbers\n * const uint32Array2 = new Uint32Array([0xffffffff, 0x00000000]);\n * const uint8Array2 = uint32ToUint8(uint32Array2);\n * console.log(uint8Array2); // Output: Uint8Array [ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 ]\n *\n * @example\n * // Example 3: Handling edge values\n * const uint32Array3 = new Uint32Array([0x0, 0x00000001]);\n * const uint8Array3 = uint32ToUint8(uint32Array3);\n * console.log(uint8Array3); // Output: Uint8Array [ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ]\n *\n * @group Binary\n */\nexport function uint32ToUint8(value: Uint32Array): Uint8Array {\n  const uint8Array = new Uint8Array(value.length * 4);\n  for (let i = 0; i < value.length; i++) {\n    uint8Array[i * 4] = value[i] & 0xff;\n    uint8Array[i * 4 + 1] = (value[i] >> 8) & 0xff;\n    uint8Array[i * 4 + 2] = (value[i] >> 16) & 0xff;\n    uint8Array[i * 4 + 3] = (value[i] >> 24) & 0xff;\n  }\n  return uint8Array;\n}\n","import { assert } from '@/assert';\n\n/**\n * Converts a Uint8Array to a Uint16Array.\n *\n * @param {Uint8Array} value - The input byte array to convert. Must have an even length.\n * @returns {Uint16Array} - The converted Uint16Array.\n *\n * @example\n * // Example 1: Converting a valid Uint8Array into a Uint16Array\n * const uint8Array = new Uint8Array([0x12, 0x34, 0x56, 0x78]);\n * const uint16Array = uint8ToUint16(uint8Array);\n * console.log(uint16Array); // Output: Uint16Array [ 0x1234, 0x5678 ]\n *\n * @example\n * // Example 2: Another conversion example\n * const uint8Array2 = new Uint8Array([0xff, 0xee, 0xdd, 0xcc]);\n * const uint16Array2 = uint8ToUint16(uint8Array2);\n * console.log(uint16Array2); // Output: Uint16Array [ 0xffee, 0xddcc ]\n *\n * @group Binary\n */\nexport function uint8ToUint16(value: Uint8Array): Uint16Array {\n  assert.ok(\n    value.length % 2 === 0,\n    'Uint8Array length must be even for conversion to Uint16Array',\n  );\n\n  const uint16Array = new Uint16Array(value.length / 2);\n\n  for (let i = 0; i < uint16Array.length; i++) {\n    uint16Array[i] = (value[i * 2] << 8) | value[i * 2 + 1];\n  }\n\n  return uint16Array;\n}\n","import { assert } from '@/assert';\n\n/**\n * Converts a `Uint8Array` into a `Uint32Array`.\n *\n * @param {Uint8Array} value - The input byte array to convert. Length must be a multiple of 4.\n * @returns {Uint32Array} - The converted array of 32-bit unsigned integers.\n *\n * @example\n * // Example 1: Converting a valid Uint8Array into a Uint32Array\n * const uint8Array = new Uint8Array([0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0]);\n * const uint32Array = uint8ToUint32(uint8Array);\n * console.log(uint32Array); // Output: Uint32Array [ 0x78563412, 0xf0debc9a ]\n *\n * @example\n * // Example 2: Another conversion example\n * const uint8Array2 = new Uint8Array([0xff, 0xee, 0xdd, 0xcc, 0xab, 0xcd, 0xef, 0x01]);\n * const uint32Array2 = uint8ToUint32(uint8Array2);\n * console.log(uint32Array2); // Output: Uint32Array [ 0xccddeeff, 0x01abcded ]\n *\n *  @group Binary\n */\nexport function uint8ToUint32(value: Uint8Array): Uint32Array {\n  assert.ok(\n    value.length % 4 === 0,\n    'Uint8Array length must be a multiple of 4 for conversion to Uint32Array',\n  );\n\n  const uint32Array = new Uint32Array(value.length / 4);\n  for (let i = 0; i < uint32Array.length; i++) {\n    uint32Array[i] =\n      (value[i * 4] << 24) |\n      (value[i * 4 + 1] << 16) |\n      (value[i * 4 + 2] << 8) |\n      value[i * 4 + 3];\n  }\n\n  return uint32Array;\n}\n","import { base64 } from '@/binary/base64';\nimport { bigIntBytes } from '@/binary/bigIntBytes';\nimport { bigIntFromBytes } from '@/binary/bigIntFromBytes';\nimport { uint16ToUint8 } from '@/binary/uint16ToUint8';\nimport { uint32ToUint8 } from '@/binary/uint32ToUint8';\nimport { uint8ToUint16 } from '@/binary/uint8ToUint16';\nimport { uint8ToUint32 } from '@/binary/uint8ToUint32';\nimport type { EJSONType } from './EJSON';\n\nexport const DateType: EJSONType = {\n  placeholder: '$date',\n  encode: value => {\n    if (value instanceof Date) {\n      return value.getTime();\n    }\n  },\n  decode(value) {\n    return new Date(value);\n  },\n};\n\nexport const BinaryType: EJSONType = {\n  placeholder: '$binary',\n  encode: value => {\n    if (value instanceof Uint8Array) {\n      return base64.encode(value, { includePadding: true });\n    } else if (value instanceof Uint16Array) {\n      return {\n        value: base64.encode(uint16ToUint8(value), { includePadding: true }),\n        bit: 16,\n      };\n    } else if (value instanceof Uint32Array) {\n      return {\n        value: base64.encode(uint32ToUint8(value), { includePadding: true }),\n        bit: 32,\n      };\n    }\n  },\n  decode(value) {\n    if (typeof value === 'string') {\n      return base64.decode(value, { strict: true });\n    } else if (value.bit === 16) {\n      return uint8ToUint16(base64.decode(value.value, { strict: true }));\n    } else if (value.bit === 32) {\n      return uint8ToUint32(base64.decode(value.value, { strict: true }));\n    }\n\n    throw new Error('Unexpected $binary bit value: ' + value.bit);\n  },\n};\n\nexport const BigIntType: EJSONType = {\n  placeholder: '$bigint',\n  encode: value => {\n    if (typeof value === 'bigint') {\n      return base64.encode(bigIntBytes(value), { includePadding: false });\n    }\n  },\n  decode(value) {\n    return bigIntFromBytes(base64.decode(value, { strict: false }));\n  },\n};\n\nexport const MapType: EJSONType = {\n  placeholder: '$map',\n  encode: (value, encode) => {\n    if (value instanceof Map) {\n      return encode(Array.from(value.entries()));\n    }\n  },\n  decode(value) {\n    return new Map(value);\n  },\n};\n\nexport const SetType: EJSONType = {\n  placeholder: '$set',\n  encode: (value, encode) => {\n    if (value instanceof Set) {\n      return encode(Array.from(value.values()));\n    }\n  },\n  decode(value) {\n    return new Set(value);\n  },\n};\n\nexport const RegexType: EJSONType = {\n  placeholder: '$regex',\n  encode: (value, encode) => {\n    if (value instanceof RegExp) {\n      const regStr = value.toString();\n      const patternStart = regStr.lastIndexOf('/');\n\n      return {\n        pattern: value.toString().slice(1, patternStart),\n        flags: regStr.slice(patternStart + 1),\n      };\n    }\n  },\n  decode(value) {\n    return new RegExp(value.pattern, value.flags);\n  },\n};\n\nexport const InfinityType: EJSONType = {\n  placeholder: '$inf',\n  encode: (value, encode) => {\n    if (value === Infinity) {\n      return 1;\n    } else if (value === -Infinity) {\n      return -1;\n    }\n  },\n  decode(value) {\n    if (value === 1) return Infinity;\n    if (value === -1) return -Infinity;\n\n    throw new Error('Unexpected $inf value: ' + value);\n  },\n};\n","import { assert } from '@/assert';\nimport {\n  isBigInt,\n  isInfinity,\n  isObject,\n  isPlainObject,\n  isPrimitive,\n} from '@/is';\nimport { deepCloneWith } from '@/object/deepCloneWith';\nimport {\n  BigIntType,\n  BinaryType,\n  DateType,\n  InfinityType,\n  MapType,\n  RegexType,\n  SetType,\n} from './types';\n\nexport type EJSONType = {\n  /**\n   * The string placeholder (must start with `$`) that represents the custom type.\n   */\n  placeholder: string;\n\n  /**\n   * Should encoded value inlined to original key\n   */\n  encodeInline?: boolean;\n\n  /**\n   * Function to encode a value into a custom representation using a custom type handler.\n   *\n   * If the function returns `undefined`, it signals that encoding for this value should\n   * be delegated to another type handler or encoding logic.\n   *\n   * @param {any} value - The value to be encoded.\n   * @param {(value: any) => any} encode - A reference to the general encoding function\n   *                                       (useful for recursive encoding logic if necessary).\n   * @returns {any} - The custom-encoded value or `undefined` to delegate encoding to another type handler.\n   */\n  encode: (value: any, encode: (value: any) => any) => any;\n\n  /**\n   * A function to decode a custom representation back into a valid JavaScript value.\n   */\n  decode: (value: any) => any;\n};\n\n/**\n * EJSON - Extended JSON handler class for custom encoding and decoding with vendor support.\n * This class provides methods to encode, decode, stringify, and parse JSON with custom type handlers.\n */\nexport class EJSON {\n  /** @internal */\n  protected typeHandlers: Map<string, Readonly<EJSONType>> = new Map();\n\n  /** @internal */\n  protected replacerReady: (value: any, key: PropertyKey | undefined) => any;\n\n  /** @internal */\n  protected encode: (value: any) => any;\n\n  /** @internal */\n  protected reviewerReady: (_: string, value: any) => any;\n\n  /** @internal */\n  protected pure: boolean = true;\n\n  protected _vendorName: string | null = null;\n\n  /**\n   * MIME type based on the provided vendor name or defaults to 'application/json'.\n   */\n  public mimetype: string = 'application/json';\n\n  public readonly Type = {\n    Date: DateType,\n    Map: MapType,\n    Set: SetType,\n    RegExp: RegexType,\n    Infinity: InfinityType,\n    BigInt: BigIntType,\n    Binary: BinaryType,\n  } as const;\n\n  constructor() {\n    this.replacerReady = this._replacer.bind(this);\n    this.reviewerReady = this._reviewer.bind(this);\n    this.encode = (value: any) => {\n      return deepCloneWith(value, this.replacerReady);\n    };\n  }\n\n  /**\n   * The vendor name used for the custom MIME type definition.\n   * If null, defaults to 'application/json'.\n   */\n  get vendorName(): string | null {\n    return this._vendorName;\n  }\n\n  set vendorName(value: string | null) {\n    this._vendorName = value;\n\n    if (!value) {\n      this.mimetype = 'application/json';\n    } else {\n      const vendorName = value\n        .split(' ')\n        .map(v => v.toLowerCase())\n        .join('.')\n        .replace(/\\.\\.+/g, '.')\n        .replace(/\\.$/, '');\n\n      this.mimetype = `application/vnd.${vendorName}+json`;\n    }\n  }\n\n  /**\n   * Adds a custom type handler for encoding/decoding logic.\n   * Ensures type placeholders are unique and adhere to conventions.\n   */\n  addType(type: Readonly<EJSONType>): this {\n    assert.ok(\n      !this.typeHandlers.has(type.placeholder),\n      `type with ${type.placeholder} already taken.`,\n    );\n\n    assert.ok(\n      type.placeholder.startsWith('$'),\n      'type placeholder must starts with $ symbol.',\n    );\n\n    this.pure = false;\n    this.typeHandlers.set(type.placeholder, type);\n    return this;\n  }\n\n  /**\n   * Stringifies a JavaScript value using custom encoding logic.\n   * @param {any} value - The value to encode and stringify.\n   * @param {string | number} [space] - Optional space for pretty-printing.\n   * @returns {string} - The JSON stringified value.\n   */\n  stringify(value: any, space?: string | number): string {\n    if (this.pure) {\n      return JSON.stringify(value, undefined, space);\n    }\n\n    return JSON.stringify(this.encode(value), undefined, space);\n  }\n\n  /**\n   * Parses a JSON string using custom decoding logic.\n   * @param {string} value - The JSON string to parse.\n   * @returns {any} - The decoded JavaScript object.\n   */\n  parse<T = any>(value: string): T {\n    if (this.pure) {\n      return JSON.parse(value);\n    }\n\n    return JSON.parse(value, this.reviewerReady);\n  }\n\n  /** @internal */\n  protected _replacer(value: any, key: PropertyKey | undefined) {\n    // deep object check\n    if (isPlainObject(value)) return;\n    // deep array check\n    if (Array.isArray(value)) return;\n    // exclude primitive\n    if (!isInfinity(value) && !isBigInt(value)) {\n      if (isPrimitive(value)) return;\n    }\n\n    for (const type of this.typeHandlers.values()) {\n      const res = type.encode(value, this.encode);\n\n      if (res !== undefined) {\n        return type.encodeInline ? res : { [type.placeholder]: res };\n      }\n    }\n\n    return value;\n  }\n\n  /** @internal */\n  protected _reviewer(_: string, value: any) {\n    const key = firstKey(value);\n\n    if (!key || key[0] !== '$') return value;\n\n    const type = this.typeHandlers.get(key);\n\n    if (type) {\n      return type.decode(value[key]);\n    }\n\n    return value;\n  }\n}\n\nfunction firstKey(value: unknown): string | null {\n  if (!isObject(value)) return null;\n\n  for (const key in value) {\n    return key;\n  }\n\n  return null;\n}\n","import { EJSON } from './EJSON';\nimport {\n  BigIntType,\n  BinaryType,\n  DateType,\n  InfinityType,\n  MapType,\n  RegexType,\n  SetType,\n} from './types';\n\n/**\n * Creates a new instance of the `EJSON` (Extensible JSON) with optional basic types pre-registered.\n *\n * This function allows you to initialize an `EJSON` instance with commonly used types like `Map`, `Set`,\n * `Date`, `RegExp`, `Infinity`, `BigInt` and `Uint8Array`. These types are added to the type handlers only when `withBasicTypes` is set to `true`.\n *\n * | Type        | Placeholder | Alias          |\n * |-------------|-------------|----------------|\n * | Date        | $date       | EJSON.Date     |\n * | Map         | $map        | EJSON.Map      |\n * | Set         | $set        | EJSON.Set      |\n * | Infinity    | $inf        | EJSON.Infinity |\n * | BigInt      | $bigint     | EJSON.BigInt   |\n * | RegExp      | $regexp     | EJSON.RegExp   |\n * | Uint8Array  | $binary     | EJSON.Binary   |\n * | Uint16Array | $binary     | EJSON.Binary   |\n * | Uint32Array | $binary     | EJSON.Binary   |\n *\n * @param {boolean} [withBasicTypes=false] - Indicates whether to include basic types like Map, Set, Date, and BigInt.\n * @returns {EJSON} - A new instance of the `EJSON` class configured with optional basic types.\n *\n * @example\n * // Instance with basic types (Map, Set, Date, BigInt, Uint8Array)\n * import { EJSON } from '@andrew_l/toolkit';\n *\n * EJSON.stringify({ value: new Date(0) });\n * // {\"value\":{\"$date\": 0}}\n *\n * @example\n * // Create an EJSON instance without any additional types\n * const ejson = createEJSON();\n *\n * ejson.stringify({ value: new Date(0) });\n * // {\"value\":\"1970-01-01T00:00:00.000Z\"}\n *\n * @example\n * // Custom type\n * import { EJSON, createEJSON } from '@andrew_l/toolkit';\n *\n * const ejson = createEJSON();\n *\n * ejson.vendorName = 'Andrew';\n *\n * // Add pre-build date type\n * ejson.addType(EJSON.Date);\n *\n * // Add custom buffer type\n * ejson.addType({\n *   placeholder: '$buffer',\n *   encode(value) {\n *     if (Buffer.isBuffer(value)) {\n *       return value.toString('hex');\n *     }\n *   },\n *   decode(value) {\n *     return Buffer.from(value, 'hex');\n *   }\n * });\n *\n * ejson.stringify({\n *   value: [\n *     Buffer.from('Hello World', 'utf8'),\n *     new Date(0)\n *   ]\n * });\n * // {\"value\":[{\"$buffer\":\"48656c6c6f20576f726c64\"},{\"$date\":0}]}\n *\n * console.log(ejson.mimetype); // application/vnd.andrew+json\n *\n * @group EJSON\n */\nexport function createEJSON(withBasicTypes: boolean = false): EJSON {\n  const ejson = new EJSON();\n\n  if (withBasicTypes) {\n    ejson.addType(MapType);\n    ejson.addType(SetType);\n    ejson.addType(DateType);\n    ejson.addType(InfinityType);\n    ejson.addType(BigIntType);\n    ejson.addType(BinaryType);\n    ejson.addType(RegexType);\n  }\n\n  return ejson;\n}\n","import type { EJSON } from './EJSON';\n\nexport interface EJSONStreamOptions {\n  /**\n   * EJSON Instance\n   */\n  ejson: EJSON;\n\n  /**\n   * Starting encoding symbol\n   */\n  op: string;\n\n  /**\n   * Separator symbol\n   */\n  sep: string;\n\n  /**\n   * Ending symbol\n   */\n  cl: string;\n\n  /** @internal */\n  onStart?: (controller: TransformStreamDefaultController) => Promise<void>;\n\n  /** @internal */\n  onFlush?: (controller: TransformStreamDefaultController) => Promise<void>;\n}\n\nexport class EJSONStream extends TransformStream<any, string> {\n  protected ejson: EJSON;\n\n  constructor({ ejson, cl, op, sep, onFlush, onStart }: EJSONStreamOptions) {\n    let firstChunk = true;\n\n    super({\n      start(controller) {\n        return Promise.resolve()\n          .then(() => {\n            if (onStart) {\n              return onStart(controller);\n            }\n          })\n          .then(() => {\n            controller.enqueue(op);\n          });\n      },\n      transform(chunk, controller) {\n        const jsonString = ejson.stringify(chunk);\n\n        if (firstChunk) {\n          firstChunk = false;\n        } else {\n          controller.enqueue(sep);\n        }\n\n        controller.enqueue(jsonString);\n      },\n      flush(controller) {\n        controller.enqueue(cl);\n\n        if (onFlush) {\n          return onFlush(controller);\n        }\n      },\n    });\n\n    this.ejson = ejson;\n  }\n\n  /**\n   * The vendor name used for the custom MIME type definition.\n   * If null, defaults to 'application/json'.\n   */\n  get vendorName(): string | null {\n    return this.ejson.vendorName;\n  }\n\n  /**\n   * MIME type based on the provided vendor name or defaults to 'application/json'.\n   */\n  get mimetype(): string {\n    return this.ejson.mimetype;\n  }\n}\n","import { createEJSON } from './createEJSON';\n\nexport const instance = createEJSON(true);\n","import { assert } from '@/assert';\nimport { isPlainObject } from '@/is';\nimport type { Awaitable } from '@/types';\nimport { EJSONStream, type EJSONStreamOptions } from './EJSONStream';\nimport { instance } from './instance';\n\nexport interface EJSONStreamOptionsWithPayload\n  extends Partial<EJSONStreamOptions> {\n  prepend?: () => Awaitable<object | null | undefined>;\n  append?: () => Awaitable<object | null | undefined>;\n  resultKey: string;\n}\n\n/**\n * Creates an instance of `EJSONStream`. This function provides flexibility to create a simple stream\n * or one with custom payload transformations, such as appending or prepending data.\n *\n * The function has overloads to handle either basic streaming options or more advanced use cases\n * with payload functions (`append`, `prepend`, `resultKey`) to modify how JSON payloads are streamed.\n *\n * @function\n * @param {Partial<EJSONStreamOptions> | EJSONStreamOptionsWithPayload} [options] - Options to configure the EJSONStream.\n * @returns {EJSONStream} An instance of the `EJSONStream`.\n *\n * @example\n * // Example 1: Create a simple EJSONStream without custom payload transformations\n * const stream = createEJSONStream();\n *\n * @example\n * // Example 2: Create EJSONStream with specific options\n * const stream = createEJSONStream({\n *   cl: ']',\n *   op: '[',\n *   sep: ',',\n *   ejson: someInstance\n * });\n *\n * @example\n * // Example 3: Using prepend and append payloads\n * const streamWithPayloads = createEJSONStream({\n *   prepend: async () => ({ key1: 'value1' }),\n *   append: async () => ({ key2: 'value2' }),\n *   resultKey: 'payload'\n * });\n *\n * // {\"key1\":\"value1\",\"payload\": [...data],\"key2\":\"value2\"}\n *\n * @group EJSON\n */\nexport function createEJSONStream(\n  options?: Partial<EJSONStreamOptions>,\n): EJSONStream;\n\nexport function createEJSONStream(\n  options: EJSONStreamOptionsWithPayload,\n): EJSONStream;\n\nexport function createEJSONStream(\n  options: Partial<EJSONStreamOptionsWithPayload> = {},\n): EJSONStream {\n  if (options.resultKey || options.append || options.prepend) {\n    return createEJSONStreamPayload(options);\n  }\n\n  return new EJSONStream(getOptions(options));\n}\n\nfunction createEJSONStreamPayload(\n  options: Partial<EJSONStreamOptionsWithPayload>,\n): EJSONStream {\n  let { cl, ejson, op, sep } = getOptions(options);\n  const { append, prepend, resultKey } = options;\n\n  assert.notEmptyString(resultKey, 'resultKey required.');\n\n  const stream = new EJSONStream({\n    ejson,\n    cl,\n    op,\n    sep,\n    onStart(controller) {\n      if (!prepend) {\n        controller.enqueue(`{\"${resultKey}\":`);\n        return Promise.resolve();\n      }\n\n      return Promise.resolve()\n        .then(() => prepend())\n        .then(data => {\n          if (data === null || data === undefined) {\n            controller.enqueue(`{\"${resultKey}\":`);\n            return;\n          }\n\n          assert.ok(\n            isPlainObject(data),\n            'prepend result expected to be plain object',\n          );\n\n          const dataPart = instance.stringify(data).slice(0, -1);\n\n          // Empty prepend object\n          if (dataPart === '{') {\n            controller.enqueue(`{\"${resultKey}\":`);\n            return;\n          }\n\n          controller.enqueue(`${dataPart}${sep}\"${resultKey}\":`);\n        });\n    },\n    onFlush(controller) {\n      if (!append) {\n        controller.enqueue('}');\n        return Promise.resolve();\n      }\n\n      return Promise.resolve()\n        .then(() => append())\n        .then(data => {\n          if (data === null || data === undefined) {\n            controller.enqueue('}');\n            return;\n          }\n\n          assert.ok(\n            isPlainObject(data),\n            'prepend result expected to be plain object',\n          );\n\n          const dataPart = instance.stringify(data).slice(1);\n\n          // Empty append object\n          if (dataPart === '}') {\n            controller.enqueue(`}`);\n            return;\n          }\n\n          controller.enqueue(`${sep}${dataPart}`);\n        });\n    },\n  });\n\n  return stream;\n}\n\nfunction getOptions(options: Partial<EJSONStreamOptions>): EJSONStreamOptions {\n  const { ejson = instance, cl = ']', op = '[', sep = ',' } = options;\n\n  return {\n    cl,\n    ejson,\n    op,\n    sep,\n  };\n}\n","import { EJSON } from '@/ejson';\nimport { isObject } from '@/is';\nimport { randomString } from '@/str/randomString';\n\nconst objectKeys = new WeakMap<object, string>();\n\nconst BSON_TYPES = Object.freeze(new Set(['ObjectID', 'ObjectId']));\n\nexport const SYM_WITH_CACHE = Symbol();\n\nexport interface ArgToKeyOptions {\n  /**\n   * Object key generation strategy.\n   *\n   * When `json` we will use `JSON.stringify` which not quite effective.\n   * Also may not hit into cache when object has different key order.\n   *\n   * When `ref` we will use WeakMap to store object key which more effective but may produce unexpected cache hit.\n   *\n   * @default `ref`\n   */\n  objectStrategy: 'json' | 'ref';\n}\n\nexport const argToKey = /*#__PURE__*/ (\n  value: unknown,\n  options: Partial<ArgToKeyOptions> = { objectStrategy: 'ref' },\n): string => {\n  let result = '';\n\n  if (isObject(value)) {\n    // edge case for mongoose objects\n    if (BSON_TYPES.has((value as any)?._bsontype)) {\n      return String(value);\n    }\n\n    let key: string;\n\n    if (options.objectStrategy === 'json') {\n      key = EJSON.stringify(value);\n    } else {\n      key = objectKeys.get(value)!;\n\n      if (!key) {\n        key = createRadomKey();\n        objectKeys.set(value, key);\n      }\n    }\n\n    return key;\n  } else if (Array.isArray(value)) {\n    result += value.map(v => argToKey(v, options)).join('/');\n  } else {\n    result = String(value);\n  }\n\n  return result;\n};\n\nfunction createRadomKey() {\n  return Date.now() + '_' + randomString(16);\n}\n","import { isPromise } from '@/is';\nimport { def } from '@/object/def';\nimport type { AnyFunction } from '@/types';\nimport { type ArgToKeyOptions, SYM_WITH_CACHE, argToKey } from './utils';\n\ninterface CreateWithCacheOptions<T extends AnyFunction>\n  extends Partial<ArgToKeyOptions> {\n  getBucket: (pointer: WithCachePointer) => WithCacheStorage;\n  getPointer: () => WithCachePointer;\n  fn: T;\n}\n\nexport type WithCachePointer = object | Function | symbol;\n\nexport interface WithCacheStorage {\n  get(key: unknown): unknown;\n  has(key: unknown): boolean;\n  delete(key: unknown): void;\n  set(key: unknown, value: unknown): void;\n}\n\nexport interface WithCache {\n  $cache: {\n    getBucket: () => WithCacheStorage;\n    getPointer: () => WithCachePointer;\n    argToKeyOptions: ArgToKeyOptions;\n  };\n}\n\nexport type WithCacheResult<T extends AnyFunction> = T & WithCache;\n\nexport function createWithCache<T extends AnyFunction>({\n  fn,\n  getPointer,\n  getBucket,\n  objectStrategy = 'ref',\n}: CreateWithCacheOptions<T>): WithCacheResult<T> {\n  const isAsync = fn.constructor.name === 'AsyncFunction';\n\n  const argToKeyOptions: ArgToKeyOptions = { objectStrategy };\n\n  const $cache: WithCache['$cache'] = {\n    getBucket: () => getBucket(getPointer()),\n    getPointer,\n    argToKeyOptions,\n  };\n\n  const wrapFn = function (this: any, ...args: Parameters<T>) {\n    const storage = getBucket(getPointer());\n    const cacheKey = args.map(v => argToKey(v, argToKeyOptions)).join('_');\n\n    if (storage.has(cacheKey)) {\n      const value = storage.get(cacheKey);\n      return isAsync ? Promise.resolve(value) : value;\n    }\n\n    const newValue = fn.apply(this, args);\n\n    if (isPromise(newValue)) {\n      // cache only success result\n      return newValue.then(value => {\n        storage.set(cacheKey, value);\n        return value;\n      });\n    }\n\n    storage.set(cacheKey, newValue);\n\n    return newValue;\n  } as T;\n\n  (wrapFn as any).$cache = $cache;\n\n  def(wrapFn, SYM_WITH_CACHE, true);\n\n  return wrapFn as any;\n}\n\n/**\n * Returns true when function is cached\n * @group Cache\n */\nexport function isWithCache(\n  value: unknown,\n): value is WithCacheResult<AnyFunction> {\n  return !!value && (value as any)[SYM_WITH_CACHE] === true;\n}\n","import { isFunction, noop } from '@/is';\nimport type { AnyFunction } from '@/types';\nimport {\n  type WithCachePointer,\n  type WithCacheResult,\n  createWithCache,\n} from '../createWithCache';\nimport type { ArgToKeyOptions } from '../createWithCache/utils';\n\nexport interface WithCacheOptions extends Partial<ArgToKeyOptions> {\n  /**\n   * Custom cache pointer\n   */\n  cachePointer?: WithCachePointer;\n}\n\nexport const cache = /*#__PURE__*/ new WeakMap<\n  WithCachePointer,\n  Map<string, any>\n>();\n\n/**\n * Wrap a function to cache results by arguments\n *\n * @example\n * const sum = withCache((a, b) => {\n *     console.log('calc?');\n *     return a + b;\n * });\n *\n * sum(1, 2); // calc?\n * sum(1, 2);\n * sum(1, 3)  // calc?\n *\n * @group Cache\n */\nexport function withCache<T extends AnyFunction>(fn: T): WithCacheResult<T>;\nexport function withCache<T extends AnyFunction>(\n  options: WithCacheOptions,\n  fn: T,\n): WithCacheResult<T>;\n\nexport function withCache(...args: any[]): WithCacheResult<AnyFunction> {\n  let options: WithCacheOptions = {};\n  let fn: AnyFunction = noop;\n\n  if (isFunction(args[0])) {\n    fn = args[0];\n  } else if (isFunction(args[1])) {\n    options = args[0] || {};\n    fn = args[1];\n  }\n\n  const pointer = options.cachePointer || fn;\n\n  const getPointer = () => pointer;\n\n  const getBucket = (pointer: any) => {\n    let fnCache = cache.get(pointer);\n\n    if (!fnCache) {\n      fnCache = new Map();\n      cache.set(pointer, fnCache);\n    }\n\n    return fnCache;\n  };\n\n  return createWithCache({\n    fn,\n    getBucket,\n    getPointer,\n    ...options,\n  });\n}\n","import { assert } from '@/assert';\n\nexport function assertCapacity(value: unknown): asserts value is number {\n  assert.number(value, 'capacity must be a number');\n  assert.ok(value > 0, 'capacity must be more then 0.');\n}\n","import { assertCapacity } from './utils';\n\n/**\n * A Map-like class with a fixed capacity, where entries are automatically removed\n * when the capacity is exceeded. This allows for efficient caching behavior,\n * ensuring that the map never grows beyond the specified capacity.\n *\n * When the map reaches its capacity, the oldest entries (in insertion order)\n * are removed to make room for new ones.\n *\n * @example\n * const cache = new FixedMap<string, number>(3);\n * cache.set('a', 1);\n * cache.set('b', 2);\n * cache.set('c', 3);\n * cache.set('d', 4); // 'a' will be evicted, as it's the oldest entry\n *\n * console.log(cache.get('a')); // undefined\n * console.log(cache.get('b')); // 2\n *\n * @group Cache\n */\nexport class FixedMap<K = any, V = any> extends Map<K, V> {\n  private _tail: K[];\n\n  constructor(private _capacity: number) {\n    assertCapacity(_capacity);\n    super();\n    this._tail = [];\n  }\n\n  set(key: K, value: V): this {\n    if (!super.has.call(this, key)) {\n      this._tail.push(key);\n    }\n\n    super.set.call(this, key, value);\n    this._drain();\n\n    return this;\n  }\n\n  delete(key: K): boolean {\n    const removed = super.delete.call(this, key);\n\n    if (removed) {\n      const idx = this._tail.findIndex(v => v === key);\n\n      if (idx > -1) {\n        this._tail.splice(idx, 1);\n      }\n    }\n\n    return removed;\n  }\n\n  clear(): void {\n    // @ts-expect-error\n    delete this._tail;\n    this._tail = [];\n\n    super.clear.call(this);\n  }\n\n  get capacity(): number {\n    return this._capacity;\n  }\n\n  set capacity(value: number) {\n    assertCapacity(value);\n    this._capacity = value;\n    this._drain();\n  }\n\n  private _drain() {\n    while (this._tail.length > this._capacity) {\n      const key = this._tail.shift();\n\n      key !== undefined && this.delete(key);\n    }\n  }\n}\n","import { FixedMap } from '../FixedMap';\n\nexport interface TimeBucketOptions {\n  /**\n   * The size of each time bucket in milliseconds. This is the interval at which\n   * the records in the bucket will expire and be dropped.\n   */\n  sizeMs: number;\n\n  /**\n   * The maximum number of entries the bucket can hold. Once the capacity is\n   * reached, the least recently used entry will be removed.\n   * @default Infinity\n   */\n  capacity?: number;\n}\n\n/**\n * A time-based bucket that holds records for a specific interval defined by `sizeMs`.\n * The records in the bucket will be dropped once the interval elapses, based on the\n * current time. The `TimeBucket` is designed to avoid using timers to track expirations.\n *\n * It can be used to store data that expires over fixed time intervals (e.g., caching,\n * throttling).\n *\n * @example\n * const bucket = new TimeBucket({ sizeMs: 1000, capacity: 10 });\n * bucket.set('key1', 'value1');\n * console.log(bucket.get('key1')); // 'value1'\n *\n * // After 1 second, the bucket will drop the expired records.\n *\n * @group Cache\n */\nexport class TimeBucket<K = any, V = any> {\n  private _pointer: number;\n  private _sizeMs: number;\n  private _bucket: FixedMap<K, V> | Map<K, V>;\n\n  constructor({ capacity = Infinity, sizeMs }: TimeBucketOptions) {\n    assetSizeMs(sizeMs);\n\n    this._sizeMs = sizeMs;\n    this._pointer = 0;\n    this._bucket = capacity === Infinity ? new Map() : new FixedMap(capacity);\n  }\n\n  get capacity(): number {\n    if (this._bucket instanceof FixedMap) {\n      return this._bucket.capacity;\n    }\n\n    return Infinity;\n  }\n\n  get sizeMs(): number {\n    return this.sizeMs;\n  }\n\n  set sizeMs(value: number) {\n    assetSizeMs(value);\n\n    this._sizeMs = value;\n\n    this._drainBucket();\n  }\n\n  get size(): number {\n    this._drainBucket();\n    return this._bucket.size;\n  }\n\n  set(key: K, value: V): this {\n    this._drainBucket();\n    this._bucket.set(key, value);\n\n    return this;\n  }\n\n  get(key: K): any | undefined {\n    this._drainBucket();\n    return this._bucket.get(key);\n  }\n\n  has(key: K): boolean {\n    this._drainBucket();\n    return this._bucket.has(key);\n  }\n\n  delete(key: K): boolean {\n    this._drainBucket();\n    return this._bucket.delete(key);\n  }\n\n  clear() {\n    this._pointer = 0;\n    this._drainBucket();\n  }\n\n  keys(): IterableIterator<K> {\n    this._drainBucket();\n\n    return this._bucket.keys();\n  }\n\n  values(): IterableIterator<V> {\n    this._drainBucket();\n\n    return this._bucket.values();\n  }\n\n  entries(): IterableIterator<[K, V]> {\n    this._drainBucket();\n\n    return this._bucket.entries();\n  }\n\n  forEach(\n    callbackfn: (value: V, key: K, map: TimeBucket<K, V>) => void,\n    thisArg?: any,\n  ): void {\n    this._drainBucket();\n    return this._bucket.forEach((value, key) => {\n      callbackfn(value, key, this);\n    });\n  }\n\n  private _drainBucket() {\n    const newPointer = bucketPointer(this._sizeMs);\n\n    if (newPointer !== this._pointer) {\n      const capacity =\n        this._bucket instanceof FixedMap ? this._bucket.capacity : Infinity;\n\n      // @ts-expect-error\n      delete this._bucket;\n\n      this._pointer = newPointer;\n      this._bucket = capacity === Infinity ? new Map() : new FixedMap(capacity);\n    }\n  }\n}\n\nfunction assetSizeMs(value: unknown) {\n  if (typeof value !== 'number' || isNaN(value)) {\n    throw new TypeError('msSize must be a number');\n  }\n\n  if (value <= 0) {\n    throw new TypeError('msSize must be more then 0.');\n  }\n}\n\nfunction bucketPointer(size: number): number {\n  return Math.floor(Date.now() / size) * size;\n}\n","import type { AnyFunction } from '@/types';\nimport {\n  type WithCachePointer,\n  type WithCacheResult,\n  createWithCache,\n} from '../createWithCache';\nimport type { ArgToKeyOptions } from '../createWithCache/utils';\nimport { TimeBucket } from '../TimeBucket';\n\nexport interface WithCacheBucketOptions extends Partial<ArgToKeyOptions> {\n  /**\n   * Define cached records drops interval.\n   */\n  sizeMs: number;\n\n  /**\n   * Capacity of cached records\n   */\n  capacity?: number;\n\n  /**\n   * Custom cache pointer\n   */\n  cachePointer?: WithCachePointer;\n}\n\nexport const cacheBucket = /*#__PURE__*/ new WeakMap<\n  WithCachePointer,\n  TimeBucket<string, any>\n>();\n\n/**\n * Wrap a function to cache results by arguments\n *\n * But with time and capacity limitation\n *\n * @example\n * const sum = withCacheBucket({ capacity: 1, sizeMs: 1000000 }, (a, b) => {\n *     console.log('calc?');\n *     return a + b;\n * });\n *\n * sum(1, 2); // calc?\n * sum(1, 2);\n * sum(1, 3)  // calc?\n * sum(1, 3)\n * sum(1, 2); // calc?\n *\n * @group Cache\n */\nexport function withCacheBucket<T extends AnyFunction>(\n  { capacity, sizeMs, cachePointer, ...options }: WithCacheBucketOptions,\n  fn: T,\n): WithCacheResult<T> {\n  const pointer = cachePointer || fn;\n\n  const getPointer = () => {\n    return pointer;\n  };\n\n  const getBucket = () => {\n    let fnCache = cacheBucket.get(pointer);\n\n    if (!fnCache) {\n      fnCache = new TimeBucket({ sizeMs, capacity });\n      cacheBucket.set(pointer, fnCache);\n    }\n\n    return fnCache;\n  };\n\n  return createWithCache({\n    fn,\n    getBucket,\n    getPointer,\n    ...options,\n  });\n}\n","import type { AnyFunction } from '@/types';\nimport {\n  type WithCachePointer,\n  type WithCacheResult,\n  createWithCache,\n} from '../createWithCache';\nimport type { ArgToKeyOptions } from '../createWithCache/utils';\nimport { FixedMap } from '../FixedMap';\n\nexport interface WithCacheFixedOptions extends Partial<ArgToKeyOptions> {\n  /**\n   * Capacity of cached records\n   */\n  capacity: number;\n\n  /**\n   * Custom cache pointer\n   */\n  cachePointer?: WithCachePointer;\n}\n\nexport const cacheFixed = /*#__PURE__*/ new WeakMap<\n  WithCachePointer,\n  FixedMap<string, any>\n>();\n\n/**\n * Wrap a function to cache results by arguments\n *\n * But with capacity limitation\n *\n * @example\n * const sum = withCacheFixed({ capacity: 1 }, (a, b) => {\n *     console.log('calc?');\n *     return a + b;\n * });\n *\n * sum(1, 2); // calc?\n * sum(1, 2);\n * sum(1, 3)  // calc?\n * sum(1, 3)\n * sum(1, 2); // calc?\n *\n * @group Cache\n */\nexport function withCacheFixed<T extends AnyFunction>(\n  { capacity, cachePointer, ...options }: WithCacheFixedOptions,\n  fn: T,\n): WithCacheResult<T> {\n  const pointer = cachePointer || fn;\n\n  const getPointer = () => fn;\n\n  const getBucket = () => {\n    let fnCache = cacheFixed.get(pointer);\n\n    if (!fnCache) {\n      fnCache = new FixedMap(capacity);\n      cacheFixed.set(pointer, fnCache);\n    }\n\n    return fnCache;\n  };\n\n  return createWithCache({\n    fn,\n    getBucket,\n    getPointer,\n    ...options,\n  });\n}\n","import { isNumber } from '@/is';\n\n/**\n * A simple implementation of a Least Recently Used (LRU) cache. This cache stores\n * key-value pairs and ensures that the most recently accessed items are kept\n * in the cache, while the least recently used items are evicted when the cache\n * reaches its capacity.\n *\n * The cache is implemented as a doubly linked list where the head represents\n * the most recently accessed item, and the tail represents the least recently\n * accessed item. When the cache is full, the least recently used item (tail)\n * is removed to make space for new items.\n *\n * @group Cache\n */\nexport class LruCache<TKey = any, TValue = any> {\n  private items: Map<TKey, number>;\n  private forward: Uint8Array | Uint16Array | Uint32Array;\n  private backward: Uint8Array | Uint16Array | Uint32Array;\n  private K: TKey[];\n  private V: (TValue | undefined)[];\n\n  size: number;\n  private head: number;\n  private tail: number;\n\n  constructor(private capacity: number) {\n    this.capacity = Math.max(isNumber(capacity) ? capacity : 0, 0);\n\n    this.forward = pointerArray(this.capacity);\n    this.backward = pointerArray(this.capacity);\n    this.K = new Array(capacity);\n    this.V = new Array(capacity);\n\n    this.items = new Map();\n\n    this.size = 0;\n    this.head = 0;\n    this.tail = 0;\n  }\n\n  /**\n   * Method used to clear the structure.\n   */\n  clear() {\n    this.size = 0;\n    this.head = 0;\n    this.tail = 0;\n    this.items.clear();\n  }\n\n  set(key: TKey, value: TValue): this {\n    let pointer = this.items.get(key);\n\n    // The key already exists, we just need to update the value and splay on top\n    if (pointer !== undefined) {\n      this.splayOnTop(pointer);\n      this.V[pointer] = value;\n      return this;\n    }\n\n    // The cache is not yet full\n    if (this.size < this.capacity) {\n      pointer = this.size++;\n    }\n\n    // Cache is full, we need to drop the last value\n    else {\n      pointer = this.tail;\n      this.tail = this.backward[pointer];\n      this.items.delete(this.K[pointer]);\n    }\n\n    // Storing key & value\n    this.items.set(key, pointer);\n    this.K[pointer] = key;\n    this.V[pointer] = value;\n\n    // Moving the item at the front of the list\n    this.forward[pointer] = this.head;\n    this.backward[this.head] = pointer;\n    this.head = pointer;\n\n    return this;\n  }\n\n  has(key: TKey): boolean {\n    return this.peek(key) !== undefined;\n  }\n\n  delete(key: TKey): void {\n    const pointer = this.items.get(key);\n\n    if (pointer === undefined) return;\n\n    this.V[pointer] = undefined;\n  }\n\n  get(key: TKey): TValue | undefined {\n    const pointer = this.items.get(key);\n\n    if (pointer === undefined) return;\n\n    this.splayOnTop(pointer);\n\n    return this.V[pointer];\n  }\n\n  /**\n   * Method used to get the value attached to the given key. Does not modify\n   * the ordering of the underlying linked list.\n   */\n  peek(key: TKey): TValue | undefined {\n    const pointer = this.items.get(key);\n\n    if (pointer === undefined) return;\n\n    return this.V[pointer];\n  }\n\n  /**\n   * Method used to create an iterator over the cache's keys from most\n   * recently used to least recently used.\n   */\n  keys(): IterableIterator<TKey> {\n    let i = 0,\n      l = this.size;\n\n    let pointer = this.head,\n      keys = this.K,\n      forward = this.forward;\n\n    const iterator: Iterator<TKey> = {\n      next: () => {\n        if (i >= l) return { done: true, value: undefined };\n\n        const key = keys[pointer];\n\n        i++;\n\n        if (i < l) pointer = forward[pointer];\n\n        // skip marked as removed\n        if (this.peek(key) === undefined) return iterator.next();\n\n        return {\n          done: false,\n          value: key,\n        };\n      },\n    };\n\n    return {\n      ...iterator,\n      [Symbol.iterator]() {\n        return this;\n      },\n    };\n  }\n\n  /**\n   * Method used to create an iterator over the cache's values from most\n   * recently used to least recently used.\n   *\n   */\n  values(): IterableIterator<TValue> {\n    let i = 0,\n      l = this.size;\n\n    let pointer = this.head,\n      values = this.V,\n      forward = this.forward;\n\n    const iterator: Iterator<TValue> = {\n      next: () => {\n        if (i >= l) return { done: true, value: undefined };\n\n        const value = values[pointer];\n\n        i++;\n\n        if (i < l) pointer = forward[pointer];\n\n        // skip marked as removed\n        if (value === undefined) return iterator.next();\n\n        return {\n          done: false,\n          value: value,\n        };\n      },\n    };\n\n    return {\n      ...iterator,\n      [Symbol.iterator]() {\n        return this;\n      },\n    };\n  }\n\n  /**\n   * Method used to create an iterator over the cache's entries from most\n   * recently used to least recently used.\n   *\n   * @return {IterableIterator<[TKey, TValue | undefined]>}\n   */\n  entries() {\n    let i = 0,\n      l = this.size;\n\n    let pointer = this.head,\n      keys = this.K,\n      values = this.V,\n      forward = this.forward;\n\n    /** @type {Iterator<[TKey, TValue | undefined]>} */\n    const iterator = {\n      next() {\n        if (i >= l) return { done: true, value: undefined };\n\n        const key = keys[pointer],\n          value = values[pointer];\n\n        i++;\n\n        if (i < l) pointer = forward[pointer];\n\n        return {\n          done: false,\n          value: [key, value],\n        };\n      },\n    };\n\n    return {\n      ...iterator,\n      [Symbol.iterator]() {\n        return this;\n      },\n    };\n  }\n\n  /**\n   * Method used to splay a value on top.\n   *\n   * @param  {number}   pointer - Pointer of the value to splay on top.\n   */\n  splayOnTop(pointer: number): this {\n    const oldHead = this.head;\n\n    if (this.head === pointer) return this;\n\n    const previous = this.backward[pointer],\n      next = this.forward[pointer];\n\n    if (this.tail === pointer) {\n      this.tail = previous;\n    } else {\n      this.backward[next] = previous;\n    }\n\n    this.forward[previous] = next;\n\n    this.backward[oldHead] = pointer;\n    this.head = pointer;\n    this.forward[pointer] = oldHead;\n\n    return this;\n  }\n\n  [Symbol.iterator]() {\n    return this.entries();\n  }\n}\n\nconst MAX_8BIT_INTEGER = Math.pow(2, 8) - 1,\n  MAX_16BIT_INTEGER = Math.pow(2, 16) - 1,\n  MAX_32BIT_INTEGER = Math.pow(2, 32) - 1;\n\nfunction pointerArray(size: number): Uint8Array | Uint16Array | Uint32Array {\n  const maxIndex = size - 1;\n\n  if (maxIndex <= MAX_8BIT_INTEGER) return new Uint8Array(size);\n\n  if (maxIndex <= MAX_16BIT_INTEGER) return new Uint16Array(size);\n\n  if (maxIndex <= MAX_32BIT_INTEGER) return new Uint32Array(size);\n\n  throw new Error('Pointer Array of size > 4294967295 is not supported.');\n}\n","import type { AnyFunction } from '@/types';\nimport {\n  type WithCachePointer,\n  type WithCacheResult,\n  createWithCache,\n} from '../createWithCache';\nimport type { ArgToKeyOptions } from '../createWithCache/utils';\nimport { LruCache } from '../LruCache';\n\nexport interface WithCacheLruOptions extends Partial<ArgToKeyOptions> {\n  capacity: number;\n  cachePointer?: WithCachePointer;\n}\n\nexport const cacheLRU = /*#__PURE__*/ new WeakMap<\n  WithCachePointer,\n  LruCache<string, any>\n>();\n\n/**\n * Wrap a function to cache results by arguments\n *\n * But with LRU\n *\n * @example\n * const sum = withCacheLRU({ capacity: 100 }, (a, b) => {\n *     console.log('calc?');\n *     return a + b;\n * });\n *\n * sum(1, 2); // calc?\n * sum(1, 2);\n *\n * @group Cache\n */\nexport function withCacheLRU<T extends AnyFunction>(\n  { capacity, cachePointer, ...options }: WithCacheLruOptions,\n  fn: T,\n): WithCacheResult<T> {\n  const pointer = cachePointer || fn;\n\n  const getPointer = () => {\n    return pointer;\n  };\n\n  const getBucket = () => {\n    let fnCache = cacheLRU.get(pointer);\n\n    if (!fnCache) {\n      fnCache = new LruCache(capacity);\n      cacheLRU.set(pointer, fnCache);\n    }\n\n    return fnCache;\n  };\n\n  return createWithCache({\n    fn,\n    getBucket,\n    getPointer,\n    ...options,\n  });\n}\n","import { type WithCachePointer, isWithCache } from '../createWithCache';\nimport { type ArgToKeyOptions, argToKey } from '../createWithCache/utils';\nimport { cache } from '../withCache';\nimport { cacheBucket } from '../withCacheBucket';\nimport { cacheFixed } from '../withCacheFixed';\nimport { cacheLRU } from '../withCacheLRU';\n\n/**\n * Drop cached result\n *\n * @example\n * const findUser = withCache((id: number) => db.users.findById(id));\n *\n * dropCache(findUser, 100500);\n *\n * @group Cache\n */\nexport function dropCache(\n  cachePointer: WithCachePointer,\n  ...args: any[]\n): boolean {\n  let argToKeyOptions: ArgToKeyOptions = { objectStrategy: 'ref' };\n  let removed = false;\n\n  if (isWithCache(cachePointer)) {\n    argToKeyOptions = cachePointer.$cache.argToKeyOptions;\n  }\n\n  const cacheKey = args.map(v => argToKey(v, argToKeyOptions)).join('_');\n\n  if (isWithCache(cachePointer)) {\n    if (cachePointer.$cache.getBucket().has(cacheKey)) {\n      removed = true;\n      cachePointer.$cache.getBucket().delete(cacheKey);\n    }\n\n    cachePointer = cachePointer.$cache.getPointer();\n  }\n\n  [cache, cacheFixed, cacheBucket, cacheLRU].forEach(map => {\n    if (map.get(cachePointer)?.has(cacheKey)) {\n      removed = true;\n      map.get(cachePointer)?.delete(cacheKey);\n    }\n  });\n\n  return removed;\n}\n","import { assertCapacity } from '../FixedMap/utils';\n\n/**\n * A `WeakMap`-like class with a fixed capacity. Entries are automatically removed\n * when the map exceeds the specified capacity. Unlike a regular `WeakMap`, the\n * entries are limited to a defined size, and the oldest entries are evicted when\n * new ones are added after the capacity is reached.\n *\n * This class behaves similarly to a `WeakMap`, but with the additional constraint\n * of a fixed size. It automatically removes the least recently added key-value\n * pairs when the map grows beyond the specified capacity.\n *\n * @example\n * const cache = new FixedWeakMap<object, number>(3);\n * const obj1 = { id: 1 };\n * const obj2 = { id: 2 };\n * const obj3 = { id: 3 };\n *\n * cache.set(obj1, 1);\n * cache.set(obj2, 2);\n * cache.set(obj3, 3);\n *\n * const obj4 = { id: 4 };\n * cache.set(obj4, 4); // obj1 will be evicted as it's the oldest\n *\n * console.log(cache.get(obj1)); // undefined\n * console.log(cache.get(obj2)); // 2\n * console.log(cache.get(obj4)); // 4\n *\n * @group Cache\n */\nexport class FixedWeakMap<K extends WeakKey = WeakKey, V = any> extends WeakMap<\n  K,\n  V\n> {\n  private _tail: K[];\n\n  constructor(private _capacity: number) {\n    assertCapacity(_capacity);\n    super();\n    this._tail = [];\n  }\n\n  set(key: K, value: V): this {\n    if (!super.has(key)) {\n      this._tail.push(key);\n    }\n\n    super.set(key, value);\n    this._drain();\n\n    return this;\n  }\n\n  delete(key: K): boolean {\n    const removed = super.delete(key);\n\n    if (removed) {\n      const idx = this._tail.findIndex(v => v === key);\n\n      if (idx > -1) {\n        this._tail.splice(idx, 1);\n      }\n    }\n\n    return removed;\n  }\n\n  clear(): void {\n    for (const item of this._tail) {\n      super.delete(item);\n    }\n\n    // @ts-expect-error\n    delete this._tail;\n    this._tail = [];\n  }\n\n  get size(): number {\n    return this._tail.length;\n  }\n\n  get capacity(): number {\n    return this._capacity;\n  }\n\n  set capacity(value: number) {\n    assertCapacity(value);\n    this._capacity = value;\n    this._drain();\n  }\n\n  private _drain() {\n    while (this._tail.length > this._capacity) {\n      const key = this._tail.shift();\n\n      key !== undefined && this.delete(key);\n    }\n  }\n}\n","import type { AnyFunction } from '@/types';\nimport { type WithCachePointer, isWithCache } from '../createWithCache';\nimport { type ArgToKeyOptions, argToKey } from '../createWithCache/utils';\nimport { cache } from '../withCache';\nimport { cacheBucket } from '../withCacheBucket';\nimport { cacheFixed } from '../withCacheFixed';\nimport { cacheLRU } from '../withCacheLRU';\n\n/**\n * Check if function has cached result\n *\n * @example\n * const findUser = withCache((id: number) => db.users.findById(id));\n *\n * const user = findUser(100500);\n *\n * isCached(findUser, 100500); // true\n *\n * @group Cache\n */\nexport function isCached<T extends AnyFunction>(\n  fn: AnyFunction,\n  ...args: Parameters<T>\n) {\n  let argToKeyOptions: ArgToKeyOptions = { objectStrategy: 'ref' };\n  let cachePointer: WithCachePointer = fn;\n  let cached = false;\n\n  if (isWithCache(fn)) {\n    argToKeyOptions = fn.$cache.argToKeyOptions;\n  }\n\n  const cacheKey = args.map(v => argToKey(v, argToKeyOptions)).join('_');\n\n  if (isWithCache(fn)) {\n    cached = fn.$cache.getBucket().has(cacheKey);\n    cachePointer = fn.$cache.getPointer();\n\n    if (cached) return true;\n  }\n\n  return !![cache, cacheFixed, cacheBucket, cacheLRU].some(storage =>\n    storage.get(cachePointer)?.has(cacheKey),\n  );\n}\n","import { isObject } from '@/is';\nimport { def } from '@/object/def';\nimport type { WithCachePointer, WithCacheResult } from '../createWithCache';\nimport {\n  type ArgToKeyOptions,\n  SYM_WITH_CACHE,\n  argToKey,\n} from '../createWithCache/utils';\nimport { TimeBucket } from '../TimeBucket';\nimport { cacheBucket } from '../withCacheBucket';\n\nconst EMPTY_SYM = Symbol('empty');\n\nexport interface WithCacheBucketBatchOptions<\n  T extends object,\n  K extends keyof T,\n> {\n  /**\n   * Define cached records drops interval.\n   */\n  sizeMs: number;\n\n  /**\n   * Cache record by object key.\n   */\n  key: K;\n\n  /**\n   * Amount of items which will handled by resolver function.\n   */\n  batchSize?: number;\n\n  /**\n   * Capacity of cached records\n   */\n  capacity?: number;\n\n  /**\n   * Custom cache pointer\n   */\n  cachePointer?: WithCachePointer;\n\n  /**\n   * Should we retry resolving for provided item key when previously we got empty result.\n   */\n  retryEmpty?: boolean;\n\n  /**\n   * Resolving item function\n   */\n  resolver?: (values: T[K][]) => Promise<T[]>;\n}\n\n/**\n * In this way we will cache item of resulted array by `key`.\n *\n * Useful when we need for example fetch batch of users by ids but took already cached results if it available.\n *\n * @example TODO\n *\n * @beta\n *\n * @group Cache\n */\nexport function withCacheBucketBatch<T extends object, K extends keyof T>(\n  {\n    capacity,\n    sizeMs,\n    key,\n    batchSize = 10,\n    cachePointer,\n    retryEmpty = true,\n  }: WithCacheBucketBatchOptions<T, K>,\n  resolver: (values: T[K][]) => Promise<T[]>,\n): WithCacheResult<(values: T[K][]) => Promise<Map<string, Readonly<T>>>> {\n  const pointer = cachePointer || resolver;\n  const argToKeyOptions: ArgToKeyOptions = {\n    objectStrategy: 'json',\n  };\n\n  const getPointer = () => {\n    return pointer;\n  };\n\n  const getBucket = () => {\n    let fnCache = cacheBucket.get(pointer);\n\n    if (!fnCache) {\n      fnCache = new TimeBucket({ sizeMs, capacity });\n      cacheBucket.set(pointer, fnCache);\n    }\n\n    return fnCache;\n  };\n\n  const wrapFn = async function (this: any, values: any) {\n    const result = new Map();\n\n    let fnCache = getBucket();\n\n    const batchSet = new Set<any>();\n\n    const drainMaybe = async () => {\n      if (!batchSet.size) return;\n\n      const items = await resolver.call(this, Array.from(batchSet));\n\n      for (let idx = 0; idx < items.length; idx++) {\n        const item = items[idx];\n\n        if (!isObject(item)) continue;\n\n        const id = argToKey(item[key], argToKeyOptions);\n\n        batchSet.delete(id);\n        result.set(id, item);\n        fnCache?.set(id, item);\n      }\n\n      for (const batchItem of batchSet.values()) {\n        fnCache?.set(batchItem, EMPTY_SYM);\n      }\n\n      batchSet.clear();\n    };\n\n    let pos = 0;\n\n    while (pos < values.length) {\n      const id = argToKey(values[pos], argToKeyOptions);\n      const item = fnCache.get(id);\n\n      if (item) {\n        if (item === EMPTY_SYM) {\n          if (retryEmpty) batchSet.add(id);\n        } else {\n          result.set(id, item);\n        }\n      } else {\n        batchSet.add(id);\n      }\n\n      if (batchSet.size >= batchSize) {\n        await drainMaybe();\n      }\n\n      pos++;\n    }\n\n    await drainMaybe();\n\n    return result;\n  };\n\n  wrapFn.$cache = { getBucket, getPointer, argToKeyOptions };\n\n  def(wrapFn, SYM_WITH_CACHE, true);\n\n  return wrapFn;\n}\n","import { isPromise } from '@/is';\nimport { deepClone } from '@/object';\nimport { def } from '@/object/def';\nimport type { AnyFunction } from '@/types';\nimport { isWithCache } from '../createWithCache';\nimport { SYM_WITH_CACHE } from '../createWithCache/utils';\n\n/**\n * Make deep cloning of function result before returning.\n *\n * @example\n * const findUser = withDeepClone(\n *   withCache((id: number) => {\n *     return { id, name: 'Andrew' };\n *   })\n * );\n *\n * const user1 = findUser(100500);\n * const user2 = findUser(100500);\n * user1.name = 'ABC';\n *\n * console.log(user1.name); // ABC\n * console.log(user2.name); // Andrew\n *\n * @group Cache\n */\nexport function withDeepClone<T extends AnyFunction>(fn: T): T {\n  const wrapFn = function (...args) {\n    // @ts-expect-error\n    const result = fn.apply(this, args);\n\n    if (isPromise(result)) {\n      return result.then(deepClone);\n    }\n\n    return deepClone(result);\n  } as T;\n\n  if (isWithCache(fn)) {\n    (wrapFn as any).$cache = fn.$cache;\n  }\n\n  if ('$cache' in fn) {\n    (wrapFn as any).$cache = fn.$cache;\n    def(wrapFn, SYM_WITH_CACHE, true);\n  }\n\n  return wrapFn;\n}\n","import type { AnyFunction } from '@/types';\nimport { cache } from '../withCache';\n\n/**\n * @example TODO\n * @group Cache\n * @beta\n */\nexport function withPointerCache<T>(\n  pointer: object,\n  dependencies: string[],\n  fn: () => T,\n): T {\n  const cacheKey = dependencies.map(String).join('_');\n\n  let fnCache = cache.get(pointer as AnyFunction);\n\n  if (fnCache) {\n    const cached = fnCache.get(cacheKey);\n    if (cached) {\n      return cached;\n    }\n  } else {\n    fnCache = new Map();\n    cache.set(pointer as AnyFunction, fnCache);\n  }\n\n  const newValue = fn();\n\n  fnCache.set(cacheKey, newValue);\n\n  return newValue;\n}\n","import type { AnyFunction } from './types';\n\n/**\n * Capture stack trace till the function and returns as a `string`\n *\n * @example\n *\n * function main() {\n *   const userId = getUserId();\n * }\n *\n * function getUserId() {\n *   const stackTrace = captureStackTrace(doCoolStuff);\n *   console.warn('Please, use getAccountId instead.', stackTrace);\n * }\n *\n * @group Errors\n */\nexport function captureStackTrace(till: AnyFunction): string {\n  const err = new Error('');\n\n  if ('captureStackTrace' in Error) {\n    (Error.captureStackTrace as any)(err, till);\n  }\n\n  return (err.stack || '').slice(6);\n}\n","import { isPromise } from './is';\nimport { toError } from './toError';\n\nexport type CatchErrorResult<T> =\n  T extends Promise<unknown>\n    ? Promise<OkResult<Awaited<T>> | ErrorResult>\n    : OkResult<T> | ErrorResult;\n\ntype ErrorResult = [Error, undefined];\n\ntype OkResult<T> = [undefined, T];\n\n/**\n * You're tired to write `try... catch`, and so are we.\n *\n * Also supports `async/await`\n *\n * @example\n * const [err, result] = catchError(() => {\n *   // danger code\n * });\n *\n * @group Errors\n */\nexport function catchError<T>(fn: () => T): CatchErrorResult<T> {\n  try {\n    const res = fn();\n\n    if (isPromise(res)) {\n      return res.then(r => [undefined, r]).catch(onError) as any;\n    }\n\n    return [undefined, res] as any;\n  } catch (err) {\n    return onError(err) as any;\n  }\n}\n\nfunction onError(error: unknown): ErrorResult {\n  const err = toError(error);\n  return [err, undefined];\n}\n","import { isNumber, isString } from '@/is';\nimport { clamp } from '@/num/clamp';\n\n/**\n * Parse alpha channel value and normalize it from 0 to 1\n *\n * @param value Value to be parsed\n * @param fallback Value which will be used as fallback when failed to parse\n *\n * @example\n * parseAlpha('0.1'); // 0.1\n * parseAlpha('10%'); // 0.1\n * parseAlpha(0.1); // 0.1\n *\n * @group Colors\n */\nexport function parseAlpha(value: unknown, fallback: number = 1): number {\n  let a: unknown = value;\n\n  if (isString(value)) {\n    a = value.endsWith('%') ? parseFloat(value) / 100 : parseFloat(value);\n  }\n\n  if (!isNumber(a)) {\n    a = fallback;\n  }\n\n  return clamp(a as number, 0, 1);\n}\n","import { isString } from '@/is';\nimport { parseAlpha } from '../parseAlpha';\nimport type { Color } from '../types';\n\nconst hexReg = new RegExp(\n  /^#([a-f0-9]{3,4}|[a-f0-9]{4}(?:[a-f0-9]{2}){1,2})\\b$/,\n  'i',\n);\n\nexport function parseHEX(value: unknown): Color.ColorChannels | null {\n  if (!isString(value)) return null;\n\n  const parsed = hexReg.exec(value);\n\n  if (!parsed) return null;\n\n  let a = 1;\n  let hex = parsed[0].replace(/^#/, '');\n\n  if (hex.length === 8) {\n    a = Number.parseInt(hex.slice(6, 8), 16) / 255;\n    hex = hex.slice(0, 6);\n  }\n\n  if (hex.length === 4) {\n    a = Number.parseInt(hex.slice(3, 4).repeat(2), 16) / 255;\n    hex = hex.slice(0, 3);\n  }\n\n  if (hex.length === 3) hex = hex + hex;\n\n  return [\n    parseInt(hex.slice(0, 2), 16),\n    parseInt(hex.slice(2, 4), 16),\n    parseInt(hex.slice(4, 6), 16),\n    parseAlpha(a),\n  ];\n}\n","import { isNumber } from '@/is';\nimport { clamp } from '../clamp';\n\n/**\n * Safely parses a percentage value and returns a number between 0 and 100.\n * It accepts both string and numeric input, automatically handling the '%' sign if present.\n * If the value is not a valid percentage, it returns 0.\n *\n * @param {unknown} value - The value to parse, which can be a string (e.g., '99%') or a number (e.g., 45).\n * @returns {number} A parsed percentage value, constrained between 0 and 100.\n * If the input is invalid or cannot be parsed, it returns 0.\n *\n * @example\n * parsePercentage('99%');\n * // Returns: 99\n *\n * @example\n * parsePercentage('150%');\n * // Returns: 100 (clamped to the maximum allowed value)\n *\n * @example\n * parsePercentage('50.5%');\n * // Returns: 50.5\n *\n * @example\n * parsePercentage('abc');\n * // Returns: 0 (invalid input)\n *\n * @example\n * parsePercentage(80);\n * // Returns: 80 (valid number input)\n *\n * @group Numbers\n */\nexport function parsePercentage(value: unknown): number {\n  const parsed = parseFloat(value as any);\n\n  if (!isNumber(parsed)) return 0;\n\n  return clamp(parsed, 0, 100);\n}\n","import type { Color } from './types';\n\nexport const float = '-?\\\\d*(?:\\\\.\\\\d+)';\nexport const number = `(${float}?)`;\nexport const percentage = `(${float}?%)`;\nexport const numberOrPercentage = `(${float}?%?)`;\n\n/**\n * Check if provided value represents color channels\n * @group Colors\n */\nexport function isColorChannels(value: unknown): value is Color.ColorChannels {\n  return Array.isArray(value) && value.length === 4;\n}\n","import { parsePercentage } from '@/num/parsePercentage';\nimport { parseAlpha } from '../parseAlpha';\nimport type { Color } from '../types';\nimport { numberOrPercentage, percentage } from '../utils';\n\nconst hsl = new RegExp(\n  `^\n  hsla?\\\\(\n    \\\\s*(-?\\\\d*(?:\\\\.\\\\d+)?(?:deg|rad|turn)?)\\\\s*,\n    \\\\s*${percentage}\\\\s*,\n    \\\\s*${percentage}\\\\s*\n    (?:,\\\\s*${numberOrPercentage}\\\\s*)?\n  \\\\)\n  $\n`.replace(/\\n|\\s/g, ''),\n);\n\nconst hsla = new RegExp(\n  `^\n  hsla?\\\\(\n    \\\\s*(-?\\\\d*(?:\\\\.\\\\d+)?(?:deg|rad|turn)?)\\\\s*\n    \\\\s+${percentage}\n    \\\\s+${percentage}\n    \\\\s*(?:\\\\s*\\\\/\\\\s*${numberOrPercentage}\\\\s*)?\n  \\\\)\n  $\n`.replace(/\\n|\\s/g, ''),\n);\n\n/**\n * Parse a string as a hsl color\n */\nexport function parseHSL(value: string): Color.HSLA | null {\n  const parsed = hsla.exec(value) || hsl.exec(value);\n\n  if (!parsed) return null;\n\n  const [, h, s, l, a = 1] = parsed;\n\n  let hh: any = h;\n  if (hh.endsWith('turn')) {\n    hh = (parseFloat(hh) * 360) / 1;\n  } else if (hh.endsWith('rad')) {\n    hh = Math.round((parseFloat(hh) * 180) / Math.PI);\n  } else {\n    hh = parseFloat(hh);\n  }\n\n  return {\n    h: hh,\n    s: parsePercentage(s),\n    l: parsePercentage(l),\n    a: parseAlpha(a === null ? 1 : a),\n  };\n}\n","/**\n * Check if bits are set in `number` bitmask\n *\n * @example\n * const scope = (1 << 1 | 1 << 2 | 1 << 3);\n *\n * checkBitmask(scope, 1 << 2); // true\n * checkBitmask(scope, 1 << 5); // false\n *\n * @group Numbers\n */\nexport function checkBitmask(scope: number, flag: number): boolean;\n\n/**\n * Check if bits are set in `bigint` bitmask\n *\n * @example\n * const scope = (1n << 1n | 1n << 2n | 1n << 3n);\n *\n * checkBitmask(scope, 1n << 2n); // true\n * checkBitmask(scope, 1n << 5n); // false\n *\n * @group Numbers\n */\nexport function checkBitmask(scope: bigint, flag: bigint): boolean;\n\nexport function checkBitmask(scope: any, flag: any): boolean {\n  return (scope & flag) === flag;\n}\n","/**\n * Returns a random integer between min (inclusive) and max (inclusive).\n * The value is no lower than min (or the next integer greater than min\n * if min isn't an integer) and no greater than max (or the next integer\n * lower than max if max isn't an integer).\n * Using Math.round() will give you a non-uniform distribution!\n *\n * @example\n * getRandomInt(0, 100); // random int between 0 - 100\n *\n * @group Numbers\n */\nexport function getRandomInt(min: number, max: number) {\n  min = Math.ceil(min);\n  max = Math.floor(max);\n  return Math.floor(Math.random() * (max - min + 1)) + min;\n}\n","import { assert } from '@/assert';\nimport { getRandomInt } from '../getRandomInt';\n\nexport interface RandomizerOptions {\n  min: number;\n  max: number;\n  pregenerateAmount: number;\n  transform: (value: number) => number;\n}\n\nclass Randomizer {\n  private _pool: number[] = [];\n  private _step: number = 0;\n  private _min: number;\n  private _max: number;\n  private _pregenerateAmount: number;\n  private _transform: (value: number) => number;\n\n  constructor({ min, max, pregenerateAmount, transform }: RandomizerOptions) {\n    this._min = min;\n    this._max = max;\n    this._pregenerateAmount = pregenerateAmount;\n    this._transform = transform;\n  }\n\n  /**\n   * Returns the current step of the randomizer.\n   *\n   * @returns {number} The current step.\n   */\n  getCurrentStep(): number {\n    return this._step;\n  }\n\n  /**\n   * Sets the current step of the randomizer.\n   *\n   * @param {number} value - The step to set.\n   * @throws {Error} If the provided value is not a valid number or less than 0.\n   */\n  setCurrentStep(value: number) {\n    assert.number(value, 'Current step must be an number');\n    assert.ok(value >= 0, 'Current step must be getter or equal 0');\n    this._step = value;\n  }\n\n  /**\n   * Retrieves a random number either from the current step or a specific step if provided.\n   *\n   * @param {number} [fromStep] - The step from which to retrieve the random number (optional).\n   * @returns {number} The random number at the current or specified step.\n   */\n  get(fromStep?: number): number {\n    if (fromStep === undefined) {\n      return this._lookup(this._step++);\n    }\n\n    return this._lookup(fromStep);\n  }\n\n  /**\n   * Resets the current step to 0.\n   */\n  resetStep() {\n    this._step = 0;\n  }\n\n  /**\n   * Resets the random number pool, clearing and repopulating it with new random values.\n   */\n  resetPool() {\n    const size = this._pregenerateAmount;\n\n    this._pool = Array.from({ length: size });\n\n    for (let step = 0; step < size; step++) {\n      this._pool[step] = this._rand();\n    }\n  }\n\n  private _rand(): number {\n    return this._transform(getRandomInt(this._min, this._max));\n  }\n\n  private _lookup(step: number): number {\n    if (this._pool[step] === undefined) {\n      this._pool[step] = this._rand();\n    }\n\n    return this._pool[step]!;\n  }\n}\n\nconst noopTransform = (v: number) => v;\n\n/**\n * Creates a random number generator with step control and optional transformation.\n * Allows caching of generated numbers for efficiency, with optional pregeneration and transformation.\n *\n * @param {RandomizerOptions} options - Configuration for the randomizer.\n * @param {number} options.min - Minimum value for the random number.\n * @param {number} options.max - Maximum value for the random number.\n * @param {number} [options.pregenerateAmount=100] - Number of random numbers to pregenerate and cache.\n * @param {(value: number) => number} [options.transform] - A function to transform the generated random number.\n * @returns {Randomizer} - The randomizer object with step control and number generation.\n *\n *\n * @example\n * // Basic usage of the randomizer\n * const randomizer = createRandomizer({\n *   min: 1,\n *   max: 10,\n *   pregenerateAmount: 5\n * });\n *\n * // Get the random number at the current step\n * console.log(randomizer.get()); // e.g., returns 3\n *\n * // Get the random number at a specific step\n * console.log(randomizer.get(2)); // e.g., returns 7\n *\n * // Get the current step\n * console.log(randomizer.getCurrentStep()); // returns the current step (e.g., 1)\n *\n * // Set the current step to 3\n * randomizer.setCurrentStep(3);\n *\n * // Get the random number at step 3\n * console.log(randomizer.get()); // returns the value for step 3\n *\n * @example\n * // Usage with a transformation function\n * const randomizerWithTransform = createRandomizer({\n *   min: 1,\n *   max: 10,\n *   pregenerateAmount: 5,\n *   transform: (value) => value * 2\n * });\n *\n * // Get a transformed random number at the current step\n * console.log(randomizerWithTransform.get()); // e.g., returns 6 (original value 3 transformed by multiplying by 2)\n *\n * // Reset the step to 0\n * randomizerWithTransform.resetStep();\n * console.log(randomizerWithTransform.get()); // returns the random number at step 0\n *\n * @group Numbers\n */\nexport function createRandomizer({\n  min = Number.MIN_SAFE_INTEGER,\n  max = Number.MAX_SAFE_INTEGER,\n  pregenerateAmount = 100,\n  transform = noopTransform,\n}: Partial<RandomizerOptions>): Randomizer {\n  return new Randomizer({ min, max, pregenerateAmount, transform });\n}\n","/**\n * A class that allows you to calculate the running mean (average) of a set of numbers.\n * It computes the average as new numbers are added and can also reset the progress.\n *\n * @example\n * // Basic usage to calculate running mean\n * const avg = findMean();\n * avg.push(1, 2, 3);\n * console.log(avg.value); // Output: 2 (average of 1, 2, 3)\n *\n * @example\n * // Reset the calculation with an initial value\n * const avg = findMean(10);\n * avg.push(20);\n * console.log(avg.value); // Output: 15 (average of 10, 20)\n * console.log(avg.count); // Output: 2 (two values added)\n */\nexport class FindMean {\n  #count: number = 0;\n  #value: number = 0;\n\n  constructor(initialValue?: number) {\n    this.reset(initialValue);\n  }\n\n  /**\n   * Resets the current progress of the mean calculation.\n   * Optionally, you can pass an initial value to start the calculation.\n   *\n   * @param {number} [initialValue] - The initial value to start the mean calculation with.\n   * @returns {FindMean} The current instance of the FindMean class for chaining.\n   *\n   * @example\n   * const avg = findMean();\n   * avg.push(2, 4);\n   * avg.reset();\n   * console.log(avg.value); // Output: 0\n   */\n  reset(initialValue?: number): FindMean {\n    if (initialValue === undefined) {\n      this.#count = 0;\n      this.#value = 0;\n    } else {\n      this.#count = 1;\n      this.#value = initialValue;\n    }\n\n    return this;\n  }\n\n  /**\n   * Retrieves the current mean value (average).\n   *\n   * @returns {number} The current mean value.\n   *\n   * @example\n   * const avg = findMean();\n   * avg.push(5, 10);\n   * console.log(avg.value); // Output: 7.5 (average of 5, 10)\n   */\n  get value(): number {\n    return this.#value;\n  }\n\n  /**\n   * Retrieves the count of numbers added so far.\n   *\n   * @returns {number} The count of numbers in the set.\n   *\n   * @example\n   * const avg = findMean();\n   * avg.push(10, 20);\n   * console.log(avg.count); // Output: 2\n   */\n  get count(): number {\n    return this.#count;\n  }\n\n  /**\n   * Adds values to the set and updates the running mean.\n   *\n   * @param {...number} values - The values to add to the set.\n   * @returns {FindMean} The current instance of the FindMean class for chaining.\n   *\n   * @example\n   * const avg = findMean();\n   * avg.push(1, 2, 3);\n   * console.log(avg.value); // Output: 2 (average of 1, 2, 3)\n   * console.log(avg.count); // Output: 3\n   */\n  push(...values: number[]): FindMean {\n    for (const item of values) {\n      this.#count++;\n      this.#value += (item - this.#value) / this.#count;\n    }\n\n    return this;\n  }\n}\n\n/**\n * Calculate the running mean (average) of a set of numbers.\n *\n * @param {number} [value] - An optional starting value for the mean calculation.\n * @returns {FindMean} A new instance of FindMean class to calculate running mean.\n *\n * @example\n * // Create a FindMean instance and add values to calculate the average\n * const avg = findMean();\n * avg.push(3, 3, 3.3);\n * console.log(avg.value); // Output: 3.1\n * console.log(avg.count); // Output: 3\n *\n * @group Numbers\n */\nexport function findMean(value?: number): FindMean {\n  return new FindMean(value);\n}\n","import { isNumber, isString } from '@/is';\n\nexport interface FormatNumber {\n  thousands: string;\n  decimal: string;\n}\n\nconst defaultFormat: FormatNumber = {\n  /**\n   * Symbol to separate thousands parts\n   */\n  thousands: ',',\n\n  /**\n   * Symbol to separate decimal part\n   */\n  decimal: '.',\n};\n\nconst regExp = /\\B(?=(\\d{3})+(?!\\d))/g;\n\n/**\n * Formats a number (or string representing a number) into a string with thousands separators and optional decimal points.\n * The function supports customizing the formatting style using the `FormatNumber` object.\n *\n * @param {number | string} value - The number or string to format.\n * If a string is passed, it is parsed to a number before formatting.\n * @param {FormatNumber} [format=defaultFormat] - The format settings for thousands and decimal separators.\n * By default, it uses the `{ thousands: ',', decimal: '.' }`.\n *\n * @returns {string} The formatted number string with appropriate thousands separators and decimal formatting.\n *\n * @example\n * // Format a number with default thousands separator\n * formatNumber(1500);\n * // Returns: '1,500'\n *\n * @example\n * // Format a number with a custom format (e.g., using a comma as the thousands separator)\n * formatNumber(1500.75, { thousands: ' ', decimal: '.' });\n * // Returns: '1 500.75'\n *\n * @group Numbers\n */\nexport function formatNumber(\n  value: number | string,\n  format: FormatNumber = defaultFormat,\n): string {\n  if (isString(value)) {\n    return formatNumber(parseFloat(value), format);\n  }\n\n  if (!isNumber(value)) return '';\n\n  const [integerPart, decimalPart] = value.toFixed(2).split('.');\n\n  let result = String(integerPart).replace(regExp, format.thousands);\n\n  if (decimalPart !== '00') {\n    result += format.decimal + decimalPart;\n  }\n\n  return result;\n}\n","/**\n * Rounds a given number to a specified number of decimal places.\n * The rounding is done using a method that shifts the decimal point, rounds the number, and then shifts it back.\n *\n * @param {number} value - The number to be rounded.\n * @param {number} [digits=2] - The number of decimal places to round to. Defaults to 2 if not provided.\n * @returns {number} The rounded number with the specified number of decimal places.\n *\n * @example\n * round2digits(3.3333333, 1);\n * // Returns: 3.3\n *\n * @example\n * round2digits(3.3333333, 2);\n * // Returns: 3.33\n *\n * @example\n * round2digits(3.3333333, 3);\n * // Returns: 3.333\n *\n * @example\n * round2digits(3.789, 0);\n * // Returns: 4 (rounded to the nearest integer)\n *\n * @group Numbers\n */\nexport function round2digits(value: number, digits: number = 2) {\n  if (digits === 0) {\n    return value << 0;\n  }\n\n  // @ts-expect-error\n  return Number(Math.round(value + 'e' + digits) + 'e-' + digits);\n}\n","import { isString } from '@/is';\nimport { type FormatNumber, formatNumber } from '../formatNumber';\nimport { round2digits } from '../round2digits';\n\nexport interface FormatMoney extends FormatNumber {\n  symbol: string;\n  symbolBefore?: boolean;\n}\n\nconst CURRENCY_FORMAT = new Map<string, FormatMoney>([\n  ['USD', { symbol: '$', thousands: ',', decimal: '.', symbolBefore: true }],\n  ['EUR', { symbol: '€', thousands: '.', decimal: ',', symbolBefore: true }],\n  ['GBP', { symbol: '£', thousands: ',', decimal: '.', symbolBefore: true }],\n  ['JPY', { symbol: '¥', thousands: ',', decimal: '', symbolBefore: true }],\n  ['AUD', { symbol: 'A$', thousands: ',', decimal: '.', symbolBefore: true }],\n  ['CAD', { symbol: 'C$', thousands: ',', decimal: '.', symbolBefore: true }],\n  ['CHF', { symbol: 'CHF', thousands: \"'\", decimal: '.', symbolBefore: true }],\n  ['CNY', { symbol: '¥', thousands: ',', decimal: '.', symbolBefore: true }],\n  ['INR', { symbol: '₹', thousands: ',', decimal: '.', symbolBefore: true }],\n  ['KRW', { symbol: '₩', thousands: ',', decimal: '', symbolBefore: true }],\n  ['RUB', { symbol: '₽', thousands: ' ', decimal: ',', symbolBefore: false }],\n  ['UAH', { symbol: '₴', thousands: ' ', decimal: ',', symbolBefore: false }],\n  ['BRL', { symbol: 'R$', thousands: '.', decimal: ',', symbolBefore: true }],\n  ['MXN', { symbol: '$', thousands: ',', decimal: '.', symbolBefore: true }],\n  ['ZAR', { symbol: 'R', thousands: ' ', decimal: ',', symbolBefore: true }],\n  ['UAH', { symbol: '₴', thousands: ' ', decimal: ',', symbolBefore: true }],\n]);\n\nconst DEF_FORMAT: FormatMoney = {\n  decimal: ' ',\n  thousands: ',',\n  symbol: '',\n  symbolBefore: false,\n};\n\n/**\n * Formats a given number (amount of money) as a currency string.\n * This function supports both integer and floating-point representations of money\n * and automatically applies the appropriate currency formatting for the specified currency code.\n *\n * @param {number} amount - The amount of money to format (in cents or as a floating-point value).\n * @param {string | FormatMoney} formatOrCode - The currency format or the currency code (e.g., 'USD').\n * If the format is passed as a string, the function will look up the format for that currency code.\n * @param {boolean} [intMode=false] - When set to `true`, the amount is considered to be in integer form (i.e., cents).\n * The value will be divided by 100 to convert it to a decimal format.\n *\n * @returns {string} The formatted money string, including the currency symbol and the properly formatted number.\n *\n * @example\n * // Basic formatting with USD currency\n * formatMoney(1500, 'USD');\n * // Returns: '$1,500'\n *\n * @example\n * // Formatting when the amount is in integer form (representing cents)\n * formatMoney(1599, 'USD', true);\n * // Returns: '$15.99'\n *\n * @group Numbers\n */\nexport function formatMoney(\n  amount: number,\n  formatOrCode: string | FormatMoney = 'USD',\n  intMode = false,\n): string {\n  if (intMode) {\n    amount = round2digits(amount / 100, 2);\n  }\n\n  const format = isString(formatOrCode)\n    ? CURRENCY_FORMAT.get(formatOrCode) || {\n        ...DEF_FORMAT,\n        symbol: formatOrCode,\n      }\n    : formatOrCode;\n\n  const formattedNumber = formatNumber(amount, format);\n\n  return format.symbolBefore\n    ? format.symbol + formattedNumber\n    : formattedNumber + format.symbol;\n}\n","/**\n * Humanizes large numbers into a more readable format using suffixes like K, M, B, T (thousand, million, billion, trillion).\n *\n * @param {number | string} input - The number or string to humanize.\n * If the input is a string, it will be parsed into a number.\n * @param {number} [decimals=1] - The number of decimal places to display. Default is 1.\n * @returns {string} A humanized string representation of the number.\n *\n * @example\n * humanize(1000000);\n * // Returns: '1M'\n *\n * @example\n * humanize(1234567890);\n * // Returns: '1.2B'\n *\n * @example\n * humanize(9876543210, 2);\n * // Returns: '9.88B'\n *\n * @example\n * humanize(500);\n * // Returns: '500'\n *\n * @example\n * humanize('1000000');\n * // Returns: '1M'\n *\n * @group Numbers\n */\nexport function humanize(input: number | string, decimals = 1): string {\n  if (input === null || input === undefined) {\n    return String(input);\n  }\n\n  decimals = Math.max(decimals, 0);\n\n  const number = parseInt(input as string, 10);\n\n  if (!Number.isFinite(number)) {\n    return String(input);\n  }\n\n  const signString = number < 0 ? '-' : '';\n  const unsignedNumber = Math.abs(number);\n  const unsignedNumberString = String(unsignedNumber);\n  const numberLength = unsignedNumberString.length;\n  const numberLengths = [13, 10, 7, 4];\n  const bigNumPrefixes = ['T', 'B', 'M', 'k'];\n\n  // small numbers\n  if (unsignedNumber < 1000) {\n    return `${signString}${unsignedNumberString}`;\n  }\n\n  // huge numbers\n  if (numberLength > numberLengths[0] + 3) {\n    return number.toExponential(decimals).replace('e+', 'x10^');\n  }\n\n  // 999 < unsignedNumber < 999,999,999,999,999\n  let length = 0;\n  for (let i = 0; i < numberLengths.length; i++) {\n    const _length = numberLengths[i];\n    if (numberLength >= _length) {\n      length = _length;\n      break;\n    }\n  }\n\n  const decimalIndex = numberLength - length + 1;\n  const unsignedNumberCharacterArray = unsignedNumberString.split('');\n\n  const wholePartArray = unsignedNumberCharacterArray.slice(0, decimalIndex);\n  const decimalPartArray = unsignedNumberCharacterArray.slice(\n    decimalIndex,\n    decimalIndex + decimals + 1,\n  );\n\n  const wholePart = wholePartArray.join('');\n\n  // pad decimalPart if necessary\n  let decimalPart = decimalPartArray.join('');\n  if (decimalPart.length < decimals) {\n    decimalPart += `${Array(decimals - decimalPart.length + 1).join('0')}`;\n  }\n\n  if (decimalPart[0] === '0') {\n    decimals = 0;\n  }\n\n  let output;\n  if (decimals === 0) {\n    output = `${signString}${wholePart}${bigNumPrefixes[numberLengths.indexOf(length)]}`;\n  } else {\n    const outputNumber = Number(`${wholePart}.${decimalPart}`).toFixed(\n      decimals,\n    );\n    output = `${signString}${outputNumber}${bigNumPrefixes[numberLengths.indexOf(length)]}`;\n  }\n\n  return output;\n}\n","import { isNumber, isString } from '@/is';\n\n/**\n * Parses all numbers from a given string and returns them as an array of numbers.\n * Supports dot decimals and ignores commas unless they appear as part of a number format.\n * Returns an empty array when the input is invalid or no numbers are found.\n *\n * @param {unknown} input - The input value to parse numbers from.\n * @returns {number[]} - An array of parsed numbers. Returns an empty array if no numbers are found.\n *\n * @example\n * parseAllNumbers(\"The temperature is -23.5°C and humidity is 60%.\");\n * // Returns: [-23.5, 60]\n *\n * @example\n * parseAllNumbers(\"No numbers here!\");\n * // Returns: []\n *\n * @example\n * parseAllNumbers(42);\n * // Returns: [42]\n *\n * @example\n * parseAllNumbers(\"1,234 and 56.78 are numbers\");\n * // Returns: [1.234, 56.78]\n *\n * @example\n * parseAllNumbers([\"Invalid type\"]);\n * // Returns: []\n *\n * @group Numbers\n */\nexport function parseAllNumbers(value: unknown): number[] {\n  if (isNumber(value)) {\n    return [value];\n  }\n\n  if (!isString(value)) {\n    return [];\n  }\n\n  const matches = value.replace(/,/g, '.').match(/-?\\d+(\\.\\d+)?/g);\n\n  if (!matches) {\n    return [];\n  }\n\n  return matches.map(Number).filter(isNumber);\n}\n","import { round2digits } from '../round2digits';\n\n/**\n * Calculates the specified percentage of a given value.\n * The result is the value multiplied by the percentage divided by 100.\n * Optionally rounds the result to a specified number of decimal places.\n *\n * @param {number} value - The value from which the percentage will be calculated.\n * @param {number} percent - The percentage to calculate from the value.\n * @param {number} [digits] - Optional. The number of decimal places to round the result to. If not provided, the result will not be rounded.\n * @returns {number} The calculated percentage of the value. If `digits` is provided, the result is rounded to the specified decimal places.\n *\n * @example\n * percentOf(200, 20);\n * // Returns: 40 (20% of 200)\n *\n * @example\n * percentOf(200, 20, 2);\n * // Returns: 40.00 (20% of 200 rounded to 2 decimal places)\n *\n * @example\n * percentOf(150, 15);\n * // Returns: 22.5 (15% of 150)\n *\n * @example\n * percentOf(1000, 10, 1);\n * // Returns: 100.0 (10% of 1000 rounded to 1 decimal place)\n *\n * @group Numbers\n */\nexport function percentOf(value: number, percent: number, digits?: number) {\n  let result = (percent / 100) * value;\n\n  if (digits) {\n    result = round2digits(result, digits);\n  }\n\n  return result;\n}\n","import { isNumber, isString } from '@/is';\nimport { clamp } from '@/num';\nimport { parseAlpha } from '../parseAlpha';\nimport type { Color } from '../types';\nimport { number, numberOrPercentage, percentage } from '../utils';\n\nconst rgb3Numbers = new RegExp(\n  `^\n  rgba?\\\\(\n    \\\\s*${number}\\\\s*,\n    \\\\s*${number}\\\\s*,\n    \\\\s*${number}\\\\s*\n    (?:,\\\\s*${numberOrPercentage}\\\\s*)?\n  \\\\)\n  $\n`.replace(/\\n|\\s/g, ''),\n);\n\nconst rgb3Percent = new RegExp(\n  `^\n  rgba?\\\\(\n    \\\\s*${percentage}\\\\s*,\n    \\\\s*${percentage}\\\\s*,\n    \\\\s*${percentage}\\\\s*\n    (?:,\\\\s*${numberOrPercentage}\\\\s*)?\n  \\\\)\n  $\n`.replace(/\\n|\\s/g, ''),\n);\n\nconst rgb4Numbers = new RegExp(\n  `^\n  rgba?\\\\(\n    \\\\s*${number}\n    \\\\s+${number}\n    \\\\s+${number}\n    \\\\s*(?:\\\\s*\\\\/\\\\s*${numberOrPercentage}\\\\s*)?\n  \\\\)\n$\n`.replace(/\\n|\\s/g, ''),\n);\n\nconst rgb4Percent = new RegExp(\n  `^\n  rgba?\\\\(\n    \\\\s*${percentage}\n    \\\\s+${percentage}\n    \\\\s+${percentage}\n    \\\\s*(?:\\\\s*\\\\/\\\\s*${numberOrPercentage}\\\\s*)?\n  \\\\)\n$\n`.replace(/\\n|\\s/g, ''),\n);\n\nconst parseValue = (num: string | number) => {\n  let n = num;\n  if (!isNumber(n))\n    n = n.endsWith('%') ? (parseFloat(n) * 255) / 100 : parseFloat(n);\n  return clamp(Math.round(n), 0, 255);\n};\n\nexport function parseRGB(value: unknown): Color.RGBA | null {\n  if (!isString(value)) return null;\n\n  const rgb =\n    rgb4Numbers.exec(value) ||\n    rgb4Percent.exec(value) ||\n    rgb3Numbers.exec(value) ||\n    rgb3Percent.exec(value);\n\n  if (!rgb) return null;\n\n  const [, r, g, b, a] = rgb;\n\n  return {\n    r: parseValue(r),\n    g: parseValue(g),\n    b: parseValue(b),\n    a: parseAlpha(a),\n  };\n}\n","import type { Color } from '../types';\n\n/**\n * Build css valid color from color channels\n *\n * @example\n * const channels = [255, 255, 255, 0.5];\n *\n * buildCssColor(channels); // 'rgba(255, 255, 255, 0.5)'\n *\n * // with applied opacity factor\n * buildCssColor(channels, 0.1); // 'rgba(255, 255, 255, 0.05)'\n *\n * @group Colors\n */\nexport function buildCssColor(\n  [r, g, b, a = 1]: Color.ColorChannels,\n  opacity = 1,\n): string {\n  return `rgba(${r}, ${g}, ${b}, ${a * opacity})`;\n}\n","import { parseAlpha } from '../parseAlpha';\nimport type { Color } from '../types';\nimport { parseHEX } from './parseHEX';\n\n/**\n * Parsing hex string as color channels\n *\n * @example\n * hexToChannels('#FFFFFF'); // [255, 255, 255, 1]\n * hexToChannels('#FFF'); // [255, 255, 255, 1]\n *\n * @group Colors\n */\nexport function hexToChannels(hexWithAlpha: string): Color.ColorChannels {\n  const [hex, alpha] = hexWithAlpha.split('/');\n  const channels = parseHEX(hex);\n\n  if (!channels) return [0, 0, 0, 0];\n\n  if (alpha) {\n    channels[3] = parseAlpha(alpha);\n  }\n\n  return channels;\n}\n","import type { Color } from '../types';\nimport { parseHSL } from './parseHSL';\n\n/**\n * Parsing HSL string as color channels\n *\n * @example\n * // [128, 51, 204, 0.15]\n * hslToChannels('hsl(270 60% 50% / 15%)');\n *\n * @group Colors\n */\nexport function hslToChannels(value: string): Color.ColorChannels {\n  const parsed = parseHSL(value);\n\n  if (!parsed) return [0, 0, 0, 0];\n\n  let { h, s, l, a } = parsed;\n\n  s /= 100;\n  l /= 100;\n  const k = (n: number) => (n + h / 30) % 12;\n  const p = s * Math.min(l, 1 - l);\n  const f = (n: number) =>\n    l - p * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1)));\n\n  return [\n    Math.round(255 * f(0)),\n    Math.round(255 * f(8)),\n    Math.round(255 * f(4)),\n    a,\n  ];\n}\n","import type { Color } from '../types';\nimport { parseRGB } from './parseRGB';\n\n/**\n * Parsing rgb() string as color channels\n *\n * @example\n * // [255, 0, 0, 0.2]\n * rgbToChannels('rgba(100% 0% 0% / 20%)');\n *\n * @group Colors\n */\nexport function rgbToChannels(value: string): Color.ColorChannels {\n  const rgb = parseRGB(value);\n\n  if (!rgb) return [0, 0, 0, 0];\n\n  return [rgb.r, rgb.g, rgb.b, rgb.a];\n}\n","import { isNumber, isString } from '@/is';\nimport { hexToChannels } from '../hexToChannels';\nimport { hslToChannels } from '../hslToChannels';\nimport { rgbToChannels } from '../rgbToChannels';\nimport type { Color } from '../types';\nimport { isColorChannels } from '../utils';\n\n/**\n * Parse css color and returns color channels\n * @group Colors\n */\nexport function colorToChannels(\n  color: string | Color.ColorChannels,\n): Color.ColorChannels {\n  if (isColorChannels(color)) {\n    return color;\n  }\n\n  if (isString(color)) {\n    color = color.trim();\n\n    if (color[0] === '#') {\n      return hexToChannels(color);\n    } else if (color.startsWith('rgb')) {\n      return rgbToChannels(color);\n    } else if (color.startsWith('rgba')) {\n      return rgbToChannels(color);\n    } else if (color.startsWith('hsl')) {\n      return hslToChannels(color);\n    } else if (color.includes(',')) {\n      const channels = color\n        .split(',')\n        .map(v => parseFloat(v))\n        .filter(isNumber)\n        .slice(0, 4);\n\n      while (channels.length < 3) {\n        channels.push(0);\n      }\n\n      return [...channels, 1].slice(0, 4) as Color.ColorChannels;\n    }\n  }\n\n  console.warn('Failed to convert color into channels', typeof color, color);\n  return [0, 0, 0, 1];\n}\n","import { buildCssColor } from '../buildCssColor';\nimport { colorToChannels } from '../colorToChannels';\nimport { parseAlpha } from '../parseAlpha';\nimport type { Color } from '../types';\n\n/**\n * Returns css valid color with adjusted alpha channel\n *\n * @example\n * alpha('rgba(0, 0, 0, 0.87)', 1); // 'rgba(0, 0, 0, 1)'\n *\n * @group Colors\n */\nexport function alpha(\n  color: string | Color.ColorChannels,\n  newAlpha: number,\n): string {\n  const [r, g, b] = colorToChannels(color);\n\n  return buildCssColor([r, g, b, parseAlpha(newAlpha)], 1);\n}\n","import { colorToChannels } from '../colorToChannels';\nimport type { Color } from '../types';\n\n/**\n * Just mixing of two colors\n *\n * @example\n * const colorA = 'rgb(50, 100, 100)';\n * const colorB = 'rgb(150, 0, 0)';\n *\n * // [100, 50, 50, 1]\n * blendColors(colorA, colorB, 0.5);\n *\n * @group Colors\n */\nexport function blendColors(\n  color1: Color.ColorChannels | string,\n  color2: Color.ColorChannels | string,\n  factor: number,\n): Color.ColorChannels {\n  const [r1, g1, b1, a1] = colorToChannels(color1);\n  const [r2, g2, b2, a2] = colorToChannels(color2);\n\n  return [\n    Math.round(r1 * (1 - factor) + r2 * factor),\n    Math.round(g1 * (1 - factor) + g2 * factor),\n    Math.round(b1 * (1 - factor) + b2 * factor),\n    Math.round(a1 * (1 - factor) + a2 * factor),\n  ];\n}\n","import { isNumber } from '@/is';\nimport type { Color } from '../types';\n\n/**\n * Converts color channels into hex\n *\n * @example\n * const channels = [255, 255, 255, 1];\n *\n * // with alpha channel\n * channelsToHex(channels); // '#FFFFFFFF'\n *\n * // without alpha channel\n * channelsToHex(channels, false); // '#FFFFFF'\n * @group Colors\n */\nexport function channelsToHex(\n  channels: Color.ColorChannels,\n  withAlpha: boolean = true,\n) {\n  const [r, g, b, a] = channels;\n\n  const outParts = [\n    r.toString(16).toUpperCase().padStart(2, '0'),\n    g.toString(16).toUpperCase().padStart(2, '0'),\n    b.toString(16).toUpperCase().padStart(2, '0'),\n  ];\n\n  if (withAlpha && isNumber(a)) {\n    outParts.push(\n      Math.round(a * 255)\n        .toString(16)\n        .substring(0, 2)\n        .toUpperCase()\n        .padStart(2, '0'),\n    );\n  }\n\n  return '#' + outParts.join('');\n}\n","import { parseAlpha } from '../parseAlpha';\nimport type { Color } from '../types';\n\n/**\n * Converts color channels into HSL\n * @group Colors\n */\nexport function channelsToHSL([r, g, b, a]: Color.ColorChannels): Color.HSLA {\n  r /= 255;\n  g /= 255;\n  b /= 255;\n\n  const max = Math.max(r, g, b);\n  const min = Math.min(r, g, b);\n  const delta = max - min;\n\n  const l = (max + min) / 2;\n\n  let h = 0;\n  let s = 0;\n\n  if (delta !== 0) {\n    s = delta / (1 - Math.abs(2 * l - 1));\n\n    if (max === r) {\n      h = ((g - b) / delta) % 6;\n    } else if (max === g) {\n      h = (b - r) / delta + 2;\n    } else if (max === b) {\n      h = (r - g) / delta + 4;\n    }\n\n    h *= 60;\n\n    if (h < 0) {\n      h += 360;\n    }\n  }\n\n  return {\n    h: Math.round(h),\n    s: Math.round(s * 100),\n    l: Math.round(l * 100),\n    a: parseAlpha(a),\n  };\n}\n","import type { Color } from '../types';\n\n/**\n * Converts color channels into RGB\n * @group Colors\n */\nexport function channelsToRGB([r, g, b, a]: Color.ColorChannels): Color.RGBA {\n  return {\n    r,\n    g,\n    b,\n    a,\n  };\n}\n","import { round2digits } from '@/num';\n\n/**\n * Calculate WCAG 2.0 contrast ratio of two luminance\n *\n * @example\n * const l1 = luminance([255, 255, 255, 1]);\n * const l2 = luminance([0, 0, 0, 1]);\n *\n * contrastRatio(l1, l2); // 21\n *\n * @group Colors\n */\nexport function contrastRatio(l1: number, l2: number) {\n  return round2digits((Math.max(l1, l2) + 0.05) / (Math.min(l1, l2) + 0.05), 4);\n}\n","import { noop } from '@/is';\n\nconst defaultWindow = (globalThis as any)?.window as Window | undefined;\n\n/**\n * Create a getter of css variable for container\n * @group Colors\n */\nexport function cssVariable(container: HTMLElement): (name: string) => string {\n  if (!defaultWindow) return noop as any;\n\n  const computedStyles = defaultWindow.getComputedStyle(container);\n\n  return (name: string) => {\n    const patterns = name.split('/', 2);\n\n    if (patterns[0]?.startsWith('--')) {\n      let value = computedStyles.getPropertyValue(patterns[0])?.trim();\n\n      if (patterns[0].startsWith('--v')) {\n        value = `rgb(${value})`;\n      }\n\n      patterns[0] = value;\n    }\n\n    return patterns.join('/');\n  };\n}\n","import { colorToChannels } from '../colorToChannels';\nimport type { Color } from '../types';\n\n/**\n * Linear color interpolating\n *\n * @example\n * // 'rgba(50, 50, 50, 1)'\n * interpolateColor(\n *   'rgb(0, 0, 0)',\n *   'rgb(100, 100, 100)',\n *   0.5\n * );\n *\n * @group Colors\n */\nexport function interpolateColor(\n  color1: string | Color.ColorChannels,\n  color2: string | Color.ColorChannels,\n  factor: number,\n): Color.ColorChannels {\n  const [r1, g1, b1, a1] = colorToChannels(color1);\n  const [r2, g2, b2, a2] = colorToChannels(color2);\n\n  return [\n    Math.round(r1 + factor * (r2 - r1)),\n    Math.round(g1 + factor * (g2 - g1)),\n    Math.round(b1 + factor * (b2 - b1)),\n    a1 + factor * (a2 - a1),\n  ];\n}\n","import type { Color } from '../types';\n\n/**\n * Calculate luminance of color\n *\n * @example\n * luminance([255, 255, 255, 1]); // 1\n * luminance([0, 0, 0, 1]); // 0\n *\n * @group Colors\n */\nexport function luminance([r, g, b]: Color.ColorChannels): number {\n  const a = [r, g, b].map(function (v) {\n    v /= 255;\n    return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);\n  });\n  return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722;\n}\n","import { blendColors } from '../blendColors';\nimport { colorToChannels } from '../colorToChannels';\nimport { contrastRatio } from '../contrastRatio';\nimport { luminance } from '../luminance';\nimport type { Color } from '../types';\n\n/**\n * Returns a color text color that should be on background to keep good contrast\n *\n * @example\n * const bgColor = 'rgb(255, 255, 255)';\n * const tint = 1;\n *\n * // 'rgba(0, 0, 0, 1)'\n * const textColor = tintedTextColor(bgColor, tint);\n *\n * @group Colors\n */\nexport function tintedTextColor(\n  background: string | Color.ColorChannels,\n  tintPercentage = 0.2,\n): Color.ColorChannels {\n  const bgColor = colorToChannels(background);\n  const bgLuminance = luminance(bgColor);\n\n  const whiteLuminance = luminance([255, 255, 255, 1]);\n  const blackLuminance = luminance([0, 0, 0, 1]);\n\n  const contrastWithWhite = contrastRatio(bgLuminance, whiteLuminance);\n  const contrastWithBlack = contrastRatio(bgLuminance, blackLuminance);\n\n  const baseTextColor: Color.ColorChannels =\n    contrastWithWhite >= contrastWithBlack ? [255, 255, 255, 1] : [0, 0, 0, 1];\n\n  const tintedColor = blendColors(baseTextColor, bgColor, tintPercentage);\n\n  const tintedLuminance = luminance(tintedColor);\n  const finalContrast = contrastRatio(bgLuminance, tintedLuminance);\n\n  if (finalContrast < 4.5) {\n    return baseTextColor;\n  }\n\n  return tintedColor;\n}\n","import { parseHEX } from './hexToChannels/parseHEX';\nimport { parseHSL } from './hslToChannels/parseHSL';\nimport { parseRGB } from './rgbToChannels/parseRGB';\nimport type { Color } from './types';\n\nexport type { Color } from './types';\n\nexport type ColorChannels = Color.ColorChannels;\n\n/**\n * General color parser api\n * @group Colors\n */\nexport const ColorParser = {\n  HSL: parseHSL,\n  RGB: parseRGB,\n  HEX: parseHEX,\n};\n\nexport { isColorChannels } from './utils';\n\nexport * from './alpha';\nexport * from './blendColors';\nexport * from './buildCssColor';\nexport * from './channelsToHex';\nexport * from './channelsToHSL';\nexport * from './channelsToRGB';\nexport * from './colorToChannels';\nexport * from './contrastRatio';\nexport * from './cssVariable';\nexport * from './hexToChannels';\nexport * from './hslToChannels';\nexport * from './interpolateColor';\nexport * from './luminance';\nexport * from './parseAlpha';\nexport * from './rgbToChannels';\nexport * from './tintedTextColor';\n","import { isString } from '@/is';\nimport { textEncoder } from '@/str/text';\n\nvar TABLE = new Int32Array([\n  0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,\n  0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,\n  0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,\n  0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,\n  0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,\n  0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,\n  0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,\n  0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,\n  0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,\n  0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,\n  0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,\n  0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,\n  0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,\n  0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,\n  0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,\n  0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,\n  0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,\n  0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,\n  0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,\n  0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,\n  0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,\n  0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,\n  0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,\n  0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,\n  0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,\n  0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,\n  0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,\n  0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,\n  0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,\n  0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,\n  0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,\n  0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,\n  0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,\n  0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,\n  0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,\n  0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,\n  0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,\n  0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,\n  0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,\n  0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,\n  0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,\n  0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,\n  0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,\n]);\n\n/**\n * Calculate crc32 hash from string\n * @group Crypto\n */\nexport function crc32(\n  value: Uint8Array | Uint8Array[] | string,\n  seed?: number,\n): number {\n  if (isString(value)) {\n    return crc32(textEncoder.encode(value), seed);\n  }\n\n  var crc = seed === 0 ? 0 : ~~seed! ^ -1;\n\n  if (value instanceof Uint8Array) {\n    for (var index = 0; index < value.length; index++) {\n      crc = TABLE[(crc ^ value[index]) & 0xff] ^ (crc >>> 8);\n    }\n  } else {\n    for (var current of value) {\n      for (var index = 0; index < current.length; index++) {\n        crc = TABLE[(crc ^ current[index]) & 0xff] ^ (crc >>> 8);\n      }\n    }\n  }\n\n  return crc ^ -1;\n}\n","import { isNumber } from '@/is';\nimport { has } from '@/object';\nimport type { DateObject } from '@/types';\n\n/**\n * Checks if a given value is a valid `DateObject`.\n *\n * A valid `DateObject` is an object that contains numeric `year`, `month`, and `date` properties.\n *\n * @param {unknown} value - The value to be checked.\n * @returns {value is DateObject} - Returns `true` if the value is a valid `DateObject`; otherwise, `false`.\n *\n * @example\n * // Valid DateObject\n * isDateObject({ year: 2024, month: 11, date: 8 }); // true\n *\n * @example\n * // Missing properties\n * isDateObject({ year: 2024, month: 11 }); // false\n *\n * @example\n * // Non-numeric values\n * isDateObject({ year: '2024', month: 11, date: 8 }); // false\n *\n * @example\n * // Non-object input\n * isDateObject('invalid'); // false\n *\n * @example\n * // Additional properties (still valid)\n * isDateObject({ year: 2024, month: 11, date: 8, extra: 'property' }); // true\n *\n * @group Date\n */\nexport function isDateObject(value: unknown): value is DateObject {\n  return (\n    has(value, ['year', 'month', 'date']) &&\n    isNumber(value.year) &&\n    isNumber(value.month) &&\n    isNumber(value.date)\n  );\n}\n","import { assert } from '@/assert';\nimport { isDate, isNumber, isString } from '@/is';\nimport type { DateObject } from '@/types';\nimport { isDateObject } from '../isDateObject';\n\nexport type DateObjectInput = Date | string | number | DateObject;\n\nexport function createDateObject(value: DateObjectInput): DateObject;\nexport function createDateObject(\n  value: DateObjectInput,\n  returnsNullWhenInvalid: true,\n): DateObject | null;\n\n/**\n * Converts a given input into a `DateObject` representing year, month, and date.\n *\n * The function supports inputs in various formats, including a `Date` object,\n * a `number` (timestamp), or an existing `DateObject`. If the input is invalid\n * and `returnsNullWhenInvalid` is set to `true`, the function returns `null`.\n * Otherwise, it throws an error for invalid input.\n\n * @param {DateObjectInput} value - The input to be converted into a `DateObject`.\n * @param {boolean} [returnsNullWhenInvalid=false] - If `true`, returns `null` for invalid input\n * instead of throwing an error.\n * @returns {DateObject | null} - A `DateObject` representing the date, or `null` if input is invalid\n * and `returnsNullWhenInvalid` is set to `true`.\n *\n * @throws {Error} If the input is invalid and `returnsNullWhenInvalid` is `false`.\n *\n * @example\n * // Using a valid Date object\n * createDateObject(new Date('2024-12-08')); // { year: 2024, month: 12, date: 8 }\n *\n * @example\n * // Using a valid timestamp\n * createDateObject(1702032000000); // { year: 2024, month: 12, date: 8 }\n *\n * @example\n * // Using an existing DateObject\n * createDateObject({ year: 2024, month: 12, date: 8 }); // { year: 2024, month: 12, date: 8 }\n *\n * @example\n * // Invalid input, returning null\n * createDateObject('invalid-date', true); // null\n *\n * @example\n * // Invalid input, throwing an error\n * createDateObject('invalid-date'); // Throws \"Failed to date parse: invalid-date.\"\n *\n * @group Date\n */\nexport function createDateObject(\n  value: DateObjectInput,\n  returnsNullWhenInvalid = false,\n): DateObject | null {\n  let result: DateObject | null = null;\n  let inputValue = value;\n\n  if (isNumber(inputValue) || isString(inputValue)) {\n    inputValue = new Date(inputValue);\n  }\n\n  if (isDate(inputValue)) {\n    result = {\n      year: inputValue.getFullYear(),\n      month: inputValue.getMonth() + 1,\n      date: inputValue.getDate(),\n    };\n  } else if (isDateObject(inputValue)) {\n    result = { ...inputValue };\n  }\n\n  assert.ok(\n    returnsNullWhenInvalid || !!result,\n    `Failed to date parse: ${value}.`,\n  );\n\n  return result;\n}\n","import { isNumber, isPlainObject } from '@/is';\nimport type { TimeObject } from '@/types';\n\n/**\n * Checks if a given value is a valid `TimeObject`.\n *\n * @param {unknown} value - The value to check if it's a valid `TimeObject`.\n * @returns {value is TimeObject} - Returns `true` if the value is a valid `TimeObject`, otherwise `false`.\n *\n * @example\n * // Valid TimeObject\n * isTimeObject({ h: 15, m: 30 }); // true\n *\n * @example\n * // Invalid TimeObject (missing `m`)\n * isTimeObject({ h: 15 }); // false\n *\n * @example\n * // Invalid TimeObject (non-number values)\n * isTimeObject({ h: '15', m: 30 }); // false\n * isTimeObject({ h: 15, m: '30' }); // false\n *\n * @example\n * // Invalid TimeObject (out-of-range hours)\n * isTimeObject({ h: -1, m: 30 }); // false\n * isTimeObject({ h: 24, m: 30 }); // false\n *\n * @example\n * // Invalid TimeObject (out-of-range minutes)\n * isTimeObject({ h: 15, m: -1 }); // false\n * isTimeObject({ h: 15, m: 60 }); // false\n *\n * @example\n * // Invalid TimeObject (non-object input)\n * isTimeObject('string'); // false\n * isTimeObject(123); // false\n * isTimeObject([]); // false\n *\n * @group Date\n */\nexport function isTimeObject(value: unknown): value is TimeObject {\n  return (\n    isPlainObject(value) &&\n    'h' in value &&\n    'm' in value &&\n    isNumber(value.h) &&\n    Number.isInteger(value.h) &&\n    isNumber(value.m) &&\n    Number.isInteger(value.m) &&\n    value.h >= 0 &&\n    value.h < 24 &&\n    value.m >= 0 &&\n    value.m < 60\n  );\n}\n","import { assert } from '@/assert';\nimport { isDate, isNumber, isString } from '@/is';\nimport type { TimeObject } from '@/types';\nimport { isTimeObject } from '../isTimeObject';\n\nexport type TimeObjectInput = Date | number | string | TimeObject;\n\nexport function createTimeObject(value: TimeObjectInput): TimeObject;\nexport function createTimeObject(\n  value: TimeObjectInput,\n  returnsNullWhenInvalid: true,\n): TimeObject | null;\n\n/**\n * Converts a given input into a `TimeObject` representing 24 hours and minutes.\n *\n * The function supports inputs in various formats, including `Date`, `number` (timestamp),\n * `string` (date string), or a pre-existing `TimeObject`. If the input is invalid and\n * `returnsNullWhenInvalid` is set to `true`, the function will return `null`; otherwise,\n * it throws an error.\n *\n * @param {TimeObjectInput} value - The input to be converted into a `TimeObject`.\n * @param {boolean} [returnsNullWhenInvalid=false] - If `true`, returns `null` for invalid input\n * instead of throwing an error.\n * @returns {TimeObject | null} - A `TimeObject` representing the time, or `null` if input is invalid\n * and `returnsNullWhenInvalid` is set to `true`.\n *\n * @throws {Error} If the input is invalid and `returnsNullWhenInvalid` is `false`.\n *\n * @example\n * // Using a valid Date object\n * createTimeObject(new Date('2024-12-08T15:30:00')); // { h: 15, m: 30 }\n *\n * @example\n * // Using a valid timestamp\n * createTimeObject(1702031400000); // { h: 15, m: 30 }\n *\n * @example\n * // Using a valid time string\n * createTimeObject('2024-12-08T15:30:00'); // { h: 15, m: 30 }\n *\n * @example\n * // Using an existing TimeObject\n * createTimeObject({ h: 10, m: 45 }); // { h: 10, m: 45 }\n *\n * @example\n * // Invalid input, returning null\n * createTimeObject('invalid-date', true); // null\n *\n * @example\n * // Invalid input, throwing an error\n * createTimeObject('invalid-date'); // Throws \"Failed to time parse: invalid-date.\"\n *\n * @group Date\n */\nexport function createTimeObject(\n  value: TimeObjectInput,\n  returnsNullWhenInvalid = false,\n): TimeObject | null {\n  let result: TimeObject | null = null;\n  let inputValue = value;\n\n  if (isNumber(inputValue)) {\n    inputValue = new Date(inputValue);\n  } else if (isString(inputValue)) {\n    // lest do inline parsing to accept HH:mm:ss\n    const [h, m] = inputValue\n      .split(':')\n      .map(v => v.trim().padStart(2, '0'))\n      .map(v => parseInt(v));\n\n    inputValue = { h, m };\n  }\n\n  if (isDate(inputValue)) {\n    result = {\n      h: inputValue.getHours(),\n      m: inputValue.getMinutes(),\n    };\n  } else if (isTimeObject(inputValue)) {\n    result = { ...inputValue };\n  }\n\n  assert.ok(\n    returnsNullWhenInvalid || !!result,\n    `Failed to time parse: ${value}.`,\n  );\n\n  return result;\n}\n","export type TimeSpanUnit = 'ms' | 's' | 'm' | 'h' | 'd' | 'w';\n\nconst UNIT_TO_MS: Record<TimeSpanUnit, number> = {\n  ms: 1,\n  s: 1000,\n  m: 1000 * 60,\n  h: 1000 * 60 * 60,\n  d: 1000 * 60 * 60 * 24,\n  w: 1000 * 60 * 60 * 24 * 7,\n};\n\n/**\n * A class representing a span of time with a specific value and unit of measurement.\n * Provides methods for conversion between time units and arithmetic operations (add, subtract).\n */\nexport class TimeSpan {\n  constructor(value: number, unit: TimeSpanUnit) {\n    this.value = value;\n    this.unit = unit;\n  }\n\n  /**\n   * The numeric value of the time span\n   */\n  public value: number;\n\n  /**\n   * The unit of the time span.\n   */\n  public unit: TimeSpanUnit;\n\n  /**\n   * Converts the time span to milliseconds.\n   *\n   * @returns {number} The equivalent time span in milliseconds.\n   * @example\n   * const ts = new TimeSpan(2, 'h');\n   * ts.milliseconds(); // Returns 7200000\n   */\n  public milliseconds(): number {\n    const multiplier = UNIT_TO_MS[this.unit];\n    return this.value * multiplier;\n  }\n\n  /**\n   * Converts the time span to seconds.\n   *\n   * @returns {number} The equivalent time span in seconds.\n   * @example\n   * const ts = new TimeSpan(2, 'm');\n   * ts.seconds(); // Returns 120\n   */\n  public seconds(): number {\n    return this.milliseconds() / UNIT_TO_MS.s;\n  }\n\n  /**\n   * Converts the time span to minutes.\n   *\n   * @returns {number} The equivalent time span in minutes.\n   * @example\n   * const ts = new TimeSpan(120, 's');\n   * ts.minutes(); // Returns 2\n   */\n  public minutes(): number {\n    return this.milliseconds() / UNIT_TO_MS.m;\n  }\n\n  /**\n   * Converts the time span to hours.\n   *\n   * @returns {number} The equivalent time span in hours.\n   * @example\n   * const ts = new TimeSpan(120, 'm');\n   * ts.hours(); // Returns 2\n   */\n  public hours(): number {\n    return this.milliseconds() / UNIT_TO_MS.h;\n  }\n\n  /**\n   * Converts the time span to days.\n   *\n   * @returns {number} The equivalent time span in days.\n   * @example\n   * const ts = new TimeSpan(48, 'h');\n   * ts.days(); // Returns 2\n   */\n  public days(): number {\n    return this.milliseconds() / UNIT_TO_MS.d;\n  }\n\n  /**\n   * Converts the time span to weeks.\n   *\n   * @returns {number} The equivalent time span in weeks.\n   * @example\n   * const ts = new TimeSpan(14, 'd');\n   * ts.weeks(); // Returns 2\n   */\n  public weeks(): number {\n    return this.milliseconds() / UNIT_TO_MS.w;\n  }\n\n  /**\n   * Adds a specified value and unit to the current time span.\n   *\n   * Returns new instance.\n   *\n   * @param {number} value - The value to add.\n   * @param {TimeSpanUnit} [unit='ms'] - The unit of the value to add (default is milliseconds).\n   * @returns {TimeSpan} A new TimeSpan instance with the added value.\n   * @example\n   * const ts = new TimeSpan(1, 'h');\n   * ts.add(30, 'm'); // Represents 1.5 hours\n   */\n  public add(value: number, unit: TimeSpanUnit = 'ms'): TimeSpan {\n    const multiplier = UNIT_TO_MS[unit];\n    return new TimeSpan(this.milliseconds() + value * multiplier, 'ms');\n  }\n\n  /**\n   * Subtracts a specified value and unit from the current time span.\n   *\n   * Returns new instance.\n   *\n   * @param {number} value - The value to subtract.\n   * @param {TimeSpanUnit} [unit='ms'] - The unit of the value to subtract (default is milliseconds).\n   * @returns {TimeSpan} A new TimeSpan instance with the subtracted value.\n   * @example\n   * const ts = new TimeSpan(1, 'h');\n   * ts.subtract(30, 'm'); // Represents 30 minutes less than 1 hour\n   */\n  public subtract(value: number, unit: TimeSpanUnit = 'ms'): TimeSpan {\n    const multiplier = UNIT_TO_MS[unit];\n    return new TimeSpan(this.milliseconds() - value * multiplier, 'ms');\n  }\n}\n","import { TimeSpan, type TimeSpanUnit } from './TimeSpan';\n\n/**\n * Creates a new instance of `TimeSpan`.\n *\n * This utility function allows you to create a `TimeSpan` object by providing a numeric value and a unit of time.\n * The default unit is `'ms'` (milliseconds).\n *\n * @param {number} value - The numeric value representing the timespan.\n * @param {TimeSpanUnit} [unit='ms'] - The unit of time for the timespan value. Options are `'ms'`, `'s'`, `'m'`, `'h'`, `'d'`, `'w'`.\n * @returns {TimeSpan} An instance of the `TimeSpan` class.\n * @example\n * // Create a TimeSpan with 500 milliseconds\n * const ts = createTimeSpan(500);\n * console.log(ts.milliseconds()); // 500\n *\n * @example\n * // Create a TimeSpan with 2 hours\n * const ts = createTimeSpan(2, 'h');\n * console.log(ts.seconds()); // 120\n *\n * @example\n * // Create a TimeSpan with 7 days\n * const ts = createTimeSpan(7, 'd');\n * console.log(ts.weeks()); // 1\n *\n * @group Date\n */\nexport function createTimeSpan(\n  value: number,\n  unit: TimeSpanUnit = 'ms',\n): TimeSpan {\n  return new TimeSpan(value, unit);\n}\n","import { isDate, isNumber, isString } from '@/is';\n\n/**\n * The base time as a timestamp, `Date` object,\n * or a similar format that the `timestampMs` function can parse.\n */\nexport type TimestampMsInput = Date | string | number;\n\n/**\n * Returns or converts the given input into milliseconds since the Unix epoch.\n *\n * @param {TimestampMsInput} [fromValue=Date.now()] - The input value to be converted to milliseconds.\n *                          Can be a `Date` object, a timestamp (number), or a string representing a date.\n *                          Defaults to the current time.\n * @returns {number} The number of milliseconds since the Unix epoch. Returns `0` if the input is invalid.\n *\n * @example\n * // Get milliseconds from a Date object\n * timestampMs(new Date('2023-01-01T00:00:00Z')); // 1672531200000\n *\n * @example\n * // Get milliseconds from a timestamp\n * timestampMs(1672531200000); // 1672531200000\n *\n * @example\n * // Get milliseconds from a date string\n * timestampMs('2023-01-01T00:00:00Z'); // 1672531200000\n *\n * @example\n * // Handle invalid input\n * timestampMs('invalid-date'); // 0\n *\n * @example\n * // Use the default value (current time)\n * timestampMs(); // Current timestamp in milliseconds\n *\n * @group Date\n */\nexport function timestampMs(fromValue: TimestampMsInput = Date.now()): number {\n  if (isDate(fromValue)) {\n    fromValue = fromValue.getTime();\n  } else if (isString(fromValue)) {\n    const dt = new Date(fromValue);\n    fromValue = isDate(dt) ? dt.getTime() : 0;\n  }\n\n  return isNumber(fromValue) ? fromValue : 0;\n}\n","import { type TimestampMsInput, timestampMs } from '../timestampMs';\n\n/**\n * Returns a `Date` object representing a time that is the given number of days\n * before or after a base time.\n *\n * @param {number} days - The number of days to add to or subtract from the base time.\n *                        Positive values move forward in time, and negative values move backward.\n * @param {TimestampMsInput} [fromValue=Date.now()] - The base time as a timestamp.\n * @returns {Date} A `Date` object representing the computed time.\n *\n * @example\n * // Get the date 7 days from now\n * dateInDays(7); // Returns a Date object 7 days in the future\n *\n * @example\n * // Get the date 5 days before a specific time\n * dateInDays(-5, new Date('2023-01-01T00:00:00Z')); // Returns 2022-12-27T00:00:00Z\n *\n * @example\n * // Use a timestamp as the base time\n * dateInDays(2, 1672531200000); // Returns a Date object 2 days after the base timestamp\n *\n * @group Date\n */\nexport function dateInDays(\n  days: number,\n  fromValue: TimestampMsInput = Date.now(),\n): Date {\n  return new Date(timestampMs(fromValue) + days * 60 * 60 * 24 * 1000);\n}\n","import { type TimestampMsInput, timestampMs } from '../timestampMs';\n\n/**\n * Returns a `Date` object representing a time that is the given number of seconds\n * before or after a base time.\n *\n * @param {number} seconds - The number of seconds to add to or subtract from the base time.\n *                           Positive values move forward in time, and negative values move backward.\n * @param {TimestampMsInput} [fromValue=Date.now()] - The base time.\n * @returns {Date} A `Date` object representing the computed time.\n *\n * @example\n * // Get the date 60 seconds from now\n * dateInSeconds(60); // Returns a Date object 1 minute in the future\n *\n * @example\n * // Get the date 30 seconds before a specific time\n * dateInSeconds(-30, new Date('2023-01-01T00:00:00Z')); // Returns 2022-12-31T23:59:30Z\n *\n * @example\n * // Use a timestamp as the base time\n * dateInSeconds(10, 1672531200000); // Returns a Date object 10 seconds after the base timestamp\n *\n * @group Date\n */\nexport function dateInSeconds(\n  seconds: number,\n  fromValue: TimestampMsInput = Date.now(),\n): Date {\n  return new Date(timestampMs(fromValue) + seconds * 1000);\n}\n","import { getRandomInt } from '@/num/getRandomInt';\nimport type { TimeObject } from '@/types';\n\n/**\n * Gets a random time within the specified range.\n *\n * Generates a random hour (`h`) and minute (`m`) between the given `startTime` and `endTime`.\n * If no range is provided, it defaults to the full day from `{ h: 0, m: 0 }` to `{ h: 23, m: 59 }`.\n *\n * @param {TimeObject} [startTime={ h: 0, m: 0 }] - The starting range for the random time.\n * @param {TimeObject} [endTime={ h: 23, m: 59 }] - The ending range for the random time.\n * @returns {TimeObject} - A random time object with `h` and `m` values within the given range.\n *\n * @example\n * // Generate a random time within the full day\n * const randomTime = getRandomTime();\n * console.log(randomTime); // e.g., { h: 12, m: 34 }\n *\n * @example\n * // Generate a random time between 9:00 and 17:00\n * const randomTime = getRandomTime({ h: 9, m: 0 }, { h: 17, m: 0 });\n * console.log(randomTime); // e.g., { h: 12, m: 15 }\n *\n * @example\n * // Generate a random time between 8:30 and 10:30\n * const randomTime = getRandomTime({ h: 8, m: 30 }, { h: 10, m: 30 });\n * console.log(randomTime); // e.g., { h: 9, m: 45 }\n *\n * @group Date\n */\nexport function getRandomTime(\n  startTime: TimeObject = { h: 0, m: 0 },\n  endTime: TimeObject = { h: 23, m: 59 },\n): TimeObject {\n  const h = getRandomInt(startTime.h, endTime.h);\n\n  if (startTime.h === endTime.h) {\n    return { h, m: getRandomInt(startTime.m, endTime.m) };\n  }\n\n  if (h === startTime.h) {\n    return { h, m: getRandomInt(startTime.m, 59) };\n  }\n\n  if (h === endTime.h) {\n    return { h, m: getRandomInt(0, endTime.m) };\n  }\n\n  return { h, m: getRandomInt(0, 59) };\n}\n","import { assert } from '@/assert';\nimport { round2digits } from '@/num/round2digits';\n\n/**\n * Converts a decimal representation of hours and minutes (HH.MM) into total seconds.\n *\n * This function takes a decimal number in the format `HH.MM`, where:\n * - The integer part represents the number of hours.\n * - The fractional part represents the minutes (in decimal) and is converted accordingly.\n *\n * It returns the total time in seconds.\n *\n * @param {number} hm - The time represented in HH.MM format (e.g., 2.30 for 2 hours and 30 minutes).\n * @returns {number} - The total number of seconds equivalent to the provided HH.MM value.\n *\n * @example\n * hmToSeconds(1.00);\n * // Returns 3600 (1 hour = 3600 seconds)\n *\n * @example\n * hmToSeconds(2.30);\n * // Returns 9000 (2 hours and 30 minutes = 2 * 3600 + 30 * 60 = 9000 seconds)\n *\n * @example\n * hmToSeconds(0.15);\n * // Returns 900 (0 hours and 15 minutes = 15 minutes = 900 seconds)\n *\n * @example\n * hmToSeconds(3.45);\n * // Returns 13500 (3 hours and 45 minutes = 3 * 3600 + 45 * 60 = 13500 seconds)\n *\n * @group Date\n */\nexport function hmToSeconds(hm: number): number {\n  hm = Number(hm);\n\n  assert.number(hm, 'expected number value');\n\n  const h = Math.floor(hm);\n  const m = round2digits(hm - h) * 100;\n\n  return h * 3600 + m * 60;\n}\n","import { isString } from '@/is';\nimport type { TimeString } from '@/types';\n\n/**\n * Checks if a given value is a valid `TimeString`.\n *\n * @param {unknown} value - The value to check if it's a valid `TimeString`.\n * @returns {value is TimeObject} - Returns `true` if the value is a valid `TimeString`, otherwise `false`.\n *\n * @example\n * // Valid TimeString\n * isTimeString('15:30'); // true\n *\n * @example\n * // Invalid TimeString\n * isTimeObject('15:30:00'); // false\n *\n * @example\n * // Invalid TimeString (out-of-range hours)\n * isTimeObject('26:00'); // false\n *\n * @group Date\n */\nexport function isTimeString(value: unknown): value is TimeString {\n  if (!isString(value)) return false;\n  const parts = value.split(':').map(Number);\n  if (parts.length !== 2) return false;\n  const [h, m] = parts;\n  return h >= 0 && h < 24 && m >= 0 && m < 60;\n}\n","import type { TimeValue } from '@/types';\nimport { isTimeObject } from '../isTimeObject';\nimport { isTimeString } from '../isTimeString';\n\n/**\n * Checks if a given value is a valid `TimeValue`.\n *\n * @param {unknown} value - The value to check if it's a valid `TimeValue`.\n * @returns {value is TimeObject} - Returns `true` if the value is a valid `TimeValue`, otherwise `false`.\n *\n * @example\n * // Valid TimeObject\n * isTimeValue({ h: 15, m: 30 }); // true\n *\n * @example\n * // Valid TimeString\n * isTimeValue('15:30'); // true\n *\n * @group Date\n */\nexport function isTimeValue(value: unknown): value is TimeValue {\n  return isTimeString(value) || isTimeObject(value);\n}\n","import { isNumber } from '@/is';\n\n/**\n * Checks if a given value is a valid weekday number.\n *\n * A valid weekday number is a number between 1 (Monday) and 7 (Sunday), inclusive.\n *\n * @param {unknown} value - The value to check if it's a valid weekday number.\n * @returns {value is number} - Returns `true` if the value is a number and represents a valid weekday, otherwise `false`.\n *\n * @example\n * // Valid weekday numbers\n * isValidWeekDay(1); // true\n * isValidWeekDay(7); // true\n *\n * @example\n * // Invalid weekday numbers\n * isValidWeekDay(0); // false\n * isValidWeekDay(8); // false\n * isValidWeekDay(-1); // false\n * isValidWeekDay('3'); // false\n * isValidWeekDay(null); // false\n * isValidWeekDay(undefined); // false\n *\n * @group Date\n */\nexport function isValidWeekDay(value: unknown): value is number {\n  return isNumber(value) && Number.isInteger(value) && value >= 1 && value <= 7;\n}\n","import { assert } from '@/assert';\nimport { round2digits } from '@/num/round2digits';\n\n/**\n * Converts seconds to a decimal representation of hours and minutes (HH.MM) rounded to two decimal places.\n *\n * This function takes a number of seconds, calculates the number of whole hours and minutes,\n * and converts them into a two-decimal representation where:\n * - The integer part represents the hours.\n * - The fractional part represents the minutes (rounded to 2 digits).\n *\n * @param {number} seconds - The total number of seconds to convert into hours and minutes.\n * @returns {number} - A decimal number in the format HH.MM representing the converted time.\n *\n * @example\n * secondsToHm(3661);\n * // Returns 1.01 (1 hour and 1 minute)\n *\n * @example\n * secondsToHm(7322);\n * // Returns 2.02 (2 hours and 2 minutes)\n *\n * @example\n * secondsToHm(59);\n * // Returns 0.59 (0 hours and 59 minutes)\n *\n * @example\n * secondsToHm(3600);\n * // Returns 1.00 (exactly 1 hour)\n *\n * @group Date\n */\nexport function secondsToHm(seconds: number): number {\n  const value = Number(seconds);\n\n  assert.number(value, 'expected number value');\n\n  const h = Math.floor(value / 3600);\n  const m = Math.floor((value % 3600) / 60);\n\n  return round2digits(h + m / 100, 2);\n}\n","import { assert } from '@/assert';\nimport { isNumber } from '@/is';\nimport type { TimeObject } from '@/types';\n\nexport function timeFromMinutes(value: number): TimeObject;\nexport function timeFromMinutes(\n  value: number,\n  returnsNullWhenInvalid: true,\n): TimeObject | null;\n\n/**\n * Converts a total number of minutes into a time object with hours and minutes.\n *\n * @param {number} value - The total number of minutes to be converted.\n *                         Can be positive, negative, or zero.\n * @param {boolean} [returnsNullWhenInvalid=false] - If `true`, the function returns `null`\n *                         instead of throwing an error when the input is invalid.\n *                         Defaults to `false`.\n * @returns {TimeObject | null} An object representing the time in `{ h: hours, m: minutes }` format,\n *                              or `null` if `returnsNullWhenInvalid` is `true` and the input is invalid.\n *\n * @throws {Error} If the input is not a number and `returnsNullWhenInvalid` is `false`.\n *\n * @example\n * // Convert 150 minutes to time\n * timeFromMinutes(150); // { h: 2, m: 30 }\n *\n * @example\n * // Handle invalid input with `returnsNullWhenInvalid` set to `true`\n * timeFromMinutes('invalid', true); // null\n *\n * @example\n * // Handle negative minutes\n * timeFromMinutes(-90); // { h: 22, m: 30 }\n *\n * @group Date\n */\nexport function timeFromMinutes(\n  value: number,\n  returnsNullWhenInvalid = false,\n): TimeObject | null {\n  if (!isNumber(value)) {\n    assert.ok(\n      returnsNullWhenInvalid,\n      'Failed to time parse from minutes: ' + value,\n    );\n    return null;\n  }\n\n  if (value === 0) {\n    return { h: 0, m: 0 };\n  }\n\n  value = value % 1440;\n\n  if (value < 0) {\n    value += 1440;\n  }\n\n  const h = Math.floor(value / 60);\n  const m = value % 60;\n\n  return { h, m };\n}\n","import { isNumber } from '@/is';\n\n/**\n * Converts a Unix timestamp (in seconds) to a `Date` object.\n *\n * This function accepts a timestamp in seconds (number) and returns a `Date` object\n * corresponding to that timestamp. If an invalid number is passed (non-numeric or NaN),\n * it returns `null`.\n *\n * @param {number} value - The Unix timestamp (in seconds) to convert into a `Date` object.\n * @returns {Date | null} The `Date` object corresponding to the provided timestamp, or `null`\n * if the value is not a valid number.\n *\n * @example\n * const date = timestampToDate(1609459200);\n * console.log(date); // Outputs: Thu Jan 01 2021 00:00:00 GMT+0000 (UTC)\n *\n * // Invalid input\n * console.log(timestampToDate('invalid')); // Outputs: null\n * console.log(timestampToDate(NaN)); // Outputs: null\n * console.log(timestampToDate(null)); // Outputs: null\n *\n * @group Date\n */\nexport function timestampToDate(value: number): Date | null {\n  if (!isNumber(value)) return null;\n  return new Date(value * 1000);\n}\n","import { assert } from '@/assert';\nimport type { TimeValue } from '@/types';\nimport { createTimeObject } from '../createTimeObject';\n\nexport function timeStringify(value: TimeValue): string;\nexport function timeStringify(\n  value: TimeValue,\n  returnsNullWhenInvalid: true,\n): string | null;\n\n/**\n * Converts a time value into a string formatted as \"HH:MM\".\n *\n * @param {TimeValue} value - A time value.\n * @param {boolean} [returnsNullWhenInvalid=false] - If `true`, the function returns `null`\n *                         instead of throwing an error when the input is invalid.\n *                         Defaults to `false`.\n * @returns {string | null} A string representing the time in \"HH:MM\" format, or `null`\n *                          if the input is invalid and `returnsNullWhenInvalid` is `true`.\n *\n * @throws {Error} If the input is invalid and `returnsNullWhenInvalid` is `false`.\n *\n * @example\n * // Convert a time object to a string\n * timeStringify({ h: 9, m: 5 }); // \"09:05\"\n *\n * @example\n * // Convert a string time value to a formatted string\n * timeStringify(\"7:30\"); // \"07:30\"\n *\n * @example\n * // Handle invalid input gracefully\n * timeStringify(\"invalid\", true); // null\n *\n * @example\n * // Handle invalid input with exception\n * timeStringify(\"invalid\"); // Throws Error\n *\n * @group Date\n */\nexport function timeStringify(\n  value: TimeValue,\n  returnsNullWhenInvalid = false,\n): string | null {\n  const timeObject = createTimeObject(value, true);\n\n  if (!timeObject) {\n    assert.ok(\n      returnsNullWhenInvalid,\n      'Failed to stringify time from: ' + JSON.stringify(value),\n    );\n    return null;\n  }\n\n  let { h, m } = timeObject;\n\n  const hStr = Math.ceil(h).toString().padStart(2, '0').slice(-2);\n  const mStr = Math.ceil(m).toString().padStart(2, '0').slice(-2);\n\n  return `${hStr}:${mStr}`;\n}\n","import type { TimeValue } from '@/types';\nimport { createTimeObject } from '../createTimeObject';\n\n/**\n * Converts a time value into the total number of minutes.\n *\n * @param {TimeValue} value - A time value\n *\n * @returns {number} The total number of minutes represented by the time value.\n *\n * @example\n * // Assuming createTimeObject(\"2:30\") returns { h: 2, m: 30 }\n * timeToMinutes(\"2:30\"); // 150\n *\n * // Assuming createTimeObject({ h: 1, m: 45 }) returns { h: 1, m: 45 }\n * timeToMinutes({ h: 1, m: 45 }); // 105\n *\n * @group Date\n */\nexport function timeToMinutes(value: TimeValue): number {\n  const time = createTimeObject(value);\n  return time.h * 60 + time.m;\n}\n","/**\n * Determines the number of ISO weeks in a given year.\n *\n * The ISO week numbering system defines a year as having 52 or 53 full weeks.\n *\n * @param {number} year - The year for which to calculate the number of ISO weeks.\n * @returns {number} - Returns 52 or 53 based on the ISO 8601 standard.\n *\n * @example\n * // Common year with 52 weeks\n * weeksInYear(2023); // 52\n *\n * @example\n * // Leap year with 53 weeks\n * weeksInYear(2020); // 53\n *\n * @group Date\n */\nexport function weeksInYear(year: number): number {\n  const target = new Date(Date.UTC(year + 1, 0, 1));\n  const dayNumber = target.getDay();\n\n  return dayNumber < 4 ? 52 : 53;\n}\n","import { EJSON } from './ejson';\nimport { isNumber } from './is';\nimport { round2digits } from './num/round2digits';\n\ntype Dict<T> = { [key: string]: T | undefined };\n\ntype ListTypeName = 'bool' | 'int' | 'decimal' | 'string';\n\ntype ListTypeNameToType<T extends ListTypeName> = T extends 'bool'\n  ? boolean\n  : T extends 'int'\n    ? number\n    : T extends 'decimal'\n      ? number\n      : T extends 'string'\n        ? string\n        : never;\n\n/**\n * Environment variable parser\n *\n * @group Environment\n */\nexport interface EnvParser {\n  /**\n   * NODE_ENV is `development`\n   */\n  readonly isDevelopment: boolean;\n\n  /**\n   * NODE_ENV is `production`\n   */\n  readonly isProduction: boolean;\n\n  /**\n   * NODE_ENV is `stage`\n   */\n  readonly isStage: boolean;\n\n  /**\n   * NODE_ENV is `test`\n   */\n  readonly isTest: boolean;\n\n  /**\n   * Returns `true` when environment key has set to `\"true\"`\n   *\n   * Returns `defaultValue` when key is not defined\n   */\n  bool(key: string, defaultValue?: boolean): boolean;\n\n  /**\n   * Returns `number` when environment key has correct number value.\n   *\n   * Returns `defaultValue` when environment key is not defined or has invalid number value\n   */\n  int(key: string, defaultValue?: number): number;\n\n  /**\n   * Returns `number` when environment key has correct number value.\n   *\n   * Returns `defaultValue` when environment key is not defined or has invalid number value\n   */\n  decimal(key: string, dights?: number, defaultValue?: number): number;\n\n  /**\n   * Returns `string` when environment key has defined.\n   *\n   * Returns `defaultValue` when environment key is not defined\n   */\n  string(key: string, defaultValue?: string): string;\n\n  /**\n   * Returns `array` of parsed environment value.\n   *\n   * Returns `defaultValue` when key is not defined\n   */\n  list<T extends ListTypeName>(\n    key: string,\n    itemType: T,\n    defaultValue?: ListTypeNameToType<T>[],\n  ): ListTypeNameToType<T>[];\n\n  /**\n   * Returns parsed json value.\n   *\n   * Returns `defaultValue` when key is not defined or invalid json value\n   */\n  json<T = any>(key: string, defaultValue?: T | null): T | null;\n}\n\n/**\n * Ready-to-use environment parser.\n *\n * Target: `process.env`\n *\n * Fallback: `import.meta.env`\n *\n * @example\n *\n * // env.string\n * const API_KEY = env.string('API_KEY', 'test_key');\n *\n * // env.bool\n * const TEST_FEATURE = env.bool('TEST_FEATURE', false);\n *\n * // env.int\n * const RETRY_ATTEMPTS = env.int('RETRY_ATTEMPTS', 5);\n *\n * // env.decimal\n * const DELAY_SECONDS = env.decimal('DELAY_SECONDS', 2, 5); // round to 2 dights\n *\n * // env.list\n * const TARGET_ROLES = env.list('TARGET_ROLES', 'string', ['ADMIN']);\n *\n * // env.json\n * const GOOGLE_CREDS = env.json<{ projectId: string; token: string; }>('GOOGLE_CREDS');\n *\n * @group Environment\n */\nexport const env: Readonly<EnvParser> = (() => {\n  if ((globalThis as any)?.process) {\n    return createEnvParser(process.env);\n  } else {\n    return createEnvParser((import.meta as any).env);\n  }\n})();\n\n/**\n * @example\n * const env = createEnvParser(process.env);\n * // const env = createEnvParser(import.meta.env);\n *\n * const API_KEY = env.string('API_KEY', 'test_key');\n *\n * @group Environment\n */\nexport function createEnvParser(\n  targetObject: Record<string, string> | Dict<string>,\n): Readonly<EnvParser> {\n  return Object.freeze({\n    get isDevelopment() {\n      return targetObject.NODE_ENV === 'development';\n    },\n\n    get isProduction() {\n      return targetObject.NODE_ENV === 'production';\n    },\n\n    get isStage() {\n      return targetObject.NODE_ENV === 'state';\n    },\n\n    get isTest() {\n      return targetObject.NODE_ENV === 'test';\n    },\n\n    bool(key: string, defaultValue: boolean = false): boolean {\n      if (!(key in targetObject)) {\n        return defaultValue;\n      }\n\n      return parseBoolean(targetObject[key]) ?? defaultValue;\n    },\n\n    int(key: string, defaultValue: number = 0): number {\n      if (!(key in targetObject)) {\n        return defaultValue;\n      }\n\n      return _parseInt(targetObject[key]) ?? defaultValue;\n    },\n\n    decimal(key: string, dights = undefined, defaultValue: number = 0): number {\n      if (!(key in targetObject)) {\n        return isNumber(dights)\n          ? round2digits(defaultValue, dights)\n          : defaultValue;\n      }\n\n      return parseDecimal(targetObject[key], dights) ?? defaultValue;\n    },\n\n    string(key: string, defaultValue: string = ''): string {\n      return targetObject[key] ?? defaultValue;\n    },\n\n    list<T extends ListTypeName>(\n      key: string,\n      type: T,\n      defaultValue: ListTypeNameToType<T>[] = [],\n    ): ListTypeNameToType<T>[] {\n      if (!(key in targetObject)) {\n        return defaultValue;\n      }\n\n      const parsers: Record<ListTypeName, (value: unknown) => any> = {\n        int: _parseInt,\n        bool: parseBoolean,\n        decimal: v => parseDecimal(v, 2),\n        string: v => v,\n      };\n\n      return ((targetObject as any)[key] as string)\n        .split(',')\n        .map((value, idx) => {\n          const parsedValue = parsers[type](value.trim());\n\n          if (parsedValue === undefined) {\n            console.warn('Warn! Failed to parse list item as ' + type, {\n              key,\n              idx,\n              type,\n              value,\n            });\n          }\n\n          return parsedValue;\n        })\n        .filter(v => v !== undefined);\n    },\n\n    json<T = any>(key: string, defaultValue: T | null = null): T | null {\n      if (!(key in targetObject)) {\n        return defaultValue;\n      }\n\n      try {\n        return EJSON.parse<T>(targetObject[key] as string);\n      } catch (err) {\n        console.warn('Failed to parse json env variable', key);\n        return defaultValue;\n      }\n    },\n  });\n}\n\nfunction parseBoolean(value: unknown): boolean | undefined {\n  if (value === 'true') return true;\n  if (value === 'false') return false;\n\n  return undefined;\n}\n\nfunction _parseInt(value: unknown): number | undefined {\n  const parsed = parseInt(value as any);\n\n  return isNumber(parsed) ? parsed : undefined;\n}\n\nfunction parseDecimal(value: unknown, dights?: number): number | undefined {\n  const parsed = parseFloat(value as any);\n\n  return isNumber(parsed)\n    ? isNumber(dights)\n      ? round2digits(parsed, dights)\n      : parsed\n    : undefined;\n}\n","import { isNumber } from '../is.js';\n\nconst CODE_TO_MESSAGE: Record<number, string> = Object.freeze({\n  100: 'Continue',\n  101: 'Switching Protocols',\n  102: 'Processing',\n  103: 'Early Hints',\n\n  200: 'OK',\n  201: 'Created',\n  202: 'Accepted',\n  203: 'Non-Authoritative Information',\n  204: 'No Content',\n  205: 'Reset Content',\n  206: 'Partial Content',\n\n  300: 'Multiple Choices',\n  301: 'Moved Permanently',\n  302: 'Found',\n  303: 'See Other',\n  304: 'Not Modified',\n  305: 'Use Proxy',\n  307: 'Temporary Redirect',\n  308: 'Permanent Redirect',\n\n  400: 'Bad Request',\n  401: 'Unauthorized',\n  402: 'Payment Required',\n  403: 'Forbidden',\n  404: 'Not Found',\n  405: 'Method Not Allowed',\n  406: 'Not Acceptable',\n  407: 'Proxy Authentication Required',\n  408: 'Request Timeout',\n  409: 'Conflict',\n  410: 'Gone',\n  411: 'Length Required',\n  412: 'Precondition Failed',\n  413: 'Payload Too Large',\n  414: 'URI Too Long',\n  415: 'Unsupported Media Type',\n  416: 'Range Not Satisfiable',\n  417: 'Expectation Failed',\n  418: \"I'm a teapot\",\n  422: 'Unprocessable Entity',\n  425: 'Too Early',\n  426: 'Upgrade Required',\n  428: 'Precondition Required',\n  429: 'Too Many Requests',\n  431: 'Request Header Fields Too Large',\n\n  500: 'Internal Server Error',\n  501: 'Not Implemented',\n  502: 'Bad Gateway',\n  503: 'Service Unavailable',\n  504: 'Gateway Timeout',\n  505: 'HTTP Version Not Supported',\n  506: 'Variant Also Negotiates',\n  507: 'Insufficient Storage',\n  508: 'Loop Detected',\n  510: 'Not Extended',\n  511: 'Network Authentication Required',\n});\n\nexport interface AppErrorOptions extends ErrorOptions {\n  /**\n   * Custom error code\n   */\n  code?: string;\n}\n\n/**\n * Simple application error class with the code\n * @group Errors\n */\nexport class AppError extends Error {\n  /**\n   * HTTP valid status code\n   */\n  statusCode: number;\n\n  /**\n   * Custom error code\n   */\n  code?: string;\n\n  constructor(message: string, statusCode?: number, options?: AppErrorOptions);\n\n  /**\n   * Message will be generated from status code\n   */\n  constructor(statusCode: number, options?: AppErrorOptions);\n\n  constructor(...args: any[]) {\n    let message = 'Unknown error';\n    let statusCode = 500;\n    let code = 'ERR_UNKNOWN';\n    let options: AppErrorOptions | undefined;\n\n    if (isNumber(args[0])) {\n      statusCode = args[0];\n      message = CODE_TO_MESSAGE[statusCode] || message;\n      options = args[1];\n    } else {\n      message = args[0] || CODE_TO_MESSAGE[statusCode] || message;\n      statusCode = isNumber(args[1]) ? args[1] : statusCode;\n      options = args[2];\n    }\n\n    // Call base class constructor\n    super(message, options);\n\n    if (typeof Error.captureStackTrace !== 'function') {\n      this.stack = new Error().stack;\n    } else {\n      Error.captureStackTrace(this, AppError);\n    }\n\n    this.statusCode = statusCode;\n    this.code = options?.code ?? code;\n  }\n\n  get name() {\n    return 'AppError';\n  }\n\n  static is(value: any): value is AppError {\n    return value instanceof AppError || value?.name === 'AppError';\n  }\n}\n","import { isString } from '@/is';\n\n/**\n * Extract file extension from string\n *\n * @example\n * getFileExtension('Andrew L - CV.pdf'); // 'pdf'\n *\n * @group Files\n */\nexport function getFileExtension(name: string, withDot = true): string | null {\n  if (!isString(name)) {\n    return null;\n  }\n\n  const ext = name.split('.').at(-1)?.split('?')?.at(0);\n  return ext ? (withDot ? `.${ext}` : ext) : null;\n}\n","import { isString } from '@/is';\nimport { hasProtocol } from '@/str/hasProtocol';\nimport { getFileExtension } from '../getFileExtension';\n\n/**\n * Extract filename from string\n *\n * @example\n * getFileName('Andrew L - CV.pdf'); // 'Andrew L - CV'\n *\n * @group Files\n */\nexport function getFileName(value: string): string | null {\n  if (hasProtocol(value)) {\n    return getFileName(decodeURI(value.split('/').at(-1)?.split('?')?.at(0)!));\n  }\n\n  if (!isString(value)) return null;\n\n  const ext = getFileExtension(value, true);\n\n  if (!ext) {\n    return value;\n  }\n\n  return value.slice(0, -ext.length);\n}\n","/**\n * Filters an array of paths to retain only the most specific (deepest) paths,\n * removing any path that is a prefix of another path.\n *\n * @param {string[]} keys - An array of dot-separated string paths.\n * @returns {string[]} - A new array containing only the most specific paths.\n *\n * @example\n * const inputPaths = [\n *   'profile',\n *   'profile.basic',\n *   'profile.basic.fullName',\n *   'profile.updatedAt'\n * ];\n *\n * const result = getMostSpecificPaths(inputPaths);\n * console.log(result); // ['profile.basic.fullName', 'profile.updatedAt']\n *\n * @group Files\n */\nexport function getMostSpecificPaths(keys: string[]): string[] {\n  keys = [...keys].sort();\n\n  const result = [];\n\n  for (let i = 0; i < keys.length; i++) {\n    const currentPath = keys[i];\n    const nextPath = keys[i + 1];\n\n    if (currentPath === nextPath) continue;\n\n    if (!nextPath || !nextPath.startsWith(currentPath + '.')) {\n      result.push(currentPath);\n    }\n  }\n\n  return result;\n}\n","/**\n * Converts bytes amount into human readably string\n *\n * @example\n * humanFileSize(1024); // 1KB\n *\n * @group Files\n */\nexport function humanFileSize(\n  bytes: number,\n  digits: number = 1,\n  withSpace: boolean = true,\n): string {\n  const thresh = 1024;\n  const units = ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n\n  if (Math.abs(bytes) < thresh) {\n    return (bytes / thresh).toFixed(digits) + ` ${units[0]}`;\n  }\n\n  let u = -1;\n  const r = 10 ** digits;\n\n  do {\n    bytes /= thresh;\n    ++u;\n  } while (\n    Math.round(Math.abs(bytes) * r) / r >= thresh &&\n    u < units.length - 1\n  );\n\n  return bytes.toFixed(digits) + (withSpace ? ' ' : '') + units[u];\n}\n","import { assert } from './assert';\nimport { env } from './env';\nimport { isString } from './is';\nimport { sprintf } from './str/sprintf';\nimport type { Logger } from './types';\n\nexport type LogLevel = Exclude<keyof Logger, 'extend'>;\n\nconst LEVEL_NAME_TO_NUM: Record<LogLevel, number> = {\n  debug: 0,\n  log: 1,\n  info: 2,\n  warn: 3,\n  error: 4,\n};\n\nconst LEVEL_NUM_TO_NAME: Record<number, LogLevel> = {\n  0: 'debug',\n  1: 'log',\n  2: 'info',\n  3: 'warn',\n  4: 'error',\n};\n\nconst LOG_LEVEL = env.string('LOG_LEVEL', 'info');\n\nlet currentLogLevel: number =\n  LOG_LEVEL in LEVEL_NAME_TO_NUM\n    ? LEVEL_NAME_TO_NUM[LOG_LEVEL as LogLevel]\n    : LEVEL_NAME_TO_NUM.log;\n\n/**\n * Set global log level.\n * @group Utility Functions\n */\nexport const setLoggerLevel = (level: LogLevel) => {\n  assert.number(LEVEL_NAME_TO_NUM[level], `Invalid log level: ${level}`);\n  currentLogLevel = LEVEL_NAME_TO_NUM[level];\n};\n\n/**\n * Set global log level.\n * @group Utility Functions\n */\nexport const getLoggerLevel = (): LogLevel => {\n  return LEVEL_NUM_TO_NAME[currentLogLevel];\n};\n\n/**\n * Create pretty simple `console.log` wrapper interface.\n *\n * @example\n * const log = logger('UserService');\n *\n * log.info('Create user: %s', 'user_1'); // Create user: %s\n *\n * @group Utility Functions\n */\nexport const logger = (...baseArgs: any[]): Logger => {\n  // handle meta.url\n  if (isString(baseArgs[0]?.url)) {\n    baseArgs[0] = baseArgs[0]?.url;\n  }\n\n  // normalize meta.url\n  if (typeof baseArgs[0] === 'string' && baseArgs[0][0] !== '[') {\n    baseArgs[0] = `[${baseArgs[0].split('/')!.at(-1)!.split('?', 1)[0]!}]`;\n  }\n\n  const writeLog = (level: LogLevel, ...[pattern, ...args]: any[]) => {\n    const levelNum = LEVEL_NAME_TO_NUM[level];\n\n    if (levelNum < currentLogLevel) {\n      return;\n    }\n\n    if (!isString(pattern)) {\n      // eslint-disable-next-line no-console\n      console[level](...baseArgs, pattern, ...args);\n      return;\n    }\n\n    const unusedArgs: any[] = [];\n    const formatted = sprintf(pattern, args, unusedArgs);\n\n    // eslint-disable-next-line no-console\n    console[level](...baseArgs, formatted, ...unusedArgs);\n  };\n\n  const log = writeLog.bind(null, 'log');\n\n  const info = writeLog.bind(null, 'info');\n\n  const warn = writeLog.bind(null, 'warn');\n\n  const error = writeLog.bind(null, 'error');\n\n  const debug = writeLog.bind(null, 'debug');\n\n  const extend = (...args: any[]) => {\n    return logger(...baseArgs, ...args);\n  };\n\n  const instance = {\n    log,\n    info,\n    warn,\n    error,\n    debug,\n    extend,\n  };\n\n  return instance;\n};\n","import { fastIdle } from '../fastIdle';\n\n/**\n * Creates a cooldown function that resolves after a specified number of executions (`amount`).\n * The cooldown can either occur on the `next` tick or after a specified delay.\n *\n * This is useful for controlling the rate of asynchronous operations, allowing you to pause\n * for a specified amount of time after a certain number of iterations in a loop.\n *\n * @example\n * // Create a cooldown function that waits 1 tick for every 10th execution\n * const cooldown = nextTickIteration(10);\n *\n * for (const item of array) {\n *     await cooldown(); // Wait 1 tick for every 10th call\n *     // Perform some async operation here\n * }\n *\n * @example\n * // Create a cooldown function with a 100ms delay after every 5 executions\n * const cooldownWithDelay = nextTickIteration(5, 100);\n * for (const item of array) {\n *     await cooldownWithDelay(); // Wait 100ms after every 5th call\n *     // Perform some async operation here\n * }\n *\n * @param amount The number of executions after which the cooldown should occur.\n * @param delay The delay type or amount. If 'tick', it uses the next idle tick.\n *              If a number is provided, it specifies a delay in milliseconds.\n * @returns A function that, when called, returns a promise resolving after the specified cooldown period.\n *\n * @group Promise\n */\nexport function nextTickIteration(\n  amount: number,\n  delay: number | 'tick' = 'tick',\n): () => Promise<void> {\n  var counter = 0;\n  var tickInterval = delay === 'tick';\n\n  return () => {\n    counter++;\n\n    if (counter >= amount) {\n      counter = 0;\n      return new Promise(resolve => {\n        if (tickInterval) {\n          fastIdle(resolve);\n        } else {\n          setTimeout(resolve, delay as number);\n        }\n      });\n    }\n\n    return Promise.resolve();\n  };\n}\n","import { nextTickIteration } from '../nextTickIteration';\n\n/**\n * Asynchronously filters an array using an async predicate function.\n *\n * This function processes an array using an async function as the predicate,\n * allowing you to avoid blocking the event loop while iterating over large arrays.\n * It ensures that the iteration happens asynchronously with minimal impact on the event loop,\n * making it useful for processing large datasets or performing async operations on each element.\n *\n * @param array - The array to be filtered.\n * @param predicate - The async predicate function.\n *  It takes three arguments: the current value, the index of the current value, and the full array.\n *  It should return a boolean value or a promise that resolves to a boolean indicating whether the value should be kept in the result array.\n *\n * @returns {Promise<T[]>} A promise that resolves to a new array containing the elements that satisfy the predicate.\n *\n * @example\n * const users = Array.from({ length: 100000 }).map((_, idx) => ({\n *   id: idx,\n *   name: 'User: ' + (idx + 1)\n * }));\n *\n * async function first100Users() {\n *   return await asyncFilter(users, (user) => user.id < 100);\n * }\n *\n * Promise.all([\n *   first100Users(),\n *   otherUsefulTask(),\n * ]).then(console.log);\n *\n * @group Promise\n */\nexport function asyncFilter<T>(\n  array: T[],\n  predicate: (\n    value: T,\n    index: number,\n    array: Array<T>,\n  ) => Promise<boolean> | boolean,\n  { concurrency = 1 } = {},\n): Promise<T[]> {\n  concurrency = Math.max(concurrency, 1);\n\n  if (array.length === 0) {\n    return Promise.resolve([]);\n  }\n\n  var result: number[] = [];\n  var currentIndex = 0;\n  var completed = 0;\n  var hasError = false;\n  var cooldown = nextTickIteration(10);\n\n  return new Promise((resolve, reject) => {\n    var processItem = (index: number) => {\n      if (hasError || index >= array.length) return;\n\n      cooldown()\n        .then(() => predicate(array[index], index, array))\n        .then(include => {\n          if (hasError) return;\n          if (include) {\n            result.push(index);\n          }\n\n          completed++;\n\n          if (completed >= array.length) {\n            resolve(result.toSorted((a, b) => a - b).map(idx => array[idx]));\n          } else {\n            if (currentIndex < array.length) {\n              processItem(currentIndex++);\n            }\n          }\n        })\n        .catch(error => {\n          if (!hasError) {\n            hasError = true;\n            reject(error);\n          }\n        });\n    };\n\n    for (; currentIndex < concurrency; currentIndex++) {\n      processItem(currentIndex);\n    }\n  });\n}\n","import { SPECIAL_VALUE, SPECIAL_VALUE_2 } from '@/specialValue';\nimport type { Awaitable, SpecialValue } from '@/types';\nimport { nextTickIteration } from '../nextTickIteration';\n\n/**\n * Asynchronously filters and maps an array in a single pass, with bounded\n * concurrency.\n *\n * The callback may be async and receives a `skip` sentinel as its second\n * argument. Return any mapped value (or a promise of one) to keep it, or return\n * `skip` to exclude the current element. Combining the filter and map avoids the\n * extra allocation and second traversal of chaining `.filter().map()`.\n *\n * Up to `concurrency` callbacks run at a time. Even though callbacks may settle\n * out of order, the resolved array preserves **strict source order** and\n * contains no gaps for skipped elements. Work is spread across microtasks so a\n * large input does not block the event loop.\n *\n * If any callback rejects (or throws), the returned promise rejects with that\n * error and no further elements are processed.\n *\n * @param array - The source array to iterate over. It is not mutated.\n * @param callbackfn - Called for each element with `(value, skip, index, array)`.\n *   Return the mapped value (or a promise of it) to keep, or `skip` to drop the\n *   element.\n * @param options - Options object.\n * @param options.concurrency - Maximum number of callbacks in flight at once.\n *   Defaults to `1` (sequential); values below `1` are clamped to `1`.\n * @returns A promise resolving to a new array of the mapped values, in source\n *   order, excluding any skipped elements.\n *\n * @example\n * ```ts\n * // Keep even numbers and double them, dropping the rest.\n * await asyncFilterMap([1, 2, 3, 4], (value, skip) =>\n *   value % 2 === 0 ? value * 2 : skip,\n * );\n * // => [4, 8]\n * ```\n *\n * @example\n * ```ts\n * // Fetch users concurrently, skipping the ones that don't exist.\n * const users = await asyncFilterMap(\n *   ids,\n *   async (id, skip) => {\n *     const res = await fetch(`/users/${id}`);\n *     return res.ok ? res.json() : skip;\n *   },\n *   { concurrency: 5 },\n * );\n * ```\n *\n * @group Promise\n */\nexport function asyncFilterMap<T, U>(\n  array: T[],\n  callbackfn: (\n    value: T,\n    skip: SpecialValue,\n    index: number,\n    array: T[],\n  ) => Awaitable<U | SpecialValue>,\n  { concurrency = 1 } = {},\n): Promise<U[]> {\n  concurrency = Math.max(concurrency, 1);\n  var mapped: U[] = [];\n\n  if (array.length === 0) {\n    return Promise.resolve(mapped);\n  }\n\n  var hasError = false;\n  // Holds completed callback results keyed by original index until they can be\n  // flushed into `mapped` in strict source order.\n  var buffer: (U | SpecialValue)[] = Array(array.length).fill(SPECIAL_VALUE_2);\n  var flushIndex = 0;\n  var completed = 0;\n  var currentIndex = 0;\n  var cooldown = nextTickIteration(10);\n\n  return new Promise((resolve, reject) => {\n    var processItem = (index: number) => {\n      if (hasError || index >= array.length) return;\n\n      cooldown()\n        .then(() => callbackfn(array[index], SPECIAL_VALUE, index, array))\n        .then(transformed => {\n          if (hasError) return;\n\n          buffer[index] = transformed;\n\n          // Flush every contiguous completed slot from the front, keeping strict\n          // source order and pushing only non-skipped values (no gaps).\n          while (\n            flushIndex < array.length &&\n            buffer[flushIndex] !== SPECIAL_VALUE_2\n          ) {\n            if (buffer[flushIndex] !== SPECIAL_VALUE) {\n              mapped.push(buffer[flushIndex] as U);\n            }\n            flushIndex++;\n          }\n\n          completed++;\n\n          if (completed >= array.length) {\n            resolve(mapped);\n          } else {\n            if (currentIndex < array.length) {\n              processItem(currentIndex++);\n            }\n          }\n        })\n        .catch(error => {\n          if (!hasError) {\n            hasError = true;\n            reject(error);\n          }\n        });\n    };\n\n    for (; currentIndex < concurrency; currentIndex++) {\n      processItem(currentIndex);\n    }\n  });\n}\n","import { nextTickIteration } from '../nextTickIteration';\n\n/**\n * Asynchronously finds the first element in an array that satisfies the provided async predicate.\n *\n * This function iterates through an array and applies an asynchronous predicate to each element.\n * If the predicate resolves to a truthy value for any element, that element is returned immediately.\n * The function is designed to prevent blocking the event loop during iteration, making it suitable\n * for processing large arrays without impacting performance.\n *\n * @param array - The array to search through.\n * @param callbackfn - The asynchronous predicate function.\n *  It takes three arguments: the current value, the index of the current value, and the full array.\n *  The predicate function should return a boolean or a promise that resolves to a boolean indicating\n *  whether the current value satisfies the condition.\n *\n * @returns {Promise<T | undefined>} A promise that resolves to the first element that satisfies the predicate, or `undefined` if no element matches.\n *\n * @example\n * // Example of using asyncFind to find users by ID asynchronously\n * const users = Array.from({ length: 100000 }).map((_, idx) => ({\n *   id: idx,\n *   name: 'User: ' + (idx + 1)\n * }));\n *\n * async function findById(userId: number) {\n *   return await asyncFind(users, (user) => user.id === userId);\n * }\n *\n * Promise.all([\n *   findById(5000),\n *   findById(6000),\n * ]).then(console.log);\n *\n * @group Promise\n */\nexport function asyncFind<T>(\n  array: T[],\n  callbackfn: (\n    value: T,\n    index: number,\n    array: T[],\n  ) => Promise<unknown> | unknown,\n): Promise<T | undefined> {\n  var i = 0;\n  var cooldown = nextTickIteration(10);\n\n  return new Promise((resolve, reject) => {\n    var processNextBatch = () => {\n      if (i < array.length) {\n        cooldown()\n          .then(() => callbackfn(array[i], i, array))\n          .then(result => {\n            if (Boolean(result)) {\n              resolve(array[i]);\n            } else {\n              i++;\n              setTimeout(processNextBatch, 0);\n            }\n          })\n          .catch(reject);\n      } else {\n        resolve(undefined);\n      }\n    };\n\n    processNextBatch();\n  });\n}\n","import { nextTickIteration } from '../nextTickIteration';\n\n/**\n * Asynchronously iterates over an array, executing the provided callback for each element with support for parallel processing.\n *\n * This function is similar to `Array.prototype.forEach()`, but it allows asynchronous operations in parallel for each array element.\n * It also prevents blocking the event loop while iterating through large arrays, improving performance for heavy tasks.\n * The function processes items in batches to manage concurrency and can be configured to process multiple items at the same time.\n *\n * **Note**: The callback function can return either a promise or a value. If it returns a promise, `asyncForEach` will wait for it to resolve before moving to the next iteration.\n *\n * @param array - The array to iterate over.\n * @param callbackfn - The async callback function to execute for each element.\n *  This function takes three parameters:\n *   - `value`: The current element of the array.\n *   - `index`: The index of the current element in the array.\n *   - `array`: The array that is being iterated over.\n *  The function should either return a `void` or a `Promise` that resolves when the async operation is done.\n *\n * @param {Object} [options] - Optional settings to control the concurrency of the operation.\n * @param {number} [options.concurrency=1] - The number of items to process in parallel. Defaults to 1 (sequential processing).\n *\n * @returns {Promise<void>} A promise that resolves when all elements have been processed.\n *\n * @example\n * async function task(taskName: string) {\n *   const largeArray = Array.from({ length: 100000 }).map((_, idx) => idx);\n *\n *   await asyncForEach(largeArray, (value) => {\n *     if (value % 100 === 0) {\n *       console.log(taskName, 'handle:', value);\n *     }\n *   });\n * }\n *\n * Promise.all([\n *   task('task 1'),\n *   task('task 2'),\n * ]);\n *\n * @group Promise\n */\nexport function asyncForEach<T>(\n  array: T[],\n  callbackfn: (\n    value: T,\n    index: number,\n    array: Array<T>,\n  ) => Promise<void> | void,\n  { concurrency = 1 } = {},\n): Promise<void> {\n  concurrency = Math.max(concurrency, 1);\n\n  if (array.length === 0) {\n    return Promise.resolve();\n  }\n\n  var hasError = false;\n  var completed = 0;\n  var currentIndex = 0;\n  var cooldown = nextTickIteration(10);\n\n  return new Promise((resolve, reject) => {\n    var processItem = (index: number) => {\n      if (hasError || index >= array.length) return;\n\n      cooldown()\n        .then(() => callbackfn(array[index], index, array))\n        .then(transformed => {\n          if (hasError) return;\n\n          completed++;\n\n          if (completed >= array.length) {\n            resolve();\n          } else {\n            if (currentIndex < array.length) {\n              processItem(currentIndex++);\n            }\n          }\n        })\n        .catch(error => {\n          if (!hasError) {\n            hasError = true;\n            reject(error);\n          }\n        });\n    };\n\n    for (; currentIndex < concurrency; currentIndex++) {\n      processItem(currentIndex);\n    }\n  });\n}\n","import { isPromise } from '@/is';\nimport type { AnyFunction } from '@/types';\nimport { defer } from '../defer';\n\nexport type SimpleEventMap<T> = Record<keyof T, any[]> | SimpleDefaultEventMap;\nexport type SimpleDefaultEventMap = [never];\n\ntype Key<K, T> = T extends SimpleDefaultEventMap\n  ? string | symbol\n  : K | keyof T;\n\ntype Listener<K, T, F> = T extends SimpleDefaultEventMap\n  ? F\n  : K extends keyof T\n    ? T[K] extends unknown[]\n      ? (...args: T[K]) => void\n      : never\n    : never;\n\ntype Listener1<K, T> = Listener<K, T, (...args: any[]) => void>;\n\ntype Args<K, T> = T extends SimpleDefaultEventMap\n  ? [...args: any[]]\n  : K extends keyof T\n    ? T[K]\n    : never;\n\nconst onError = (error: unknown) => {\n  console.error(error);\n};\n\n/**\n * Simplified version on nodejs `EventEmitter` but platform agnostic\n *\n * @example\n * const emitter = new SimpleEventEmitter();\n *\n * emitter.on('message', (data) => {\n *   console.log('msg', data)\n * });\n *\n * emitter.once('message', (data) => {\n *   console.log('once msg', data)\n * });\n *\n * emitter.emit('message', { text: 'Hello' });\n * emitter.emit('message', { text: 'Hello 2' });\n *\n * @group Promise\n */\nexport class SimpleEventEmitter<\n  T extends SimpleEventMap<T> = SimpleDefaultEventMap,\n> {\n  #listeners: Map<any, Set<AnyFunction>> = new Map();\n\n  constructor() {\n    // @ts-expect-error\n    this.on('error', onError);\n  }\n\n  static once(\n    emitter: SimpleEventEmitter,\n    eventName: string | symbol,\n  ): Promise<any[]> {\n    const q = defer<any[]>();\n\n    emitter.once(eventName, (...args: any[]) => q.resolve(args));\n\n    return q.promise;\n  }\n\n  emit<K>(eventName: Key<K, T>, ...args: Args<K, T>): boolean {\n    const set = this.#listeners.get(eventName);\n\n    if (!set) return false;\n\n    set.forEach(fn => {\n      try {\n        const result = fn(...args);\n\n        if (isPromise(result)) {\n          result.catch(err => {\n            // @ts-expect-error\n            this.emit('error' as any, err);\n          });\n        }\n      } catch (err) {\n        // @ts-expect-error\n        this.emit('error' as any, err);\n      }\n    });\n\n    return true;\n  }\n\n  on<K>(eventName: Key<K, T>, listener: Listener1<K, T>): this {\n    if (!this.#listeners.has(eventName)) {\n      this.#listeners.set(eventName, new Set());\n    }\n\n    const set = this.#listeners.get(eventName)!;\n\n    set.add(listener);\n\n    return this;\n  }\n\n  once<K>(eventName: Key<K, T>, listener: Listener1<K, T>): this {\n    const wrapped = (...args: any[]) => {\n      // @ts-expect-error\n      this.off(eventName, wrapped);\n      listener(...args);\n    };\n\n    // @ts-expect-error\n    this.on(eventName, wrapped);\n\n    return this;\n  }\n\n  off<K>(eventName: Key<K, T>, listener: Listener1<K, T>): this {\n    const set = this.#listeners.get(eventName);\n\n    if (set) {\n      set.delete(listener);\n\n      if (set.size === 0) {\n        this.#listeners.delete(eventName);\n      }\n    }\n\n    return this;\n  }\n\n  removeAllListeners<K>(eventName?: Key<K, T>): this {\n    if (eventName === undefined) {\n      this.#listeners.clear();\n      return this;\n    }\n\n    this.#listeners.delete(eventName);\n\n    return this;\n  }\n}\n","import { SimpleEventEmitter } from '../SimpleEventEmitter';\n\n/**\n * A basic queue implementation with a limit and event-based synchronization.\n *\n * This class allows you to put items into a queue and retrieve them asynchronously.\n * If the queue exceeds a specified limit, the `put` operation will wait until an item is retrieved,\n * and similarly, the `get` operation will wait if there are no items available in the queue.\n *\n * @example\n * // Create a queue with a limit of 10 items\n * const sendQueue = new Queue<any>(10);\n *\n * // Add items to the queue\n * sendQueue.put({ url: '/api/message.send', params: { text: 'hello' } });\n * sendQueue.put({ url: '/api/message.send', params: { text: 'how are you?' } });\n *\n * // Retrieve and process items from the queue asynchronously\n * while (true) {\n *   const req = await sendQueue.get();\n *   http.post(req.url, { body: req.params });\n * }\n *\n * @param limit - Optional maximum number of items the queue can hold. If not provided, the queue has no limit.\n *\n * @group Promise\n */\nexport class Queue<T> {\n  items: T[] = [];\n  #limit?: number;\n  #events = new SimpleEventEmitter();\n\n  constructor(limit?: number) {\n    this.#limit = limit;\n  }\n\n  get(): Promise<T> {\n    var getItem = (): Promise<T> => {\n      const item = this.items.shift()!;\n      this.#events.emit('get');\n      return Promise.resolve(item);\n    };\n\n    if (this.items.length === 0) {\n      return SimpleEventEmitter.once(this.#events, 'put').then(getItem);\n    }\n\n    return getItem();\n  }\n\n  put(item: T): Promise<void> {\n    var putItem = (): Promise<void> => {\n      this.items.push(item);\n      this.#events.emit('put');\n      return Promise.resolve();\n    };\n\n    if (this.#limit && this.items.length >= this.#limit) {\n      return SimpleEventEmitter.once(this.#events, 'get').then(putItem);\n    }\n\n    return putItem();\n  }\n}\n","import { Queue } from '../Queue';\n\n/**\n * An asynchronous queue implementation that can be iterated using an async iterator.\n * It allows items to be added (`put`) and consumed asynchronously, with the ability to signal when the queue is closed.\n * This class supports async iteration, enabling users to process items as they become available, and provides an end signal once the queue is closed.\n *\n * @example\n * const textStream = new AsyncIterableQueue<string>();\n *\n * const readTimer = setInterval(() => {\n *   textStream.put('Hey ' + Math.random());\n * }, 100);\n *\n * setTimeout(() => {\n *   textStream.close();\n *   clearInterval(readTimer);\n * });\n *\n * for await (const text of textStream) {\n *   console.log('text part', { text });\n * }\n *\n * @group Promise\n */\nexport class AsyncIterableQueue<T> implements AsyncIterable<T> {\n  private _queue: Queue<T | typeof AsyncIterableQueue.QUEUE_END_MARKER>;\n  private _closed = false;\n  private static readonly QUEUE_END_MARKER = Symbol('QUEUE_END_MARKER');\n\n  constructor() {\n    this._queue = new Queue<T | typeof AsyncIterableQueue.QUEUE_END_MARKER>();\n  }\n\n  get closed(): boolean {\n    return this._closed;\n  }\n\n  put(item: T): void {\n    if (this._closed) {\n      throw new Error('Queue is closed');\n    }\n    this._queue.put(item);\n  }\n\n  close(): void {\n    if (this._closed) return;\n\n    this._closed = true;\n    this._queue.put(AsyncIterableQueue.QUEUE_END_MARKER);\n  }\n\n  [Symbol.asyncIterator](): AsyncIterator<T> {\n    return {\n      next: (): Promise<IteratorResult<T>> => {\n        if (this._closed && this._queue.items.length === 0) {\n          return Promise.resolve({ value: undefined, done: true });\n        }\n\n        return this._queue.get().then(item => {\n          if (item === AsyncIterableQueue.QUEUE_END_MARKER && this._closed) {\n            return { value: undefined, done: true };\n          }\n          return { value: item as T, done: false };\n        });\n      },\n    };\n  }\n}\n","import { nextTickIteration } from '../nextTickIteration';\n\n/**\n * Asynchronously maps over an array, applying the provided callback function to each element,\n * with support for parallel processing of array elements.\n *\n * This function is similar to `arr.map()`, but allows asynchronous operations\n * for each array element, helping to avoid blocking the event loop when processing large arrays.\n * It processes the array elements in batches, providing support for concurrency, meaning multiple\n * elements can be processed in parallel.\n *\n * **Note**: The callback function can return either a value or a `Promise`. If a `Promise` is returned,\n * `asyncMap` will wait for it to resolve before moving on to the next iteration.\n *\n * @param array - The array to iterate over.\n * @param callbackfn - The async callback function to apply to each element.\n *  This function takes three parameters:\n *   - `value`: The current element of the array.\n *   - `index`: The index of the current element in the array.\n *   - `array`: The array being processed.\n *  The callback should return either a transformed value (`U`) or a `Promise<U>`.\n *\n * @param {Object} [options] - Optional configuration for controlling concurrency.\n * @param {number} [options.concurrency=1] - The number of items to process concurrently. Default is 1 (sequential processing).\n *\n * @returns {Promise<U[]>} A promise that resolves to an array of transformed elements.\n *\n * @example\n * const users = Array.from({ length: 100 }).map((_, idx) => ({\n *   id: idx,\n *   name: 'User: ' + (idx + 1)\n * }));\n *\n * async function withUserClients() {\n *   return await asyncMap(users, async (user) => {\n *     const clients = await db.clients.find({ user: user.id });\n *\n *     return { ...user, clients };\n *   }, { concurrency: 10 });\n * }\n *\n * Promise.all([\n *   withUserClients(),\n *   otherUsefulTask(),\n * ]).then(console.log);\n *\n * @group Promise\n */\nexport function asyncMap<T, U>(\n  array: T[],\n  callbackfn: (value: T, index: number, array: Array<T>) => Promise<U> | U,\n  { concurrency = 1 } = {},\n): Promise<Array<U>> {\n  concurrency = Math.max(concurrency, 1);\n\n  if (array.length === 0) {\n    return Promise.resolve([]);\n  }\n\n  var hasError = false;\n  var result: U[] = Array(array.length);\n  var completed = 0;\n  var currentIndex = 0;\n  var cooldown = nextTickIteration(10);\n\n  return new Promise((resolve, reject) => {\n    var processItem = (index: number) => {\n      if (hasError || index >= array.length) return;\n\n      cooldown()\n        .then(() => callbackfn(array[index], index, array))\n        .then(transformed => {\n          if (hasError) return;\n\n          result[index] = transformed;\n\n          completed++;\n\n          if (completed >= array.length) {\n            resolve(result);\n          } else {\n            if (currentIndex < array.length) {\n              processItem(currentIndex++);\n            }\n          }\n        })\n        .catch(error => {\n          if (!hasError) {\n            hasError = true;\n            reject(error);\n          }\n        });\n    };\n\n    for (; currentIndex < concurrency; currentIndex++) {\n      processItem(currentIndex);\n    }\n  });\n}\n","import { catchError } from '@/catchError';\nimport { toError } from '@/toError';\nimport type { AnyFunction } from '@/types';\n\n/**\n * A custom promise that supports cancellation.\n * Allows users to cancel the promise operation before it completes, avoiding unnecessary execution.\n * This class provides a mechanism to perform asynchronous tasks that can be stopped midway by calling the `cancel` method.\n *\n * @example\n * const task = new CancellablePromise<void>(async (resolve, reject, onCancel) => {\n *   let cancelled = false;\n *   onCancel(() => {\n *     cancelled = true;  // Define the cancellation logic here\n *   });\n *\n *   while (!cancelled) {\n *     await delay(1000);  // Simulate async work\n *     console.log('handling task...');\n *   }\n * });\n *\n * // Cancel the task after 5 seconds\n * setTimeout(() => task.cancel(), 5000);\n *\n * await task;  // This will be cancelled before it completes\n * console.log('Task completed or cancelled');\n *\n * @group Promise\n */\nexport class CancellablePromise<T> implements Promise<T> {\n  #promise: Promise<T>;\n  #cancelFns: (() => void)[];\n  #isCancelled: boolean = false;\n  #error: Error | null = null;\n\n  constructor(\n    executor: (\n      resolve: (value: T | PromiseLike<T>) => void,\n      reject: (reason?: any) => void,\n      onCancel: (cancelFn: () => void) => void,\n    ) => void,\n  ) {\n    this.#cancelFns = [];\n    this.#promise = new Promise<T>((resolve, reject) => {\n      executor(\n        resolve,\n        reason => {\n          this.#error = toError(reason, 'Unknown rejection reason.');\n          reject(reason);\n        },\n        (fn: AnyFunction) => {\n          this.#cancelFns.push(fn);\n        },\n      );\n    });\n  }\n\n  get [Symbol.toStringTag](): string {\n    return (\n      this.#promise[Symbol.toStringTag] +\n      (this.isCancelled ? ' (Cancelled)' : '')\n    );\n  }\n\n  get isCancelled(): boolean {\n    return this.#isCancelled;\n  }\n\n  get error(): Error | null {\n    return this.#error;\n  }\n\n  then<TResult1 = T, TResult2 = never>(\n    onfulfilled?: ((value: T) => TResult1 | Promise<TResult1>) | null,\n    onrejected?: ((reason: any) => TResult2 | Promise<TResult2>) | null,\n  ): Promise<TResult1 | TResult2> {\n    return this.#promise.then(onfulfilled, onrejected);\n  }\n\n  catch<TResult = never>(\n    onrejected?: ((reason: any) => TResult | Promise<TResult>) | null,\n  ): Promise<T | TResult> {\n    return this.#promise.catch(onrejected);\n  }\n\n  finally(onfinally?: (() => void) | null): Promise<T> {\n    return this.#promise.finally(onfinally);\n  }\n\n  cancel(): void {\n    if (this.#isCancelled) return;\n\n    this.#isCancelled = true;\n\n    for (const fn of this.#cancelFns) {\n      catchError(fn);\n    }\n  }\n\n  static from<T>(promise: Promise<T>): CancellablePromise<T> {\n    return new CancellablePromise<T>((resolve, reject) => {\n      promise.then(resolve).catch(reject);\n    });\n  }\n}\n","import type { AnyFunction } from '@/types';\n\ntype NoneToVoidFunction = () => void;\n\nconst FAST_RAF_TIMEOUT_FALLBACK_MS = 300;\n\nconst defaultWindow = (globalThis as any)?.window as Window | undefined;\nconst raf =\n  defaultWindow?.requestAnimationFrame ||\n  ((cb: AnyFunction) => setTimeout(cb, 0));\n\nlet fastRafCallbacks: Set<NoneToVoidFunction> | undefined;\nlet fastRafFallbackCallbacks: Set<NoneToVoidFunction> | undefined;\nlet fastRafFallbackTimeout: any;\n\n/**\n * Stacks callbacks for `requestAnimationFrame` into a single execution call.\n *\n * This function allows multiple `fastRaf` calls to be batched into a single animation frame callback.\n * The callbacks are executed in the same frame, one after the other. Additionally, if `withTimeoutFallback` is true,\n * the callbacks will be executed after a fallback timeout if `requestAnimationFrame` is not available.\n * If called from within another RAF callback, the execution might be immediate.\n *\n * @example\n * // Callbacks will be executed in the same `requestAnimationFrame` cycle\n * fastRaf(() => console.log(1));\n * fastRaf(() => console.log(2));\n *\n * // Output:\n * // 1\n * // 2\n *\n * @param callback The callback function to be executed in the next `requestAnimationFrame`.\n * @param [withTimeoutFallback=false] Optional flag to execute callbacks after a fallback timeout if `requestAnimationFrame` is not available.\n * @group Promise\n */\nexport function fastRaf(\n  callback: NoneToVoidFunction,\n  withTimeoutFallback = false,\n) {\n  if (!fastRafCallbacks) {\n    fastRafCallbacks = new Set([callback]);\n\n    raf(() => {\n      const currentCallbacks = fastRafCallbacks!;\n\n      fastRafCallbacks = undefined;\n      fastRafFallbackCallbacks = undefined;\n\n      if (fastRafFallbackTimeout) {\n        clearTimeout(fastRafFallbackTimeout);\n        fastRafFallbackTimeout = undefined;\n      }\n\n      currentCallbacks.forEach(cb => cb());\n    });\n  } else {\n    fastRafCallbacks.add(callback);\n  }\n\n  if (withTimeoutFallback) {\n    if (!fastRafFallbackCallbacks) {\n      fastRafFallbackCallbacks = new Set([callback]);\n    } else {\n      fastRafFallbackCallbacks.add(callback);\n    }\n\n    if (!fastRafFallbackTimeout) {\n      fastRafFallbackTimeout = setTimeout(() => {\n        const currentTimeoutCallbacks = fastRafFallbackCallbacks!;\n\n        if (fastRafCallbacks) {\n          currentTimeoutCallbacks.forEach(\n            fastRafCallbacks.delete,\n            fastRafCallbacks,\n          );\n        }\n        fastRafFallbackCallbacks = undefined;\n\n        if (fastRafFallbackTimeout) {\n          clearTimeout(fastRafFallbackTimeout);\n          fastRafFallbackTimeout = undefined;\n        }\n\n        currentTimeoutCallbacks.forEach(cb => cb());\n      }, FAST_RAF_TIMEOUT_FALLBACK_MS);\n    }\n  }\n}\n\nexport function rafPromise() {\n  return new Promise<void>(resolve => {\n    fastRaf(resolve);\n  });\n}\n","import { assert } from '@/assert';\nimport { noop } from '@/is';\nimport { type Defer, defer } from '@/promise/defer';\nimport { toError } from '@/toError';\nimport type { Awaitable } from '@/types';\nimport { SimpleEventEmitter } from '../SimpleEventEmitter';\nimport { asyncForEach } from '../asyncForEach';\n\n/**\n * Configuration options for creating a ResourcePool instance.\n * @template T The type of resource being pooled\n */\nexport interface ResourcePoolOptions<T = unknown> {\n  /** Maximum number of resources that can exist in the pool */\n  poolSize: number;\n\n  /**\n   * Whether to automatically create resources when needed, up to poolSize limit.\n   * If false, resources must be pre-created or acquired requests will queue.\n   * @default false\n   */\n  auto?: boolean;\n\n  /** Factory function to create new resources */\n  createResource: () => Awaitable<T>;\n\n  /** Optional cleanup function called when destroying resources */\n  destroyResource?: (resource: T) => Awaitable<void>;\n}\n\nexport type ResourcePoolEventMap = {\n  error: [error: Error];\n};\n\n/**\n * Internal state container for ResourcePool to group related data.\n * @template T The type of resource being pooled\n * @internal\n */\ninterface PoolState<T> {\n  /** Resources currently available for acquisition */\n  availableResources: T[];\n  /** Resources currently in use by consumers */\n  inUseResources: Set<T>;\n  /** Queue of pending acquisition requests waiting for resources */\n  queueAcquire: Defer<T>[];\n  /** Queue of drain requests waiting for all resources to be released */\n  queueDrain: Defer<void>[];\n  /** Queue of destroy requests waiting for destruction to complete */\n  queueDestroy: Defer<void>[];\n  /** Flag indicating if the pool is currently being destroyed */\n  createPending: number;\n  /** Flag indicating if the pool is currently being destroyed */\n  destroying: boolean;\n}\n\n/**\n * A generic resource pool that manages the lifecycle of expensive resources.\n *\n * ResourcePool provides a way to:\n * - Limit the number of concurrent resources (e.g., database connections, file handles)\n * - Reuse resources to avoid creation/destruction overhead\n * - Queue requests when all resources are in use\n * - Automatically create resources on demand (when auto mode is enabled)\n * - Gracefully handle resource cleanup and pool destruction\n *\n * @template T The type of resource being pooled\n *\n * @example\n * ```typescript\n * // Database connection pool\n * const dbPool = new ResourcePool({\n *   poolSize: 10,\n *   auto: true,\n *   createResource: () => createDatabaseConnection(),\n *   destroyResource: (conn) => conn.close()\n * });\n *\n * // Acquire and use a connection\n * const conn = await dbPool.acquire();\n * try {\n *   const result = await conn.query('SELECT * FROM users');\n *   return result;\n * } finally {\n *   dbPool.release(conn);\n * }\n * ```\n *\n * @group Promise\n */\nexport class ResourcePool<\n  T = unknown,\n> extends SimpleEventEmitter<ResourcePoolEventMap> {\n  private readonly poolSize: number;\n  private readonly auto: boolean;\n  private readonly createResource: () => Awaitable<T>;\n  private readonly destroyResource?: (resource: T) => Awaitable<void>;\n  private readonly state: PoolState<T>;\n\n  /**\n   * Creates a new ResourcePool instance.\n   *\n   * @param options Configuration options for the pool\n   *\n   * @example\n   * ```typescript\n   * const pool = new ResourcePool({\n   *   poolSize: 5,\n   *   auto: true,\n   *   createResource: async () => new DatabaseConnection(),\n   *   destroyResource: async (conn) => conn.close()\n   * });\n   * ```\n   */\n  constructor({\n    poolSize,\n    auto = false,\n    createResource,\n    destroyResource,\n  }: ResourcePoolOptions<T>) {\n    super();\n    this.poolSize = poolSize;\n    this.auto = auto;\n    this.createResource = createResource;\n    this.destroyResource = destroyResource;\n    this.removeAllListeners('error');\n\n    this.state = {\n      availableResources: [],\n      inUseResources: new Set(),\n      queueAcquire: [],\n      queueDrain: [],\n      queueDestroy: [],\n      createPending: 0,\n      destroying: false,\n    };\n  }\n\n  /**\n   * Whether the pool is idle (no resources currently in use).\n   * Useful for determining if it's safe to destroy the pool.\n   */\n  get isIdle(): boolean {\n    return this.state.inUseResources.size === 0;\n  }\n\n  /** Number of resources currently available for acquisition */\n  get availableCount(): number {\n    return this.state.availableResources.length;\n  }\n\n  /** Number of resources currently in use */\n  get usedCount(): number {\n    return this.state.inUseResources.size;\n  }\n\n  /** Maximum number of resources this pool can manage */\n  get size(): number {\n    return this.poolSize;\n  }\n\n  /**\n   * Acquires a resource from the pool.\n   *\n   * This method will:\n   * 1. Return an available resource immediately if one exists\n   * 2. Create a new resource if auto mode is enabled and under the pool limit\n   * 3. Queue the request and wait if no resources are available\n   *\n   * @returns Promise that resolves to an acquired resource\n   * @throws Error if the pool is destroyed while waiting (when rejectAcquires is true)\n   *\n   * @example\n   * ```typescript\n   * const resource = await pool.acquire();\n   * try {\n   *   // Use the resource\n   *   await resource.doSomething();\n   * } finally {\n   *   pool.release(resource); // Always release in finally block\n   * }\n   * ```\n   */\n  acquire(): Promise<T> {\n    if (this.state.destroying) {\n      return this.enqueueAcquireRequest();\n    }\n    let availableResource = this.tryGetAvailableResource();\n    if (availableResource !== null) {\n      return Promise.resolve(availableResource);\n    }\n\n    return Promise.resolve()\n      .then(() => this.tryCreateAutoResource())\n      .then(autoCreatedResource => {\n        if (autoCreatedResource !== null) {\n          return autoCreatedResource;\n        }\n\n        // Check for available resources again, maybe someone free now\n        availableResource = this.tryGetAvailableResource();\n        if (availableResource !== null) {\n          return availableResource;\n        }\n\n        return this.enqueueAcquireRequest();\n      });\n  }\n\n  /**\n   * Returns a resource to the pool, making it available for reuse.\n   *\n   * The resource will be made available to the next queued acquisition request,\n   * or returned to the available pool if no requests are pending.\n   *\n   * @param resource The resource to return to the pool\n   *\n   * @example\n   * ```typescript\n   * const resource = await pool.acquire();\n   * try {\n   *   // Use resource...\n   * } finally {\n   *   pool.release(resource); // Always release when done\n   * }\n   * ```\n   *\n   * @remarks\n   * - Safe to call multiple times with the same resource (idempotent)\n   * - Only resources that were acquired from this pool should be released\n   * - Triggers drain completion if this was the last resource in use\n   */\n  release(resource: T): void {\n    if (!this.state.inUseResources.has(resource)) {\n      return;\n    }\n\n    this.processNextAcquireRequest(resource);\n    this.checkForDrainCompletion();\n  }\n\n  /**\n   * Manually add a resource to the pool.\n   *\n   * @param resource The resource to return to the pool\n   *\n   * @throws Error if resource already exists in the pool.\n   * @throws Error if size reached.\n   */\n  add(resource: T): void {\n    assert.ok(\n      this.poolSize >\n        this.state.availableResources.length + this.state.inUseResources.size,\n      'Pool size reached',\n    );\n\n    assert.ok(\n      !this.state.inUseResources.has(resource) &&\n        !this.state.availableResources.includes(resource),\n      'This resource already added to the pool',\n    );\n\n    this.state.inUseResources.add(resource);\n    this.processNextAcquireRequest(resource);\n  }\n\n  /**\n   * Waits for all currently acquired resources to be released.\n   *\n   * This is useful for graceful shutdown scenarios where you want to ensure\n   * all work is completed before destroying the pool.\n   *\n   * @returns Promise that resolves when all resources are returned to the pool\n   *\n   * @example\n   * ```typescript\n   * // Graceful shutdown\n   * console.log('Waiting for all connections to be released...');\n   * await pool.drain();\n   * console.log('All connections released, safe to destroy pool');\n   * await pool.destroy();\n   * ```\n   *\n   * @remarks\n   * - Resolves immediately if no resources are currently in use\n   * - Multiple drain calls can be made concurrently; they will all resolve together\n   * - Does not prevent new acquisitions; use destroy() to prevent new usage\n   */\n  drain(): Promise<void> {\n    if (this.isIdle) {\n      return Promise.resolve();\n    }\n\n    const drainDefer = defer<void>();\n    this.state.queueDrain.push(drainDefer);\n    return drainDefer.promise;\n  }\n\n  /**\n   * Destroys the pool and all its resources.\n   *\n   * This method will:\n   * 1. Wait for all resources to be released (drain)\n   * 2. Optionally reject any pending acquisition requests\n   * 3. Call destroyResource() on all available resources\n   * 4. Clean up internal state\n   *\n   * @param rejectAcquires Whether to reject pending acquire() requests with an error\n   *                       If false, pending requests will remain queued indefinitely\n   * @returns Promise that resolves when destruction is complete\n   *\n   * @example\n   * ```typescript\n   * // Graceful shutdown - let pending requests complete\n   * await pool.destroy(false);\n   *\n   * // Immediate shutdown - reject pending requests\n   * await pool.destroy(true);\n   * ```\n   *\n   * @remarks\n   * - Safe to call multiple times; subsequent calls will wait for the first to complete\n   * - The pool cannot be used after destruction\n   * - Resources currently in use will not be force-destroyed; drain() is called first\n   * - If destroyResource was not provided, resources are simply discarded\n   */\n  destroy(rejectAcquires = false): Promise<void> {\n    if (this.state.destroying) {\n      return this.enqueueDestroyRequest();\n    }\n\n    this.state.destroying = true;\n\n    return Promise.resolve()\n      .then(() => this.drain())\n      .then(() => {\n        if (rejectAcquires) {\n          this.rejectPendingAcquires();\n        }\n\n        return this.destroyAllResources();\n      })\n      .then(() => this.resetState())\n      .catch(err => {\n        this.emit('error', toError(err));\n      })\n      .finally(() => {\n        this.state.destroying = false;\n        this.resolveDestroyQueue();\n      });\n  }\n\n  private tryGetAvailableResource(): T | null {\n    if (this.state.availableResources.length === 0) {\n      return null;\n    }\n\n    const resource = this.state.availableResources.pop()!;\n    this.state.inUseResources.add(resource);\n    return resource;\n  }\n\n  private isLimitReached() {\n    return (\n      this.state.inUseResources.size +\n        this.state.createPending +\n        this.state.availableResources.length >=\n      this.poolSize\n    );\n  }\n\n  private tryCreateAutoResource(): Promise<T | null> {\n    if (!this.auto || this.isLimitReached()) {\n      return Promise.resolve(null);\n    }\n\n    this.state.createPending++;\n\n    return Promise.resolve()\n      .then(() => this.createResource())\n      .then(resource => {\n        this.state.inUseResources.add(resource);\n        return resource;\n      })\n      .finally(() => {\n        this.state.createPending--;\n      });\n  }\n\n  private enqueueAcquireRequest(): Promise<T> {\n    const acquireDefer = defer<T>();\n    this.state.queueAcquire.push(acquireDefer);\n    return acquireDefer.promise;\n  }\n\n  private moveResourceToAvailable(resource: T): void {\n    this.state.inUseResources.delete(resource);\n    this.state.availableResources.push(resource);\n  }\n\n  private processNextAcquireRequest(resource: T): void {\n    if (this.state.destroying || this.state.queueAcquire.length === 0) {\n      this.moveResourceToAvailable(resource);\n      return;\n    }\n\n    const nextRequest = this.state.queueAcquire.shift()!;\n    nextRequest.resolve(resource);\n  }\n\n  private checkForDrainCompletion(): void {\n    if (this.isIdle && this.state.queueDrain.length > 0) {\n      this.state.queueDrain.forEach(deferred => deferred.resolve());\n      this.state.queueDrain = [];\n    }\n  }\n\n  private enqueueDestroyRequest(): Promise<void> {\n    const destroyDefer = defer<void>();\n    this.state.queueDestroy.push(destroyDefer);\n    return destroyDefer.promise;\n  }\n\n  private rejectPendingAcquires(): void {\n    const destroyError = new Error('ResourcePool destroyed');\n    this.state.queueAcquire.forEach(deferred => deferred.reject(destroyError));\n    this.state.queueAcquire = [];\n  }\n\n  private destroyAllResources(): Promise<void> {\n    if (!this.destroyResource || this.state.availableResources.length === 0) {\n      return Promise.resolve();\n    }\n\n    return asyncForEach(\n      this.state.availableResources,\n      resource => {\n        return Promise.resolve()\n          .then(() => this.destroyResource!(resource))\n          .catch(err => this.emit('error', toError(err)))\n          .then(noop);\n      },\n      { concurrency: 4 },\n    );\n  }\n\n  private resetState(): void {\n    this.state.availableResources = [];\n  }\n\n  private resolveDestroyQueue(): void {\n    this.state.queueDestroy.forEach(deferred => deferred.resolve());\n    this.state.queueDestroy = [];\n  }\n}\n","import { CancellablePromise } from '../../index.js';\n\nexport const SCHEDULER_JOB_FLAGS = {\n  QUEUED: 1 << 0,\n  ALLOW_RECURSE: 1 << 2,\n  DISPOSED: 1 << 3,\n} as const;\n\nexport namespace Scheduler {\n  export type Job<T = any> = (() => T) & JobOptions;\n\n  export type JobOptions = {\n    id?: number;\n\n    /**\n     * flags can technically be undefined, but it can still be used in bitwise\n     * operations just like 0.\n     */\n    flags?: number;\n\n    jobName?: string;\n  };\n}\n\n/**\n * Creates a microtask scheduler that batches jobs and flushes them in\n * priority order on the next tick.\n *\n * Jobs are functions queued via {@link Scheduler.queueJob}. Each job may carry\n * an optional numeric `id` used to order the queue — lower `id` runs first,\n * and jobs without an `id` run last. Re-queueing the same job within an\n * active flush cycle is a no-op unless `SCHEDULER_JOB_FLAGS.ALLOW_RECURSE`\n * is set on the job. Use {@link Scheduler.queueJobWait} when you need to\n * await a job's result through a {@link CancellablePromise}, and the\n * `onJob` / `onJobStart` / `onJobComplete` hooks to observe lifecycle.\n *\n * @example\n * ```typescript\n * const scheduler = createScheduler();\n *\n * const log = (msg: string) => () => console.log(msg);\n *\n * const first = log('first');\n * first.id = 1;\n * const second = log('second');\n * second.id = 2;\n *\n * scheduler.queueJob(second);\n * scheduler.queueJob(first);\n *\n * scheduler.nextTick().then(() => console.log('flushed'));\n * // → first\n * // → second\n * // → flushed\n * ```\n *\n * @group Promise\n */\nexport function createScheduler(): Scheduler {\n  return new Scheduler();\n}\n\nexport class Scheduler {\n  protected queue: Scheduler.Job[] = [];\n  protected flushIndex: number = -1;\n  protected resolvedPromise: Promise<any> = Promise.resolve();\n  protected currentFlushPromise: Promise<void> | null = null;\n  protected onJobCbs: ((job: Scheduler.JobOptions) => void)[] = [];\n  protected onJobStartCbs: ((job: Scheduler.JobOptions) => void)[] = [];\n  protected onJobCompleteCbs: ((job: Scheduler.JobOptions) => void)[] = [];\n\n  constructor() {\n    for (const methodName of Object.getOwnPropertyNames(\n      Object.getPrototypeOf(this),\n    )) {\n      (this as any)[methodName] = (this as any)[methodName].bind(this);\n    }\n  }\n\n  onJob(fn: (job: Scheduler.JobOptions) => void): void {\n    this.onJobCbs.push(fn);\n  }\n\n  onJobStart(fn: (job: Scheduler.JobOptions) => void): void {\n    this.onJobStartCbs.push(fn);\n  }\n\n  onJobComplete(fn: (job: Scheduler.JobOptions) => void) {\n    this.onJobCompleteCbs.push(fn);\n  }\n\n  nextTick(fn?: () => void): Promise<void> {\n    const p = this.currentFlushPromise || this.resolvedPromise;\n    return fn ? p.then(this ? fn.bind(this) : fn) : p;\n  }\n\n  queueJob<T>(job: Scheduler.Job<T>, opts?: Scheduler.JobOptions): void {\n    if (opts) {\n      Object.assign(job, opts);\n    }\n\n    if (!(job.flags! & SCHEDULER_JOB_FLAGS.QUEUED)) {\n      const jobId = getId(job);\n      const lastJob = this.queue[this.queue.length - 1];\n      if (!lastJob || jobId >= getId(lastJob)) {\n        this.queue.push(job);\n      } else {\n        this.queue.splice(this.findInsertionIndex(jobId), 0, job);\n      }\n\n      job.flags! |= SCHEDULER_JOB_FLAGS.QUEUED;\n      this.queueFlush();\n\n      for (const hookFn of this.onJobCbs) {\n        hookFn(job);\n      }\n    }\n  }\n\n  queueJobWait<T>(\n    job: Scheduler.Job<T>,\n    opts?: Scheduler.JobOptions,\n  ): CancellablePromise<Awaited<T>> {\n    return new CancellablePromise((resolve, reject, onCancel) => {\n      onCancel(() => {\n        job.flags! |= SCHEDULER_JOB_FLAGS.DISPOSED;\n        reject(new Error('Canceled'));\n      });\n\n      const fn: Scheduler.Job = () => {\n        return Promise.resolve()\n          .then(() => job() as any)\n          .then(resolve)\n          .catch(reject);\n      };\n\n      fn.id = job.id;\n      fn.flags = job.flags;\n\n      this.queueJob(fn, opts);\n    });\n  }\n\n  protected findInsertionIndex(id: number) {\n    let start = this.flushIndex + 1;\n    let end = this.queue.length;\n\n    while (start < end) {\n      const middle = (start + end) >>> 1;\n      const middleJob = this.queue[middle];\n      const middleJobId = getId(middleJob);\n      if (middleJobId < id) {\n        start = middle + 1;\n      } else {\n        end = middle;\n      }\n    }\n\n    return start;\n  }\n\n  protected async flushJobs(): Promise<void> {\n    try {\n      for (\n        this.flushIndex = 0;\n        this.flushIndex < this.queue.length;\n        this.flushIndex++\n      ) {\n        const job = this.queue[this.flushIndex];\n        if (job && !(job.flags! & SCHEDULER_JOB_FLAGS.DISPOSED)) {\n          if (job.flags! & SCHEDULER_JOB_FLAGS.ALLOW_RECURSE) {\n            job.flags! &= ~SCHEDULER_JOB_FLAGS.QUEUED;\n          }\n\n          for (const hookFn of this.onJobStartCbs) {\n            hookFn(job);\n          }\n\n          await job();\n\n          for (const hookFn of this.onJobCompleteCbs) {\n            hookFn(job);\n          }\n\n          if (!(job.flags! & SCHEDULER_JOB_FLAGS.ALLOW_RECURSE)) {\n            job.flags! &= ~SCHEDULER_JOB_FLAGS.QUEUED;\n          }\n        }\n      }\n    } finally {\n      // If there was an error we still need to clear the QUEUED flags\n      for (; this.flushIndex < this.queue.length; this.flushIndex++) {\n        const job = this.queue[this.flushIndex];\n        if (job) {\n          job.flags! &= ~SCHEDULER_JOB_FLAGS.QUEUED;\n        }\n      }\n\n      this.flushIndex = -1;\n      this.queue.length = 0;\n\n      this.currentFlushPromise = null;\n      // If new jobs have been added to either queue, keep flushing\n      if (this.queue.length) {\n        return this.flushJobs();\n      }\n    }\n  }\n\n  protected queueFlush() {\n    if (!this.currentFlushPromise) {\n      this.currentFlushPromise = this.resolvedPromise.then(this.flushJobs);\n    }\n  }\n}\nfunction getId(job: Scheduler.Job): number {\n  return job.id == null ? Infinity : job.id;\n}\n","import { AppError } from '@/errors/AppError';\nimport { isFunction, isPromise } from '@/is';\nimport type { Awaitable } from '@/types';\n\n/**\n * Throws an error if the provided promise or callback is not resolved within the specified timeout period.\n *\n * This function can be used to ensure that an asynchronous operation does not take too long to complete.\n * If the operation exceeds the specified time limit, the provided `timeoutError` is thrown.\n *\n * @example\n * // Example usage: Throw an error if no response is received within 1 second\n * await timeout(\n *   1000, // Timeout duration in milliseconds\n *   (signal) => {\n *     const account = await http.get('/api/users/me');\n *\n *     if (signal.aborted) return; // If the timeout occurs, abort the operation\n *\n *     const statistics = await http.get('/api/users/me/statistics');\n *\n *     return { ...account, statistics };\n *   },\n *   new Error('Request account timeout') // Custom error to throw on timeout\n * );\n *\n * @param ms - The maximum time (in milliseconds) to wait for the promise or callback to resolve.\n * @param promiseOrCallback - The asynchronous operation to execute. This can either be:\n *   - A `Promise` that will be awaited until completion, or\n *   - A function that takes an `AbortSignal` and returns a `Promise` or a value.\n * @param timeoutError - The error that will be thrown if the timeout is reached before the promise or callback resolves.\n *   (Defaults to `AppError(408)` if not provided).\n * @returns A `Promise` that resolves with the result of the provided `promiseOrCallback`, or rejects with the `timeoutError` if the timeout occurs.\n *\n * @throws {Error} - Throws the `timeoutError` if the operation exceeds the specified timeout.\n *\n * @group Promise\n */\nexport function timeout<T = any>(\n  ms: number,\n  promiseOrCallback: Promise<T> | ((abortSignal: AbortSignal) => Awaitable<T>),\n  timeoutError: any = new AppError(408),\n): Promise<T> {\n  const abortController = new AbortController();\n\n  let taskResult: any;\n\n  if (isFunction(promiseOrCallback)) {\n    taskResult = promiseOrCallback(abortController.signal);\n  } else if (isPromise(promiseOrCallback)) {\n    taskResult = promiseOrCallback;\n  } else {\n    throw new TypeError(\n      'Expected promise or callback as second argument, received: ' +\n        String(promiseOrCallback),\n    );\n  }\n\n  if (!isPromise(taskResult)) {\n    return Promise.resolve(taskResult);\n  }\n\n  let timer: ReturnType<typeof setTimeout> | undefined;\n\n  return Promise.race([\n    taskResult,\n    new Promise((_, reject) => {\n      timer = setTimeout(() => {\n        abortController.abort();\n        reject(timeoutError);\n      }, ms);\n    }),\n  ]).finally(() => {\n    timer && clearTimeout(timer);\n    timer = undefined;\n  }) as Promise<T>;\n}\n","import { isFunction, isPromise } from '@/is';\nimport type { Awaitable } from '@/types';\n\ntype ToPromiseResult<T> = T extends () => Awaitable<infer X>\n  ? X\n  : T extends Promise<infer X>\n    ? X\n    : T;\n\n/**\n * Wraps a value or a thunk in a `Promise`, always resolving on the next microtask.\n *\n * - If `value` is a function, it is called and its return value (sync or async) is awaited.\n *   Synchronous throws are converted to rejections.\n * - Otherwise, `value` is resolved as-is.\n *\n * @param value - A plain value or a zero-argument function returning `Awaitable<T>`.\n * @returns A `Promise` that resolves to the value or the function's result.\n *\n * @example\n * // Plain value\n * await toPromise(42); // → 42\n *\n * @example\n * // Sync function\n * await toPromise(() => computeResult()); // → result\n *\n * @example\n * // Async function\n * await toPromise(() => fetch('/api/data').then(r => r.json()));\n *\n * @group Promise\n */\nexport function toPromise<T>(value: T): Promise<ToPromiseResult<T>> {\n  if (isFunction(value)) {\n    return Promise.resolve().then(() => value());\n  } else if (isPromise(value)) {\n    return value as any;\n  }\n\n  return Promise.resolve().then(() => value) as any;\n}\n","import { arrayable } from '@/array';\nimport { argToKey } from '@/cache/createWithCache/utils';\nimport { isString } from '@/is';\nimport type { Arrayable } from '@/types';\nimport { type Defer, defer } from '../defer';\n\ntype ResolverFn<R extends Promise<any>, T = any, A extends any[] = any[]> = (\n  this: T,\n  ...args: A\n) => R;\n\ntype WithResolve<R extends Promise<any>, T = any, A extends any[] = any[]> = (\n  this: T,\n  ...args: A\n) => R;\n\n/**\n * A function that generates cache key based on the arguments.\n *\n * @param args - The original function arguments\n * @param computeKey - A helper function to stringify arguments into a cache key\n * @returns A cache key string if a variant should be used, or undefined to skip this variant\n */\ntype GetCacheKey = (\n  args: any[],\n  computeKey: (...args: any[]) => string,\n) => string | null | undefined;\n\nconst stringifyArgs = (...args: any[]): string => {\n  return args.map(v => argToKey(v, { objectStrategy: 'json' })).join('_');\n};\n\n/**\n * Wraps an async function to guarantee single execution for identical arguments.\n * Acts as a request deduplication mechanism - when multiple calls are made with the same\n * arguments before the first call completes, all calls wait for and receive the result\n * of the first execution.\n *\n * This is useful for preventing redundant async operations like duplicate API calls or\n * database queries that are triggered simultaneously.\n *\n * @template R - The Promise return type of the wrapped function\n * @template T - The `this` context type for the function\n * @template A - The argument types tuple for the function\n *\n * @param fn - The async function to wrap\n * @param getCacheKey - Optional array of functions to generate alternative cache keys.\n *   Useful when different argument combinations should be treated as equivalent.\n *\n * @returns A wrapped version of the function with deduplication behavior\n *\n * @example Basic usage - deduplicating database queries\n * ```ts\n * const fetchUserById = withResolve((userId: number) =>\n *   db.users.findById(userId)\n * );\n *\n * // Only produces 1 database query, both calls receive the same result\n * const [user1, user2] = await Promise.all([\n *   fetchUserById(100),\n *   fetchUserById(100)\n * ]);\n * ```\n *\n * @example With cache key variants\n * ```ts\n * const fetchUser = withResolve(\n *   (id: number, options?: { fresh?: boolean }) => api.getUser(id, options),\n *   [\n *     // Treat calls with/without options as equivalent if fresh is false/undefined\n *     (args, computeKey) => {\n *       const [id, options] = args;\n *       if (options?.fresh) {\n *         return null;\n *       }\n *\n *       return computeKey(id, {});\n *     }\n *   ]\n * );\n *\n * // Both calls deduplicated to single request\n * await Promise.all([\n *   fetchUser(1),\n *   fetchUser(1, { fresh: false })\n * ]);\n * ```\n *\n * @remarks\n * - The cache is held only during the execution of the first call\n * - Once the promise resolves or rejects, the cache entry is cleared\n * - All waiting calls receive the same result (success or error)\n * - Works with both resolved and rejected promises\n *\n * @group Promise\n */\nexport function withResolve<\n  R extends Promise<any>,\n  T = any,\n  A extends any[] = any[],\n>(\n  fn: ResolverFn<R, T, A>,\n  getCacheKey?: Arrayable<GetCacheKey>,\n): WithResolve<R, T, A> {\n  const cache = new Map<string | symbol, Defer[]>();\n  const cacheKeyVariants = arrayable(getCacheKey);\n\n  return function (this: T, ...args: A) {\n    let cacheKey: string | symbol = stringifyArgs(...args);\n\n    if (cacheKeyVariants?.length) {\n      for (const getCacheKey of cacheKeyVariants) {\n        const newCacheKey = getCacheKey(args, stringifyArgs);\n\n        if (newCacheKey === null) {\n          cacheKey = Symbol(); // Use random symbol as cache key\n          break;\n        } else if (isString(newCacheKey) && cache.has(newCacheKey)) {\n          cacheKey = newCacheKey;\n          break;\n        }\n      }\n    }\n\n    const defers = cache.get(cacheKey) || [];\n    const size = defers.length;\n\n    const q = defer<unknown>();\n    defers.push(q);\n    cache.set(cacheKey, defers);\n\n    if (size) {\n      return q.promise;\n    }\n\n    resolver(this, cacheKey, args);\n\n    return q.promise;\n  } as WithResolve<R, T, A>;\n\n  function resolver(self: T, cacheKey: string | symbol, args: A) {\n    const onSuccess = (r: any) => {\n      const defers = cache.get(cacheKey) || [];\n\n      for (const q of defers) {\n        q.resolve(r);\n      }\n\n      cache.delete(cacheKey);\n    };\n\n    const onError = (r: any) => {\n      const defers = cache.get(cacheKey) || [];\n\n      for (const q of defers) {\n        q.reject(r);\n      }\n\n      cache.delete(cacheKey);\n    };\n\n    try {\n      fn.apply(self, args).then(onSuccess).catch(onError);\n    } catch (err) {\n      onError(err);\n    }\n  }\n}\n"],"mappings":"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"}