speexjs-core 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +117 -0
- package/CONTRIBUTING.md +55 -0
- package/PUBLISH.md +45 -0
- package/README.md +174 -0
- package/ROADMAP.md +72 -0
- package/SECURITY.md +35 -0
- package/SUMMARY.md +321 -0
- package/dist/async/index.d.ts +232 -0
- package/dist/async/index.js +366 -0
- package/dist/async/index.js.map +1 -0
- package/dist/collection/index.d.ts +230 -0
- package/dist/collection/index.js +375 -0
- package/dist/collection/index.js.map +1 -0
- package/dist/color/index.d.ts +128 -0
- package/dist/color/index.js +167 -0
- package/dist/color/index.js.map +1 -0
- package/dist/core/index.d.ts +119 -0
- package/dist/core/index.js +324 -0
- package/dist/core/index.js.map +1 -0
- package/dist/crypto/index.d.ts +84 -0
- package/dist/crypto/index.js +144 -0
- package/dist/crypto/index.js.map +1 -0
- package/dist/date/index.d.ts +588 -0
- package/dist/date/index.js +737 -0
- package/dist/date/index.js.map +1 -0
- package/dist/dep-exray/analyzer/index.d.ts +7 -0
- package/dist/dep-exray/analyzer/index.js +68 -0
- package/dist/dep-exray/analyzer/index.js.map +1 -0
- package/dist/dep-exray/cli.d.ts +1 -0
- package/dist/dep-exray/cli.js +441 -0
- package/dist/dep-exray/cli.js.map +1 -0
- package/dist/dep-exray/index.d.ts +5 -0
- package/dist/dep-exray/index.js +454 -0
- package/dist/dep-exray/index.js.map +1 -0
- package/dist/dep-exray/known-mappings.d.ts +17 -0
- package/dist/dep-exray/known-mappings.js +122 -0
- package/dist/dep-exray/known-mappings.js.map +1 -0
- package/dist/dep-exray/reporter/index.d.ts +5 -0
- package/dist/dep-exray/reporter/index.js +89 -0
- package/dist/dep-exray/reporter/index.js.map +1 -0
- package/dist/dep-exray/scanner/index.d.ts +5 -0
- package/dist/dep-exray/scanner/index.js +299 -0
- package/dist/dep-exray/scanner/index.js.map +1 -0
- package/dist/dep-exray/types.d.ts +38 -0
- package/dist/dep-exray/types.js +1 -0
- package/dist/dep-exray/types.js.map +1 -0
- package/dist/error/index.d.ts +148 -0
- package/dist/error/index.js +115 -0
- package/dist/error/index.js.map +1 -0
- package/dist/index-BgG21uJC.d.ts +166 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +4378 -0
- package/dist/index.js.map +1 -0
- package/dist/io/index.d.ts +39 -0
- package/dist/io/index.js +111 -0
- package/dist/io/index.js.map +1 -0
- package/dist/logger/index.d.ts +1 -0
- package/dist/logger/index.js +214 -0
- package/dist/logger/index.js.map +1 -0
- package/dist/logger/transports.d.ts +1 -0
- package/dist/logger/transports.js +122 -0
- package/dist/logger/transports.js.map +1 -0
- package/dist/math/index.d.ts +362 -0
- package/dist/math/index.js +372 -0
- package/dist/math/index.js.map +1 -0
- package/dist/path/index.d.ts +81 -0
- package/dist/path/index.js +134 -0
- package/dist/path/index.js.map +1 -0
- package/dist/string/index.d.ts +234 -0
- package/dist/string/index.js +411 -0
- package/dist/string/index.js.map +1 -0
- package/dist/type/index.d.ts +85 -0
- package/dist/type/index.js +107 -0
- package/dist/type/index.js.map +1 -0
- package/dist/validation/index.d.ts +203 -0
- package/dist/validation/index.js +402 -0
- package/dist/validation/index.js.map +1 -0
- package/package.json +172 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/index.ts","../src/math/index.ts","../src/date/index.ts","../src/crypto/index.ts","../src/path/index.ts","../src/collection/index.ts","../src/string/index.ts","../src/async/queue.ts","../src/async/semaphore.ts","../src/async/memoize.ts","../src/async/ratelimit.ts","../src/async/mutex.ts","../src/async/batch.ts","../src/async/waterfall.ts","../src/async/index.ts","../src/io/index.ts","../src/type/index.ts","../src/dep-exray/scanner/index.ts","../src/dep-exray/known-mappings.ts","../src/dep-exray/reporter/index.ts","../src/dep-exray/analyzer/index.ts","../src/validation/isNIK.ts","../src/validation/isNPWP.ts","../src/validation/isPhone.ts","../src/validation/isEmail.ts","../src/validation/isURL.ts","../src/validation/parseNIK.ts","../src/validation/isPlatNomor.ts","../src/validation/isKodepos.ts","../src/validation/isNoRekening.ts","../src/validation/isNoSIM.ts","../src/validation/isPassport.ts","../src/validation/isNoBPJS.ts","../src/validation/isNoKK.ts","../src/error/createError.ts","../src/error/MultiError.ts","../src/logger/logger.ts","../src/logger/transports.ts","../src/color/index.ts"],"sourcesContent":["export interface DebounceOptions {\r\n leading?: boolean\r\n trailing?: boolean\r\n maxWait?: number\r\n}\r\n\r\nexport interface DebouncedFunction<T extends (...args: unknown[]) => unknown> {\r\n (...args: Parameters<T>): void\r\n cancel(): void\r\n flush(): void\r\n}\r\n\r\nexport interface MemoizedFunction<T extends (...args: unknown[]) => unknown> {\r\n (...args: Parameters<T>): ReturnType<T>\r\n cache: Map<string, ReturnType<T>>\r\n}\r\n\r\nexport interface RetryOptions {\r\n attempts?: number\r\n baseDelay?: number\r\n maxDelay?: number\r\n shouldRetry?: (error: unknown) => boolean\r\n}\r\n\r\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\r\n if (value === null || typeof value !== 'object') return false\r\n const proto = Object.getPrototypeOf(value)\r\n return proto === Object.prototype || proto === null\r\n}\r\n\r\nfunction getType(value: unknown): string {\r\n return Object.prototype.toString.call(value)\r\n}\r\n\r\nfunction clone<T>(value: T, seen: WeakMap<object, unknown>): T {\r\n if (value === null || typeof value !== 'object') return value\r\n\r\n if (seen.has(value as object)) return seen.get(value as object) as T\r\n\r\n const tag = getType(value)\r\n\r\n if (tag === '[object Date]') {\r\n const cloned = new Date((value as unknown as Date).getTime())\r\n seen.set(value as object, cloned)\r\n return cloned as unknown as T\r\n }\r\n\r\n if (tag === '[object RegExp]') {\r\n const regExp = value as unknown as RegExp\r\n const cloned = new RegExp(regExp.source, regExp.flags)\r\n cloned.lastIndex = regExp.lastIndex\r\n seen.set(value as object, cloned)\r\n return cloned as unknown as T\r\n }\r\n\r\n if (tag === '[object Map]') {\r\n const cloned = new Map<unknown, unknown>()\r\n seen.set(value as object, cloned)\r\n ;(value as unknown as Map<unknown, unknown>).forEach((v, k) => {\r\n cloned.set(clone(k, seen), clone(v, seen))\r\n })\r\n return cloned as unknown as T\r\n }\r\n\r\n if (tag === '[object Set]') {\r\n const cloned = new Set<unknown>()\r\n seen.set(value as object, cloned)\r\n ;(value as unknown as Set<unknown>).forEach(v => {\r\n cloned.add(clone(v, seen))\r\n })\r\n return cloned as unknown as T\r\n }\r\n\r\n if (Array.isArray(value)) {\r\n const cloned: unknown[] = []\r\n seen.set(value as object, cloned)\r\n for (let i = 0; i < value.length; i++) {\r\n cloned[i] = clone(value[i], seen)\r\n }\r\n return cloned as unknown as T\r\n }\r\n\r\n if (tag === '[object Object]') {\r\n const cloned: Record<string, unknown> = {}\r\n seen.set(value as object, cloned)\r\n const keys = Object.keys(value as Record<string, unknown>)\r\n for (let i = 0; i < keys.length; i++) {\r\n const key = keys[i]!\r\n cloned[key] = clone((value as Record<string, unknown>)[key], seen)\r\n }\r\n return cloned as unknown as T\r\n }\r\n\r\n return value\r\n}\r\n\r\n/**\r\n * Deep clone a value, supporting objects, arrays, Date, RegExp, Map, Set,\r\n * and cyclic references.\r\n *\r\n * @param value - The value to clone.\r\n * @returns A deep copy of the input value.\r\n */\r\nexport function deepClone<T>(value: T): T {\r\n const seen = new WeakMap<object, unknown>()\r\n return clone(value, seen)\r\n}\r\n\r\n/**\r\n * Deep merge multiple objects. Arrays are overwritten, not concatenated.\r\n * `null` and `undefined` source objects are skipped.\r\n *\r\n * @param objects - The objects to merge.\r\n * @returns A new object with merged properties.\r\n */\r\nexport function deepMerge<T extends Record<string, unknown>>(...objects: Partial<T>[]): T {\r\n const result = {} as T\r\n\r\n for (let i = 0; i < objects.length; i++) {\r\n const obj = objects[i]\r\n if (obj === null || obj === undefined) continue\r\n\r\n const keys = Object.keys(obj) as (keyof T)[]\r\n for (let j = 0; j < keys.length; j++) {\r\n const key = keys[j]!\r\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') continue\r\n const val = obj[key]\r\n const existing = result[key]\r\n\r\n if (val !== undefined && isPlainObject(val) && isPlainObject(existing)) {\r\n result[key] = deepMerge(\r\n existing as Record<string, unknown>,\r\n val as Record<string, unknown>\r\n ) as T[keyof T]\r\n } else if (val !== undefined) {\r\n result[key] = val as T[keyof T]\r\n }\r\n }\r\n }\r\n\r\n return result\r\n}\r\n\r\n/**\r\n * Creates a debounced function that delays invoking `fn` until after `wait`\r\n * milliseconds have elapsed since the last invocation. Supports leading,\r\n * trailing, and maxWait options. The returned function also has `.cancel()`\r\n * and `.flush()` methods.\r\n *\r\n * @param fn - The function to debounce.\r\n * @param wait - The number of milliseconds to delay.\r\n * @param options - Optional configuration.\r\n * @returns A debounced function with `.cancel()` and `.flush()`.\r\n */\r\nexport function debounce<T extends (...args: unknown[]) => unknown>(\r\n fn: T,\r\n wait: number,\r\n options?: DebounceOptions\r\n): DebouncedFunction<T> {\r\n const { leading = false, trailing = true, maxWait } = options ?? {}\r\n\r\n let timer: ReturnType<typeof setTimeout> | null = null\r\n let maxTimer: ReturnType<typeof setTimeout> | null = null\r\n let lastArgs: Parameters<T> | null = null\r\n let lastCallTime: number | null = null\r\n let lastInvokeTime = 0\r\n\r\n function invoke(time: number): void {\r\n lastInvokeTime = time\r\n if (lastArgs) {\r\n fn(...lastArgs)\r\n lastArgs = null\r\n }\r\n }\r\n\r\n function startTimer(waitTime: number): void {\r\n if (timer) clearTimeout(timer)\r\n timer = setTimeout(() => {\r\n const now = Date.now()\r\n if (lastArgs && trailing) {\r\n invoke(now)\r\n }\r\n timer = null\r\n lastCallTime = null\r\n }, waitTime)\r\n }\r\n\r\n function startMaxTimer(): void {\r\n if (maxWait === undefined || maxTimer) return\r\n maxTimer = setTimeout(() => {\r\n if (lastArgs) {\r\n invoke(Date.now())\r\n if (timer) {\r\n clearTimeout(timer)\r\n timer = null\r\n }\r\n lastCallTime = null\r\n }\r\n }, maxWait)\r\n }\r\n\r\n function clearAllTimers(): void {\r\n if (timer) {\r\n clearTimeout(timer)\r\n timer = null\r\n }\r\n if (maxTimer) {\r\n clearTimeout(maxTimer)\r\n maxTimer = null\r\n }\r\n }\r\n\r\n function shouldInvoke(time: number): boolean {\r\n if (lastCallTime === null) return true\r\n const timeSinceLastCall = time - lastCallTime\r\n const timeSinceLastInvoke = time - lastInvokeTime\r\n return (\r\n timeSinceLastCall >= wait ||\r\n (maxWait !== undefined && timeSinceLastInvoke >= maxWait)\r\n )\r\n }\r\n\r\n const debounced = function (this: unknown, ...args: Parameters<T>): void {\r\n const time = Date.now()\r\n const isInvoking = shouldInvoke(time)\r\n\r\n lastArgs = args\r\n lastCallTime = time\r\n\r\n if (isInvoking && !timer && leading) {\r\n invoke(time)\r\n }\r\n\r\n if (!timer) {\r\n startTimer(wait)\r\n if (maxWait !== undefined) {\r\n startMaxTimer()\r\n }\r\n }\r\n } as DebouncedFunction<T>\r\n\r\n debounced.cancel = (): void => {\r\n clearAllTimers()\r\n lastArgs = null\r\n lastCallTime = null\r\n lastInvokeTime = 0\r\n }\r\n\r\n debounced.flush = (): void => {\r\n if (timer && lastArgs) {\r\n invoke(Date.now())\r\n clearAllTimers()\r\n lastCallTime = null\r\n }\r\n }\r\n\r\n return debounced\r\n}\r\n\r\n/**\r\n * Creates a throttled function that only invokes `fn` at most once per\r\n * `wait` milliseconds.\r\n *\r\n * @param fn - The function to throttle.\r\n * @param wait - The number of milliseconds to throttle invocations to.\r\n * @returns A throttled function.\r\n */\r\nexport function throttle<T extends (...args: unknown[]) => unknown>(\r\n fn: T,\r\n wait: number\r\n): (...args: Parameters<T>) => void {\r\n let lastTime = 0\r\n let timer: ReturnType<typeof setTimeout> | null = null\r\n let lastArgs: Parameters<T> | null = null\r\n\r\n const throttled = function (this: unknown, ...args: Parameters<T>): void {\r\n const now = Date.now()\r\n const remaining = wait - (now - lastTime)\r\n\r\n if (remaining <= 0) {\r\n if (timer) {\r\n clearTimeout(timer)\r\n timer = null\r\n }\r\n lastTime = now\r\n lastArgs = null\r\n fn.apply(this, args)\r\n } else {\r\n lastArgs = args\r\n if (!timer) {\r\n timer = setTimeout(() => {\r\n lastTime = Date.now()\r\n timer = null\r\n if (lastArgs) {\r\n fn.apply(this, lastArgs)\r\n lastArgs = null\r\n }\r\n }, remaining)\r\n }\r\n }\r\n }\r\n\r\n return throttled\r\n}\r\n\r\n/**\r\n * Creates a memoized version of `fn`. Uses a `Map` cache keyed by the\r\n * first argument by default, or by a custom `resolver` function.\r\n *\r\n * @param fn - The function to memoize.\r\n * @param resolver - Optional function to determine the cache key.\r\n * @returns The memoized function with a `.cache` property.\r\n */\r\nexport function memoize<T extends (...args: unknown[]) => unknown>(\r\n fn: T,\r\n resolver?: (...args: Parameters<T>) => string\r\n): MemoizedFunction<T> {\r\n const cache = new Map<string, ReturnType<T>>()\r\n\r\n const memoized = function (this: unknown, ...args: Parameters<T>): ReturnType<T> {\r\n const key = resolver ? resolver(...args) : String(args[0])\r\n if (cache.has(key)) {\r\n return cache.get(key) as ReturnType<T>\r\n }\r\n const result = fn.apply(this, args) as ReturnType<T>\r\n cache.set(key, result)\r\n return result\r\n }\r\n\r\n memoized.cache = cache\r\n\r\n return memoized as MemoizedFunction<T>\r\n}\r\n\r\n/**\r\n * Retries an async function with exponential backoff and jitter.\r\n *\r\n * @param fn - The async function to retry.\r\n * @param options - Retry configuration.\r\n * @returns A promise that resolves with the function result.\r\n */\r\nexport function retry<T>(\r\n fn: () => Promise<T>,\r\n options?: RetryOptions\r\n): Promise<T> {\r\n const {\r\n attempts = 3,\r\n baseDelay = 1000,\r\n maxDelay = 30000,\r\n shouldRetry = () => true,\r\n } = options ?? {}\r\n\r\n let attempt = 0\r\n\r\n const execute = (): Promise<T> => {\r\n attempt++\r\n return fn().catch((error: unknown) => {\r\n if (attempt >= attempts || !shouldRetry(error)) {\r\n throw error\r\n }\r\n\r\n const delay = Math.min(\r\n baseDelay * Math.pow(2, attempt - 1) + Math.random() * baseDelay,\r\n maxDelay\r\n )\r\n\r\n return new Promise<T>(resolve => {\r\n setTimeout(() => {\r\n resolve(execute())\r\n }, delay)\r\n })\r\n })\r\n }\r\n\r\n return execute()\r\n}\r\n\r\n/**\r\n * A no-operation function that returns `undefined`.\r\n */\r\nexport function noop(): void {\r\n return undefined\r\n}\r\n\r\n/**\r\n * Returns the given value unchanged.\r\n *\r\n * @param value - The value to return.\r\n * @returns The same value.\r\n */\r\nexport function identity<T>(value: T): T {\r\n return value\r\n}\r\n\r\n/**\r\n * Creates a function that invokes `fn` only once. Subsequent calls return\r\n * the result of the first invocation.\r\n *\r\n * @param fn - The function to wrap.\r\n * @returns A function that runs only once.\r\n */\r\nexport function once<T extends (...args: unknown[]) => unknown>(\r\n fn: T\r\n): (...args: Parameters<T>) => ReturnType<T> {\r\n let called = false\r\n let result: ReturnType<T>\r\n\r\n return function (this: unknown, ...args: Parameters<T>): ReturnType<T> {\r\n if (!called) {\r\n called = true\r\n result = fn.apply(this, args) as ReturnType<T>\r\n }\r\n return result\r\n }\r\n}\r\n\r\n/**\r\n * Deep equality check between two values. Supports primitives, objects,\r\n * arrays, Date, RegExp, Map, Set, and nested structures. Circular\r\n * references are handled.\r\n *\r\n * @example deepEqual({ a: 1, b: { c: 2 } }, { a: 1, b: { c: 2 } }) // true\r\n * @example deepEqual({ a: 1 }, { a: 2 }) // false\r\n */\r\nexport function deepEqual(a: unknown, b: unknown): boolean {\r\n if (Object.is(a, b)) return true\r\n if (a === null || b === null || typeof a !== typeof b) return false\r\n if (typeof a !== 'object') return false\r\n\r\n const aObj = a as Record<string, unknown>\r\n const bObj = b as Record<string, unknown>\r\n\r\n if (Array.isArray(a) && Array.isArray(b)) {\r\n if (a.length !== b.length) return false\r\n for (let i = 0; i < a.length; i++) {\r\n if (!deepEqual(a[i], b[i])) return false\r\n }\r\n return true\r\n }\r\n\r\n if (a instanceof Date && b instanceof Date) {\r\n return a.getTime() === b.getTime()\r\n }\r\n\r\n if (a instanceof RegExp && b instanceof RegExp) {\r\n return a.source === b.source && a.flags === b.flags\r\n }\r\n\r\n if (a instanceof Map && b instanceof Map) {\r\n if (a.size !== b.size) return false\r\n for (const [k, v] of a) {\r\n if (!b.has(k) || !deepEqual(v, b.get(k))) return false\r\n }\r\n return true\r\n }\r\n\r\n if (a instanceof Set && b instanceof Set) {\r\n if (a.size !== b.size) return false\r\n for (const v of a) {\r\n if (!b.has(v)) return false\r\n }\r\n return true\r\n }\r\n\r\n const keysA = Object.keys(aObj)\r\n const keysB = Object.keys(bObj)\r\n if (keysA.length !== keysB.length) return false\r\n\r\n for (const key of keysA) {\r\n if (!Object.prototype.hasOwnProperty.call(bObj, key)) return false\r\n if (!deepEqual(aObj[key], bObj[key])) return false\r\n }\r\n return true\r\n}\r\n\r\n/**\r\n * Performs left-to-right function composition.\r\n *\r\n * @example const fn = pipe((x: number) => x + 1, (x: number) => x * 2)\r\n * fn(3) // 8\r\n */\r\nexport function pipe<T>(initial: T, ...fns: Array<(arg: T) => T>): T\r\nexport function pipe<T, R>(initial: T, ...fns: Array<(arg: unknown) => unknown>): R\r\nexport function pipe(initial: unknown, ...fns: Array<(arg: unknown) => unknown>): unknown {\r\n return fns.reduce((acc, fn) => fn(acc), initial)\r\n}\r\n\r\n/**\r\n * Performs right-to-left function composition.\r\n *\r\n * @example const fn = compose((x: number) => x * 2, (x: number) => x + 1)\r\n * fn(3) // 8 — same as (3+1)*2\r\n */\r\nexport function compose<T>(...fns: Array<(arg: T) => T>): (initial: T) => T\r\nexport function compose(...fns: Array<(arg: unknown) => unknown>): (initial: unknown) => unknown {\r\n return (initial: unknown) => fns.reduceRight((acc, fn) => fn(acc), initial)\r\n}\r\n","/**\r\n * Error thrown when attempting to divide by zero.\r\n */\r\nexport class DivisionByZeroError extends Error {\r\n constructor() {\r\n super('Division by zero')\r\n this.name = 'DivisionByZeroError'\r\n }\r\n}\r\n\r\nfunction getPrecision(value: number): number {\r\n if (!isFinite(value)) return 0\r\n const eIndex = String(value).indexOf('e')\r\n if (eIndex > -1) {\r\n const exp = parseInt(String(value).slice(eIndex + 1), 10)\r\n if (exp < 0) return Math.abs(exp)\r\n return 0\r\n }\r\n const str = String(value)\r\n const dot = str.indexOf('.')\r\n return dot === -1 ? 0 : str.length - dot - 1\r\n}\r\n\r\nfunction toPrecisionFactor(a: number, b: number): number {\r\n return Math.pow(10, Math.max(getPrecision(a), getPrecision(b)))\r\n}\r\n\r\n/**\r\n * Safely adds two numbers, handling floating-point precision.\r\n *\r\n * @param a - First number.\r\n * @param b - Second number.\r\n * @returns The sum.\r\n */\r\nexport function add(a: number, b: number): number {\r\n const factor = toPrecisionFactor(a, b)\r\n return (Math.round(a * factor) + Math.round(b * factor)) / factor\r\n}\r\n\r\n/**\r\n * Safely subtracts two numbers, handling floating-point precision.\r\n *\r\n * @param a - First number.\r\n * @param b - Second number.\r\n * @returns The difference.\r\n */\r\nexport function sub(a: number, b: number): number {\r\n const factor = toPrecisionFactor(a, b)\r\n return (Math.round(a * factor) - Math.round(b * factor)) / factor\r\n}\r\n\r\n/**\r\n * Safely multiplies two numbers, handling floating-point precision.\r\n *\r\n * @param a - First number.\r\n * @param b - Second number.\r\n * @returns The product.\r\n */\r\nexport function mul(a: number, b: number): number {\r\n const factorA = toPrecisionFactor(a, 1)\r\n const factorB = toPrecisionFactor(1, b)\r\n const result = (Math.round(a * factorA) * Math.round(b * factorB)) / (factorA * factorB)\r\n return result\r\n}\r\n\r\n/**\r\n * Safely divides two numbers.\r\n *\r\n * @param a - The dividend.\r\n * @param b - The divisor.\r\n * @returns The quotient.\r\n * @throws {DivisionByZeroError} If `b` is zero.\r\n */\r\nexport function div(a: number, b: number): number {\r\n if (b === 0) throw new DivisionByZeroError()\r\n const factor = toPrecisionFactor(a, b)\r\n return Math.round(a * factor) / Math.round(b * factor)\r\n}\r\n\r\n/**\r\n * Rounds a number to the given precision.\r\n *\r\n * @param value - The number to round.\r\n * @param precision - Number of decimal places (default 0).\r\n * @returns The rounded value.\r\n */\r\nexport function round(value: number, precision: number = 0): number {\r\n const factor = Math.pow(10, precision)\r\n // Use toPrecision to avoid floating-point multiplication errors\r\n // e.g. 1.005 * 100 = 100.49999999999999 without this fix\r\n const shifted = Number((value * factor).toPrecision(15))\r\n return Math.round(shifted) / factor\r\n}\r\n\r\n/**\r\n * Floors a number to the given precision.\r\n *\r\n * @param value - The number to floor.\r\n * @param precision - Number of decimal places (default 0).\r\n * @returns The floored value.\r\n */\r\nexport function floor(value: number, precision: number = 0): number {\r\n const factor = Math.pow(10, precision)\r\n return Math.floor(value * factor) / factor\r\n}\r\n\r\n/**\r\n * Ceils a number to the given precision.\r\n *\r\n * @param value - The number to ceil.\r\n * @param precision - Number of decimal places (default 0).\r\n * @returns The ceiled value.\r\n */\r\nexport function ceil(value: number, precision: number = 0): number {\r\n const factor = Math.pow(10, precision)\r\n return Math.ceil(value * factor) / factor\r\n}\r\n\r\n/**\r\n * Checks if two numbers are approximately equal within a tolerance.\r\n *\r\n * @param a - First number.\r\n * @param b - Second number.\r\n * @param tolerance - Maximum difference (default `Number.EPSILON`).\r\n * @returns Whether the numbers are approximately equal.\r\n */\r\nexport function approxEqual(a: number, b: number, tolerance: number = Number.EPSILON): boolean {\r\n return Math.abs(a - b) <= tolerance\r\n}\r\n\r\n/**\r\n * Clamps a value within the inclusive range [min, max].\r\n *\r\n * @param value - The value to clamp.\r\n * @param min - The lower bound.\r\n * @param max - The upper bound.\r\n * @returns The clamped value.\r\n * @throws {RangeError} If `min` exceeds `max`.\r\n */\r\nexport function clamp(value: number, min: number, max: number): number {\r\n if (min > max) {\r\n throw new RangeError('Minimum value cannot exceed maximum value')\r\n }\r\n return Math.min(Math.max(value, min), max)\r\n}\r\n\r\n/**\r\n * Computes the sum of an array of numbers.\r\n *\r\n * @param values - Array of numbers.\r\n * @returns The total sum.\r\n */\r\nexport function sum(values: number[]): number {\r\n let total = 0\r\n for (let i = 0; i < values.length; i++) {\r\n total += values[i]!\r\n }\r\n return total\r\n}\r\n\r\n/**\r\n * Computes the average (mean) of an array of numbers.\r\n *\r\n * @param values - Array of numbers.\r\n * @returns The average.\r\n * @throws {RangeError} If the array is empty.\r\n */\r\nexport function average(values: number[]): number {\r\n if (values.length === 0) {\r\n throw new RangeError('Cannot compute average of an empty array')\r\n }\r\n return sum(values) / values.length\r\n}\r\n\r\n/**\r\n * Generates a random integer between `min` and `max` (inclusive).\r\n *\r\n * @param min - The minimum integer.\r\n * @param max - The maximum integer.\r\n * @returns A random integer.\r\n * @throws {RangeError} If arguments are not integers or `min > max`.\r\n */\r\nexport function randomInt(min: number, max: number): number {\r\n if (!Number.isInteger(min) || !Number.isInteger(max)) {\r\n throw new RangeError('Arguments must be integers')\r\n }\r\n if (min > max) {\r\n throw new RangeError('Minimum value cannot exceed maximum value')\r\n }\r\n return Math.floor(Math.random() * (max - min + 1)) + min\r\n}\r\n\r\n/**\r\n * Checks if a number is within the inclusive range [min, max].\r\n *\r\n * @param value - The number to check.\r\n * @param min - The lower bound.\r\n * @param max - The upper bound.\r\n * @returns Whether the value is in range.\r\n */\r\nexport function inRange(value: number, min: number, max: number): boolean {\r\n return value >= min && value <= max\r\n}\r\n\r\n// ─── Statistics ─────────────────────────────────────────\r\n\r\n/**\r\n * Computes the median of an array of numbers.\r\n *\r\n * @param values - Array of numbers.\r\n * @returns The median value.\r\n * @throws {RangeError} If the array is empty.\r\n */\r\nexport function median(values: number[]): number {\r\n if (values.length === 0) throw new RangeError('Cannot compute median of an empty array')\r\n const sorted = [...values].sort((a, b) => a - b)\r\n const mid = Math.floor(sorted.length / 2)\r\n return sorted.length % 2 === 0 ? (sorted[mid - 1]! + sorted[mid]!) / 2 : sorted[mid]!\r\n}\r\n\r\n/**\r\n * Computes the population standard deviation.\r\n *\r\n * @param values - Array of numbers.\r\n * @returns The standard deviation.\r\n * @throws {RangeError} If the array has fewer than 2 values.\r\n */\r\nexport function stddev(values: number[]): number {\r\n if (values.length < 2) throw new RangeError('Need at least 2 values for stddev')\r\n const mean = sum(values) / values.length\r\n const sqDiffs = values.map((v) => (v - mean) ** 2)\r\n return Math.sqrt(sqDiffs.reduce((a, b) => a + b, 0) / values.length)\r\n}\r\n\r\n/**\r\n * Computes the sample standard deviation (Bessel's correction).\r\n *\r\n * @param values - Array of numbers.\r\n * @returns The sample standard deviation.\r\n * @throws {RangeError} If the array has fewer than 2 values.\r\n */\r\nexport function sampleStddev(values: number[]): number {\r\n if (values.length < 2) throw new RangeError('Need at least 2 values for sample stddev')\r\n const mean = sum(values) / values.length\r\n const sqDiffs = values.map((v) => (v - mean) ** 2)\r\n return Math.sqrt(sqDiffs.reduce((a, b) => a + b, 0) / (values.length - 1))\r\n}\r\n\r\n/**\r\n * Computes the percentile value (0-100) using linear interpolation.\r\n *\r\n * @param values - Array of numbers.\r\n * @param p - Percentile (0-100).\r\n * @returns The percentile value.\r\n * @throws {RangeError} If p is outside [0, 100] or array is empty.\r\n */\r\nexport function percentile(values: number[], p: number): number {\r\n if (values.length === 0) throw new RangeError('Cannot compute percentile of empty array')\r\n if (p < 0 || p > 100) throw new RangeError('Percentile must be between 0 and 100')\r\n const sorted = [...values].sort((a, b) => a - b)\r\n const rank = (p / 100) * (sorted.length - 1)\r\n const lower = Math.floor(rank)\r\n const upper = Math.ceil(rank)\r\n if (lower === upper) return sorted[lower]!\r\n return sorted[lower]! + (sorted[upper]! - sorted[lower]!) * (rank - lower)\r\n}\r\n\r\n/**\r\n * Computes the Pearson correlation coefficient between two arrays.\r\n *\r\n * @param x - First array.\r\n * @param y - Second array.\r\n * @returns The correlation coefficient (-1 to 1).\r\n * @throws {RangeError} If arrays have different lengths or fewer than 2 pairs.\r\n */\r\nexport function correlation(x: number[], y: number[]): number {\r\n if (x.length !== y.length) throw new RangeError('Arrays must have the same length')\r\n if (x.length < 2) throw new RangeError('Need at least 2 pairs for correlation')\r\n const n = x.length\r\n const meanX = sum(x) / n\r\n const meanY = sum(y) / n\r\n let num = 0\r\n let denX = 0\r\n let denY = 0\r\n for (let i = 0; i < n; i++) {\r\n const dx = x[i]! - meanX\r\n const dy = y[i]! - meanY\r\n num += dx * dy\r\n denX += dx * dx\r\n denY += dy * dy\r\n }\r\n if (denX === 0 || denY === 0) return 0\r\n return num / Math.sqrt(denX * denY)\r\n}\r\n\r\n/**\r\n * Formats a number as a currency string with locale support.\r\n *\r\n * @example formatCurrency(1500000) // \"Rp1.500.000\"\r\n * @example formatCurrency(1500000, { notation: 'compact' }) // \"Rp1,5 jt\"\r\n * @example formatCurrency(99.99, { locale: 'en-US', currency: 'USD' }) // \"$99.99\"\r\n *\r\n * @param value - The number to format.\r\n * @param options - Formatting options.\r\n * @returns The formatted currency string.\r\n */\r\nexport function formatCurrency(\r\n value: number,\r\n options?: { locale?: string; currency?: string; notation?: 'standard' | 'compact' },\r\n): string {\r\n const locale = options?.locale ?? 'id-ID'\r\n const currency = options?.currency ?? 'IDR'\r\n const notation = options?.notation ?? 'standard'\r\n\r\n try {\r\n return new Intl.NumberFormat(locale, {\r\n style: 'currency',\r\n currency,\r\n notation,\r\n minimumFractionDigits: 0,\r\n maximumFractionDigits: 2,\r\n }).format(value)\r\n } catch {\r\n return `${currency} ${value.toLocaleString(locale)}`\r\n }\r\n}\r\n\r\n// ─── Parity ─────────────────────────────────────────────\r\n\r\n/**\r\n * Checks if a number is even.\r\n *\r\n * @example isEven(4) // true\r\n * @example isEven(7) // false\r\n *\r\n * @param n - The number to check.\r\n * @returns Whether the number is even.\r\n */\r\nexport function isEven(n: number): boolean {\r\n return n % 2 === 0\r\n}\r\n\r\n/**\r\n * Checks if a number is odd.\r\n *\r\n * @example isOdd(3) // true\r\n * @example isOdd(8) // false\r\n *\r\n * @param n - The number to check.\r\n * @returns Whether the number is odd.\r\n */\r\nexport function isOdd(n: number): boolean {\r\n return n % 2 !== 0\r\n}\r\n\r\n// ─── Number Theory ──────────────────────────────────────\r\n\r\n/**\r\n * Computes the greatest common divisor (GCD) using the Euclidean algorithm.\r\n *\r\n * @example gcd(12, 8) // 4\r\n * @example gcd(17, 5) // 1\r\n *\r\n * @param a - First integer.\r\n * @param b - Second integer.\r\n * @returns The GCD.\r\n */\r\nexport function gcd(a: number, b: number): number {\r\n if (!Number.isInteger(a) || !Number.isInteger(b)) {\r\n throw new RangeError('Arguments must be integers')\r\n }\r\n a = Math.abs(a)\r\n b = Math.abs(b)\r\n while (b !== 0) {\r\n const t = b\r\n b = a % b\r\n a = t\r\n }\r\n return a\r\n}\r\n\r\n/**\r\n * Computes the least common multiple (LCM).\r\n *\r\n * @example lcm(4, 6) // 12\r\n * @example lcm(7, 5) // 35\r\n *\r\n * @param a - First integer.\r\n * @param b - Second integer.\r\n * @returns The LCM.\r\n * @throws {RangeError} If either argument is zero.\r\n */\r\nexport function lcm(a: number, b: number): number {\r\n if (!Number.isInteger(a) || !Number.isInteger(b)) {\r\n throw new RangeError('Arguments must be integers')\r\n }\r\n if (a === 0 || b === 0) {\r\n throw new RangeError('Arguments must be non-zero')\r\n }\r\n return Math.abs(a * b) / gcd(a, b)\r\n}\r\n\r\n/**\r\n * Computes the factorial of a non-negative integer.\r\n *\r\n * @example factorial(5) // 120\r\n * @example factorial(0) // 1\r\n *\r\n * @param n - Non-negative integer.\r\n * @returns The factorial.\r\n * @throws {RangeError} If n is negative or not an integer.\r\n */\r\nexport function factorial(n: number): number {\r\n if (!Number.isInteger(n)) {\r\n throw new RangeError('Argument must be an integer')\r\n }\r\n if (n < 0) {\r\n throw new RangeError('Factorial is not defined for negative numbers')\r\n }\r\n let result = 1\r\n for (let i = 2; i <= n; i++) {\r\n result *= i\r\n }\r\n return result\r\n}\r\n\r\n/**\r\n * Tests whether a number is prime (optimized trial division).\r\n *\r\n * @example isPrime(7) // true\r\n * @example isPrime(10) // false\r\n *\r\n * @param n - Positive integer.\r\n * @returns Whether the number is prime.\r\n * @throws {RangeError} If n is not an integer or is less than 2.\r\n */\r\nexport function isPrime(n: number): boolean {\r\n if (!Number.isInteger(n)) {\r\n throw new RangeError('Argument must be an integer')\r\n }\r\n if (n < 2) return false\r\n if (n === 2 || n === 3) return true\r\n if (n % 2 === 0 || n % 3 === 0) return false\r\n const limit = Math.sqrt(n)\r\n for (let i = 5; i <= limit; i += 6) {\r\n if (n % i === 0 || n % (i + 2) === 0) return false\r\n }\r\n return true\r\n}\r\n\r\n// ─── Angle Conversion ───────────────────────────────────\r\n\r\n/**\r\n * Converts degrees to radians.\r\n *\r\n * @example toRadians(180) // ~3.14159\r\n *\r\n * @param degrees - Angle in degrees.\r\n * @returns Angle in radians.\r\n */\r\nexport function toRadians(degrees: number): number {\r\n return (degrees * Math.PI) / 180\r\n}\r\n\r\n/**\r\n * Converts radians to degrees.\r\n *\r\n * @example toDegrees(Math.PI) // 180\r\n *\r\n * @param radians - Angle in radians.\r\n * @returns Angle in degrees.\r\n */\r\nexport function toDegrees(radians: number): number {\r\n return (radians * 180) / Math.PI\r\n}\r\n\r\n// ─── Interpolation & Mapping ────────────────────────────\r\n\r\n/**\r\n * Linearly interpolates between `a` and `b` by `t`.\r\n *\r\n * @example lerp(0, 100, 0.5) // 50\r\n *\r\n * @param a - Start value.\r\n * @param b - End value.\r\n * @param t - Interpolation factor (typically 0–1).\r\n * @returns The interpolated value.\r\n */\r\nexport function lerp(a: number, b: number, t: number): number {\r\n return a + (b - a) * t\r\n}\r\n\r\n/**\r\n * Calculates what percentage `value` is of `total`.\r\n *\r\n * @example percentageOf(25, 200) // 12.5\r\n *\r\n * @param value - The part value.\r\n * @param total - The total value.\r\n * @returns The percentage.\r\n * @throws {RangeError} If total is zero.\r\n */\r\nexport function percentageOf(value: number, total: number): number {\r\n if (total === 0) {\r\n throw new RangeError('Total must be non-zero')\r\n }\r\n return (value / total) * 100\r\n}\r\n\r\n/**\r\n * Maps a value from one range to another.\r\n *\r\n * @example mapRange(0.5, 0, 1, 0, 100) // 50\r\n *\r\n * @param value - The value to map.\r\n * @param inMin - Lower bound of the input range.\r\n * @param inMax - Upper bound of the input range.\r\n * @param outMin - Lower bound of the output range.\r\n * @param outMax - Upper bound of the output range.\r\n * @returns The mapped value.\r\n * @throws {RangeError} If the input range is zero.\r\n */\r\nexport function mapRange(value: number, inMin: number, inMax: number, outMin: number, outMax: number): number {\r\n if (inMin === inMax) {\r\n throw new RangeError('Input range must not be zero')\r\n }\r\n return ((value - inMin) / (inMax - inMin)) * (outMax - outMin) + outMin\r\n}\r\n\r\n// ─── Statistics ─────────────────────────────────────────\r\n\r\n/**\r\n * Computes the statistical mode(s) — the most frequently occurring value(s).\r\n *\r\n * @example mode([1, 2, 2, 3]) // [2]\r\n * @example mode([1, 1, 2, 2]) // [1, 2]\r\n *\r\n * @param values - Array of numbers.\r\n * @returns Array of mode value(s).\r\n * @throws {RangeError} If the array is empty.\r\n */\r\nexport function mode(values: number[]): number[] {\r\n if (values.length === 0) {\r\n throw new RangeError('Cannot compute mode of an empty array')\r\n }\r\n const freq = new Map<number, number>()\r\n let maxFreq = 0\r\n for (const v of values) {\r\n const count = (freq.get(v) ?? 0) + 1\r\n freq.set(v, count)\r\n if (count > maxFreq) maxFreq = count\r\n }\r\n const result: number[] = []\r\n for (const [v, count] of freq) {\r\n if (count === maxFreq) result.push(v)\r\n }\r\n return result\r\n}\r\n\r\n/**\r\n * Generates an array of numbers from `start` to `end` (inclusive),\r\n * incremented by `step`.\r\n *\r\n * @example range(1, 5) // [1, 2, 3, 4, 5]\r\n * @example range(0, 10, 2) // [0, 2, 4, 6, 8, 10]\r\n *\r\n * @param start - Start of the range.\r\n * @param end - End of the range (inclusive).\r\n * @param step - Increment (defaults to 1 or -1 based on direction).\r\n * @returns Array of numbers.\r\n * @throws {RangeError} If step is zero.\r\n */\r\nexport function range(start: number, end: number, step?: number): number[] {\r\n const dir = end >= start ? 1 : -1\r\n const s = step ?? dir\r\n if (s === 0) {\r\n throw new RangeError('Step must not be zero')\r\n }\r\n if ((end - start) * s < 0) {\r\n return []\r\n }\r\n const result: number[] = []\r\n let i = start\r\n if (s > 0) {\r\n while (i <= end) {\r\n result.push(i)\r\n i += s\r\n }\r\n } else {\r\n while (i >= end) {\r\n result.push(i)\r\n i += s\r\n }\r\n }\r\n return result\r\n}\r\n\r\n/**\r\n * Computes the weighted mean of values with corresponding weights.\r\n *\r\n * @example weightedAverage([10, 20], [1, 4]) // 18\r\n *\r\n * @param values - Array of values.\r\n * @param weights - Array of weights.\r\n * @returns The weighted average.\r\n * @throws {RangeError} If arrays are empty, differ in length, or sum of weights is zero.\r\n */\r\nexport function weightedAverage(values: number[], weights: number[]): number {\r\n if (values.length === 0 || weights.length === 0) {\r\n throw new RangeError('Arrays must not be empty')\r\n }\r\n if (values.length !== weights.length) {\r\n throw new RangeError('Values and weights must have the same length')\r\n }\r\n let weightedSum = 0\r\n let weightSum = 0\r\n for (let i = 0; i < values.length; i++) {\r\n weightedSum += values[i]! * weights[i]!\r\n weightSum += weights[i]!\r\n }\r\n if (weightSum === 0) {\r\n throw new RangeError('Sum of weights must be non-zero')\r\n }\r\n return weightedSum / weightSum\r\n}\r\n\r\n/**\r\n * Computes the geometric mean of an array of numbers.\r\n *\r\n * @example geometricMean([4, 9]) // 6\r\n *\r\n * @param values - Array of positive numbers.\r\n * @returns The geometric mean.\r\n * @throws {RangeError} If the array is empty or contains negative values.\r\n */\r\nexport function geometricMean(values: number[]): number {\r\n if (values.length === 0) {\r\n throw new RangeError('Cannot compute geometric mean of an empty array')\r\n }\r\n for (const v of values) {\r\n if (v < 0) {\r\n throw new RangeError('Values must be non-negative for geometric mean')\r\n }\r\n }\r\n const logSum = values.reduce((acc, v) => (v === 0 ? acc : acc + Math.log(v)), 0)\r\n if (logSum === -Infinity) return 0\r\n return Math.exp(logSum / values.length)\r\n}\r\n\r\n/**\r\n * Computes the number of combinations (n choose k) — selecting k items from n without order.\r\n *\r\n * @example combinations(5, 2) // 10\r\n *\r\n * @param n - Total items.\r\n * @param k - Chosen items.\r\n * @returns The number of combinations.\r\n * @throws {RangeError} If n < k, or either is negative / non-integer.\r\n */\r\nexport function combinations(n: number, k: number): number {\r\n if (!Number.isInteger(n) || !Number.isInteger(k)) {\r\n throw new RangeError('Arguments must be integers')\r\n }\r\n if (n < 0 || k < 0) {\r\n throw new RangeError('Arguments must be non-negative')\r\n }\r\n if (k > n) {\r\n throw new RangeError('k must not exceed n')\r\n }\r\n if (k === 0 || k === n) return 1\r\n const r = Math.min(k, n - k)\r\n let result = 1\r\n for (let i = 1; i <= r; i++) {\r\n result = (result * (n - r + i)) / i\r\n }\r\n return result\r\n}\r\n\r\n/**\r\n * Computes the number of permutations — selecting k items from n in order.\r\n *\r\n * @example permutations(5, 2) // 20\r\n *\r\n * @param n - Total items.\r\n * @param k - Chosen items.\r\n * @returns The number of permutations.\r\n * @throws {RangeError} If n < k, or either is negative / non-integer.\r\n */\r\nexport function permutations(n: number, k: number): number {\r\n if (!Number.isInteger(n) || !Number.isInteger(k)) {\r\n throw new RangeError('Arguments must be integers')\r\n }\r\n if (n < 0 || k < 0) {\r\n throw new RangeError('Arguments must be non-negative')\r\n }\r\n if (k > n) {\r\n throw new RangeError('k must not exceed n')\r\n }\r\n let result = 1\r\n for (let i = n; i > n - k; i--) {\r\n result *= i\r\n }\r\n return result\r\n}\r\n","/**\n * Error thrown when a date value is invalid.\n */\nexport class InvalidDateError extends Error {\n constructor(input: unknown) {\n super(`Invalid date: ${String(input)}`)\n this.name = 'InvalidDateError'\n }\n}\n\nexport interface DateDiff {\n years: number\n months: number\n days: number\n hours: number\n minutes: number\n seconds: number\n}\n\nconst MONTH_NAMES_SHORT = [\n 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',\n 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec',\n] as const\n\nconst MONTH_NAMES_FULL = [\n 'January', 'February', 'March', 'April', 'May', 'June',\n 'July', 'August', 'September', 'October', 'November', 'December',\n] as const\n\nconst MONTH_MAP: Record<string, number> = {\n jan: 0, january: 0,\n feb: 1, february: 1,\n mar: 2, march: 2,\n apr: 3, april: 3,\n may: 4,\n jun: 5, june: 5,\n jul: 6, july: 6,\n aug: 7, august: 7,\n sep: 8, september: 8,\n oct: 9, october: 9,\n nov: 10, november: 10,\n dec: 11, december: 11,\n}\n\n/**\n * Formats a Date to a string using the given format pattern.\n *\n * Supported tokens:\n * - `YYYY` — 4-digit year\n * - `YY` — 2-digit year\n * - `MMMM` — full month name\n * - `MMM` — abbreviated month name\n * - `MM` — 2-digit month (01–12)\n * - `DD` — 2-digit day (01–31)\n * - `HH` — 2-digit hours (00–23)\n * - `mm` — 2-digit minutes\n * - `ss` — 2-digit seconds\n * - `SSS` — milliseconds\n *\n * @param date - The date to format.\n * @param format - The format string (default `'YYYY-MM-DD'`).\n * @returns The formatted date string.\n */\nexport function formatDate(date: Date, format: string = 'YYYY-MM-DD'): string {\n const year = date.getFullYear()\n const month = date.getMonth()\n const day = date.getDate()\n const hours = date.getHours()\n const minutes = date.getMinutes()\n const seconds = date.getSeconds()\n const ms = date.getMilliseconds()\n\n const pad = (n: number, len: number = 2): string => String(n).padStart(len, '0')\n\n return format\n .replace(/YYYY/g, String(year))\n .replace(/YY/g, String(year).slice(-2))\n .replace(/MMMM/g, MONTH_NAMES_FULL[month]!)\n .replace(/MMM/g, MONTH_NAMES_SHORT[month]!)\n .replace(/MM/g, pad(month + 1))\n .replace(/DD/g, pad(day))\n .replace(/HH/g, pad(hours))\n .replace(/mm/g, pad(minutes))\n .replace(/ss/g, pad(seconds))\n .replace(/SSS/g, pad(ms, 3))\n}\n\n/**\n * Parses a date from a string, number (timestamp in ms), or Date object.\n *\n * Supported string formats:\n * - ISO (`YYYY-MM-DD`, `YYYY-MM-DDTHH:mm:ss`)\n * - `DD/MM/YYYY` or `DD-MM-YYYY`\n * - `DD MMM YYYY` or `DD MMMM YYYY`\n * - Unix timestamp (milliseconds)\n *\n * @param input - The value to parse.\n * @returns A valid Date object.\n * @throws {InvalidDateError} If the input cannot be parsed.\n */\nexport function parseDate(input: string | number | Date): Date {\n if (input instanceof Date) {\n if (isNaN(input.getTime())) throw new InvalidDateError(input)\n return new Date(input.getTime())\n }\n\n if (typeof input === 'number') {\n const d = new Date(input)\n if (isNaN(d.getTime())) throw new InvalidDateError(input)\n return d\n }\n\n const trimmed = input.trim()\n\n // ISO format: YYYY-MM-DD or YYYY-MM-DDTHH:mm:ss\n const isoMatch = trimmed.match(/^(\\d{4})-(\\d{2})-(\\d{2})(?:T(\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d+))?)?(?:Z|[+-]\\d{2}:?\\d{2})?$/)\n if (isoMatch) {\n const d = new Date(\n parseInt(isoMatch[1]!, 10),\n parseInt(isoMatch[2]!, 10) - 1,\n parseInt(isoMatch[3]!, 10),\n isoMatch[4] ? parseInt(isoMatch[4]!, 10) : 0,\n isoMatch[5] ? parseInt(isoMatch[5]!, 10) : 0,\n isoMatch[6] ? parseInt(isoMatch[6]!, 10) : 0,\n isoMatch[7] ? parseInt(isoMatch[7]!.padEnd(3, '0'), 10) : 0\n )\n if (!isNaN(d.getTime())) return d\n }\n\n // DD/MM/YYYY or DD-MM-YYYY\n const dmyMatch = trimmed.match(/^(\\d{1,2})[\\/-](\\d{1,2})[\\/-](\\d{4})$/)\n if (dmyMatch) {\n const year = parseInt(dmyMatch[3]!, 10)\n const month = parseInt(dmyMatch[2]!, 10) - 1\n const day = parseInt(dmyMatch[1]!, 10)\n const d = new Date(year, month, day)\n // Validate that the date didn't overflow (e.g. Feb 29 in non-leap year)\n if (!isNaN(d.getTime()) && d.getMonth() === month && d.getDate() === day) return d\n }\n\n // DD MMM YYYY or DD MMMM YYYY\n const textMatch = trimmed.match(/^(\\d{1,2})\\s+([a-zA-Z]+)\\s+(\\d{4})$/)\n if (textMatch) {\n const monthIndex = MONTH_MAP[textMatch[2]!.toLowerCase()]\n if (monthIndex !== undefined) {\n const year = parseInt(textMatch[3]!, 10)\n const day = parseInt(textMatch[1]!, 10)\n const d = new Date(year, monthIndex, day)\n if (!isNaN(d.getTime()) && d.getMonth() === monthIndex && d.getDate() === day) return d\n }\n }\n\n // Unix timestamp (milliseconds) as string\n const numMatch = trimmed.match(/^-?\\d+$/)\n if (numMatch) {\n const d = new Date(parseInt(numMatch[0], 10))\n if (!isNaN(d.getTime())) return d\n }\n\n // Fallback: let Date.parse try\n const fallback = new Date(trimmed)\n if (!isNaN(fallback.getTime())) return fallback\n\n throw new InvalidDateError(input)\n}\n\nfunction isValidDate(d: Date): boolean {\n return d instanceof Date && !isNaN(d.getTime())\n}\n\nconst MS_IN_SECOND = 1000\nconst MS_IN_MINUTE = 60 * MS_IN_SECOND\nconst MS_IN_HOUR = 60 * MS_IN_MINUTE\nconst MS_IN_DAY = 24 * MS_IN_HOUR\n\n/**\n * Computes the difference between two dates.\n *\n * @param date1 - Start date.\n * @param date2 - End date.\n * @returns An object with years, months, days, hours, minutes, seconds.\n * @throws {InvalidDateError} If either date is invalid.\n */\nexport function dateDiff(date1: Date, date2: Date): DateDiff {\n if (!isValidDate(date1) || !isValidDate(date2)) {\n throw new InvalidDateError('Invalid date provided to dateDiff')\n }\n\n let years = date2.getFullYear() - date1.getFullYear()\n let months = date2.getMonth() - date1.getMonth()\n let days = date2.getDate() - date1.getDate()\n\n if (days < 0) {\n months -= 1\n const prevMonth = new Date(date2.getFullYear(), date2.getMonth(), 0)\n days += prevMonth.getDate()\n }\n\n if (months < 0) {\n years -= 1\n months += 12\n }\n\n const msDiff = Math.abs(date2.getTime() - date1.getTime())\n const totalSeconds = Math.floor(msDiff / MS_IN_SECOND)\n const hours = Math.floor((msDiff % MS_IN_DAY) / MS_IN_HOUR)\n const minutes = Math.floor((msDiff % MS_IN_HOUR) / MS_IN_MINUTE)\n const seconds = totalSeconds % 60\n\n return { years, months, days, hours, minutes, seconds }\n}\n\n/**\n * Adds days to a date.\n *\n * @param date - The original date.\n * @param days - Number of days to add (negative to subtract).\n * @returns A new Date.\n * @throws {InvalidDateError} If the input date is invalid.\n */\nexport function addDays(date: Date, days: number): Date {\n if (!isValidDate(date)) throw new InvalidDateError(date)\n const result = new Date(date.getTime())\n result.setDate(result.getDate() + days)\n return result\n}\n\n/**\n * Adds months to a date. Handles month-end overflow (e.g., Jan 31 + 1 month\n * becomes Feb 28).\n *\n * @param date - The original date.\n * @param months - Number of months to add (negative to subtract).\n * @returns A new Date.\n * @throws {InvalidDateError} If the input date is invalid.\n */\nexport function addMonths(date: Date, months: number): Date {\n if (!isValidDate(date)) throw new InvalidDateError(date)\n const result = new Date(date.getTime())\n const targetMonth = result.getMonth() + months\n result.setMonth(targetMonth)\n\n if (result.getMonth() !== ((targetMonth % 12) + 12) % 12) {\n result.setDate(0)\n }\n\n return result\n}\n\n/**\n * Adds years to a date. Handles leap-year overflow (e.g., Feb 29 + 1 year\n * becomes Feb 28).\n *\n * @param date - The original date.\n * @param years - Number of years to add (negative to subtract).\n * @returns A new Date.\n * @throws {InvalidDateError} If the input date is invalid.\n */\nexport function addYears(date: Date, years: number): Date {\n if (!isValidDate(date)) throw new InvalidDateError(date)\n const result = new Date(date.getTime())\n const targetYear = result.getFullYear() + years\n result.setFullYear(targetYear)\n\n if (result.getFullYear() !== targetYear) {\n result.setDate(0)\n }\n\n return result\n}\n\n/**\n * Returns the start of the day (00:00:00.000) for the given date.\n *\n * @param date - The date.\n * @returns A new Date set to midnight.\n * @throws {InvalidDateError} If the input date is invalid.\n */\nexport function startOfDay(date: Date): Date {\n if (!isValidDate(date)) throw new InvalidDateError(date)\n return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0, 0)\n}\n\n/**\n * Returns the end of the day (23:59:59.999) for the given date.\n *\n * @param date - The date.\n * @returns A new Date set to the last millisecond of the day.\n * @throws {InvalidDateError} If the input date is invalid.\n */\nexport function endOfDay(date: Date): Date {\n if (!isValidDate(date)) throw new InvalidDateError(date)\n return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59, 999)\n}\n\n/**\n * Returns the first moment of the month for the given date.\n *\n * @param date - The date.\n * @returns A new Date set to the start of the month.\n * @throws {InvalidDateError} If the input date is invalid.\n */\nexport function startOfMonth(date: Date): Date {\n if (!isValidDate(date)) throw new InvalidDateError(date)\n return new Date(date.getFullYear(), date.getMonth(), 1, 0, 0, 0, 0)\n}\n\n/**\n * Returns the last moment of the month for the given date.\n *\n * @param date - The date.\n * @returns A new Date set to the end of the month.\n * @throws {InvalidDateError} If the input date is invalid.\n */\nexport function endOfMonth(date: Date): Date {\n if (!isValidDate(date)) throw new InvalidDateError(date)\n return new Date(date.getFullYear(), date.getMonth() + 1, 0, 23, 59, 59, 999)\n}\n\n/**\n * Returns the first moment of the year for the given date.\n *\n * @param date - The date.\n * @returns A new Date set to Jan 1 00:00:00.000.\n * @throws {InvalidDateError} If the input date is invalid.\n */\nexport function startOfYear(date: Date): Date {\n if (!isValidDate(date)) throw new InvalidDateError(date)\n return new Date(date.getFullYear(), 0, 1, 0, 0, 0, 0)\n}\n\n/**\n * Returns the last moment of the year for the given date.\n *\n * @param date - The date.\n * @returns A new Date set to Dec 31 23:59:59.999.\n * @throws {InvalidDateError} If the input date is invalid.\n */\nexport function endOfYear(date: Date): Date {\n if (!isValidDate(date)) throw new InvalidDateError(date)\n return new Date(date.getFullYear(), 12, 0, 23, 59, 59, 999)\n}\n\n/**\n * Checks if the date falls on a weekend (Saturday or Sunday).\n *\n * @param date - The date to check.\n * @returns Whether the date is a weekend.\n * @throws {InvalidDateError} If the input date is invalid.\n */\nexport function isWeekend(date: Date): boolean {\n if (!isValidDate(date)) throw new InvalidDateError(date)\n const day = date.getDay()\n return day === 0 || day === 6\n}\n\n/**\n * Checks if a year is a leap year.\n *\n * @param year - The year to check.\n * @returns Whether the year is a leap year.\n */\nexport function isLeapYear(year: number): boolean {\n return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0\n}\n\n/**\n * Checks if `date1` is before `date2`.\n *\n * @param date1 - First date.\n * @param date2 - Second date.\n * @returns Whether `date1` is before `date2`.\n * @throws {InvalidDateError} If either date is invalid.\n */\nexport function isBefore(date1: Date, date2: Date): boolean {\n if (!isValidDate(date1) || !isValidDate(date2)) {\n throw new InvalidDateError('Invalid date provided to isBefore')\n }\n return date1.getTime() < date2.getTime()\n}\n\n/**\n * Checks if `date1` is after `date2`.\n *\n * @param date1 - First date.\n * @param date2 - Second date.\n * @returns Whether `date1` is after `date2`.\n * @throws {InvalidDateError} If either date is invalid.\n */\nexport function isAfter(date1: Date, date2: Date): boolean {\n if (!isValidDate(date1) || !isValidDate(date2)) {\n throw new InvalidDateError('Invalid date provided to isAfter')\n }\n return date1.getTime() > date2.getTime()\n}\n\n/**\n * Checks if a date is within the inclusive range [start, end].\n *\n * @param date - The date to check.\n * @param start - Start of the range.\n * @param end - End of the range.\n * @returns Whether the date is between start and end.\n * @throws {InvalidDateError} If any date is invalid.\n */\nexport function isBetween(date: Date, start: Date, end: Date): boolean {\n if (!isValidDate(date) || !isValidDate(start) || !isValidDate(end)) {\n throw new InvalidDateError('Invalid date provided to isBetween')\n }\n return date.getTime() >= start.getTime() && date.getTime() <= end.getTime()\n}\n\n/**\n * Checks if a date is a business day (Monday to Friday).\n *\n * @param date - The date to check.\n * @returns Whether the date is a business day.\n */\nexport function isBusinessDay(date: Date): boolean {\n return isValidDate(date) && !isWeekend(date)\n}\n\n/**\n * Adds business days (skipping weekends) to a date.\n *\n * @param date - The starting date.\n * @param days - Number of business days to add (negative to subtract).\n * @returns A new Date.\n * @throws {InvalidDateError} If the input date is invalid.\n */\nexport function addBusinessDays(date: Date, days: number): Date {\n if (!isValidDate(date)) throw new InvalidDateError(date)\n\n const result = new Date(date.getTime())\n let remaining = Math.abs(days)\n const step = days >= 0 ? 1 : -1\n\n while (remaining > 0) {\n result.setDate(result.getDate() + step)\n const day = result.getDay()\n if (day !== 0 && day !== 6) {\n remaining--\n }\n }\n\n return result\n}\n\n/**\n * Calculates age in years from a birth date.\n *\n * @param birthDate - The date of birth.\n * @returns The age in years.\n * @throws {InvalidDateError} If the birth date is invalid.\n */\nexport function calculateAge(birthDate: Date): number {\n if (!isValidDate(birthDate)) throw new InvalidDateError(birthDate)\n\n const today = new Date()\n let age = today.getFullYear() - birthDate.getFullYear()\n const monthDiff = today.getMonth() - birthDate.getMonth()\n\n if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {\n age--\n }\n\n return age\n}\n\n// ─── Time Ago & Time Remaining ───────────────────────────────────────────────\n\ninterface LocaleLabels {\n years: { single: string; plural: string }\n months: { single: string; plural: string }\n weeks: { single: string; plural: string }\n days: { single: string; plural: string }\n hours: { single: string; plural: string }\n minutes: { single: string; plural: string }\n seconds: { single: string; plural: string }\n}\n\nconst LOCALE_LABELS: Record<string, LocaleLabels> = {\n id: {\n years: { single: 'tahun', plural: 'tahun' },\n months: { single: 'bulan', plural: 'bulan' },\n weeks: { single: 'minggu', plural: 'minggu' },\n days: { single: 'hari', plural: 'hari' },\n hours: { single: 'jam', plural: 'jam' },\n minutes: { single: 'menit', plural: 'menit' },\n seconds: { single: 'detik', plural: 'detik' },\n },\n en: {\n years: { single: 'year', plural: 'years' },\n months: { single: 'month', plural: 'months' },\n weeks: { single: 'week', plural: 'weeks' },\n days: { single: 'day', plural: 'days' },\n hours: { single: 'hour', plural: 'hours' },\n minutes: { single: 'minute', plural: 'minutes' },\n seconds: { single: 'second', plural: 'seconds' },\n },\n}\n\nfunction getSuffix(diffMs: number, kind: 'ago' | 'remaining', locale: string): string {\n if (diffMs < 0) {\n return locale === 'en' ? 'ago' : 'yang lalu'\n }\n if (kind === 'remaining') {\n return locale === 'en' ? 'remaining' : 'lagi'\n }\n return locale === 'en' ? 'ago' : 'yang lalu'\n}\n\nfunction formatRelativeTime(absDiffMs: number, suffix: string, locale: string): string {\n const labels = LOCALE_LABELS[locale] ?? LOCALE_LABELS.id!\n\n const seconds = Math.floor(absDiffMs / 1000)\n const minutes = Math.floor(seconds / 60)\n const hours = Math.floor(minutes / 60)\n const days = Math.floor(hours / 24)\n const weeks = Math.floor(days / 7)\n const months = Math.floor(days / 30.4375)\n const years = Math.floor(days / 365.25)\n\n let count: number\n let unit: keyof LocaleLabels\n\n if (years >= 1) { count = years; unit = 'years' }\n else if (months >= 1) { count = months; unit = 'months' }\n else if (weeks >= 1) { count = weeks; unit = 'weeks' }\n else if (days >= 1) { count = days; unit = 'days' }\n else if (hours >= 1) { count = hours; unit = 'hours' }\n else if (minutes >= 1) { count = minutes; unit = 'minutes' }\n else { count = Math.max(1, seconds); unit = 'seconds' }\n\n const label = count === 1 ? labels[unit].single : labels[unit].plural\n return `${count} ${label} ${suffix}`\n}\n\n/**\n * Returns a human-readable relative time string (e.g. \"5 menit yang lalu\").\n *\n * @param date - The past date.\n * @param options - Options with locale ('id' by default, 'en' supported).\n * @returns A relative time string.\n */\nexport function timeAgo(date: Date, options?: { locale?: string }): string {\n const diff = Date.now() - date.getTime()\n const locale = options?.locale ?? 'id'\n const suffix = getSuffix(diff, 'ago', locale)\n return formatRelativeTime(Math.abs(diff), suffix, locale)\n}\n\n/**\n * Shows the time remaining until a future date.\n *\n * @param target - The target future date.\n * @param options - Options with locale ('id' by default, 'en' supported).\n * @returns A relative time string.\n */\nexport function timeRemaining(target: Date, options?: { locale?: string }): string {\n const diff = target.getTime() - Date.now()\n const locale = options?.locale ?? 'id'\n const suffix = getSuffix(diff, 'remaining', locale)\n return formatRelativeTime(Math.abs(diff), suffix, locale)\n}\n\n// ─── Duration ────────────────────────────────────────────────────────────────\n\n/**\n * Represents a duration split into calendar and time components.\n */\nexport interface Duration {\n years: number\n months: number\n days: number\n hours: number\n minutes: number\n seconds: number\n}\n\n/**\n * Formats a Duration object into a human-readable string.\n *\n * @example\n * formatDuration({ hours: 2, minutes: 30, seconds: 15 }) // \"2 jam 30 menit 15 detik\"\n * formatDuration({ hours: 2, minutes: 30 }, { locale: 'en' }) // \"2 hours 30 minutes\"\n *\n * @param duration - The duration to format.\n * @param options - Options with locale ('id' by default, 'en' supported).\n * @returns A formatted duration string.\n */\nexport function formatDuration(duration: Duration, options?: { locale?: string }): string {\n const locale = options?.locale ?? 'id'\n const labels = LOCALE_LABELS[locale] ?? LOCALE_LABELS.id!\n\n const parts: string[] = []\n const entries: [keyof Duration, number][] = [\n ['years', duration.years],\n ['months', duration.months],\n ['days', duration.days],\n ['hours', duration.hours],\n ['minutes', duration.minutes],\n ['seconds', duration.seconds],\n ]\n\n for (const [key, value] of entries) {\n if (value > 0) {\n const label = value === 1 ? labels[key].single : labels[key].plural\n parts.push(`${value} ${label}`)\n }\n }\n\n if (parts.length === 0) {\n const label = labels.seconds.plural\n return `0 ${label}`\n }\n\n return parts.join(' ')\n}\n\n// ─── Timezone Helpers ────────────────────────────────────────────────────────\n\n/** UTC+7 — Western Indonesia Time (WIB). */\nexport const TIMEZONE_WIB = 7\n\n/** UTC+8 — Central Indonesia Time (WITA). */\nexport const TIMEZONE_WITA = 8\n\n/** UTC+9 — Eastern Indonesia Time (WIT). */\nexport const TIMEZONE_WIT = 9\n\n/**\n * Converts a date to a specific timezone offset by returning a new Date whose\n * local-time getters (getHours, getMinutes etc.) reflect the target timezone.\n *\n * @param date - The source date.\n * @param offsetHours - The timezone offset in hours (e.g. 7 for WIB).\n * @returns A new Date adjusted to the target timezone.\n * @throws {InvalidDateError} If the input date is invalid.\n */\nexport function toTimezone(date: Date, offsetHours: number): Date {\n if (!isValidDate(date)) throw new InvalidDateError(date)\n const utcMs = date.getTime() + date.getTimezoneOffset() * 60000\n return new Date(utcMs + offsetHours * 3600000)\n}\n\n/**\n * Formats a date in a specific timezone using `formatDate` tokens.\n *\n * @param date - The source date.\n * @param format - The format string (see `formatDate` for supported tokens).\n * @param offsetHours - The timezone offset in hours.\n * @returns The formatted date string.\n */\nexport function formatInTimezone(date: Date, format: string, offsetHours: number): string {\n return formatDate(toTimezone(date, offsetHours), format)\n}\n\n// ─── Comparison Helpers ──────────────────────────────────────────────────────\n\n/**\n * Checks if a date is today.\n *\n * @param date - The date to check.\n * @returns Whether the date is today.\n * @throws {InvalidDateError} If the input date is invalid.\n *\n * @example\n * isToday(new Date()) // true\n */\nexport function isToday(date: Date): boolean {\n if (!isValidDate(date)) throw new InvalidDateError(date)\n const now = new Date()\n return (\n date.getFullYear() === now.getFullYear() &&\n date.getMonth() === now.getMonth() &&\n date.getDate() === now.getDate()\n )\n}\n\n/**\n * Checks if a date is yesterday.\n *\n * @param date - The date to check.\n * @returns Whether the date is yesterday.\n * @throws {InvalidDateError} If the input date is invalid.\n *\n * @example\n * isYesterday(new Date(Date.now() - 86400000)) // true\n */\nexport function isYesterday(date: Date): boolean {\n if (!isValidDate(date)) throw new InvalidDateError(date)\n const yesterday = new Date()\n yesterday.setDate(yesterday.getDate() - 1)\n return (\n date.getFullYear() === yesterday.getFullYear() &&\n date.getMonth() === yesterday.getMonth() &&\n date.getDate() === yesterday.getDate()\n )\n}\n\n/**\n * Checks if a date is tomorrow.\n *\n * @param date - The date to check.\n * @returns Whether the date is tomorrow.\n * @throws {InvalidDateError} If the input date is invalid.\n *\n * @example\n * isTomorrow(new Date(Date.now() + 86400000)) // true\n */\nexport function isTomorrow(date: Date): boolean {\n if (!isValidDate(date)) throw new InvalidDateError(date)\n const tomorrow = new Date()\n tomorrow.setDate(tomorrow.getDate() + 1)\n return (\n date.getFullYear() === tomorrow.getFullYear() &&\n date.getMonth() === tomorrow.getMonth() &&\n date.getDate() === tomorrow.getDate()\n )\n}\n\n/**\n * Checks if a date is in the past (before now).\n *\n * @param date - The date to check.\n * @returns Whether the date is in the past.\n * @throws {InvalidDateError} If the input date is invalid.\n *\n * @example\n * isPast(new Date('2020-01-01')) // true\n */\nexport function isPast(date: Date): boolean {\n if (!isValidDate(date)) throw new InvalidDateError(date)\n return date.getTime() < Date.now()\n}\n\n/**\n * Checks if a date is in the future (after now).\n *\n * @param date - The date to check.\n * @returns Whether the date is in the future.\n * @throws {InvalidDateError} If the input date is invalid.\n *\n * @example\n * isFuture(new Date('2099-01-01')) // true\n */\nexport function isFuture(date: Date): boolean {\n if (!isValidDate(date)) throw new InvalidDateError(date)\n return date.getTime() > Date.now()\n}\n\n/**\n * Checks if two dates fall on the same calendar day.\n *\n * @param date1 - First date.\n * @param date2 - Second date.\n * @returns Whether the dates are the same day.\n * @throws {InvalidDateError} If either date is invalid.\n *\n * @example\n * isSameDay(new Date('2024-01-01'), new Date('2024-01-01')) // true\n */\nexport function isSameDay(date1: Date, date2: Date): boolean {\n if (!isValidDate(date1) || !isValidDate(date2)) {\n throw new InvalidDateError('Invalid date provided to isSameDay')\n }\n return (\n date1.getFullYear() === date2.getFullYear() &&\n date1.getMonth() === date2.getMonth() &&\n date1.getDate() === date2.getDate()\n )\n}\n\n/**\n * Returns the number of days in the month of the given date.\n *\n * @param date - The date.\n * @returns Number of days in the month (28–31).\n * @throws {InvalidDateError} If the input date is invalid.\n *\n * @example\n * daysInMonth(new Date('2024-02-01')) // 29 (leap year)\n */\nexport function daysInMonth(date: Date): number {\n if (!isValidDate(date)) throw new InvalidDateError(date)\n return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate()\n}\n\n/**\n * Returns the day of the year (1–366).\n *\n * @param date - The date.\n * @returns Day of the year (1-indexed).\n * @throws {InvalidDateError} If the input date is invalid.\n *\n * @example\n * dayOfYear(new Date('2024-01-01')) // 1\n */\nexport function dayOfYear(date: Date): number {\n if (!isValidDate(date)) throw new InvalidDateError(date)\n const start = new Date(date.getFullYear(), 0, 0)\n return Math.floor((date.getTime() - start.getTime()) / MS_IN_DAY)\n}\n\n/**\n * Returns the ISO week number (1–53).\n *\n * The algorithm uses the Thursday of the same week as the reference\n * to determine which year the week belongs to, per ISO 8601.\n *\n * @param date - The date.\n * @returns The ISO week number.\n * @throws {InvalidDateError} If the input date is invalid.\n *\n * @example\n * weekOfYear(new Date('2024-01-01')) // 1\n */\nexport function weekOfYear(date: Date): number {\n if (!isValidDate(date)) throw new InvalidDateError(date)\n const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()))\n const dayNum = d.getUTCDay() || 7\n d.setUTCDate(d.getUTCDate() + 4 - dayNum)\n const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1))\n const weekNum = Math.ceil((((d.getTime() - yearStart.getTime()) / 86400000) + 1) / 7)\n return weekNum\n}\n\n/**\n * Returns the quarter of the year (1–4).\n *\n * @param date - The date.\n * @returns The quarter (1 for Jan–Mar, 2 for Apr–Jun, etc.).\n * @throws {InvalidDateError} If the input date is invalid.\n *\n * @example\n * quarter(new Date('2024-04-01')) // 2\n */\nexport function quarter(date: Date): number {\n if (!isValidDate(date)) throw new InvalidDateError(date)\n return Math.floor(date.getMonth() / 3) + 1\n}\n\n/**\n * Returns the latest (maximum) date from an array of dates.\n *\n * @param dates - Array of Date objects.\n * @returns The latest date.\n * @throws {Error} If the array is empty.\n * @throws {InvalidDateError} If any date is invalid.\n *\n * @example\n * maxDate([new Date('2024-01-01'), new Date('2025-01-01')]) // 2025-01-01\n */\nexport function maxDate(dates: Date[]): Date {\n if (dates.length === 0) throw new Error('maxDate requires at least one date')\n const ms = Math.max(...dates.map(d => {\n if (!isValidDate(d)) throw new InvalidDateError(d)\n return d.getTime()\n }))\n return new Date(ms)\n}\n\n/**\n * Returns the earliest (minimum) date from an array of dates.\n *\n * @param dates - Array of Date objects.\n * @returns The earliest date.\n * @throws {Error} If the array is empty.\n * @throws {InvalidDateError} If any date is invalid.\n *\n * @example\n * minDate([new Date('2024-01-01'), new Date('2025-01-01')]) // 2024-01-01\n */\nexport function minDate(dates: Date[]): Date {\n if (dates.length === 0) throw new Error('minDate requires at least one date')\n const ms = Math.min(...dates.map(d => {\n if (!isValidDate(d)) throw new InvalidDateError(d)\n return d.getTime()\n }))\n return new Date(ms)\n}\n\n// ─── Weekday Helpers ─────────────────────────────────────────────────────────\n\nfunction getNextWeekday(date: Date, targetDay: number): Date {\n if (!isValidDate(date)) throw new InvalidDateError(date)\n const result = new Date(date)\n const currentDay = result.getDay()\n let diff = targetDay - currentDay\n if (diff <= 0) diff += 7\n result.setDate(result.getDate() + diff)\n return result\n}\n\nfunction getLastWeekday(date: Date, targetDay: number): Date {\n if (!isValidDate(date)) throw new InvalidDateError(date)\n const result = new Date(date)\n const currentDay = result.getDay()\n let diff = currentDay - targetDay\n if (diff <= 0) diff += 7\n result.setDate(result.getDate() - diff)\n return result\n}\n\n/**\n * Returns the next Monday from the given date.\n *\n * @param date - Reference date.\n * @returns The next Monday.\n * @throws {InvalidDateError} If the input date is invalid.\n *\n * @example\n * nextMonday(new Date('2024-01-01')) // 2024-01-08 (Monday)\n */\nexport function nextMonday(date: Date): Date { return getNextWeekday(date, 1) }\n\n/**\n * Returns the next Tuesday from the given date.\n *\n * @param date - Reference date.\n * @returns The next Tuesday.\n * @throws {InvalidDateError} If the input date is invalid.\n *\n * @example\n * nextTuesday(new Date('2024-01-01')) // 2024-01-02 (Tuesday)\n */\nexport function nextTuesday(date: Date): Date { return getNextWeekday(date, 2) }\n\n/**\n * Returns the next Wednesday from the given date.\n *\n * @param date - Reference date.\n * @returns The next Wednesday.\n * @throws {InvalidDateError} If the input date is invalid.\n */\nexport function nextWednesday(date: Date): Date { return getNextWeekday(date, 3) }\n\n/**\n * Returns the next Thursday from the given date.\n *\n * @param date - Reference date.\n * @returns The next Thursday.\n * @throws {InvalidDateError} If the input date is invalid.\n */\nexport function nextThursday(date: Date): Date { return getNextWeekday(date, 4) }\n\n/**\n * Returns the next Friday from the given date.\n *\n * @param date - Reference date.\n * @returns The next Friday.\n * @throws {InvalidDateError} If the input date is invalid.\n */\nexport function nextFriday(date: Date): Date { return getNextWeekday(date, 5) }\n\n/**\n * Returns the next Saturday from the given date.\n *\n * @param date - Reference date.\n * @returns The next Saturday.\n * @throws {InvalidDateError} If the input date is invalid.\n */\nexport function nextSaturday(date: Date): Date { return getNextWeekday(date, 6) }\n\n/**\n * Returns the next Sunday from the given date.\n *\n * @param date - Reference date.\n * @returns The next Sunday.\n * @throws {InvalidDateError} If the input date is invalid.\n */\nexport function nextSunday(date: Date): Date { return getNextWeekday(date, 0) }\n\n/**\n * Returns the last (previous) Monday from the given date.\n *\n * @param date - Reference date.\n * @returns The last Monday.\n * @throws {InvalidDateError} If the input date is invalid.\n *\n * @example\n * lastMonday(new Date('2024-01-03')) // 2024-01-01 (Monday)\n */\nexport function lastMonday(date: Date): Date { return getLastWeekday(date, 1) }\n\n/**\n * Returns the last (previous) Tuesday from the given date.\n *\n * @param date - Reference date.\n * @returns The last Tuesday.\n * @throws {InvalidDateError} If the input date is invalid.\n */\nexport function lastTuesday(date: Date): Date { return getLastWeekday(date, 2) }\n\n/**\n * Returns the last (previous) Wednesday from the given date.\n *\n * @param date - Reference date.\n * @returns The last Wednesday.\n * @throws {InvalidDateError} If the input date is invalid.\n */\nexport function lastWednesday(date: Date): Date { return getLastWeekday(date, 3) }\n\n/**\n * Returns the last (previous) Thursday from the given date.\n *\n * @param date - Reference date.\n * @returns The last Thursday.\n * @throws {InvalidDateError} If the input date is invalid.\n */\nexport function lastThursday(date: Date): Date { return getLastWeekday(date, 4) }\n\n/**\n * Returns the last (previous) Friday from the given date.\n *\n * @param date - Reference date.\n * @returns The last Friday.\n * @throws {InvalidDateError} If the input date is invalid.\n *\n * @example\n * lastFriday(new Date('2024-01-03')) // 2023-12-29 (Friday)\n */\nexport function lastFriday(date: Date): Date { return getLastWeekday(date, 5) }\n\n/**\n * Returns the last (previous) Saturday from the given date.\n *\n * @param date - Reference date.\n * @returns The last Saturday.\n * @throws {InvalidDateError} If the input date is invalid.\n */\nexport function lastSaturday(date: Date): Date { return getLastWeekday(date, 6) }\n\n/**\n * Returns the last (previous) Sunday from the given date.\n *\n * @param date - Reference date.\n * @returns The last Sunday.\n * @throws {InvalidDateError} If the input date is invalid.\n */\nexport function lastSunday(date: Date): Date { return getLastWeekday(date, 0) }\n\n// ─── Duration Parsing ────────────────────────────────────────────────────────\n\n/**\n * Parses a human-readable duration string into milliseconds.\n *\n * Supported units:\n * - `w` — weeks\n * - `d` — days\n * - `h` — hours\n * - `m` — minutes\n * - `s` — seconds\n *\n * @param input - Duration string (e.g. `\"1h30m\"`, `\"2d\"`, `\"1w2d6h\"`).\n * @returns Total milliseconds.\n *\n * @example\n * parseDuration('1h30m') // 5400000\n * parseDuration('2d') // 172800000\n * parseDuration('1w') // 604800000\n */\nexport function parseDuration(input: string): number {\n const regex = /(\\d+)\\s*([wdhms])/g\n let ms = 0\n let match: RegExpExecArray | null\n while ((match = regex.exec(input)) !== null) {\n const val = parseInt(match[1]!, 10)\n switch (match[2]) {\n case 'w': ms += val * 7 * MS_IN_DAY; break\n case 'd': ms += val * MS_IN_DAY; break\n case 'h': ms += val * MS_IN_HOUR; break\n case 'm': ms += val * MS_IN_MINUTE; break\n case 's': ms += val * MS_IN_SECOND; break\n }\n }\n return ms\n}\n\n// ─── Indonesian Holidays ─────────────────────────────────────────────────────\n\ninterface HolidayEntry {\n name: string\n month: number\n day: number\n}\n\nconst INDONESIAN_FIXED_HOLIDAYS: HolidayEntry[] = [\n { name: 'New Year', month: 0, day: 1 },\n { name: 'Labor Day', month: 4, day: 1 },\n { name: 'Pancasila Day', month: 5, day: 1 },\n { name: 'Independence Day', month: 7, day: 17 },\n { name: 'National Awakening Day', month: 4, day: 20 },\n { name: 'National Heroes Day', month: 10, day: 10 },\n { name: 'Christmas', month: 11, day: 25 },\n]\n\nfunction computeEaster(year: number): Date {\n const a = year % 19\n const b = Math.floor(year / 100)\n const c = year % 100\n const d = Math.floor(b / 4)\n const e = b % 4\n const f = Math.floor((b + 8) / 25)\n const g = Math.floor((b - f + 1) / 3)\n const h = (19 * a + b - d - g + 15) % 30\n const i = Math.floor(c / 4)\n const k = c % 4\n const l = (32 + 2 * e + 2 * i - h - k) % 7\n const m = Math.floor((a + 11 * h + 22 * l) / 451)\n const month = Math.floor((h + l - 7 * m + 114) / 31)\n const day = ((h + l - 7 * m + 114) % 31) + 1\n return new Date(year, month - 1, day)\n}\n\nconst CHINESE_NEW_YEAR: Record<number, { month: number; day: number }> = {\n 2024: { month: 1, day: 10 },\n 2025: { month: 0, day: 29 },\n 2026: { month: 1, day: 17 },\n 2027: { month: 1, day: 6 },\n 2028: { month: 0, day: 26 },\n 2029: { month: 1, day: 13 },\n 2030: { month: 2, day: 3 },\n}\n\nconst NYEPI: Record<number, { month: number; day: number }> = {\n 2024: { month: 2, day: 11 },\n 2025: { month: 2, day: 29 },\n 2026: { month: 2, day: 19 },\n 2027: { month: 2, day: 7 },\n 2028: { month: 2, day: 26 },\n 2029: { month: 2, day: 15 },\n 2030: { month: 2, day: 5 },\n}\n\nconst VESAK: Record<number, { month: number; day: number }> = {\n 2024: { month: 4, day: 23 },\n 2025: { month: 4, day: 12 },\n 2026: { month: 4, day: 31 },\n 2027: { month: 4, day: 20 },\n 2028: { month: 4, day: 9 },\n 2029: { month: 4, day: 28 },\n 2030: { month: 4, day: 18 },\n}\n\nconst EID_AL_FITR: Record<number, Array<{ month: number; day: number }>> = {\n 2024: [{ month: 3, day: 10 }, { month: 3, day: 11 }],\n 2025: [{ month: 2, day: 31 }, { month: 3, day: 1 }],\n 2026: [{ month: 2, day: 21 }, { month: 2, day: 22 }],\n 2027: [{ month: 2, day: 10 }, { month: 2, day: 11 }],\n 2028: [{ month: 2, day: 28 }, { month: 2, day: 29 }],\n 2029: [{ month: 2, day: 17 }, { month: 2, day: 18 }],\n 2030: [{ month: 2, day: 7 }, { month: 2, day: 8 }],\n}\n\nconst EID_AL_ADHA: Record<number, { month: number; day: number }> = {\n 2024: { month: 5, day: 17 },\n 2025: { month: 5, day: 7 },\n 2026: { month: 4, day: 27 },\n 2027: { month: 4, day: 17 },\n 2028: { month: 5, day: 5 },\n 2029: { month: 4, day: 25 },\n 2030: { month: 4, day: 15 },\n}\n\nconst ISLAMIC_NEW_YEAR: Record<number, { month: number; day: number }> = {\n 2024: { month: 6, day: 7 },\n 2025: { month: 5, day: 27 },\n 2026: { month: 5, day: 16 },\n 2027: { month: 5, day: 6 },\n 2028: { month: 6, day: 24 },\n 2029: { month: 6, day: 13 },\n 2030: { month: 6, day: 3 },\n}\n\nconst PROPHETS_BIRTHDAY: Record<number, { month: number; day: number }> = {\n 2024: { month: 8, day: 16 },\n 2025: { month: 8, day: 5 },\n 2026: { month: 7, day: 26 },\n 2027: { month: 7, day: 16 },\n 2028: { month: 8, day: 3 },\n 2029: { month: 7, day: 23 },\n 2030: { month: 7, day: 13 },\n}\n\nconst ISRA_MIRAJ: Record<number, { month: number; day: number }> = {\n 2024: { month: 1, day: 8 },\n 2025: { month: 0, day: 28 },\n 2026: { month: 0, day: 17 },\n 2027: { month: 0, day: 6 },\n 2028: { month: 0, day: 26 },\n 2029: { month: 1, day: 14 },\n 2030: { month: 1, day: 3 },\n}\n\nfunction addHolidayEntry(\n entries: HolidayEntry[],\n name: string,\n month: number,\n day: number,\n): void {\n entries.push({ name, month, day })\n}\n\nfunction getIndonesianHolidaysForYear(year: number): HolidayEntry[] {\n const holidays: HolidayEntry[] = [...INDONESIAN_FIXED_HOLIDAYS]\n\n // Easter-based holidays (computed)\n const easter = computeEaster(year)\n addHolidayEntry(holidays, 'Good Friday', easter.getMonth(), easter.getDate() - 2)\n addHolidayEntry(holidays, 'Easter', easter.getMonth(), easter.getDate())\n\n // Ascension = Easter + 39 days\n const ascension = new Date(easter)\n ascension.setDate(ascension.getDate() + 39)\n addHolidayEntry(holidays, 'Ascension of Jesus Christ', ascension.getMonth(), ascension.getDate())\n\n // Lookup-based movable holidays\n const cny = CHINESE_NEW_YEAR[year]\n if (cny) addHolidayEntry(holidays, 'Chinese New Year', cny.month, cny.day)\n\n const nyepi = NYEPI[year]\n if (nyepi) addHolidayEntry(holidays, 'Nyepi (Day of Silence)', nyepi.month, nyepi.day)\n\n const vesak = VESAK[year]\n if (vesak) addHolidayEntry(holidays, 'Vesak (Buddha\\'s Birthday)', vesak.month, vesak.day)\n\n const eidDays = EID_AL_FITR[year]\n if (eidDays) {\n eidDays.forEach((entry, idx) => {\n addHolidayEntry(holidays, idx === 0 ? 'Eid al-Fitr' : 'Eid al-Fitr (Day 2)', entry.month, entry.day)\n })\n }\n\n const eidAdha = EID_AL_ADHA[year]\n if (eidAdha) addHolidayEntry(holidays, 'Eid al-Adha', eidAdha.month, eidAdha.day)\n\n const islNewYear = ISLAMIC_NEW_YEAR[year]\n if (islNewYear) addHolidayEntry(holidays, 'Islamic New Year', islNewYear.month, islNewYear.day)\n\n const prophetBday = PROPHETS_BIRTHDAY[year]\n if (prophetBday) addHolidayEntry(holidays, 'Prophet Muhammad\\'s Birthday', prophetBday.month, prophetBday.day)\n\n const isra = ISRA_MIRAJ[year]\n if (isra) addHolidayEntry(holidays, 'Isra\\' Mi\\'raj (Ascension of Prophet Muhammad)', isra.month, isra.day)\n\n return holidays\n}\n\n/**\n * Checks if a date is an Indonesian public holiday.\n *\n * Includes fixed-date holidays (New Year, Labor Day, Pancasila Day,\n * Independence Day, National Awakening Day, National Heroes Day, Christmas),\n * Easter-based holidays (Good Friday, Easter, Ascension), and lookup-based\n * movable holidays (Chinese New Year, Nyepi, Vesak, Eid al-Fitr,\n * Eid al-Adha, Islamic New Year, Prophet's Birthday, Isra' Mi'raj).\n *\n * Movable holidays (Chinese New Year, Nyepi, Vesak, Islamic holidays) are\n * precomputed for years 2024–2030. Dates outside this range may return\n * `false` for those holidays.\n *\n * @param date - The date to check.\n * @returns Whether the date is an Indonesian public holiday.\n * @throws {InvalidDateError} If the input date is invalid.\n *\n * @example\n * isHolidayIndonesia(new Date('2024-08-17')) // true (Independence Day)\n * isHolidayIndonesia(new Date('2024-12-25')) // true (Christmas)\n */\nexport function isHolidayIndonesia(date: Date): boolean {\n if (!isValidDate(date)) throw new InvalidDateError(date)\n\n const year = date.getFullYear()\n const holidays = getIndonesianHolidaysForYear(year)\n\n for (const h of holidays) {\n if (h.month === date.getMonth() && h.day === date.getDate()) {\n return true\n }\n }\n\n return false\n}\n\n/**\n * Returns the name(s) of Indonesian public holidays for a given date, or an\n * empty array if the date is not a holiday.\n *\n * @param date - The date to check.\n * @returns Array of holiday names.\n * @throws {InvalidDateError} If the input date is invalid.\n *\n * @example\n * getIndonesianHolidayNames(new Date('2024-08-17')) // ['Independence Day']\n */\nexport function getIndonesianHolidayNames(date: Date): string[] {\n if (!isValidDate(date)) throw new InvalidDateError(date)\n\n const year = date.getFullYear()\n const holidays = getIndonesianHolidaysForYear(year)\n const names: string[] = []\n\n for (const h of holidays) {\n if (h.month === date.getMonth() && h.day === date.getDate()) {\n names.push(h.name)\n }\n }\n\n return names\n}\n","/**\r\n * Simple hash function using the djb2 algorithm.\r\n * Fast, non-cryptographic — suitable for hashtables, not security.\r\n *\r\n * @param str - The string to hash.\r\n * @returns A 32-bit integer hash.\r\n */\r\nexport function hash(str: string): number {\r\n let h = 5381\r\n for (let i = 0; i < str.length; i++) {\r\n h = ((h << 5) + h + str.charCodeAt(i)) | 0\r\n }\r\n return h >>> 0\r\n}\r\n\r\n/**\r\n * Produces a deterministic hex hash from a string.\r\n * NOT actual MD5 — use for cache keys / deterministic IDs.\r\n *\r\n * @param str - The string to hash.\r\n * @returns A 32-character hex string.\r\n */\r\nexport function simpleHash(str: string): string {\r\n let h1 = 0x67452301\r\n let h2 = 0xefcdab89\r\n let h3 = 0x98badcfe\r\n let h4 = 0x10325476\r\n\r\n for (let i = 0; i < str.length; i++) {\r\n const c = str.charCodeAt(i)\r\n h1 = (h1 + c) | 0\r\n h2 = (h2 + (c << 3) + i) | 0\r\n h3 = (h3 ^ c) | 0\r\n h4 = (h4 + (c << 5) + (c << 1)) | 0\r\n }\r\n\r\n const toHex = (n: number): string => (n >>> 0).toString(16).padStart(8, '0')\r\n return toHex(h1) + toHex(h2) + toHex(h3) + toHex(h4)\r\n}\r\n\r\nfunction getRandomBytes(size: number): Uint8Array {\r\n if (typeof crypto !== 'undefined' && typeof crypto.getRandomValues === 'function') {\r\n const bytes = new Uint8Array(size)\r\n crypto.getRandomValues(bytes)\r\n return bytes\r\n }\r\n throw new Error('Crypto API unavailable. Cannot generate secure random bytes.')\r\n}\r\n\r\n/**\r\n * Generates random bytes as a hex string.\r\n *\r\n * @param size - Number of random bytes (default 16).\r\n * @returns A hex string of length `size * 2`.\r\n */\r\nexport function randomHex(size: number = 16): string {\r\n const bytes = getRandomBytes(size)\r\n let result = ''\r\n for (let i = 0; i < bytes.length; i++) {\r\n result += bytes[i]!.toString(16).padStart(2, '0')\r\n }\r\n return result\r\n}\r\n\r\nfunction utf8ToBytes(str: string): Uint8Array {\r\n if (typeof TextEncoder !== 'undefined') {\r\n return new TextEncoder().encode(str)\r\n }\r\n const bytes = new Uint8Array(str.length)\r\n for (let i = 0; i < str.length; i++) {\r\n bytes[i] = str.charCodeAt(i)\r\n }\r\n return bytes\r\n}\r\n\r\nfunction bytesToUtf8(bytes: Uint8Array): string {\r\n if (typeof TextDecoder !== 'undefined') {\r\n return new TextDecoder().decode(bytes)\r\n }\r\n let result = ''\r\n for (let i = 0; i < bytes.length; i++) {\r\n result += String.fromCharCode(bytes[i]!)\r\n }\r\n return result\r\n}\r\n\r\nfunction bytesToBase64(bytes: Uint8Array): string {\r\n let binary = ''\r\n for (let i = 0; i < bytes.length; i++) {\r\n binary += String.fromCharCode(bytes[i]!)\r\n }\r\n if (typeof btoa === 'function') {\r\n return btoa(binary)\r\n }\r\n return Buffer.from(binary, 'latin1').toString('base64')\r\n}\r\n\r\nfunction base64ToBytes(str: string): Uint8Array {\r\n let binary: string\r\n if (typeof atob === 'function') {\r\n binary = atob(str)\r\n } else {\r\n binary = Buffer.from(str, 'base64').toString('latin1')\r\n }\r\n const bytes = new Uint8Array(binary.length)\r\n for (let i = 0; i < binary.length; i++) {\r\n bytes[i] = binary.charCodeAt(i)\r\n }\r\n return bytes\r\n}\r\n\r\n/**\r\n * Encodes a string to base64. Works in both Node.js and browser.\r\n * Handles UTF-8 characters correctly.\r\n *\r\n * @param str - The string to encode.\r\n * @returns The base64-encoded string.\r\n */\r\nexport function base64Encode(str: string): string {\r\n const bytes = utf8ToBytes(str)\r\n return bytesToBase64(bytes)\r\n}\r\n\r\n/**\r\n * Decodes a base64-encoded string. Works in both Node.js and browser.\r\n *\r\n * @param str - The base64 string to decode.\r\n * @returns The decoded string.\r\n */\r\nexport function base64Decode(str: string): string {\r\n const bytes = base64ToBytes(str)\r\n return bytesToUtf8(bytes)\r\n}\r\n\r\n/**\r\n * Generates a cryptographically random token string.\r\n *\r\n * @param bytes - Number of random bytes (default 32 → 64-char hex).\r\n * @returns A hex string suitable for API keys, reset tokens, etc.\r\n */\r\nexport function generateToken(bytes: number = 32): string {\r\n return randomHex(bytes)\r\n}\r\n\r\n/**\r\n * Generates a numeric OTP of the given length.\r\n *\r\n * @param length - Number of digits (default 6).\r\n * @returns A numeric string of the specified length.\r\n */\r\nexport function generateOTP(length: number = 6): string {\r\n const bytes = getRandomBytes(length)\r\n let otp = ''\r\n for (let i = 0; i < length; i++) {\r\n otp += (bytes[i]! % 10).toString()\r\n }\r\n return otp\r\n}\r\n\r\n/**\r\n * Simple XOR cipher — symmetrical, for light obfuscation only.\r\n *\r\n * ⚠️ WARNING: This is NOT encryption. XOR cipher provides zero security\r\n * against any attacker. Do NOT use this for passwords, API keys, personal\r\n * data, or any sensitive information. It can be trivially reversed.\r\n * For real encryption, use native `crypto.subtle` (Web) or `node:crypto`.\r\n *\r\n * Suitable only for: basic data masking, simple anti-scraping, educational purposes.\r\n *\r\n * @param str - The input string (will be transformed).\r\n * @param key - The cipher key.\r\n * @returns The XOR-transformed string.\r\n */\r\nexport function xorCipher(str: string, key: string): string {\r\n let result = ''\r\n for (let i = 0; i < str.length; i++) {\r\n const code = str.charCodeAt(i) ^ key.charCodeAt(i % key.length)\r\n result += String.fromCharCode(code)\r\n }\r\n return result\r\n}\r\n\r\n/**\r\n * Computes a simple checksum (CRC-like) for file integrity checks.\r\n *\r\n * @param input - The input string.\r\n * @returns An 8-character hex checksum.\r\n */\r\nexport function checksum(input: string): string {\r\n let crc = 0xffffffff\r\n for (let i = 0; i < input.length; i++) {\r\n crc ^= input.charCodeAt(i)\r\n for (let j = 0; j < 8; j++) {\r\n if (crc & 1) {\r\n crc = (crc >>> 1) ^ 0xedb88320\r\n } else {\r\n crc = crc >>> 1\r\n }\r\n }\r\n }\r\n return ((crc ^ 0xffffffff) >>> 0).toString(16).padStart(8, '0')\r\n}\r\n\r\n/**\r\n * Constant-time string comparison to prevent timing attacks.\r\n *\r\n * @param a - First string.\r\n * @param b - Second string.\r\n * @returns Whether the strings are equal.\r\n */\r\nexport function constantTimeEqual(a: string, b: string): boolean {\r\n if (a.length !== b.length) return false\r\n let result = 0\r\n for (let i = 0; i < a.length; i++) {\r\n result |= a.charCodeAt(i) ^ b.charCodeAt(i)\r\n }\r\n return result === 0\r\n}\r\n","const SEP = '/'\r\n\r\n/**\r\n * Joins path segments with the proper separator.\r\n *\r\n * @param segments - Path segments to join.\r\n * @returns The joined path.\r\n */\r\nexport function join(...segments: string[]): string {\r\n const parts: string[] = []\r\n for (const seg of segments) {\r\n if (seg === '') continue\r\n const split = seg.split(/[\\\\/]/)\r\n for (const part of split) {\r\n if (part === '' || part === '.') continue\r\n if (part === '..') {\r\n if (parts.length > 0 && parts[parts.length - 1] !== '..') {\r\n parts.pop()\r\n } else {\r\n parts.push('..')\r\n }\r\n } else {\r\n parts.push(part)\r\n }\r\n }\r\n }\r\n if (parts.length === 0) return '.'\r\n const result = parts.join(SEP)\r\n if (segments.length > 0 && segments[0]!.startsWith('/')) {\r\n return SEP + result\r\n }\r\n return result\r\n}\r\n\r\n/**\r\n * Resolves path segments to an absolute path.\r\n *\r\n * @param segments - Path segments to resolve.\r\n * @returns The resolved absolute path.\r\n */\r\nexport function resolve(...segments: string[]): string {\r\n let resolved = ''\r\n let isAbs = false\r\n\r\n for (const seg of segments) {\r\n if (seg.startsWith('/')) {\r\n resolved = seg\r\n isAbs = true\r\n } else if (isAbs) {\r\n resolved = join(resolved, seg)\r\n } else {\r\n resolved = resolved ? join(resolved, seg) : seg\r\n }\r\n }\r\n\r\n if (!isAbs) {\r\n resolved = join(SEP, resolved)\r\n }\r\n\r\n return normalize(resolved)\r\n}\r\n\r\n/**\r\n * Returns the filename from a path.\r\n *\r\n * @param p - The path.\r\n * @param ext - Optional extension to strip.\r\n * @returns The filename.\r\n */\r\nexport function basename(p: string, ext?: string): string {\r\n const normalized = p.replace(/[\\\\/]+$/, '')\r\n const idx = normalized.lastIndexOf(SEP)\r\n let base = idx === -1 ? normalized : normalized.slice(idx + 1)\r\n if (ext && base.endsWith(ext)) {\r\n base = base.slice(0, -ext.length)\r\n }\r\n return base\r\n}\r\n\r\n/**\r\n * Returns the directory portion of a path.\r\n *\r\n * @param p - The path.\r\n * @returns The directory path.\r\n */\r\nexport function dirname(p: string): string {\r\n if (p === SEP) return SEP\r\n const normalized = p.replace(/[\\\\/]+$/, '')\r\n if (normalized === '') return '.'\r\n const idx = normalized.lastIndexOf(SEP)\r\n if (idx === -1) return '.'\r\n if (idx === 0) return SEP\r\n return normalized.slice(0, idx)\r\n}\r\n\r\n/**\r\n * Returns the file extension from a path.\r\n *\r\n * @param p - The path.\r\n * @returns The extension including the dot, or empty string.\r\n */\r\nexport function extname(p: string): string {\r\n const base = basename(p)\r\n const idx = base.lastIndexOf('.')\r\n if (idx === -1 || idx === 0) return ''\r\n return base.slice(idx)\r\n}\r\n\r\n/**\r\n * Normalizes a path, resolving '..' and '.' segments.\r\n *\r\n * @param p - The path to normalize.\r\n * @returns The normalized path.\r\n */\r\nexport function normalize(p: string): string {\r\n const parts = p.split(/[\\\\/]+/)\r\n const stack: string[] = []\r\n let isAbs = p.startsWith('/')\r\n\r\n for (const part of parts) {\r\n if (part === '' || part === '.') continue\r\n if (part === '..') {\r\n if (stack.length > 0 && stack[stack.length - 1] !== '..') {\r\n stack.pop()\r\n } else if (!isAbs) {\r\n stack.push('..')\r\n }\r\n } else {\r\n stack.push(part)\r\n }\r\n }\r\n\r\n const result = stack.join(SEP)\r\n if (isAbs) return SEP + result\r\n if (result === '') return '.'\r\n return result\r\n}\r\n\r\n/**\r\n * Checks if a path is absolute.\r\n *\r\n * @param p - The path to check.\r\n * @returns Whether the path is absolute.\r\n */\r\nexport function isAbsolute(p: string): boolean {\r\n return p.startsWith('/')\r\n}\r\n\r\n/**\r\n * Computes the relative path from `from` to `to`.\r\n *\r\n * @param from - The base path.\r\n * @param to - The target path.\r\n * @returns The relative path.\r\n */\r\nexport function relative(from: string, to: string): string {\r\n const fromParts = normalize(from).split(SEP)\r\n const toParts = normalize(to).split(SEP)\r\n\r\n let i = 0\r\n while (i < fromParts.length && i < toParts.length && fromParts[i] === toParts[i]) {\r\n i++\r\n }\r\n\r\n const up = fromParts.slice(i).map(() => '..')\r\n const down = toParts.slice(i)\r\n const result = [...up, ...down].join(SEP)\r\n\r\n return result || '.'\r\n}\r\n\r\nexport interface ParsedPath {\r\n root: string\r\n dir: string\r\n base: string\r\n name: string\r\n ext: string\r\n}\r\n\r\n/**\r\n * Parses a path into its components.\r\n *\r\n * @param p - The path to parse.\r\n * @returns An object with root, dir, base, name, and ext.\r\n */\r\nexport function parse(p: string): ParsedPath {\r\n const root = p.startsWith(SEP) ? SEP : ''\r\n const base = basename(p)\r\n const ext = extname(base)\r\n const name = ext ? base.slice(0, -ext.length) : base\r\n const dir = root ? dirname(p) : (dirname(p) === '.' ? '' : dirname(p))\r\n\r\n return { root, dir, base, name, ext }\r\n}\r\n\r\n/**\r\n * Formats a parsed path object back into a path string.\r\n *\r\n * @param parsed - The parsed path components.\r\n * @returns The formatted path string.\r\n */\r\nexport function format(parsed: Partial<ParsedPath>): string {\r\n const { root = '', dir = '', base = '', name = '', ext = '' } = parsed\r\n const baseName = base || name + ext\r\n if (dir) {\r\n return dir + SEP + baseName\r\n }\r\n return root + baseName\r\n}\r\n","/**\r\n * Groups an array of items by a key extracted from each item.\r\n *\r\n * @example groupBy([{ type: 'a' }, { type: 'b' }, { type: 'a' }], x => x.type)\r\n * // => { a: [{ type: 'a' }, { type: 'a' }], b: [{ type: 'b' }] }\r\n */\r\nexport function groupBy<T, K extends string | number | symbol>(items: T[], keyFn: (item: T) => K): Record<K, T[]> {\r\n const result = {} as Record<K, T[]>\r\n for (const item of items) {\r\n const key = keyFn(item)\r\n if (!result[key]) result[key] = []\r\n result[key]!.push(item)\r\n }\r\n return result\r\n}\r\n\r\n/**\r\n * Creates an object keyed by the result of keyFn for each item.\r\n *\r\n * @example keyBy([{ id: 1, name: 'a' }, { id: 2, name: 'b' }], x => x.id)\r\n * // => { 1: { id: 1, name: 'a' }, 2: { id: 2, name: 'b' } }\r\n */\r\nexport function keyBy<T, K extends string | number | symbol>(items: T[], keyFn: (item: T) => K): Record<K, T> {\r\n const result = {} as Record<K, T>\r\n for (const item of items) {\r\n const key = keyFn(item)\r\n result[key] = item\r\n }\r\n return result\r\n}\r\n\r\n/**\r\n * Returns a copy of the object with the specified keys omitted.\r\n */\r\nexport function omit<T extends Record<string, unknown>, K extends keyof T>(obj: T, keys: K[]): Omit<T, K> {\r\n const result = { ...obj } as T\r\n for (const key of keys) {\r\n delete result[key]\r\n }\r\n return result as Omit<T, K>\r\n}\r\n\r\n/**\r\n * Returns a copy of the object with only the specified keys.\r\n */\r\nexport function pick<T extends Record<string, unknown>, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> {\r\n const result = {} as Pick<T, K>\r\n for (const key of keys) {\r\n if (key in obj) {\r\n result[key] = obj[key]\r\n }\r\n }\r\n return result\r\n}\r\n\r\n/**\r\n * Extracts a property value from each item in an array.\r\n */\r\nexport function pluck<T, K extends keyof T>(items: T[], key: K): T[K][] {\r\n return items.map(item => item[key])\r\n}\r\n\r\n/**\r\n * Randomizes array order in-place using the Fisher-Yates algorithm.\r\n */\r\nexport function shuffle<T>(items: T[]): T[] {\r\n const result = [...items]\r\n for (let i = result.length - 1; i > 0; i--) {\r\n const j = Math.floor(Math.random() * (i + 1))\r\n const temp = result[i]!\r\n result[i] = result[j]!\r\n result[j] = temp\r\n }\r\n return result\r\n}\r\n\r\n/**\r\n * Returns a random element from the array, or undefined if empty.\r\n */\r\nexport function sample<T>(items: T[]): T | undefined {\r\n return items.length > 0 ? items[Math.floor(Math.random() * items.length)] : undefined\r\n}\r\n\r\n/**\r\n * Returns an array of `size` random elements (without duplicates).\r\n */\r\nexport function sampleSize<T>(items: T[], size: number): T[] {\r\n if (size <= 0 || items.length === 0) return []\r\n const pool = shuffle(items)\r\n return pool.slice(0, Math.min(size, items.length))\r\n}\r\n\r\n/**\r\n * Splits an array into chunks of the specified size.\r\n */\r\nexport function chunk<T>(items: T[], size: number): T[][] {\r\n if (size <= 0 || items.length === 0) return []\r\n const result: T[][] = []\r\n for (let i = 0; i < items.length; i += size) {\r\n result.push(items.slice(i, i + size))\r\n }\r\n return result\r\n}\r\n\r\n/**\r\n * Returns a sorted copy of the array using the provided criteria functions.\r\n * Earlier criteria take precedence.\r\n */\r\nfunction compareValues(a: unknown, b: unknown): number {\r\n if (a === b) return 0\r\n if (a == null) return -1\r\n if (b == null) return 1\r\n if (typeof a === 'string' && typeof b === 'string') return a < b ? -1 : 1\r\n if (typeof a === 'number' && typeof b === 'number') return a < b ? -1 : 1\r\n return String(a) < String(b) ? -1 : 1\r\n}\r\n\r\nexport function sortBy<T>(items: T[], ...criteria: Array<(item: T) => unknown>): T[] {\r\n return [...items].sort((a, b) => {\r\n for (const criterion of criteria) {\r\n const cmp = compareValues(criterion(a), criterion(b))\r\n if (cmp !== 0) return cmp\r\n }\r\n return 0\r\n })\r\n}\r\n\r\n/**\r\n * Returns a sorted copy of the array by a single key and direction.\r\n */\r\nexport function orderBy<T>(items: T[], key: (item: T) => unknown, direction: SortDirection = 'asc'): T[] {\r\n return [...items].sort((a, b) => {\r\n const cmp = compareValues(key(a), key(b))\r\n return direction === 'asc' ? cmp : -cmp\r\n })\r\n}\r\n\r\n/**\r\n * Returns unique elements based on the result of keyFn.\r\n */\r\nexport function uniqueBy<T>(items: T[], keyFn: (item: T) => unknown): T[] {\r\n const seen = new Set<unknown>()\r\n return items.filter(item => {\r\n const key = keyFn(item)\r\n if (seen.has(key)) return false\r\n seen.add(key)\r\n return true\r\n })\r\n}\r\n\r\n/**\r\n * Flattens an array of arrays one level.\r\n */\r\nexport function flatten<T>(items: T[][]): T[] {\r\n const result: T[] = []\r\n for (const sub of items) {\r\n for (const item of sub) {\r\n result.push(item)\r\n }\r\n }\r\n return result\r\n}\r\n\r\n/**\r\n * Returns an array with unique primitive values.\r\n */\r\nexport function uniq<T>(items: T[]): T[] {\r\n return [...new Set(items)]\r\n}\r\n\r\n/**\r\n * Returns the first element, or undefined if empty.\r\n */\r\nexport function first<T>(items: T[]): T | undefined {\r\n return items[0]\r\n}\r\n\r\n/**\r\n * Returns the last element, or undefined if empty.\r\n */\r\nexport function last<T>(items: T[]): T | undefined {\r\n return items[items.length - 1]\r\n}\r\n\r\n/**\r\n * Checks if a value is empty.\r\n * Works for arrays, objects, strings, Map, and Set.\r\n */\r\nexport function isEmpty(value: unknown): boolean {\r\n if (Array.isArray(value)) return value.length === 0\r\n if (typeof value === 'string') return value.length === 0\r\n if (value instanceof Map || value instanceof Set) return value.size === 0\r\n if (value !== null && typeof value === 'object') return Object.keys(value as Record<string, unknown>).length === 0\r\n return false\r\n}\r\n\r\nexport type SortDirection = 'asc' | 'desc'\r\n\r\nexport function topoSort<T extends { id: string; dependencies?: string[] }>(items: T[]): T[] {\r\n const adj = new Map<string, string[]>()\r\n const inDegree = new Map<string, number>()\r\n const itemMap = new Map<string, T>()\r\n\r\n for (const item of items) {\r\n itemMap.set(item.id, item)\r\n if (!adj.has(item.id)) adj.set(item.id, [])\r\n if (!inDegree.has(item.id)) inDegree.set(item.id, 0)\r\n }\r\n\r\n for (const item of items) {\r\n if (item.dependencies) {\r\n for (const depId of item.dependencies) {\r\n adj.get(depId)?.push(item.id)\r\n inDegree.set(item.id, (inDegree.get(item.id) ?? 0) + 1)\r\n }\r\n }\r\n }\r\n\r\n const queue: string[] = []\r\n for (const [id, degree] of inDegree) {\r\n if (degree === 0) queue.push(id)\r\n }\r\n\r\n const sorted: string[] = []\r\n while (queue.length > 0) {\r\n const id = queue.shift()!\r\n sorted.push(id)\r\n for (const neighbor of adj.get(id) ?? []) {\r\n const newDegree = (inDegree.get(neighbor) ?? 1) - 1\r\n inDegree.set(neighbor, newDegree)\r\n if (newDegree === 0) queue.push(neighbor)\r\n }\r\n }\r\n\r\n if (sorted.length !== items.length) {\r\n throw new Error('Circular dependency detected')\r\n }\r\n\r\n return sorted.map(id => itemMap.get(id)!)\r\n}\r\n\r\nexport function slidingWindows<T>(items: T[], size: number, step: number = 1): T[][] {\r\n if (size <= 0 || items.length === 0 || step <= 0) return []\r\n const result: T[][] = []\r\n for (let i = 0; i + size <= items.length; i += step) {\r\n result.push(items.slice(i, i + size))\r\n }\r\n return result\r\n}\r\n\r\nexport function tumblingWindows<T>(items: T[], size: number): T[][] {\r\n if (size <= 0 || items.length === 0) return []\r\n const result: T[][] = []\r\n for (let i = 0; i < items.length; i += size) {\r\n result.push(items.slice(i, i + size))\r\n }\r\n return result\r\n}\r\n\r\n/**\r\n * Gets a nested value from an object using a dot-separated path.\r\n *\r\n * @example deepGet({ a: { b: 2 } }, 'a.b') // 2\r\n * @example deepGet({ a: { b: 2 } }, 'a.c') // undefined\r\n */\r\nexport function deepGet<T = unknown>(obj: unknown, path: string, default_?: T): T | undefined {\r\n const keys = path.split('.')\r\n let current: unknown = obj\r\n for (const key of keys) {\r\n if (current === null || current === undefined) return default_\r\n if (typeof current !== 'object') return default_\r\n const curObj = current as Record<string, unknown>\r\n if (!(key in curObj)) return default_\r\n current = curObj[key]\r\n }\r\n return (current as T) ?? default_\r\n}\r\n\r\n/**\r\n * Sets a nested value in an object using a dot-separated path.\r\n * Creates intermediate objects/arrays as needed.\r\n *\r\n * @example deepSet({ a: { b: 2 } }, 'a.b', 3) // { a: { b: 3 } }\r\n * @example deepSet({}, 'a.b.c', 1) // { a: { b: { c: 1 } } }\r\n */\r\nexport function deepSet<T extends Record<string, unknown>>(obj: T, path: string, value: unknown): T {\r\n const keys = path.split('.')\r\n const PROTO_KEYS = new Set(['__proto__', 'constructor', 'prototype'])\r\n for (const key of keys) {\r\n if (PROTO_KEYS.has(key)) {\r\n return { ...obj } as T\r\n }\r\n }\r\n const result = { ...obj } as Record<string, unknown>\r\n let current = result\r\n for (let i = 0; i < keys.length - 1; i++) {\r\n const key = keys[i]!\r\n const next = current[key]\r\n if (next === null || next === undefined || typeof next !== 'object') {\r\n const isArray = /^\\d+$/.test(keys[i + 1]!)\r\n current[key] = isArray ? [] : {}\r\n }\r\n current = current[key] as Record<string, unknown>\r\n }\r\n current[keys[keys.length - 1]!] = value\r\n return result as T\r\n}\r\n\r\n/**\r\n * Splits an array into two groups: those that pass the predicate and those that don't.\r\n *\r\n * @example partition([1, 2, 3, 4, 5], n => n % 2 === 0)\r\n * // => [[2, 4], [1, 3, 5]]\r\n */\r\nexport function partition<T>(items: T[], predicate: (item: T) => boolean): [T[], T[]] {\r\n const pass: T[] = []\r\n const fail: T[] = []\r\n for (const item of items) {\r\n if (predicate(item)) pass.push(item)\r\n else fail.push(item)\r\n }\r\n return [pass, fail]\r\n}\r\n\r\n/**\r\n * Removes all falsy values from an array (false, null, 0, '', undefined, NaN).\r\n *\r\n * @example compact([0, 1, false, 2, '', 3, null, undefined, NaN])\r\n * // => [1, 2, 3]\r\n */\r\nexport function compact<T>(items: (T | false | null | 0 | '' | undefined)[]): T[] {\r\n return items.filter(Boolean) as T[]\r\n}\r\n\r\n/**\r\n * Returns elements in array A that are not in array B (uses SameValueZero).\r\n *\r\n * @example difference([1, 2, 3, 4], [2, 4])\r\n * // => [1, 3]\r\n */\r\nexport function difference<T>(a: T[], b: T[]): T[] {\r\n const setB = new Set(b)\r\n return a.filter(item => !setB.has(item))\r\n}\r\n\r\n/**\r\n * Returns elements present in all given arrays (uses SameValueZero).\r\n *\r\n * @example intersection([1, 2, 3], [2, 3, 4])\r\n * // => [2, 3]\r\n */\r\nexport function intersection<T>(a: T[], b: T[]): T[] {\r\n const setB = new Set(b)\r\n return a.filter(item => setB.has(item))\r\n}\r\n\r\n/**\r\n * Returns unique elements from all given arrays.\r\n *\r\n * @example union([1, 2], [2, 3], [3, 4])\r\n * // => [1, 2, 3, 4]\r\n */\r\nexport function union<T>(...arrays: T[][]): T[] {\r\n const set = new Set<T>()\r\n for (const arr of arrays) {\r\n for (const item of arr) {\r\n set.add(item)\r\n }\r\n }\r\n return [...set]\r\n}\r\n\r\n/**\r\n * Merges arrays element-wise into tuples, stopping at the shortest array.\r\n *\r\n * @example zip(['a', 'b', 'c'], [1, 2])\r\n * // => [['a', 1], ['b', 2]]\r\n */\r\nexport function zip<T, U>(a: T[], b: U[]): [T, U][]\r\nexport function zip<T, U, V>(a: T[], b: U[], c: V[]): [T, U, V][]\r\nexport function zip<T>(...arrays: T[][]): T[][] {\r\n if (arrays.length === 0) return []\r\n const minLen = Math.min(...arrays.map(a => a.length))\r\n const result: T[][] = []\r\n for (let i = 0; i < minLen; i++) {\r\n const tuple: T[] = []\r\n for (const arr of arrays) {\r\n tuple.push(arr[i]!)\r\n }\r\n result.push(tuple)\r\n }\r\n return result\r\n}\r\n\r\n/**\r\n * Inverse of zip: splits an array of tuples back into individual arrays.\r\n *\r\n * @example unzip([['a', 1], ['b', 2]])\r\n * // => [['a', 'b'], [1, 2]]\r\n */\r\nexport function unzip<T>(paired: T[][]): T[][] {\r\n if (paired.length === 0) return []\r\n const tupleLen = paired.reduce((max, t) => Math.max(max, t.length), 0)\r\n const result: T[][] = Array.from({ length: tupleLen }, () => [])\r\n for (const tuple of paired) {\r\n for (let i = 0; i < tupleLen; i++) {\r\n result[i]!.push(tuple[i] as T)\r\n }\r\n }\r\n return result\r\n}\r\n\r\n/**\r\n * Counts occurrences of each key produced by the key function.\r\n *\r\n * @example countBy([1, 2, 3, 4, 5], n => n % 2 === 0 ? 'even' : 'odd')\r\n * // => { odd: 3, even: 2 }\r\n */\r\nexport function countBy<T, K extends string | number | symbol>(items: T[], keyFn: (item: T) => K): Record<K, number> {\r\n const result = {} as Record<K, number>\r\n for (const item of items) {\r\n const key = keyFn(item)\r\n result[key] = (result[key] ?? 0) + 1\r\n }\r\n return result\r\n}\r\n\r\n/**\r\n * Returns the element with the maximum value by the key function.\r\n *\r\n * @example maxBy([{ name: 'a', score: 10 }, { name: 'b', score: 20 }], x => x.score)\r\n * // => { name: 'b', score: 20 }\r\n */\r\nexport function maxBy<T>(items: T[], keyFn: (item: T) => number): T | undefined {\r\n if (items.length === 0) return undefined\r\n let maxItem = items[0]!\r\n let maxVal = keyFn(maxItem)\r\n for (let i = 1; i < items.length; i++) {\r\n const val = keyFn(items[i]!)\r\n if (val > maxVal) {\r\n maxVal = val\r\n maxItem = items[i]!\r\n }\r\n }\r\n return maxItem\r\n}\r\n\r\n/**\r\n * Returns the element with the minimum value by the key function.\r\n *\r\n * @example minBy([{ name: 'a', score: 10 }, { name: 'b', score: 20 }], x => x.score)\r\n * // => { name: 'a', score: 10 }\r\n */\r\nexport function minBy<T>(items: T[], keyFn: (item: T) => number): T | undefined {\r\n if (items.length === 0) return undefined\r\n let minItem = items[0]!\r\n let minVal = keyFn(minItem)\r\n for (let i = 1; i < items.length; i++) {\r\n const val = keyFn(items[i]!)\r\n if (val < minVal) {\r\n minVal = val\r\n minItem = items[i]!\r\n }\r\n }\r\n return minItem\r\n}\r\n\r\n/**\r\n * Returns the sum of values produced by the key function.\r\n *\r\n * @example sumBy([{ n: 1 }, { n: 2 }, { n: 3 }], x => x.n)\r\n * // => 6\r\n */\r\nexport function sumBy<T>(items: T[], keyFn: (item: T) => number): number {\r\n let total = 0\r\n for (const item of items) {\r\n total += keyFn(item)\r\n }\r\n return total\r\n}\r\n\r\n/**\r\n * Returns the index of the first element satisfying the predicate, or -1.\r\n *\r\n * @example findIndex([1, 3, 5, 8, 10], n => n % 2 === 0)\r\n * // => 3\r\n */\r\nexport function findIndex<T>(items: T[], predicate: (item: T) => boolean, fromIndex: number = 0): number {\r\n for (let i = fromIndex; i < items.length; i++) {\r\n if (predicate(items[i]!)) return i\r\n }\r\n return -1\r\n}\r\n\r\n/**\r\n * Finds the last element satisfying the predicate.\r\n *\r\n * @example findLast([1, 2, 3, 4, 5], n => n % 2 === 0)\r\n * // => 4\r\n */\r\nexport function findLast<T>(items: T[], predicate: (item: T) => boolean): T | undefined {\r\n for (let i = items.length - 1; i >= 0; i--) {\r\n if (predicate(items[i]!)) return items[i]\r\n }\r\n return undefined\r\n}\r\n\r\n/**\r\n * Drops the first n elements from the array.\r\n *\r\n * @example drop([1, 2, 3, 4, 5], 2)\r\n * // => [3, 4, 5]\r\n */\r\nexport function drop<T>(items: T[], n: number = 1): T[] {\r\n return items.slice(Math.max(0, n))\r\n}\r\n\r\n/**\r\n * Drops the last n elements from the array.\r\n *\r\n * @example dropRight([1, 2, 3, 4, 5], 2)\r\n * // => [1, 2, 3]\r\n */\r\nexport function dropRight<T>(items: T[], n: number = 1): T[] {\r\n return items.slice(0, Math.max(0, items.length - n))\r\n}\r\n\r\n/**\r\n * Takes the first n elements from the array.\r\n *\r\n * @example take([1, 2, 3, 4, 5], 2)\r\n * // => [1, 2]\r\n */\r\nexport function take<T>(items: T[], n: number = 1): T[] {\r\n return items.slice(0, Math.max(0, n))\r\n}\r\n\r\n/**\r\n * Takes the last n elements from the array.\r\n *\r\n * @example takeRight([1, 2, 3, 4, 5], 2)\r\n * // => [4, 5]\r\n */\r\nexport function takeRight<T>(items: T[], n: number = 1): T[] {\r\n return items.slice(Math.max(0, items.length - n))\r\n}\r\n\r\n/**\r\n * Removes specified values from the array (uses SameValueZero).\r\n *\r\n * @example without([1, 2, 1, 3, 1, 4], 1, 3)\r\n * // => [2, 4]\r\n */\r\nexport function without<T>(items: T[], ...values: T[]): T[] {\r\n const exclude = new Set(values)\r\n return items.filter(item => !exclude.has(item))\r\n}\r\n\r\n/**\r\n * Gets the element at the given index. Supports negative indexing.\r\n *\r\n * @example nth([1, 2, 3], 1) // => 2\r\n * @example nth([1, 2, 3], -1) // => 3\r\n */\r\nexport function nth<T>(items: T[], index: number): T | undefined {\r\n return index < 0 ? items[items.length + index] : items[index]\r\n}\r\n","import { formatCurrency } from '../math/index.js'\r\n\r\nconst WORD_SPLIT_RE = /[A-Z]?[a-z]+|[A-Z]+(?=[A-Z][a-z]|\\d|\\b)|\\d+/g\r\n\r\nfunction splitWords(str: string): string[] {\r\n return str.match(WORD_SPLIT_RE) ?? []\r\n}\r\n\r\n/**\r\n * Capitalizes the first character and lowercases the rest.\r\n */\r\nexport function capitalize(str: string): string {\r\n if (str.length === 0) return str\r\n return str[0]!.toUpperCase() + str.slice(1).toLowerCase()\r\n}\r\n\r\n/**\r\n * Converts a string to camelCase.\r\n */\r\nexport function camelCase(str: string): string {\r\n const words = splitWords(str)\r\n if (words.length === 0) return ''\r\n const [firstWord, ...rest] = words\r\n return firstWord!.toLowerCase() + rest.map(w => w[0]!.toUpperCase() + w.slice(1).toLowerCase()).join('')\r\n}\r\n\r\n/**\r\n * Converts a string to kebab-case.\r\n */\r\nexport function kebabCase(str: string): string {\r\n return splitWords(str).map(w => w.toLowerCase()).join('-')\r\n}\r\n\r\n/**\r\n * Converts a string to snake_case.\r\n */\r\nexport function snakeCase(str: string): string {\r\n return splitWords(str).map(w => w.toLowerCase()).join('_')\r\n}\r\n\r\n/**\r\n * Converts a string to PascalCase.\r\n */\r\nexport function pascalCase(str: string): string {\r\n return splitWords(str).map(w => w[0]!.toUpperCase() + w.slice(1).toLowerCase()).join('')\r\n}\r\n\r\n/**\r\n * Truncates a string to the specified length, appending a suffix (default \"...\").\r\n */\r\nexport function truncate(str: string, maxLength: number, suffix = '...'): string {\r\n if (str.length <= maxLength) return str\r\n return str.slice(0, Math.max(0, maxLength - suffix.length)) + suffix\r\n}\r\n\r\n/**\r\n * Simple string interpolation using {{key}} syntax.\r\n *\r\n * @example template(\"Hello {{name}}\", { name: \"world\" }) // => \"Hello world\"\r\n */\r\nexport function template(str: string, data: Record<string, string | number>): string {\r\n return str.replace(/\\{\\{(\\w+)\\}\\}/g, (_, key: string) => {\r\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') return `{{${key}}}`\r\n const value = data[key]\r\n return value !== undefined ? String(value) : `{{${key}}}`\r\n })\r\n}\r\n\r\n/**\r\n * Generates a UUID v4 string.\r\n * Uses crypto.randomUUID when available, falls back to manual implementation.\r\n */\r\nexport function uuid(): string {\r\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\r\n return crypto.randomUUID()\r\n }\r\n const hex = '0123456789abcdef'\r\n const chars: string[] = []\r\n for (let i = 0; i < 36; i++) {\r\n if (i === 8 || i === 13 || i === 18 || i === 23) {\r\n chars.push('-')\r\n } else if (i === 14) {\r\n chars.push('4')\r\n } else if (i === 19) {\r\n chars.push(hex[Math.floor(Math.random() * 4) + 8]!)\r\n } else {\r\n chars.push(hex[Math.floor(Math.random() * 16)]!)\r\n }\r\n }\r\n return chars.join('')\r\n}\r\n\r\n/**\r\n * Generates a short random ID with configurable length and alphabet.\r\n *\r\n * @default size = 21, alphabet = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-\"\r\n */\r\nexport function nanoid(size = 21, alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-'): string {\r\n const len = alphabet.length\r\n const bytes = new Uint8Array(size)\r\n if (typeof crypto !== 'undefined' && typeof crypto.getRandomValues === 'function') {\r\n crypto.getRandomValues(bytes)\r\n } else {\r\n throw new Error('Crypto API unavailable. Cannot generate secure random ID.')\r\n }\r\n let result = ''\r\n for (let i = 0; i < size; i++) {\r\n result += alphabet[bytes[i]! % len]!\r\n }\r\n return result\r\n}\r\n\r\nconst HTML_ESCAPE_MAP: Record<string, string> = {\r\n '&': '&',\r\n '<': '<',\r\n '>': '>',\r\n '\"': '"',\r\n \"'\": ''',\r\n '`': '`',\r\n '/': '/',\r\n}\r\n\r\nconst HTML_UNESCAPE_MAP: Record<string, string> = {\r\n '&': '&',\r\n '<': '<',\r\n '>': '>',\r\n '"': '\"',\r\n ''': \"'\",\r\n ''': \"'\",\r\n '`': '`',\r\n '/': '/',\r\n}\r\n\r\n/**\r\n * Escapes HTML special characters (&, <, >, \", ').\r\n */\r\nexport function escapeHtml(str: string): string {\r\n return str.replace(/[&<>\"'`\\/]/g, ch => HTML_ESCAPE_MAP[ch] ?? ch)\r\n}\r\n\r\n/**\r\n * Unescapes common HTML entities.\r\n */\r\nexport function unescapeHtml(str: string): string {\r\n return str.replace(/&(?:amp|lt|gt|quot|#39|#x27|#96|#x2F);/g, entity => HTML_UNESCAPE_MAP[entity] ?? entity)\r\n}\r\n\r\n/**\r\n * Removes whitespace from both ends of a string.\r\n */\r\nexport function trim(str: string): string {\r\n return str.trim()\r\n}\r\n\r\n/**\r\n * Removes whitespace from the start of a string.\r\n */\r\nexport function trimStart(str: string): string {\r\n return str.trimStart()\r\n}\r\n\r\n/**\r\n * Removes whitespace from the end of a string.\r\n */\r\nexport function trimEnd(str: string): string {\r\n return str.trimEnd()\r\n}\r\n\r\n/**\r\n * Pads a string to the given length by adding characters to both sides.\r\n */\r\nexport function pad(str: string, length: number, char = ' '): string {\r\n const totalPadding = Math.max(0, length - str.length)\r\n const leftPad = Math.floor(totalPadding / 2)\r\n const rightPad = totalPadding - leftPad\r\n return char.repeat(leftPad) + str + char.repeat(rightPad)\r\n}\r\n\r\n/**\r\n * Pads the start of a string to the given length.\r\n */\r\nexport function padStart(str: string, length: number, char = ' '): string {\r\n return str.padStart(length, char)\r\n}\r\n\r\n/**\r\n * Pads the end of a string to the given length.\r\n */\r\nexport function padEnd(str: string, length: number, char = ' '): string {\r\n return str.padEnd(length, char)\r\n}\r\n\r\n/**\r\n * Reverses a string.\r\n */\r\nexport function reverse(str: string): string {\r\n return str.split('').reverse().join('')\r\n}\r\n\r\n/**\r\n * Splits a string into words.\r\n */\r\nexport function words(str: string): string[] {\r\n return splitWords(str)\r\n}\r\n\r\n/**\r\n * Converts a string to a URL-friendly slug.\r\n */\r\nexport function slugify(str: string): string {\r\n return str\r\n .toLowerCase()\r\n .replace(/[^\\w\\s-]/g, '')\r\n .replace(/[\\s_]+/g, '-')\r\n .replace(/-+/g, '-')\r\n .replace(/^-+/, '')\r\n .replace(/-+$/, '')\r\n}\r\n\r\n/**\r\n * Counts occurrences of a substring in a string.\r\n */\r\nexport function countOccurrences(str: string, substring: string): number {\r\n if (substring.length === 0 || str.length === 0) return 0\r\n let count = 0\r\n let pos = 0\r\n while ((pos = str.indexOf(substring, pos)) !== -1) {\r\n count++\r\n pos += substring.length\r\n }\r\n return count\r\n}\r\n\r\n/**\r\n * Computes the Levenshtein distance between two strings.\r\n * Uses iterative DP with O(min(m,n)) space.\r\n */\r\nexport function levenshtein(a: string, b: string): number {\r\n const an = a.length\r\n const bn = b.length\r\n if (an === 0) return bn\r\n if (bn === 0) return an\r\n if (an < bn) return levenshtein(b, a)\r\n\r\n let prev = new Uint32Array(bn + 1)\r\n let curr = new Uint32Array(bn + 1)\r\n for (let j = 0; j <= bn; j++) prev[j] = j\r\n\r\n for (let i = 1; i <= an; i++) {\r\n curr[0] = i\r\n for (let j = 1; j <= bn; j++) {\r\n const cost = a[i - 1] === b[j - 1] ? 0 : 1\r\n curr[j] = Math.min(\r\n prev[j]! + 1,\r\n curr[j - 1]! + 1,\r\n prev[j - 1]! + cost,\r\n )\r\n }\r\n ;[prev, curr] = [curr, prev]\r\n }\r\n return prev[bn]!\r\n}\r\n\r\n/**\r\n * Performs a simple fuzzy match: checks if all characters of query\r\n * appear in str in order (case-insensitive).\r\n */\r\nexport function fuzzyMatch(str: string, query: string): boolean {\r\n if (query.length === 0) return true\r\n if (str.length === 0) return false\r\n const sl = str.toLowerCase()\r\n const ql = query.toLowerCase()\r\n let si = 0\r\n for (let qi = 0; qi < ql.length; qi++) {\r\n si = sl.indexOf(ql[qi]!, si)\r\n if (si === -1) return false\r\n si++\r\n }\r\n return true\r\n}\r\n\r\n/**\r\n * Masks parts of a string, useful for data compliance (PDPA/GDPR).\r\n *\r\n * @example maskString('08123456789') // \"0812****789\"\r\n * @example maskString('hello@email.com') // \"h***@e***.com\"\r\n * @example maskString('1234567890', { start: 0, end: 4, char: '#' }) // \"####567890\"\r\n */\r\nexport function maskString(\r\n str: string,\r\n options?: {\r\n start?: number\r\n end?: number\r\n char?: string\r\n },\r\n): string {\r\n if (str.length === 0) return str\r\n const maskChar = options?.char ?? '*'\r\n const start = options?.start ?? Math.ceil(str.length * 0.25)\r\n const end = options?.end ?? Math.floor(str.length * 0.75)\r\n\r\n if (start >= end || start < 0) return str\r\n const clampedStart = Math.max(0, start)\r\n const clampedEnd = Math.min(str.length, end)\r\n return (\r\n str.slice(0, clampedStart) +\r\n maskChar.repeat(clampedEnd - clampedStart) +\r\n str.slice(clampedEnd)\r\n )\r\n}\r\n\r\n// ─── Indonesian Locale Utilities ────────────────────────\r\n\r\nconst SATUAN = ['', 'satu', 'dua', 'tiga', 'empat', 'lima', 'enam', 'tujuh', 'delapan', 'sembilan'] as const\r\nconst BELASAN = ['sepuluh', 'sebelas', 'dua belas', 'tiga belas', 'empat belas', 'lima belas', 'enam belas', 'tujuh belas', 'delapan belas', 'sembilan belas'] as const\r\nconst PULUHAN = ['', '', 'dua puluh', 'tiga puluh', 'empat puluh', 'lima puluh', 'enam puluh', 'tujuh puluh', 'delapan puluh', 'sembilan puluh'] as const\r\n\r\nfunction _terbilang(n: number): string {\r\n if (n < 0) return 'minus ' + _terbilang(-n)\r\n if (n === 0) return 'nol'\r\n if (n < 10) return SATUAN[n]!\r\n if (n < 20) return n === 10 ? 'sepuluh' : n === 11 ? 'sebelas' : BELASAN[n - 10]!\r\n if (n < 100) {\r\n const pul = Math.floor(n / 10)\r\n const sat = n % 10\r\n return PULUHAN[pul]! + (sat > 0 ? ' ' + SATUAN[sat]! : '')\r\n }\r\n if (n < 1000) {\r\n const ratus = Math.floor(n / 100)\r\n const sis = n % 100\r\n const ratusStr = ratus === 1 ? 'seratus' : SATUAN[ratus]! + ' ratus'\r\n return ratusStr + (sis > 0 ? ' ' + _terbilang(sis) : '')\r\n }\r\n if (n < 1_000_000) {\r\n const rib = Math.floor(n / 1000)\r\n const sis = n % 1000\r\n const ribStr = rib === 1 ? 'seribu' : _terbilang(rib) + ' ribu'\r\n return ribStr + (sis > 0 ? ' ' + _terbilang(sis) : '')\r\n }\r\n if (n < 1_000_000_000) {\r\n const jut = Math.floor(n / 1_000_000)\r\n const sis = n % 1_000_000\r\n return _terbilang(jut) + ' juta' + (sis > 0 ? ' ' + _terbilang(sis) : '')\r\n }\r\n if (n < 1_000_000_000_000) {\r\n const mil = Math.floor(n / 1_000_000_000)\r\n const sis = n % 1_000_000_000\r\n return _terbilang(mil) + ' miliar' + (sis > 0 ? ' ' + _terbilang(sis) : '')\r\n }\r\n const tril = Math.floor(n / 1_000_000_000_000)\r\n const sis = n % 1_000_000_000_000\r\n return _terbilang(tril) + ' triliun' + (sis > 0 ? ' ' + _terbilang(sis) : '')\r\n}\r\n\r\n/**\r\n * Converts a number to Indonesian words (terbilang).\r\n *\r\n * @example terbilang(1500000) // \"satu juta lima ratus ribu\"\r\n * @example terbilang(2024) // \"dua ribu dua puluh empat\"\r\n * @example terbilang(11) // \"sebelas\"\r\n * @example terbilang(100) // \"seratus\"\r\n */\r\nexport function terbilang(value: number): string {\r\n if (!Number.isFinite(value)) throw new RangeError('Input must be a finite number')\r\n if (value > Number.MAX_SAFE_INTEGER) throw new RangeError('Input terlalu besar')\r\n return _terbilang(Math.floor(Math.abs(value)))\r\n}\r\n\r\n/**\r\n * Formats a number as Indonesian Rupiah string.\r\n *\r\n * @example formatRupiah(1500000) // \"Rp1.500.000\"\r\n * @example formatRupiah(1500000, { notation: 'compact' }) // \"Rp1,5 jt\"\r\n */\r\nexport function formatRupiah(\r\n value: number,\r\n options?: { notation?: 'standard' | 'compact' },\r\n): string {\r\n return formatCurrency(value, { locale: 'id-ID', currency: 'IDR', notation: options?.notation })\r\n}\r\n\r\n/**\r\n * Formats a byte count into a human-readable string.\r\n *\r\n * @example formatBytes(1024) // \"1 KB\"\r\n * @example formatBytes(1536) // \"1.5 KB\"\r\n * @example formatBytes(1048576) // \"1 MB\"\r\n * @example formatBytes(0) // \"0 B\"\r\n */\r\nexport function formatBytes(bytes: number, options?: { decimals?: number }): string {\r\n if (bytes === 0) return '0 B'\r\n if (!Number.isFinite(bytes) || bytes < 0) return '0 B'\r\n const k = 1024\r\n const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB']\r\n const i = Math.floor(Math.log(bytes) / Math.log(k))\r\n const dm = options?.decimals ?? (i === 0 ? 0 : 1)\r\n const index = Math.min(i, sizes.length - 1)\r\n return parseFloat((bytes / Math.pow(k, index)).toFixed(dm)) + ' ' + sizes[index]\r\n}\r\n\r\n/**\r\n * Generates a random alphanumeric string of the specified length.\r\n *\r\n * @example randomString() // \"a3F8k2...\"\r\n * @example randomString(8) // \"X7j2K9mQ\"\r\n */\r\nexport function randomString(length: number = 16): string {\r\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'\r\n const bytes = new Uint8Array(length)\r\n if (typeof crypto !== 'undefined' && typeof crypto.getRandomValues === 'function') {\r\n crypto.getRandomValues(bytes)\r\n } else {\r\n throw new Error('Crypto API unavailable. Cannot generate secure random string.')\r\n }\r\n let result = ''\r\n for (let i = 0; i < length; i++) {\r\n result += chars[bytes[i]! % chars.length]\r\n }\r\n return result\r\n}\r\n\r\n/**\r\n * Returns a random boolean value.\r\n *\r\n * @example randomBoolean() // true or false\r\n */\r\nexport function randomBoolean(): boolean {\r\n return Math.random() >= 0.5\r\n}\r\n\r\n/**\r\n * Basic English pluralization helper. Adds 's' or 'es' based on simple rules.\r\n *\r\n * @example pluralize(1, 'apple') // \"apple\"\r\n * @example pluralize(3, 'apple') // \"apples\"\r\n * @example pluralize(0, 'box') // \"boxes\"\r\n * @example pluralize(1, 'box') // \"box\"\r\n */\r\nexport function pluralize(count: number, singular: string): string {\r\n if (count === 1) return singular\r\n const last = singular[singular.length - 1]\r\n const lastTwo = singular.slice(-2)\r\n if (last === 's' || last === 'x' || last === 'z' || lastTwo === 'ch' || lastTwo === 'sh') {\r\n return singular + 'es'\r\n }\r\n if (last === 'y' && singular.length > 2 && !'aeiou'.includes(singular[singular.length - 2]!)) {\r\n return singular.slice(0, -1) + 'ies'\r\n }\r\n return singular + 's'\r\n}\r\n\r\n/**\r\n * Removes all HTML tags from a string, including script and style content.\r\n *\r\n * @example stripHtml('<p>Hello <b>world</b></p>') // \"Hello world\"\r\n * @example stripHtml('<script>alert(\"x\")</script>hi') // \"hi\"\r\n */\r\nexport function stripHtml(str: string): string {\r\n return str.replace(/<[^>]*>/g, '')\r\n}\r\n\r\n/**\r\n * Truncates a string by word count, appending a suffix when truncated.\r\n *\r\n * @example truncateWords('hello world foo bar', 2) // \"hello world...\"\r\n * @example truncateWords('hello world foo bar', 2, '…') // \"hello world…\"\r\n */\r\nexport function truncateWords(str: string, count: number, suffix = '...'): string {\r\n const words = str.split(/\\s+/).filter(Boolean)\r\n if (words.length <= count) return str\r\n return words.slice(0, count).join(' ') + suffix\r\n}\r\n\r\n/**\r\n * Checks if a string is a palindrome, ignoring case, spaces, and punctuation.\r\n *\r\n * @example isPalindrome('A man, a plan, a canal: Panama') // true\r\n * @example isPalindrome('race a car') // false\r\n */\r\nexport function isPalindrome(str: string): boolean {\r\n const cleaned = str.replace(/[^a-zA-Z0-9]/g, '').toLowerCase()\r\n if (cleaned.length <= 1) return true\r\n let left = 0\r\n let right = cleaned.length - 1\r\n while (left < right) {\r\n if (cleaned[left] !== cleaned[right]) return false\r\n left++\r\n right--\r\n }\r\n return true\r\n}\r\n\r\n/**\r\n * Checks if two strings are anagrams, ignoring case and spaces.\r\n *\r\n * @example isAnagram('listen', 'silent') // true\r\n * @example isAnagram('hello', 'world') // false\r\n */\r\nexport function isAnagram(str1: string, str2: string): boolean {\r\n const clean = (s: string) => s.replace(/\\s/g, '').toLowerCase().split('').sort().join('')\r\n return clean(str1) === clean(str2)\r\n}\r\n\r\n/**\r\n * Computes the Dice coefficient similarity between two strings (0-1).\r\n *\r\n * @example similarity('hello', 'hallo') // 0.666...\r\n * @example similarity('abc', 'xyz') // 0\r\n */\r\nexport function similarity(a: string, b: string): number {\r\n if (a === b) return 1\r\n if (a.length < 2 || b.length < 2) return 0\r\n const bigrams = new Map<string, number>()\r\n for (let i = 0; i < a.length - 1; i++) {\r\n const bg = a.slice(i, i + 2)\r\n bigrams.set(bg, (bigrams.get(bg) ?? 0) + 1)\r\n }\r\n let intersection = 0\r\n for (let i = 0; i < b.length - 1; i++) {\r\n const bg = b.slice(i, i + 2)\r\n const count = bigrams.get(bg) ?? 0\r\n if (count > 0) {\r\n bigrams.set(bg, count - 1)\r\n intersection++\r\n }\r\n }\r\n return (2 * intersection) / (a.length + b.length - 2)\r\n}\r\n\r\n/**\r\n * Removes common leading whitespace from each line in a multi-line string.\r\n *\r\n * @example dedent(' hello\\n world') // \"hello\\nworld\"\r\n * @example dedent(' foo\\n bar') // \"foo\\n bar\"\r\n */\r\nexport function dedent(str: string): string {\r\n const lines = str.split('\\n')\r\n if (lines.length === 0) return str\r\n const indent = lines.reduce<number | null>((min, line) => {\r\n if (line.trim().length === 0) return min\r\n const leading = line.match(/^[ \\t]*/)?.[0]?.length ?? 0\r\n return min === null ? leading : Math.min(min, leading)\r\n }, null)\r\n if (indent === null || indent === 0) return str\r\n return lines.map(line => line.slice(indent)).join('\\n')\r\n}\r\n\r\n/**\r\n * Counts the number of words in a string, handling multiple spaces and punctuation.\r\n *\r\n * @example wordCount('hello world') // 2\r\n * @example wordCount(' hello world! ') // 2\r\n */\r\nexport function wordCount(str: string): number {\r\n const match = str.match(/[a-zA-Z0-9]+(?:['\\u2019][a-zA-Z]+)?/g)\r\n return match ? match.length : 0\r\n}\r\n\r\n/**\r\n * Swaps the case of each character in a string (upper to lower, lower to upper).\r\n *\r\n * @example swapCase('Hello World') // \"hELLO wORLD\"\r\n * @example swapCase('ABC123') // \"abc123\"\r\n */\r\nexport function swapCase(str: string): string {\r\n let result = ''\r\n for (let i = 0; i < str.length; i++) {\r\n const ch = str[i]!\r\n if (ch >= 'a' && ch <= 'z') {\r\n result += ch.toUpperCase()\r\n } else if (ch >= 'A' && ch <= 'Z') {\r\n result += ch.toLowerCase()\r\n } else {\r\n result += ch\r\n }\r\n }\r\n return result\r\n}\r\n\r\n/**\r\n * Converts a string to COBOL / SCREAMING_SNAKE_CASE.\r\n *\r\n * @example toCobolCase('helloWorld') // \"HELLO_WORLD\"\r\n * @example toCobolCase('getUserByID') // \"GET_USER_BY_ID\"\r\n */\r\nexport function toCobolCase(str: string): string {\r\n const words = splitWords(str)\r\n return words.map(w => w.toUpperCase()).join('_')\r\n}\r\n\r\n/**\r\n * Counts character frequency in a string.\r\n *\r\n * @example charCount('hello') // { h: 1, e: 1, l: 2, o: 1 }\r\n * @example charCount('aabb') // { a: 2, b: 2 }\r\n */\r\nexport function charCount(str: string): Record<string, number> {\r\n const result: Record<string, number> = {}\r\n for (let i = 0; i < str.length; i++) {\r\n const ch = str[i]!\r\n result[ch] = (result[ch] ?? 0) + 1\r\n }\r\n return result\r\n}\r\n","export interface QueueOptions {\n concurrency?: number\n}\n\n/**\n * Priority-based async task queue with concurrency control.\n *\n * @example\n * const queue = new Queue({ concurrency: 2 })\n * const result = await queue.add(() => fetch('/api/data'))\n */\nexport class Queue<T = unknown> {\n private _tasks: Array<{\n priority: number\n task: () => Promise<T>\n resolve: (value: T) => void\n reject: (reason: unknown) => void\n }> = []\n private _running = 0\n private _paused = false\n private _idleResolve: (() => void) | null = null\n private _maxConcurrency: number\n\n constructor(options?: QueueOptions) {\n this._maxConcurrency = options?.concurrency ?? 1\n if (this._maxConcurrency < 1) this._maxConcurrency = 1\n }\n\n get pending(): number {\n return this._tasks.length\n }\n\n get running(): number {\n return this._running\n }\n\n add<R>(task: () => Promise<R>, options?: { priority?: number }): Promise<R> {\n return new Promise<R>((resolve, reject) => {\n this._tasks.push({\n priority: options?.priority ?? 0,\n task: task as unknown as () => Promise<T>,\n resolve: resolve as (value: T) => void,\n reject,\n })\n this._tasks.sort((a, b) => b.priority - a.priority)\n this._process()\n })\n }\n\n pause(): void {\n this._paused = true\n }\n\n resume(): void {\n this._paused = false\n this._process()\n }\n\n clear(): void {\n const err = new Error('Queue cleared')\n for (const t of this._tasks) t.reject(err)\n this._tasks = []\n }\n\n onIdle(): Promise<void> {\n if (this._running === 0 && this._tasks.length === 0) return Promise.resolve()\n return new Promise<void>((resolve) => {\n this._idleResolve = resolve\n })\n }\n\n private _process(): void {\n if (this._paused) return\n while (this._running < this._maxConcurrency && this._tasks.length > 0) {\n const item = this._tasks.shift()!\n this._running++\n item\n .task()\n .then((result) => item.resolve(result))\n .catch((err) => item.reject(err))\n .finally(() => {\n this._running--\n this._process()\n if (this._running === 0 && this._tasks.length === 0 && this._idleResolve) {\n this._idleResolve()\n this._idleResolve = null\n }\n })\n }\n }\n}\n\nexport default Queue\n","/**\n * Semaphore for controlling concurrent access to a resource.\n *\n * @example\n * const sem = new Semaphore(2)\n * await sem.use(async () => {\n * // Only 2 callers at a time\n * await doSomething()\n * })\n */\nexport class Semaphore {\n private _available: number\n private _waiting: Array<() => void> = []\n\n constructor(concurrency: number) {\n if (concurrency < 1) throw new RangeError('Semaphore concurrency must be >= 1')\n this._available = concurrency\n }\n\n get available(): number {\n return this._available\n }\n\n acquire(): Promise<() => void> {\n if (this._available > 0) {\n this._available--\n return Promise.resolve(this._release.bind(this))\n }\n return new Promise<() => void>((resolve) => {\n this._waiting.push(() => {\n this._available--\n resolve(this._release.bind(this))\n })\n })\n }\n\n async use<T>(fn: () => Promise<T>): Promise<T> {\n const release = await this.acquire()\n try {\n return await fn()\n } finally {\n release()\n }\n }\n\n private _release(): void {\n this._available++\n if (this._waiting.length > 0) {\n const next = this._waiting.shift()\n if (next) next()\n }\n }\n}\n\nexport default Semaphore\n","/**\n * Options for memoizeAsync.\n */\nexport interface MemoizeAsyncOptions {\n /** Time-to-live in milliseconds (default: 60000) */\n ttl?: number\n /** Return stale value while fetching fresh data (default: false) */\n staleWhileRevalidate?: boolean\n /** Maximum number of cached entries (default: 100) */\n maxSize?: number\n /** Custom cache key resolver. Defaults to JSON.stringify of args. */\n resolver?: (...args: unknown[]) => string\n}\n\ninterface CacheEntry {\n value: unknown\n timestamp: number\n promise?: Promise<unknown>\n}\n\n/**\n * Memoizes an async function with TTL, stale-while-revalidate, and bounded cache.\n *\n * @example\n * const fetchData = memoizeAsync(async (id: string) => {\n * return await api.fetch(id)\n * }, { ttl: 5000, staleWhileRevalidate: true })\n *\n * const data = await fetchData('123') // cached for 5s\n * const data2 = await fetchData('123') // returns cached, refreshes in bg\n */\nexport function memoizeAsync<T extends (...args: unknown[]) => Promise<unknown>>(\n fn: T,\n options?: MemoizeAsyncOptions,\n): T & {\n cache: Map<string, CacheEntry>\n clear: () => void\n} {\n const {\n ttl = 60000,\n staleWhileRevalidate = false,\n maxSize = 100,\n resolver = (...args: unknown[]) => JSON.stringify(args),\n } = options ?? {}\n\n const cache = new Map<string, CacheEntry>()\n\n const memoized = (async (...args: unknown[]): Promise<unknown> => {\n const key = resolver(...args)\n const now = Date.now()\n const entry = cache.get(key)\n\n if (entry && now - entry.timestamp < ttl) {\n return entry.value\n }\n\n if (entry && staleWhileRevalidate && now - entry.timestamp >= ttl) {\n if (entry.promise) {\n return entry.value\n }\n entry.promise = fn(...args)\n .then((result) => {\n entry.value = result\n entry.timestamp = now\n entry.promise = undefined\n return result\n })\n .catch((err) => {\n entry.promise = undefined\n throw err\n })\n return entry.value\n }\n\n const result = await fn(...args)\n cache.set(key, { value: result, timestamp: now })\n\n if (cache.size > maxSize) {\n const firstKey = cache.keys().next().value\n if (firstKey !== undefined) cache.delete(firstKey)\n }\n\n return result\n }) as T & {\n cache: Map<string, CacheEntry>\n clear: () => void\n }\n\n memoized.cache = cache\n memoized.clear = () => cache.clear()\n\n return memoized\n}\n\nexport default memoizeAsync\n","/**\n * Rate limiter that restricts the number of requests within a sliding time window.\n *\n * @example\n * const limiter = new RateLimiter({ maxRequests: 5, perWindow: 1000 })\n * if (limiter.tryAcquire()) {\n * // Allowed\n * }\n *\n * @example\n * const limiter = new RateLimiter({ maxRequests: 2, perWindow: 1000 })\n * await limiter.acquire()\n * await limiter.acquire()\n * // Third call waits until the window rolls\n */\nexport class RateLimiter {\n private _maxRequests: number\n private _perWindow: number\n private _timestamps: number[] = []\n\n constructor(options: { maxRequests: number; perWindow: number }) {\n if (options.maxRequests < 1) throw new RangeError('maxRequests must be >= 1')\n if (options.perWindow < 1) throw new RangeError('perWindow must be >= 1')\n this._maxRequests = options.maxRequests\n this._perWindow = options.perWindow\n }\n\n private _prune(): void {\n const now = Date.now()\n const cutoff = now - this._perWindow\n while (this._timestamps.length > 0) {\n const ts = this._timestamps[0]\n if (ts === undefined || ts > cutoff) break\n this._timestamps.shift()\n }\n }\n\n /**\n * Check if a request is allowed without waiting.\n */\n tryAcquire(): boolean {\n this._prune()\n if (this._timestamps.length < this._maxRequests) {\n this._timestamps.push(Date.now())\n return true\n }\n return false\n }\n\n /**\n * Wait until a request is allowed.\n */\n async acquire(): Promise<void> {\n while (true) {\n this._prune()\n if (this._timestamps.length < this._maxRequests) {\n this._timestamps.push(Date.now())\n return\n }\n const oldest = this._timestamps[0] ?? Date.now()\n const waitMs = oldest + this._perWindow - Date.now()\n if (waitMs > 0) {\n await new Promise<void>(resolve => setTimeout(resolve, waitMs))\n }\n }\n }\n\n /**\n * Current number of pending requests in the window.\n */\n get pending(): number {\n this._prune()\n return this._timestamps.length\n }\n}\n\nexport default RateLimiter\n","/**\n * Mutex for exclusive access to a critical section.\n *\n * @example\n * const mutex = new Mutex()\n * const release = await mutex.acquire()\n * try {\n * // Exclusive access\n * } finally {\n * release()\n * }\n *\n * @example\n * const mutex = new Mutex()\n * const result = await mutex.use(async () => {\n * return await fetch('/api/data')\n * })\n */\nexport class Mutex {\n private _locked = false\n private _waiting: Array<() => void> = []\n\n /**\n * Acquire the lock. Returns a release function to be called when done.\n */\n acquire(): Promise<() => void> {\n if (!this._locked) {\n this._locked = true\n return Promise.resolve(this._release.bind(this))\n }\n return new Promise<() => void>(resolve => {\n this._waiting.push(() => {\n resolve(this._release.bind(this))\n })\n })\n }\n\n /**\n * Run a function with the lock held and automatically release it.\n */\n async use<T>(fn: () => Promise<T>): Promise<T> {\n const release = await this.acquire()\n try {\n return await fn()\n } finally {\n release()\n }\n }\n\n /**\n * Whether the mutex is currently locked.\n */\n get locked(): boolean {\n return this._locked\n }\n\n private _release(): void {\n if (this._waiting.length > 0) {\n const next = this._waiting.shift()\n if (next) next()\n } else {\n this._locked = false\n }\n }\n}\n\nexport default Mutex\n","/**\n * Process an array of items in sequential batches.\n *\n * @example\n * const items = [1, 2, 3, 4, 5]\n * const results = await batch(items, 2, async (batch) => {\n * return batch.map(n => n * 2)\n * })\n * // results = [2, 4, 6, 8, 10]\n */\nexport async function batch<T, R>(\n items: T[],\n batchSize: number,\n fn: (batch: T[]) => Promise<R[]>,\n): Promise<R[]> {\n if (batchSize < 1) throw new RangeError('batchSize must be >= 1')\n\n const results: R[] = []\n for (let i = 0; i < items.length; i += batchSize) {\n const chunk = items.slice(i, i + batchSize)\n const batchResults = await fn(chunk)\n results.push(...batchResults)\n }\n return results\n}\n\nexport default batch\n","/**\n * Execute async tasks in sequence, passing each result to the next task.\n *\n * @example\n * const result = await waterfall([\n * async (n: number) => n + 1,\n * async (n: number) => n * 2,\n * async (n: number) => `Result: ${n}`,\n * ], 1)\n * // result = \"Result: 4\"\n *\n * @example\n * const result = await waterfall([\n * async () => fetch('/api/data').then(r => r.json()),\n * async (data) => process(data),\n * ])\n */\nexport async function waterfall(\n tasks: Array<(arg: any) => Promise<any>>,\n initial?: any,\n): Promise<any> {\n let result = initial\n for (const task of tasks) {\n result = await task(result)\n }\n return result\n}\n\nexport default waterfall\n","import type { RetryOptions } from '../core/index.js'\r\n\r\n/**\r\n * Delays execution for the given number of milliseconds.\r\n */\r\nexport function sleep(ms: number): Promise<void> {\r\n return new Promise(resolve => setTimeout(resolve, ms))\r\n}\r\n\r\n/**\r\n * Rejects a promise if it does not resolve within the specified timeout.\r\n */\r\nexport async function timeout<T>(promise: Promise<T>, ms: number, errorMessage?: string): Promise<T> {\r\n let timer: ReturnType<typeof setTimeout> | undefined\r\n const timeoutPromise = new Promise<never>((_, reject) => {\r\n timer = setTimeout(() => reject(new Error(errorMessage ?? `Promise timed out after ${ms}ms`)), ms)\r\n })\r\n try {\r\n return await Promise.race([promise, timeoutPromise])\r\n } finally {\r\n if (timer !== undefined) clearTimeout(timer)\r\n }\r\n}\r\n\r\n/**\r\n * Races a promise against a timeout, returning 'timeout' if the timer wins.\r\n */\r\nexport async function raceWithTimeout<T>(promise: Promise<T>, ms: number): Promise<T | 'timeout'> {\r\n let timer: ReturnType<typeof setTimeout> | undefined\r\n const timeoutPromise = new Promise<'timeout'>(resolve => {\r\n timer = setTimeout(() => resolve('timeout'), ms)\r\n })\r\n try {\r\n return await Promise.race([promise, timeoutPromise])\r\n } finally {\r\n if (timer !== undefined) clearTimeout(timer)\r\n }\r\n}\r\n\r\n/**\r\n * Maps over an array with an async function, using Promise.allSettled.\r\n * Returns an array of PromiseSettledResult.\r\n */\r\nexport async function allSettledMap<T, R>(\r\n items: T[],\r\n fn: (item: T) => Promise<R>,\r\n): Promise<PromiseSettledResult<R>[]> {\r\n return await Promise.allSettled(items.map(fn))\r\n}\r\n\r\n/**\r\n * Maps over an array with an async function, limiting concurrency.\r\n *\r\n * @param concurrency - Maximum number of concurrent operations (default Infinity)\r\n */\r\nexport async function parallelMap<T, R>(\r\n items: T[],\r\n fn: (item: T) => Promise<R>,\r\n concurrency = Number.POSITIVE_INFINITY,\r\n): Promise<R[]> {\r\n if (concurrency === Number.POSITIVE_INFINITY) {\r\n return await Promise.all(items.map(fn))\r\n }\r\n\r\n const results: R[] = []\r\n const queue = [...items]\r\n\r\n const worker = async (): Promise<void> => {\r\n while (queue.length > 0) {\r\n const item = queue.shift()!\r\n results.push(await fn(item))\r\n }\r\n }\r\n\r\n const workerCount = Math.min(concurrency, items.length)\r\n const workers = Array.from({ length: workerCount }, () => worker())\r\n await Promise.all(workers)\r\n return results\r\n}\r\n\r\n/**\r\n * Retries an async function with exponential backoff.\r\n */\r\nexport async function retryAsync<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T> {\r\n const { attempts = 3, baseDelay = 1000, maxDelay = 30000, shouldRetry = () => true } = options ?? {}\r\n let lastError: unknown\r\n for (let attempt = 0; attempt < attempts; attempt++) {\r\n try {\r\n return await fn()\r\n } catch (error) {\r\n lastError = error\r\n if (!shouldRetry(error) || attempt >= attempts - 1) break\r\n const delay = Math.min(baseDelay * 2 ** attempt + Math.random() * baseDelay, maxDelay)\r\n await sleep(delay)\r\n }\r\n }\r\n throw lastError\r\n}\r\n\r\n/**\r\n * Composes async functions, passing the result of each to the next.\r\n */\r\nexport async function pipeline<T>(initial: T, ...fns: Array<(arg: T) => Promise<T>>): Promise<T> {\r\n let result = initial\r\n for (const fn of fns) {\r\n result = await fn(result)\r\n }\r\n return result\r\n}\r\n\r\n/**\r\n * Creates a deferred promise with external resolve and reject methods.\r\n */\r\nexport function deferred<T>(): Deferred<T> {\r\n let resolve!: (value: T) => void\r\n let reject!: (reason: unknown) => void\r\n const promise = new Promise<T>((res, rej) => {\r\n resolve = res\r\n reject = rej\r\n })\r\n return { promise, resolve, reject }\r\n}\r\n\r\nexport interface Deferred<T> {\r\n promise: Promise<T>\r\n resolve: (value: T) => void\r\n reject: (reason: unknown) => void\r\n}\r\n\r\n// ─── Queue, Semaphore, memoizeAsync ─────────────────────\r\nexport { Queue } from './queue.js'\r\nexport type { QueueOptions } from './queue.js'\r\nexport { Semaphore } from './semaphore.js'\r\nexport { memoizeAsync } from './memoize.js'\r\nexport type { MemoizeAsyncOptions } from './memoize.js'\r\n\r\n// ─── RateLimiter, Mutex, batch, waterfall ───────────────\r\nexport { RateLimiter } from './ratelimit.js'\r\nexport { Mutex } from './mutex.js'\r\nexport { batch } from './batch.js'\r\nexport { waterfall } from './waterfall.js'\r\n","/**\r\n * Options for CSV parsing.\r\n */\r\nexport interface CsvOptions {\r\n delimiter?: string\r\n header?: boolean\r\n skipEmptyLines?: boolean\r\n}\r\n\r\n/**\r\n * Parses a CSV string into an array of records (objects).\r\n *\r\n * @param input - CSV string\r\n * @param options - Optional parsing options\r\n */\r\nexport function parseCsv(input: string, options?: CsvOptions): Record<string, string>[] {\r\n const { delimiter = ',', header = true, skipEmptyLines = true } = options ?? {}\r\n\r\n const lines = input.split(/\\r?\\n/)\r\n const rows: string[][] = []\r\n\r\n for (const line of lines) {\r\n const trimmed = line.trim()\r\n if (skipEmptyLines && trimmed.length === 0) continue\r\n const values = parseCsvLine(trimmed, delimiter)\r\n rows.push(values)\r\n }\r\n\r\n if (rows.length === 0) return []\r\n\r\n if (header) {\r\n const [head, ...body] = rows\r\n if (head === undefined) return []\r\n return body.map(row => {\r\n const record: Record<string, string> = {}\r\n for (let i = 0; i < head.length; i++) {\r\n if (head[i] === '__proto__' || head[i] === 'constructor' || head[i] === 'prototype') continue\r\n record[head[i]!] = row[i] ?? ''\r\n }\r\n return record\r\n })\r\n }\r\n\r\n return rows.map(row => {\r\n const record: Record<string, string> = {}\r\n for (let i = 0; i < row.length; i++) {\r\n record[String(i)] = row[i]!\r\n }\r\n return record\r\n })\r\n}\r\n\r\nfunction parseCsvLine(line: string, delimiter: string): string[] {\r\n const result: string[] = []\r\n let current = ''\r\n let inQuotes = false\r\n\r\n for (let i = 0; i < line.length; i++) {\r\n const ch = line[i]!\r\n if (inQuotes) {\r\n if (ch === '\"') {\r\n if (line[i + 1] === '\"') {\r\n current += '\"'\r\n i++\r\n } else {\r\n inQuotes = false\r\n }\r\n } else {\r\n current += ch\r\n }\r\n } else {\r\n if (ch === '\"') {\r\n inQuotes = true\r\n } else if (ch === delimiter) {\r\n result.push(current)\r\n current = ''\r\n } else {\r\n current += ch\r\n }\r\n }\r\n }\r\n result.push(current)\r\n return result\r\n}\r\n\r\n/**\r\n * Converts an array of records to a CSV string.\r\n */\r\nexport function stringifyCsv(data: Record<string, unknown>[], options?: { delimiter?: string }): string {\r\n const { delimiter = ',' } = options ?? {}\r\n if (data.length === 0) return ''\r\n\r\n const headers = Object.keys(data[0]!)\r\n const lines: string[] = [headers.map(v => escapeCsvField(v, delimiter)).join(delimiter)]\r\n\r\n for (const record of data) {\r\n const row = headers.map(h => escapeCsvField(String(record[h] ?? ''), delimiter))\r\n lines.push(row.join(delimiter))\r\n }\r\n\r\n return lines.join('\\n')\r\n}\r\n\r\nfunction escapeCsvField(value: string, delimiter: string): string {\r\n if (value.includes('\"') || value.includes(delimiter) || value.includes('\\n') || value.includes('\\r')) {\r\n return '\"' + value.replace(/\"/g, '\"\"') + '\"'\r\n }\r\n return value\r\n}\r\n\r\n/**\r\n * Safely parses a JSON string, returning the default value or null on failure.\r\n */\r\nexport function safeJsonParse<T>(input: string, default_?: T): T | null {\r\n try {\r\n return JSON.parse(input) as T\r\n } catch {\r\n return default_ ?? null\r\n }\r\n}\r\n\r\n/**\r\n * Reads an environment variable with optional default.\r\n */\r\nexport function env(name: string, default_?: string): string {\r\n const value = process.env[name]\r\n return value ?? default_ ?? ''\r\n}\r\n\r\n/**\r\n * Reads an environment variable as an integer.\r\n */\r\nexport function envInt(name: string, default_?: number): number {\r\n const value = process.env[name]\r\n if (value === undefined || value === '') return default_ ?? 0\r\n const parsed = Number.parseInt(value, 10)\r\n return Number.isNaN(parsed) ? (default_ ?? 0) : parsed\r\n}\r\n\r\n/**\r\n * Reads an environment variable as a boolean.\r\n */\r\nexport function envBool(name: string, default_?: boolean): boolean {\r\n const value = process.env[name]\r\n if (value === undefined || value === '') return default_ ?? false\r\n return value === 'true' || value === '1' || value === 'yes'\r\n}\r\n","/**\r\n * Checks if a value is a string.\r\n */\r\nexport function isString(value: unknown): value is string {\r\n return typeof value === 'string'\r\n}\r\n\r\n/**\r\n * Checks if a value is a number (not NaN, not Infinity).\r\n */\r\nexport function isNumber(value: unknown): value is number {\r\n return typeof value === 'number' && Number.isFinite(value)\r\n}\r\n\r\n/**\r\n * Checks if a value is a boolean.\r\n */\r\nexport function isBoolean(value: unknown): value is boolean {\r\n return typeof value === 'boolean'\r\n}\r\n\r\n/**\r\n * Checks if a value is a plain object (not null, not array, typeof 'object').\r\n */\r\nexport function isObject(value: unknown): value is Record<string, unknown> {\r\n return value !== null && typeof value === 'object' && !Array.isArray(value)\r\n}\r\n\r\n/**\r\n * Checks if a value is an array.\r\n */\r\nexport function isArray(value: unknown): value is unknown[] {\r\n return Array.isArray(value)\r\n}\r\n\r\n/**\r\n * Checks if a value is a function.\r\n */\r\nexport function isFunction(value: unknown): value is (...args: unknown[]) => unknown {\r\n return typeof value === 'function'\r\n}\r\n\r\n/**\r\n * Checks if a value is a Date.\r\n */\r\nexport function isDate(value: unknown): value is Date {\r\n return value instanceof Date && !Number.isNaN(value.getTime())\r\n}\r\n\r\n/**\r\n * Checks if a value is a RegExp.\r\n */\r\nexport function isRegExp(value: unknown): value is RegExp {\r\n return value instanceof RegExp\r\n}\r\n\r\n/**\r\n * Checks if a value is a Map.\r\n */\r\nexport function isMap(value: unknown): value is Map<unknown, unknown> {\r\n return value instanceof Map\r\n}\r\n\r\n/**\r\n * Checks if a value is a Set.\r\n */\r\nexport function isSet(value: unknown): value is Set<unknown> {\r\n return value instanceof Set\r\n}\r\n\r\n/**\r\n * Checks if a value is a Promise.\r\n */\r\nexport function isPromise(value: unknown): value is Promise<unknown> {\r\n return value instanceof Promise\r\n}\r\n\r\n/**\r\n * Checks if a value is null.\r\n */\r\nexport function isNull(value: unknown): value is null {\r\n return value === null\r\n}\r\n\r\n/**\r\n * Checks if a value is undefined.\r\n */\r\nexport function isUndefined(value: unknown): value is undefined {\r\n return value === undefined\r\n}\r\n\r\n/**\r\n * Checks if a value is null or undefined.\r\n */\r\nexport function isNil(value: unknown): value is null | undefined {\r\n return value === null || value === undefined\r\n}\r\n\r\n/**\r\n * Checks if a value is empty.\r\n * Works for strings, arrays, objects, Map, and Set.\r\n */\r\nexport function isEmpty(value: unknown): boolean {\r\n if (value === null || value === undefined) return true\r\n if (typeof value === 'string') return value.length === 0\r\n if (Array.isArray(value)) return value.length === 0\r\n if (value instanceof Map || value instanceof Set) return value.size === 0\r\n if (typeof value === 'object') return Object.keys(value as Record<string, unknown>).length === 0\r\n return false\r\n}\r\n\r\n/**\r\n * Asserts that a value is defined (not null or undefined).\r\n * Throws if the value is null or undefined.\r\n */\r\nexport function assertDefined<T>(value: T, message?: string): asserts value is NonNullable<T> {\r\n if (value === null || value === undefined) {\r\n throw new Error(message ?? 'Expected value to be defined')\r\n }\r\n}\r\n\r\n/**\r\n * Asserts that a value matches a type guard. Throws if it doesn't.\r\n */\r\nexport function assertType<T>(value: unknown, guard: (v: unknown) => v is T, message?: string): asserts value is T {\r\n if (!guard(value)) {\r\n throw new Error(message ?? 'Value does not match expected type')\r\n }\r\n}\r\n\r\n/**\r\n * Wraps a value in an array if it is not already one.\r\n */\r\nexport function ensureArray<T>(value: T | T[]): T[] {\r\n return Array.isArray(value) ? value : [value]\r\n}\r\n\r\n/** Alias for ensureArray. Wraps a value in an array if it is not already one. */\r\nexport const castArray = ensureArray\r\n\r\n/**\r\n * Returns a string representation of the value's type.\r\n *\r\n * Possible values: \"string\", \"number\", \"boolean\", \"array\", \"object\", \"function\",\r\n * \"date\", \"regexp\", \"map\", \"set\", \"promise\", \"null\", \"undefined\", \"nan\", \"infinity\"\r\n */\r\nexport function getType(value: unknown): string {\r\n if (value === null) return 'null'\r\n if (value === undefined) return 'undefined'\r\n if (typeof value === 'string') return 'string'\r\n if (typeof value === 'boolean') return 'boolean'\r\n if (typeof value === 'function') return 'function'\r\n if (typeof value === 'number') {\r\n if (Number.isNaN(value)) return 'nan'\r\n if (!Number.isFinite(value)) return 'infinity'\r\n return 'number'\r\n }\r\n if (Array.isArray(value)) return 'array'\r\n if (value instanceof Date) return 'date'\r\n if (value instanceof RegExp) return 'regexp'\r\n if (value instanceof Map) return 'map'\r\n if (value instanceof Set) return 'set'\r\n if (value instanceof Promise) return 'promise'\r\n return 'object'\r\n}\r\n","import { readFileSync, readdirSync, existsSync } from 'node:fs'\r\nimport { join, basename } from 'node:path'\r\nimport type { ScanResult, ReplacementSuggestion, SecurityIssue, ScannerConfig } from '../types.js'\r\nimport { KNOWN_MAPPINGS, KNOWN_CVES, type PackageMapping } from '../known-mappings.js'\r\n\r\ninterface LockfilePackages {\r\n [key: string]: { version?: string; dependencies?: Record<string, string> } | undefined\r\n}\r\n\r\ninterface LockfileData {\r\n packages: LockfilePackages\r\n}\r\n\r\nfunction parsePackageJson(path: string): { name: string; dependencies: Record<string, string>; devDependencies: Record<string, string> } {\r\n const raw = readFileSync(path, 'utf-8')\r\n const json = JSON.parse(raw)\r\n return {\r\n name: json.name ?? basename(join(path, '..')),\r\n dependencies: (json.dependencies as Record<string, string>) ?? {},\r\n devDependencies: (json.devDependencies as Record<string, string>) ?? {},\r\n }\r\n}\r\n\r\nfunction parseLockfile(projectPath: string): LockfileData | null {\r\n const lockPath = join(projectPath, 'package-lock.json')\r\n if (!existsSync(lockPath)) return null\r\n try {\r\n const raw = readFileSync(lockPath, 'utf-8')\r\n const json = JSON.parse(raw)\r\n const packages: LockfilePackages = {}\r\n\r\n if (json.packages) {\r\n for (const [key, val] of Object.entries(json.packages as Record<string, { version?: string }>)) {\r\n if (key) {\r\n packages[key] = val\r\n }\r\n }\r\n }\r\n\r\n if (json.dependencies && Object.keys(packages).length === 0) {\r\n for (const [key, val] of Object.entries(json.dependencies as Record<string, { version?: string; requires?: Record<string, string> }>)) {\r\n packages[key] = { version: val.version, dependencies: val.requires }\r\n }\r\n }\r\n\r\n return { packages }\r\n } catch {\r\n return null\r\n }\r\n}\r\n\r\nfunction detectImportInFile(filePath: string, regex: RegExp): boolean {\r\n try {\r\n const content = readFileSync(filePath, 'utf-8')\r\n return regex.test(content)\r\n } catch {\r\n return false\r\n }\r\n}\r\n\r\nfunction detectImportsInSrc(projectPath: string, mapping: PackageMapping): boolean {\r\n const regex = new RegExp(mapping.detectionPattern)\r\n const srcDir = join(projectPath, 'src')\r\n if (!existsSync(srcDir)) return false\r\n\r\n try {\r\n const files = collectSourceFiles(srcDir)\r\n for (const file of files) {\r\n if (detectImportInFile(file, regex)) return true\r\n }\r\n } catch {\r\n return false\r\n }\r\n return false\r\n}\r\n\r\nfunction collectSourceFiles(dir: string): string[] {\r\n const results: string[] = []\r\n try {\r\n const entries = readdirSync(dir, { withFileTypes: true })\r\n for (const entry of entries) {\r\n if (entry.name === 'node_modules' || entry.name === 'dist' || entry.name === '.git' || entry.name === 'coverage' || entry.name === '.tsup') {\r\n continue\r\n }\r\n const full = join(dir, entry.name)\r\n if (entry.isDirectory()) {\r\n results.push(...collectSourceFiles(full))\r\n } else if (entry.isFile()) {\r\n const ext = entry.name.split('.').pop()\r\n if (ext === 'ts' || ext === 'tsx' || ext === 'js' || ext === 'jsx' || ext === 'mjs' || ext === 'cjs') {\r\n results.push(full)\r\n }\r\n }\r\n }\r\n } catch {\r\n // skip inaccessible dirs\r\n }\r\n return results\r\n}\r\n\r\nfunction estimateTransitiveCount(lockfile: LockfileData | null, directNames: Set<string>): number {\r\n if (!lockfile) return 0\r\n let count = 0\r\n for (const key of Object.keys(lockfile.packages)) {\r\n if (!key || key === '') continue\r\n const name = key.startsWith('node_modules/') ? key.slice('node_modules/'.length) : key\r\n const rootName = name.startsWith('@') ? `${name.split('/')[0]}/${name.split('/')[1]}` : name.split('/')[0]\r\n if (rootName && !directNames.has(rootName)) {\r\n count++\r\n }\r\n }\r\n return count\r\n}\r\n\r\nfunction parseSize(value: string): number {\r\n const cleaned = value.replace(/\\(.*?\\)/g, '').trim()\r\n const match = cleaned.match(/^([\\d.]+)\\s*(KB|MB)/i)\r\n if (!match) return 0\r\n const num = Number.parseFloat(match[1]!)\r\n if (!match[2]) return 0\r\n if (match[2].toUpperCase() === 'MB') return num * 1024\r\n return num\r\n}\r\n\r\nexport async function scanProject(config: ScannerConfig): Promise<ScanResult> {\r\n const projectPath = config.path ?? '.'\r\n const pkgPath = join(projectPath, 'package.json')\r\n\r\n if (!existsSync(pkgPath)) {\r\n throw new Error(`No package.json found at ${projectPath}. Run dep-exray in a JavaScript/TypeScript project directory.`)\r\n }\r\n\r\n const pkg = parsePackageJson(pkgPath)\r\n const lockfile = parseLockfile(projectPath)\r\n\r\n const allDeps: Record<string, string> = { ...pkg.dependencies, ...pkg.devDependencies }\r\n const directNames = new Set(Object.keys(allDeps))\r\n\r\n const transitiveCount = estimateTransitiveCount(lockfile, directNames)\r\n\r\n const highImpactReplacements: ReplacementSuggestion[] = []\r\n const mediumImpactReplacements: ReplacementSuggestion[] = []\r\n const securityIssues: SecurityIssue[] = []\r\n\r\n const sizeMap: Record<string, string> = {}\r\n for (const m of KNOWN_MAPPINGS) {\r\n sizeMap[m.name] = m.size\r\n }\r\n\r\n for (const mapping of KNOWN_MAPPINGS) {\r\n const isDirect = directNames.has(mapping.name)\r\n if (!isDirect) continue\r\n\r\n const isUsed = detectImportsInSrc(projectPath, mapping)\r\n if (!isUsed && !config.verbose) continue\r\n\r\n const mappingSize = parseSize(sizeMap[mapping.name] ?? '0 KB')\r\n const replacementSize = mapping.replacement.startsWith('native') ? 0 : 5\r\n const reductionStr = mappingSize > 1024\r\n ? `${(mappingSize / 1024).toFixed(1)} MB → ${replacementSize} KB`\r\n : `${mappingSize.toFixed(0)} KB → ${replacementSize} KB`\r\n\r\n const suggestion: ReplacementSuggestion = {\r\n packageName: mapping.name,\r\n reason: mapping.reason,\r\n replacement: mapping.replacement,\r\n estimatedSizeReduction: reductionStr,\r\n confidence: mapping.confidence,\r\n autoPrReady: mapping.autoPrReady,\r\n }\r\n\r\n if (mapping.confidence === 'high') {\r\n highImpactReplacements.push(suggestion)\r\n } else {\r\n mediumImpactReplacements.push(suggestion)\r\n }\r\n }\r\n\r\n for (const [name, cves] of Object.entries(KNOWN_CVES)) {\r\n if (directNames.has(name)) {\r\n for (const cveItem of cves) {\r\n securityIssues.push({\r\n packageName: name,\r\n cveId: cveItem.cve,\r\n severity: cveItem.severity as SecurityIssue['severity'],\r\n fix: cveItem.fix,\r\n })\r\n }\r\n }\r\n }\r\n\r\n let totalSizeKB = 0\r\n for (const depName of directNames) {\r\n const sizeStr = sizeMap[depName]\r\n if (sizeStr) {\r\n totalSizeKB += parseSize(sizeStr)\r\n } else {\r\n totalSizeKB += 50\r\n }\r\n }\r\n totalSizeKB += transitiveCount * 30\r\n\r\n const totalSizeStr = totalSizeKB > 1024\r\n ? `${(totalSizeKB / 1024).toFixed(1)} MB`\r\n : `${totalSizeKB.toFixed(0)} KB`\r\n\r\n return {\r\n projectName: pkg.name,\r\n directDeps: directNames.size,\r\n transitiveDeps: transitiveCount,\r\n totalEstimatedSize: totalSizeStr,\r\n highImpactReplacements,\r\n mediumImpactReplacements,\r\n securityIssues,\r\n }\r\n}\r\n","\r\n\r\nexport interface PackageMapping {\r\n name: string\r\n size: string\r\n replacement: string\r\n confidence: 'high' | 'medium' | 'low'\r\n autoPrReady: boolean\r\n reason: string\r\n detectionPattern: string\r\n}\r\n\r\nexport const KNOWN_MAPPINGS: PackageMapping[] = [\r\n {\r\n name: 'lodash',\r\n size: '4.2 MB',\r\n replacement: 'jscore-core',\r\n confidence: 'high',\r\n autoPrReady: true,\r\n reason: 'Most lodash functions have direct replacements in jscore-core with 99% API compatibility',\r\n detectionPattern: 'from [\\'\"]lodash[\\'\"]|require\\\\([\\'\"]lodash[\\'\"]\\\\)',\r\n },\r\n {\r\n name: 'moment',\r\n size: '2.5 MB',\r\n replacement: 'jscore-core/date',\r\n confidence: 'high',\r\n autoPrReady: true,\r\n reason: 'date utilities in jscore-core cover 95% of common moment use cases',\r\n detectionPattern: 'from [\\'\"]moment[\\'\"]|require\\\\([\\'\"]moment[\\'\"]\\\\)',\r\n },\r\n {\r\n name: 'date-fns',\r\n size: '1.2 MB (tree-shaked ~50KB)',\r\n replacement: 'jscore-core/date',\r\n confidence: 'medium',\r\n autoPrReady: false,\r\n reason: 'Partially overlapping — jscore-core covers basic date ops but not all locale support',\r\n detectionPattern: 'from [\\'\"]date-fns[\\'\"]|require\\\\([\\'\"]date-fns[\\'\"]\\\\)',\r\n },\r\n {\r\n name: 'axios',\r\n size: '1.6 MB',\r\n replacement: 'native fetch + jscore-core/async/retry',\r\n confidence: 'medium',\r\n autoPrReady: false,\r\n reason: 'Native fetch covers most use cases; needs manual review for interceptors',\r\n detectionPattern: 'from [\\'\"]axios[\\'\"]|require\\\\([\\'\"]axios[\\'\"]\\\\)',\r\n },\r\n {\r\n name: 'uuid',\r\n size: '30 KB',\r\n replacement: 'crypto.randomUUID() (native)',\r\n confidence: 'high',\r\n autoPrReady: true,\r\n reason: 'crypto.randomUUID() is available in all modern Node.js and browsers',\r\n detectionPattern: 'from [\\'\"]uuid[\\'\"]|require\\\\([\\'\"]uuid[\\'\"]\\\\)',\r\n },\r\n {\r\n name: 'deepmerge',\r\n size: '15 KB',\r\n replacement: 'jscore-core',\r\n confidence: 'high',\r\n autoPrReady: true,\r\n reason: 'jscore-core provides deepMerge out of the box',\r\n detectionPattern: 'from [\\'\"]deepmerge[\\'\"]|require\\\\([\\'\"]deepmerge[\\'\"]\\\\)',\r\n },\r\n {\r\n name: 'lodash.merge',\r\n size: '25 KB',\r\n replacement: 'jscore-core',\r\n confidence: 'high',\r\n autoPrReady: true,\r\n reason: 'jscore-core provides deepMerge out of the box',\r\n detectionPattern: 'from [\\'\"]lodash\\\\.(merge|clone|pick|omit|get|set)[\\'\"]',\r\n },\r\n {\r\n name: 'chalk',\r\n size: '45 KB',\r\n replacement: 'picocolors',\r\n confidence: 'medium',\r\n autoPrReady: false,\r\n reason: \"picocolors is 3KB vs chalk's 45KB with same API\",\r\n detectionPattern: 'from [\\'\"]chalk[\\'\"]|require\\\\([\\'\"]chalk[\\'\"]\\\\)',\r\n },\r\n {\r\n name: 'nanoid',\r\n size: '8 KB',\r\n replacement: 'jscore-core/string (nanoid)',\r\n confidence: 'high',\r\n autoPrReady: true,\r\n reason: 'jscore-core provides nanoid with same API',\r\n detectionPattern: 'from [\\'\"]nanoid[\\'\"]|require\\\\([\\'\"]nanoid[\\'\"]\\\\)',\r\n },\r\n {\r\n name: 'dayjs',\r\n size: '50 KB',\r\n replacement: 'jscore-core/date',\r\n confidence: 'medium',\r\n autoPrReady: false,\r\n reason: 'Partially overlapping — covers basics but not all plugins',\r\n detectionPattern: 'from [\\'\"]dayjs[\\'\"]|require\\\\([\\'\"]dayjs[\\'\"]\\\\)',\r\n },\r\n {\r\n name: 'clsx',\r\n size: '5 KB',\r\n replacement: 'native template literals',\r\n confidence: 'high',\r\n autoPrReady: true,\r\n reason: 'Can be replaced with simple template literal conditional pattern',\r\n detectionPattern: 'from [\\'\"]clsx[\\'\"]|require\\\\([\\'\"]clsx[\\'\"]\\\\)',\r\n },\r\n]\r\n\r\nexport const KNOWN_CVES: Record<string, { cve: string; severity: string; fix: string }[]> = {\r\n 'ansi-regex': [\r\n { cve: 'CVE-2021-3807', severity: 'high', fix: 'Update to ansi-regex@6.0.1 or later' },\r\n ],\r\n 'semver': [\r\n { cve: 'CVE-2022-25883', severity: 'medium', fix: 'Update to semver@7.5.2 or later' },\r\n ],\r\n 'json5': [\r\n { cve: 'CVE-2022-46175', severity: 'high', fix: 'Update to json5@2.2.3 or later' },\r\n ],\r\n 'lodash': [\r\n { cve: 'CVE-2020-28502', severity: 'high', fix: 'Update to lodash@4.17.21 or later' },\r\n { cve: 'CVE-2020-8203', severity: 'medium', fix: 'Update to lodash@4.17.21 or later' },\r\n ],\r\n}\r\n","import type { ScanResult, ReplacementSuggestion, SecurityIssue } from '../types.js'\n\n// ANSI color codes — zero dependencies\nconst _ = {\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n dim: '\\x1b[2m',\n red: '\\x1b[31m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n blue: '\\x1b[34m',\n cyan: '\\x1b[36m',\n white: '\\x1b[37m',\n}\n\nfunction style(text: string, codes: string[]): string {\n return codes.join('') + text + _.reset\n}\n\nfunction severityColor(severity: SecurityIssue['severity']): string {\n switch (severity) {\n case 'critical': return style(severity.toUpperCase(), [_.bold, _.red])\n case 'high': return style(severity.toUpperCase(), [_.red])\n case 'medium': return style(severity.toUpperCase(), [_.yellow])\n case 'low': return style(severity.toUpperCase(), [_.dim])\n }\n}\n\nfunction confidenceIcon(confidence: ReplacementSuggestion['confidence']): string {\n switch (confidence) {\n case 'high': return style('●', [_.green])\n case 'medium': return style('●', [_.yellow])\n case 'low': return style('●', [_.red])\n }\n}\n\nexport function generateReport(result: ScanResult, jsonOutput?: boolean): string {\n if (jsonOutput) {\n return JSON.stringify(result, null, 2)\n }\n\n const lines: string[] = []\n\n const t = (text: string, codes: string[] = [_.cyan]) => style(text, [_.bold, ...codes])\n\n lines.push(t(`┌${'─'.repeat(58)}┐`))\n lines.push(t(`│${' '.repeat(18)}dep-exray Report${' '.repeat(21)}│`))\n lines.push(t(`├${'─'.repeat(58)}┤`))\n lines.push(t(`│ ${style('📦 PROJECT:', [_.white])} ${style(result.projectName, [_.bold])}${' '.repeat(Math.max(1, 47 - result.projectName.length))}│`))\n lines.push(t(`│ ${style('📊 DEPENDENCIES:', [_.white])} ${style(String(result.directDeps), [_.bold])} direct + ${style(String(result.transitiveDeps), [_.bold])} transitive${' '.repeat(Math.max(1, 27 - String(result.transitiveDeps).length))}│`))\n lines.push(t(`│ ${style('💾 TOTAL SIZE:', [_.white])} ${style(result.totalEstimatedSize, [_.bold])}${' '.repeat(Math.max(1, 42 - result.totalEstimatedSize.length))}│`))\n lines.push(t(`├${'─'.repeat(58)}┤`))\n\n if (result.highImpactReplacements.length > 0) {\n lines.push(t(`│ ${style('🟢', [_.green])} ${style('HIGH IMPACT REPLACEMENTS', [_.bold, _.green])}${' '.repeat(23)}│`))\n for (const item of result.highImpactReplacements) {\n const autoPr = item.autoPrReady ? style('✓ Auto-PR ready', [_.green]) : style('Manual review needed', [_.dim])\n const confIcon = confidenceIcon(item.confidence)\n lines.push(t(`├${'─'.repeat(58)}┤`))\n lines.push(t(`│ ${style('✗', [_.red])} ${style(item.packageName, [_.bold])} (${item.estimatedSizeReduction})${' '.repeat(Math.max(1, 38 - item.estimatedSizeReduction.length))}│`))\n lines.push(t(`│ ${style('→', [_.dim])} ${style(item.replacement, [_.cyan])}${' '.repeat(Math.max(1, 51 - item.replacement.length))}│`))\n lines.push(t(`│ ${style('└─', [_.dim])} ${autoPr} ${confIcon} ${item.confidence}${' '.repeat(Math.max(1, 35))}│`))\n }\n }\n\n if (result.mediumImpactReplacements.length > 0) {\n lines.push(t(`├${'─'.repeat(58)}┤`))\n lines.push(t(`│ ${style('🟡', [_.yellow])} ${style('MEDIUM IMPACT REPLACEMENTS', [_.bold, _.yellow])}${' '.repeat(20)}│`))\n for (const item of result.mediumImpactReplacements) {\n const autoPr = item.autoPrReady ? style('✓ Auto-PR ready', [_.green]) : style('Manual review needed', [_.dim])\n const confIcon = confidenceIcon(item.confidence)\n lines.push(t(`├${'─'.repeat(58)}┤`))\n lines.push(t(`│ ${style('✗', [_.red])} ${style(item.packageName, [_.bold])} (${item.estimatedSizeReduction})${' '.repeat(Math.max(1, 38 - item.estimatedSizeReduction.length))}│`))\n lines.push(t(`│ ${style('→', [_.dim])} ${style(item.replacement, [_.cyan])}${' '.repeat(Math.max(1, 51 - item.replacement.length))}│`))\n lines.push(t(`│ ${style('└─', [_.dim])} ${autoPr} ${confIcon} ${item.confidence}${' '.repeat(Math.max(1, 35))}│`))\n }\n }\n\n if (result.securityIssues.length > 0) {\n lines.push(t(`├${'─'.repeat(58)}┤`))\n lines.push(t(`│ ${style('🔴', [_.red])} ${style('SECURITY ISSUES', [_.bold, _.red])}${' '.repeat(33)}│`))\n for (const issue of result.securityIssues) {\n lines.push(t(`├${'─'.repeat(58)}┤`))\n lines.push(t(`│ ${severityColor(issue.severity)} ${style(issue.cveId, [_.bold])} in ${issue.packageName}${' '.repeat(Math.max(1, 40 - issue.packageName.length))}│`))\n lines.push(t(`│ ${style('→', [_.dim])} ${issue.fix}${' '.repeat(Math.max(1, 52 - issue.fix.length))}│`))\n }\n }\n\n lines.push(t(`└${'─'.repeat(58)}┘`))\n\n return lines.join('\\n')\n}\n","import { readFileSync } from 'node:fs'\r\nimport { readdirSync, statSync } from 'node:fs'\r\nimport { join, extname } from 'node:path'\r\n\r\nconst SOURCE_EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs'])\r\n\r\nfunction isSourceFile(file: string): boolean {\r\n return SOURCE_EXTENSIONS.has(extname(file))\r\n}\r\n\r\nfunction collectSourceFiles(dir: string): string[] {\r\n const results: string[] = []\r\n try {\r\n const entries = readdirSync(dir, { withFileTypes: true })\r\n for (const entry of entries) {\r\n const fullPath = join(dir, entry.name)\r\n if (entry.name === 'node_modules' || entry.name === 'dist' || entry.name === '.git' || entry.name === 'coverage' || entry.name === '.tsup') {\r\n continue\r\n }\r\n if (entry.isDirectory()) {\r\n results.push(...collectSourceFiles(fullPath))\r\n } else if (entry.isFile() && isSourceFile(entry.name)) {\r\n results.push(fullPath)\r\n }\r\n }\r\n } catch {\r\n // skip directories we can't read\r\n }\r\n return results\r\n}\r\n\r\nfunction escapeRegex(str: string): string {\r\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\r\n}\r\n\r\nexport async function analyzeUsage(\r\n projectPath: string,\r\n packageName: string,\r\n): Promise<{\r\n isUsed: boolean\r\n importCount: number\r\n importLocations: string[]\r\n}> {\r\n const importLocations: string[] = []\r\n const escaped = escapeRegex(packageName)\r\n const importRegex = new RegExp(\r\n `(?:from\\\\s+['\"]${escaped}(?:/['\"]|['\"])|require\\\\(\\\\s*['\"]${escaped}(?:/|['\"]))`,\r\n 'g',\r\n )\r\n\r\n const srcDir = join(projectPath, 'src')\r\n let files: string[]\r\n try {\r\n if (statSync(srcDir).isDirectory()) {\r\n files = collectSourceFiles(srcDir)\r\n } else {\r\n files = collectSourceFiles(projectPath)\r\n }\r\n } catch {\r\n files = collectSourceFiles(projectPath)\r\n }\r\n\r\n for (const file of files) {\r\n try {\r\n const content = readFileSync(file, 'utf-8')\r\n importRegex.lastIndex = 0\r\n if (importRegex.test(content)) {\r\n importLocations.push(file)\r\n }\r\n } catch {\r\n // skip unreadable files\r\n }\r\n }\r\n\r\n return {\r\n isUsed: importLocations.length > 0,\r\n importCount: importLocations.length,\r\n importLocations,\r\n }\r\n}\r\n","/**\n * Validates an Indonesian NIK (Nomor Induk Kependudukan / Resident Identity Number).\n *\n * A valid NIK:\n * - Must be exactly 16 digits\n * - Structure: PP CC DD DDMMYY SSSS\n * - PP: Province code (2 digits)\n * - CC: City code (2 digits)\n * - DD: District code (2 digits)\n * - DDMMYY: Birth date (6 digits; for women the day is incremented by 40)\n * - SSSS: Serial number (4 digits)\n * - The birth date must correspond to a valid calendar date\n *\n * @param value - The NIK string (digits only or with dots)\n * @returns `true` if the value is a valid NIK\n *\n * @example isNIK('3201010203940001') // => true (male, born 2 March 1994)\n * @example isNIK('3201015203940001') // => true (female, born 12 March 1994)\n * @example isNIK('1234567890123456') // => false (invalid birth date)\n * @example isNIK('320101') // => false (too short)\n */\nexport function isNIK(value: string): boolean {\n const digits = value.replace(/\\D/g, '')\n if (digits.length !== 16) return false\n\n const rawDay = Number.parseInt(digits.slice(6, 8), 10)\n const month = Number.parseInt(digits.slice(8, 10), 10)\n const year = Number.parseInt(digits.slice(10, 12), 10)\n\n if (rawDay < 1 || rawDay > 71) return false\n if (month < 1 || month > 12) return false\n\n let day = rawDay\n if (day >= 41) day -= 40\n\n const fullYear = year < 70 ? 2000 + year : 1900 + year\n const date = new Date(fullYear, month - 1, day)\n\n return (\n date.getFullYear() === fullYear &&\n date.getMonth() === month - 1 &&\n date.getDate() === day\n )\n}\n","/**\n * Validates an Indonesian NPWP (Nomor Pokok Wajib Pajak / Tax Identification Number).\n *\n * A valid NPWP:\n * - Must be 15 or 16 digits (formatted: `XX.XXX.XXX.X-XXX.XXX` or plain digits)\n * - The last digit is a checksum computed from the preceding digits\n *\n * The checksum uses a weighted-sum algorithm with a repeating weight pattern of\n * `[3, 7, 1]`. The computed checksum must equal the last digit.\n *\n * @param value - The NPWP string (formatted with dots & dash, or plain digits)\n * @returns `true` if the value is a valid NPWP\n *\n * @example isNPWP('12.345.678.9-012.344') // => true\n * @example isNPWP('123456789012344') // => true (plain digits)\n * @example isNPWP('12.345.678.9-012.345') // => false (invalid checksum)\n */\nexport function isNPWP(value: string): boolean {\n const digits = value.replace(/\\D/g, '')\n if (digits.length !== 15 && digits.length !== 16) return false\n\n const nums: number[] = []\n for (let i = 0; i < digits.length; i++) {\n nums.push(Number.parseInt(digits[i]!, 10))\n }\n\n const checkDigit = nums[nums.length - 1]!\n\n let sum = 0\n for (let i = 0; i < nums.length - 1; i++) {\n sum += nums[i]! * [3, 7, 1][i % 3]!\n }\n\n const computed = (11 - (sum % 11)) % 10\n return computed === checkDigit\n}\n","const INDONESIAN_PREFIXES: ReadonlyArray<[number, number]> = [\n [11, 19],\n [21, 29],\n [51, 59],\n [77, 79],\n [95, 99],\n]\n\nfunction isValidIndonesianPrefix(prefix: number): boolean {\n for (const [min, max] of INDONESIAN_PREFIXES) {\n if (prefix >= min && prefix <= max) return true\n }\n return false\n}\n\n/**\n * Validates a phone number.\n *\n * For Indonesian numbers (`country = 'id'`):\n * - Accepted formats: `08xx…`, `+628xx…`, `628xx…`\n * - Must start with a valid operator prefix:\n * 0811-0819, 0821-0829, 0851-0859, 0877-0879, 0895-0899\n * - 10–13 digits after the country code\n *\n * For generic numbers (`country = 'any'`):\n * - Any string with 10–15 digits is accepted\n *\n * @param value - The phone number string\n * @param country - Country to validate against (`'id'` or `'any'`; default `'id'`)\n * @returns `true` if the value is a valid phone number\n *\n * @example isPhone('08123456789') // => true\n * @example isPhone('+628123456789') // => true\n * @example isPhone('628123456789') // => true\n * @example isPhone('081234567') // => false (too short)\n * @example isPhone('089123456789') // => false (invalid prefix 91)\n */\nexport function isPhone(value: string, country: 'id' | 'any' = 'id'): boolean {\n const digits = value.replace(/\\D/g, '')\n\n if (country === 'any') {\n return digits.length >= 10 && digits.length <= 15\n }\n\n if (digits.length < 10) return false\n\n let normalized: string\n if (digits.startsWith('62')) {\n normalized = digits.slice(2)\n } else if (digits.startsWith('0')) {\n normalized = digits.slice(1)\n } else {\n normalized = digits\n }\n\n if (normalized.length < 10 || normalized.length > 13) return false\n if (!normalized.startsWith('8')) return false\n\n const prefix = Number.parseInt(normalized.slice(1, 3), 10)\n return isValidIndonesianPrefix(prefix)\n}\n","const LOCAL_SPECIAL = \"!#$%&'*+/=?^_`{|}~-\"\n\nfunction isQuotedLocalPart(local: string): boolean {\n if (local.length < 2) return false\n let i = 1\n while (i < local.length - 1) {\n const ch = local[i]!\n if (ch === '\\\\') {\n i++\n if (i >= local.length - 1) return false\n } else if (ch === '\"') {\n return false\n }\n i++\n }\n return true\n}\n\nfunction isUnquotedLocalPart(local: string): boolean {\n if (local.length === 0 || local.startsWith('.') || local.endsWith('.')) return false\n\n for (let i = 0; i < local.length; i++) {\n const ch = local[i]!\n if (\n (ch >= 'a' && ch <= 'z') ||\n (ch >= 'A' && ch <= 'Z') ||\n (ch >= '0' && ch <= '9') ||\n ch === '.' ||\n LOCAL_SPECIAL.includes(ch)\n ) {\n continue\n }\n return false\n }\n\n for (let i = 1; i < local.length; i++) {\n if (local[i] === '.' && local[i - 1] === '.') return false\n }\n\n return true\n}\n\nfunction isValidDomain(domain: string): boolean {\n if (domain.length === 0 || domain.startsWith('.') || domain.endsWith('.')) return false\n\n const labels = domain.split('.')\n if (labels.length < 2) return false\n\n for (const label of labels) {\n if (label.length === 0 || label.length > 63) return false\n if (label.startsWith('-') || label.endsWith('-')) return false\n\n for (let i = 0; i < label.length; i++) {\n const ch = label[i]!\n if (\n !(\n (ch >= 'a' && ch <= 'z') ||\n (ch >= 'A' && ch <= 'Z') ||\n (ch >= '0' && ch <= '9') ||\n ch === '-'\n )\n ) {\n return false\n }\n }\n }\n\n return true\n}\n\n/**\n * RFC‑compliant email address validation.\n *\n * Validation rules:\n * - Total length ≤ 254 characters\n * - Local part ≤ 64 characters; supports quoted strings (including escaped\n * characters), unquoted letters / digits / `!#$%&'*+/=?^_`{|}~-`, and dots\n * (no leading, trailing, or consecutive dots)\n * - Domain part ≤ 255 characters; valid DNS labels separated by dots, each\n * label ≤ 63 characters, no leading/trailing hyphens, at least two labels\n *\n * @param value - The email address string\n * @returns `true` if the value is a syntactically valid email address\n *\n * @example isEmail('user@example.com') // => true\n * @example isEmail('user.name+tag@example.co.id') // => true\n * @example isEmail('\"quoted@local\"@example.com') // => true\n * @example isEmail('not-an-email') // => false\n */\nexport function isEmail(value: string): boolean {\n if (value.length > 254) return false\n\n const atIndex = value.lastIndexOf('@')\n if (atIndex < 1 || atIndex === value.length - 1) return false\n\n const localPart = value.slice(0, atIndex)\n const domainPart = value.slice(atIndex + 1)\n\n if (localPart.length > 64) return false\n if (domainPart.length > 255) return false\n\n if (localPart.startsWith('\"') && localPart.endsWith('\"')) {\n if (!isQuotedLocalPart(localPart)) return false\n } else {\n if (!isUnquotedLocalPart(localPart)) return false\n }\n\n return isValidDomain(domainPart)\n}\n","const IPV4_OCTET = /^(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/\n\nfunction isValidIPv4(hostname: string): boolean {\n const octets = hostname.split('.')\n if (octets.length !== 4) return false\n return octets.every(octet => IPV4_OCTET.test(octet))\n}\n\nfunction isValidDNSHostname(hostname: string): boolean {\n if (hostname.startsWith('.') || hostname.endsWith('.')) return false\n\n const labels = hostname.split('.')\n if (labels.length < 2) return false\n\n for (const label of labels) {\n if (label.length === 0 || label.length > 63) return false\n if (label.startsWith('-') || label.endsWith('-')) return false\n\n for (let i = 0; i < label.length; i++) {\n const ch = label[i]!\n if (\n !(\n (ch >= 'a' && ch <= 'z') ||\n (ch >= 'A' && ch <= 'Z') ||\n (ch >= '0' && ch <= '9') ||\n ch === '-'\n )\n ) {\n return false\n }\n }\n }\n\n return true\n}\n\nfunction isValidHostname(hostname: string): boolean {\n if (hostname.length === 0) return false\n\n // IPv6 literal\n if (hostname.startsWith('[') && hostname.endsWith(']')) {\n return hostname.length > 2\n }\n\n // IPv4\n if (/^\\d/.test(hostname) || /\\d$/.test(hostname)) {\n if (isValidIPv4(hostname)) return true\n }\n\n // localhost\n if (hostname === 'localhost') return true\n\n // DNS hostname\n return isValidDNSHostname(hostname)\n}\n\n/**\n * Validates a URL.\n *\n * A valid URL:\n * - Must use the `http` or `https` protocol\n * - Must have a valid hostname (DNS name, IPv4, IPv6 literal, or `localhost`)\n * - May include an optional port, path, query string, and fragment\n *\n * @param value - The URL string\n * @returns `true` if the value is a valid http/https URL\n *\n * @example isURL('https://example.com') // => true\n * @example isURL('http://example.com:8080/path?q=1#f') // => true\n * @example isURL('ftp://example.com') // => false\n * @example isURL('not-a-url') // => false\n */\nexport function isURL(value: string): boolean {\n try {\n const url = new URL(value)\n\n if (url.protocol !== 'http:' && url.protocol !== 'https:') {\n return false\n }\n\n return isValidHostname(url.hostname)\n } catch {\n return false\n }\n}\n","/**\n * Parse data dari NIK (Nomor Induk Kependudukan).\n *\n * @example parseNIK('3201010203940001')\n * // { nik: '3201010203940001', valid: true, gender: 'LAKI-LAKI', birthDate: Date(1994-03-02), province: 'JAWA BARAT', city: 'BOGOR', district: 'CIAWI' }\n *\n * @example parseNIK('3201015203940001')\n * // { nik: '3201015203940001', valid: true, gender: 'PEREMPUAN', birthDate: Date(1994-03-12), province: 'JAWA BARAT', ... }\n */\nexport function parseNIK(value: string): NIKInfo {\n const digits = value.replace(/\\D/g, '')\n const info: NIKInfo = {\n nik: value,\n valid: false,\n gender: null,\n birthDate: null,\n province: null,\n provinceCode: null,\n city: null,\n cityCode: null,\n district: null,\n districtCode: null,\n uniqueCode: null,\n }\n\n if (digits.length !== 16) return info\n\n const provinceCode = digits.slice(0, 2)\n const cityCode = digits.slice(2, 4)\n const districtCode = digits.slice(4, 6)\n const rawDay = Number.parseInt(digits.slice(6, 8), 10)\n const month = Number.parseInt(digits.slice(8, 10), 10)\n const year = Number.parseInt(digits.slice(10, 12), 10)\n const uniqueCode = digits.slice(12, 16)\n\n if (rawDay < 1 || rawDay > 71 || month < 1 || month > 12) return info\n\n const gender: 'LAKI-LAKI' | 'PEREMPUAN' = rawDay >= 41 ? 'PEREMPUAN' : 'LAKI-LAKI'\n let day = rawDay\n if (day >= 41) day -= 40\n\n const fullYear = year < 70 ? 2000 + year : 1900 + year\n const birthDate = new Date(fullYear, month - 1, day)\n\n if (\n birthDate.getFullYear() !== fullYear ||\n birthDate.getMonth() !== month - 1 ||\n birthDate.getDate() !== day\n ) {\n return info\n }\n\n return {\n nik: value,\n valid: true,\n gender,\n birthDate,\n province: PROVINCE_CODES[provinceCode] ?? null,\n provinceCode,\n city: null,\n cityCode,\n district: null,\n districtCode,\n uniqueCode,\n }\n}\n\nexport interface NIKInfo {\n nik: string\n valid: boolean\n gender: 'LAKI-LAKI' | 'PEREMPUAN' | null\n birthDate: Date | null\n province: string | null\n provinceCode: string | null\n city: string | null\n cityCode: string | null\n district: string | null\n districtCode: string | null\n uniqueCode: string | null\n}\n\nconst PROVINCE_CODES: Record<string, string> = {\n '11': 'ACEH',\n '12': 'SUMATERA UTARA',\n '13': 'SUMATERA BARAT',\n '14': 'RIAU',\n '15': 'JAMBI',\n '16': 'SUMATERA SELATAN',\n '17': 'BENGKULU',\n '18': 'LAMPUNG',\n '19': 'KEPULAUAN BANGKA BELITUNG',\n '21': 'KEPULAUAN RIAU',\n '31': 'DKI JAKARTA',\n '32': 'JAWA BARAT',\n '33': 'JAWA TENGAH',\n '34': 'DI YOGYAKARTA',\n '35': 'JAWA TIMUR',\n '36': 'BANTEN',\n '51': 'BALI',\n '52': 'NUSA TENGGARA BARAT',\n '53': 'NUSA TENGGARA TIMUR',\n '61': 'KALIMANTAN BARAT',\n '62': 'KALIMANTAN TENGAH',\n '63': 'KALIMANTAN SELATAN',\n '64': 'KALIMANTAN TIMUR',\n '65': 'KALIMANTAN UTARA',\n '71': 'SULAWESI UTARA',\n '72': 'SULAWESI TENGAH',\n '73': 'SULAWESI SELATAN',\n '74': 'SULAWESI TENGGARA',\n '75': 'GORONTALO',\n '76': 'SULAWESI BARAT',\n '81': 'MALUKU',\n '82': 'MALUKU UTARA',\n '91': 'PAPUA',\n '92': 'PAPUA BARAT',\n '93': 'PAPUA SELATAN',\n '94': 'PAPUA TENGAH',\n '95': 'PAPUA PEGUNUNGAN',\n}\n","/**\n * Validasi Plat Nomor Kendaraan Bermotor Indonesia.\n *\n * Format: [KODE_DEPAN] [ANGKA] [KODE_BELAKANG]\n * - Kode depan: 1-2 huruf (kode daerah)\n * - Angka: 1-4 digit\n * - Kode belakang: 1-3 huruf (opsional)\n *\n * @example isPlatNomor('B 1234 CD') // true (Jakarta)\n * @example isPlatNomor('AB 5678 XYZ') // true\n * @example isPlatNomor('B 1 A') // true\n * @example isPlatNomor('INVALID') // false\n */\nexport function isPlatNomor(value: string): boolean {\n const trimmed = value.trim().toUpperCase()\n const regex = /^([A-Z]{1,2})\\s*(\\d{1,4})\\s*([A-Z]{0,3})$/\n const match = trimmed.match(regex)\n if (!match) return false\n\n const kodeDepan = match[1]!\n const angka = parseInt(match[2]!, 10)\n const kodeBelakang = match[3] || ''\n\n if (!KODE_DAERAH.includes(kodeDepan)) return false\n if (angka < 1 || angka > 9999) return false\n if (kodeBelakang.length > 3) return false\n return true\n}\n\nconst KODE_DAERAH = [\n 'A', 'AA', 'AB', 'AD', 'AE', 'AG', 'B', 'BA', 'BB', 'BD', 'BE', 'BG',\n 'BH', 'BK', 'BL', 'BM', 'BN', 'BP', 'BR', 'BT', 'BU', 'BV', 'BW', 'D',\n 'DA', 'DB', 'DC', 'DD', 'DE', 'DF', 'DG', 'DH', 'DK', 'DL', 'DM', 'DN',\n 'DP', 'DR', 'DT', 'DU', 'DW', 'E', 'EA', 'EB', 'ED', 'EE', 'F', 'G',\n 'H', 'K', 'KB', 'KH', 'KI', 'KU', 'KT', 'L', 'M', 'N', 'NB', 'NG',\n 'NK', 'NM', 'P', 'PA', 'PB', 'R', 'S', 'ST', 'T', 'W', 'Z',\n]\n","/**\n * Validasi kode pos Indonesia.\n * Kode pos Indonesia terdiri dari 5 digit angka.\n *\n * @example isKodepos('16110') // true (Bogor)\n * @example isKodepos('12345') // true\n * @example isKodepos('1234') // false (kurang)\n * @example isKodepos('ABCDE') // false\n */\nexport function isKodepos(value: string): boolean {\n if (value.length !== 5) return false\n return /^\\d{5}$/.test(value)\n}\n","/**\n * Validasi nomor rekening bank Indonesia.\n * Format: 8-16 digit angka (tergantung bank).\n *\n * @example isNoRekening('1234567890') // true (10 digit)\n * @example isNoRekening('12345678') // true (8 digit - minimum)\n * @example isNoRekening('1234567890123456') // true (16 digit - maksimum)\n * @example isNoRekening('12345') // false (kurang dari 8 digit)\n */\nexport function isNoRekening(value: string): boolean {\n const digits = value.replace(/\\D/g, '')\n if (digits.length < 8 || digits.length > 16) return false\n return true\n}\n","/**\n * Validasi Nomor SIM Indonesia.\n * Format: 12 digit angka (2 digit golongan + 6 digit tanggal lahir + 4 digit nomor seri).\n *\n * @example isNoSIM('123456789012') // true (12 digit)\n * @example isNoSIM('12345') // false\n */\nexport function isNoSIM(value: string): boolean {\n const digits = value.replace(/\\D/g, '')\n return digits.length === 12\n}\n","/**\n * Validasi nomor paspor Indonesia.\n * Format: 2 huruf + 7 digit angka (total 9 karakter).\n *\n * @example isPassport('AB1234567') // true\n * @example isPassport('123456789') // false (harus ada huruf)\n */\nexport function isPassport(value: string): boolean {\n return /^[A-Za-z]{2}\\d{7}$/.test(value.trim())\n}\n","/**\n * Validasi nomor BPJS Kesehatan Indonesia.\n * Format: 13 digit angka.\n *\n * @example isNoBPJS('1234567890123') // true\n * @example isNoBPJS('12345') // false\n */\nexport function isNoBPJS(value: string): boolean {\n const digits = value.replace(/\\D/g, '')\n return digits.length === 13\n}\n","/**\n * Validasi Nomor Kartu Keluarga (KK) Indonesia.\n * Format: 16 digit angka.\n *\n * @example isNoKK('1234567890123456') // true\n * @example isNoKK('12345') // false\n */\nexport function isNoKK(value: string): boolean {\n const digits = value.replace(/\\D/g, '')\n return digits.length === 16\n}\n","/**\n * Predefined error codes mapped to their default HTTP status codes.\n */\nexport interface ErrorCodeMap {\n 'BAD_REQUEST': 400\n 'UNAUTHORIZED': 401\n 'FORBIDDEN': 403\n 'NOT_FOUND': 404\n 'CONFLICT': 409\n 'VALIDATION_ERROR': 422\n 'TOO_MANY': 429\n 'INTERNAL': 500\n 'BAD_GATEWAY': 502\n 'UNAVAILABLE': 503\n}\n\n/** Union of all known error codes. */\nexport type ErrorCode = keyof ErrorCodeMap\n\n/** Default HTTP status for each error code. */\nconst defaultStatus: ErrorCodeMap = {\n 'BAD_REQUEST': 400,\n 'UNAUTHORIZED': 401,\n 'FORBIDDEN': 403,\n 'NOT_FOUND': 404,\n 'CONFLICT': 409,\n 'VALIDATION_ERROR': 422,\n 'TOO_MANY': 429,\n 'INTERNAL': 500,\n 'BAD_GATEWAY': 502,\n 'UNAVAILABLE': 503,\n}\n\n/**\n * A typed error with a machine-readable code, HTTP status, optional details, and cause.\n *\n * - `code` – Short machine-readable identifier (e.g. `'NOT_FOUND'`).\n * - `status` – Defaults to the mapped HTTP status for the code; can be overridden.\n * - `details` – Arbitrary metadata attached to the error.\n *\n * @example\n * ```ts\n * throw new TypedError('NOT_FOUND', 'User not found', { details: { userId } })\n * ```\n */\nexport class TypedError extends Error {\n readonly code: string\n readonly status: number\n readonly details?: unknown\n\n constructor(\n code: string,\n message: string,\n options?: { status?: number; details?: unknown; cause?: unknown },\n ) {\n super(message, { cause: options?.cause })\n this.name = 'TypedError'\n this.code = code\n this.status = options?.status ?? defaultStatus[code as ErrorCode] ?? 500\n this.details = options?.details\n\n Object.setPrototypeOf(this, new.target.prototype)\n }\n\n /**\n * Serialize the error to a plain JSON-safe object.\n */\n toJSON(): {\n name: string\n message: string\n code: string\n status: number\n details: unknown\n cause: unknown\n stack?: string\n } {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n status: this.status,\n details: this.details,\n cause: this.cause,\n ...(this.stack ? { stack: this.stack } : {}),\n }\n }\n\n override toString(): string {\n return `${this.name} [${this.code}]: ${this.message}`\n }\n}\n\n/**\n * Create a typed error from a known error code.\n *\n * The HTTP status is automatically derived from the code but can be overridden\n * via an explicit `status` in options.\n *\n * @example\n * ```ts\n * throw createError('NOT_FOUND', 'User not found', { details: { userId: 1 } })\n * ```\n */\nexport function createError(\n code: ErrorCode,\n message: string,\n options?: { details?: unknown; cause?: unknown },\n): TypedError {\n return new TypedError(code, message, options)\n}\n\n/**\n * Checks whether an unknown value is a {@link TypedError}.\n *\n * @example\n * ```ts\n * if (isTypedError(err)) {\n * console.log(err.code, err.status)\n * }\n * ```\n */\nexport function isTypedError(error: unknown): error is TypedError {\n return error instanceof TypedError\n}\n","/**\n * Collects multiple errors into a single aggregate error.\n *\n * Useful for batch operations where independent steps may each fail and you\n * want to report all failures together rather than throwing on the first one.\n *\n * @example\n * ```ts\n * const err = new MultiError([\n * new Error('First failure'),\n * new Error('Second failure'),\n * ])\n * throw err\n * ```\n */\nexport class MultiError extends Error {\n readonly errors: Error[]\n\n constructor(errors: Error[], message?: string) {\n const joined = errors.map((e) => e.message).join('; ')\n super(message ?? joined)\n this.name = 'MultiError'\n this.errors = [...errors]\n\n Object.setPrototypeOf(this, new.target.prototype)\n }\n\n /** Number of collected errors. */\n get length(): number {\n return this.errors.length\n }\n\n /**\n * Check if any collected error satisfies `predicate`.\n *\n * @example\n * ```ts\n * if (err.some(e => e.message.includes('timeout'))) { … }\n * ```\n */\n some(predicate: (error: Error) => boolean): boolean {\n return this.errors.some(predicate)\n }\n\n /** Array of all error messages. */\n get messages(): string[] {\n return this.errors.map((e) => e.message)\n }\n\n /**\n * Serialize to a plain JSON-safe object.\n */\n toJSON(): {\n name: string\n message: string\n errors: Array<{ name: string; message: string; stack?: string }>\n stack?: string\n } {\n return {\n name: this.name,\n message: this.message,\n errors: this.errors.map((e) => ({\n name: e.name,\n message: e.message,\n ...(e.stack ? { stack: e.stack } : {}),\n })),\n ...(this.stack ? { stack: this.stack } : {}),\n }\n }\n\n override toString(): string {\n return `${this.name}: ${this.message}`\n }\n}\n\n/**\n * Run `fn` and capture any thrown error.\n *\n * If `fn` returns successfully, `result` holds the return value and `errors`\n * is an empty array. If `fn` throws, `errors` contains the thrown value\n * (wrapped in an `Error` if it is not already one).\n *\n * @example\n * ```ts\n * const { result, errors } = collectErrors(() => {\n * return riskyOperation()\n * })\n * if (errors.length > 0) {\n * console.error('Operation failed', errors)\n * }\n * ```\n */\nexport function collectErrors<T>(\n fn: () => T,\n): { result?: T; errors: Error[] } {\n try {\n return { result: fn(), errors: [] }\n } catch (err) {\n return {\n errors: [err instanceof Error ? err : new Error(String(err))],\n }\n }\n}\n","/**\n * Represents the severity level of a log entry.\n * Ordered from least to most severe: debug < info < warn < error.\n */\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error'\n\n/**\n * Log function signature bound to a specific severity level.\n */\nexport type LogFn = (message: string, meta?: Record<string, unknown>) => void\n\n/**\n * Configuration options for creating a Logger instance.\n */\nexport interface LoggerOptions {\n /** Minimum log level to output (default: 'info'). */\n level?: LogLevel\n /** Optional name tag prepended to every message as `[name]`. */\n name?: string\n /** Custom transport; defaults to {@link consoleTransport}. */\n transport?: Transport\n}\n\n/**\n * A transport handles the formatted output of log entries.\n * Implementations write to stdout, files, buffers, or remote services.\n */\nexport interface Transport {\n log(level: LogLevel, message: string, meta?: Record<string, unknown>): void\n}\n\nconst LEVEL_ORDER: Record<LogLevel, number> = { debug: 0, info: 1, warn: 2, error: 3 }\n\n/**\n * Structured logger with level filtering, child loggers, and pluggable transport.\n *\n * @example\n * ```ts\n * const log = new Logger({ level: 'debug', name: 'app' })\n * log.info('server started', { port: 3000 })\n *\n * const child = log.child({ requestId: 'abc-123' })\n * child.warn('slow query', { durationMs: 450 })\n * ```\n */\nexport class Logger {\n private _level: LogLevel\n private _name?: string\n private _transport: Transport\n private _extraMeta: Record<string, unknown>\n\n constructor(options?: LoggerOptions) {\n this._level = options?.level ?? 'info'\n this._name = options?.name\n this._transport = options?.transport ?? consoleTransport\n this._extraMeta = Object.create(null)\n }\n\n private _shouldLog(target: LogLevel): boolean {\n return LEVEL_ORDER[this._level] <= LEVEL_ORDER[target]\n }\n\n private _log(level: LogLevel, message: string, meta?: Record<string, unknown>): void {\n if (level !== 'error' && !this._shouldLog(level)) return\n\n const merged: Record<string, unknown> = Object.create(null)\n for (const key of Object.keys(this._extraMeta)) {\n merged[key] = (this._extraMeta as Record<string, unknown>)[key]!\n }\n if (meta !== undefined) {\n for (const key of Object.keys(meta)) {\n merged[key] = meta[key]!\n }\n }\n\n const label = this._name !== undefined ? `[${this._name}] ${message}` : message\n const finalMeta = Object.keys(merged).length > 0 ? merged : undefined\n this._transport.log(level, label, finalMeta)\n }\n\n /** Log at `debug` level. Only emitted when the current level is `'debug'`. */\n debug: LogFn = (message, meta?) => this._log('debug', message, meta)\n\n /** Log at `info` level. Emitted when level is `'debug'` or `'info'`. */\n info: LogFn = (message, meta?) => this._log('info', message, meta)\n\n /** Log at `warn` level. Emitted when level is `'debug'`, `'info'`, or `'warn'`. */\n warn: LogFn = (message, meta?) => this._log('warn', message, meta)\n\n /** Log at `error` level. Always emitted regardless of current level. */\n error: LogFn = (message, meta?) => this._log('error', message, meta)\n\n /**\n * Creates a child logger that inherits the parent's level, name, and transport,\n * but merges `extraMeta` into every log call. Child metadata is shallow-merged\n * on top of the parent's inherited metadata.\n *\n * @param extraMeta - Additional context to include in every log entry.\n */\n child(extraMeta: Record<string, unknown>): Logger {\n const child = new Logger({\n level: this._level,\n name: this._name,\n transport: this._transport,\n })\n const inherited: Record<string, unknown> = Object.create(null)\n for (const key of Object.keys(this._extraMeta)) {\n inherited[key] = (this._extraMeta as Record<string, unknown>)[key]!\n }\n for (const key of Object.keys(extraMeta)) {\n inherited[key] = extraMeta[key]!\n }\n child._extraMeta = inherited\n return child\n }\n\n /** Updates the minimum log level for this instance. */\n setLevel(level: LogLevel): void {\n this._level = level\n }\n\n /** Returns the current minimum log level. */\n getLevel(): LogLevel {\n return this._level\n }\n\n /**\n * Creates a new named Logger.\n * Convenience shorthand for `new Logger({ ...options, name })`.\n *\n * @param name - The name tag shown in log output.\n * @param options - Additional configuration.\n */\n static create(name: string, options?: LoggerOptions): Logger {\n return new Logger({ ...options, name })\n }\n}\n\n/**\n * Default transport that writes formatted log lines to `console.log`.\n *\n * Output format: `[LEVEL] message {meta}`\n *\n * When a logger has a name, the format becomes: `[LEVEL] [name] message {meta}`\n */\nexport const consoleTransport: Transport = {\n log(level, message, meta) {\n const metaStr =\n meta !== undefined && Object.keys(meta).length > 0 ? ` ${JSON.stringify(meta)}` : ''\n console.log(`[${level.toUpperCase()}] ${message}${metaStr}`)\n },\n}\n\n/**\n * Default logger instance at `'info'` level with no name.\n */\nexport const logger: Logger = new Logger()\n","import type { LogLevel } from './logger.js'\n\n/**\n * A transport handles the formatted output of log entries.\n */\nexport interface Transport {\n log(level: LogLevel, message: string, meta?: Record<string, unknown>): void\n}\n\nconst LEVEL_COLORS: Record<LogLevel, string> = {\n debug: '\\x1b[90m',\n info: '\\x1b[34m',\n warn: '\\x1b[33m',\n error: '\\x1b[31m',\n}\n\nconst RESET = '\\x1b[0m'\n\n/**\n * Creates a console transport that writes formatted log lines to `console.log`.\n *\n * The level prefix is optionally colored using ANSI escape codes:\n * - `debug` → gray\n * - `info` → blue\n * - `warn` → yellow\n * - `error` → red\n *\n * @param options - Configuration for the console transport.\n * @param options.colors - Enable ANSI color output (default: `true`).\n * @param options.timestamp - Prepend an ISO-8601 timestamp (default: `false`).\n */\nexport function createConsoleTransport(options?: {\n colors?: boolean\n timestamp?: boolean\n}): Transport {\n const useColors = options?.colors !== false\n const showTimestamp = options?.timestamp ?? false\n\n return {\n log(level, message, meta) {\n const parts: string[] = []\n\n if (showTimestamp) {\n parts.push(new Date().toISOString())\n }\n\n if (useColors) {\n const color = LEVEL_COLORS[level]\n parts.push(`${color}[${level.toUpperCase()}]${RESET}`)\n } else {\n parts.push(`[${level.toUpperCase()}]`)\n }\n\n parts.push(message)\n\n if (meta !== undefined && Object.keys(meta).length > 0) {\n parts.push(JSON.stringify(meta))\n }\n\n console.log(parts.join(' '))\n },\n }\n}\n\n/**\n * Creates a transport that outputs structured JSON lines.\n *\n * Each log entry is serialized as a single JSON object with\n * `timestamp`, `level`, `message`, and optional `meta` fields.\n *\n * @param options - Configuration for the JSON transport.\n * @param options.stream - A writable stream (e.g. `process.stdout`).\n * Defaults to `process.stdout` in Node.js, falls\n * back to `console.log` in browsers.\n */\nexport function createJsonTransport(options?: {\n stream?: { write(data: string): void }\n}): Transport {\n const writeStream =\n options?.stream ??\n (typeof process !== 'undefined' &&\n typeof process.stdout !== 'undefined' &&\n typeof process.stdout.write === 'function'\n ? (process.stdout as { write(data: string): void })\n : undefined)\n\n return {\n log(level, message, meta) {\n const entry: Record<string, unknown> = {\n timestamp: new Date().toISOString(),\n level,\n message,\n }\n if (meta !== undefined && Object.keys(meta).length > 0) {\n entry.meta = meta\n }\n const line = JSON.stringify(entry)\n if (writeStream !== undefined) {\n writeStream.write(line + '\\n')\n } else {\n console.log(line)\n }\n },\n }\n}\n\n/**\n * Creates a transport that appends log entries to a file.\n *\n * Each line is formatted as: `[timestamp] [LEVEL] message {meta}`\n *\n * ⚠️ Node.js only. Silently discards log entries when `fs` is unavailable\n * (browsers, Deno, Bun — though Bun supports `fs`).\n *\n * @param filename - Path to the log file.\n * @param options - Configuration for the file transport.\n * @param options.maxSize - Maximum file size in bytes before rotation\n * (default: 10 MB). **Note:** rotation is not\n * yet implemented; this is reserved for future use.\n */\nexport function createFileTransport(\n filename: string,\n _options?: { maxSize?: number },\n): Transport {\n // Try to resolve fs synchronously at construction time\n // Uses process.versions.node as a heuristic for Node.js environment\n let fs: { appendFileSync: (path: string, data: string) => void } | null = null\n try {\n if (typeof process !== 'undefined' && process.versions?.node) {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const m = require('fs') as { appendFileSync: (path: string, data: string) => void }\n fs = m\n }\n } catch {\n // fs unavailable (browser, edge runtime)\n }\n\n return {\n log(level, message, meta) {\n if (fs === null) return\n\n const metaStr =\n meta !== undefined && Object.keys(meta).length > 0 ? ` ${JSON.stringify(meta)}` : ''\n const line = `[${new Date().toISOString()}] [${level.toUpperCase()}] ${message}${metaStr}\\n`\n\n try {\n fs.appendFileSync(filename, line)\n } catch {\n // Silently drop if write fails (disk full, permissions, etc.)\n }\n },\n }\n}\n\n/**\n * Creates a buffered transport that batches log entries and flushes them\n * to the underlying transport when either the buffer size or flush interval\n * is reached (whichever comes first).\n *\n * Useful for reducing I/O pressure in high-throughput scenarios.\n *\n * @param transport - The underlying transport to flush to.\n * @param options - Configuration for the buffer.\n * @param options.maxSize - Maximum number of entries before forced flush\n * (default: 100).\n * @param options.flushIntervalMs - How often to auto-flush in milliseconds\n * (default: 5000). Set to `0` to disable\n * interval flushing.\n */\nexport function createBufferedTransport(\n transport: Transport,\n options?: { maxSize?: number; flushIntervalMs?: number },\n): Transport {\n const maxSize = options?.maxSize ?? 100\n const flushIntervalMs = options?.flushIntervalMs ?? 5000\n\n const buffer: Array<{\n level: LogLevel\n message: string\n meta?: Record<string, unknown>\n }> = []\n\n let timer: ReturnType<typeof setTimeout> | undefined\n\n function flush(): void {\n if (timer !== undefined) {\n clearTimeout(timer)\n timer = undefined\n }\n for (let i = 0; i < buffer.length; i++) {\n const entry = buffer[i]!\n transport.log(entry.level, entry.message, entry.meta)\n }\n buffer.length = 0\n }\n\n function scheduleFlush(): void {\n if (timer !== undefined || flushIntervalMs <= 0) return\n timer = setTimeout((): void => {\n timer = undefined\n flush()\n }, flushIntervalMs)\n }\n\n return {\n log(level, message, meta) {\n buffer.push({ level, message, meta })\n if (buffer.length >= maxSize) {\n flush()\n } else {\n scheduleFlush()\n }\n },\n }\n}\n","/**\n * Converts a hex color string to RGB values.\n *\n * @example hexToRgb('#ff0000') // { r: 255, g: 0, b: 0 }\n * @example hexToRgb('#f00') // { r: 255, g: 0, b: 0 }\n * @example hexToRgb('#FF8800') // { r: 255, g: 136, b: 0 }\n */\nexport function hexToRgb(hex: string): { r: number; g: number; b: number } | null {\n let h = hex.replace('#', '')\n if (h.length === 3) h = h[0]! + h[0] + h[1]! + h[1] + h[2]! + h[2]\n if (h.length !== 6) return null\n const num = Number.parseInt(h, 16)\n if (isNaN(num)) return null\n return {\n r: (num >> 16) & 255,\n g: (num >> 8) & 255,\n b: num & 255,\n }\n}\n\n/**\n * Converts RGB values to a hex color string.\n *\n * @example rgbToHex(255, 0, 0) // \"#ff0000\"\n * @example rgbToHex(255, 136, 0) // \"#ff8800\"\n */\nexport function rgbToHex(r: number, g: number, b: number): string {\n const toHex = (n: number) => Math.max(0, Math.min(255, Math.round(n))).toString(16).padStart(2, '0')\n return '#' + toHex(r) + toHex(g) + toHex(b)\n}\n\n/**\n * Lightens a hex color by a given percentage (0-100).\n *\n * @example lighten('#ff0000', 20) // \"#ff3333\"\n * @example lighten('#0000ff', 50) // \"#7f7fff\"\n */\nexport function lighten(hex: string, percent: number): string {\n const rgb = hexToRgb(hex)\n if (!rgb) return hex\n const factor = percent / 100\n return rgbToHex(\n rgb.r + (255 - rgb.r) * factor,\n rgb.g + (255 - rgb.g) * factor,\n rgb.b + (255 - rgb.b) * factor,\n )\n}\n\n/**\n * Darkens a hex color by a given percentage (0-100).\n *\n * @example darken('#ff0000', 20) // \"#cc0000\"\n * @example darken('#00ff00', 50) // \"#008000\"\n */\nexport function darken(hex: string, percent: number): string {\n const rgb = hexToRgb(hex)\n if (!rgb) return hex\n const factor = percent / 100\n return rgbToHex(\n rgb.r * (1 - factor),\n rgb.g * (1 - factor),\n rgb.b * (1 - factor),\n )\n}\n\n/**\n * Checks the WCAG contrast ratio between two hex colors.\n * Returns the ratio as a number (1-21). WCAG AA requires 4.5:1 for normal text.\n *\n * @example contrastRatio('#000000', '#ffffff') // 21\n * @example contrastRatio('#ff0000', '#ffffff') // 3.99\n */\nexport function contrastRatio(hex1: string, hex2: string): number {\n const lum1 = relativeLuminance(hex1)\n const lum2 = relativeLuminance(hex2)\n const lighter = Math.max(lum1, lum2)\n const darker = Math.min(lum1, lum2)\n return Number(((lighter + 0.05) / (darker + 0.05)).toFixed(2))\n}\n\nfunction relativeLuminance(hex: string): number {\n const rgb = hexToRgb(hex)\n if (!rgb) return 0\n const vals = [rgb.r / 255, rgb.g / 255, rgb.b / 255].map((c) => {\n return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4)\n })\n return 0.2126 * vals[0]! + 0.7152 * vals[1]! + 0.0722 * vals[2]!\n}\n\n/**\n * Checks if a hex color meets WCAG AA contrast ratio (4.5:1) against another color.\n *\n * @example meetsWCAG('#000000', '#ffffff') // true (black on white)\n * @example meetsWCAG('#999999', '#ffffff') // false (gray on white)\n */\nexport function meetsWCAG(hex1: string, hex2: string, level?: 'AA' | 'AAA'): boolean {\n const ratio = contrastRatio(hex1, hex2)\n const threshold = level === 'AAA' ? 7 : 4.5\n return ratio >= threshold\n}\n\n/**\n * Checks if a string is a valid hex color.\n * Supports 3-digit (#rgb), 6-digit (#rrggbb), with or without leading `#`.\n *\n * @example isValidHex('#ff0000') // true\n * @example isValidHex('#f00') // true\n * @example isValidHex('ff0000') // true\n * @example isValidHex('#xyz') // false\n */\nexport function isValidHex(value: string): boolean {\n return /^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(value)\n}\n\n/**\n * Converts a hex color to an HSL object.\n * Returns `null` for invalid input.\n *\n * @example hexToHsl('#ff0000') // { h: 0, s: 100, l: 50 }\n * @example hexToHsl('#00ff00') // { h: 120, s: 100, l: 50 }\n * @example hexToHsl('#0000ff') // { h: 240, s: 100, l: 50 }\n */\nexport function hexToHsl(hex: string): { h: number; s: number; l: number } | null {\n const rgb = hexToRgb(hex)\n if (!rgb) return null\n const r = rgb.r / 255\n const g = rgb.g / 255\n const b = rgb.b / 255\n const max = Math.max(r, g, b)\n const min = Math.min(r, g, b)\n const l = (max + min) / 2\n if (max === min) return { h: 0, s: 0, l: Math.round(l * 100) }\n const d = max - min\n const s = l > 0.5 ? d / (2 - max - min) : d / (max + min)\n let h = 0\n switch (max) {\n case r: h = ((g - b) / d + (g < b ? 6 : 0)) / 6; break\n case g: h = ((b - r) / d + 2) / 6; break\n case b: h = ((r - g) / d + 4) / 6; break\n }\n return {\n h: Math.round(h * 360),\n s: Math.round(s * 100),\n l: Math.round(l * 100),\n }\n}\n\n/**\n * Converts HSL values to a hex color string.\n *\n * @example hslToHex(0, 100, 50) // '#ff0000'\n * @example hslToHex(120, 100, 50) // '#00ff00'\n * @example hslToHex(240, 100, 50) // '#0000ff'\n */\nexport function hslToHex(h: number, s: number, l: number): string {\n const hue = h / 360\n const sat = s / 100\n const lig = l / 100\n if (sat === 0) {\n const val = Math.round(lig * 255)\n return rgbToHex(val, val, val)\n }\n const hue2rgb = (p: number, q: number, t: number): number => {\n let tt = t\n if (tt < 0) tt += 1\n if (tt > 1) tt -= 1\n if (tt < 1 / 6) return p + (q - p) * 6 * tt\n if (tt < 1 / 2) return q\n if (tt < 2 / 3) return p + (q - p) * (2 / 3 - tt) * 6\n return p\n }\n const q = lig < 0.5 ? lig * (1 + sat) : lig + sat - lig * sat\n const p = 2 * lig - q\n return rgbToHex(\n Math.round(hue2rgb(p, q, hue + 1 / 3) * 255),\n Math.round(hue2rgb(p, q, hue) * 255),\n Math.round(hue2rgb(p, q, hue - 1 / 3) * 255),\n )\n}\n\n/**\n * Blends two hex colors together with a weight factor.\n * Weight 0 = fully color1, weight 1 = fully color2. Default 0.5.\n *\n * @example mix('#ff0000', '#0000ff') // '#7f007f'\n * @example mix('#ff0000', '#0000ff', 0) // '#ff0000'\n * @example mix('#ff0000', '#0000ff', 1) // '#0000ff'\n */\nexport function mix(color1: string, color2: string, weight: number = 0.5): string {\n const rgb1 = hexToRgb(color1)\n const rgb2 = hexToRgb(color2)\n if (!rgb1 || !rgb2) return color1\n const w = Math.max(0, Math.min(1, weight))\n const lerp = (a: number, b: number) => Math.floor(a + (b - a) * w)\n return rgbToHex(lerp(rgb1.r, rgb2.r), lerp(rgb1.g, rgb2.g), lerp(rgb1.b, rgb2.b))\n}\n\n/**\n * Generates a random hex color.\n *\n * @example randomColor() // '#a3f07b'\n */\nexport function randomColor(): string {\n const r = Math.floor(Math.random() * 256)\n const g = Math.floor(Math.random() * 256)\n const b = Math.floor(Math.random() * 256)\n return rgbToHex(r, g, b)\n}\n\n/**\n * Checks if a hex color is perceived as light (useful for text contrast decisions).\n *\n * @example isLight('#ffffff') // true\n * @example isLight('#000000') // false\n * @example isLight('#ff0000') // false\n */\nexport function isLight(hex: string): boolean {\n const rgb = hexToRgb(hex)\n if (!rgb) return false\n return (0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b) / 255 > 0.5\n}\n\n/**\n * Checks if a hex color is perceived as dark.\n *\n * @example isDark('#000000') // true\n * @example isDark('#ffffff') // false\n */\nexport function isDark(hex: string): boolean {\n return !isLight(hex)\n}\n\n/**\n * Returns the complementary color (180° hue rotation).\n *\n * @example complementary('#ff0000') // '#00ffff'\n * @example complementary('#00ff00') // '#ff00ff'\n * @example complementary('#0000ff') // '#ffff00'\n */\nexport function complementary(hex: string): string {\n const hsl = hexToHsl(hex)\n if (!hsl) return hex\n return hslToHex((hsl.h + 180) % 360, hsl.s, hsl.l)\n}\n\n/**\n * Sets opacity on a hex color, returning an 8-digit hex (#rrggbbaa).\n * Opacity is clamped to 0-1.\n *\n * @example alpha('#ff0000', 0.5) // '#ff000080'\n * @example alpha('#00ff00', 1) // '#00ff00ff'\n * @example alpha('#0000ff', 0) // '#0000ff00'\n */\nexport function alpha(hex: string, opacity: number): string {\n const rgb = hexToRgb(hex)\n if (!rgb) return hex\n const a = Math.max(0, Math.min(1, opacity))\n const alphaHex = Math.round(a * 255).toString(16).padStart(2, '0')\n return rgbToHex(rgb.r, rgb.g, rgb.b) + alphaHex\n}\n"],"mappings":"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","names":["resolve","format","pad","sub","isArray","words","_","sis","last","intersection","resolve","resolve","result","resolve","resolve","chunk","resolve","_","getType","join","basename","basename","join","readFileSync","readdirSync","join","extname","collectSourceFiles","sum","p","q","lerp"]}
|