full-utils 3.0.1 → 3.0.2
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/dist/browser.cjs +1 -1
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +1 -1
- package/dist/browser.d.ts +1 -1
- package/dist/browser.mjs +1 -1
- package/dist/browser.mjs.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -13
- package/dist/index.d.ts +13 -13
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/node.cjs +1 -1
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.cts +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/node.mjs +1 -1
- package/dist/node.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/arr/arrFuncArgs.ts","../src/arr/arrSplitPortions.ts","../src/bool/boolNormalize.ts","../src/common/wait.ts","../src/date/dateFloorMin.ts","../src/date/dateStr.ts","../src/date/datePartsSec.ts","../src/date/dateSecParts.ts","../src/ip-addr/ipStrNum.ts","../src/ip-addr/ipNumStr.ts","../src/is/isArr.ts","../src/is/isArrFilled.ts","../src/is/isBool.ts","../src/is/isDate.ts","../src/is/isEmail.ts","../src/is/isExists.ts","../src/is/isFunc.ts","../src/is/isIpAddr.ts","../src/is/isMacAddr.ts","../src/is/isNum.ts","../src/is/isNumFloat.ts","../src/is/isNumN.ts","../src/is/isNumNZ.ts","../src/is/isNumP.ts","../src/is/isNumPZ.ts","../src/is/isObj.ts","../src/is/isObjFilled.ts","../src/is/isPassword.ts","../src/is/isPhone.ts","../src/is/isStr.ts","../src/is/isStrBool.ts","../src/is/isStrFilled.ts","../src/is/isStrAscDesc.ts","../src/is/isVar.ts","../src/is/isClass.ts","../src/json/jsonStrLike.ts","../src/json/jsonParse.ts","../src/json/jsonDecode.ts","../src/json/jsonEncode.ts","../src/num/fixedDecimalToStr.ts","../src/num/fixedDecimalToNum.ts","../src/num/convertExponentialToParts.ts","../src/num/normalizeToDecimalComponents.ts","../src/num/parseToFixedDecimal.ts","../src/num/roundFixedDecimal.ts","../src/num/numNormalize.ts","../src/str/strLowerCase.ts","../src/str/strNormalCase.ts","../src/str/strNull.ts","../src/str/strPhone.ts","../src/str/strTrim.ts","../src/str/strUndefined.ts","../src/str/strNormalize.ts","../src/url/urlObj.ts"],"names":["arrFuncArgs","value","isStr","src","buf","inQuote","quoteChar","esc","depthParen","depthBracket","depthBrace","items","finalize","trimmed","i","ch","raw","isStrBool","boolNormalize","n","numNormalize","rawStr","jsonDecode","arrSplitPortions","arr","portionLength","out","isBool","isNumP","isNumNZ","isStrFilled","wait","timeout","resolve","dateFloorMin","everyMinutes","date","step","m","floored","d","dateStr","pad","year","month","day","hours","minutes","seconds","datePartsSec","parts","days","dateSecParts","total","ipStrNum","ip","p","buffer","dv","ipNumStr","num","nbuffer","ndv","output","isArr","isArrFilled","isDate","isNum","emailRegex","isEmail","isExists","isFunc","IPV4_RE","isIpAddr","v","isMacAddr","isNumFloat","isNumN","isNumPZ","isObj","isObjFilled","isPassword","minLength","maxLength","requireUppercase","requireLowercase","requireDigit","requireSpecial","isPhone","valueProcessed","normalized","isStrAscDesc","isVar","isClass","QUOTED_RE","jsonStrLike","s","allowString","pr","jsonParse","str","item","key","jsonEncode","fixedDecimalToStr","signSymbol","allDigitsString","padZeros","integerBoundary","integerText","fractionalText","fixedDecimalToNum","convertExponentialToParts","sign","exponentialString","match","coefficient","exponentText","integerPart","fractionalPart","allDigits","exponentValue","exponent","digitsToLeft","missingZeros","splitIndex","normalizeToDecimalComponents","input","absoluteValue","exponentialForm","processed","parseToFixedDecimal","integerDigits","fractionalDigits","combinedDigits","roundFixedDecimal","source","decimalPlaces","roundMode","targetPrecision","digitsToRemove","divisionFactor","remainder","halfThreshold","roundedValue","round","throwError","err","strLowerCase","strTrim","strNormalCase","parsed","strNull","formatToPhone","defaultCountry","phone","strUndefined","strNormalize","t","urlObj"],"mappings":"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","file":"index.mjs","sourcesContent":["import { \n\tisStrBool,\n\tisStr, \n\tjsonDecode,\n\tboolNormalize,\n\tnumNormalize,\n} from '../index';\n\n/**\n * A narrow union describing which quoting characters are recognized by the parser.\n *\n * @remarks\n * The parser treats both single quotes (`'`) and double quotes (`\"`) as valid string\n * delimiters. When inside a quoted segment, commas are not considered separators,\n * and typical backslash escapes are honored (e.g., `\\\"`, `\\'`, `\\\\`).\n *\n * @public\n * @since 2.0.0\n */\ntype Quote = \"'\" | '\"' | null;\n\n/**\n * Parse a human-typed string of function-like arguments into a normalized array of JS values.\n *\n * @summary\n * Splits by **top-level commas** (ignoring commas that appear inside quotes, parentheses,\n * brackets, or braces) and **coerces** each token to a sensible JavaScript type:\n * `null`, `undefined`, booleans, numbers (including `Infinity`/`-Infinity`), strings\n * (with quote stripping and unescaping), and JSON objects/arrays. Tokens that look like\n * a macro or call marker (start with `$` and end with `)`) are returned **as is**.\n *\n * @remarks\n * ### How parsing works\n * 1. **Input normalization**\n * - Non-string inputs are returned as a single-element array `[value]`.\n * - Leading/trailing whitespace is trimmed.\n * - If the entire string is wrapped in square brackets (`[...]`), the brackets are\n * removed (so the function accepts both `a,b,c` and `[a, b, c]`).\n * - Empty input (after trimming or after removing `[...]`) yields `[]`.\n *\n * 2. **Tokenization by top-level commas**\n * - The string is scanned left-to-right.\n * - The parser tracks nesting **depth** for `()`, `[]`, `{}` and whether it is\n * currently **inside quotes**. A comma only splits tokens at **depth 0** and\n * **outside quotes**.\n *\n * 3. **Per-token coercion (in this order)**\n * - **Macro / call marker**: If a token starts with `$`, contains `(`, and ends\n * with `)`, it is returned unchanged (e.g., `\"$env(PATH)\"`).\n * - **Literals**: `null` → `null`, `undefined` → `undefined`.\n * - **Booleans**: Using {@link isStrBool} + {@link boolNormalize} (e.g., `\"true\"`,\n * `\"False\"`, `\"yes\"`, `\"0\"` depending on your implementation).\n * - **Numbers**: Using {@link numNormalize}. If the result is finite, it is returned.\n * Explicit `\"Infinity\"` and `\"-Infinity\"` are also supported.\n * - **Quoted strings**: `'text'` or `\"text\"` → inner text with escapes processed\n * (`\\\\` → `\\`, `\\'` → `'`, `\\\"` → `\"`).\n * - **JSON**: If token begins with `{` and ends with `}`, or begins with `[` and\n * ends with `]`, the function attempts `jsonDecode`. On failure, the raw string\n * is returned.\n * - **Fallback**: Raw token as string.\n *\n * ### Escaping inside quotes\n * - Backslash escaping is supported while inside quotes:\n * - `\\\\` for a literal backslash\n * - `\\\"` inside double quotes\n * - `\\'` inside single quotes\n *\n * ### Non-throwing behavior\n * - The function aims to be **robust** and **non-throwing**. Invalid JSON will be\n * returned as a plain string rather than crashing.\n *\n * ### Security considerations\n * - The parser **does not** evaluate code; it only returns strings or parsed values.\n * If you plan to execute anything returned (e.g., tokens starting with `$...`),\n * do so in a sandbox with explicit allow-lists.\n *\n * ### Limitations\n * - Numerical parsing relies on {@link numNormalize}. Extremely large or high-precision\n * decimals may still be subject to JavaScript `number` precision limits unless your\n * `numNormalize` converts to a safer representation.\n * - Only basic backslash escapes are handled in quoted strings (no `\\uXXXX` decoding here).\n * - Whitespace outside quotes is trimmed from each token; internal whitespace is preserved.\n *\n * @example\n * // Basic values\n * arrFuncArgs('1, true, \"hello\"'); // => [1, true, \"hello\"]\n *\n * @example\n * // Bracket-wrapped list\n * arrFuncArgs('[1, 2, 3]'); // => [1, 2, 3]\n *\n * @example\n * // Nested structures and quoting\n * arrFuncArgs('{\"a\":1,\"b\":[2,3]}, \"te,xt\", (x,y)'); // => [ {a:1,b:[2,3]}, \"te,xt\", \"(x,y)\" ]\n *\n * @example\n * // Booleans, null/undefined, and Infinity\n * arrFuncArgs('yes, NO, null, undefined, Infinity, -Infinity');\n * // => [true, false, null, undefined, Infinity, -Infinity]\n *\n * @example\n * // Macro-like token (returned as-is)\n * arrFuncArgs('$env(PATH)'); // => [\"$env(PATH)\"]\n *\n * @example\n * // Escapes inside quotes\n * arrFuncArgs('\"He said: \\\\\"Hi\\\\\"\", \\'It\\\\\\'s ok\\', \"\\\\\\\\path\"');\n * // => ['He said: \"Hi\"', \"It's ok\", \"\\\\path\"]\n *\n * @example\n * // Empty and whitespace inputs\n * arrFuncArgs(' '); // => []\n * arrFuncArgs('[]'); // => []\n * arrFuncArgs('[ ]'); // => []\n * arrFuncArgs(' [ a , b ] '); // => [\"a\", \"b\"]\n *\n * @param value - Raw string containing comma-separated arguments.\n * If `value` is **not** a string, the function returns `[value]` unchanged.\n *\n * @returns An array of coerced values (`unknown[]`). Each item is one parsed token.\n *\n * @see isStrBool\n * @see boolNormalize\n * @see numNormalize\n * @see jsonDecode\n *\n * @public\n * @since 2.0.0\n */\nexport function arrFuncArgs(value: string): unknown[] {\n\tif (!isStr(value)) {\n\t\treturn [value];\n\t}\n\tlet src = value.trim();\n\t\n\tif (src === '') {\n\t\treturn [];\n\t}\n\tif (src.startsWith('[') && src.endsWith(']')) {\n\t\tsrc = src.slice(1, -1).trim();\n\t\t\n\t\tif (src === '') {\n\t\t\treturn [];\n\t\t}\n\t}\n\tlet buf = '',\n\t\tinQuote = false,\n\t\tquoteChar: Quote = null,\n\t\tesc = false,\n\t\tdepthParen = 0,\n\t\tdepthBracket = 0,\n\t\tdepthBrace = 0;\n\n\tconst items: string[] = [];\n\tconst finalize = () => {\n\t\tconst trimmed = buf.trim();\n\t\t\n\t\tif (trimmed !== '') {\n\t\t\titems.push(trimmed);\n\t\t}\n\t\tbuf = '';\n\t};\n\n\tfor (let i = 0; i < src.length; i++) {\n\t\tconst ch = src[i];\n\n\t\tif (inQuote) {\n\t\t\tbuf += ch;\n\n\t\t\tif (esc) { \n\t\t\t\tesc = false; \n\t\t\t\tcontinue; \n\t\t\t}\n\t\t\tif (ch === '\\\\') { \n\t\t\t\tesc = true; \n\t\t\t\tcontinue; \n\t\t\t}\n\t\t\tif (ch === quoteChar) {\n\t\t\t\tinQuote = false;\n\t\t\t\tquoteChar = null;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (ch === '\"' || ch === \"'\") {\n\t\t\tinQuote = true;\n\t\t\tquoteChar = ch as Quote;\n\t\t\tbuf += ch;\n\t\t\t\n\t\t\tcontinue;\n\t\t}\n\t\tif (ch === '(') { \n\t\t\tdepthParen++; \n\t\t\tbuf += ch; \n\n\t\t\tcontinue; \n\t\t}\n\t\tif (ch === ')') { \n\t\t\tdepthParen = Math.max(0, depthParen - 1); \n\t\t\tbuf += ch; \n\t\t\t\n\t\t\tcontinue; \n\t\t}\n\t\tif (ch === '[') { \n\t\t\tdepthBracket++; \n\t\t\tbuf += ch; \n\t\t\t\n\t\t\tcontinue; \n\t\t}\n\t\tif (ch === ']') { \n\t\t\tdepthBracket = Math.max(0, depthBracket - 1); \n\t\t\tbuf += ch; \n\t\t\t\n\t\t\tcontinue; \n\t\t}\n\t\tif (ch === '{') { \n\t\t\tdepthBrace++; \n\t\t\tbuf += ch; \n\t\t\t\n\t\t\tcontinue; \n\t\t}\n\t\tif (ch === '}') { \n\t\t\tdepthBrace = Math.max(0, depthBrace - 1); \n\t\t\tbuf += ch; \n\n\t\t\tcontinue; \n\t\t}\n\t\tif (ch === ',' && depthParen === 0 && depthBracket === 0 && depthBrace === 0) {\n\t\t\tfinalize();\n\t\t\t\n\t\t\tcontinue;\n\t\t}\n\t\tbuf += ch;\n\t}\n\tif (buf.length) {\n\t\tfinalize();\n\t}\n\treturn items.map((raw: string): unknown => {\n\t\tif (raw.startsWith('$') && raw.includes('(') && raw.endsWith(')')) {\n\t\t\treturn raw;\n\t\t}\n\t\tif (raw === 'null') {\n\t\t\treturn null;\n\t\t}\n\t\tif (raw === 'undefined') {\n\t\t\treturn undefined;\n\t\t}\n\t\tif (isStrBool(raw)) {\n\t\t\treturn boolNormalize(raw);\n\t\t}\n\t\tconst n = numNormalize(raw as any);\n\t\t\n\t\tif (Number.isFinite(n)) {\n\t\t\treturn n;\n\t\t}\t\t\n\t\tif (raw === 'Infinity') {\n\t\t\treturn Infinity;\n\t\t}\n\t\tif (raw === '-Infinity') {\n\t\t\treturn -Infinity;\n\t\t}\n\t\tconst rawStr: string = String(raw || '');\n\t\tconst hasQuotes = rawStr.length >= 2\n\t\t\t&& ((rawStr.startsWith(\"'\") && rawStr.endsWith(\"'\")) \n\t\t\t\t|| (rawStr.startsWith('\"') && rawStr.endsWith('\"')));\n\n\t\tif (hasQuotes) {\n\t\t\treturn rawStr\n\t\t\t\t.slice(1, -1)\n\t\t\t\t.replace(/\\\\\\\\/g, '\\\\')\n\t\t\t\t.replace(/\\\\'/g, \"'\")\n\t\t\t\t.replace(/\\\\\"/g, '\"');\n\t\t}\n\t\tif ((rawStr.startsWith('{') && rawStr.endsWith('}')) || (rawStr.startsWith('[') && rawStr.endsWith(']'))) {\n\t\t\ttry {\n\t\t\t\treturn jsonDecode(rawStr);\n\t\t\t} \n\t\t\tcatch {\n\t\t\t}\n\t\t}\n\t\treturn rawStr;\n\t});\n}\n","\n/**\n * Splits an input array into smaller subarrays (portions) of a given fixed size.\n *\n * @summary\n * Returns an array of chunks, where each chunk contains at most `portionLength` elements.\n * The final chunk may contain fewer elements if the input array length is not evenly divisible\n * by `portionLength`.\n *\n * @typeParam T - Type of the elements in the input array.\n *\n * @param arr - The source array to be split. It can be any readonly array (or tuple).\n * @param portionLength - The desired size of each portion. Must be a **positive integer**.\n *\n * @returns A new two-dimensional array (`T[][]`), where each inner array is one portion.\n * If `portionLength` is not a positive integer, an empty array is returned.\n *\n * @remarks\n * - This function is **non-mutating**: the original array is never modified.\n * - If `portionLength` exceeds the array length, the result will be a single chunk\n * containing the entire array.\n * - If the input array is empty, the result is an empty array.\n * - Uses `Array.prototype.slice()` internally, so the returned chunks are **shallow copies**.\n *\n * ### Performance\n * - Time complexity: **O(n)** — each element is visited exactly once.\n * - Space complexity: **O(n)** — proportional to the total number of elements copied.\n * - For extremely large arrays (millions of elements), prefer a streaming approach\n * if memory is a concern.\n *\n * ### Edge cases\n * - `portionLength <= 0` → returns `[]`.\n * - `portionLength` is not an integer (e.g. `2.5`, `NaN`) → returns `[]`.\n * - `arr.length === 0` → returns `[]`.\n * - Works correctly with frozen arrays and readonly tuples.\n *\n * @example\n * // Split an array into groups of 3\n * arrSplitPortions([1, 2, 3, 4, 5, 6, 7], 3);\n * // => [[1, 2, 3], [4, 5, 6], [7]]\n *\n * @example\n * // Portion length larger than array\n * arrSplitPortions(['a', 'b'], 5);\n * // => [['a', 'b']]\n *\n * @example\n * // Non-integer or invalid sizes\n * arrSplitPortions([1, 2, 3], 0); // => []\n * arrSplitPortions([1, 2, 3], -2); // => []\n * arrSplitPortions([1, 2, 3], NaN); // => []\n *\n * @example\n * // Works with readonly arrays\n * const input = [10, 20, 30, 40] as const;\n * const result = arrSplitPortions(input, 2);\n * // result: [[10, 20], [30, 40]]\n *\n * @category Array\n * @public\n * @since 2.0.0\n */\nexport function arrSplitPortions<T>(arr: readonly T[], portionLength: number): T[][] {\n\tif (!Number.isInteger(portionLength) || portionLength <= 0) {\n\t\treturn [];\n\t}\n\tconst out: T[][] = [];\n\tlet i = 0;\n\t\n\twhile (i < arr.length) {\n\t\tout.push(arr.slice(i, i + portionLength));\n\t\ti += portionLength;\n\t}\n\treturn out;\n}\n","import { \n\tisBool,\n\tisNumP, \n\tisNumNZ,\n\tisStrFilled,\n} from '../index';\n\n/**\n * Converts any given value into a normalized boolean (`true` / `false`).\n *\n * @summary\n * Performs **loose coercion** of different input types into a `boolean`\n * following predictable rules for numbers, strings, and actual boolean values.\n * Non-recognized values always return `false`.\n *\n * @param value - Any unknown input that should be interpreted as a boolean.\n *\n * @returns The normalized boolean result (`true` or `false`).\n *\n * @remarks\n * This function is designed to **gracefully handle** a wide variety of input forms —\n * including primitive values, numeric types, and user-typed strings (like `\"yes\"`, `\"no\"`, `\"on\"`, `\"off\"`).\n *\n * ### Conversion Rules (in order of precedence)\n * 1. **Native booleans** → returned as-is.\n * - `true` → `true`\n * - `false` → `false`\n *\n * 2. **Positive numbers** → interpreted as `true`.\n * - `isNumP(value)` check passes (typically `> 0`).\n * - Examples: `1`, `42`, `3.14` → `true`\n *\n * 3. **Zero or negative numbers** → interpreted as `false`.\n * - `isNumNZ(value)` check passes (typically `<= 0`).\n * - Examples: `0`, `-1` → `false`\n *\n * 4. **Truthy strings** → `\"true\"`, `\"1\"`, `\"yes\"`, `\"on\"` (case-insensitive)\n * - `\"TrUe\"` → `true`\n * - `\" YES \"` → `true`\n *\n * 5. **Falsy strings** → `\"false\"`, `\"0\"`, `\"no\"`, `\"off\"` (case-insensitive)\n * - `\"False\"` → `false`\n * - `\" off \"` → `false`\n *\n * 6. **Everything else** → `false`\n * - `null`, `undefined`, `NaN`, empty string, symbols, objects, arrays, etc.\n *\n * ### String Handling\n * - Strings are **trimmed** and **lower-cased** before comparison.\n * - Case and whitespace are ignored.\n * - Empty strings (`\"\"`) return `false`.\n *\n * ### Error Safety\n * - The function **never throws**.\n * - Non-primitive or unexpected types are handled safely and result in `false`.\n *\n * ### Performance\n * - Time complexity: **O(1)**.\n * - Space complexity: **O(1)**.\n *\n * ### Examples\n *\n * @example\n * // Native booleans\n * boolNormalize(true); // => true\n * boolNormalize(false); // => false\n *\n * @example\n * // Numeric values\n * boolNormalize(1); // => true\n * boolNormalize(0); // => false\n * boolNormalize(-5); // => false\n *\n * @example\n * // String values\n * boolNormalize('yes'); // => true\n * boolNormalize('No'); // => false\n * boolNormalize('TRUE'); // => true\n * boolNormalize('false'); // => false\n * boolNormalize('on'); // => true\n * boolNormalize('off'); // => false\n *\n * @example\n * // Mixed and invalid inputs\n * boolNormalize(null); // => false\n * boolNormalize(undefined); // => false\n * boolNormalize([]); // => false\n * boolNormalize({}); // => false\n * boolNormalize('maybe'); // => false\n *\n * @see isBool\n * @see isNumP\n * @see isNumNZ\n * @see isStrFilled\n *\n * @category Conversion\n * @public\n * @since 2.0.0\n */\nexport function boolNormalize(value: unknown): boolean {\n\tswitch (true) {\n\t\tcase isBool(value):\n\t\t\treturn value;\n\n\t\tcase isNumP(value):\n\t\t\treturn true;\n\n\t\tcase isNumNZ(value):\n\t\t\treturn false;\n\n\t\tcase isStrFilled(value) && [ 'true', '1', 'yes', 'on' ].includes(String(value ?? '').trim().toLowerCase()):\n\t\t\treturn true;\n\n\t\tcase isStrFilled(value) && [ 'false', '0', 'no', 'off' ].includes(String(value ?? '').trim().toLowerCase()):\n\t\t\treturn false;\n\t}\n\treturn false;\n}\n","/**\n * Waits asynchronously for the specified amount of time.\n *\n * @summary\n * A tiny promise-based delay utility that resolves after `timeout` milliseconds.\n * It wraps `setTimeout` in a `Promise`, making it convenient to use with\n * `async/await` or as part of larger promise chains.\n *\n * @param timeout - The delay duration in **milliseconds** before the promise resolves.\n * @defaultValue 0\n *\n * @returns A `Promise<void | true>` that settles after the given delay.\n *\n * @example\n * // Basic usage: pause for ~500 ms\n * await wait(500);\n * console.log('Half a second later…');\n *\n * @example\n * // Measure elapsed time\n * const started = Date.now();\n * await wait(1200);\n * const elapsed = Date.now() - started; // ~= 1200ms (subject to timer clamping and scheduling)\n *\n * @example\n * // Use inside a retry/backoff loop\n * for (let attempt = 1; attempt <= 5; attempt++) {\n * try {\n * await doWork();\n * break;\n * } catch (err) {\n * // exponential backoff between attempts\n * await wait(2 ** attempt * 100);\n * }\n * }\n *\n * @example\n * // Parallel delays (resolve when the longest finishes)\n * await Promise.all([wait(100), wait(250), wait(50)]);\n *\n * @remarks\n * - **Timing accuracy:** JavaScript timers are **best-effort** and may be delayed\n * by event-loop load, CPU throttling, tab being backgrounded, or platform-specific\n * clamping. Treat `timeout` as a *minimum* delay, not an exact scheduler.\n * - **Negative or non-finite values:** Passing `<= 0`, `NaN`, or a non-finite value\n * effectively behaves like `0` and resolves on a future macrotask tick.\n * - **Cancellation:** This helper **does not support cancellation**. If you need to\n * abort a wait, consider a variant that accepts an `AbortSignal` and clears the\n * timer when aborted.\n * - **Event loop semantics:** `setTimeout(0)` schedules a **macrotask**; it does not\n * run synchronously. Code after `await wait(0)` will execute on a subsequent turn\n * of the event loop.\n * \n * Notes:\n * - Suitable for throttling UI interactions, pacing network retries, and writing\n * deterministic tests (with caution re: flakiness).\n * - Keep delays small in performance-critical code paths; prefer debouncing or\n * requestAnimationFrame for UI-animation pacing when appropriate.\n * \n * \tComplexity:\n * - Time: **O(1)** (scheduling a single timer)\n * - Space: **O(1)** (a promise and a timer reference)\n *\n * Performance:\n * - The function allocates a single promise and a timer handle.\n * - Timer resolution is platform dependent; Node.js and browsers may clamp very\n * small delays to a minimum threshold under load.\n *\n * Security:\n * - No I/O, side effects, or data exposure. Purely schedules a future resolution.\n * \n * <b>Returns remarks</b>:\n * The internal promise resolves with the value `true`, but callers typically\n * use `await wait(...)` and ignore the value. If you need a strictly `void`\n * result, you can cast or ignore the resolution value.\n *\n * @category Utilities • Timing\n * @since 1.0.0\n * @see {@link https://developer.mozilla.org/docs/Web/API/setTimeout MDN: setTimeout}\n */\nexport async function wait(timeout: number = 0) {\n\tawait (new Promise((resolve) => setTimeout(() => resolve(true), timeout)));\n}\n","/**\n * Floors a given {@link Date} object down to the nearest time interval in minutes.\n *\n * @remarks\n * This utility function is commonly used for time bucketing, grouping logs, or\n * aligning timestamps to fixed intervals (e.g. 5-minute or 15-minute marks).\n *\n * It takes an arbitrary `Date` and returns a **new** `Date` instance (it does not\n * mutate the input) where:\n *\n * - The `minutes` value is floored down to the nearest multiple of `everyMinutes`.\n * - `seconds` and `milliseconds` are reset to `0`.\n * - The hour and day remain unchanged.\n *\n * The step is automatically clamped to the range **1 – 60 minutes** to prevent\n * invalid or nonsensical values.\n * \n * The function allocates a single new `Date` object. \n * It is safe for high-frequency use in real-time systems and event batching.\n *\n * @param everyMinutes - The step interval (in minutes) used for rounding down.\n * Must be a positive finite number. \n * Values below 1 are treated as 1, values above 60 as 60.\n *\n * @param date - The input date to be floored. \n * Defaults to the current time (`new Date()`).\n *\n * @returns A **new** `Date` instance, representing the same hour as the input,\n * but with minutes rounded down to the nearest `everyMinutes` multiple.\n *\n * @example\n * ```ts\n * // Example 1: Floor to the nearest 15-minute mark\n * const d = new Date('2025-10-18T10:43:27');\n * dateFloorMin(15, d);\n * // -> 2025-10-18T10:30:00.000Z\n * ```\n *\n * @example\n * ```ts\n * // Example 2: Using default date (current time)\n * const nowFloored = dateFloorMin(10);\n * // -> e.g. 2025-10-18T09:20:00.000Z\n * ```\n *\n * @example\n * ```ts\n * // Example 3: Clamp behavior\n * dateFloorMin(-5, new Date()); // treated as 1 minute\n * dateFloorMin(999, new Date()); // treated as 60 minutes\n * ```\n *\n * @throws Never throws — invalid step values are automatically normalized.\n *\n * @see {@link Date#setMinutes} for the underlying mutation logic.\n * @see {@link Date#getMinutes} for how minutes are extracted from a Date.\n *\n * @public\n * @category Date & Time\n * @since 2.0.0\n */\nexport function dateFloorMin(everyMinutes = 1, date = new Date()): Date {\n\tconst step = Math.min(60, Math.max(1, Math.trunc(Math.abs(everyMinutes))));\n\tconst m = date.getMinutes();\n\tconst floored = Math.floor(m / step) * step;\n\tconst d = new Date(date);\n\t\n\td.setMinutes(floored, 0, 0);\n\t\n\treturn d;\n}\n","/**\n * Formats a {@link Date} object into a human-readable timestamp string\n * using the pattern `\"YYYY-MM-DD HH:mm:ss\"`.\n *\n * @remarks\n * This function is a simple and locale-independent date formatter that always\n * outputs a **24-hour clock** timestamp with leading zeros for all numeric parts.\n * \n * It does **not** depend on the user's locale or time zone settings beyond what\n * is stored in the provided `Date` object. If you pass a `Date` constructed\n * from UTC or local time, the formatted output will reflect that same basis.\n *\n * Each date/time component (month, day, hours, minutes, seconds) is padded to\n * two digits using {@link String.padStart}, ensuring consistent width such as\n * `2025-03-07 09:04:02`.\n * \n * - The format is fixed-width and consistent — ideal for logs, filenames,\n * and database-friendly timestamps.\n * - The output is **not ISO 8601** (which uses a `'T'` separator and optional\n * timezone offset). \n * Example: ISO → `\"2025-10-18T10:43:27Z\"` \n * This function → `\"2025-10-18 10:43:27\"`.\n *\n * @param date - The date to format. Defaults to the **current system time**\n * (`new Date()`).\n *\n * @returns A formatted timestamp string in `\"YYYY-MM-DD HH:mm:ss\"` form.\n *\n * @example\n * ```ts\n * // Example 1: Specific date\n * const d = new Date('2025-10-18T10:43:27Z');\n * dateStr(d);\n * // -> \"2025-10-18 10:43:27\"\n * ```\n *\n * @example\n * ```ts\n * // Example 2: Default (current) date\n * dateStr();\n * // -> e.g. \"2025-10-18 12:07:55\"\n * ```\n *\n * @example\n * ```ts\n * // Example 3: Padding behavior\n * const d = new Date('2025-03-07T09:04:02');\n * dateStr(d);\n * // -> \"2025-03-07 09:04:02\"\n * ```\n *\n * @throws Never throws.\n *\n * @see {@link Date} for JavaScript’s native date-handling API.\n * @see {@link Intl.DateTimeFormat} for locale-aware formatting if needed.\n *\n * @public\n * @category Date & Time\n * @since 2.0.0\n */\nexport function dateStr(date = new Date()): string {\n\tconst pad = (n: number) => String(n).padStart(2, '0');\n\n\tconst year = date.getFullYear();\n\tconst month = pad(date.getMonth() + 1);\n\tconst day = pad(date.getDate());\n\n\tconst hours = pad(date.getHours());\n\tconst minutes = pad(date.getMinutes());\n\tconst seconds = pad(date.getSeconds());\n\n\treturn `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;\n}\n","import type { TimeParts } from '../index';\nimport { dateSecParts } from '../index';\n\n/**\n * Converts a partial {@link TimeParts} structure (days, hours, minutes, seconds)\n * into a total number of **seconds**.\n *\n * @remarks\n * This helper provides a simple way to normalize human-readable time components\n * into a single scalar duration in seconds. \n * It can be useful for:\n * - time-based arithmetic (e.g., adding offsets to timestamps),\n * - scheduling or delay computation,\n * - serializing durations into numeric fields (e.g., databases or APIs).\n *\n * All fields (`days`, `hours`, `minutes`, `seconds`) are **optional**; any missing\n * value defaults to `0`. The calculation uses fixed conversion factors:\n *\n * - 1 day = 86 400 seconds \n * - 1 hour = 3 600 seconds \n * - 1 minute = 60 seconds\n * \n * - Fractional or negative numbers are accepted and processed arithmetically.\n * Example: `{ minutes: 1.5 }` → `90`; `{ hours: -1 }` → `-3600`.\n * - The function performs no validation; it assumes numeric input.\n * TypeScript typing (`number`) ensures intended usage.\n *\n * @param parts - A partial object containing any subset of time fields.\n * Missing values default to zero.\n *\n * @returns The total number of seconds represented by the provided time parts.\n *\n * @example\n * ```ts\n * // Example 1: Simple conversion\n * datePartsSec({ hours: 1, minutes: 30 }); // -> 5400\n *\n * // Example 2: Full time span\n * datePartsSec({ days: 2, hours: 3, minutes: 5, seconds: 10 });\n * // -> 183910\n *\n * // Example 3: Partial / missing fields\n * datePartsSec({}); // -> 0\n * datePartsSec({ minutes: 5 }); // -> 300\n * ```\n *\n * @throws Never throws.\n *\n * @see {@link dateSecParts} — the inverse operation that expands seconds back into components.\n *\n * @public\n * @category Date & Time\n * @since 2.0.0\n */\nexport function datePartsSec(parts: TimeParts): number {\n\tconst { days = 0, hours = 0, minutes = 0, seconds = 0 } = parts;\n\n\treturn days * 86400 + hours * 3600 + minutes * 60 + seconds;\n}\n","import type { TimeParts } from '../index';\nimport { datePartsSec } from '../index';\n\n/**\n * Decomposes a total number of seconds into discrete time components:\n * **days**, **hours**, **minutes**, and **seconds**.\n *\n * @remarks\n * This is the inverse operation of {@link datePartsSec}.\n * It converts a flat duration (in seconds) into a more human-readable structure\n * suitable for display, logging, or formatting.\n *\n * The function performs integer division using {@link Math.floor} for each component\n * and ensures that the result satisfies:\n *\n * ```\n * 0 <= hours < 24 \n * 0 <= minutes < 60 \n * 0 <= seconds < 60\n * ```\n *\n * Any fractional part of the input (e.g., `12.75`) is truncated (floored) to the\n * nearest lower whole second. \n * Negative or non-finite inputs are considered invalid and will throw an error.\n * \n * - Uses only a few arithmetic operations and is **O(1)**.\n * - Safe for real-time conversions or high-frequency usage (e.g., monitoring dashboards).\n *\n * @param total - Total duration in seconds. \n * Must be a **finite, non-negative number**.\n *\n * @returns A {@link TimeParts} object with integer fields:\n * - `days`\n * - `hours`\n * - `minutes`\n * - `seconds`\n *\n * @example\n * ```ts\n * // Example 1: Basic conversion\n * dateSecParts(3661);\n * // -> { days: 0, hours: 1, minutes: 1, seconds: 1 }\n * ```\n *\n * @example\n * ```ts\n * // Example 2: Multi-day value\n * dateSecParts(90061);\n * // -> { days: 1, hours: 1, minutes: 1, seconds: 1 }\n * ```\n *\n * @example\n * ```ts\n * // Example 3: Invalid input\n * dateSecParts(-10); // throws Error(\"Invalid total seconds\")\n * dateSecParts(NaN); // throws Error(\"Invalid total seconds\")\n * ```\n *\n * @throws {Error}\n * Thrown when `total` is not a finite, non-negative number.\n *\n * @see {@link datePartsSec} — the complementary function that aggregates components into seconds.\n * @see {@link TimeParts} — the return type describing the breakdown of time.\n *\n * @public\n * @category Date & Time\n * @since 2.0.0\n */\nexport function dateSecParts(total: number): TimeParts {\n\tif (!Number.isFinite(total) || total < 0) {\n\t\tthrow new Error('Invalid total seconds');\n\t}\n\tconst days = Math.floor(total / 86400);\n\tconst hours = Math.floor((total % 86400) / 3600);\n\tconst minutes = Math.floor((total % 3600) / 60);\n\tconst seconds = total % 60;\n\t\n\treturn { days, hours, minutes, seconds };\n}\n","import { ipNumStr } from '../index';\nimport { parseIPv4 } from './parseIPv4';\n\n/**\n * Converts a dotted-decimal IPv4 address string (e.g. `\"192.168.0.1\"`)\n * into its **32-bit unsigned integer** representation.\n *\n * @remarks\n * This function performs a strict validation of the IPv4 address and encodes\n * each of its four octets into a 32-bit number using **big-endian (network byte order)**.\n *\n * The resulting number is in the range `0..4_294_967_295` (`0xFFFFFFFF`),\n * where:\n *\n * - `\"0.0.0.0\"` → `0`\n * - `\"255.255.255.255\"` → `4294967295`\n *\n * This representation is particularly useful for:\n * - performing numeric range comparisons (e.g., IP ranges, CIDR checks);\n * - storing IPv4 values compactly in binary structures or databases;\n * - bitwise operations such as masking and subnet arithmetic.\n * \n * - The conversion uses a {@link DataView} and explicit byte writes\n * to guarantee consistent big-endian behavior across platforms.\n * - The output number is safe for 32-bit unsigned arithmetic via `>>> 0`.\n * - If you need the inverse operation, see {@link numToIpAddr}.\n *\n * @param ip - The IPv4 address in dotted-quad string form.\n *\n * @returns A 32-bit **unsigned integer** representing the given IPv4 address.\n *\n * @example\n * ```ts\n * // Example 1: Simple conversion\n * ipStrNum(\"192.168.0.1\");\n * // -> 3232235521\n *\n * // Example 2: Edge values\n * ipStrNum(\"0.0.0.0\"); // -> 0\n * ipStrNum(\"255.255.255.255\"); // -> 4294967295\n * ```\n *\n * @example\n * ```ts\n * // Example 3: Invalid input\n * ipStrNum(\"192.168.1\"); // throws Error(\"Invalid IPv4 address\")\n * ipStrNum(\"256.0.0.1\"); // throws Error(\"Invalid IPv4 address\")\n * ipStrNum(\"abc.def.ghi.jkl\"); // throws Error(\"Invalid IPv4 address\")\n * ```\n *\n * @throws {Error}\n * Thrown when:\n * - The input does not contain exactly four parts separated by dots.\n * - Any octet is not an integer between 0 and 255 inclusive.\n *\n * @see {@link numToIpAddr} — converts a 32-bit integer back to an IPv4 string.\n * @see {@link parseIPv4} — similar numeric parser using bitwise operations.\n *\n * @public\n * @category Network & IP\n * @since 2.0.0\n */\nexport function ipStrNum(ip: string): number {\n\tconst parts = ip.split('.').map(p => Number(p));\n\n\tif (parts.length !== 4 || parts.some(p => !Number.isInteger(p) || p < 0 || p > 255)) {\n\t\tthrow new Error('Invalid IPv4 address');\n\t}\n\n\tconst buffer = new ArrayBuffer(4);\n\tconst dv = new DataView(buffer);\n\tlet i = 0;\n\n\twhile (i < 4) {\n\t\tdv.setUint8(i, parts[i]);\n\t\ti++;\n\t}\n\treturn dv.getUint32(0, false);\n}\n","import { \n\tisNumP,\n\tipStrNum, \n} from '../index';\n\n/**\n * Converts a 32-bit unsigned integer (numeric IPv4 representation)\n * back into its dotted-decimal string form (e.g. `\"192.168.0.1\"`).\n *\n * @remarks\n * This is the inverse of {@link ipStrNum}. \n * It interprets the input number as a **big-endian (network-byte-order)**\n * IPv4 value, extracting each of the four octets and joining them into\n * the standard dotted-quad notation.\n *\n * If the input is not a valid finite number (checked via {@link isNumP}),\n * an empty string `\"\"` is returned instead of throwing an exception.\n *\n * The resulting string always consists of **exactly four decimal octets**\n * separated by dots, with each octet in the range `0–255`.\n * \n * - Internally uses {@link DataView} to ensure consistent big-endian behavior\n * across all platforms.\n * - The output format is always normalized (no leading zeros, no spaces).\n * - For the forward direction (string → number), see {@link ipStrNum}.\n *\n * @param num - The 32-bit unsigned integer representing an IPv4 address.\n *\n * @returns A dotted-decimal IPv4 string (e.g. `\"10.0.0.1\"`), \n * or an empty string if the input is invalid.\n *\n * @example\n * ```ts\n * // Example 1: Basic conversion\n * ipNumStr(3232235521);\n * // -> \"192.168.0.1\"\n *\n * // Example 2: Edge values\n * ipNumStr(0); // -> \"0.0.0.0\"\n * ipNumStr(4294967295); // -> \"255.255.255.255\"\n * ```\n *\n * @example\n * ```ts\n * // Example 3: Invalid inputs\n * ipNumStr(NaN); // -> \"\"\n * ipNumStr(Infinity); // -> \"\"\n * ipNumStr(-5); // -> \"\"\n * ```\n *\n * @throws Never throws; invalid inputs simply return an empty string.\n *\n * @see {@link ipStrNum} — converts dotted IPv4 strings to numeric form.\n * @see {@link parseIPv4} — alternative parser using bitwise arithmetic.\n *\n * @public\n * @category Network & IP\n * @since 2.0.0\n */\nexport function ipNumStr(num: number): string {\n\tif (!isNumP(num)) {\n\t\treturn '';\n\t}\n\tconst nbuffer = new ArrayBuffer(4);\n\tconst ndv = new DataView(nbuffer);\n\n\tndv.setUint32(0, num, false);\n\n\tconst output: number[] = [];\n\tlet i = 0;\n\t\n\twhile (i < 4) {\n\t\toutput.push(ndv.getUint8(i));\n\t\ti++;\n\t}\n\treturn output.join('.');\n}\n","/**\n * Checks whether a given value is an array.\n *\n * @summary\n * A strongly typed wrapper around {@link Array.isArray}, with an enhanced TypeScript\n * type guard that asserts the value as a **readonly non-empty array** (`readonly [T, ...T[]]`).\n *\n * @typeParam T - The expected element type of the array (defaults to `unknown`).\n *\n * @param value - Any value to test.\n *\n * @returns `true` if the value is an array (of any kind), otherwise `false`.\n * The return type acts as a **type guard**, allowing TypeScript to infer that\n * `value` is a readonly array of `T` when the function returns `true`.\n *\n * @remarks\n * - Internally uses the native {@link Array.isArray} method.\n * - Works correctly across realms (e.g., iframes, worker contexts, etc.).\n * - The type guard ensures `value` is a **readonly non-empty array**, not just an empty list.\n * This provides safer downstream access patterns when empty arrays are not expected.\n * - If you need to allow empty arrays, consider changing the type to `readonly T[]`.\n *\n * ### Performance\n * - Time complexity: **O(1)** — constant time native check.\n * - Space complexity: **O(1)**.\n *\n * ### Common pitfalls\n * - `isArr([])` → `true`, even though the static type is `readonly [T, ...T[]]`.\n * TypeScript does not validate runtime emptiness; you should still check `value.length`.\n * - `isArr('abc')` → `false`\n * - `isArr({ length: 3 })` → `false`\n *\n * ### Examples\n *\n * @example\n * // Basic usage\n * isArr([1, 2, 3]); // => true\n * isArr('hello'); // => false\n * isArr({}); // => false\n *\n * @example\n * // With type inference\n * const val: unknown = [10, 20];\n * if (isArr<number>(val)) {\n * // TypeScript now knows val: readonly [number, ...number[]]\n * console.log(val[0]); // OK\n * }\n *\n * @example\n * // With mixed content\n * isArr([true, 'text', 123]); // => true\n *\n * @see Array.isArray\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isArr<T = unknown>(value: unknown): value is readonly [T, ...T[]] {\n\treturn Array.isArray(value);\n}\n","import { isArr } from '../index';\n\n\n/**\n * Checks whether a value is a **non-empty array**.\n *\n * @summary\n * A strongly-typed type guard that returns `true` only if the input value is an array\n * (via {@link isArr}) and contains at least one element (`length > 0`).\n * \n * Useful for narrowing unknown data to a **readonly non-empty tuple type**\n * (`readonly [T, ...T[]]`), which gives TypeScript safer access guarantees.\n *\n * @typeParam T - Expected element type of the array (defaults to `unknown`).\n *\n * @param value - Any value to test.\n *\n * @returns `true` if `value` is an array with at least one element; otherwise `false`.\n *\n * @remarks\n * ### Type narrowing\n * When this function returns `true`, TypeScript automatically infers that:\n * ```ts\n * value is readonly [T, ...T[]]\n * ```\n * \n * That means inside the `if` block, you can safely access `value[0]`\n * without additional checks.\n *\n * ### Behavior\n * - Delegates the array check to {@link isArr}.\n * - Works with both mutable (`T[]`) and readonly arrays (`readonly T[]`).\n * - Does **not** mutate or clone the array.\n * - Returns `false` for:\n * - Non-array values (`null`, `undefined`, `object`, `string`, etc.).\n * - Empty arrays (`[]`).\n *\n * ### Performance\n * - Time complexity: **O(1)** (constant time check).\n * - Space complexity: **O(1)**.\n *\n * ### Examples\n *\n * @example\n * // Basic usage\n * isArrFilled([1, 2, 3]); // => true\n * isArrFilled([]); // => false\n *\n * @example\n * // With type inference\n * const maybeNumbers: unknown = [10, 20];\n * if (isArrFilled<number>(maybeNumbers)) {\n * // value is now typed as: readonly [number, ...number[]]\n * console.log(maybeNumbers[0]); // OK\n * }\n *\n * @example\n * // Non-array values\n * isArrFilled('abc'); // => false\n * isArrFilled(null); // => false\n * isArrFilled(undefined); // => false\n * isArrFilled({ length: 2 }); // => false\n *\n * @see isArr\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isArrFilled<T = unknown>(value: unknown): value is readonly [ T, ...T[] ] {\n\treturn isArr(value) && value.length > 0;\n}\n","/**\n * Checks whether a given value is a boolean (`true` or `false`).\n *\n * @summary\n * A strict type guard that returns `true` only if `value` is of type `\"boolean\"`.\n * \n * This helps safely narrow unknown or mixed-type values in TypeScript code,\n * especially when working with dynamic data sources, JSON, or user input.\n *\n * @param value - Any value to check.\n *\n * @returns `true` if the value is strictly a boolean, otherwise `false`.\n *\n * @remarks\n * - Uses the built-in `typeof` operator (`typeof value === \"boolean\"`). \n * - Does **not** coerce values — only primitive `true` or `false` are accepted.\n * - Returns `false` for Boolean objects created via `new Boolean()`, because those\n * are of type `\"object\"`, not `\"boolean\"`.\n * - Designed as a **type guard**, so when it returns `true`, TypeScript will infer:\n * ```ts\n * value is boolean\n * ```\n *\n * ### Performance\n * - Time complexity: **O(1)** (constant).\n * - Space complexity: **O(1)**.\n *\n * ### Examples\n *\n * @example\n * // Basic usage\n * isBool(true); // => true\n * isBool(false); // => true\n * isBool(0); // => false\n * isBool('true'); // => false\n *\n * @example\n * // With type narrowing\n * const val: unknown = Math.random() > 0.5 ? true : 'yes';\n * if (isBool(val)) {\n * // TypeScript now knows val: boolean\n * console.log(val ? 'OK' : 'NO');\n * }\n *\n * @example\n * // Boolean object is not accepted\n * isBool(new Boolean(true)); // => false\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isBool(value: unknown): value is boolean {\n\treturn typeof value === 'boolean';\n}\n","import { \n\tisStr,\n\tisNum, \n} from '../index';\n\n/**\n * Checks whether a value represents a **valid JavaScript date**.\n *\n * @summary\n * Returns `true` if the given value is either:\n * - an actual `Date` instance with a valid timestamp, or\n * - a string or number that can be successfully parsed by the JavaScript `Date` constructor.\n *\n * Returns `false` for invalid dates (`Invalid Date`), empty strings, `NaN`, or non-date types.\n *\n * @param value - Any value to test (can be a `Date`, string, number, or other type).\n *\n * @returns `true` if the value can be interpreted as a valid date, otherwise `false`.\n *\n * @remarks\n * ### Validation logic\n * 1. **If `value` is a `Date` instance:** \n * Checks `!Number.isNaN(value.getTime())` — ensures it’s a real date, not an invalid one.\n * ```ts\n * isDate(new Date('invalid')); // false\n * ```\n *\n * 2. **If `value` is a string or number:** \n * Attempts to construct a new `Date(value)`. \n * Returns `true` only if the resulting date’s timestamp is finite (not `NaN`).\n *\n * 3. **Otherwise:** \n * Returns `false`.\n *\n * ### What counts as \"valid\"\n * - OK: `\"2024-12-31\"`, `\"2024-12-31T23:59:59Z\"`, `1728000000000`, `new Date()`\n * - BAD: `\"abc\"`, `NaN`, `{}`, `null`, `undefined`, `new Date('invalid')`\n *\n * ### Type safety\n * - This is **not** a strict type guard (it doesn’t narrow to `Date`), \n * but you can pair it with a cast when `true`:\n * ```ts\n * if (isDate(v)) {\n * const d = new Date(v); // guaranteed valid\n * }\n * ```\n *\n * ### Performance\n * - Time complexity: **O(1)** \n * (`Date` construction and timestamp check are constant-time operations).\n * - Space complexity: **O(1)**.\n *\n * ### Examples\n *\n * @example\n * // Valid Date instances\n * isDate(new Date()); // => true\n * isDate(new Date('2024-05-01')); // => true\n *\n * @example\n * // From strings or timestamps\n * isDate('2025-01-01T00:00:00Z'); // => true\n * isDate(1700000000000); // => true\n * isDate('not-a-date'); // => false\n *\n * @example\n * // Invalid cases\n * isDate({}); // => false\n * isDate([]); // => false\n * isDate(''); // => false\n * isDate(new Date('invalid')); // => false\n *\n * @see isStr\n * @see isNum\n * @see Date\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isDate(value: unknown): boolean {\n\tif (value instanceof Date) {\n\t\treturn !Number.isNaN(value.getTime());\n\t}\n\tif (isStr(value) || isNum(value)) {\n\t\tconst d = new Date(value as any);\n\n\t\treturn !Number.isNaN(d.getTime());\n\t}\n\treturn false;\n}\n","import { isStrFilled } from '../index';\n\nconst emailRegex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z]{2,})+$/;\n\n/**\n * Checks whether a given value is a **valid email address**.\n *\n * @summary\n * Validates that the input is a non-empty string and matches a simplified but\n * practical email pattern according to RFC 5322-compatible syntax rules.\n *\n * @param value - Any value to test (string or unknown).\n *\n * @returns `true` if the value is a non-empty string that looks like a valid email, \n * otherwise `false`.\n *\n * @remarks\n * ### Validation process\n * 1. Ensures the input is a **non-empty string** via {@link isStrFilled}.\n * 2. Tests the value against a precompiled **regular expression**:\n * ```\n * /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+\n * @[a-zA-Z0-9]\n * (?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\n * (?:\\.[a-zA-Z]{2,})+$/\n * ```\n * This allows standard ASCII characters in the local part and enforces:\n * - at least one `@` separator \n * - valid domain and subdomain segments \n * - a top-level domain of at least two letters.\n *\n * ### Behavior notes\n * - Returns `false` for empty strings, `null`, `undefined`, or non-string inputs.\n * - Does **not** perform DNS or MX record validation — only syntactic matching.\n * - Intended for lightweight client-side or structural checks.\n * - If you need full compliance with RFC 6531 (Unicode / IDN), normalize the address first.\n *\n * ### Performance\n * - Time complexity: **O(n)** — proportional to input length.\n * - Space complexity: **O(1)**.\n * - The compiled regex is cached and reused for efficiency.\n *\n * ### Examples\n *\n * @example\n * // Valid emails\n * isEmail('user@example.com'); // => true\n * isEmail('john.doe+alias@mail.co.uk'); // => true\n *\n * @example\n * // Invalid formats\n * isEmail(''); // => false\n * isEmail('user@'); // => false\n * isEmail('@example.com'); // => false\n * isEmail('user@@example.com'); // => false\n * isEmail('user example@domain.com'); // => false\n *\n * @example\n * // Non-string inputs\n * isEmail(null); // => false\n * isEmail(undefined); // => false\n * isEmail(12345); // => false\n *\n * @see isStrFilled\n *\n * @category Validation\n * @public\n * @since 2.0.0\n */\nexport function isEmail(value: unknown): value is string {\n\tif (!isStrFilled(value)) {\n\t\treturn false;\n\t}\n\treturn emailRegex.test(value);\n}\n","/**\n * Checks whether a value **exists** — i.e. is neither `null` nor `undefined`.\n *\n * @summary\n * A minimal and strongly typed utility that acts as a **type guard**\n * to filter out `null` and `undefined` values in TypeScript. \n * It is especially useful in array filters and conditional checks\n * where you need to ensure a value is \"present\".\n *\n * @typeParam T - The original type of the tested value.\n *\n * @param value - Any value that may be `null` or `undefined`.\n *\n * @returns `true` if `value` is not `null` and not `undefined`, otherwise `false`.\n *\n * @remarks\n * ### Type narrowing\n * When this function returns `true`, TypeScript automatically infers:\n * ```ts\n * value is T\n * ```\n * \n * That means inside the `if` block (or after using `Array.filter(isExists)`),\n * the compiler knows the value cannot be `null` or `undefined`.\n *\n * ### Behavior\n * - Returns `false` for `null` and `undefined`.\n * - Returns `true` for any other type — including `false`, `0`, `''`, `NaN`, empty arrays, etc.\n * - The check is **strict** (`!==`) — no type coercion occurs.\n *\n * ### Typical use cases\n * - Filtering arrays that may contain `null` or `undefined`.\n * - Guarding optional values before access.\n * - Simplifying type-safe checks in functional chains.\n *\n * ### Performance\n * - Time complexity: **O(1)**\n * - Space complexity: **O(1)**\n *\n * ### Examples\n *\n * @example\n * // Basic checks\n * isExists(null); // => false\n * isExists(undefined); // => false\n * isExists(0); // => true\n * isExists(''); // => true\n * isExists(false); // => true\n *\n * @example\n * // With TypeScript narrowing\n * const val: string | null | undefined = getValue();\n * if (isExists(val)) {\n * // val is now guaranteed to be a string\n * console.log(val.toUpperCase());\n * }\n *\n * @example\n * // Filtering nullable arrays\n * const arr = [1, null, 2, undefined, 3];\n * const clean = arr.filter(isExists);\n * // clean: number[] => [1, 2, 3]\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isExists<T>(value: T | null | undefined): value is T {\n\treturn value !== null && value !== undefined;\n}\n","/**\n * Checks whether a given value is a **function**.\n *\n * @summary\n * A strict type guard that returns `true` only if `value` is a callable function. \n * It works with regular functions, arrow functions, async functions, class constructors,\n * and built-in functions like `setTimeout`.\n *\n * @typeParam T - The expected function type to narrow to (defaults to the base `Function` type).\n *\n * @param value - Any value to check.\n *\n * @returns `true` if the value is of type `\"function\"`, otherwise `false`.\n *\n * @remarks\n * ### Type narrowing\n * When this function returns `true`, TypeScript infers that:\n * ```ts\n * value is T\n * ```\n * \n * This allows safe calling of the function or using its specific signature.\n *\n * ### Behavior\n * - Returns `true` for:\n * - Normal functions: `function test() {}`\n * - Arrow functions: `() => {}`\n * - Async functions: `async () => {}`\n * - Generator functions: `function* gen() {}`\n * - Class constructors (typeof `MyClass`).\n * - Returns `false` for:\n * - Non-callable objects or primitives.\n * - Function-like objects that aren't real functions (e.g., `{ call() {} }`).\n *\n * ### Performance\n * - Time complexity: **O(1)**\n * - Space complexity: **O(1)**\n *\n * ### Examples\n *\n * @example\n * // Basic usage\n * isFunc(() => {}); // => true\n * isFunc(function test() {}); // => true\n * isFunc(class A {}); // => true\n * isFunc(123); // => false\n * isFunc({}); // => false\n *\n * @example\n * // Type narrowing\n * const fn: unknown = () => 'ok';\n * if (isFunc<() => string>(fn)) {\n * const result = fn(); // result: string\n * }\n *\n * @example\n * // Class constructors are also \"functions\"\n * class MyClass {}\n * isFunc(MyClass); // => true\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isFunc<T extends Function = Function>(value: unknown): value is T {\n\treturn typeof value === 'function';\n}\n","import { isStr } from '../index';\n\nconst IPV4_RE = /^(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$/;\n\n/**\n * Checks whether a given value is a **valid IPv4 address**.\n *\n * @summary\n * Validates that the input is a string containing four octets (e.g. `\"192.168.0.1\"`),\n * where each octet is a number between `0` and `255`, separated by dots.\n *\n * @param value - Any value to test (string or unknown).\n *\n * @returns `true` if the value is a syntactically valid IPv4 address, otherwise `false`.\n *\n * @remarks\n * ### Validation steps\n * 1. Ensures the input is a string via {@link isStr}.\n * 2. Trims leading and trailing whitespace.\n * 3. Tests the cleaned string against a strict regular expression for IPv4 format:\n * ```\n * /^(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.\n * (25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.\n * (25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.\n * (25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$/\n * ```\n * Each group allows:\n * - `0–9`, `00–99`, `100–199`, `200–249`, `250–255`\n *\n * ### Behavior notes\n * - Returns `false` for non-strings, empty strings, or malformed IPs.\n * - Does **not** support IPv6 (use a separate validator for that).\n * - Does **not** perform CIDR or subnet validation — only syntax checking.\n * - Leading zeros are allowed (e.g. `\"010.000.000.001\"` is accepted, as per regex).\n *\n * ### Performance\n * - Time complexity: **O(1)** (fixed regex evaluation).\n * - Space complexity: **O(1)**.\n *\n * ### Examples\n *\n * @example\n * // Valid IPv4 addresses\n * isIpAddr('192.168.0.1'); // => true\n * isIpAddr('8.8.8.8'); // => true\n * isIpAddr('0.0.0.0'); // => true\n * isIpAddr('255.255.255.255'); // => true\n *\n * @example\n * // Invalid IPv4 strings\n * isIpAddr('256.0.0.1'); // => false (octet > 255)\n * isIpAddr('192.168.0'); // => false (missing octet)\n * isIpAddr('192.168.0.1.5'); // => false (too many octets)\n * isIpAddr('192.168.0.A'); // => false (non-numeric)\n * isIpAddr('192,168,0,1'); // => false (wrong separator)\n *\n * @example\n * // Non-string inputs\n * isIpAddr(12345); // => false\n * isIpAddr(null); // => false\n * isIpAddr(undefined); // => false\n *\n * @see isStr\n *\n * @category Validation\n * @public\n * @since 2.0.0\n */\nexport function isIpAddr(value: unknown): value is string {\n\tif (!isStr(value)) {\n\t\treturn false;\n\t}\n\tconst v = value.trim();\n\t\n\treturn IPV4_RE.test(v);\n}\n","import { isStr } from '../index';\n\n/**\n * Checks whether a given value is a **valid MAC address**.\n *\n * @summary\n * Validates that the input is a string formatted as a standard 6-octet\n * MAC (Media Access Control) address, consisting of 12 hexadecimal digits\n * separated by either colons (`:`) or hyphens (`-`).\n *\n * @param value - Any value to test (typically a string from user input or network data).\n *\n * @returns `true` if the value matches the MAC address pattern, otherwise `false`.\n *\n * @remarks\n * ### Accepted formats\n * - `00:1A:2B:3C:4D:5E`\n * - `00-1A-2B-3C-4D-5E`\n * - Both uppercase and lowercase hexadecimal digits are allowed.\n * - Mixed separators (e.g., `\"00:1A-2B:3C-4D:5E\"`) are **not** accepted.\n *\n * ### Validation logic\n * 1. Confirms that `value` is a string via {@link isStr}.\n * 2. Uses the following regular expression:\n * ```\n * /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/\n * ```\n * which enforces:\n * - Exactly 6 byte segments (`xx:xx:xx:xx:xx:xx` or `xx-xx-xx-xx-xx-xx`)\n * - Each segment: two hexadecimal digits (`0–9`, `A–F`, `a–f`)\n * - A consistent separator (`:` or `-`)\n *\n * ### Behavior notes\n * - Returns `false` for empty strings, non-strings, or malformed addresses.\n * - Does **not** support 8-octet EUI-64 or Cisco short 3-octet formats.\n * - Does **not** check for broadcast or multicast address semantics — only syntax.\n *\n * ### Performance\n * - Time complexity: **O(1)** (fixed regex match)\n * - Space complexity: **O(1)** (no allocations beyond regex)\n *\n * ### Examples\n *\n * @example\n * // Valid MAC addresses\n * isMacAddr('00:1A:2B:3C:4D:5E'); // => true\n * isMacAddr('AA-BB-CC-DD-EE-FF'); // => true\n * isMacAddr('ff:ff:ff:ff:ff:ff'); // => true\n *\n * @example\n * // Invalid MAC addresses\n * isMacAddr('00:1A:2B:3C:4D'); // => false (too short)\n * isMacAddr('00:1A:2B:3C:4D:5E:7F'); // => false (too long)\n * isMacAddr('00:1A:2B:3C:4D:ZZ'); // => false (invalid hex)\n * isMacAddr('001A.2B3C.4D5E'); // => false (wrong format)\n * isMacAddr(''); // => false\n *\n * @example\n * // Non-string values\n * isMacAddr(null); // => false\n * isMacAddr(undefined); // => false\n * isMacAddr(123456); // => false\n *\n * @see isStr\n * @see isIp\n *\n * @category Validation\n * @public\n * @since 2.0.0\n */\nexport function isMacAddr(value: unknown): value is string {\n\treturn isStr(value) && /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/.test(value);\n}\n","/**\n * Checks whether a given value is a **finite number**.\n *\n * @summary\n * A strict type guard that returns `true` only if `value` is of type `\"number\"`\n * and is a finite numeric value (not `NaN`, `Infinity`, or `-Infinity`).\n *\n * @param value - Any value to check.\n *\n * @returns `true` if the value is a finite number, otherwise `false`.\n *\n * @remarks\n * ### Behavior\n * - Uses the built-in `typeof` operator to ensure the value is a primitive number.\n * - Rejects special non-finite numeric values:\n * - `NaN`\n * - `Infinity`\n * - `-Infinity`\n * - Does **not** coerce strings — `\"123\"` returns `false`.\n * - Works only with **number primitives**, not `Number` objects (`new Number(5)` returns `false`).\n *\n * ### Type narrowing\n * When this function returns `true`, TypeScript automatically infers:\n * ```ts\n * value is number\n * ```\n * allowing you to use numeric operators and arithmetic safely.\n *\n * ### Comparison with related checks\n * | Function | Accepts | Rejects |\n * |----------------|---------------------------------|--------------------------------|\n * | `isNum` | finite numbers only | `NaN`, `Infinity`, non-numbers |\n * | `isNumP` | positive finite numbers | `0`, negatives, `NaN` |\n * | `isNumNZ` | zero or negative finite numbers | positives, `NaN` |\n *\n * ### Performance\n * - Time complexity: **O(1)**\n * - Space complexity: **O(1)**\n *\n * ### Examples\n *\n * @example\n * // Valid finite numbers\n * isNum(42); // => true\n * isNum(0); // => true\n * isNum(-3.14); // => true\n *\n * @example\n * // Invalid numeric values\n * isNum(NaN); // => false\n * isNum(Infinity); // => false\n * isNum(-Infinity); // => false\n *\n * @example\n * // Non-number inputs\n * isNum('123'); // => false\n * isNum(true); // => false\n * isNum(null); // => false\n * isNum(undefined); // => false\n *\n * @example\n * // TypeScript narrowing\n * const x: unknown = 100;\n * if (isNum(x)) {\n * console.log(x.toFixed(2)); // OK — x is number\n * }\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isNum(value: unknown): value is number {\n\treturn (typeof value === 'number') && Number.isFinite(value);\n}\n","import { isNum } from '../index';\n\n/**\n * Checks whether a given value is a **finite non-integer (floating-point) number**.\n *\n * @summary\n * Returns `true` if the value is a finite number and **has a fractional part**\n * (i.e. not an integer). \n * Acts as a strict type guard for float-like numeric values.\n *\n * @param value - Any value to test.\n *\n * @returns `true` if the value is a finite, non-integer number; otherwise `false`.\n *\n * @remarks\n * ### Behavior\n * - First verifies that the value is a finite number via {@link isNum}.\n * - Then ensures it is **not** an integer using `!Number.isInteger(value)`.\n * - Rejects all non-numeric, `NaN`, or infinite values.\n *\n * ### Comparison with related checks\n * | Function | Matches | Rejects |\n * |----------------|--------------------------------|------------------------------------|\n * | `isNum` | any finite number | `NaN`, `Infinity`, `-Infinity` |\n * | `isNumFloat` | finite numbers **with fraction** | integers, `NaN`, non-numbers |\n * | `isNumInt` | finite **integers** only | floats, `NaN`, non-numbers |\n *\n * ### Performance\n * - Time complexity: **O(1)** \n * - Space complexity: **O(1)**\n *\n * ### Examples\n *\n * @example\n * // Valid floats\n * isNumFloat(3.14); // => true\n * isNumFloat(-0.001); // => true\n * isNumFloat(1 / 3); // => true\n *\n * @example\n * // Integers\n * isNumFloat(0); // => false\n * isNumFloat(42); // => false\n * isNumFloat(-7); // => false\n *\n * @example\n * // Invalid or non-number values\n * isNumFloat(NaN); // => false\n * isNumFloat(Infinity); // => false\n * isNumFloat('3.14'); // => false\n * isNumFloat(null); // => false\n *\n * @example\n * // Type narrowing\n * const val: unknown = 12.5;\n * if (isNumFloat(val)) {\n * const n = val * 2; // val is number\n * }\n *\n * @see isNum\n * @see Number.isInteger\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isNumFloat(value: unknown): value is number {\n\treturn isNum(value) && !Number.isInteger(value);\n}\n","import { isNum } from '../index';\n\n/**\n * Checks whether a given value is a **negative finite number**.\n *\n * @summary\n * A strict type guard that returns `true` only if the input is a finite number\n * and its value is **less than 0**. \n * Useful for safely detecting negative numeric values without coercion.\n *\n * @param value - Any value to test.\n *\n * @returns `true` if the value is a finite number less than zero, otherwise `false`.\n *\n * @remarks\n * ### Behavior\n * - Relies on {@link isNum} to ensure the value is a finite number (not `NaN`, `Infinity`, etc.).\n * - Then checks `value < 0`.\n * - Returns `false` for zero, positive numbers, and all non-numeric types.\n *\n * ### Comparison with related checks\n * | Function | Description | Condition |\n * |--------------|----------------------------------------|-----------------------------|\n * | `isNum` | Any finite number | `Number.isFinite(value)` |\n * | `isNumP` | Positive numbers only | `value > 0` |\n * | `isNumN` | Negative numbers only | `value < 0` |\n * | `isNumNZ` | Negative or zero numbers | `value <= 0` |\n * | `isNumFloat` | Finite non-integer (fractional) numbers | `!Number.isInteger(value)` |\n *\n * ### Performance\n * - Time complexity: **O(1)** \n * - Space complexity: **O(1)**\n *\n * ### Examples\n *\n * @example\n * // Negative numbers\n * isNumN(-1); // => true\n * isNumN(-3.14); // => true\n * isNumN(-0.0001); // => true\n *\n * @example\n * // Non-negative numbers\n * isNumN(0); // => false\n * isNumN(1); // => false\n * isNumN(42); // => false\n *\n * @example\n * // Invalid values\n * isNumN(NaN); // => false\n * isNumN('-5'); // => false\n * isNumN(null); // => false\n * isNumN(undefined); // => false\n *\n * @example\n * // Type narrowing\n * const val: unknown = -12;\n * if (isNumN(val)) {\n * const abs = Math.abs(val); // val is number\n * }\n *\n * @see isNum\n * @see isNumP\n * @see isNumNZ\n * @see isNumFloat\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isNumN(value: unknown): value is number {\n\treturn isNum(value) && value < 0;\n}\n","import { isNum } from '../index';\n\n/**\n * Checks whether a given value is a **finite number that is less than or equal to zero**.\n *\n * @summary\n * A strict type guard that returns `true` if the input is a finite number and\n * its value is **negative or zero**. \n * Commonly used to identify non-positive numeric values.\n *\n * @param value - Any value to test.\n *\n * @returns `true` if the value is a finite number less than or equal to zero; otherwise `false`.\n *\n * @remarks\n * ### Behavior\n * - Uses {@link isNum} to ensure the input is a finite number (rejects `NaN`, `Infinity`, etc.).\n * - Then checks the condition `value <= 0`.\n * - Returns `false` for all positive numbers and non-numeric values.\n *\n * ### Comparison with related checks\n * | Function | Description | Condition |\n * |--------------|-----------------------------------|----------------|\n * | `isNum` | Any finite number | — |\n * | `isNumP` | Positive numbers only | `value > 0` |\n * | `isNumN` | Negative numbers only | `value < 0` |\n * | `isNumNZ` | Negative **or zero** numbers | `value <= 0` |\n * | `isNumFloat` | Finite non-integer (fractional) | `!Number.isInteger(value)` |\n *\n * ### Performance\n * - Time complexity: **O(1)** \n * - Space complexity: **O(1)**\n *\n * ### Examples\n *\n * @example\n * // Negative and zero values\n * isNumNZ(-1); // => true\n * isNumNZ(-0.5); // => true\n * isNumNZ(0); // => true\n *\n * @example\n * // Positive values\n * isNumNZ(0.0001); // => false\n * isNumNZ(5); // => false\n *\n * @example\n * // Invalid or non-numeric inputs\n * isNumNZ('0'); // => false\n * isNumNZ(NaN); // => false\n * isNumNZ(Infinity); // => false\n * isNumNZ(null); // => false\n *\n * @example\n * // Type narrowing\n * const x: unknown = -10;\n * if (isNumNZ(x)) {\n * console.log(x.toFixed(2)); // x is number\n * }\n *\n * @see isNum\n * @see isNumP\n * @see isNumN\n * @see isNumFloat\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isNumNZ(value: unknown): value is number {\n\treturn isNum(value) && value <= 0;\n}\n","import { isNum } from '../index';\n\n/**\n * Checks whether a given value is a **positive finite number**.\n *\n * @summary\n * A strict type guard that returns `true` only if the input is a finite number\n * greater than zero (`> 0`). \n * Useful for safely validating numeric values that must be positive — such as\n * counters, IDs, amounts, or dimensions.\n *\n * @param value - Any value to test.\n *\n * @returns `true` if the value is a finite positive number, otherwise `false`.\n *\n * @remarks\n * ### Behavior\n * - Uses {@link isNum} to ensure the input is a finite number (`NaN`, `Infinity`, and `-Infinity` are rejected).\n * - Returns `true` only when `value > 0`.\n * - Returns `false` for zero, negative, or non-numeric values.\n *\n * ### Comparison with related checks\n * | Function | Description | Condition |\n * |--------------|-----------------------------------|----------------------------|\n * | `isNum` | Any finite number | — |\n * | `isNumP` | Positive numbers only | `value > 0` |\n * | `isNumN` | Negative numbers only | `value < 0` |\n * | `isNumNZ` | Negative **or zero** numbers | `value <= 0` |\n * | `isNumFloat` | Finite non-integer (fractional) | `!Number.isInteger(value)` |\n *\n * ### Performance\n * - Time complexity: **O(1)** \n * - Space complexity: **O(1)**\n *\n * ### Examples\n *\n * @example\n * // Positive values\n * isNumP(1); // => true\n * isNumP(3.14); // => true\n * isNumP(0.00001); // => true\n *\n * @example\n * // Zero and negatives\n * isNumP(0); // => false\n * isNumP(-1); // => false\n * isNumP(-0.5); // => false\n *\n * @example\n * // Invalid or non-numeric inputs\n * isNumP('5'); // => false\n * isNumP(NaN); // => false\n * isNumP(Infinity); // => false\n * isNumP(null); // => false\n *\n * @example\n * // Type narrowing\n * const x: unknown = 12;\n * if (isNumP(x)) {\n * console.log(x.toFixed(1)); // x is number\n * }\n *\n * @see isNum\n * @see isNumN\n * @see isNumNZ\n * @see isNumFloat\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isNumP(value: unknown): value is number {\n\treturn isNum(value) && value > 0;\n}\n","import { isNum } from '../index';\n\n/**\n * Checks whether a given value is a **finite number greater than or equal to zero**.\n *\n * @summary\n * A strict type guard that returns `true` if the input is a finite number\n * and its value is **non-negative** (`≥ 0`). \n * Useful for safely validating values such as counters, sizes, durations,\n * and other quantities that cannot be negative.\n *\n * @param value - Any value to test.\n *\n * @returns `true` if the value is a finite number greater than or equal to zero; otherwise `false`.\n *\n * @remarks\n * ### Behavior\n * - Uses {@link isNum} to ensure the input is a finite number (`NaN`, `Infinity`, `-Infinity` are rejected).\n * - Returns `true` when `value >= 0`.\n * - Returns `false` for negative numbers or non-numeric inputs.\n *\n * ### Comparison with related checks\n * | Function | Description | Condition |\n * |--------------|----------------------------------|----------------------------|\n * | `isNum` | Any finite number | — |\n * | `isNumP` | Positive numbers only | `value > 0` |\n * | `isNumPZ` | Non-negative numbers (`≥ 0`) | `value >= 0` |\n * | `isNumN` | Negative numbers only | `value < 0` |\n * | `isNumNZ` | Negative or zero numbers | `value <= 0` |\n * | `isNumFloat` | Finite non-integer numbers | `!Number.isInteger(value)` |\n *\n * ### Performance\n * - Time complexity: **O(1)** \n * - Space complexity: **O(1)**\n *\n * ### Examples\n *\n * @example\n * // Non-negative numbers\n * isNumPZ(0); // => true\n * isNumPZ(5); // => true\n * isNumPZ(3.14); // => true\n *\n * @example\n * // Negative numbers\n * isNumPZ(-1); // => false\n * isNumPZ(-0.1); // => false\n *\n * @example\n * // Invalid or non-numeric inputs\n * isNumPZ('10'); // => false\n * isNumPZ(NaN); // => false\n * isNumPZ(Infinity); // => false\n * isNumPZ(null); // => false\n *\n * @example\n * // Type narrowing\n * const val: unknown = 7;\n * if (isNumPZ(val)) {\n * console.log(Math.sqrt(val)); // val is number\n * }\n *\n * @see isNum\n * @see isNumP\n * @see isNumN\n * @see isNumNZ\n * @see isNumFloat\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isNumPZ(value: unknown): value is number {\n\treturn isNum(value) && value >= 0;\n}\n","/**\n * Checks whether a given value is a **plain object** (i.e. `{}`), not `null`, not an array, and not a class instance.\n *\n * @summary\n * A strict type guard that returns `true` only if the input is a plain object\n * created using an object literal (`{}`) or `Object.create(null)`. \n * Excludes arrays, functions, `null`, and instances of custom classes.\n *\n * @param value - Any value to test.\n *\n * @returns `true` if the value is a non-null, non-array plain object; otherwise `false`.\n *\n * @remarks\n * ### Behavior\n * The check ensures all of the following:\n * 1. `typeof value === \"object\"` — confirms the value is object-like.\n * 2. `value !== null` — excludes `null`, since `typeof null === \"object\"`.\n * 3. `Object.prototype.toString.call(value) === \"[object Object]\"` — filters out built-ins like `Map`, `Set`, `Date`, etc.\n * 4. `!Array.isArray(value)` — ensures arrays are excluded.\n *\n * ### What counts as a \"plain object\"\n * `{}`, `{ a: 1 }`, `Object.create(null)` \n * `[]`, `new Date()`, `new Map()`, `null`, class instances.\n *\n * ### Comparison with related concepts\n * | Example value | Result | Explanation |\n * |--------------------------|---------|----------------------------------|\n * | `{}` | true | Plain object |\n * | `Object.create(null)` | true | No prototype but still object |\n * | `[]` | false | Array excluded |\n * | `null` | false | Explicitly filtered |\n * | `new Date()` | false | Built-in class instance |\n * | `class A {}; new A()` | false | Custom class instance |\n *\n * ### Type narrowing\n * When this function returns `true`, TypeScript infers:\n * ```ts\n * value is Record<string, unknown>\n * ```\n * allowing safe property access and iteration.\n *\n * ### Performance\n * - Time complexity: **O(1)**\n * - Space complexity: **O(1)**\n *\n * ### Examples\n *\n * @example\n * // Plain objects\n * isObj({}); // => true\n * isObj({ key: 'value' }); // => true\n * isObj(Object.create(null)); // => true\n *\n * @example\n * // Non-objects or special cases\n * isObj(null); // => false\n * isObj([]); // => false\n * isObj(new Date()); // => false\n * isObj(new Map()); // => false\n * isObj(() => {}); // => false\n *\n * @example\n * // Type narrowing\n * const val: unknown = { x: 1 };\n * if (isObj(val)) {\n * console.log(val.x); // safe: val is Record<string, unknown>\n * }\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isObj(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === 'object' \n\t\t&& value !== null \n\t\t&& Object.prototype.toString.call(value) === '[object Object]'\n\t\t&& !Array.isArray(value);\n}\n","import { isObj } from '../index';\n\n/**\n * Checks whether a given value is a **non-empty plain object**.\n *\n * @summary\n * A strict type guard that returns `true` only if the input is a plain object\n * (validated by {@link isObj}) **and** has at least one own enumerable key. \n * In other words, it must be an object literal like `{ a: 1 }`, not `{}`.\n *\n * @param value - Any value to test.\n *\n * @returns `true` if the value is a plain object with at least one own property; otherwise `false`.\n *\n * @remarks\n * ### Behavior\n * - Uses {@link isObj} to verify the value is a plain object (not `null`, not an array, not a class instance).\n * - Calls `Object.keys(value).length > 0` to ensure the object has one or more keys.\n * - Returns `false` for empty objects (`{}`), arrays, functions, `null`, and other non-object types.\n *\n * ### Comparison with related checks\n * | Function | Description | Example |\n * |------------------|---------------------------------------|----------------------|\n * | `isObj` | Checks if value is a plain object | `{}` true / `[]` false |\n * | `isObjFilled` | Checks if plain object is **non-empty** | `{a: 1}` true / `{}` false |\n * | `isArrFilled` | Checks if array is non-empty | `[1]` true / `[]` false |\n * | `isStrFilled` | Checks if string is non-empty | `'a'` true / `''` false |\n *\n * ### Type narrowing\n * When this function returns `true`, TypeScript infers:\n * ```ts\n * value is Record<string, unknown>\n * ```\n * allowing safe property access and iteration.\n *\n * ### Performance\n * - Time complexity: **O(n)** — proportional to the number of object keys.\n * - Space complexity: **O(1)**.\n *\n * ### Examples\n *\n * @example\n * // Non-empty plain objects\n * isObjFilled({ a: 1 }); // => true\n * isObjFilled({ key: null }); // => true\n * isObjFilled({ nested: {} }); // => true\n *\n * @example\n * // Empty or invalid objects\n * isObjFilled({}); // => false\n * isObjFilled([]); // => false\n * isObjFilled(null); // => false\n * isObjFilled(new Date()); // => false\n *\n * @example\n * // Type narrowing\n * const data: unknown = { x: 5 };\n * if (isObjFilled(data)) {\n * console.log(Object.keys(data)); // safe\n * }\n *\n * @see isObj\n * @see isArrFilled\n * @see isStrFilled\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isObjFilled(value: unknown): value is Record<string, unknown> {\n\treturn isObj(value) && Object.keys(value).length > 0;\n}\n","import type { PasswordOptions } from '../index';\nimport { isStr } from '../index';\n\n/**\n * Validates whether a string meets configurable **password strength requirements**.\n *\n * @summary\n * A flexible password validation helper that checks for length, uppercase and lowercase letters,\n * digits, and special characters. \n * All rules are configurable through the optional {@link PasswordOptions} parameter.\n *\n * @param value - The value to validate as a password.\n * @param options - Optional validation rules (see {@link PasswordOptions}). \n * Defaults ensure strong password requirements:\n * ```ts\n * {\n * minLength: 8,\n * maxLength: 256,\n * requireUppercase: true,\n * requireLowercase: true,\n * requireDigit: true,\n * requireSpecial: true\n * }\n * ```\n *\n * @returns `true` if the value is a valid string matching all configured requirements, otherwise `false`.\n *\n * @remarks\n * ### Behavior\n * 1. Ensures `value` is a string using {@link isStr}.\n * 2. Enforces **length limits** (`minLength` ≤ length ≤ `maxLength`).\n * 3. Optionally checks for:\n * - Uppercase characters (Latin or Cyrillic): `/[A-ZА-Я]/`\n * - Lowercase characters (Latin or Cyrillic): `/[a-zа-я]/`\n * - Digits: `/\\d/`\n * - Special characters: `/[~!?@#$%^&*_\\-+()\\[\\]{}><\\\\\\/|\"'.,:;=]/`\n * 4. Returns `true` only if all active checks pass.\n *\n * ### Default rule set (strong password)\n * - At least 8 characters long \n * - Contains uppercase and lowercase letters \n * - Contains at least one digit \n * - Contains at least one special symbol \n * - Not longer than 256 characters\n *\n * ### Example configuration\n * ```ts\n * // Minimal check — only length between 6 and 20\n * isPassword('abcdef', { minLength: 6, maxLength: 20, requireSpecial: false });\n *\n * // Strict corporate policy\n * isPassword('Qwerty#123', { minLength: 10, requireSpecial: true });\n *\n * // Simplified mobile app rule\n * isPassword('myPass1', { requireSpecial: false });\n * ```\n *\n * ### Type narrowing\n * When this function returns `true`, TypeScript infers:\n * ```ts\n * value is string\n * ```\n * allowing you to safely treat it as a verified password.\n *\n * ### Performance\n * - Time complexity: **O(n)** (depends on string length and regex scans).\n * - Space complexity: **O(1)**.\n *\n * ### Examples\n *\n * @example\n * // Default strong policy (8+ chars, upper, lower, digit, special)\n * isPassword('Aa1@aaaa'); // => true\n * isPassword('Password123!'); // => true\n * isPassword('qwerty'); // => false (no upper/digit/special)\n *\n * @example\n * // Custom rules\n * isPassword('abc123', {\n * minLength: 6,\n * requireUppercase: false,\n * requireSpecial: false\n * }); // => true\n *\n * @example\n * // Invalid inputs\n * isPassword(''); // => false\n * isPassword(null); // => false\n * isPassword(undefined); // => false\n * isPassword(123456); // => false\n *\n * @see isStr\n *\n * @category Validation\n * @public\n * @since 2.0.0\n */\nexport function isPassword(\n\tvalue: unknown,\n\t{\n\t\tminLength = 8,\n\t\tmaxLength = 256,\n\t\trequireUppercase = true,\n\t\trequireLowercase = true,\n\t\trequireDigit = true,\n\t\trequireSpecial = true,\n\t}: PasswordOptions = {}\n): value is string {\n\tif (!isStr(value)) {\n\t\treturn false;\n\t}\n\tif (value.length < minLength || value.length > maxLength) {\n\t\treturn false;\n\t}\n\tif (requireUppercase && !/[A-ZА-Я]/.test(value)) {\n\t\treturn false;\n\t}\n\tif (requireLowercase && !/[a-zа-я]/.test(value)) {\n\t\treturn false;\n\t}\n\tif (requireDigit && !/\\d/.test(value)) {\n\t\treturn false;\n\t}\n\tif (requireSpecial && !/[~!?@#$%^&*_\\-+()\\[\\]{}><\\\\\\/|\"'.,:;=]/.test(value)) {\n\t\treturn false;\n\t}\n\treturn true;\n}\n","import { \n\tisStrFilled,\n\tisNum, \n} from '../index';\n\n/**\n * Checks whether a given value is a **valid phone number** in a generic international format.\n *\n * @summary\n * A flexible, language-neutral phone number validator that accepts both string and numeric inputs. \n * It supports optional leading `\"+\"`, allows dashes (`\"-\"`) as separators, and ensures that the\n * number structure is syntactically valid — not necessarily region-specific.\n *\n * @param value - Any value to test (string or number).\n *\n * @returns `true` if the value represents a valid phone-like number, otherwise `false`.\n *\n * @remarks\n * ### Validation logic\n * 1. **Type check:** \n * Accepts strings and finite numbers (`isStrFilled` or `isNum` must pass).\n * 2. **Normalization:** \n * Converts to string and trims whitespace.\n * 3. **Negative or misplaced signs:** \n * Rejects numbers starting with `\"-\"`.\n * 4. **Plus sign validation:** \n * - Only one `+` is allowed. \n * - If present, it must appear **only at the start**.\n * 5. **Character whitelist:** \n * The number must match the pattern `/^\\+?[0-9-]+$/`, \n * i.e., only digits, dashes, and an optional leading plus sign.\n * 6. **Length check:** \n * Must be between **3** and **20** characters (inclusive).\n * 7. **Ending rule:** \n * The last character must be a digit.\n * 8. **Double-dash check:** \n * Rejects sequences containing `\"--\"`.\n *\n * ### Behavior\n * - Accepts: `+1234567890`, `380-67-123-4567`, `79001234567`, `12345`.\n * - Rejects: `\"--123\"`, `\"++123\"`, `\"12a34\"`, `\"12 34\"`, `\"-123\"`, `\"123-\"`.\n * - Not region-specific — does **not** check country codes or local dialing rules.\n * - Designed for structural validation only.\n *\n * ### Comparison\n * | Example | Valid | Reason |\n * |----------------------|:------:|--------------------------------|\n * | `+380671234567` | true | Proper international format |\n * | `067-123-4567` | true | Local format with dashes |\n * | `123` | true | Minimum valid length |\n * | `+12-34-56--78` | false | Contains `\"--\"` |\n * | `+12A345` | false | Contains letters |\n * | `123-` | false | Ends with non-digit |\n * | `++38050` | false | Multiple `\"+\"` symbols |\n * | `380+501234` | false | Misplaced plus |\n *\n * ### Type narrowing\n * When this function returns `true`, TypeScript infers:\n * ```ts\n * value is string\n * ```\n * even if the original value was numeric — ensuring it can be safely stored or formatted as text.\n *\n * ### Performance\n * - Time complexity: **O(n)** — single regex checks and scans.\n * - Space complexity: **O(1)**.\n *\n * ### Examples\n *\n * @example\n * // Valid international numbers\n * isPhone('+380671234567'); // => true\n * isPhone('380-67-123-4567'); // => true\n * isPhone(380501234567); // => true\n *\n * @example\n * // Invalid formats\n * isPhone('--12345'); // => false\n * isPhone('+12+34'); // => false\n * isPhone('12A345'); // => false\n * isPhone('123-'); // => false\n * isPhone(''); // => false\n *\n * @example\n * // Type narrowing\n * const val: unknown = '+14155552671';\n * if (isPhone(val)) {\n * console.log(val.replace(/\\D/g, '')); // safe normalization\n * }\n *\n * @see isStrFilled\n * @see isNum\n * @see formatToPhone\n *\n * @category Validation\n * @public\n * @since 2.0.0\n */\nexport function isPhone(value: unknown): value is string {\n\tif (!isStrFilled(value) \n\t\t&& !isNum(value)) {\n\t\treturn false;\n\t}\n\tconst valueProcessed = String(value).trim();\n\n\tif (valueProcessed.startsWith('-')) {\n\t\treturn false;\n\t}\n\tif ((valueProcessed.match(/\\+/g) || []).length > 1) {\n\t\treturn false;\n\t}\n\tif (valueProcessed.includes('+') && !valueProcessed.startsWith('+')) {\n\t\treturn false;\n\t}\n\tif (!/^\\+?[0-9-]+$/.test(valueProcessed)) {\n\t\treturn false;\n\t}\n\tif (valueProcessed.length < 3 || valueProcessed.length > 20) {\n\t\treturn false;\n\t}\n\tif (!/[0-9]$/.test(valueProcessed)) {\n\t\treturn false;\n\t}\n\tif (valueProcessed.includes('--')) {\n\t\treturn false;\n\t}\n\treturn true;\n}\n","/**\n * Checks whether a given value is a **string** primitive.\n *\n * @summary\n * A strict type guard that returns `true` only if the provided value\n * has the JavaScript type `\"string\"`. \n * Rejects all non-string types, including `String` objects created via `new String()`.\n *\n * @param value - Any value to test.\n *\n * @returns `true` if the value is a string primitive, otherwise `false`.\n *\n * @remarks\n * ### Behavior\n * - Uses the `typeof` operator for a strict type check.\n * - Does **not** coerce values — `\"123\"` is valid, but `123` is not.\n * - Returns `false` for:\n * - `String` wrapper objects (`new String('abc')`)\n * - Non-string types (`number`, `boolean`, `object`, `undefined`, etc.)\n *\n * ### Type narrowing\n * When this function returns `true`, TypeScript infers:\n * ```ts\n * value is string\n * ```\n * enabling full access to string methods safely.\n *\n * ### Comparison\n * | Input | Result | Note |\n * |------------------|:------:|-----------------------------------|\n * | `'hello'` | true | String literal |\n * | `new String('x')`| false | Object wrapper, not primitive |\n * | `123` | false | Number |\n * | `null` | false | Not a string |\n * | `undefined` | false | Not a string |\n *\n * ### Performance\n * - Time complexity: **O(1)** \n * - Space complexity: **O(1)**\n *\n * ### Examples\n *\n * @example\n * // Basic usage\n * isStr('Hello'); // => true\n * isStr(''); // => true\n * isStr(123); // => false\n * isStr(null); // => false\n *\n * @example\n * // Type narrowing\n * const val: unknown = 'abc';\n * if (isStr(val)) {\n * console.log(val.toUpperCase()); // safe\n * }\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isStr(value: unknown): value is string {\n\treturn typeof value === 'string';\n}\n","import { isStrFilled } from '../index';\n\n/**\n * Checks whether a given value is a **string representation of a boolean** — `\"true\"` or `\"false\"`.\n *\n * @summary\n * A strict type guard that returns `true` if the input is a non-empty string\n * equal to `\"true\"` or `\"false\"` (case-insensitive, with whitespace ignored). \n * Commonly used for validating query parameters, environment variables, or serialized booleans.\n *\n * @param value - Any value to test.\n *\n * @returns `true` if the value is a string `\"true\"` or `\"false\"` (ignoring case and whitespace), otherwise `false`.\n *\n * @remarks\n * ### Behavior\n * 1. Uses {@link isStrFilled} to ensure the input is a non-empty string.\n * 2. Trims whitespace and converts it to lowercase.\n * 3. Returns `true` only if the normalized string equals `\"true\"` or `\"false\"`.\n * 4. Returns `false` for other strings, numbers, or non-string types.\n *\n * ### Typical usage\n * This utility is helpful when you need to:\n * - Parse stringified boolean flags (`'true'`, `'false'`)\n * - Validate configuration or query params\n * - Handle environment variables (`process.env.FEATURE_ENABLED`)\n *\n * ### Type narrowing\n * When this function returns `true`, TypeScript infers:\n * ```ts\n * value is string\n * ```\n * and you can safely pass it to a boolean converter (e.g. `formatToBool()`).\n *\n * ### Performance\n * - Time complexity: **O(1)** \n * - Space complexity: **O(1)**\n *\n * ### Examples\n *\n * @example\n * // Valid boolean strings\n * isStrBool('true'); // => true\n * isStrBool('FALSE'); // => true\n * isStrBool(' True '); // => true\n *\n * @example\n * // Invalid strings\n * isStrBool('yes'); // => false\n * isStrBool('0'); // => false\n * isStrBool(''); // => false\n *\n * @example\n * // Non-string inputs\n * isStrBool(true); // => false\n * isStrBool(1); // => false\n * isStrBool(null); // => false\n *\n * @example\n * // Combined with formatToBool()\n * import { formatToBool } from '../bool/formatToBool';\n *\n * const val: unknown = 'False';\n * if (isStrBool(val)) {\n * console.log(formatToBool(val)); // false\n * }\n *\n * @see isStr\n * @see isStrFilled\n * @see isBool\n * @see formatToBool\n *\n * @category Validation\n * @public\n * @since 2.0.0\n */\nexport function isStrBool(value: unknown): value is string {\n\tif (!isStrFilled(value)) {\n\t\treturn false;\n\t}\n\tconst normalized = value.trim().toLowerCase();\n\t\n\treturn normalized === 'true' || normalized === 'false';\n}\n","import { isStr } from '../index';\n\n/**\n * Checks whether a given value is a **non-empty string** (not just whitespace).\n *\n * @summary\n * A strict type guard that returns `true` only if the value is a string\n * containing at least one non-whitespace character. \n * This is an extended form of {@link isStr} that excludes empty (`\"\"`) and\n * whitespace-only strings (`\" \"`).\n *\n * @param value - Any value to test.\n *\n * @returns `true` if the value is a string with visible content, otherwise `false`.\n *\n * @remarks\n * ### Behavior\n * - Uses {@link isStr} to confirm the value is a string primitive.\n * - Calls `.trim()` to remove whitespace and checks if the resulting length is greater than zero.\n * - Returns `false` for:\n * - Empty strings (`\"\"`)\n * - Whitespace-only strings (`\" \"`, `\"\\n\"`, `\"\\t\"`)\n * - Non-string values (`number`, `boolean`, `object`, `null`, etc.)\n *\n * ### Comparison\n * | Function | Description | Example |\n * |-----------------|-----------------------------------|---------------------------|\n * | `isStr` | Any string (including empty) | `\"\"` true |\n * | `isStrFilled` | Non-empty trimmed string only | `\" \"` false / `\"x\"` true |\n *\n * ### Type narrowing\n * When this function returns `true`, TypeScript infers:\n * ```ts\n * value is string\n * ```\n * ensuring safe use of string operations.\n *\n * ### Performance\n * - Time complexity: **O(n)** (due to `.trim()`).\n * - Space complexity: **O(1)**.\n *\n * ### Examples\n *\n * @example\n * // Valid strings\n * isStrFilled('hello'); // => true\n * isStrFilled(' text '); // => true\n *\n * @example\n * // Empty or whitespace-only\n * isStrFilled(''); // => false\n * isStrFilled(' '); // => false\n *\n * @example\n * // Non-string values\n * isStrFilled(null); // => false\n * isStrFilled(123); // => false\n * isStrFilled(undefined); // => false\n *\n * @example\n * // Type narrowing\n * const val: unknown = ' value ';\n * if (isStrFilled(val)) {\n * console.log(val.trim().toUpperCase()); // safe\n * }\n *\n * @see isStr\n * @see isArrFilled\n * @see isObjFilled\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isStrFilled(value: unknown): value is string {\n\treturn isStr(value) && value.trim().length > 0;\n}\n","import { isStrFilled } from '../index';\n\n/**\n * Checks whether a given value is a string equal to **\"asc\"** or **\"desc\"** (case-insensitive).\n *\n * @summary\n * A strict type guard that validates sorting direction strings — \n * `\"asc\"` (ascending) or `\"desc\"` (descending). \n * Useful for validating API parameters, SQL sort directives, or UI sort controls.\n *\n * @param value - Any value to test.\n *\n * @returns `true` if the value is a non-empty string representing `\"asc\"` or `\"desc\"`, otherwise `false`.\n *\n * @remarks\n * ### Behavior\n * 1. Uses {@link isStrFilled} to ensure the value is a non-empty string.\n * 2. Trims whitespace and converts it to lowercase.\n * 3. Returns `true` only if the normalized value equals `\"asc\"` or `\"desc\"`.\n * 4. Returns `false` for empty strings, other words, or non-string types.\n *\n * ### Type narrowing\n * When this function returns `true`, TypeScript infers:\n * ```ts\n * value is 'asc' | 'desc'\n * ```\n * which is ideal for type-safe sort order handling in functions and APIs.\n *\n * ### Performance\n * - Time complexity: **O(1)** (fixed length checks)\n * - Space complexity: **O(1)**\n *\n * ### Examples\n *\n * @example\n * // Valid inputs\n * isStrAscDesc('asc'); // => true\n * isStrAscDesc('DESC'); // => true\n * isStrAscDesc(' Asc '); // => true\n *\n * @example\n * // Invalid inputs\n * isStrAscDesc('ascending'); // => false\n * isStrAscDesc(''); // => false\n * isStrAscDesc(null); // => false\n * isStrAscDesc('up'); // => false\n *\n * @example\n * // Type narrowing in use\n * function sortData(order: unknown) {\n * if (isStrAscDesc(order)) {\n * console.log(`Sorting in ${order} order`);\n * } else {\n * console.log('Invalid sort direction');\n * }\n * }\n *\n * @see isStr\n * @see isStrFilled\n *\n * @category Validation\n * @public\n * @since 2.0.0\n */\nexport function isStrAscDesc(value: unknown): value is 'asc' | 'desc' {\n\tif (!isStrFilled(value)) {\n\t\treturn false;\n\t}\n\tconst normalized = value.trim().toLowerCase();\n\t\n\treturn normalized === 'asc' || normalized === 'desc';\n}\n","import { isStr } from '../index';\n\n/**\n * Checks whether a given value is a **valid variable-like identifier**.\n *\n * @summary\n * A strict type guard that returns `true` only if the value is a string\n * matching the pattern of a valid **programming variable name**: \n * must start with a letter (`A–Z`, `a–z`) or underscore (`_`),\n * and may contain only letters, digits, or underscores afterward.\n *\n * @param value - Any value to test.\n *\n * @returns `true` if the value is a syntactically valid variable name; otherwise `false`.\n *\n * @remarks\n * ### Validation rule\n * Uses the following regular expression:\n * ```regex\n * /^[A-Za-z_][A-Za-z0-9_]*$/\n * ```\n * This enforces:\n * - **First character:** a Latin letter (`A–Z`, `a–z`) or underscore (`_`)\n * - **Subsequent characters:** any combination of letters, digits, or underscores\n * - **No spaces, symbols, or Unicode letters** are allowed\n *\n * ### Typical use cases\n * - Validating variable names in configuration files or templates\n * - Checking safe property keys for code generation\n * - Ensuring identifiers in scripting or parsing logic\n *\n * ### Behavior\n * - Returns `false` for:\n * - Strings starting with digits (`\"1abc\"`)\n * - Strings containing hyphens or spaces (`\"my-var\"`, `\"user name\"`)\n * - Empty strings or non-string values\n * - Returns `true` for:\n * - `\"name\"`, `\"_value\"`, `\"myVar1\"`, `\"SOME_CONSTANT\"`\n *\n * ### Type narrowing\n * When this function returns `true`, TypeScript infers:\n * ```ts\n * value is string\n * ```\n * ensuring safe string usage in contexts like symbol tables or identifier maps.\n *\n * ### Performance\n * - Time complexity: **O(n)** — proportional to string length (regex evaluation)\n * - Space complexity: **O(1)**\n *\n * ### Examples\n *\n * @example\n * // Valid identifiers\n * isVar('name'); // => true\n * isVar('_id'); // => true\n * isVar('myVar1'); // => true\n * isVar('SOME_CONSTANT'); // => true\n *\n * @example\n * // Invalid identifiers\n * isVar(''); // => false\n * isVar('1var'); // => false\n * isVar('user-name'); // => false\n * isVar('my var'); // => false\n * isVar('$value'); // => false\n *\n * @example\n * // Non-string values\n * isVar(null); // => false\n * isVar(123); // => false\n * isVar({}); // => false\n *\n * @see isStr\n * @see isStrFilled\n *\n * @category Validation\n * @public\n * @since 2.0.0\n */\nexport function isVar(value: unknown): value is string {\n\treturn isStr(value) && /^[A-Za-z_][A-Za-z0-9_]*$/.test(value);\n}\n","import { isFunc } from './isFunc';\n\nexport function isClass(value: unknown): boolean {\n\treturn isFunc(value) && /^class\\s/.test(Function.prototype.toString.call(value))\n}\n","import type { JSONLike } from '../index';\nimport { jsonParse } from '../index';\n\n/**\n * Matches strings surrounded by a single, double, or backtick quote.\n *\n * @example\n * ```ts\n * QUOTED_RE.test(`\"hello\"`); // true\n * QUOTED_RE.test(`'world'`); // true\n * QUOTED_RE.test('`foo`'); // true\n * QUOTED_RE.test('bar'); // false\n * ```\n *\n * @internal\n */\nconst QUOTED_RE = /^(['\"`])([\\s\\S]*)\\1$/;\n\n/**\n * Parses a string that may represent JSON, quoted scalars, or plain text.\n *\n * @remarks\n * The parsing order is:\n *\n * 1. Try JSON via {@link jsonParse}. If it works, return the parsed value.\n * 2. If not JSON, check if the string is quoted with `'`, `\"` or `` ` ``.\n * If quoted, return the **unquoted** inner text.\n * 3. If not quoted:\n * - If `allowString === true`, return the **trimmed** string as-is.\n * - Otherwise return `null`.\n *\n * This helper is used recursively by {@link jsonDecode} to decode string fields\n * found inside arrays/objects.\n *\n * @param s - Source string.\n * @param allowString - Whether to allow returning raw (unquoted) strings.\n * @returns A JSON-like value, or `null` if the string cannot be interpreted\n * and `allowString` is `false`.\n *\n * @example\n * ```ts\n * jsonStrLike('{\"a\":1}', false); // -> { a: 1 }\n * jsonStrLike('\"hello\"', false); // -> \"hello\"\n * jsonStrLike('hello', false); // -> null\n * jsonStrLike('hello', true); // -> \"hello\"\n * ```\n *\n * @internal\n */\nexport function jsonStrLike(s: string, allowString: boolean): JSONLike | null {\n\tconst trimmed = s.trim();\n\tconst pr = jsonParse(trimmed);\n\t\n\tif (pr.ok) {\n\t\treturn pr.value;\n\t}\n\tconst m = QUOTED_RE.exec(trimmed);\n\t\n\tif (m) {\n\t\treturn m[2] as JSONLike;\n\t}\n\treturn allowString ? (trimmed as JSONLike) : null;\n}","import type { JSONLike } from '../index';\n\n/**\n * Attempts to parse a string using native {@link JSON.parse}.\n *\n * @remarks\n * Returns a discriminated union with `{ ok: true, value }` on success,\n * or `{ ok: false }` on any parsing error. Exceptions are caught and\n * **never thrown** to callers.\n *\n * @param str - The candidate JSON string.\n * @returns A result object indicating parse success/failure.\n *\n * @example\n * ```ts\n * jsonParse('{\"a\":1}'); // { ok: true, value: { a: 1 } }\n * jsonParse('not json'); // { ok: false }\n * ```\n *\n * @internal\n */\nexport function jsonParse(str: string): { ok: true; value: JSONLike } | { ok: false } {\n\ttry {\n\t\treturn { ok: true, value: JSON.parse(str) as JSONLike };\n\t} \n\tcatch (err) {\n\t}\n\treturn { ok: false };\n}","import type { JSONLike } from '../index';\nimport { \n\tisArrFilled,\n\tisArr, \n\tisObjFilled,\n\tisObj,\n\tisStrFilled,\n\tisNum,\n\tisBool,\n\tjsonEncode,\n\tjsonStrLike,\n} from '../index';\n\n/**\n * Best-effort decoder that normalizes unknown input into a JSON-like value.\n *\n * @remarks\n * `jsonDecode` accepts many shapes of input and produces a `JSONLike` (or `null`)\n * according to the following rules:\n *\n * - **Primitive passthrough**: `null`, numbers, and booleans are returned as-is.\n * - **Arrays/Objects (filled)**: for each string element/property, we attempt to decode\n * it via {@link jsonStrLike} (JSON → unquoted string → raw string if `allowString`).\n * Non-string items are passed through unchanged (cast to `JSONLike`).\n * - **Arrays/Objects (empty)**: returned as-is (they’re valid JSON).\n * - **Standalone strings**: decoded via {@link jsonStrLike}.\n * - **Other values**: return `null`.\n *\n * The function is **non-throwing**; any JSON parse errors are swallowed internally\n * and mapped to either unquoted/raw strings (depending on `allowString`) or `null`.\n * \n * - Uses native `JSON.parse` — safe for untrusted strings provided you do not eval the result.\n * - Does **not** perform schema validation; if you need strict shapes, validate after decoding.\n *\n * @typeParam T - Target type to cast the normalized result to. \n * Defaults to `JSONLike`. Use with care — this is a **type cast**, not a runtime check.\n *\n * @param value - The unknown input to decode (can be primitives, arrays, objects, etc.).\n * @param allowString - If `true`, non-JSON, non-quoted strings are returned as trimmed strings.\n * If `false`, such strings decode to `null`.\n *\n * @returns The decoded value cast to `T`, or `null` when it cannot be decoded.\n *\n * @example\n * ```ts\n * // 1) Primitives pass through\n * jsonDecode(42); // 42\n * jsonDecode(true); // true\n * jsonDecode(null); // null\n *\n * // 2) JSON string\n * jsonDecode('{\"a\":[1,\"2\"]}'); // { a: [1, \"2\"] }\n *\n * // 3) Quoted string\n * jsonDecode('\"hello\"'); // \"hello\"\n *\n * // 4) Raw string with allowString=false (default)\n * jsonDecode('hello'); // null\n *\n * // 5) Raw string with allowString=true\n * jsonDecode('hello', true); // \"hello\"\n *\n * // 6) Arrays/objects with string fields get per-field decoding\n * jsonDecode({ a: '{\"k\":1}', b: 'world' }, true);\n * // -> { a: { k: 1 }, b: \"world\" }\n * ```\n *\n * @throws Never throws; invalid inputs yield `null` or are passed through per rules above.\n *\n * @public\n * @category JSON\n * @since 2.0.0\n */\nexport function jsonDecode<T = JSONLike>(value: unknown, allowString = false): T | null {\n\tif (value === null || isNum(value) || isBool(value)) {\n\t\treturn value as unknown as T;\n\t}\n\tif (isArrFilled(value)) {\n\t\tconst arr = value as ReadonlyArray<unknown>;\n\t\tconst out: JSONLike[] = [];\n\t\t\n\t\tfor (const item of arr) {\n\t\t\tif (isStrFilled(item)) {\n\t\t\t\tout.push(jsonStrLike(String(item), allowString));\n\t\t\t}\n\t\t\telse {\n\t\t\t\tout.push(item as JSONLike);\n\t\t\t}\n\t\t}\n\t\treturn out as unknown as T;\n\t}\n\tif (isObjFilled(value)) {\n\t\tconst src = value as Record<string, unknown>;\n\t\tconst out: Record<string, JSONLike> = {};\n\t\t\n\t\tfor (const key of Object.keys(src)) {\n\t\t\tconst v = src[key];\n\t\t\t\n\t\t\tif (isStrFilled(v)) {\n\t\t\t\tout[key] = jsonStrLike(String(v), allowString);\n\t\t\t} \n\t\t\telse {\n\t\t\t\tout[key] = v as JSONLike;\n\t\t\t}\n\t\t}\n\t\treturn out as unknown as T;\n\t}\n\tif (isArr(value) || isObj(value)) {\n\t\treturn value as unknown as T;\n\t}\n\tif (isStrFilled(value)) {\n\t\treturn jsonStrLike(String(value), allowString) as unknown as T;\n\t}\n\treturn null;\n}\n","import { \n\tisObj,\n\tisArr, \n\tjsonDecode,\n} from '../index';\n\n/**\n * Safely serializes a plain object or array into a JSON string.\n *\n * @remarks\n * This helper wraps {@link JSON.stringify} and adds two key safety features:\n *\n * 1. It only serializes **objects** and **arrays**, ignoring all other data types\n * (numbers, strings, booleans, `null`, `undefined`).\n * 2. It catches all potential `JSON.stringify` errors (such as circular references)\n * and returns an empty string `\"\"` instead of throwing.\n *\n * The function is thus ideal for safe logging, diagnostics, or best-effort\n * serialization where throwing is undesirable.\n * \n * - The output is always a valid JSON string (or empty string on failure).\n * - Use {@link jsonDecode} to reverse the process and safely parse it back.\n * - BigInt values are **not supported** by `JSON.stringify` — they will trigger\n * a caught error, resulting in an empty string.\n *\n * @param value - Any value to encode. Only arrays or plain objects will be serialized;\n * other types return an empty string.\n *\n * @returns The JSON-encoded string representation of the input, \n * or an empty string (`\"\"`) if:\n * - The input is not an array or object.\n * - Serialization fails (e.g., circular reference or BigInt values).\n *\n * @example\n * ```ts\n * // Example 1: Basic usage\n * jsonEncode({ a: 1, b: true });\n * // -> '{\"a\":1,\"b\":true}'\n *\n * // Example 2: Arrays\n * jsonEncode([1, 2, 3]);\n * // -> '[1,2,3]'\n *\n * // Example 3: Non-serializable input\n * jsonEncode(123); // -> ''\n * jsonEncode('hello'); // -> ''\n * jsonEncode(undefined); // -> ''\n *\n * // Example 4: Circular reference\n * const obj: any = {};\n * obj.self = obj;\n * jsonEncode(obj); // -> '' (fails safely)\n * ```\n *\n * @throws Never throws — all exceptions from `JSON.stringify` are caught internally.\n *\n * @see {@link jsonDecode} — performs the inverse operation with safe parsing and normalization.\n * @see {@link JSON.stringify} — the native method used under the hood.\n *\n * @public\n * @category JSON\n * @since 2.0.0\n */\nexport function jsonEncode(value: unknown): string {\n\ttry {\n\t\treturn (isObj(value) || isArr(value)) ? JSON.stringify(value) : '';\n\t}\n\tcatch (err) {\n\t}\n\treturn '';\n}\n","import type { FixedDecimal } from './types';\n\n/**\n * Converts a {@link FixedDecimal} — an exact, integer-based decimal structure —\n * into its canonical string representation (e.g. `\"-123.456\"`).\n *\n * @remarks\n * This function is **exact and reversible**: no precision loss occurs because it\n * operates on the raw digit string (`digitsInteger`) and inserts the decimal point\n * purely by string manipulation.\n *\n * The algorithm:\n * 1. Converts the `digitsInteger` `BigInt` to a string of digits.\n * 2. If `scale` is `0`, returns the signed integer directly.\n * 3. If `scale` is positive:\n * - Pads with leading zeros when the number of digits is smaller than `scale`.\n * - Otherwise, splits at the appropriate boundary between integer and fractional parts.\n * \n * O(n) where `n` is the number of digits in `digitsInteger.toString()`.\n *\n * @param value - The {@link FixedDecimal} object:\n * - `sign`: `1` for positive or `-1` for negative numbers.\n * - `digitsInteger`: All digits as a `BigInt` without a decimal point.\n * - `scale`: The number of digits after the decimal point.\n *\n * @returns A string representation of the number, including a `-` sign if negative.\n * If the number is fractional, a single `.` separates integer and fractional parts.\n *\n * @example\n * ```ts\n * const fd: FixedDecimal = { sign: 1, digitsInteger: 12345n, scale: 2 };\n * fixedDecimalToStr(fd); // \"123.45\"\n * ```\n *\n * @example\n * ```ts\n * // Negative number\n * const neg: FixedDecimal = { sign: -1, digitsInteger: 987n, scale: 3 };\n * fixedDecimalToStr(neg); // \"-0.987\"\n * ```\n *\n * @example\n * ```ts\n * // Small fractional with fewer digits than scale\n * const tiny: FixedDecimal = { sign: 1, digitsInteger: 12n, scale: 5 };\n * fixedDecimalToStr(tiny); // \"0.00012\"\n * ```\n *\n * @example\n * ```ts\n * // Whole number (scale = 0)\n * const whole: FixedDecimal = { sign: 1, digitsInteger: 42n, scale: 0 };\n * fixedDecimalToStr(whole); // \"42\"\n * ```\n *\n * @see changeFixedDecimalScale — for adjusting the scale value safely\n * @see fixedDecimalToNum — for converting to a JavaScript number\n *\n * @since 2.0.0\n */\nexport function fixedDecimalToStr(value: FixedDecimal): string {\n\tconst signSymbol = value.sign < 0 ? '-' : '';\n\tconst allDigitsString = value.digitsInteger.toString();\n\n\tif (value.scale === 0) {\n\t\treturn signSymbol + allDigitsString;\n\t}\n\tconst padZeros = value.scale - allDigitsString.length;\n\n\tif (padZeros >= 0) {\n\t\treturn signSymbol + '0.' + '0'.repeat(padZeros) + allDigitsString;\n\t}\n\tconst integerBoundary = allDigitsString.length - value.scale;\n\tconst integerText = allDigitsString.slice(0, integerBoundary);\n\tconst fractionalText = allDigitsString.slice(integerBoundary);\n\n\treturn signSymbol + integerText + '.' + fractionalText;\n}\n","import type { FixedDecimal } from './types';\nimport { fixedDecimalToStr } from './fixedDecimalToStr';\n\n/**\n * Converts a {@link FixedDecimal} — an exact decimal representation —\n * into a native JavaScript `number` (IEEE 754 double precision).\n *\n * @remarks\n * This function is a **lossy** conversion when `value` contains\n * more precision than JavaScript’s floating-point format can represent.\n * It internally calls {@link fixedDecimalToStr} to produce a normalized\n * string such as `\"-123.4567\"` and then passes it to the built-in\n * `Number()` constructor.\n * \n * O(n) relative to the number of digits in `digitsInteger`\n * (due to string creation in {@link fixedDecimalToStr}).\n *\n * @param value - The {@link FixedDecimal} instance to convert.\n * Must contain:\n * - `sign`: either `1` or `-1`;\n * - `digitsInteger`: a `bigint` representing all digits without any decimal point;\n * - `scale`: how many digits belong after the decimal point.\n *\n * @returns The approximate numeric value as a JavaScript `number`.\n * If the string form is too large or too precise, the result may be\n * rounded or become `Infinity`.\n *\n * @example\n * ```ts\n * const fd: FixedDecimal = { sign: 1, digitsInteger: 12345n, scale: 2 };\n * // Represents exactly 123.45\n * const num = fixedDecimalToNum(fd); // 123.45 (Number)\n * ```\n *\n * @example\n * ```ts\n * // Handles negative numbers as well\n * const neg: FixedDecimal = { sign: -1, digitsInteger: 987n, scale: 3 };\n * const n = fixedDecimalToNum(neg); // -0.987\n * ```\n *\n * @example\n * ```ts\n * // Extreme precision may lose digits beyond ~15–17 significant figures\n * const big: FixedDecimal = { sign: 1, digitsInteger: 12345678901234567890n, scale: 10 };\n * const approx = fixedDecimalToNum(big);\n * console.log(approx); // ~1234567890.1234567 (rounded)\n * ```\n *\n * @see fixedDecimalToStr — for the exact string representation\n * @see https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number#precision JavaScript number precision\n *\n * @since 2.0.0\n */\nexport function fixedDecimalToNum(value: FixedDecimal): number {\n\treturn Number(fixedDecimalToStr(value));\n}\n","import { isNumPZ } from '../index';\n\n/**\n * Converts a number expressed in normalized exponential/scientific notation\n * (e.g., `\"1.23e+5\"`, `\"4e-7\"`, `\"0009.500e2\"`) into its **sign**, **integer**,\n * and **fractional** parts as plain decimal digit strings — **without** any\n * decimal point or leading `+`/`-` characters.\n *\n * @remarks\n * - This function does **not** perform numeric arithmetic; instead it does a\n * textual normalization that preserves all significant digits exactly.\n * - It accepts the `sign` separately so that callers can pre-parse signs from\n * inputs like `\"-1.23e3\"` and pass `sign = -1` with `exponentialString = \"1.23e3\"`.\n * (If you already have a positive string, pass `sign = 1`.)\n * - The function normalizes the coefficient and exponent first, then uses a\n * single regex match to validate the shape:\n * - Coefficient: `([0-9]+)(?:\\.([0-9]*))?`\n * - Exponent: `e([+\\-]?[0-9]+)`\n * - Trailing zeros are added to the **integer** side for positive net exponents,\n * while leading zeros are added to the **fractional** side for negative net exponents.\n * - All returned parts (`integerPart`, `fractionalPart`) contain only ASCII digits.\n * The decimal point is **not** returned; you can re-insert it if needed by\n * placing it between `integerPart` and `fractionalPart`.\n * \n * Time O(n) and space O(n), where n is the number of digits in the coefficient,\n * due to string concatenation and slicing.\n *\n * @param sign - The pre-parsed sign of the number: `1` for positive, `-1` for negative.\n * @param exponentialString - A string in exponential notation.\n * Examples: `\"1e3\"`, `\"1.23e+5\"`, `\"4.560e-2\"`, `\"0009.500e2\"`.\n * The function is case-insensitive for the `'e'` and tolerates leading zeros in the coefficient.\n *\n * @returns An object with three properties:\n * - `sign`: Echo of the input sign (`1` | `-1`).\n * - `integerPart`: All digits to the left of the decimal point after expansion.\n * - `fractionalPart`: All digits to the right of the decimal point after expansion.\n *\n * @throws {Error} If `exponentialString` cannot be parsed as scientific notation.\n *\n * @example\n * ```ts\n * // 1.23 × 10^5 = 123000\n * convertExponentialToParts(1, \"1.23e5\");\n * // => { sign: 1, integerPart: \"123000\", fractionalPart: \"\" }\n * ```\n *\n * @example\n * ```ts\n * // 4.5 × 10^-3 = 0.0045\n * convertExponentialToParts(1, \"4.5e-3\");\n * // => { sign: 1, integerPart: \"0\", fractionalPart: \"0045\" }\n * ```\n *\n * @example\n * ```ts\n * // -7.00e+0 = -7\n * convertExponentialToParts(-1, \"7.00e0\");\n * // => { sign: -1, integerPart: \"7\", fractionalPart: \"\" }\n * ```\n *\n * @example\n * ```ts\n * // Leading zeros in coefficient are handled; fractional length adjusts exponent\n * convertExponentialToParts(1, \"0009.500e2\"); // 9.500 × 10^2 = 950\n * // => { sign: 1, integerPart: \"950\", fractionalPart: \"\" }\n * ```\n *\n * @example\n * ```ts\n * // You can reconstruct a normalized decimal string yourself:\n * const { sign, integerPart, fractionalPart } = convertExponentialToParts(-1, \"1.234e-2\");\n * const signChar = sign < 0 ? \"-\" : \"\";\n * const plain = fractionalPart ? `${integerPart}.${fractionalPart}` : integerPart;\n * // plain == \"0.01234\"\n * const result = signChar + plain; // \"-0.01234\"\n * ```\n *\n * @see isNumPZ — utility used here to detect non-negative integers (exponent ≥ 0).\n *\n * @since 2.0.0\n */\nexport function convertExponentialToParts(\n\tsign: 1 | -1,\n\texponentialString: string\n): { sign: 1 | -1; integerPart: string; fractionalPart: string } {\n\tconst match = /^([0-9]+)(?:\\.([0-9]*))?e([+\\-]?[0-9]+)$/i.exec(\n\t\t(() => {\n\t\t\tconst [coefficient, exponentText] = exponentialString.split(/e/i);\n\t\t\tconst [integerPart, fractionalPart = ''] = coefficient.split('.');\n\t\t\tconst allDigits = integerPart.replace(/^0+/, '') + fractionalPart;\n\t\t\tconst exponentValue = parseInt(exponentText, 10) - fractionalPart.length;\n\t\t\t\n\t\t\treturn `${allDigits || '0'}e${exponentValue}`;\n\t\t})()\n\t);\n\n\tif (!match) {\n\t\tthrow new Error('Failed to parse exponential notation.');\n\t}\n\tlet allDigits = match[1];\n\tconst exponent = parseInt(match[3], 10);\n\n\tif (isNumPZ(exponent)) {\n\t\tallDigits = allDigits + '0'.repeat(exponent);\n\t\t\n\t\treturn { \n\t\t\tsign, \n\t\t\tintegerPart: allDigits || '0', \n\t\t\tfractionalPart: '', \n\t\t};\n\t} \n\telse {\n\t\tconst digitsToLeft = -exponent;\n\t\t\n\t\tif (digitsToLeft >= allDigits.length) {\n\t\t\tconst missingZeros = '0'.repeat(digitsToLeft - allDigits.length);\n\t\t\t\n\t\t\treturn {\n\t\t\t\tsign,\n\t\t\t\tintegerPart: '0',\n\t\t\t\tfractionalPart: missingZeros + allDigits,\n\t\t\t};\n\t\t}\n\t\telse {\n\t\t\tconst splitIndex = allDigits.length - digitsToLeft;\n\t\t\t\n\t\t\treturn {\n\t\t\t\tsign,\n\t\t\t\tintegerPart: allDigits.slice(0, splitIndex),\n\t\t\t\tfractionalPart: allDigits.slice(splitIndex),\n\t\t\t};\n\t\t}\n\t}\n}","import { convertExponentialToParts } from './convertExponentialToParts';\n\n/**\n * Normalizes an arbitrary numeric input into sign, integer, and fractional string parts\n * without losing precision, preparing it for exact fixed-decimal processing.\n *\n * @remarks\n * This utility accepts `bigint`, `number`, and `string` inputs and returns a tuple-like\n * object with three fields:\n *\n * - `sign`: `1` for non-negative values, `-1` for negative values.\n * - `integerPart`: the digits before the decimal point as a string (no sign, no separators).\n * - `fractionalPart`: the digits after the decimal point as a string (no sign, no separators).\n *\n * For JavaScript `number`s, the function first checks finiteness and then converts the\n * absolute value to an exponential string (via `toExponential(30)`) to avoid\n * floating-point artifacts when extracting digits. It delegates parsing of that exponential\n * form to {@link convertExponentialToParts}.\n *\n * For `string`s, the function:\n * - Trims whitespace and replaces a comma `,` decimal separator with a dot `.`.\n * - Parses and removes a leading `+`/`-` sign (if present).\n * - Validates the remaining characters with a permissive numeric pattern that allows:\n * - optional integer digits,\n * - an optional decimal point with digits,\n * - an optional scientific exponent (`e` or `E` with optional `+`/`-` and digits).\n * - If an exponent is present, it delegates to {@link convertExponentialToParts};\n * otherwise it splits on the decimal point.\n *\n * **Important:** This function does not strip leading zeros in `integerPart` or trailing\n * zeros in `fractionalPart`. If you need canonicalized output (e.g., remove leading/trailing\n * zeros), do that in a later step (e.g., when building your fixed-decimal representation).\n *\n * @param input - The numeric input to normalize. Supported types:\n * - `bigint` (e.g., `123n`, `-9007199254740993n`)\n * - `number` (finite only; `NaN`, `Infinity`, `-Infinity` will throw)\n * - `string` (e.g., `\"42\"`, `\"-0.034\"`, `\"1.2e-5\"`, with optional leading sign, optional\n * decimal part, optional exponent; commas are allowed as decimal separators and are\n * converted to dots)\n *\n * @returns An object with the normalized components:\n * ```ts\n * {\n * sign: 1 | -1;\n * integerPart: string;\n * fractionalPart: string;\n * }\n * ```\n * The `integerPart` and `fractionalPart` contain only ASCII digits (`0`–`9`) and\n * **never** include sign or exponent markers.\n *\n * @throws {Error}\n * - If `input` is a `number` but not finite (`NaN`, `Infinity`, `-Infinity`).\n * - If `input` is a `string` that is empty after trimming/replacement.\n * - If `input` is a `string` that fails the numeric validation regex.\n * - If `input` is of an unsupported type (not `bigint`, `number`, or `string`).\n * - Any errors propagated from {@link convertExponentialToParts} when parsing exponential forms.\n *\n * @example\n * // bigint input → fractional part is empty\n * normalizeToDecimalComponents(123n);\n * // => { sign: 1, integerPart: \"123\", fractionalPart: \"\" }\n *\n * @example\n * // negative bigint\n * normalizeToDecimalComponents(-987654321n);\n * // => { sign: -1, integerPart: \"987654321\", fractionalPart: \"\" }\n *\n * @example\n * // finite number input; uses exponential internally to avoid FP artifacts\n * normalizeToDecimalComponents(0.0000034);\n * // => { sign: 1, integerPart: \"0\", fractionalPart: \"0000034\" } // exact digits\n *\n * @example\n * // string with decimal comma and explicit sign\n * normalizeToDecimalComponents(\"+1,250\");\n * // => { sign: 1, integerPart: \"1\", fractionalPart: \"250\" }\n *\n * @example\n * // scientific notation string\n * normalizeToDecimalComponents(\"-1.234e+3\");\n * // => { sign: -1, integerPart: \"1234\", fractionalPart: \"\" }\n *\n * @example\n * // invalid string (throws)\n * normalizeToDecimalComponents(\"12.34.56\"); // Error: Invalid numeric string.\n *\n * @see convertExponentialToParts\n * @category Parsing\n * @since 2.0.0\n * @public\n */\nexport function normalizeToDecimalComponents(input: unknown): {\n\tsign: 1 | -1;\n\tintegerPart: string;\n\tfractionalPart: string;\n} {\n\tif (typeof input === 'bigint') {\n\t\tconst sign: 1 | -1 = input < 0n ? -1 : 1;\n\t\tconst absoluteValue = (input < 0n ? -input : input).toString();\n\t\t\n\t\treturn { \n\t\t\tsign, \n\t\t\tintegerPart: absoluteValue, \n\t\t\tfractionalPart: '', \n\t\t};\n\t}\n\tif (typeof input === 'number') {\n\t\tif (!Number.isFinite(input)) {\n\t\t\tthrow new Error('Input number is not finite.');\n\t\t}\n\t\tconst sign: 1 | -1 = input < 0 ? -1 : 1;\n\t\tconst absoluteValue = Math.abs(input);\n\t\tconst exponentialForm = absoluteValue.toExponential(30); // например \"1.23456e-5\"\n\t\t\n\t\treturn convertExponentialToParts(sign, exponentialForm);\n\t}\n\tif (typeof input === 'string') {\n\t\tlet processed = input.trim().replace(',', '.');\n\t\t\n\t\tif (!processed) {\n\t\t\tthrow new Error('Input string is empty.');\n\t\t}\n\t\tlet sign: 1 | -1 = 1;\n\t\t\n\t\tif (processed.startsWith('+') || processed.startsWith('-')) {\n\t\t\tsign = processed.startsWith('-') ? -1 : 1;\n\t\t\tprocessed = processed.slice(1);\n\t\t}\n\t\tif (/^[0-9]*\\.?[0-9]*(e[+\\-]?[0-9]+)?$/i.test(processed)) {\n\t\t\tif (/e/i.test(processed)) {\n\t\t\t\treturn convertExponentialToParts(sign, processed);\n\t\t\t}\n\t\t\tconst [ integerPart = '0', fractionalPart = '' ] = processed.split('.');\n\t\t\t\n\t\t\treturn { \n\t\t\t\tsign, \n\t\t\t\tintegerPart, \n\t\t\t\tfractionalPart, \n\t\t\t};\n\t\t}\n\t\tthrow new Error('Invalid numeric string.');\n\t}\n\tthrow new Error('Unsupported input type.');\n}","import type { FixedDecimal } from './types';\nimport { normalizeToDecimalComponents } from './normalizeToDecimalComponents';\n\n/**\n * Parses any numeric input (`number`, `bigint`, or `string`) into an exact {@link FixedDecimal}\n * representation, preserving all digits without floating-point rounding errors.\n *\n * @remarks\n * This function transforms arbitrary numeric input into a **fixed-precision decimal structure**\n * that can safely represent extremely large or small values without losing information.\n * It achieves this by first decomposing the input using {@link normalizeToDecimalComponents}\n * and then constructing a `FixedDecimal` object consisting of:\n *\n * - `sign` → `1` for positive values, `-1` for negative values.\n * - `digitsInteger` → a `BigInt` that encodes *all digits* of the number as if\n * the decimal point were removed.\n * - `scale` → the count of digits that were originally after the decimal point.\n *\n * The resulting value can later be precisely converted back to a string or to a\n * JavaScript `number` using helpers like `fixedDecimalToStr` or `fixedDecimalToNum`.\n *\n * This process **avoids IEEE-754 floating-point artifacts**, ensuring mathematically\n * exact handling of decimal fractions (e.g. `\"0.1\" + \"0.2\" → 0.3` instead of `0.30000000000000004`).\n *\n * @param input - Any numeric source value. Supported types:\n * - `number` — finite only (`NaN`, `Infinity`, `-Infinity` will throw).\n * - `bigint` — directly converted without fractional digits.\n * - `string` — may contain optional sign, decimal point, or exponential notation (`1.23e-5`).\n * Commas `,` as decimal separators are also supported and converted to dots `.`.\n *\n * @returns A normalized {@link FixedDecimal} object:\n * ```ts\n * {\n * sign: 1 | -1; // the numeric sign\n * digitsInteger: bigint; // all digits as a BigInt, no decimal point\n * scale: number; // number of digits after the decimal\n * }\n * ```\n *\n * @throws {Error}\n * - If the input is not a supported type (`number`, `bigint`, or `string`).\n * - If the string cannot be parsed as a valid numeric representation.\n * - If the number is not finite.\n * - Any error propagated from {@link normalizeToDecimalComponents}.\n *\n * @example\n * // Simple integer number\n * parseToFixedDecimal(42);\n * // => { sign: 1, digitsInteger: 42n, scale: 0 }\n *\n * @example\n * // Decimal fraction\n * parseToFixedDecimal(\"123.456\");\n * // => { sign: 1, digitsInteger: 123456n, scale: 3 }\n *\n * @example\n * // Number in exponential notation\n * parseToFixedDecimal(\"-1.23e-4\");\n * // => { sign: -1, digitsInteger: 123n, scale: 6 } // represents -0.000123\n *\n * @example\n * // Leading zeros and trailing fractional zeros are trimmed internally\n * parseToFixedDecimal(\"00045.67000\");\n * // => { sign: 1, digitsInteger: 4567n, scale: 2 } // \"45.67\"\n *\n * @example\n * // Very large integer input using bigint\n * parseToFixedDecimal(123456789012345678901234567890n);\n * // => { sign: 1, digitsInteger: 123456789012345678901234567890n, scale: 0 }\n *\n * @example\n * // Negative value with high precision fraction\n * parseToFixedDecimal(\"-0.00000003432\");\n * // => { sign: -1, digitsInteger: 3432n, scale: 11 }\n *\n * @see normalizeToDecimalComponents\n * @see FixedDecimal\n * @see fixedDecimalToNum\n * @see fixedDecimalToStr\n *\n * @category Parsing\n * @since 2.0.0\n * @public\n */\nexport function parseToFixedDecimal(input: unknown): FixedDecimal {\n\tconst { \n\t\tsign, \n\t\tintegerPart, \n\t\tfractionalPart, \n\t} = normalizeToDecimalComponents(input);\n\tconst integerDigits = integerPart.replace(/^0+/, '') || '0';\n\tconst fractionalDigits = fractionalPart.replace(/0+$/, '');\n\tconst combinedDigits = (integerDigits + fractionalDigits) || '0';\n\n\treturn {\n\t\tsign,\n\t\tdigitsInteger: BigInt(combinedDigits),\n\t\tscale: fractionalDigits.length,\n\t};\n}\n","import type { FixedDecimal } from './types';\n\n/**\n * Rounds a {@link FixedDecimal} value to the specified number of fractional digits,\n * using either **half-up** (standard rounding) or **truncation** (cut-off without rounding).\n *\n * @remarks\n * This function operates entirely in fixed-precision integer space (`BigInt` arithmetic),\n * so rounding is mathematically exact — it never suffers from floating-point errors.\n *\n * Internally, it determines how many fractional digits must be removed from\n * `source.digitsInteger` to reach the desired precision (`decimalPlaces`), divides\n * by `10 ** digitsToRemove`, and conditionally increments the result depending on\n * the remainder and rounding mode.\n *\n * It preserves the original `sign` and returns a new {@link FixedDecimal} object\n * with an updated `scale` (number of digits after the decimal point).\n *\n * ---\n * **Rounding modes:**\n * - `'half-up'` — standard rounding to nearest neighbor; `.5` rounds **away from zero**.\n * Example: `1.235 → 1.24`, `-1.235 → -1.24`.\n * - `'trunc'` — truncates digits beyond the target precision (rounds **toward zero**).\n * Example: `1.239 → 1.23`, `-1.239 → -1.23`.\n *\n * ---\n * @param source - The input {@link FixedDecimal} to round.\n * Must contain a valid combination of:\n * - `sign`: `1` or `-1`\n * - `digitsInteger`: a `BigInt` representing all digits (no decimal point)\n * - `scale`: number of digits after the decimal\n *\n * @param decimalPlaces - Target number of digits to keep **after the decimal point**.\n * Values less than 0 are treated as 0. \n * For example, rounding to `2` means \"keep two digits after the decimal\".\n *\n * @param roundMode - Rounding algorithm to use:\n * - `'half-up'` (default) → rounds 0.5 and higher up.\n * - `'trunc'` → simply removes extra digits without rounding up.\n *\n * @defaultValue `'half-up'`\n *\n * @returns A **new** {@link FixedDecimal} with the adjusted `digitsInteger`\n * and `scale` equal to `decimalPlaces`. \n * If the requested precision is greater than or equal to `source.scale`,\n * the source value is returned unchanged (shallow copy).\n *\n * @throws {Error}\n * - Never throws directly in normal use, but may propagate errors if invalid\n * numeric parameters are passed (e.g., non-integer `decimalPlaces`).\n *\n * ---\n * @example\n * // Half-up rounding\n * const value: FixedDecimal = { sign: 1, digitsInteger: 123456n, scale: 3 }; // 123.456\n * roundFixedDecimal(value, 2, 'half-up');\n * // => { sign: 1, digitsInteger: 12346n, scale: 2 } // 123.46\n *\n * @example\n * // Truncation (cut-off)\n * const value: FixedDecimal = { sign: 1, digitsInteger: 123456n, scale: 3 };\n * roundFixedDecimal(value, 2, 'trunc');\n * // => { sign: 1, digitsInteger: 12345n, scale: 2 } // 123.45\n *\n * @example\n * // No rounding needed (scale already smaller)\n * const v: FixedDecimal = { sign: -1, digitsInteger: 1234n, scale: 1 }; // -123.4\n * roundFixedDecimal(v, 3);\n * // => identical copy: { sign: -1, digitsInteger: 1234n, scale: 1 }\n *\n * @example\n * // Rounding very small values\n * const v: FixedDecimal = { sign: 1, digitsInteger: 123n, scale: 6 }; // 0.000123\n * roundFixedDecimal(v, 4);\n * // => { sign: 1, digitsInteger: 1n, scale: 4 } // 0.0001\n *\n * @example\n * // Rounding negative numbers (half-up → away from zero)\n * const v: FixedDecimal = { sign: -1, digitsInteger: 125n, scale: 2 }; // -1.25\n * roundFixedDecimal(v, 1, 'half-up');\n * // => { sign: -1, digitsInteger: 13n, scale: 1 } // -1.3\n *\n * @see FixedDecimal\n * @see parseToFixedDecimal\n * @see fixedDecimalToNum\n * @see fixedDecimalToStr\n * @see formatToNum\n *\n * @category Math\n * @since 2.0.0\n * @public\n */\nexport function roundFixedDecimal(\n\tsource: FixedDecimal,\n\tdecimalPlaces: number,\n\troundMode: 'half-up' | 'trunc' = 'half-up'\n): FixedDecimal {\n\tconst targetPrecision = Math.max(0, Math.trunc(decimalPlaces));\n\n\tif (source.scale <= targetPrecision) {\n\t\treturn { ...source };\n\t}\n\tconst digitsToRemove = source.scale - targetPrecision;\n\tconst divisionFactor = 10n ** BigInt(digitsToRemove);\n\tconst integerPart = source.digitsInteger / divisionFactor;\n\tconst remainder = source.digitsInteger % divisionFactor;\n\n\tif (roundMode === 'trunc' || remainder === 0n) {\n\t\treturn { \n\t\t\tsign: source.sign, \n\t\t\tdigitsInteger: integerPart, \n\t\t\tscale: targetPrecision, \n\t\t};\n\t}\n\tconst halfThreshold = divisionFactor / 2n;\n\tconst shouldRoundUp = remainder >= halfThreshold;\n\tconst roundedValue = shouldRoundUp ? integerPart + 1n : integerPart;\n\t\n\treturn { \n\t\tsign: source.sign, \n\t\tdigitsInteger: roundedValue, \n\t\tscale: targetPrecision, \n\t};\n}","import { fixedDecimalToNum } from './fixedDecimalToNum';\nimport { parseToFixedDecimal } from './parseToFixedDecimal';\nimport { roundFixedDecimal } from './roundFixedDecimal';\n\n/**\n * Converts an arbitrary numeric input to a JavaScript `number`, optionally rounding\n * it to a fixed number of fractional digits using **half-up** rounding.\n *\n * @remarks\n * This function is a convenience wrapper around your fixed-precision helpers:\n *\n * 1. {@link parseToFixedDecimal} — parses the unknown input (`number`/`string`/etc.)\n * into an exact, lossless fixed-decimal representation.\n * 2. `roundFixedDecimal` — (invoked only when `round > 1`) rounds that fixed-decimal\n * value to the requested scale using the **half-up** algorithm.\n * 3. {@link fixedDecimalToNum} — converts the (optionally rounded) fixed-decimal\n * back to a JavaScript `number`.\n *\n * Because rounding is done in fixed-precision space, you avoid common IEEE-754\n * floating-point artifacts (e.g., `0.1 + 0.2 !== 0.3`) during parsing/rounding.\n * Precision is finally limited only at the last step when the value is converted\n * to a JS `number`.\n *\n * @param value - Any value that represents a number. Typical cases:\n * - `number` (e.g., `12`, `-0.034`, `1e6`)\n * - numeric `string` (e.g., `\"42\"`, `\"-123.456\"`)\n * - values that your {@link parseToFixedDecimal} knows how to normalize.\n *\n * If the value cannot be parsed by {@link parseToFixedDecimal}, an error will be thrown from there.\n *\n * @param round - Target number of fractional digits for rounding **in fixed-precision**.\n * - If `round > 1`, the function rounds to exactly `round` digits after the decimal point\n * using **half-up** (i.e., `.5` rounds away from zero) via `roundFixedDecimal`.\n * - If `round <= 1`, no rounding is applied; the parsed value is passed through as-is.\n *\n * @defaultValue `1` (no rounding; passthrough)\n *\n * @returns The resulting numeric value as a JavaScript `number`.\n *\n * @throws {Error}\n * - Re-throws any parsing/normalization errors from {@link parseToFixedDecimal}.\n * - Re-throws any rounding errors from `roundFixedDecimal` (e.g., invalid scale).\n *\n * @example\n * // No rounding (default `round = 1` → passthrough)\n * numNormalize(\"123.456\"); // => 123.456\n * numNormalize(0.034); // => 0.034\n *\n * @example\n * // Round to 2 fractional digits (half-up)\n * numNormalize(\"123.456\", 2); // => 123.46 (because .456 → .46)\n * numNormalize(\"-1.235\", 2); // => -1.24 (half-up away from zero)\n *\n * @example\n * // Large values: parsed and rounded in fixed precision, then converted to number\n * numNormalize(\"234893249238948.000003432\", 6); // precise rounding in fixed space,\n * // final result as JS number\n *\n * @example\n * // Explicit passthrough (any `round <= 1` behaves the same)\n * numNormalize(\"1000.555\", 1); // => 1000.555 (no rounding step invoked)\n * numNormalize(\"1000.555\", 0); // => 1000.555 (still no rounding)\n *\n * @see parseToFixedDecimal\n * @see fixedDecimalToNum\n * @see roundFixedDecimal\n *\n * @category Number Formatting\n * @since 2.0.0\n * @public\n */\nexport function numNormalize(value: unknown, round: number = 1, throwError: boolean = false): number {\n\ttry {\n\t\treturn fixedDecimalToNum((round > 1) ? roundFixedDecimal(parseToFixedDecimal(value), round, 'half-up') : parseToFixedDecimal(value));\n\t}\n\tcatch (err: any) {\n\t\tif (throwError) {\n\t\t\tthrow err;\n\t\t}\n\t}\n\treturn 0;\n}\n","import { \n\tisStrFilled,\n\tisStr,\n\tstrTrim, \n} from '../index';\n\n/**\n * Converts any given string-like value into a lower-cased, trimmed string.\n *\n * @summary\n * Safely transforms an unknown value into a normalized lowercase string.\n * If the input is not a valid non-empty string, the function returns an empty string (`\"\"`).\n *\n * @param value - Any unknown input to convert to lowercase.\n *\n * @returns A lowercase string, or an empty string if the input is not a valid string.\n *\n * @remarks\n * ### Processing steps\n * 1. **Type check** — ensures the input is a string using {@link isStr}.\n * 2. **Trimming** — removes leading and trailing whitespace via {@link strTrim}.\n * 3. **Validation** — ensures the result is non-empty with {@link isStrFilled}.\n * 4. **Lowercasing** — calls `String.prototype.toLowerCase()` on the trimmed text.\n * 5. If the string is empty or not valid at any step, returns `\"\"`.\n *\n * ### Error safety\n * - The function **never throws**, regardless of input type.\n * - Non-string inputs (numbers, booleans, objects, arrays, `null`, `undefined`) all yield `\"\"`.\n *\n * ### Use cases\n * - Case-insensitive string comparison (normalize both sides with `strLowerCase`).\n * - Normalizing user input before storing or indexing.\n * - Simplifying logic where optional strings may be `null` or empty.\n *\n * ### Performance\n * - Time complexity: **O(n)** (where `n` = string length, due to trimming and lowercasing).\n * - Space complexity: **O(n)** (new string created by normalization).\n *\n * ### Examples\n *\n * @example\n * // Basic strings\n * strLowerCase('HELLO'); // => \"hello\"\n * strLowerCase(' TEST '); // => \"test\"\n *\n * @example\n * // Mixed types\n * strLowerCase(123); // => \"\"\n * strLowerCase(true); // => \"\"\n * strLowerCase(null); // => \"\"\n *\n * @example\n * // Empty or whitespace inputs\n * strLowerCase(' '); // => \"\"\n * strLowerCase(''); // => \"\"\n *\n * @example\n * // Already lowercase\n * strLowerCase('data'); // => \"data\"\n *\n * @see isStr\n * @see isStrFilled\n * @see strTrim\n *\n * @category String\n * @public\n * @since 2.0.0\n */\nexport function strLowerCase(value?: unknown): string {\n\tif (!isStr(value)) {\n\t\treturn '';\n\t}\n\tconst trimmed = strTrim(value);\n\t\n\treturn isStrFilled(trimmed) ? trimmed.toLowerCase() : '';\n}\n","import { \n\tisStrFilled,\n\tisStr,\n\tstrLowerCase, \n} from '../index';\n\nexport function strNormalCase(value?: unknown): string {\n\tif (!isStr(value)) {\n\t\treturn '';\n\t}\n\tconst parsed = strLowerCase(value);\n\t\n\treturn isStrFilled(parsed) ? (parsed[0].toUpperCase() + parsed.slice(1)) : '';\n}\n","import { \n\tisStr,\n\tstrTrim,\n\tstrUndefined, \n} from '../index';\n\n/**\n * Converts `undefined` or empty (whitespace-only) strings into `null`.\n *\n * @summary\n * Safely normalizes optional values by replacing both `undefined` and blank strings\n * with `null`, while preserving all other values as-is. \n * This helps unify \"missing\" or \"empty\" values under a single, database-friendly\n * `null` representation.\n *\n * @param value - Any input value that may be a string, `undefined`, or another type.\n *\n * @returns\n * - `null` if:\n * - The input is `undefined`, or\n * - The input is a string that becomes empty after trimming (using {@link strTrim}).\n * - Otherwise returns the original `value`.\n *\n * @remarks\n * ### Processing steps\n * 1. If `value` is `undefined`, returns `null`.\n * 2. If `value` is a string:\n * - Trims it with {@link strTrim}, removing whitespace and invisible characters.\n * - If the trimmed result is empty (`''`), returns `null`.\n * 3. Otherwise returns the original value unchanged.\n *\n * ### Behavior notes\n * - Non-string, defined values (like `0`, `false`, `{}`, `[]`) are **not modified**.\n * - The function is **pure** (non-mutating) and safe for use in JSON or ORM normalization.\n * - Often used to prepare form data, REST payloads, or DB entities for consistent nullability.\n *\n * ### Comparison with {@link strUndefined}\n * | Case | `strNull` | `strUndefined` |\n * |------|----------------|----------------------|\n * | `undefined` | `null` | `undefined` |\n * | `''` (empty string) | `null` | `undefined` |\n * | `'text'` | `'text'` | `'text'` |\n * | non-string (e.g. `0`) | `0` | `0` |\n *\n * ### Use cases\n * - Unifying “empty” form values before DB insertion (`''` or `undefined` → `null`)\n * - Sanitizing request bodies before persistence or validation\n * - Preventing inconsistent null/undefined states across backend and frontend layers\n *\n * ### Performance\n * - Time complexity: **O(n)** (depends on string length)\n * - Space complexity: **O(n)** (creates a trimmed string copy)\n *\n * ### Examples\n *\n * @example\n * // Empty and whitespace strings\n * strNull(''); // => null\n * strNull(' '); // => null\n *\n * @example\n * // Undefined also becomes null\n * strNull(undefined); // => null\n *\n * @example\n * // Non-empty strings remain as-is\n * strNull('Hello'); // => \"Hello\"\n * strNull(' Data '); // => \" Data \"\n *\n * @example\n * // Non-string types are preserved\n * strNull(0); // => 0\n * strNull(false); // => false\n * strNull([]); // => []\n * strNull({}); // => {}\n *\n * @see isStr\n * @see strTrim\n * @see strUndefined\n *\n * @category String\n * @public\n * @since 2.0.0\n */\nexport function strNull(value: unknown) {\n\treturn ((isStr(value) && strTrim(value) === '') || value === undefined) ? null : value;\n}\n","import { \n\tisStr,\n\tstrTrim, \n} from '../index';\n\n/**\n * Normalizes and validates a phone number into international format (`E.164` style).\n *\n * @summary\n * Converts various human-entered phone number formats (with spaces, dashes, parentheses,\n * or local prefixes) into a clean, standardized string beginning with `\"+\"`\n * and containing 10–15 digits.\n *\n * Returns `null` if the value is not a valid phone number after normalization.\n *\n * @param value - The input value to format. Can be any unknown type; only strings are processed.\n * @param defaultCountry - Optional international prefix to prepend for 10-digit local numbers\n * (defaults to `\"+7\"` — Russia/Kazakhstan). \n * Use your target country code (e.g., `\"+34\"` for Spain, `\"+1\"` for USA).\n *\n * @returns\n * A normalized phone number in `+XXXXXXXXXX` format if valid, or `null` if the input\n * cannot be interpreted as a valid number.\n *\n * @remarks\n * ### Normalization rules\n * 1. **Input validation:** \n * If `value` is not a string, returns `null`.\n *\n * 2. **Trimming and cleaning:** \n * Removes all whitespace, hyphens, parentheses, and dots.\n * Example: \n * `\" (123) 456-7890 \"` → `\"1234567890\"`.\n *\n * 3. **International formats:**\n * - `00` prefix (common in Europe) is replaced with `\"+\"`. \n * → `\"0049123456789\"` → `\"+49123456789\"`.\n *\n * 4. **Local numbers (10 digits):** \n * Prepends the `defaultCountry` code. \n * → `\"1234567890\"` → `\"+71234567890\"` (default country `+7`).\n *\n * 5. **Generic international numbers (9–15 digits):** \n * If not starting with `\"0\"`, adds `\"+\"` prefix. \n * → `\"380501234567\"` → `\"+380501234567\"`.\n *\n * 6. **Validation check:** \n * The result must match the pattern `/^\\+\\d{10,15}$/` \n * — i.e., plus sign followed by 10–15 digits. \n * If not, returns `null`.\n *\n * ### Error safety\n * - Never throws — all invalid or unexpected inputs return `null`.\n * - Automatically cleans up common formatting symbols without side effects.\n *\n * ### Performance\n * - Time complexity: **O(n)** (string length).\n * - Space complexity: **O(n)** (new string creation during cleanup).\n *\n * ### Common pitfalls\n * - Numbers starting with `\"0\"` are **rejected**, since they are ambiguous.\n * - 8-digit local formats are not automatically expanded — use a country-specific parser if needed.\n * - This function performs **basic formatting and validation**, not full ITU-T E.164 compliance.\n *\n * ### Examples\n *\n * @example\n * // International format already valid\n * formatToPhone('+380501234567'); // => \"+380501234567\"\n *\n * @example\n * // European \"00\" prefix\n * formatToPhone('00442079460729'); // => \"+442079460729\"\n *\n * @example\n * // Local 10-digit number (default country +7)\n * formatToPhone('9123456789'); // => \"+79123456789\"\n *\n * @example\n * // With custom default country\n * formatToPhone('9876543210', '+34'); // => \"+349876543210\"\n *\n * @example\n * // Strings with spaces, punctuation, parentheses\n * formatToPhone('(050) 123-45-67'); // => \"+70501234567\"\n * formatToPhone('+1 (202) 555-0183'); // => \"+12025550183\"\n *\n * @example\n * // Invalid or ambiguous inputs\n * formatToPhone(''); // => null\n * formatToPhone('000123456'); // => null\n * formatToPhone('abcdefgh'); // => null\n * formatToPhone(null); // => null\n * formatToPhone(true); // => null\n *\n * @see isStr\n * @see strTrim\n *\n * @category String\n * @public\n * @since 2.0.0\n */\nexport function formatToPhone(value?: unknown, defaultCountry = '+7'): string | null {\n\tif (!isStr(value)) {\n\t\treturn null;\n\t}\n\tlet phone = strTrim(value).replace(/[\\s\\-().]/g, '');\n\n\tif (/^00\\d{8,15}$/.test(phone)) {\n\t\tphone = '+' + phone.slice(2);\n\t}\n\telse if (/^\\d{10}$/.test(phone)) {\n\t\tphone = defaultCountry + phone;\n\t}\n\telse if (/^\\d{9,15}$/.test(phone) && !phone.startsWith('0')) {\n\t\tphone = '+' + phone;\n\t}\n\treturn /^\\+\\d{10,15}$/.test(phone) ? phone : null;\n}\n","import { isStr } from '../index';\n\n\n/**\n * Trims, normalizes, and cleans up invisible characters from a string.\n *\n * @summary\n * Safely converts any input into a clean, Unicode-normalized string with all\n * leading/trailing whitespace removed and zero-width characters stripped out.\n * \n * Returns an empty string (`\"\"`) for all non-string inputs.\n *\n * @param value - Any value that may contain text or string-like content.\n *\n * @returns A normalized, trimmed string without invisible Unicode separators.\n * Returns an empty string if `value` is not a string.\n *\n * @remarks\n * ### Processing steps\n * 1. **Type check:** \n * Uses {@link isStr} to ensure the input is a string. \n * Non-strings are converted to `\"\"`.\n *\n * 2. **Trimming:** \n * Removes all leading and trailing whitespace (`String.prototype.trim()`).\n *\n * 3. **Unicode normalization:** \n * Applies `normalize('NFKC')` — Compatibility Composition — which:\n * - Converts full-width and compatibility forms into canonical ones. \n * Example: `\"ABC\"` → `\"ABC\"`.\n * - Normalizes composed characters (e.g., `\"é\"` vs `\"é\"`).\n *\n * 4. **Invisible character cleanup:** \n * Removes hidden zero-width Unicode characters commonly introduced by copy/paste:\n * - `U+200B` ZERO WIDTH SPACE \n * - `U+200C` ZERO WIDTH NON-JOINER \n * - `U+200D` ZERO WIDTH JOINER \n * - `U+FEFF` ZERO WIDTH NO-BREAK SPACE (BOM)\n *\n * 5. **Safe stringification:** \n * Non-string values are returned as empty string rather than `\"undefined\"` or `\"null\"`.\n *\n * ### Benefits\n * - Eliminates subtle text differences that break comparisons or hashing.\n * - Prevents user input issues caused by hidden characters.\n * - Safe to use in both frontend and backend environments.\n *\n * ### Performance\n * - Time complexity: **O(n)** — proportional to the input string length.\n * - Space complexity: **O(n)** — creates a new normalized copy.\n *\n * ### Common use cases\n * - Sanitizing user input before validation or storage.\n * - Cleaning keys, tags, and names from external data sources.\n * - Preparing values for strict equality or hashing.\n *\n * ### Examples\n *\n * @example\n * // Basic trimming\n * strTrim(' Hello '); // => \"Hello\"\n *\n * @example\n * // Removes zero-width characters\n * strTrim('word\\u200B'); // => \"word\"\n *\n * @example\n * // Unicode normalization\n * strTrim('ABC'); // => \"ABC\"\n * strTrim('e\\u0301'); // => \"é\"\n *\n * @example\n * // Non-string inputs\n * strTrim(123); // => \"\"\n * strTrim(null); // => \"\"\n * strTrim(undefined); // => \"\"\n * strTrim({ text: 'hi' }); // => \"\"\n *\n * @see isStr\n * @see String.prototype.normalize\n *\n * @category String\n * @public\n * @since 2.0.0\n */\nexport function strTrim(value: unknown): string {\n\treturn String(isStr(value) ? value.trim().normalize('NFKC').replace(/[\\u200B-\\u200D\\uFEFF]/g, '') : '');\t\n}\n","import { \n\tisStr,\n\tstrTrim,\n\tstrNull, \n} from '../index';\n\n/**\n * Converts `null` or empty (whitespace-only) strings into `undefined`.\n *\n * @summary\n * Normalizes optional values by replacing both `null` and blank strings\n * with `undefined`, while keeping all other values unchanged. \n * This is useful when preparing objects for APIs or serialization,\n * where `undefined` fields are automatically omitted or ignored.\n *\n * @param value - Any value that may be a string, `null`, or another type.\n *\n * @returns\n * - `undefined` if:\n * - The value is `null`, or\n * - The value is a string that becomes empty after trimming (via {@link strTrim}).\n * - Otherwise returns the original value.\n *\n * @remarks\n * ### Processing steps\n * 1. If `value` is `null`, return `undefined`.\n * 2. If `value` is a string:\n * - Trim using {@link strTrim} to remove whitespace and invisible characters.\n * - If trimmed result is empty, return `undefined`.\n * 3. Otherwise, return the original value unchanged.\n *\n * ### Behavior notes\n * - Non-string, non-null values (`0`, `false`, `{}`, `[]`, etc.) are **not modified**.\n * - The function is **non-mutating** — it never changes the original reference.\n * - It complements {@link strNull}, depending on whether your system\n * prefers `undefined` (omit field) or `null` (explicit empty value).\n *\n * ### Comparison with {@link strNull}\n * | Case | `strNull` | `strUndefined` |\n * |------|----------------|----------------------|\n * | `null` | `null` | `undefined` |\n * | `undefined` | `null` | `undefined` |\n * | `''` (empty string) | `null` | `undefined` |\n * | `'text'` | `'text'` | `'text'` |\n * | Non-string (e.g. `0`) | `0` | `0` |\n *\n * ### Use cases\n * - Preparing data before sending to REST or GraphQL APIs \n * (so empty fields are omitted during JSON serialization)\n * - Cleaning form input values before saving or validation\n * - Ensuring `undefined` consistency in optional object properties\n *\n * ### Performance\n * - Time complexity: **O(n)** (depends on string length)\n * - Space complexity: **O(n)** (due to string trimming)\n *\n * ### Examples\n *\n * @example\n * // Empty and whitespace-only strings\n * strUndefined(''); // => undefined\n * strUndefined(' '); // => undefined\n *\n * @example\n * // null is also normalized\n * strUndefined(null); // => undefined\n *\n * @example\n * // Non-empty strings remain unchanged\n * strUndefined('Hello'); // => \"Hello\"\n *\n * @example\n * // Non-string types are preserved\n * strUndefined(0); // => 0\n * strUndefined(false); // => false\n * strUndefined([]); // => []\n * strUndefined({}); // => {}\n *\n * @see isStr\n * @see strTrim\n * @see strNull\n *\n * @category String\n * @public\n * @since 2.0.0\n */\nexport function strUndefined(value: unknown) {\n\treturn ((isStr(value) && strTrim(value) === '') || value === null) ? undefined : value\n}\n","import { \n\tisStr,\n\tstrTrim, \n} from '../index';\n\nexport const strNormalize = (v: unknown) => {\n\tif (!isStr(v)) {\n\t\treturn v;\n\t}\n\tconst t = String(strTrim(v) || '');\n\t\n\treturn t === '' \n\t\t? null \n\t\t: t.toLowerCase();\n};\n","import type { UrlObj } from './types';\n\nexport function urlObj(value: string = ''): UrlObj {\n\treturn {} as UrlObj;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/arr/arrFuncArgs.ts","../src/arr/arrSplitPortions.ts","../src/bool/boolNormalize.ts","../src/common/wait.ts","../src/date/dateFloorMin.ts","../src/date/dateStr.ts","../src/date/datePartsSec.ts","../src/date/dateSecParts.ts","../src/ip-addr/ipStrNum.ts","../src/ip-addr/ipNumStr.ts","../src/is/isArr.ts","../src/is/isArrFilled.ts","../src/is/isBool.ts","../src/is/isDate.ts","../src/is/isEmail.ts","../src/is/isExists.ts","../src/is/isFunc.ts","../src/is/isIpAddr.ts","../src/is/isMacAddr.ts","../src/is/isNum.ts","../src/is/isNumFloat.ts","../src/is/isNumN.ts","../src/is/isNumNZ.ts","../src/is/isNumP.ts","../src/is/isNumPZ.ts","../src/is/isObj.ts","../src/is/isObjFilled.ts","../src/is/isPassword.ts","../src/is/isPhone.ts","../src/is/isStr.ts","../src/is/isStrBool.ts","../src/is/isStrFilled.ts","../src/is/isStrAscDesc.ts","../src/is/isVar.ts","../src/is/isClass.ts","../src/json/jsonStrLike.ts","../src/json/jsonParse.ts","../src/json/jsonDecode.ts","../src/json/jsonEncode.ts","../src/num/fixedDecimalToStr.ts","../src/num/fixedDecimalToNum.ts","../src/num/convertExponentialToParts.ts","../src/num/normalizeToDecimalComponents.ts","../src/num/parseToFixedDecimal.ts","../src/num/roundFixedDecimal.ts","../src/num/numNormalize.ts","../src/str/strLowerCase.ts","../src/str/strNormalCase.ts","../src/str/strNull.ts","../src/str/strPhone.ts","../src/str/strTrim.ts","../src/str/strUndefined.ts","../src/str/strNormalize.ts","../src/url/urlObj.ts"],"names":["arrFuncArgs","value","isStr","src","buf","inQuote","quoteChar","esc","depthParen","depthBracket","depthBrace","items","finalize","trimmed","i","ch","raw","isStrBool","boolNormalize","n","numNormalize","rawStr","jsonDecode","arrSplitPortions","arr","portionLength","out","isBool","isNumP","isNumNZ","isStrFilled","wait","timeout","resolve","dateFloorMin","everyMinutes","date","step","m","floored","d","dateStr","pad","year","month","day","hours","minutes","seconds","datePartsSec","parts","days","dateSecParts","total","ipStrNum","ip","p","buffer","dv","ipNumStr","num","nbuffer","ndv","output","isArr","isArrFilled","isDate","isNum","emailRegex","isEmail","isExists","isFunc","IPV4_RE","isIpAddr","v","isMacAddr","isNumFloat","isNumN","isNumPZ","isObj","isObjFilled","isPassword","minLength","maxLength","requireUppercase","requireLowercase","requireDigit","requireSpecial","isPhone","valueProcessed","normalized","isStrAscDesc","isVar","isClass","QUOTED_RE","jsonStrLike","s","allowString","pr","jsonParse","str","item","key","jsonEncode","fixedDecimalToStr","signSymbol","allDigitsString","padZeros","integerBoundary","integerText","fractionalText","fixedDecimalToNum","convertExponentialToParts","sign","exponentialString","match","coefficient","exponentText","integerPart","fractionalPart","allDigits","exponentValue","exponent","digitsToLeft","missingZeros","splitIndex","normalizeToDecimalComponents","input","absoluteValue","exponentialForm","processed","parseToFixedDecimal","integerDigits","fractionalDigits","combinedDigits","roundFixedDecimal","source","decimalPlaces","roundMode","targetPrecision","digitsToRemove","divisionFactor","remainder","halfThreshold","roundedValue","round","throwError","err","strLowerCase","strTrim","strNormalCase","parsed","strNull","strPhone","defaultCountry","phone","strUndefined","strNormalize","t","urlObj"],"mappings":"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","file":"index.mjs","sourcesContent":["import { \n\tisStrBool,\n\tisStr, \n\tjsonDecode,\n\tboolNormalize,\n\tnumNormalize,\n} from '../index';\n\n/**\n * A narrow union describing which quoting characters are recognized by the parser.\n *\n * @remarks\n * The parser treats both single quotes (`'`) and double quotes (`\"`) as valid string\n * delimiters. When inside a quoted segment, commas are not considered separators,\n * and typical backslash escapes are honored (e.g., `\\\"`, `\\'`, `\\\\`).\n *\n * @public\n * @since 2.0.0\n */\ntype Quote = \"'\" | '\"' | null;\n\n/**\n * Parse a human-typed string of function-like arguments into a normalized array of JS values.\n *\n * @summary\n * Splits by **top-level commas** (ignoring commas that appear inside quotes, parentheses,\n * brackets, or braces) and **coerces** each token to a sensible JavaScript type:\n * `null`, `undefined`, booleans, numbers (including `Infinity`/`-Infinity`), strings\n * (with quote stripping and unescaping), and JSON objects/arrays. Tokens that look like\n * a macro or call marker (start with `$` and end with `)`) are returned **as is**.\n *\n * @remarks\n * ### How parsing works\n * 1. **Input normalization**\n * - Non-string inputs are returned as a single-element array `[value]`.\n * - Leading/trailing whitespace is trimmed.\n * - If the entire string is wrapped in square brackets (`[...]`), the brackets are\n * removed (so the function accepts both `a,b,c` and `[a, b, c]`).\n * - Empty input (after trimming or after removing `[...]`) yields `[]`.\n *\n * 2. **Tokenization by top-level commas**\n * - The string is scanned left-to-right.\n * - The parser tracks nesting **depth** for `()`, `[]`, `{}` and whether it is\n * currently **inside quotes**. A comma only splits tokens at **depth 0** and\n * **outside quotes**.\n *\n * 3. **Per-token coercion (in this order)**\n * - **Macro / call marker**: If a token starts with `$`, contains `(`, and ends\n * with `)`, it is returned unchanged (e.g., `\"$env(PATH)\"`).\n * - **Literals**: `null` → `null`, `undefined` → `undefined`.\n * - **Booleans**: Using {@link isStrBool} + {@link boolNormalize} (e.g., `\"true\"`,\n * `\"False\"`, `\"yes\"`, `\"0\"` depending on your implementation).\n * - **Numbers**: Using {@link numNormalize}. If the result is finite, it is returned.\n * Explicit `\"Infinity\"` and `\"-Infinity\"` are also supported.\n * - **Quoted strings**: `'text'` or `\"text\"` → inner text with escapes processed\n * (`\\\\` → `\\`, `\\'` → `'`, `\\\"` → `\"`).\n * - **JSON**: If token begins with `{` and ends with `}`, or begins with `[` and\n * ends with `]`, the function attempts `jsonDecode`. On failure, the raw string\n * is returned.\n * - **Fallback**: Raw token as string.\n *\n * ### Escaping inside quotes\n * - Backslash escaping is supported while inside quotes:\n * - `\\\\` for a literal backslash\n * - `\\\"` inside double quotes\n * - `\\'` inside single quotes\n *\n * ### Non-throwing behavior\n * - The function aims to be **robust** and **non-throwing**. Invalid JSON will be\n * returned as a plain string rather than crashing.\n *\n * ### Security considerations\n * - The parser **does not** evaluate code; it only returns strings or parsed values.\n * If you plan to execute anything returned (e.g., tokens starting with `$...`),\n * do so in a sandbox with explicit allow-lists.\n *\n * ### Limitations\n * - Numerical parsing relies on {@link numNormalize}. Extremely large or high-precision\n * decimals may still be subject to JavaScript `number` precision limits unless your\n * `numNormalize` converts to a safer representation.\n * - Only basic backslash escapes are handled in quoted strings (no `\\uXXXX` decoding here).\n * - Whitespace outside quotes is trimmed from each token; internal whitespace is preserved.\n *\n * @example\n * // Basic values\n * arrFuncArgs('1, true, \"hello\"'); // => [1, true, \"hello\"]\n *\n * @example\n * // Bracket-wrapped list\n * arrFuncArgs('[1, 2, 3]'); // => [1, 2, 3]\n *\n * @example\n * // Nested structures and quoting\n * arrFuncArgs('{\"a\":1,\"b\":[2,3]}, \"te,xt\", (x,y)'); // => [ {a:1,b:[2,3]}, \"te,xt\", \"(x,y)\" ]\n *\n * @example\n * // Booleans, null/undefined, and Infinity\n * arrFuncArgs('yes, NO, null, undefined, Infinity, -Infinity');\n * // => [true, false, null, undefined, Infinity, -Infinity]\n *\n * @example\n * // Macro-like token (returned as-is)\n * arrFuncArgs('$env(PATH)'); // => [\"$env(PATH)\"]\n *\n * @example\n * // Escapes inside quotes\n * arrFuncArgs('\"He said: \\\\\"Hi\\\\\"\", \\'It\\\\\\'s ok\\', \"\\\\\\\\path\"');\n * // => ['He said: \"Hi\"', \"It's ok\", \"\\\\path\"]\n *\n * @example\n * // Empty and whitespace inputs\n * arrFuncArgs(' '); // => []\n * arrFuncArgs('[]'); // => []\n * arrFuncArgs('[ ]'); // => []\n * arrFuncArgs(' [ a , b ] '); // => [\"a\", \"b\"]\n *\n * @param value - Raw string containing comma-separated arguments.\n * If `value` is **not** a string, the function returns `[value]` unchanged.\n *\n * @returns An array of coerced values (`unknown[]`). Each item is one parsed token.\n *\n * @see isStrBool\n * @see boolNormalize\n * @see numNormalize\n * @see jsonDecode\n *\n * @public\n * @since 2.0.0\n */\nexport function arrFuncArgs(value: string): unknown[] {\n\tif (!isStr(value)) {\n\t\treturn [value];\n\t}\n\tlet src = value.trim();\n\t\n\tif (src === '') {\n\t\treturn [];\n\t}\n\tif (src.startsWith('[') && src.endsWith(']')) {\n\t\tsrc = src.slice(1, -1).trim();\n\t\t\n\t\tif (src === '') {\n\t\t\treturn [];\n\t\t}\n\t}\n\tlet buf = '',\n\t\tinQuote = false,\n\t\tquoteChar: Quote = null,\n\t\tesc = false,\n\t\tdepthParen = 0,\n\t\tdepthBracket = 0,\n\t\tdepthBrace = 0;\n\n\tconst items: string[] = [];\n\tconst finalize = () => {\n\t\tconst trimmed = buf.trim();\n\t\t\n\t\tif (trimmed !== '') {\n\t\t\titems.push(trimmed);\n\t\t}\n\t\tbuf = '';\n\t};\n\n\tfor (let i = 0; i < src.length; i++) {\n\t\tconst ch = src[i];\n\n\t\tif (inQuote) {\n\t\t\tbuf += ch;\n\n\t\t\tif (esc) { \n\t\t\t\tesc = false; \n\t\t\t\tcontinue; \n\t\t\t}\n\t\t\tif (ch === '\\\\') { \n\t\t\t\tesc = true; \n\t\t\t\tcontinue; \n\t\t\t}\n\t\t\tif (ch === quoteChar) {\n\t\t\t\tinQuote = false;\n\t\t\t\tquoteChar = null;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (ch === '\"' || ch === \"'\") {\n\t\t\tinQuote = true;\n\t\t\tquoteChar = ch as Quote;\n\t\t\tbuf += ch;\n\t\t\t\n\t\t\tcontinue;\n\t\t}\n\t\tif (ch === '(') { \n\t\t\tdepthParen++; \n\t\t\tbuf += ch; \n\n\t\t\tcontinue; \n\t\t}\n\t\tif (ch === ')') { \n\t\t\tdepthParen = Math.max(0, depthParen - 1); \n\t\t\tbuf += ch; \n\t\t\t\n\t\t\tcontinue; \n\t\t}\n\t\tif (ch === '[') { \n\t\t\tdepthBracket++; \n\t\t\tbuf += ch; \n\t\t\t\n\t\t\tcontinue; \n\t\t}\n\t\tif (ch === ']') { \n\t\t\tdepthBracket = Math.max(0, depthBracket - 1); \n\t\t\tbuf += ch; \n\t\t\t\n\t\t\tcontinue; \n\t\t}\n\t\tif (ch === '{') { \n\t\t\tdepthBrace++; \n\t\t\tbuf += ch; \n\t\t\t\n\t\t\tcontinue; \n\t\t}\n\t\tif (ch === '}') { \n\t\t\tdepthBrace = Math.max(0, depthBrace - 1); \n\t\t\tbuf += ch; \n\n\t\t\tcontinue; \n\t\t}\n\t\tif (ch === ',' && depthParen === 0 && depthBracket === 0 && depthBrace === 0) {\n\t\t\tfinalize();\n\t\t\t\n\t\t\tcontinue;\n\t\t}\n\t\tbuf += ch;\n\t}\n\tif (buf.length) {\n\t\tfinalize();\n\t}\n\treturn items.map((raw: string): unknown => {\n\t\tif (raw.startsWith('$') && raw.includes('(') && raw.endsWith(')')) {\n\t\t\treturn raw;\n\t\t}\n\t\tif (raw === 'null') {\n\t\t\treturn null;\n\t\t}\n\t\tif (raw === 'undefined') {\n\t\t\treturn undefined;\n\t\t}\n\t\tif (isStrBool(raw)) {\n\t\t\treturn boolNormalize(raw);\n\t\t}\n\t\tconst n = numNormalize(raw as any);\n\t\t\n\t\tif (Number.isFinite(n)) {\n\t\t\treturn n;\n\t\t}\t\t\n\t\tif (raw === 'Infinity') {\n\t\t\treturn Infinity;\n\t\t}\n\t\tif (raw === '-Infinity') {\n\t\t\treturn -Infinity;\n\t\t}\n\t\tconst rawStr: string = String(raw || '');\n\t\tconst hasQuotes = rawStr.length >= 2\n\t\t\t&& ((rawStr.startsWith(\"'\") && rawStr.endsWith(\"'\")) \n\t\t\t\t|| (rawStr.startsWith('\"') && rawStr.endsWith('\"')));\n\n\t\tif (hasQuotes) {\n\t\t\treturn rawStr\n\t\t\t\t.slice(1, -1)\n\t\t\t\t.replace(/\\\\\\\\/g, '\\\\')\n\t\t\t\t.replace(/\\\\'/g, \"'\")\n\t\t\t\t.replace(/\\\\\"/g, '\"');\n\t\t}\n\t\tif ((rawStr.startsWith('{') && rawStr.endsWith('}')) || (rawStr.startsWith('[') && rawStr.endsWith(']'))) {\n\t\t\ttry {\n\t\t\t\treturn jsonDecode(rawStr);\n\t\t\t} \n\t\t\tcatch {\n\t\t\t}\n\t\t}\n\t\treturn rawStr;\n\t});\n}\n","\n/**\n * Splits an input array into smaller subarrays (portions) of a given fixed size.\n *\n * @summary\n * Returns an array of chunks, where each chunk contains at most `portionLength` elements.\n * The final chunk may contain fewer elements if the input array length is not evenly divisible\n * by `portionLength`.\n *\n * @typeParam T - Type of the elements in the input array.\n *\n * @param arr - The source array to be split. It can be any readonly array (or tuple).\n * @param portionLength - The desired size of each portion. Must be a **positive integer**.\n *\n * @returns A new two-dimensional array (`T[][]`), where each inner array is one portion.\n * If `portionLength` is not a positive integer, an empty array is returned.\n *\n * @remarks\n * - This function is **non-mutating**: the original array is never modified.\n * - If `portionLength` exceeds the array length, the result will be a single chunk\n * containing the entire array.\n * - If the input array is empty, the result is an empty array.\n * - Uses `Array.prototype.slice()` internally, so the returned chunks are **shallow copies**.\n *\n * ### Performance\n * - Time complexity: **O(n)** — each element is visited exactly once.\n * - Space complexity: **O(n)** — proportional to the total number of elements copied.\n * - For extremely large arrays (millions of elements), prefer a streaming approach\n * if memory is a concern.\n *\n * ### Edge cases\n * - `portionLength <= 0` → returns `[]`.\n * - `portionLength` is not an integer (e.g. `2.5`, `NaN`) → returns `[]`.\n * - `arr.length === 0` → returns `[]`.\n * - Works correctly with frozen arrays and readonly tuples.\n *\n * @example\n * // Split an array into groups of 3\n * arrSplitPortions([1, 2, 3, 4, 5, 6, 7], 3);\n * // => [[1, 2, 3], [4, 5, 6], [7]]\n *\n * @example\n * // Portion length larger than array\n * arrSplitPortions(['a', 'b'], 5);\n * // => [['a', 'b']]\n *\n * @example\n * // Non-integer or invalid sizes\n * arrSplitPortions([1, 2, 3], 0); // => []\n * arrSplitPortions([1, 2, 3], -2); // => []\n * arrSplitPortions([1, 2, 3], NaN); // => []\n *\n * @example\n * // Works with readonly arrays\n * const input = [10, 20, 30, 40] as const;\n * const result = arrSplitPortions(input, 2);\n * // result: [[10, 20], [30, 40]]\n *\n * @category Array\n * @public\n * @since 2.0.0\n */\nexport function arrSplitPortions<T>(arr: readonly T[], portionLength: number): T[][] {\n\tif (!Number.isInteger(portionLength) || portionLength <= 0) {\n\t\treturn [];\n\t}\n\tconst out: T[][] = [];\n\tlet i = 0;\n\t\n\twhile (i < arr.length) {\n\t\tout.push(arr.slice(i, i + portionLength));\n\t\ti += portionLength;\n\t}\n\treturn out;\n}\n","import { \n\tisBool,\n\tisNumP, \n\tisNumNZ,\n\tisStrFilled,\n} from '../index';\n\n/**\n * Converts any given value into a normalized boolean (`true` / `false`).\n *\n * @summary\n * Performs **loose coercion** of different input types into a `boolean`\n * following predictable rules for numbers, strings, and actual boolean values.\n * Non-recognized values always return `false`.\n *\n * @param value - Any unknown input that should be interpreted as a boolean.\n *\n * @returns The normalized boolean result (`true` or `false`).\n *\n * @remarks\n * This function is designed to **gracefully handle** a wide variety of input forms —\n * including primitive values, numeric types, and user-typed strings (like `\"yes\"`, `\"no\"`, `\"on\"`, `\"off\"`).\n *\n * ### Conversion Rules (in order of precedence)\n * 1. **Native booleans** → returned as-is.\n * - `true` → `true`\n * - `false` → `false`\n *\n * 2. **Positive numbers** → interpreted as `true`.\n * - `isNumP(value)` check passes (typically `> 0`).\n * - Examples: `1`, `42`, `3.14` → `true`\n *\n * 3. **Zero or negative numbers** → interpreted as `false`.\n * - `isNumNZ(value)` check passes (typically `<= 0`).\n * - Examples: `0`, `-1` → `false`\n *\n * 4. **Truthy strings** → `\"true\"`, `\"1\"`, `\"yes\"`, `\"on\"` (case-insensitive)\n * - `\"TrUe\"` → `true`\n * - `\" YES \"` → `true`\n *\n * 5. **Falsy strings** → `\"false\"`, `\"0\"`, `\"no\"`, `\"off\"` (case-insensitive)\n * - `\"False\"` → `false`\n * - `\" off \"` → `false`\n *\n * 6. **Everything else** → `false`\n * - `null`, `undefined`, `NaN`, empty string, symbols, objects, arrays, etc.\n *\n * ### String Handling\n * - Strings are **trimmed** and **lower-cased** before comparison.\n * - Case and whitespace are ignored.\n * - Empty strings (`\"\"`) return `false`.\n *\n * ### Error Safety\n * - The function **never throws**.\n * - Non-primitive or unexpected types are handled safely and result in `false`.\n *\n * ### Performance\n * - Time complexity: **O(1)**.\n * - Space complexity: **O(1)**.\n *\n * ### Examples\n *\n * @example\n * // Native booleans\n * boolNormalize(true); // => true\n * boolNormalize(false); // => false\n *\n * @example\n * // Numeric values\n * boolNormalize(1); // => true\n * boolNormalize(0); // => false\n * boolNormalize(-5); // => false\n *\n * @example\n * // String values\n * boolNormalize('yes'); // => true\n * boolNormalize('No'); // => false\n * boolNormalize('TRUE'); // => true\n * boolNormalize('false'); // => false\n * boolNormalize('on'); // => true\n * boolNormalize('off'); // => false\n *\n * @example\n * // Mixed and invalid inputs\n * boolNormalize(null); // => false\n * boolNormalize(undefined); // => false\n * boolNormalize([]); // => false\n * boolNormalize({}); // => false\n * boolNormalize('maybe'); // => false\n *\n * @see isBool\n * @see isNumP\n * @see isNumNZ\n * @see isStrFilled\n *\n * @category Conversion\n * @public\n * @since 2.0.0\n */\nexport function boolNormalize(value: unknown): boolean {\n\tswitch (true) {\n\t\tcase isBool(value):\n\t\t\treturn value;\n\n\t\tcase isNumP(value):\n\t\t\treturn true;\n\n\t\tcase isNumNZ(value):\n\t\t\treturn false;\n\n\t\tcase isStrFilled(value) && [ 'true', '1', 'yes', 'on' ].includes(String(value ?? '').trim().toLowerCase()):\n\t\t\treturn true;\n\n\t\tcase isStrFilled(value) && [ 'false', '0', 'no', 'off' ].includes(String(value ?? '').trim().toLowerCase()):\n\t\t\treturn false;\n\t}\n\treturn false;\n}\n","/**\n * Waits asynchronously for the specified amount of time.\n *\n * @summary\n * A tiny promise-based delay utility that resolves after `timeout` milliseconds.\n * It wraps `setTimeout` in a `Promise`, making it convenient to use with\n * `async/await` or as part of larger promise chains.\n *\n * @param timeout - The delay duration in **milliseconds** before the promise resolves.\n * @defaultValue 0\n *\n * @returns A `Promise<void | true>` that settles after the given delay.\n *\n * @example\n * // Basic usage: pause for ~500 ms\n * await wait(500);\n * console.log('Half a second later…');\n *\n * @example\n * // Measure elapsed time\n * const started = Date.now();\n * await wait(1200);\n * const elapsed = Date.now() - started; // ~= 1200ms (subject to timer clamping and scheduling)\n *\n * @example\n * // Use inside a retry/backoff loop\n * for (let attempt = 1; attempt <= 5; attempt++) {\n * try {\n * await doWork();\n * break;\n * } catch (err) {\n * // exponential backoff between attempts\n * await wait(2 ** attempt * 100);\n * }\n * }\n *\n * @example\n * // Parallel delays (resolve when the longest finishes)\n * await Promise.all([wait(100), wait(250), wait(50)]);\n *\n * @remarks\n * - **Timing accuracy:** JavaScript timers are **best-effort** and may be delayed\n * by event-loop load, CPU throttling, tab being backgrounded, or platform-specific\n * clamping. Treat `timeout` as a *minimum* delay, not an exact scheduler.\n * - **Negative or non-finite values:** Passing `<= 0`, `NaN`, or a non-finite value\n * effectively behaves like `0` and resolves on a future macrotask tick.\n * - **Cancellation:** This helper **does not support cancellation**. If you need to\n * abort a wait, consider a variant that accepts an `AbortSignal` and clears the\n * timer when aborted.\n * - **Event loop semantics:** `setTimeout(0)` schedules a **macrotask**; it does not\n * run synchronously. Code after `await wait(0)` will execute on a subsequent turn\n * of the event loop.\n * \n * Notes:\n * - Suitable for throttling UI interactions, pacing network retries, and writing\n * deterministic tests (with caution re: flakiness).\n * - Keep delays small in performance-critical code paths; prefer debouncing or\n * requestAnimationFrame for UI-animation pacing when appropriate.\n * \n * \tComplexity:\n * - Time: **O(1)** (scheduling a single timer)\n * - Space: **O(1)** (a promise and a timer reference)\n *\n * Performance:\n * - The function allocates a single promise and a timer handle.\n * - Timer resolution is platform dependent; Node.js and browsers may clamp very\n * small delays to a minimum threshold under load.\n *\n * Security:\n * - No I/O, side effects, or data exposure. Purely schedules a future resolution.\n * \n * <b>Returns remarks</b>:\n * The internal promise resolves with the value `true`, but callers typically\n * use `await wait(...)` and ignore the value. If you need a strictly `void`\n * result, you can cast or ignore the resolution value.\n *\n * @category Utilities • Timing\n * @since 1.0.0\n * @see {@link https://developer.mozilla.org/docs/Web/API/setTimeout MDN: setTimeout}\n */\nexport async function wait(timeout: number = 0) {\n\tawait (new Promise((resolve) => setTimeout(() => resolve(true), timeout)));\n}\n","/**\n * Floors a given {@link Date} object down to the nearest time interval in minutes.\n *\n * @remarks\n * This utility function is commonly used for time bucketing, grouping logs, or\n * aligning timestamps to fixed intervals (e.g. 5-minute or 15-minute marks).\n *\n * It takes an arbitrary `Date` and returns a **new** `Date` instance (it does not\n * mutate the input) where:\n *\n * - The `minutes` value is floored down to the nearest multiple of `everyMinutes`.\n * - `seconds` and `milliseconds` are reset to `0`.\n * - The hour and day remain unchanged.\n *\n * The step is automatically clamped to the range **1 – 60 minutes** to prevent\n * invalid or nonsensical values.\n * \n * The function allocates a single new `Date` object. \n * It is safe for high-frequency use in real-time systems and event batching.\n *\n * @param everyMinutes - The step interval (in minutes) used for rounding down.\n * Must be a positive finite number. \n * Values below 1 are treated as 1, values above 60 as 60.\n *\n * @param date - The input date to be floored. \n * Defaults to the current time (`new Date()`).\n *\n * @returns A **new** `Date` instance, representing the same hour as the input,\n * but with minutes rounded down to the nearest `everyMinutes` multiple.\n *\n * @example\n * ```ts\n * // Example 1: Floor to the nearest 15-minute mark\n * const d = new Date('2025-10-18T10:43:27');\n * dateFloorMin(15, d);\n * // -> 2025-10-18T10:30:00.000Z\n * ```\n *\n * @example\n * ```ts\n * // Example 2: Using default date (current time)\n * const nowFloored = dateFloorMin(10);\n * // -> e.g. 2025-10-18T09:20:00.000Z\n * ```\n *\n * @example\n * ```ts\n * // Example 3: Clamp behavior\n * dateFloorMin(-5, new Date()); // treated as 1 minute\n * dateFloorMin(999, new Date()); // treated as 60 minutes\n * ```\n *\n * @throws Never throws — invalid step values are automatically normalized.\n *\n * @see {@link Date#setMinutes} for the underlying mutation logic.\n * @see {@link Date#getMinutes} for how minutes are extracted from a Date.\n *\n * @public\n * @category Date & Time\n * @since 2.0.0\n */\nexport function dateFloorMin(everyMinutes = 1, date = new Date()): Date {\n\tconst step = Math.min(60, Math.max(1, Math.trunc(Math.abs(everyMinutes))));\n\tconst m = date.getMinutes();\n\tconst floored = Math.floor(m / step) * step;\n\tconst d = new Date(date);\n\t\n\td.setMinutes(floored, 0, 0);\n\t\n\treturn d;\n}\n","/**\n * Formats a {@link Date} object into a human-readable timestamp string\n * using the pattern `\"YYYY-MM-DD HH:mm:ss\"`.\n *\n * @remarks\n * This function is a simple and locale-independent date formatter that always\n * outputs a **24-hour clock** timestamp with leading zeros for all numeric parts.\n * \n * It does **not** depend on the user's locale or time zone settings beyond what\n * is stored in the provided `Date` object. If you pass a `Date` constructed\n * from UTC or local time, the formatted output will reflect that same basis.\n *\n * Each date/time component (month, day, hours, minutes, seconds) is padded to\n * two digits using {@link String.padStart}, ensuring consistent width such as\n * `2025-03-07 09:04:02`.\n * \n * - The format is fixed-width and consistent — ideal for logs, filenames,\n * and database-friendly timestamps.\n * - The output is **not ISO 8601** (which uses a `'T'` separator and optional\n * timezone offset). \n * Example: ISO → `\"2025-10-18T10:43:27Z\"` \n * This function → `\"2025-10-18 10:43:27\"`.\n *\n * @param date - The date to format. Defaults to the **current system time**\n * (`new Date()`).\n *\n * @returns A formatted timestamp string in `\"YYYY-MM-DD HH:mm:ss\"` form.\n *\n * @example\n * ```ts\n * // Example 1: Specific date\n * const d = new Date('2025-10-18T10:43:27Z');\n * dateStr(d);\n * // -> \"2025-10-18 10:43:27\"\n * ```\n *\n * @example\n * ```ts\n * // Example 2: Default (current) date\n * dateStr();\n * // -> e.g. \"2025-10-18 12:07:55\"\n * ```\n *\n * @example\n * ```ts\n * // Example 3: Padding behavior\n * const d = new Date('2025-03-07T09:04:02');\n * dateStr(d);\n * // -> \"2025-03-07 09:04:02\"\n * ```\n *\n * @throws Never throws.\n *\n * @see {@link Date} for JavaScript’s native date-handling API.\n * @see {@link Intl.DateTimeFormat} for locale-aware formatting if needed.\n *\n * @public\n * @category Date & Time\n * @since 2.0.0\n */\nexport function dateStr(date = new Date()): string {\n\tconst pad = (n: number) => String(n).padStart(2, '0');\n\n\tconst year = date.getFullYear();\n\tconst month = pad(date.getMonth() + 1);\n\tconst day = pad(date.getDate());\n\n\tconst hours = pad(date.getHours());\n\tconst minutes = pad(date.getMinutes());\n\tconst seconds = pad(date.getSeconds());\n\n\treturn `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;\n}\n","import type { TimeParts } from '../index';\nimport { dateSecParts } from '../index';\n\n/**\n * Converts a partial {@link TimeParts} structure (days, hours, minutes, seconds)\n * into a total number of **seconds**.\n *\n * @remarks\n * This helper provides a simple way to normalize human-readable time components\n * into a single scalar duration in seconds. \n * It can be useful for:\n * - time-based arithmetic (e.g., adding offsets to timestamps),\n * - scheduling or delay computation,\n * - serializing durations into numeric fields (e.g., databases or APIs).\n *\n * All fields (`days`, `hours`, `minutes`, `seconds`) are **optional**; any missing\n * value defaults to `0`. The calculation uses fixed conversion factors:\n *\n * - 1 day = 86 400 seconds \n * - 1 hour = 3 600 seconds \n * - 1 minute = 60 seconds\n * \n * - Fractional or negative numbers are accepted and processed arithmetically.\n * Example: `{ minutes: 1.5 }` → `90`; `{ hours: -1 }` → `-3600`.\n * - The function performs no validation; it assumes numeric input.\n * TypeScript typing (`number`) ensures intended usage.\n *\n * @param parts - A partial object containing any subset of time fields.\n * Missing values default to zero.\n *\n * @returns The total number of seconds represented by the provided time parts.\n *\n * @example\n * ```ts\n * // Example 1: Simple conversion\n * datePartsSec({ hours: 1, minutes: 30 }); // -> 5400\n *\n * // Example 2: Full time span\n * datePartsSec({ days: 2, hours: 3, minutes: 5, seconds: 10 });\n * // -> 183910\n *\n * // Example 3: Partial / missing fields\n * datePartsSec({}); // -> 0\n * datePartsSec({ minutes: 5 }); // -> 300\n * ```\n *\n * @throws Never throws.\n *\n * @see {@link dateSecParts} — the inverse operation that expands seconds back into components.\n *\n * @public\n * @category Date & Time\n * @since 2.0.0\n */\nexport function datePartsSec(parts: TimeParts): number {\n\tconst { days = 0, hours = 0, minutes = 0, seconds = 0 } = parts;\n\n\treturn days * 86400 + hours * 3600 + minutes * 60 + seconds;\n}\n","import type { TimeParts } from '../index';\nimport { datePartsSec } from '../index';\n\n/**\n * Decomposes a total number of seconds into discrete time components:\n * **days**, **hours**, **minutes**, and **seconds**.\n *\n * @remarks\n * This is the inverse operation of {@link datePartsSec}.\n * It converts a flat duration (in seconds) into a more human-readable structure\n * suitable for display, logging, or formatting.\n *\n * The function performs integer division using {@link Math.floor} for each component\n * and ensures that the result satisfies:\n *\n * ```\n * 0 <= hours < 24 \n * 0 <= minutes < 60 \n * 0 <= seconds < 60\n * ```\n *\n * Any fractional part of the input (e.g., `12.75`) is truncated (floored) to the\n * nearest lower whole second. \n * Negative or non-finite inputs are considered invalid and will throw an error.\n * \n * - Uses only a few arithmetic operations and is **O(1)**.\n * - Safe for real-time conversions or high-frequency usage (e.g., monitoring dashboards).\n *\n * @param total - Total duration in seconds. \n * Must be a **finite, non-negative number**.\n *\n * @returns A {@link TimeParts} object with integer fields:\n * - `days`\n * - `hours`\n * - `minutes`\n * - `seconds`\n *\n * @example\n * ```ts\n * // Example 1: Basic conversion\n * dateSecParts(3661);\n * // -> { days: 0, hours: 1, minutes: 1, seconds: 1 }\n * ```\n *\n * @example\n * ```ts\n * // Example 2: Multi-day value\n * dateSecParts(90061);\n * // -> { days: 1, hours: 1, minutes: 1, seconds: 1 }\n * ```\n *\n * @example\n * ```ts\n * // Example 3: Invalid input\n * dateSecParts(-10); // throws Error(\"Invalid total seconds\")\n * dateSecParts(NaN); // throws Error(\"Invalid total seconds\")\n * ```\n *\n * @throws {Error}\n * Thrown when `total` is not a finite, non-negative number.\n *\n * @see {@link datePartsSec} — the complementary function that aggregates components into seconds.\n * @see {@link TimeParts} — the return type describing the breakdown of time.\n *\n * @public\n * @category Date & Time\n * @since 2.0.0\n */\nexport function dateSecParts(total: number): TimeParts {\n\tif (!Number.isFinite(total) || total < 0) {\n\t\tthrow new Error('Invalid total seconds');\n\t}\n\tconst days = Math.floor(total / 86400);\n\tconst hours = Math.floor((total % 86400) / 3600);\n\tconst minutes = Math.floor((total % 3600) / 60);\n\tconst seconds = total % 60;\n\t\n\treturn { days, hours, minutes, seconds };\n}\n","import { ipNumStr } from '../index';\nimport { parseIPv4 } from './parseIPv4';\n\n/**\n * Converts a dotted-decimal IPv4 address string (e.g. `\"192.168.0.1\"`)\n * into its **32-bit unsigned integer** representation.\n *\n * @remarks\n * This function performs a strict validation of the IPv4 address and encodes\n * each of its four octets into a 32-bit number using **big-endian (network byte order)**.\n *\n * The resulting number is in the range `0..4_294_967_295` (`0xFFFFFFFF`),\n * where:\n *\n * - `\"0.0.0.0\"` → `0`\n * - `\"255.255.255.255\"` → `4294967295`\n *\n * This representation is particularly useful for:\n * - performing numeric range comparisons (e.g., IP ranges, CIDR checks);\n * - storing IPv4 values compactly in binary structures or databases;\n * - bitwise operations such as masking and subnet arithmetic.\n * \n * - The conversion uses a {@link DataView} and explicit byte writes\n * to guarantee consistent big-endian behavior across platforms.\n * - The output number is safe for 32-bit unsigned arithmetic via `>>> 0`.\n * - If you need the inverse operation, see {@link numToIpAddr}.\n *\n * @param ip - The IPv4 address in dotted-quad string form.\n *\n * @returns A 32-bit **unsigned integer** representing the given IPv4 address.\n *\n * @example\n * ```ts\n * // Example 1: Simple conversion\n * ipStrNum(\"192.168.0.1\");\n * // -> 3232235521\n *\n * // Example 2: Edge values\n * ipStrNum(\"0.0.0.0\"); // -> 0\n * ipStrNum(\"255.255.255.255\"); // -> 4294967295\n * ```\n *\n * @example\n * ```ts\n * // Example 3: Invalid input\n * ipStrNum(\"192.168.1\"); // throws Error(\"Invalid IPv4 address\")\n * ipStrNum(\"256.0.0.1\"); // throws Error(\"Invalid IPv4 address\")\n * ipStrNum(\"abc.def.ghi.jkl\"); // throws Error(\"Invalid IPv4 address\")\n * ```\n *\n * @throws {Error}\n * Thrown when:\n * - The input does not contain exactly four parts separated by dots.\n * - Any octet is not an integer between 0 and 255 inclusive.\n *\n * @see {@link numToIpAddr} — converts a 32-bit integer back to an IPv4 string.\n * @see {@link parseIPv4} — similar numeric parser using bitwise operations.\n *\n * @public\n * @category Network & IP\n * @since 2.0.0\n */\nexport function ipStrNum(ip: string): number {\n\tconst parts = ip.split('.').map(p => Number(p));\n\n\tif (parts.length !== 4 || parts.some(p => !Number.isInteger(p) || p < 0 || p > 255)) {\n\t\tthrow new Error('Invalid IPv4 address');\n\t}\n\n\tconst buffer = new ArrayBuffer(4);\n\tconst dv = new DataView(buffer);\n\tlet i = 0;\n\n\twhile (i < 4) {\n\t\tdv.setUint8(i, parts[i]);\n\t\ti++;\n\t}\n\treturn dv.getUint32(0, false);\n}\n","import { \n\tisNumP,\n\tipStrNum, \n} from '../index';\n\n/**\n * Converts a 32-bit unsigned integer (numeric IPv4 representation)\n * back into its dotted-decimal string form (e.g. `\"192.168.0.1\"`).\n *\n * @remarks\n * This is the inverse of {@link ipStrNum}. \n * It interprets the input number as a **big-endian (network-byte-order)**\n * IPv4 value, extracting each of the four octets and joining them into\n * the standard dotted-quad notation.\n *\n * If the input is not a valid finite number (checked via {@link isNumP}),\n * an empty string `\"\"` is returned instead of throwing an exception.\n *\n * The resulting string always consists of **exactly four decimal octets**\n * separated by dots, with each octet in the range `0–255`.\n * \n * - Internally uses {@link DataView} to ensure consistent big-endian behavior\n * across all platforms.\n * - The output format is always normalized (no leading zeros, no spaces).\n * - For the forward direction (string → number), see {@link ipStrNum}.\n *\n * @param num - The 32-bit unsigned integer representing an IPv4 address.\n *\n * @returns A dotted-decimal IPv4 string (e.g. `\"10.0.0.1\"`), \n * or an empty string if the input is invalid.\n *\n * @example\n * ```ts\n * // Example 1: Basic conversion\n * ipNumStr(3232235521);\n * // -> \"192.168.0.1\"\n *\n * // Example 2: Edge values\n * ipNumStr(0); // -> \"0.0.0.0\"\n * ipNumStr(4294967295); // -> \"255.255.255.255\"\n * ```\n *\n * @example\n * ```ts\n * // Example 3: Invalid inputs\n * ipNumStr(NaN); // -> \"\"\n * ipNumStr(Infinity); // -> \"\"\n * ipNumStr(-5); // -> \"\"\n * ```\n *\n * @throws Never throws; invalid inputs simply return an empty string.\n *\n * @see {@link ipStrNum} — converts dotted IPv4 strings to numeric form.\n * @see {@link parseIPv4} — alternative parser using bitwise arithmetic.\n *\n * @public\n * @category Network & IP\n * @since 2.0.0\n */\nexport function ipNumStr(num: number): string {\n\tif (!isNumP(num)) {\n\t\treturn '';\n\t}\n\tconst nbuffer = new ArrayBuffer(4);\n\tconst ndv = new DataView(nbuffer);\n\n\tndv.setUint32(0, num, false);\n\n\tconst output: number[] = [];\n\tlet i = 0;\n\t\n\twhile (i < 4) {\n\t\toutput.push(ndv.getUint8(i));\n\t\ti++;\n\t}\n\treturn output.join('.');\n}\n","/**\n * Checks whether a given value is an array.\n *\n * @summary\n * A strongly typed wrapper around {@link Array.isArray}, with an enhanced TypeScript\n * type guard that asserts the value as a **readonly non-empty array** (`readonly [T, ...T[]]`).\n *\n * @typeParam T - The expected element type of the array (defaults to `unknown`).\n *\n * @param value - Any value to test.\n *\n * @returns `true` if the value is an array (of any kind), otherwise `false`.\n * The return type acts as a **type guard**, allowing TypeScript to infer that\n * `value` is a readonly array of `T` when the function returns `true`.\n *\n * @remarks\n * - Internally uses the native {@link Array.isArray} method.\n * - Works correctly across realms (e.g., iframes, worker contexts, etc.).\n * - The type guard ensures `value` is a **readonly non-empty array**, not just an empty list.\n * This provides safer downstream access patterns when empty arrays are not expected.\n * - If you need to allow empty arrays, consider changing the type to `readonly T[]`.\n *\n * ### Performance\n * - Time complexity: **O(1)** — constant time native check.\n * - Space complexity: **O(1)**.\n *\n * ### Common pitfalls\n * - `isArr([])` → `true`, even though the static type is `readonly [T, ...T[]]`.\n * TypeScript does not validate runtime emptiness; you should still check `value.length`.\n * - `isArr('abc')` → `false`\n * - `isArr({ length: 3 })` → `false`\n *\n * ### Examples\n *\n * @example\n * // Basic usage\n * isArr([1, 2, 3]); // => true\n * isArr('hello'); // => false\n * isArr({}); // => false\n *\n * @example\n * // With type inference\n * const val: unknown = [10, 20];\n * if (isArr<number>(val)) {\n * // TypeScript now knows val: readonly [number, ...number[]]\n * console.log(val[0]); // OK\n * }\n *\n * @example\n * // With mixed content\n * isArr([true, 'text', 123]); // => true\n *\n * @see Array.isArray\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isArr<T = unknown>(value: unknown): value is readonly [T, ...T[]] {\n\treturn Array.isArray(value);\n}\n","import { isArr } from '../index';\n\n\n/**\n * Checks whether a value is a **non-empty array**.\n *\n * @summary\n * A strongly-typed type guard that returns `true` only if the input value is an array\n * (via {@link isArr}) and contains at least one element (`length > 0`).\n * \n * Useful for narrowing unknown data to a **readonly non-empty tuple type**\n * (`readonly [T, ...T[]]`), which gives TypeScript safer access guarantees.\n *\n * @typeParam T - Expected element type of the array (defaults to `unknown`).\n *\n * @param value - Any value to test.\n *\n * @returns `true` if `value` is an array with at least one element; otherwise `false`.\n *\n * @remarks\n * ### Type narrowing\n * When this function returns `true`, TypeScript automatically infers that:\n * ```ts\n * value is readonly [T, ...T[]]\n * ```\n * \n * That means inside the `if` block, you can safely access `value[0]`\n * without additional checks.\n *\n * ### Behavior\n * - Delegates the array check to {@link isArr}.\n * - Works with both mutable (`T[]`) and readonly arrays (`readonly T[]`).\n * - Does **not** mutate or clone the array.\n * - Returns `false` for:\n * - Non-array values (`null`, `undefined`, `object`, `string`, etc.).\n * - Empty arrays (`[]`).\n *\n * ### Performance\n * - Time complexity: **O(1)** (constant time check).\n * - Space complexity: **O(1)**.\n *\n * ### Examples\n *\n * @example\n * // Basic usage\n * isArrFilled([1, 2, 3]); // => true\n * isArrFilled([]); // => false\n *\n * @example\n * // With type inference\n * const maybeNumbers: unknown = [10, 20];\n * if (isArrFilled<number>(maybeNumbers)) {\n * // value is now typed as: readonly [number, ...number[]]\n * console.log(maybeNumbers[0]); // OK\n * }\n *\n * @example\n * // Non-array values\n * isArrFilled('abc'); // => false\n * isArrFilled(null); // => false\n * isArrFilled(undefined); // => false\n * isArrFilled({ length: 2 }); // => false\n *\n * @see isArr\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isArrFilled<T = unknown>(value: unknown): value is readonly [ T, ...T[] ] {\n\treturn isArr(value) && value.length > 0;\n}\n","/**\n * Checks whether a given value is a boolean (`true` or `false`).\n *\n * @summary\n * A strict type guard that returns `true` only if `value` is of type `\"boolean\"`.\n * \n * This helps safely narrow unknown or mixed-type values in TypeScript code,\n * especially when working with dynamic data sources, JSON, or user input.\n *\n * @param value - Any value to check.\n *\n * @returns `true` if the value is strictly a boolean, otherwise `false`.\n *\n * @remarks\n * - Uses the built-in `typeof` operator (`typeof value === \"boolean\"`). \n * - Does **not** coerce values — only primitive `true` or `false` are accepted.\n * - Returns `false` for Boolean objects created via `new Boolean()`, because those\n * are of type `\"object\"`, not `\"boolean\"`.\n * - Designed as a **type guard**, so when it returns `true`, TypeScript will infer:\n * ```ts\n * value is boolean\n * ```\n *\n * ### Performance\n * - Time complexity: **O(1)** (constant).\n * - Space complexity: **O(1)**.\n *\n * ### Examples\n *\n * @example\n * // Basic usage\n * isBool(true); // => true\n * isBool(false); // => true\n * isBool(0); // => false\n * isBool('true'); // => false\n *\n * @example\n * // With type narrowing\n * const val: unknown = Math.random() > 0.5 ? true : 'yes';\n * if (isBool(val)) {\n * // TypeScript now knows val: boolean\n * console.log(val ? 'OK' : 'NO');\n * }\n *\n * @example\n * // Boolean object is not accepted\n * isBool(new Boolean(true)); // => false\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isBool(value: unknown): value is boolean {\n\treturn typeof value === 'boolean';\n}\n","import { \n\tisStr,\n\tisNum, \n} from '../index';\n\n/**\n * Checks whether a value represents a **valid JavaScript date**.\n *\n * @summary\n * Returns `true` if the given value is either:\n * - an actual `Date` instance with a valid timestamp, or\n * - a string or number that can be successfully parsed by the JavaScript `Date` constructor.\n *\n * Returns `false` for invalid dates (`Invalid Date`), empty strings, `NaN`, or non-date types.\n *\n * @param value - Any value to test (can be a `Date`, string, number, or other type).\n *\n * @returns `true` if the value can be interpreted as a valid date, otherwise `false`.\n *\n * @remarks\n * ### Validation logic\n * 1. **If `value` is a `Date` instance:** \n * Checks `!Number.isNaN(value.getTime())` — ensures it’s a real date, not an invalid one.\n * ```ts\n * isDate(new Date('invalid')); // false\n * ```\n *\n * 2. **If `value` is a string or number:** \n * Attempts to construct a new `Date(value)`. \n * Returns `true` only if the resulting date’s timestamp is finite (not `NaN`).\n *\n * 3. **Otherwise:** \n * Returns `false`.\n *\n * ### What counts as \"valid\"\n * - OK: `\"2024-12-31\"`, `\"2024-12-31T23:59:59Z\"`, `1728000000000`, `new Date()`\n * - BAD: `\"abc\"`, `NaN`, `{}`, `null`, `undefined`, `new Date('invalid')`\n *\n * ### Type safety\n * - This is **not** a strict type guard (it doesn’t narrow to `Date`), \n * but you can pair it with a cast when `true`:\n * ```ts\n * if (isDate(v)) {\n * const d = new Date(v); // guaranteed valid\n * }\n * ```\n *\n * ### Performance\n * - Time complexity: **O(1)** \n * (`Date` construction and timestamp check are constant-time operations).\n * - Space complexity: **O(1)**.\n *\n * ### Examples\n *\n * @example\n * // Valid Date instances\n * isDate(new Date()); // => true\n * isDate(new Date('2024-05-01')); // => true\n *\n * @example\n * // From strings or timestamps\n * isDate('2025-01-01T00:00:00Z'); // => true\n * isDate(1700000000000); // => true\n * isDate('not-a-date'); // => false\n *\n * @example\n * // Invalid cases\n * isDate({}); // => false\n * isDate([]); // => false\n * isDate(''); // => false\n * isDate(new Date('invalid')); // => false\n *\n * @see isStr\n * @see isNum\n * @see Date\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isDate(value: unknown): boolean {\n\tif (value instanceof Date) {\n\t\treturn !Number.isNaN(value.getTime());\n\t}\n\tif (isStr(value) || isNum(value)) {\n\t\tconst d = new Date(value as any);\n\n\t\treturn !Number.isNaN(d.getTime());\n\t}\n\treturn false;\n}\n","import { isStrFilled } from '../index';\n\nconst emailRegex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z]{2,})+$/;\n\n/**\n * Checks whether a given value is a **valid email address**.\n *\n * @summary\n * Validates that the input is a non-empty string and matches a simplified but\n * practical email pattern according to RFC 5322-compatible syntax rules.\n *\n * @param value - Any value to test (string or unknown).\n *\n * @returns `true` if the value is a non-empty string that looks like a valid email, \n * otherwise `false`.\n *\n * @remarks\n * ### Validation process\n * 1. Ensures the input is a **non-empty string** via {@link isStrFilled}.\n * 2. Tests the value against a precompiled **regular expression**:\n * ```\n * /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+\n * @[a-zA-Z0-9]\n * (?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\n * (?:\\.[a-zA-Z]{2,})+$/\n * ```\n * This allows standard ASCII characters in the local part and enforces:\n * - at least one `@` separator \n * - valid domain and subdomain segments \n * - a top-level domain of at least two letters.\n *\n * ### Behavior notes\n * - Returns `false` for empty strings, `null`, `undefined`, or non-string inputs.\n * - Does **not** perform DNS or MX record validation — only syntactic matching.\n * - Intended for lightweight client-side or structural checks.\n * - If you need full compliance with RFC 6531 (Unicode / IDN), normalize the address first.\n *\n * ### Performance\n * - Time complexity: **O(n)** — proportional to input length.\n * - Space complexity: **O(1)**.\n * - The compiled regex is cached and reused for efficiency.\n *\n * ### Examples\n *\n * @example\n * // Valid emails\n * isEmail('user@example.com'); // => true\n * isEmail('john.doe+alias@mail.co.uk'); // => true\n *\n * @example\n * // Invalid formats\n * isEmail(''); // => false\n * isEmail('user@'); // => false\n * isEmail('@example.com'); // => false\n * isEmail('user@@example.com'); // => false\n * isEmail('user example@domain.com'); // => false\n *\n * @example\n * // Non-string inputs\n * isEmail(null); // => false\n * isEmail(undefined); // => false\n * isEmail(12345); // => false\n *\n * @see isStrFilled\n *\n * @category Validation\n * @public\n * @since 2.0.0\n */\nexport function isEmail(value: unknown): value is string {\n\tif (!isStrFilled(value)) {\n\t\treturn false;\n\t}\n\treturn emailRegex.test(value);\n}\n","/**\n * Checks whether a value **exists** — i.e. is neither `null` nor `undefined`.\n *\n * @summary\n * A minimal and strongly typed utility that acts as a **type guard**\n * to filter out `null` and `undefined` values in TypeScript. \n * It is especially useful in array filters and conditional checks\n * where you need to ensure a value is \"present\".\n *\n * @typeParam T - The original type of the tested value.\n *\n * @param value - Any value that may be `null` or `undefined`.\n *\n * @returns `true` if `value` is not `null` and not `undefined`, otherwise `false`.\n *\n * @remarks\n * ### Type narrowing\n * When this function returns `true`, TypeScript automatically infers:\n * ```ts\n * value is T\n * ```\n * \n * That means inside the `if` block (or after using `Array.filter(isExists)`),\n * the compiler knows the value cannot be `null` or `undefined`.\n *\n * ### Behavior\n * - Returns `false` for `null` and `undefined`.\n * - Returns `true` for any other type — including `false`, `0`, `''`, `NaN`, empty arrays, etc.\n * - The check is **strict** (`!==`) — no type coercion occurs.\n *\n * ### Typical use cases\n * - Filtering arrays that may contain `null` or `undefined`.\n * - Guarding optional values before access.\n * - Simplifying type-safe checks in functional chains.\n *\n * ### Performance\n * - Time complexity: **O(1)**\n * - Space complexity: **O(1)**\n *\n * ### Examples\n *\n * @example\n * // Basic checks\n * isExists(null); // => false\n * isExists(undefined); // => false\n * isExists(0); // => true\n * isExists(''); // => true\n * isExists(false); // => true\n *\n * @example\n * // With TypeScript narrowing\n * const val: string | null | undefined = getValue();\n * if (isExists(val)) {\n * // val is now guaranteed to be a string\n * console.log(val.toUpperCase());\n * }\n *\n * @example\n * // Filtering nullable arrays\n * const arr = [1, null, 2, undefined, 3];\n * const clean = arr.filter(isExists);\n * // clean: number[] => [1, 2, 3]\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isExists<T>(value: T | null | undefined): value is T {\n\treturn value !== null && value !== undefined;\n}\n","/**\n * Checks whether a given value is a **function**.\n *\n * @summary\n * A strict type guard that returns `true` only if `value` is a callable function. \n * It works with regular functions, arrow functions, async functions, class constructors,\n * and built-in functions like `setTimeout`.\n *\n * @typeParam T - The expected function type to narrow to (defaults to the base `Function` type).\n *\n * @param value - Any value to check.\n *\n * @returns `true` if the value is of type `\"function\"`, otherwise `false`.\n *\n * @remarks\n * ### Type narrowing\n * When this function returns `true`, TypeScript infers that:\n * ```ts\n * value is T\n * ```\n * \n * This allows safe calling of the function or using its specific signature.\n *\n * ### Behavior\n * - Returns `true` for:\n * - Normal functions: `function test() {}`\n * - Arrow functions: `() => {}`\n * - Async functions: `async () => {}`\n * - Generator functions: `function* gen() {}`\n * - Class constructors (typeof `MyClass`).\n * - Returns `false` for:\n * - Non-callable objects or primitives.\n * - Function-like objects that aren't real functions (e.g., `{ call() {} }`).\n *\n * ### Performance\n * - Time complexity: **O(1)**\n * - Space complexity: **O(1)**\n *\n * ### Examples\n *\n * @example\n * // Basic usage\n * isFunc(() => {}); // => true\n * isFunc(function test() {}); // => true\n * isFunc(class A {}); // => true\n * isFunc(123); // => false\n * isFunc({}); // => false\n *\n * @example\n * // Type narrowing\n * const fn: unknown = () => 'ok';\n * if (isFunc<() => string>(fn)) {\n * const result = fn(); // result: string\n * }\n *\n * @example\n * // Class constructors are also \"functions\"\n * class MyClass {}\n * isFunc(MyClass); // => true\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isFunc<T extends Function = Function>(value: unknown): value is T {\n\treturn typeof value === 'function';\n}\n","import { isStr } from '../index';\n\nconst IPV4_RE = /^(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$/;\n\n/**\n * Checks whether a given value is a **valid IPv4 address**.\n *\n * @summary\n * Validates that the input is a string containing four octets (e.g. `\"192.168.0.1\"`),\n * where each octet is a number between `0` and `255`, separated by dots.\n *\n * @param value - Any value to test (string or unknown).\n *\n * @returns `true` if the value is a syntactically valid IPv4 address, otherwise `false`.\n *\n * @remarks\n * ### Validation steps\n * 1. Ensures the input is a string via {@link isStr}.\n * 2. Trims leading and trailing whitespace.\n * 3. Tests the cleaned string against a strict regular expression for IPv4 format:\n * ```\n * /^(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.\n * (25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.\n * (25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.\n * (25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$/\n * ```\n * Each group allows:\n * - `0–9`, `00–99`, `100–199`, `200–249`, `250–255`\n *\n * ### Behavior notes\n * - Returns `false` for non-strings, empty strings, or malformed IPs.\n * - Does **not** support IPv6 (use a separate validator for that).\n * - Does **not** perform CIDR or subnet validation — only syntax checking.\n * - Leading zeros are allowed (e.g. `\"010.000.000.001\"` is accepted, as per regex).\n *\n * ### Performance\n * - Time complexity: **O(1)** (fixed regex evaluation).\n * - Space complexity: **O(1)**.\n *\n * ### Examples\n *\n * @example\n * // Valid IPv4 addresses\n * isIpAddr('192.168.0.1'); // => true\n * isIpAddr('8.8.8.8'); // => true\n * isIpAddr('0.0.0.0'); // => true\n * isIpAddr('255.255.255.255'); // => true\n *\n * @example\n * // Invalid IPv4 strings\n * isIpAddr('256.0.0.1'); // => false (octet > 255)\n * isIpAddr('192.168.0'); // => false (missing octet)\n * isIpAddr('192.168.0.1.5'); // => false (too many octets)\n * isIpAddr('192.168.0.A'); // => false (non-numeric)\n * isIpAddr('192,168,0,1'); // => false (wrong separator)\n *\n * @example\n * // Non-string inputs\n * isIpAddr(12345); // => false\n * isIpAddr(null); // => false\n * isIpAddr(undefined); // => false\n *\n * @see isStr\n *\n * @category Validation\n * @public\n * @since 2.0.0\n */\nexport function isIpAddr(value: unknown): value is string {\n\tif (!isStr(value)) {\n\t\treturn false;\n\t}\n\tconst v = value.trim();\n\t\n\treturn IPV4_RE.test(v);\n}\n","import { isStr } from '../index';\n\n/**\n * Checks whether a given value is a **valid MAC address**.\n *\n * @summary\n * Validates that the input is a string formatted as a standard 6-octet\n * MAC (Media Access Control) address, consisting of 12 hexadecimal digits\n * separated by either colons (`:`) or hyphens (`-`).\n *\n * @param value - Any value to test (typically a string from user input or network data).\n *\n * @returns `true` if the value matches the MAC address pattern, otherwise `false`.\n *\n * @remarks\n * ### Accepted formats\n * - `00:1A:2B:3C:4D:5E`\n * - `00-1A-2B-3C-4D-5E`\n * - Both uppercase and lowercase hexadecimal digits are allowed.\n * - Mixed separators (e.g., `\"00:1A-2B:3C-4D:5E\"`) are **not** accepted.\n *\n * ### Validation logic\n * 1. Confirms that `value` is a string via {@link isStr}.\n * 2. Uses the following regular expression:\n * ```\n * /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/\n * ```\n * which enforces:\n * - Exactly 6 byte segments (`xx:xx:xx:xx:xx:xx` or `xx-xx-xx-xx-xx-xx`)\n * - Each segment: two hexadecimal digits (`0–9`, `A–F`, `a–f`)\n * - A consistent separator (`:` or `-`)\n *\n * ### Behavior notes\n * - Returns `false` for empty strings, non-strings, or malformed addresses.\n * - Does **not** support 8-octet EUI-64 or Cisco short 3-octet formats.\n * - Does **not** check for broadcast or multicast address semantics — only syntax.\n *\n * ### Performance\n * - Time complexity: **O(1)** (fixed regex match)\n * - Space complexity: **O(1)** (no allocations beyond regex)\n *\n * ### Examples\n *\n * @example\n * // Valid MAC addresses\n * isMacAddr('00:1A:2B:3C:4D:5E'); // => true\n * isMacAddr('AA-BB-CC-DD-EE-FF'); // => true\n * isMacAddr('ff:ff:ff:ff:ff:ff'); // => true\n *\n * @example\n * // Invalid MAC addresses\n * isMacAddr('00:1A:2B:3C:4D'); // => false (too short)\n * isMacAddr('00:1A:2B:3C:4D:5E:7F'); // => false (too long)\n * isMacAddr('00:1A:2B:3C:4D:ZZ'); // => false (invalid hex)\n * isMacAddr('001A.2B3C.4D5E'); // => false (wrong format)\n * isMacAddr(''); // => false\n *\n * @example\n * // Non-string values\n * isMacAddr(null); // => false\n * isMacAddr(undefined); // => false\n * isMacAddr(123456); // => false\n *\n * @see isStr\n * @see isIp\n *\n * @category Validation\n * @public\n * @since 2.0.0\n */\nexport function isMacAddr(value: unknown): value is string {\n\treturn isStr(value) && /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/.test(value);\n}\n","/**\n * Checks whether a given value is a **finite number**.\n *\n * @summary\n * A strict type guard that returns `true` only if `value` is of type `\"number\"`\n * and is a finite numeric value (not `NaN`, `Infinity`, or `-Infinity`).\n *\n * @param value - Any value to check.\n *\n * @returns `true` if the value is a finite number, otherwise `false`.\n *\n * @remarks\n * ### Behavior\n * - Uses the built-in `typeof` operator to ensure the value is a primitive number.\n * - Rejects special non-finite numeric values:\n * - `NaN`\n * - `Infinity`\n * - `-Infinity`\n * - Does **not** coerce strings — `\"123\"` returns `false`.\n * - Works only with **number primitives**, not `Number` objects (`new Number(5)` returns `false`).\n *\n * ### Type narrowing\n * When this function returns `true`, TypeScript automatically infers:\n * ```ts\n * value is number\n * ```\n * allowing you to use numeric operators and arithmetic safely.\n *\n * ### Comparison with related checks\n * | Function | Accepts | Rejects |\n * |----------------|---------------------------------|--------------------------------|\n * | `isNum` | finite numbers only | `NaN`, `Infinity`, non-numbers |\n * | `isNumP` | positive finite numbers | `0`, negatives, `NaN` |\n * | `isNumNZ` | zero or negative finite numbers | positives, `NaN` |\n *\n * ### Performance\n * - Time complexity: **O(1)**\n * - Space complexity: **O(1)**\n *\n * ### Examples\n *\n * @example\n * // Valid finite numbers\n * isNum(42); // => true\n * isNum(0); // => true\n * isNum(-3.14); // => true\n *\n * @example\n * // Invalid numeric values\n * isNum(NaN); // => false\n * isNum(Infinity); // => false\n * isNum(-Infinity); // => false\n *\n * @example\n * // Non-number inputs\n * isNum('123'); // => false\n * isNum(true); // => false\n * isNum(null); // => false\n * isNum(undefined); // => false\n *\n * @example\n * // TypeScript narrowing\n * const x: unknown = 100;\n * if (isNum(x)) {\n * console.log(x.toFixed(2)); // OK — x is number\n * }\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isNum(value: unknown): value is number {\n\treturn (typeof value === 'number') && Number.isFinite(value);\n}\n","import { isNum } from '../index';\n\n/**\n * Checks whether a given value is a **finite non-integer (floating-point) number**.\n *\n * @summary\n * Returns `true` if the value is a finite number and **has a fractional part**\n * (i.e. not an integer). \n * Acts as a strict type guard for float-like numeric values.\n *\n * @param value - Any value to test.\n *\n * @returns `true` if the value is a finite, non-integer number; otherwise `false`.\n *\n * @remarks\n * ### Behavior\n * - First verifies that the value is a finite number via {@link isNum}.\n * - Then ensures it is **not** an integer using `!Number.isInteger(value)`.\n * - Rejects all non-numeric, `NaN`, or infinite values.\n *\n * ### Comparison with related checks\n * | Function | Matches | Rejects |\n * |----------------|--------------------------------|------------------------------------|\n * | `isNum` | any finite number | `NaN`, `Infinity`, `-Infinity` |\n * | `isNumFloat` | finite numbers **with fraction** | integers, `NaN`, non-numbers |\n * | `isNumInt` | finite **integers** only | floats, `NaN`, non-numbers |\n *\n * ### Performance\n * - Time complexity: **O(1)** \n * - Space complexity: **O(1)**\n *\n * ### Examples\n *\n * @example\n * // Valid floats\n * isNumFloat(3.14); // => true\n * isNumFloat(-0.001); // => true\n * isNumFloat(1 / 3); // => true\n *\n * @example\n * // Integers\n * isNumFloat(0); // => false\n * isNumFloat(42); // => false\n * isNumFloat(-7); // => false\n *\n * @example\n * // Invalid or non-number values\n * isNumFloat(NaN); // => false\n * isNumFloat(Infinity); // => false\n * isNumFloat('3.14'); // => false\n * isNumFloat(null); // => false\n *\n * @example\n * // Type narrowing\n * const val: unknown = 12.5;\n * if (isNumFloat(val)) {\n * const n = val * 2; // val is number\n * }\n *\n * @see isNum\n * @see Number.isInteger\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isNumFloat(value: unknown): value is number {\n\treturn isNum(value) && !Number.isInteger(value);\n}\n","import { isNum } from '../index';\n\n/**\n * Checks whether a given value is a **negative finite number**.\n *\n * @summary\n * A strict type guard that returns `true` only if the input is a finite number\n * and its value is **less than 0**. \n * Useful for safely detecting negative numeric values without coercion.\n *\n * @param value - Any value to test.\n *\n * @returns `true` if the value is a finite number less than zero, otherwise `false`.\n *\n * @remarks\n * ### Behavior\n * - Relies on {@link isNum} to ensure the value is a finite number (not `NaN`, `Infinity`, etc.).\n * - Then checks `value < 0`.\n * - Returns `false` for zero, positive numbers, and all non-numeric types.\n *\n * ### Comparison with related checks\n * | Function | Description | Condition |\n * |--------------|----------------------------------------|-----------------------------|\n * | `isNum` | Any finite number | `Number.isFinite(value)` |\n * | `isNumP` | Positive numbers only | `value > 0` |\n * | `isNumN` | Negative numbers only | `value < 0` |\n * | `isNumNZ` | Negative or zero numbers | `value <= 0` |\n * | `isNumFloat` | Finite non-integer (fractional) numbers | `!Number.isInteger(value)` |\n *\n * ### Performance\n * - Time complexity: **O(1)** \n * - Space complexity: **O(1)**\n *\n * ### Examples\n *\n * @example\n * // Negative numbers\n * isNumN(-1); // => true\n * isNumN(-3.14); // => true\n * isNumN(-0.0001); // => true\n *\n * @example\n * // Non-negative numbers\n * isNumN(0); // => false\n * isNumN(1); // => false\n * isNumN(42); // => false\n *\n * @example\n * // Invalid values\n * isNumN(NaN); // => false\n * isNumN('-5'); // => false\n * isNumN(null); // => false\n * isNumN(undefined); // => false\n *\n * @example\n * // Type narrowing\n * const val: unknown = -12;\n * if (isNumN(val)) {\n * const abs = Math.abs(val); // val is number\n * }\n *\n * @see isNum\n * @see isNumP\n * @see isNumNZ\n * @see isNumFloat\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isNumN(value: unknown): value is number {\n\treturn isNum(value) && value < 0;\n}\n","import { isNum } from '../index';\n\n/**\n * Checks whether a given value is a **finite number that is less than or equal to zero**.\n *\n * @summary\n * A strict type guard that returns `true` if the input is a finite number and\n * its value is **negative or zero**. \n * Commonly used to identify non-positive numeric values.\n *\n * @param value - Any value to test.\n *\n * @returns `true` if the value is a finite number less than or equal to zero; otherwise `false`.\n *\n * @remarks\n * ### Behavior\n * - Uses {@link isNum} to ensure the input is a finite number (rejects `NaN`, `Infinity`, etc.).\n * - Then checks the condition `value <= 0`.\n * - Returns `false` for all positive numbers and non-numeric values.\n *\n * ### Comparison with related checks\n * | Function | Description | Condition |\n * |--------------|-----------------------------------|----------------|\n * | `isNum` | Any finite number | — |\n * | `isNumP` | Positive numbers only | `value > 0` |\n * | `isNumN` | Negative numbers only | `value < 0` |\n * | `isNumNZ` | Negative **or zero** numbers | `value <= 0` |\n * | `isNumFloat` | Finite non-integer (fractional) | `!Number.isInteger(value)` |\n *\n * ### Performance\n * - Time complexity: **O(1)** \n * - Space complexity: **O(1)**\n *\n * ### Examples\n *\n * @example\n * // Negative and zero values\n * isNumNZ(-1); // => true\n * isNumNZ(-0.5); // => true\n * isNumNZ(0); // => true\n *\n * @example\n * // Positive values\n * isNumNZ(0.0001); // => false\n * isNumNZ(5); // => false\n *\n * @example\n * // Invalid or non-numeric inputs\n * isNumNZ('0'); // => false\n * isNumNZ(NaN); // => false\n * isNumNZ(Infinity); // => false\n * isNumNZ(null); // => false\n *\n * @example\n * // Type narrowing\n * const x: unknown = -10;\n * if (isNumNZ(x)) {\n * console.log(x.toFixed(2)); // x is number\n * }\n *\n * @see isNum\n * @see isNumP\n * @see isNumN\n * @see isNumFloat\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isNumNZ(value: unknown): value is number {\n\treturn isNum(value) && value <= 0;\n}\n","import { isNum } from '../index';\n\n/**\n * Checks whether a given value is a **positive finite number**.\n *\n * @summary\n * A strict type guard that returns `true` only if the input is a finite number\n * greater than zero (`> 0`). \n * Useful for safely validating numeric values that must be positive — such as\n * counters, IDs, amounts, or dimensions.\n *\n * @param value - Any value to test.\n *\n * @returns `true` if the value is a finite positive number, otherwise `false`.\n *\n * @remarks\n * ### Behavior\n * - Uses {@link isNum} to ensure the input is a finite number (`NaN`, `Infinity`, and `-Infinity` are rejected).\n * - Returns `true` only when `value > 0`.\n * - Returns `false` for zero, negative, or non-numeric values.\n *\n * ### Comparison with related checks\n * | Function | Description | Condition |\n * |--------------|-----------------------------------|----------------------------|\n * | `isNum` | Any finite number | — |\n * | `isNumP` | Positive numbers only | `value > 0` |\n * | `isNumN` | Negative numbers only | `value < 0` |\n * | `isNumNZ` | Negative **or zero** numbers | `value <= 0` |\n * | `isNumFloat` | Finite non-integer (fractional) | `!Number.isInteger(value)` |\n *\n * ### Performance\n * - Time complexity: **O(1)** \n * - Space complexity: **O(1)**\n *\n * ### Examples\n *\n * @example\n * // Positive values\n * isNumP(1); // => true\n * isNumP(3.14); // => true\n * isNumP(0.00001); // => true\n *\n * @example\n * // Zero and negatives\n * isNumP(0); // => false\n * isNumP(-1); // => false\n * isNumP(-0.5); // => false\n *\n * @example\n * // Invalid or non-numeric inputs\n * isNumP('5'); // => false\n * isNumP(NaN); // => false\n * isNumP(Infinity); // => false\n * isNumP(null); // => false\n *\n * @example\n * // Type narrowing\n * const x: unknown = 12;\n * if (isNumP(x)) {\n * console.log(x.toFixed(1)); // x is number\n * }\n *\n * @see isNum\n * @see isNumN\n * @see isNumNZ\n * @see isNumFloat\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isNumP(value: unknown): value is number {\n\treturn isNum(value) && value > 0;\n}\n","import { isNum } from '../index';\n\n/**\n * Checks whether a given value is a **finite number greater than or equal to zero**.\n *\n * @summary\n * A strict type guard that returns `true` if the input is a finite number\n * and its value is **non-negative** (`≥ 0`). \n * Useful for safely validating values such as counters, sizes, durations,\n * and other quantities that cannot be negative.\n *\n * @param value - Any value to test.\n *\n * @returns `true` if the value is a finite number greater than or equal to zero; otherwise `false`.\n *\n * @remarks\n * ### Behavior\n * - Uses {@link isNum} to ensure the input is a finite number (`NaN`, `Infinity`, `-Infinity` are rejected).\n * - Returns `true` when `value >= 0`.\n * - Returns `false` for negative numbers or non-numeric inputs.\n *\n * ### Comparison with related checks\n * | Function | Description | Condition |\n * |--------------|----------------------------------|----------------------------|\n * | `isNum` | Any finite number | — |\n * | `isNumP` | Positive numbers only | `value > 0` |\n * | `isNumPZ` | Non-negative numbers (`≥ 0`) | `value >= 0` |\n * | `isNumN` | Negative numbers only | `value < 0` |\n * | `isNumNZ` | Negative or zero numbers | `value <= 0` |\n * | `isNumFloat` | Finite non-integer numbers | `!Number.isInteger(value)` |\n *\n * ### Performance\n * - Time complexity: **O(1)** \n * - Space complexity: **O(1)**\n *\n * ### Examples\n *\n * @example\n * // Non-negative numbers\n * isNumPZ(0); // => true\n * isNumPZ(5); // => true\n * isNumPZ(3.14); // => true\n *\n * @example\n * // Negative numbers\n * isNumPZ(-1); // => false\n * isNumPZ(-0.1); // => false\n *\n * @example\n * // Invalid or non-numeric inputs\n * isNumPZ('10'); // => false\n * isNumPZ(NaN); // => false\n * isNumPZ(Infinity); // => false\n * isNumPZ(null); // => false\n *\n * @example\n * // Type narrowing\n * const val: unknown = 7;\n * if (isNumPZ(val)) {\n * console.log(Math.sqrt(val)); // val is number\n * }\n *\n * @see isNum\n * @see isNumP\n * @see isNumN\n * @see isNumNZ\n * @see isNumFloat\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isNumPZ(value: unknown): value is number {\n\treturn isNum(value) && value >= 0;\n}\n","/**\n * Checks whether a given value is a **plain object** (i.e. `{}`), not `null`, not an array, and not a class instance.\n *\n * @summary\n * A strict type guard that returns `true` only if the input is a plain object\n * created using an object literal (`{}`) or `Object.create(null)`. \n * Excludes arrays, functions, `null`, and instances of custom classes.\n *\n * @param value - Any value to test.\n *\n * @returns `true` if the value is a non-null, non-array plain object; otherwise `false`.\n *\n * @remarks\n * ### Behavior\n * The check ensures all of the following:\n * 1. `typeof value === \"object\"` — confirms the value is object-like.\n * 2. `value !== null` — excludes `null`, since `typeof null === \"object\"`.\n * 3. `Object.prototype.toString.call(value) === \"[object Object]\"` — filters out built-ins like `Map`, `Set`, `Date`, etc.\n * 4. `!Array.isArray(value)` — ensures arrays are excluded.\n *\n * ### What counts as a \"plain object\"\n * `{}`, `{ a: 1 }`, `Object.create(null)` \n * `[]`, `new Date()`, `new Map()`, `null`, class instances.\n *\n * ### Comparison with related concepts\n * | Example value | Result | Explanation |\n * |--------------------------|---------|----------------------------------|\n * | `{}` | true | Plain object |\n * | `Object.create(null)` | true | No prototype but still object |\n * | `[]` | false | Array excluded |\n * | `null` | false | Explicitly filtered |\n * | `new Date()` | false | Built-in class instance |\n * | `class A {}; new A()` | false | Custom class instance |\n *\n * ### Type narrowing\n * When this function returns `true`, TypeScript infers:\n * ```ts\n * value is Record<string, unknown>\n * ```\n * allowing safe property access and iteration.\n *\n * ### Performance\n * - Time complexity: **O(1)**\n * - Space complexity: **O(1)**\n *\n * ### Examples\n *\n * @example\n * // Plain objects\n * isObj({}); // => true\n * isObj({ key: 'value' }); // => true\n * isObj(Object.create(null)); // => true\n *\n * @example\n * // Non-objects or special cases\n * isObj(null); // => false\n * isObj([]); // => false\n * isObj(new Date()); // => false\n * isObj(new Map()); // => false\n * isObj(() => {}); // => false\n *\n * @example\n * // Type narrowing\n * const val: unknown = { x: 1 };\n * if (isObj(val)) {\n * console.log(val.x); // safe: val is Record<string, unknown>\n * }\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isObj(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === 'object' \n\t\t&& value !== null \n\t\t&& Object.prototype.toString.call(value) === '[object Object]'\n\t\t&& !Array.isArray(value);\n}\n","import { isObj } from '../index';\n\n/**\n * Checks whether a given value is a **non-empty plain object**.\n *\n * @summary\n * A strict type guard that returns `true` only if the input is a plain object\n * (validated by {@link isObj}) **and** has at least one own enumerable key. \n * In other words, it must be an object literal like `{ a: 1 }`, not `{}`.\n *\n * @param value - Any value to test.\n *\n * @returns `true` if the value is a plain object with at least one own property; otherwise `false`.\n *\n * @remarks\n * ### Behavior\n * - Uses {@link isObj} to verify the value is a plain object (not `null`, not an array, not a class instance).\n * - Calls `Object.keys(value).length > 0` to ensure the object has one or more keys.\n * - Returns `false` for empty objects (`{}`), arrays, functions, `null`, and other non-object types.\n *\n * ### Comparison with related checks\n * | Function | Description | Example |\n * |------------------|---------------------------------------|----------------------|\n * | `isObj` | Checks if value is a plain object | `{}` true / `[]` false |\n * | `isObjFilled` | Checks if plain object is **non-empty** | `{a: 1}` true / `{}` false |\n * | `isArrFilled` | Checks if array is non-empty | `[1]` true / `[]` false |\n * | `isStrFilled` | Checks if string is non-empty | `'a'` true / `''` false |\n *\n * ### Type narrowing\n * When this function returns `true`, TypeScript infers:\n * ```ts\n * value is Record<string, unknown>\n * ```\n * allowing safe property access and iteration.\n *\n * ### Performance\n * - Time complexity: **O(n)** — proportional to the number of object keys.\n * - Space complexity: **O(1)**.\n *\n * ### Examples\n *\n * @example\n * // Non-empty plain objects\n * isObjFilled({ a: 1 }); // => true\n * isObjFilled({ key: null }); // => true\n * isObjFilled({ nested: {} }); // => true\n *\n * @example\n * // Empty or invalid objects\n * isObjFilled({}); // => false\n * isObjFilled([]); // => false\n * isObjFilled(null); // => false\n * isObjFilled(new Date()); // => false\n *\n * @example\n * // Type narrowing\n * const data: unknown = { x: 5 };\n * if (isObjFilled(data)) {\n * console.log(Object.keys(data)); // safe\n * }\n *\n * @see isObj\n * @see isArrFilled\n * @see isStrFilled\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isObjFilled(value: unknown): value is Record<string, unknown> {\n\treturn isObj(value) && Object.keys(value).length > 0;\n}\n","import type { PasswordOptions } from '../index';\nimport { isStr } from '../index';\n\n/**\n * Validates whether a string meets configurable **password strength requirements**.\n *\n * @summary\n * A flexible password validation helper that checks for length, uppercase and lowercase letters,\n * digits, and special characters. \n * All rules are configurable through the optional {@link PasswordOptions} parameter.\n *\n * @param value - The value to validate as a password.\n * @param options - Optional validation rules (see {@link PasswordOptions}). \n * Defaults ensure strong password requirements:\n * ```ts\n * {\n * minLength: 8,\n * maxLength: 256,\n * requireUppercase: true,\n * requireLowercase: true,\n * requireDigit: true,\n * requireSpecial: true\n * }\n * ```\n *\n * @returns `true` if the value is a valid string matching all configured requirements, otherwise `false`.\n *\n * @remarks\n * ### Behavior\n * 1. Ensures `value` is a string using {@link isStr}.\n * 2. Enforces **length limits** (`minLength` ≤ length ≤ `maxLength`).\n * 3. Optionally checks for:\n * - Uppercase characters (Latin or Cyrillic): `/[A-ZА-Я]/`\n * - Lowercase characters (Latin or Cyrillic): `/[a-zа-я]/`\n * - Digits: `/\\d/`\n * - Special characters: `/[~!?@#$%^&*_\\-+()\\[\\]{}><\\\\\\/|\"'.,:;=]/`\n * 4. Returns `true` only if all active checks pass.\n *\n * ### Default rule set (strong password)\n * - At least 8 characters long \n * - Contains uppercase and lowercase letters \n * - Contains at least one digit \n * - Contains at least one special symbol \n * - Not longer than 256 characters\n *\n * ### Example configuration\n * ```ts\n * // Minimal check — only length between 6 and 20\n * isPassword('abcdef', { minLength: 6, maxLength: 20, requireSpecial: false });\n *\n * // Strict corporate policy\n * isPassword('Qwerty#123', { minLength: 10, requireSpecial: true });\n *\n * // Simplified mobile app rule\n * isPassword('myPass1', { requireSpecial: false });\n * ```\n *\n * ### Type narrowing\n * When this function returns `true`, TypeScript infers:\n * ```ts\n * value is string\n * ```\n * allowing you to safely treat it as a verified password.\n *\n * ### Performance\n * - Time complexity: **O(n)** (depends on string length and regex scans).\n * - Space complexity: **O(1)**.\n *\n * ### Examples\n *\n * @example\n * // Default strong policy (8+ chars, upper, lower, digit, special)\n * isPassword('Aa1@aaaa'); // => true\n * isPassword('Password123!'); // => true\n * isPassword('qwerty'); // => false (no upper/digit/special)\n *\n * @example\n * // Custom rules\n * isPassword('abc123', {\n * minLength: 6,\n * requireUppercase: false,\n * requireSpecial: false\n * }); // => true\n *\n * @example\n * // Invalid inputs\n * isPassword(''); // => false\n * isPassword(null); // => false\n * isPassword(undefined); // => false\n * isPassword(123456); // => false\n *\n * @see isStr\n *\n * @category Validation\n * @public\n * @since 2.0.0\n */\nexport function isPassword(\n\tvalue: unknown,\n\t{\n\t\tminLength = 8,\n\t\tmaxLength = 256,\n\t\trequireUppercase = true,\n\t\trequireLowercase = true,\n\t\trequireDigit = true,\n\t\trequireSpecial = true,\n\t}: PasswordOptions = {}\n): value is string {\n\tif (!isStr(value)) {\n\t\treturn false;\n\t}\n\tif (value.length < minLength || value.length > maxLength) {\n\t\treturn false;\n\t}\n\tif (requireUppercase && !/[A-ZА-Я]/.test(value)) {\n\t\treturn false;\n\t}\n\tif (requireLowercase && !/[a-zа-я]/.test(value)) {\n\t\treturn false;\n\t}\n\tif (requireDigit && !/\\d/.test(value)) {\n\t\treturn false;\n\t}\n\tif (requireSpecial && !/[~!?@#$%^&*_\\-+()\\[\\]{}><\\\\\\/|\"'.,:;=]/.test(value)) {\n\t\treturn false;\n\t}\n\treturn true;\n}\n","import { \n\tisStrFilled,\n\tisNum, \n} from '../index';\n\n/**\n * Checks whether a given value is a **valid phone number** in a generic international format.\n *\n * @summary\n * A flexible, language-neutral phone number validator that accepts both string and numeric inputs. \n * It supports optional leading `\"+\"`, allows dashes (`\"-\"`) as separators, and ensures that the\n * number structure is syntactically valid — not necessarily region-specific.\n *\n * @param value - Any value to test (string or number).\n *\n * @returns `true` if the value represents a valid phone-like number, otherwise `false`.\n *\n * @remarks\n * ### Validation logic\n * 1. **Type check:** \n * Accepts strings and finite numbers (`isStrFilled` or `isNum` must pass).\n * 2. **Normalization:** \n * Converts to string and trims whitespace.\n * 3. **Negative or misplaced signs:** \n * Rejects numbers starting with `\"-\"`.\n * 4. **Plus sign validation:** \n * - Only one `+` is allowed. \n * - If present, it must appear **only at the start**.\n * 5. **Character whitelist:** \n * The number must match the pattern `/^\\+?[0-9-]+$/`, \n * i.e., only digits, dashes, and an optional leading plus sign.\n * 6. **Length check:** \n * Must be between **3** and **20** characters (inclusive).\n * 7. **Ending rule:** \n * The last character must be a digit.\n * 8. **Double-dash check:** \n * Rejects sequences containing `\"--\"`.\n *\n * ### Behavior\n * - Accepts: `+1234567890`, `380-67-123-4567`, `79001234567`, `12345`.\n * - Rejects: `\"--123\"`, `\"++123\"`, `\"12a34\"`, `\"12 34\"`, `\"-123\"`, `\"123-\"`.\n * - Not region-specific — does **not** check country codes or local dialing rules.\n * - Designed for structural validation only.\n *\n * ### Comparison\n * | Example | Valid | Reason |\n * |----------------------|:------:|--------------------------------|\n * | `+380671234567` | true | Proper international format |\n * | `067-123-4567` | true | Local format with dashes |\n * | `123` | true | Minimum valid length |\n * | `+12-34-56--78` | false | Contains `\"--\"` |\n * | `+12A345` | false | Contains letters |\n * | `123-` | false | Ends with non-digit |\n * | `++38050` | false | Multiple `\"+\"` symbols |\n * | `380+501234` | false | Misplaced plus |\n *\n * ### Type narrowing\n * When this function returns `true`, TypeScript infers:\n * ```ts\n * value is string\n * ```\n * even if the original value was numeric — ensuring it can be safely stored or formatted as text.\n *\n * ### Performance\n * - Time complexity: **O(n)** — single regex checks and scans.\n * - Space complexity: **O(1)**.\n *\n * ### Examples\n *\n * @example\n * // Valid international numbers\n * isPhone('+380671234567'); // => true\n * isPhone('380-67-123-4567'); // => true\n * isPhone(380501234567); // => true\n *\n * @example\n * // Invalid formats\n * isPhone('--12345'); // => false\n * isPhone('+12+34'); // => false\n * isPhone('12A345'); // => false\n * isPhone('123-'); // => false\n * isPhone(''); // => false\n *\n * @example\n * // Type narrowing\n * const val: unknown = '+14155552671';\n * if (isPhone(val)) {\n * console.log(val.replace(/\\D/g, '')); // safe normalization\n * }\n *\n * @see isStrFilled\n * @see isNum\n * @see formatToPhone\n *\n * @category Validation\n * @public\n * @since 2.0.0\n */\nexport function isPhone(value: unknown): value is string {\n\tif (!isStrFilled(value) \n\t\t&& !isNum(value)) {\n\t\treturn false;\n\t}\n\tconst valueProcessed = String(value).trim();\n\n\tif (valueProcessed.startsWith('-')) {\n\t\treturn false;\n\t}\n\tif ((valueProcessed.match(/\\+/g) || []).length > 1) {\n\t\treturn false;\n\t}\n\tif (valueProcessed.includes('+') && !valueProcessed.startsWith('+')) {\n\t\treturn false;\n\t}\n\tif (!/^\\+?[0-9-]+$/.test(valueProcessed)) {\n\t\treturn false;\n\t}\n\tif (valueProcessed.length < 3 || valueProcessed.length > 20) {\n\t\treturn false;\n\t}\n\tif (!/[0-9]$/.test(valueProcessed)) {\n\t\treturn false;\n\t}\n\tif (valueProcessed.includes('--')) {\n\t\treturn false;\n\t}\n\treturn true;\n}\n","/**\n * Checks whether a given value is a **string** primitive.\n *\n * @summary\n * A strict type guard that returns `true` only if the provided value\n * has the JavaScript type `\"string\"`. \n * Rejects all non-string types, including `String` objects created via `new String()`.\n *\n * @param value - Any value to test.\n *\n * @returns `true` if the value is a string primitive, otherwise `false`.\n *\n * @remarks\n * ### Behavior\n * - Uses the `typeof` operator for a strict type check.\n * - Does **not** coerce values — `\"123\"` is valid, but `123` is not.\n * - Returns `false` for:\n * - `String` wrapper objects (`new String('abc')`)\n * - Non-string types (`number`, `boolean`, `object`, `undefined`, etc.)\n *\n * ### Type narrowing\n * When this function returns `true`, TypeScript infers:\n * ```ts\n * value is string\n * ```\n * enabling full access to string methods safely.\n *\n * ### Comparison\n * | Input | Result | Note |\n * |------------------|:------:|-----------------------------------|\n * | `'hello'` | true | String literal |\n * | `new String('x')`| false | Object wrapper, not primitive |\n * | `123` | false | Number |\n * | `null` | false | Not a string |\n * | `undefined` | false | Not a string |\n *\n * ### Performance\n * - Time complexity: **O(1)** \n * - Space complexity: **O(1)**\n *\n * ### Examples\n *\n * @example\n * // Basic usage\n * isStr('Hello'); // => true\n * isStr(''); // => true\n * isStr(123); // => false\n * isStr(null); // => false\n *\n * @example\n * // Type narrowing\n * const val: unknown = 'abc';\n * if (isStr(val)) {\n * console.log(val.toUpperCase()); // safe\n * }\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isStr(value: unknown): value is string {\n\treturn typeof value === 'string';\n}\n","import { isStrFilled } from '../index';\n\n/**\n * Checks whether a given value is a **string representation of a boolean** — `\"true\"` or `\"false\"`.\n *\n * @summary\n * A strict type guard that returns `true` if the input is a non-empty string\n * equal to `\"true\"` or `\"false\"` (case-insensitive, with whitespace ignored). \n * Commonly used for validating query parameters, environment variables, or serialized booleans.\n *\n * @param value - Any value to test.\n *\n * @returns `true` if the value is a string `\"true\"` or `\"false\"` (ignoring case and whitespace), otherwise `false`.\n *\n * @remarks\n * ### Behavior\n * 1. Uses {@link isStrFilled} to ensure the input is a non-empty string.\n * 2. Trims whitespace and converts it to lowercase.\n * 3. Returns `true` only if the normalized string equals `\"true\"` or `\"false\"`.\n * 4. Returns `false` for other strings, numbers, or non-string types.\n *\n * ### Typical usage\n * This utility is helpful when you need to:\n * - Parse stringified boolean flags (`'true'`, `'false'`)\n * - Validate configuration or query params\n * - Handle environment variables (`process.env.FEATURE_ENABLED`)\n *\n * ### Type narrowing\n * When this function returns `true`, TypeScript infers:\n * ```ts\n * value is string\n * ```\n * and you can safely pass it to a boolean converter (e.g. `formatToBool()`).\n *\n * ### Performance\n * - Time complexity: **O(1)** \n * - Space complexity: **O(1)**\n *\n * ### Examples\n *\n * @example\n * // Valid boolean strings\n * isStrBool('true'); // => true\n * isStrBool('FALSE'); // => true\n * isStrBool(' True '); // => true\n *\n * @example\n * // Invalid strings\n * isStrBool('yes'); // => false\n * isStrBool('0'); // => false\n * isStrBool(''); // => false\n *\n * @example\n * // Non-string inputs\n * isStrBool(true); // => false\n * isStrBool(1); // => false\n * isStrBool(null); // => false\n *\n * @example\n * // Combined with formatToBool()\n * import { formatToBool } from '../bool/formatToBool';\n *\n * const val: unknown = 'False';\n * if (isStrBool(val)) {\n * console.log(formatToBool(val)); // false\n * }\n *\n * @see isStr\n * @see isStrFilled\n * @see isBool\n * @see formatToBool\n *\n * @category Validation\n * @public\n * @since 2.0.0\n */\nexport function isStrBool(value: unknown): value is string {\n\tif (!isStrFilled(value)) {\n\t\treturn false;\n\t}\n\tconst normalized = value.trim().toLowerCase();\n\t\n\treturn normalized === 'true' || normalized === 'false';\n}\n","import { isStr } from '../index';\n\n/**\n * Checks whether a given value is a **non-empty string** (not just whitespace).\n *\n * @summary\n * A strict type guard that returns `true` only if the value is a string\n * containing at least one non-whitespace character. \n * This is an extended form of {@link isStr} that excludes empty (`\"\"`) and\n * whitespace-only strings (`\" \"`).\n *\n * @param value - Any value to test.\n *\n * @returns `true` if the value is a string with visible content, otherwise `false`.\n *\n * @remarks\n * ### Behavior\n * - Uses {@link isStr} to confirm the value is a string primitive.\n * - Calls `.trim()` to remove whitespace and checks if the resulting length is greater than zero.\n * - Returns `false` for:\n * - Empty strings (`\"\"`)\n * - Whitespace-only strings (`\" \"`, `\"\\n\"`, `\"\\t\"`)\n * - Non-string values (`number`, `boolean`, `object`, `null`, etc.)\n *\n * ### Comparison\n * | Function | Description | Example |\n * |-----------------|-----------------------------------|---------------------------|\n * | `isStr` | Any string (including empty) | `\"\"` true |\n * | `isStrFilled` | Non-empty trimmed string only | `\" \"` false / `\"x\"` true |\n *\n * ### Type narrowing\n * When this function returns `true`, TypeScript infers:\n * ```ts\n * value is string\n * ```\n * ensuring safe use of string operations.\n *\n * ### Performance\n * - Time complexity: **O(n)** (due to `.trim()`).\n * - Space complexity: **O(1)**.\n *\n * ### Examples\n *\n * @example\n * // Valid strings\n * isStrFilled('hello'); // => true\n * isStrFilled(' text '); // => true\n *\n * @example\n * // Empty or whitespace-only\n * isStrFilled(''); // => false\n * isStrFilled(' '); // => false\n *\n * @example\n * // Non-string values\n * isStrFilled(null); // => false\n * isStrFilled(123); // => false\n * isStrFilled(undefined); // => false\n *\n * @example\n * // Type narrowing\n * const val: unknown = ' value ';\n * if (isStrFilled(val)) {\n * console.log(val.trim().toUpperCase()); // safe\n * }\n *\n * @see isStr\n * @see isArrFilled\n * @see isObjFilled\n *\n * @category Type Guards\n * @public\n * @since 2.0.0\n */\nexport function isStrFilled(value: unknown): value is string {\n\treturn isStr(value) && value.trim().length > 0;\n}\n","import { isStrFilled } from '../index';\n\n/**\n * Checks whether a given value is a string equal to **\"asc\"** or **\"desc\"** (case-insensitive).\n *\n * @summary\n * A strict type guard that validates sorting direction strings — \n * `\"asc\"` (ascending) or `\"desc\"` (descending). \n * Useful for validating API parameters, SQL sort directives, or UI sort controls.\n *\n * @param value - Any value to test.\n *\n * @returns `true` if the value is a non-empty string representing `\"asc\"` or `\"desc\"`, otherwise `false`.\n *\n * @remarks\n * ### Behavior\n * 1. Uses {@link isStrFilled} to ensure the value is a non-empty string.\n * 2. Trims whitespace and converts it to lowercase.\n * 3. Returns `true` only if the normalized value equals `\"asc\"` or `\"desc\"`.\n * 4. Returns `false` for empty strings, other words, or non-string types.\n *\n * ### Type narrowing\n * When this function returns `true`, TypeScript infers:\n * ```ts\n * value is 'asc' | 'desc'\n * ```\n * which is ideal for type-safe sort order handling in functions and APIs.\n *\n * ### Performance\n * - Time complexity: **O(1)** (fixed length checks)\n * - Space complexity: **O(1)**\n *\n * ### Examples\n *\n * @example\n * // Valid inputs\n * isStrAscDesc('asc'); // => true\n * isStrAscDesc('DESC'); // => true\n * isStrAscDesc(' Asc '); // => true\n *\n * @example\n * // Invalid inputs\n * isStrAscDesc('ascending'); // => false\n * isStrAscDesc(''); // => false\n * isStrAscDesc(null); // => false\n * isStrAscDesc('up'); // => false\n *\n * @example\n * // Type narrowing in use\n * function sortData(order: unknown) {\n * if (isStrAscDesc(order)) {\n * console.log(`Sorting in ${order} order`);\n * } else {\n * console.log('Invalid sort direction');\n * }\n * }\n *\n * @see isStr\n * @see isStrFilled\n *\n * @category Validation\n * @public\n * @since 2.0.0\n */\nexport function isStrAscDesc(value: unknown): value is 'asc' | 'desc' {\n\tif (!isStrFilled(value)) {\n\t\treturn false;\n\t}\n\tconst normalized = value.trim().toLowerCase();\n\t\n\treturn normalized === 'asc' || normalized === 'desc';\n}\n","import { isStr } from '../index';\n\n/**\n * Checks whether a given value is a **valid variable-like identifier**.\n *\n * @summary\n * A strict type guard that returns `true` only if the value is a string\n * matching the pattern of a valid **programming variable name**: \n * must start with a letter (`A–Z`, `a–z`) or underscore (`_`),\n * and may contain only letters, digits, or underscores afterward.\n *\n * @param value - Any value to test.\n *\n * @returns `true` if the value is a syntactically valid variable name; otherwise `false`.\n *\n * @remarks\n * ### Validation rule\n * Uses the following regular expression:\n * ```regex\n * /^[A-Za-z_][A-Za-z0-9_]*$/\n * ```\n * This enforces:\n * - **First character:** a Latin letter (`A–Z`, `a–z`) or underscore (`_`)\n * - **Subsequent characters:** any combination of letters, digits, or underscores\n * - **No spaces, symbols, or Unicode letters** are allowed\n *\n * ### Typical use cases\n * - Validating variable names in configuration files or templates\n * - Checking safe property keys for code generation\n * - Ensuring identifiers in scripting or parsing logic\n *\n * ### Behavior\n * - Returns `false` for:\n * - Strings starting with digits (`\"1abc\"`)\n * - Strings containing hyphens or spaces (`\"my-var\"`, `\"user name\"`)\n * - Empty strings or non-string values\n * - Returns `true` for:\n * - `\"name\"`, `\"_value\"`, `\"myVar1\"`, `\"SOME_CONSTANT\"`\n *\n * ### Type narrowing\n * When this function returns `true`, TypeScript infers:\n * ```ts\n * value is string\n * ```\n * ensuring safe string usage in contexts like symbol tables or identifier maps.\n *\n * ### Performance\n * - Time complexity: **O(n)** — proportional to string length (regex evaluation)\n * - Space complexity: **O(1)**\n *\n * ### Examples\n *\n * @example\n * // Valid identifiers\n * isVar('name'); // => true\n * isVar('_id'); // => true\n * isVar('myVar1'); // => true\n * isVar('SOME_CONSTANT'); // => true\n *\n * @example\n * // Invalid identifiers\n * isVar(''); // => false\n * isVar('1var'); // => false\n * isVar('user-name'); // => false\n * isVar('my var'); // => false\n * isVar('$value'); // => false\n *\n * @example\n * // Non-string values\n * isVar(null); // => false\n * isVar(123); // => false\n * isVar({}); // => false\n *\n * @see isStr\n * @see isStrFilled\n *\n * @category Validation\n * @public\n * @since 2.0.0\n */\nexport function isVar(value: unknown): value is string {\n\treturn isStr(value) && /^[A-Za-z_][A-Za-z0-9_]*$/.test(value);\n}\n","import { isFunc } from './isFunc';\n\nexport function isClass(value: unknown): boolean {\n\treturn isFunc(value) && /^class\\s/.test(Function.prototype.toString.call(value))\n}\n","import type { JSONLike } from '../index';\nimport { jsonParse } from '../index';\n\n/**\n * Matches strings surrounded by a single, double, or backtick quote.\n *\n * @example\n * ```ts\n * QUOTED_RE.test(`\"hello\"`); // true\n * QUOTED_RE.test(`'world'`); // true\n * QUOTED_RE.test('`foo`'); // true\n * QUOTED_RE.test('bar'); // false\n * ```\n *\n * @internal\n */\nconst QUOTED_RE = /^(['\"`])([\\s\\S]*)\\1$/;\n\n/**\n * Parses a string that may represent JSON, quoted scalars, or plain text.\n *\n * @remarks\n * The parsing order is:\n *\n * 1. Try JSON via {@link jsonParse}. If it works, return the parsed value.\n * 2. If not JSON, check if the string is quoted with `'`, `\"` or `` ` ``.\n * If quoted, return the **unquoted** inner text.\n * 3. If not quoted:\n * - If `allowString === true`, return the **trimmed** string as-is.\n * - Otherwise return `null`.\n *\n * This helper is used recursively by {@link jsonDecode} to decode string fields\n * found inside arrays/objects.\n *\n * @param s - Source string.\n * @param allowString - Whether to allow returning raw (unquoted) strings.\n * @returns A JSON-like value, or `null` if the string cannot be interpreted\n * and `allowString` is `false`.\n *\n * @example\n * ```ts\n * jsonStrLike('{\"a\":1}', false); // -> { a: 1 }\n * jsonStrLike('\"hello\"', false); // -> \"hello\"\n * jsonStrLike('hello', false); // -> null\n * jsonStrLike('hello', true); // -> \"hello\"\n * ```\n *\n * @internal\n */\nexport function jsonStrLike(s: string, allowString: boolean): JSONLike | null {\n\tconst trimmed = s.trim();\n\tconst pr = jsonParse(trimmed);\n\t\n\tif (pr.ok) {\n\t\treturn pr.value;\n\t}\n\tconst m = QUOTED_RE.exec(trimmed);\n\t\n\tif (m) {\n\t\treturn m[2] as JSONLike;\n\t}\n\treturn allowString ? (trimmed as JSONLike) : null;\n}","import type { JSONLike } from '../index';\n\n/**\n * Attempts to parse a string using native {@link JSON.parse}.\n *\n * @remarks\n * Returns a discriminated union with `{ ok: true, value }` on success,\n * or `{ ok: false }` on any parsing error. Exceptions are caught and\n * **never thrown** to callers.\n *\n * @param str - The candidate JSON string.\n * @returns A result object indicating parse success/failure.\n *\n * @example\n * ```ts\n * jsonParse('{\"a\":1}'); // { ok: true, value: { a: 1 } }\n * jsonParse('not json'); // { ok: false }\n * ```\n *\n * @internal\n */\nexport function jsonParse(str: string): { ok: true; value: JSONLike } | { ok: false } {\n\ttry {\n\t\treturn { ok: true, value: JSON.parse(str) as JSONLike };\n\t} \n\tcatch (err) {\n\t}\n\treturn { ok: false };\n}","import type { JSONLike } from '../index';\nimport { \n\tisArrFilled,\n\tisArr, \n\tisObjFilled,\n\tisObj,\n\tisStrFilled,\n\tisNum,\n\tisBool,\n\tjsonEncode,\n\tjsonStrLike,\n} from '../index';\n\n/**\n * Best-effort decoder that normalizes unknown input into a JSON-like value.\n *\n * @remarks\n * `jsonDecode` accepts many shapes of input and produces a `JSONLike` (or `null`)\n * according to the following rules:\n *\n * - **Primitive passthrough**: `null`, numbers, and booleans are returned as-is.\n * - **Arrays/Objects (filled)**: for each string element/property, we attempt to decode\n * it via {@link jsonStrLike} (JSON → unquoted string → raw string if `allowString`).\n * Non-string items are passed through unchanged (cast to `JSONLike`).\n * - **Arrays/Objects (empty)**: returned as-is (they’re valid JSON).\n * - **Standalone strings**: decoded via {@link jsonStrLike}.\n * - **Other values**: return `null`.\n *\n * The function is **non-throwing**; any JSON parse errors are swallowed internally\n * and mapped to either unquoted/raw strings (depending on `allowString`) or `null`.\n * \n * - Uses native `JSON.parse` — safe for untrusted strings provided you do not eval the result.\n * - Does **not** perform schema validation; if you need strict shapes, validate after decoding.\n *\n * @typeParam T - Target type to cast the normalized result to. \n * Defaults to `JSONLike`. Use with care — this is a **type cast**, not a runtime check.\n *\n * @param value - The unknown input to decode (can be primitives, arrays, objects, etc.).\n * @param allowString - If `true`, non-JSON, non-quoted strings are returned as trimmed strings.\n * If `false`, such strings decode to `null`.\n *\n * @returns The decoded value cast to `T`, or `null` when it cannot be decoded.\n *\n * @example\n * ```ts\n * // 1) Primitives pass through\n * jsonDecode(42); // 42\n * jsonDecode(true); // true\n * jsonDecode(null); // null\n *\n * // 2) JSON string\n * jsonDecode('{\"a\":[1,\"2\"]}'); // { a: [1, \"2\"] }\n *\n * // 3) Quoted string\n * jsonDecode('\"hello\"'); // \"hello\"\n *\n * // 4) Raw string with allowString=false (default)\n * jsonDecode('hello'); // null\n *\n * // 5) Raw string with allowString=true\n * jsonDecode('hello', true); // \"hello\"\n *\n * // 6) Arrays/objects with string fields get per-field decoding\n * jsonDecode({ a: '{\"k\":1}', b: 'world' }, true);\n * // -> { a: { k: 1 }, b: \"world\" }\n * ```\n *\n * @throws Never throws; invalid inputs yield `null` or are passed through per rules above.\n *\n * @public\n * @category JSON\n * @since 2.0.0\n */\nexport function jsonDecode<T = JSONLike>(value: unknown, allowString = false): T | null {\n\tif (value === null || isNum(value) || isBool(value)) {\n\t\treturn value as unknown as T;\n\t}\n\tif (isArrFilled(value)) {\n\t\tconst arr = value as ReadonlyArray<unknown>;\n\t\tconst out: JSONLike[] = [];\n\t\t\n\t\tfor (const item of arr) {\n\t\t\tif (isStrFilled(item)) {\n\t\t\t\tout.push(jsonStrLike(String(item), allowString));\n\t\t\t}\n\t\t\telse {\n\t\t\t\tout.push(item as JSONLike);\n\t\t\t}\n\t\t}\n\t\treturn out as unknown as T;\n\t}\n\tif (isObjFilled(value)) {\n\t\tconst src = value as Record<string, unknown>;\n\t\tconst out: Record<string, JSONLike> = {};\n\t\t\n\t\tfor (const key of Object.keys(src)) {\n\t\t\tconst v = src[key];\n\t\t\t\n\t\t\tif (isStrFilled(v)) {\n\t\t\t\tout[key] = jsonStrLike(String(v), allowString);\n\t\t\t} \n\t\t\telse {\n\t\t\t\tout[key] = v as JSONLike;\n\t\t\t}\n\t\t}\n\t\treturn out as unknown as T;\n\t}\n\tif (isArr(value) || isObj(value)) {\n\t\treturn value as unknown as T;\n\t}\n\tif (isStrFilled(value)) {\n\t\treturn jsonStrLike(String(value), allowString) as unknown as T;\n\t}\n\treturn null;\n}\n","import { \n\tisObj,\n\tisArr, \n\tjsonDecode,\n} from '../index';\n\n/**\n * Safely serializes a plain object or array into a JSON string.\n *\n * @remarks\n * This helper wraps {@link JSON.stringify} and adds two key safety features:\n *\n * 1. It only serializes **objects** and **arrays**, ignoring all other data types\n * (numbers, strings, booleans, `null`, `undefined`).\n * 2. It catches all potential `JSON.stringify` errors (such as circular references)\n * and returns an empty string `\"\"` instead of throwing.\n *\n * The function is thus ideal for safe logging, diagnostics, or best-effort\n * serialization where throwing is undesirable.\n * \n * - The output is always a valid JSON string (or empty string on failure).\n * - Use {@link jsonDecode} to reverse the process and safely parse it back.\n * - BigInt values are **not supported** by `JSON.stringify` — they will trigger\n * a caught error, resulting in an empty string.\n *\n * @param value - Any value to encode. Only arrays or plain objects will be serialized;\n * other types return an empty string.\n *\n * @returns The JSON-encoded string representation of the input, \n * or an empty string (`\"\"`) if:\n * - The input is not an array or object.\n * - Serialization fails (e.g., circular reference or BigInt values).\n *\n * @example\n * ```ts\n * // Example 1: Basic usage\n * jsonEncode({ a: 1, b: true });\n * // -> '{\"a\":1,\"b\":true}'\n *\n * // Example 2: Arrays\n * jsonEncode([1, 2, 3]);\n * // -> '[1,2,3]'\n *\n * // Example 3: Non-serializable input\n * jsonEncode(123); // -> ''\n * jsonEncode('hello'); // -> ''\n * jsonEncode(undefined); // -> ''\n *\n * // Example 4: Circular reference\n * const obj: any = {};\n * obj.self = obj;\n * jsonEncode(obj); // -> '' (fails safely)\n * ```\n *\n * @throws Never throws — all exceptions from `JSON.stringify` are caught internally.\n *\n * @see {@link jsonDecode} — performs the inverse operation with safe parsing and normalization.\n * @see {@link JSON.stringify} — the native method used under the hood.\n *\n * @public\n * @category JSON\n * @since 2.0.0\n */\nexport function jsonEncode(value: unknown): string {\n\ttry {\n\t\treturn (isObj(value) || isArr(value)) ? JSON.stringify(value) : '';\n\t}\n\tcatch (err) {\n\t}\n\treturn '';\n}\n","import type { FixedDecimal } from './types';\n\n/**\n * Converts a {@link FixedDecimal} — an exact, integer-based decimal structure —\n * into its canonical string representation (e.g. `\"-123.456\"`).\n *\n * @remarks\n * This function is **exact and reversible**: no precision loss occurs because it\n * operates on the raw digit string (`digitsInteger`) and inserts the decimal point\n * purely by string manipulation.\n *\n * The algorithm:\n * 1. Converts the `digitsInteger` `BigInt` to a string of digits.\n * 2. If `scale` is `0`, returns the signed integer directly.\n * 3. If `scale` is positive:\n * - Pads with leading zeros when the number of digits is smaller than `scale`.\n * - Otherwise, splits at the appropriate boundary between integer and fractional parts.\n * \n * O(n) where `n` is the number of digits in `digitsInteger.toString()`.\n *\n * @param value - The {@link FixedDecimal} object:\n * - `sign`: `1` for positive or `-1` for negative numbers.\n * - `digitsInteger`: All digits as a `BigInt` without a decimal point.\n * - `scale`: The number of digits after the decimal point.\n *\n * @returns A string representation of the number, including a `-` sign if negative.\n * If the number is fractional, a single `.` separates integer and fractional parts.\n *\n * @example\n * ```ts\n * const fd: FixedDecimal = { sign: 1, digitsInteger: 12345n, scale: 2 };\n * fixedDecimalToStr(fd); // \"123.45\"\n * ```\n *\n * @example\n * ```ts\n * // Negative number\n * const neg: FixedDecimal = { sign: -1, digitsInteger: 987n, scale: 3 };\n * fixedDecimalToStr(neg); // \"-0.987\"\n * ```\n *\n * @example\n * ```ts\n * // Small fractional with fewer digits than scale\n * const tiny: FixedDecimal = { sign: 1, digitsInteger: 12n, scale: 5 };\n * fixedDecimalToStr(tiny); // \"0.00012\"\n * ```\n *\n * @example\n * ```ts\n * // Whole number (scale = 0)\n * const whole: FixedDecimal = { sign: 1, digitsInteger: 42n, scale: 0 };\n * fixedDecimalToStr(whole); // \"42\"\n * ```\n *\n * @see changeFixedDecimalScale — for adjusting the scale value safely\n * @see fixedDecimalToNum — for converting to a JavaScript number\n *\n * @since 2.0.0\n */\nexport function fixedDecimalToStr(value: FixedDecimal): string {\n\tconst signSymbol = value.sign < 0 ? '-' : '';\n\tconst allDigitsString = value.digitsInteger.toString();\n\n\tif (value.scale === 0) {\n\t\treturn signSymbol + allDigitsString;\n\t}\n\tconst padZeros = value.scale - allDigitsString.length;\n\n\tif (padZeros >= 0) {\n\t\treturn signSymbol + '0.' + '0'.repeat(padZeros) + allDigitsString;\n\t}\n\tconst integerBoundary = allDigitsString.length - value.scale;\n\tconst integerText = allDigitsString.slice(0, integerBoundary);\n\tconst fractionalText = allDigitsString.slice(integerBoundary);\n\n\treturn signSymbol + integerText + '.' + fractionalText;\n}\n","import type { FixedDecimal } from './types';\nimport { fixedDecimalToStr } from './fixedDecimalToStr';\n\n/**\n * Converts a {@link FixedDecimal} — an exact decimal representation —\n * into a native JavaScript `number` (IEEE 754 double precision).\n *\n * @remarks\n * This function is a **lossy** conversion when `value` contains\n * more precision than JavaScript’s floating-point format can represent.\n * It internally calls {@link fixedDecimalToStr} to produce a normalized\n * string such as `\"-123.4567\"` and then passes it to the built-in\n * `Number()` constructor.\n * \n * O(n) relative to the number of digits in `digitsInteger`\n * (due to string creation in {@link fixedDecimalToStr}).\n *\n * @param value - The {@link FixedDecimal} instance to convert.\n * Must contain:\n * - `sign`: either `1` or `-1`;\n * - `digitsInteger`: a `bigint` representing all digits without any decimal point;\n * - `scale`: how many digits belong after the decimal point.\n *\n * @returns The approximate numeric value as a JavaScript `number`.\n * If the string form is too large or too precise, the result may be\n * rounded or become `Infinity`.\n *\n * @example\n * ```ts\n * const fd: FixedDecimal = { sign: 1, digitsInteger: 12345n, scale: 2 };\n * // Represents exactly 123.45\n * const num = fixedDecimalToNum(fd); // 123.45 (Number)\n * ```\n *\n * @example\n * ```ts\n * // Handles negative numbers as well\n * const neg: FixedDecimal = { sign: -1, digitsInteger: 987n, scale: 3 };\n * const n = fixedDecimalToNum(neg); // -0.987\n * ```\n *\n * @example\n * ```ts\n * // Extreme precision may lose digits beyond ~15–17 significant figures\n * const big: FixedDecimal = { sign: 1, digitsInteger: 12345678901234567890n, scale: 10 };\n * const approx = fixedDecimalToNum(big);\n * console.log(approx); // ~1234567890.1234567 (rounded)\n * ```\n *\n * @see fixedDecimalToStr — for the exact string representation\n * @see https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number#precision JavaScript number precision\n *\n * @since 2.0.0\n */\nexport function fixedDecimalToNum(value: FixedDecimal): number {\n\treturn Number(fixedDecimalToStr(value));\n}\n","import { isNumPZ } from '../index';\n\n/**\n * Converts a number expressed in normalized exponential/scientific notation\n * (e.g., `\"1.23e+5\"`, `\"4e-7\"`, `\"0009.500e2\"`) into its **sign**, **integer**,\n * and **fractional** parts as plain decimal digit strings — **without** any\n * decimal point or leading `+`/`-` characters.\n *\n * @remarks\n * - This function does **not** perform numeric arithmetic; instead it does a\n * textual normalization that preserves all significant digits exactly.\n * - It accepts the `sign` separately so that callers can pre-parse signs from\n * inputs like `\"-1.23e3\"` and pass `sign = -1` with `exponentialString = \"1.23e3\"`.\n * (If you already have a positive string, pass `sign = 1`.)\n * - The function normalizes the coefficient and exponent first, then uses a\n * single regex match to validate the shape:\n * - Coefficient: `([0-9]+)(?:\\.([0-9]*))?`\n * - Exponent: `e([+\\-]?[0-9]+)`\n * - Trailing zeros are added to the **integer** side for positive net exponents,\n * while leading zeros are added to the **fractional** side for negative net exponents.\n * - All returned parts (`integerPart`, `fractionalPart`) contain only ASCII digits.\n * The decimal point is **not** returned; you can re-insert it if needed by\n * placing it between `integerPart` and `fractionalPart`.\n * \n * Time O(n) and space O(n), where n is the number of digits in the coefficient,\n * due to string concatenation and slicing.\n *\n * @param sign - The pre-parsed sign of the number: `1` for positive, `-1` for negative.\n * @param exponentialString - A string in exponential notation.\n * Examples: `\"1e3\"`, `\"1.23e+5\"`, `\"4.560e-2\"`, `\"0009.500e2\"`.\n * The function is case-insensitive for the `'e'` and tolerates leading zeros in the coefficient.\n *\n * @returns An object with three properties:\n * - `sign`: Echo of the input sign (`1` | `-1`).\n * - `integerPart`: All digits to the left of the decimal point after expansion.\n * - `fractionalPart`: All digits to the right of the decimal point after expansion.\n *\n * @throws {Error} If `exponentialString` cannot be parsed as scientific notation.\n *\n * @example\n * ```ts\n * // 1.23 × 10^5 = 123000\n * convertExponentialToParts(1, \"1.23e5\");\n * // => { sign: 1, integerPart: \"123000\", fractionalPart: \"\" }\n * ```\n *\n * @example\n * ```ts\n * // 4.5 × 10^-3 = 0.0045\n * convertExponentialToParts(1, \"4.5e-3\");\n * // => { sign: 1, integerPart: \"0\", fractionalPart: \"0045\" }\n * ```\n *\n * @example\n * ```ts\n * // -7.00e+0 = -7\n * convertExponentialToParts(-1, \"7.00e0\");\n * // => { sign: -1, integerPart: \"7\", fractionalPart: \"\" }\n * ```\n *\n * @example\n * ```ts\n * // Leading zeros in coefficient are handled; fractional length adjusts exponent\n * convertExponentialToParts(1, \"0009.500e2\"); // 9.500 × 10^2 = 950\n * // => { sign: 1, integerPart: \"950\", fractionalPart: \"\" }\n * ```\n *\n * @example\n * ```ts\n * // You can reconstruct a normalized decimal string yourself:\n * const { sign, integerPart, fractionalPart } = convertExponentialToParts(-1, \"1.234e-2\");\n * const signChar = sign < 0 ? \"-\" : \"\";\n * const plain = fractionalPart ? `${integerPart}.${fractionalPart}` : integerPart;\n * // plain == \"0.01234\"\n * const result = signChar + plain; // \"-0.01234\"\n * ```\n *\n * @see isNumPZ — utility used here to detect non-negative integers (exponent ≥ 0).\n *\n * @since 2.0.0\n */\nexport function convertExponentialToParts(\n\tsign: 1 | -1,\n\texponentialString: string\n): { sign: 1 | -1; integerPart: string; fractionalPart: string } {\n\tconst match = /^([0-9]+)(?:\\.([0-9]*))?e([+\\-]?[0-9]+)$/i.exec(\n\t\t(() => {\n\t\t\tconst [coefficient, exponentText] = exponentialString.split(/e/i);\n\t\t\tconst [integerPart, fractionalPart = ''] = coefficient.split('.');\n\t\t\tconst allDigits = integerPart.replace(/^0+/, '') + fractionalPart;\n\t\t\tconst exponentValue = parseInt(exponentText, 10) - fractionalPart.length;\n\t\t\t\n\t\t\treturn `${allDigits || '0'}e${exponentValue}`;\n\t\t})()\n\t);\n\n\tif (!match) {\n\t\tthrow new Error('Failed to parse exponential notation.');\n\t}\n\tlet allDigits = match[1];\n\tconst exponent = parseInt(match[3], 10);\n\n\tif (isNumPZ(exponent)) {\n\t\tallDigits = allDigits + '0'.repeat(exponent);\n\t\t\n\t\treturn { \n\t\t\tsign, \n\t\t\tintegerPart: allDigits || '0', \n\t\t\tfractionalPart: '', \n\t\t};\n\t} \n\telse {\n\t\tconst digitsToLeft = -exponent;\n\t\t\n\t\tif (digitsToLeft >= allDigits.length) {\n\t\t\tconst missingZeros = '0'.repeat(digitsToLeft - allDigits.length);\n\t\t\t\n\t\t\treturn {\n\t\t\t\tsign,\n\t\t\t\tintegerPart: '0',\n\t\t\t\tfractionalPart: missingZeros + allDigits,\n\t\t\t};\n\t\t}\n\t\telse {\n\t\t\tconst splitIndex = allDigits.length - digitsToLeft;\n\t\t\t\n\t\t\treturn {\n\t\t\t\tsign,\n\t\t\t\tintegerPart: allDigits.slice(0, splitIndex),\n\t\t\t\tfractionalPart: allDigits.slice(splitIndex),\n\t\t\t};\n\t\t}\n\t}\n}","import { convertExponentialToParts } from './convertExponentialToParts';\n\n/**\n * Normalizes an arbitrary numeric input into sign, integer, and fractional string parts\n * without losing precision, preparing it for exact fixed-decimal processing.\n *\n * @remarks\n * This utility accepts `bigint`, `number`, and `string` inputs and returns a tuple-like\n * object with three fields:\n *\n * - `sign`: `1` for non-negative values, `-1` for negative values.\n * - `integerPart`: the digits before the decimal point as a string (no sign, no separators).\n * - `fractionalPart`: the digits after the decimal point as a string (no sign, no separators).\n *\n * For JavaScript `number`s, the function first checks finiteness and then converts the\n * absolute value to an exponential string (via `toExponential(30)`) to avoid\n * floating-point artifacts when extracting digits. It delegates parsing of that exponential\n * form to {@link convertExponentialToParts}.\n *\n * For `string`s, the function:\n * - Trims whitespace and replaces a comma `,` decimal separator with a dot `.`.\n * - Parses and removes a leading `+`/`-` sign (if present).\n * - Validates the remaining characters with a permissive numeric pattern that allows:\n * - optional integer digits,\n * - an optional decimal point with digits,\n * - an optional scientific exponent (`e` or `E` with optional `+`/`-` and digits).\n * - If an exponent is present, it delegates to {@link convertExponentialToParts};\n * otherwise it splits on the decimal point.\n *\n * **Important:** This function does not strip leading zeros in `integerPart` or trailing\n * zeros in `fractionalPart`. If you need canonicalized output (e.g., remove leading/trailing\n * zeros), do that in a later step (e.g., when building your fixed-decimal representation).\n *\n * @param input - The numeric input to normalize. Supported types:\n * - `bigint` (e.g., `123n`, `-9007199254740993n`)\n * - `number` (finite only; `NaN`, `Infinity`, `-Infinity` will throw)\n * - `string` (e.g., `\"42\"`, `\"-0.034\"`, `\"1.2e-5\"`, with optional leading sign, optional\n * decimal part, optional exponent; commas are allowed as decimal separators and are\n * converted to dots)\n *\n * @returns An object with the normalized components:\n * ```ts\n * {\n * sign: 1 | -1;\n * integerPart: string;\n * fractionalPart: string;\n * }\n * ```\n * The `integerPart` and `fractionalPart` contain only ASCII digits (`0`–`9`) and\n * **never** include sign or exponent markers.\n *\n * @throws {Error}\n * - If `input` is a `number` but not finite (`NaN`, `Infinity`, `-Infinity`).\n * - If `input` is a `string` that is empty after trimming/replacement.\n * - If `input` is a `string` that fails the numeric validation regex.\n * - If `input` is of an unsupported type (not `bigint`, `number`, or `string`).\n * - Any errors propagated from {@link convertExponentialToParts} when parsing exponential forms.\n *\n * @example\n * // bigint input → fractional part is empty\n * normalizeToDecimalComponents(123n);\n * // => { sign: 1, integerPart: \"123\", fractionalPart: \"\" }\n *\n * @example\n * // negative bigint\n * normalizeToDecimalComponents(-987654321n);\n * // => { sign: -1, integerPart: \"987654321\", fractionalPart: \"\" }\n *\n * @example\n * // finite number input; uses exponential internally to avoid FP artifacts\n * normalizeToDecimalComponents(0.0000034);\n * // => { sign: 1, integerPart: \"0\", fractionalPart: \"0000034\" } // exact digits\n *\n * @example\n * // string with decimal comma and explicit sign\n * normalizeToDecimalComponents(\"+1,250\");\n * // => { sign: 1, integerPart: \"1\", fractionalPart: \"250\" }\n *\n * @example\n * // scientific notation string\n * normalizeToDecimalComponents(\"-1.234e+3\");\n * // => { sign: -1, integerPart: \"1234\", fractionalPart: \"\" }\n *\n * @example\n * // invalid string (throws)\n * normalizeToDecimalComponents(\"12.34.56\"); // Error: Invalid numeric string.\n *\n * @see convertExponentialToParts\n * @category Parsing\n * @since 2.0.0\n * @public\n */\nexport function normalizeToDecimalComponents(input: unknown): {\n\tsign: 1 | -1;\n\tintegerPart: string;\n\tfractionalPart: string;\n} {\n\tif (typeof input === 'bigint') {\n\t\tconst sign: 1 | -1 = input < 0n ? -1 : 1;\n\t\tconst absoluteValue = (input < 0n ? -input : input).toString();\n\t\t\n\t\treturn { \n\t\t\tsign, \n\t\t\tintegerPart: absoluteValue, \n\t\t\tfractionalPart: '', \n\t\t};\n\t}\n\tif (typeof input === 'number') {\n\t\tif (!Number.isFinite(input)) {\n\t\t\tthrow new Error('Input number is not finite.');\n\t\t}\n\t\tconst sign: 1 | -1 = input < 0 ? -1 : 1;\n\t\tconst absoluteValue = Math.abs(input);\n\t\tconst exponentialForm = absoluteValue.toExponential(30); // например \"1.23456e-5\"\n\t\t\n\t\treturn convertExponentialToParts(sign, exponentialForm);\n\t}\n\tif (typeof input === 'string') {\n\t\tlet processed = input.trim().replace(',', '.');\n\t\t\n\t\tif (!processed) {\n\t\t\tthrow new Error('Input string is empty.');\n\t\t}\n\t\tlet sign: 1 | -1 = 1;\n\t\t\n\t\tif (processed.startsWith('+') || processed.startsWith('-')) {\n\t\t\tsign = processed.startsWith('-') ? -1 : 1;\n\t\t\tprocessed = processed.slice(1);\n\t\t}\n\t\tif (/^[0-9]*\\.?[0-9]*(e[+\\-]?[0-9]+)?$/i.test(processed)) {\n\t\t\tif (/e/i.test(processed)) {\n\t\t\t\treturn convertExponentialToParts(sign, processed);\n\t\t\t}\n\t\t\tconst [ integerPart = '0', fractionalPart = '' ] = processed.split('.');\n\t\t\t\n\t\t\treturn { \n\t\t\t\tsign, \n\t\t\t\tintegerPart, \n\t\t\t\tfractionalPart, \n\t\t\t};\n\t\t}\n\t\tthrow new Error('Invalid numeric string.');\n\t}\n\tthrow new Error('Unsupported input type.');\n}","import type { FixedDecimal } from './types';\nimport { normalizeToDecimalComponents } from './normalizeToDecimalComponents';\n\n/**\n * Parses any numeric input (`number`, `bigint`, or `string`) into an exact {@link FixedDecimal}\n * representation, preserving all digits without floating-point rounding errors.\n *\n * @remarks\n * This function transforms arbitrary numeric input into a **fixed-precision decimal structure**\n * that can safely represent extremely large or small values without losing information.\n * It achieves this by first decomposing the input using {@link normalizeToDecimalComponents}\n * and then constructing a `FixedDecimal` object consisting of:\n *\n * - `sign` → `1` for positive values, `-1` for negative values.\n * - `digitsInteger` → a `BigInt` that encodes *all digits* of the number as if\n * the decimal point were removed.\n * - `scale` → the count of digits that were originally after the decimal point.\n *\n * The resulting value can later be precisely converted back to a string or to a\n * JavaScript `number` using helpers like `fixedDecimalToStr` or `fixedDecimalToNum`.\n *\n * This process **avoids IEEE-754 floating-point artifacts**, ensuring mathematically\n * exact handling of decimal fractions (e.g. `\"0.1\" + \"0.2\" → 0.3` instead of `0.30000000000000004`).\n *\n * @param input - Any numeric source value. Supported types:\n * - `number` — finite only (`NaN`, `Infinity`, `-Infinity` will throw).\n * - `bigint` — directly converted without fractional digits.\n * - `string` — may contain optional sign, decimal point, or exponential notation (`1.23e-5`).\n * Commas `,` as decimal separators are also supported and converted to dots `.`.\n *\n * @returns A normalized {@link FixedDecimal} object:\n * ```ts\n * {\n * sign: 1 | -1; // the numeric sign\n * digitsInteger: bigint; // all digits as a BigInt, no decimal point\n * scale: number; // number of digits after the decimal\n * }\n * ```\n *\n * @throws {Error}\n * - If the input is not a supported type (`number`, `bigint`, or `string`).\n * - If the string cannot be parsed as a valid numeric representation.\n * - If the number is not finite.\n * - Any error propagated from {@link normalizeToDecimalComponents}.\n *\n * @example\n * // Simple integer number\n * parseToFixedDecimal(42);\n * // => { sign: 1, digitsInteger: 42n, scale: 0 }\n *\n * @example\n * // Decimal fraction\n * parseToFixedDecimal(\"123.456\");\n * // => { sign: 1, digitsInteger: 123456n, scale: 3 }\n *\n * @example\n * // Number in exponential notation\n * parseToFixedDecimal(\"-1.23e-4\");\n * // => { sign: -1, digitsInteger: 123n, scale: 6 } // represents -0.000123\n *\n * @example\n * // Leading zeros and trailing fractional zeros are trimmed internally\n * parseToFixedDecimal(\"00045.67000\");\n * // => { sign: 1, digitsInteger: 4567n, scale: 2 } // \"45.67\"\n *\n * @example\n * // Very large integer input using bigint\n * parseToFixedDecimal(123456789012345678901234567890n);\n * // => { sign: 1, digitsInteger: 123456789012345678901234567890n, scale: 0 }\n *\n * @example\n * // Negative value with high precision fraction\n * parseToFixedDecimal(\"-0.00000003432\");\n * // => { sign: -1, digitsInteger: 3432n, scale: 11 }\n *\n * @see normalizeToDecimalComponents\n * @see FixedDecimal\n * @see fixedDecimalToNum\n * @see fixedDecimalToStr\n *\n * @category Parsing\n * @since 2.0.0\n * @public\n */\nexport function parseToFixedDecimal(input: unknown): FixedDecimal {\n\tconst { \n\t\tsign, \n\t\tintegerPart, \n\t\tfractionalPart, \n\t} = normalizeToDecimalComponents(input);\n\tconst integerDigits = integerPart.replace(/^0+/, '') || '0';\n\tconst fractionalDigits = fractionalPart.replace(/0+$/, '');\n\tconst combinedDigits = (integerDigits + fractionalDigits) || '0';\n\n\treturn {\n\t\tsign,\n\t\tdigitsInteger: BigInt(combinedDigits),\n\t\tscale: fractionalDigits.length,\n\t};\n}\n","import type { FixedDecimal } from './types';\n\n/**\n * Rounds a {@link FixedDecimal} value to the specified number of fractional digits,\n * using either **half-up** (standard rounding) or **truncation** (cut-off without rounding).\n *\n * @remarks\n * This function operates entirely in fixed-precision integer space (`BigInt` arithmetic),\n * so rounding is mathematically exact — it never suffers from floating-point errors.\n *\n * Internally, it determines how many fractional digits must be removed from\n * `source.digitsInteger` to reach the desired precision (`decimalPlaces`), divides\n * by `10 ** digitsToRemove`, and conditionally increments the result depending on\n * the remainder and rounding mode.\n *\n * It preserves the original `sign` and returns a new {@link FixedDecimal} object\n * with an updated `scale` (number of digits after the decimal point).\n *\n * ---\n * **Rounding modes:**\n * - `'half-up'` — standard rounding to nearest neighbor; `.5` rounds **away from zero**.\n * Example: `1.235 → 1.24`, `-1.235 → -1.24`.\n * - `'trunc'` — truncates digits beyond the target precision (rounds **toward zero**).\n * Example: `1.239 → 1.23`, `-1.239 → -1.23`.\n *\n * ---\n * @param source - The input {@link FixedDecimal} to round.\n * Must contain a valid combination of:\n * - `sign`: `1` or `-1`\n * - `digitsInteger`: a `BigInt` representing all digits (no decimal point)\n * - `scale`: number of digits after the decimal\n *\n * @param decimalPlaces - Target number of digits to keep **after the decimal point**.\n * Values less than 0 are treated as 0. \n * For example, rounding to `2` means \"keep two digits after the decimal\".\n *\n * @param roundMode - Rounding algorithm to use:\n * - `'half-up'` (default) → rounds 0.5 and higher up.\n * - `'trunc'` → simply removes extra digits without rounding up.\n *\n * @defaultValue `'half-up'`\n *\n * @returns A **new** {@link FixedDecimal} with the adjusted `digitsInteger`\n * and `scale` equal to `decimalPlaces`. \n * If the requested precision is greater than or equal to `source.scale`,\n * the source value is returned unchanged (shallow copy).\n *\n * @throws {Error}\n * - Never throws directly in normal use, but may propagate errors if invalid\n * numeric parameters are passed (e.g., non-integer `decimalPlaces`).\n *\n * ---\n * @example\n * // Half-up rounding\n * const value: FixedDecimal = { sign: 1, digitsInteger: 123456n, scale: 3 }; // 123.456\n * roundFixedDecimal(value, 2, 'half-up');\n * // => { sign: 1, digitsInteger: 12346n, scale: 2 } // 123.46\n *\n * @example\n * // Truncation (cut-off)\n * const value: FixedDecimal = { sign: 1, digitsInteger: 123456n, scale: 3 };\n * roundFixedDecimal(value, 2, 'trunc');\n * // => { sign: 1, digitsInteger: 12345n, scale: 2 } // 123.45\n *\n * @example\n * // No rounding needed (scale already smaller)\n * const v: FixedDecimal = { sign: -1, digitsInteger: 1234n, scale: 1 }; // -123.4\n * roundFixedDecimal(v, 3);\n * // => identical copy: { sign: -1, digitsInteger: 1234n, scale: 1 }\n *\n * @example\n * // Rounding very small values\n * const v: FixedDecimal = { sign: 1, digitsInteger: 123n, scale: 6 }; // 0.000123\n * roundFixedDecimal(v, 4);\n * // => { sign: 1, digitsInteger: 1n, scale: 4 } // 0.0001\n *\n * @example\n * // Rounding negative numbers (half-up → away from zero)\n * const v: FixedDecimal = { sign: -1, digitsInteger: 125n, scale: 2 }; // -1.25\n * roundFixedDecimal(v, 1, 'half-up');\n * // => { sign: -1, digitsInteger: 13n, scale: 1 } // -1.3\n *\n * @see FixedDecimal\n * @see parseToFixedDecimal\n * @see fixedDecimalToNum\n * @see fixedDecimalToStr\n * @see formatToNum\n *\n * @category Math\n * @since 2.0.0\n * @public\n */\nexport function roundFixedDecimal(\n\tsource: FixedDecimal,\n\tdecimalPlaces: number,\n\troundMode: 'half-up' | 'trunc' = 'half-up'\n): FixedDecimal {\n\tconst targetPrecision = Math.max(0, Math.trunc(decimalPlaces));\n\n\tif (source.scale <= targetPrecision) {\n\t\treturn { ...source };\n\t}\n\tconst digitsToRemove = source.scale - targetPrecision;\n\tconst divisionFactor = 10n ** BigInt(digitsToRemove);\n\tconst integerPart = source.digitsInteger / divisionFactor;\n\tconst remainder = source.digitsInteger % divisionFactor;\n\n\tif (roundMode === 'trunc' || remainder === 0n) {\n\t\treturn { \n\t\t\tsign: source.sign, \n\t\t\tdigitsInteger: integerPart, \n\t\t\tscale: targetPrecision, \n\t\t};\n\t}\n\tconst halfThreshold = divisionFactor / 2n;\n\tconst shouldRoundUp = remainder >= halfThreshold;\n\tconst roundedValue = shouldRoundUp ? integerPart + 1n : integerPart;\n\t\n\treturn { \n\t\tsign: source.sign, \n\t\tdigitsInteger: roundedValue, \n\t\tscale: targetPrecision, \n\t};\n}","import { fixedDecimalToNum } from './fixedDecimalToNum';\nimport { parseToFixedDecimal } from './parseToFixedDecimal';\nimport { roundFixedDecimal } from './roundFixedDecimal';\n\n/**\n * Converts an arbitrary numeric input to a JavaScript `number`, optionally rounding\n * it to a fixed number of fractional digits using **half-up** rounding.\n *\n * @remarks\n * This function is a convenience wrapper around your fixed-precision helpers:\n *\n * 1. {@link parseToFixedDecimal} — parses the unknown input (`number`/`string`/etc.)\n * into an exact, lossless fixed-decimal representation.\n * 2. `roundFixedDecimal` — (invoked only when `round > 1`) rounds that fixed-decimal\n * value to the requested scale using the **half-up** algorithm.\n * 3. {@link fixedDecimalToNum} — converts the (optionally rounded) fixed-decimal\n * back to a JavaScript `number`.\n *\n * Because rounding is done in fixed-precision space, you avoid common IEEE-754\n * floating-point artifacts (e.g., `0.1 + 0.2 !== 0.3`) during parsing/rounding.\n * Precision is finally limited only at the last step when the value is converted\n * to a JS `number`.\n *\n * @param value - Any value that represents a number. Typical cases:\n * - `number` (e.g., `12`, `-0.034`, `1e6`)\n * - numeric `string` (e.g., `\"42\"`, `\"-123.456\"`)\n * - values that your {@link parseToFixedDecimal} knows how to normalize.\n *\n * If the value cannot be parsed by {@link parseToFixedDecimal}, an error will be thrown from there.\n *\n * @param round - Target number of fractional digits for rounding **in fixed-precision**.\n * - If `round > 1`, the function rounds to exactly `round` digits after the decimal point\n * using **half-up** (i.e., `.5` rounds away from zero) via `roundFixedDecimal`.\n * - If `round <= 1`, no rounding is applied; the parsed value is passed through as-is.\n *\n * @defaultValue `1` (no rounding; passthrough)\n *\n * @returns The resulting numeric value as a JavaScript `number`.\n *\n * @throws {Error}\n * - Re-throws any parsing/normalization errors from {@link parseToFixedDecimal}.\n * - Re-throws any rounding errors from `roundFixedDecimal` (e.g., invalid scale).\n *\n * @example\n * // No rounding (default `round = 1` → passthrough)\n * numNormalize(\"123.456\"); // => 123.456\n * numNormalize(0.034); // => 0.034\n *\n * @example\n * // Round to 2 fractional digits (half-up)\n * numNormalize(\"123.456\", 2); // => 123.46 (because .456 → .46)\n * numNormalize(\"-1.235\", 2); // => -1.24 (half-up away from zero)\n *\n * @example\n * // Large values: parsed and rounded in fixed precision, then converted to number\n * numNormalize(\"234893249238948.000003432\", 6); // precise rounding in fixed space,\n * // final result as JS number\n *\n * @example\n * // Explicit passthrough (any `round <= 1` behaves the same)\n * numNormalize(\"1000.555\", 1); // => 1000.555 (no rounding step invoked)\n * numNormalize(\"1000.555\", 0); // => 1000.555 (still no rounding)\n *\n * @see parseToFixedDecimal\n * @see fixedDecimalToNum\n * @see roundFixedDecimal\n *\n * @category Number Formatting\n * @since 2.0.0\n * @public\n */\nexport function numNormalize(value: unknown, round: number = 1, throwError: boolean = false): number {\n\ttry {\n\t\treturn fixedDecimalToNum((round > 1) ? roundFixedDecimal(parseToFixedDecimal(value), round, 'half-up') : parseToFixedDecimal(value));\n\t}\n\tcatch (err: any) {\n\t\tif (throwError) {\n\t\t\tthrow err;\n\t\t}\n\t}\n\treturn 0;\n}\n","import { \n\tisStrFilled,\n\tisStr,\n\tstrTrim, \n} from '../index';\n\n/**\n * Converts any given string-like value into a lower-cased, trimmed string.\n *\n * @summary\n * Safely transforms an unknown value into a normalized lowercase string.\n * If the input is not a valid non-empty string, the function returns an empty string (`\"\"`).\n *\n * @param value - Any unknown input to convert to lowercase.\n *\n * @returns A lowercase string, or an empty string if the input is not a valid string.\n *\n * @remarks\n * ### Processing steps\n * 1. **Type check** — ensures the input is a string using {@link isStr}.\n * 2. **Trimming** — removes leading and trailing whitespace via {@link strTrim}.\n * 3. **Validation** — ensures the result is non-empty with {@link isStrFilled}.\n * 4. **Lowercasing** — calls `String.prototype.toLowerCase()` on the trimmed text.\n * 5. If the string is empty or not valid at any step, returns `\"\"`.\n *\n * ### Error safety\n * - The function **never throws**, regardless of input type.\n * - Non-string inputs (numbers, booleans, objects, arrays, `null`, `undefined`) all yield `\"\"`.\n *\n * ### Use cases\n * - Case-insensitive string comparison (normalize both sides with `strLowerCase`).\n * - Normalizing user input before storing or indexing.\n * - Simplifying logic where optional strings may be `null` or empty.\n *\n * ### Performance\n * - Time complexity: **O(n)** (where `n` = string length, due to trimming and lowercasing).\n * - Space complexity: **O(n)** (new string created by normalization).\n *\n * ### Examples\n *\n * @example\n * // Basic strings\n * strLowerCase('HELLO'); // => \"hello\"\n * strLowerCase(' TEST '); // => \"test\"\n *\n * @example\n * // Mixed types\n * strLowerCase(123); // => \"\"\n * strLowerCase(true); // => \"\"\n * strLowerCase(null); // => \"\"\n *\n * @example\n * // Empty or whitespace inputs\n * strLowerCase(' '); // => \"\"\n * strLowerCase(''); // => \"\"\n *\n * @example\n * // Already lowercase\n * strLowerCase('data'); // => \"data\"\n *\n * @see isStr\n * @see isStrFilled\n * @see strTrim\n *\n * @category String\n * @public\n * @since 2.0.0\n */\nexport function strLowerCase(value?: unknown): string {\n\tif (!isStr(value)) {\n\t\treturn '';\n\t}\n\tconst trimmed = strTrim(value);\n\t\n\treturn isStrFilled(trimmed) ? trimmed.toLowerCase() : '';\n}\n","import { \n\tisStrFilled,\n\tisStr,\n\tstrLowerCase, \n} from '../index';\n\nexport function strNormalCase(value?: unknown): string {\n\tif (!isStr(value)) {\n\t\treturn '';\n\t}\n\tconst parsed = strLowerCase(value);\n\t\n\treturn isStrFilled(parsed) ? (parsed[0].toUpperCase() + parsed.slice(1)) : '';\n}\n","import { \n\tisStr,\n\tstrTrim,\n\tstrUndefined, \n} from '../index';\n\n/**\n * Converts `undefined` or empty (whitespace-only) strings into `null`.\n *\n * @summary\n * Safely normalizes optional values by replacing both `undefined` and blank strings\n * with `null`, while preserving all other values as-is. \n * This helps unify \"missing\" or \"empty\" values under a single, database-friendly\n * `null` representation.\n *\n * @param value - Any input value that may be a string, `undefined`, or another type.\n *\n * @returns\n * - `null` if:\n * - The input is `undefined`, or\n * - The input is a string that becomes empty after trimming (using {@link strTrim}).\n * - Otherwise returns the original `value`.\n *\n * @remarks\n * ### Processing steps\n * 1. If `value` is `undefined`, returns `null`.\n * 2. If `value` is a string:\n * - Trims it with {@link strTrim}, removing whitespace and invisible characters.\n * - If the trimmed result is empty (`''`), returns `null`.\n * 3. Otherwise returns the original value unchanged.\n *\n * ### Behavior notes\n * - Non-string, defined values (like `0`, `false`, `{}`, `[]`) are **not modified**.\n * - The function is **pure** (non-mutating) and safe for use in JSON or ORM normalization.\n * - Often used to prepare form data, REST payloads, or DB entities for consistent nullability.\n *\n * ### Comparison with {@link strUndefined}\n * | Case | `strNull` | `strUndefined` |\n * |------|----------------|----------------------|\n * | `undefined` | `null` | `undefined` |\n * | `''` (empty string) | `null` | `undefined` |\n * | `'text'` | `'text'` | `'text'` |\n * | non-string (e.g. `0`) | `0` | `0` |\n *\n * ### Use cases\n * - Unifying “empty” form values before DB insertion (`''` or `undefined` → `null`)\n * - Sanitizing request bodies before persistence or validation\n * - Preventing inconsistent null/undefined states across backend and frontend layers\n *\n * ### Performance\n * - Time complexity: **O(n)** (depends on string length)\n * - Space complexity: **O(n)** (creates a trimmed string copy)\n *\n * ### Examples\n *\n * @example\n * // Empty and whitespace strings\n * strNull(''); // => null\n * strNull(' '); // => null\n *\n * @example\n * // Undefined also becomes null\n * strNull(undefined); // => null\n *\n * @example\n * // Non-empty strings remain as-is\n * strNull('Hello'); // => \"Hello\"\n * strNull(' Data '); // => \" Data \"\n *\n * @example\n * // Non-string types are preserved\n * strNull(0); // => 0\n * strNull(false); // => false\n * strNull([]); // => []\n * strNull({}); // => {}\n *\n * @see isStr\n * @see strTrim\n * @see strUndefined\n *\n * @category String\n * @public\n * @since 2.0.0\n */\nexport function strNull(value: unknown) {\n\treturn ((isStr(value) && strTrim(value) === '') || value === undefined) ? null : value;\n}\n","import { \n\tisStr,\n\tstrTrim, \n} from '../index';\n\n/**\n * Normalizes and validates a phone number into international format (`E.164` style).\n *\n * @summary\n * Converts various human-entered phone number formats (with spaces, dashes, parentheses,\n * or local prefixes) into a clean, standardized string beginning with `\"+\"`\n * and containing 10–15 digits.\n *\n * Returns `null` if the value is not a valid phone number after normalization.\n *\n * @param value - The input value to format. Can be any unknown type; only strings are processed.\n * @param defaultCountry - Optional international prefix to prepend for 10-digit local numbers\n * (defaults to `\"+7\"` — Russia/Kazakhstan). \n * Use your target country code (e.g., `\"+34\"` for Spain, `\"+1\"` for USA).\n *\n * @returns\n * A normalized phone number in `+XXXXXXXXXX` format if valid, or `null` if the input\n * cannot be interpreted as a valid number.\n *\n * @remarks\n * ### Normalization rules\n * 1. **Input validation:** \n * If `value` is not a string, returns `null`.\n *\n * 2. **Trimming and cleaning:** \n * Removes all whitespace, hyphens, parentheses, and dots.\n * Example: \n * `\" (123) 456-7890 \"` → `\"1234567890\"`.\n *\n * 3. **International formats:**\n * - `00` prefix (common in Europe) is replaced with `\"+\"`. \n * → `\"0049123456789\"` → `\"+49123456789\"`.\n *\n * 4. **Local numbers (10 digits):** \n * Prepends the `defaultCountry` code. \n * → `\"1234567890\"` → `\"+71234567890\"` (default country `+7`).\n *\n * 5. **Generic international numbers (9–15 digits):** \n * If not starting with `\"0\"`, adds `\"+\"` prefix. \n * → `\"380501234567\"` → `\"+380501234567\"`.\n *\n * 6. **Validation check:** \n * The result must match the pattern `/^\\+\\d{10,15}$/` \n * — i.e., plus sign followed by 10–15 digits. \n * If not, returns `null`.\n *\n * ### Error safety\n * - Never throws — all invalid or unexpected inputs return `null`.\n * - Automatically cleans up common formatting symbols without side effects.\n *\n * ### Performance\n * - Time complexity: **O(n)** (string length).\n * - Space complexity: **O(n)** (new string creation during cleanup).\n *\n * ### Common pitfalls\n * - Numbers starting with `\"0\"` are **rejected**, since they are ambiguous.\n * - 8-digit local formats are not automatically expanded — use a country-specific parser if needed.\n * - This function performs **basic formatting and validation**, not full ITU-T E.164 compliance.\n *\n * ### Examples\n *\n * @example\n * // International format already valid\n * strPhone('+380501234567'); // => \"+380501234567\"\n *\n * @example\n * // European \"00\" prefix\n * strPhone('00442079460729'); // => \"+442079460729\"\n *\n * @example\n * // Local 10-digit number (default country +7)\n * strPhone('9123456789'); // => \"+79123456789\"\n *\n * @example\n * // With custom default country\n * strPhone('9876543210', '+34'); // => \"+349876543210\"\n *\n * @example\n * // Strings with spaces, punctuation, parentheses\n * strPhone('(050) 123-45-67'); // => \"+70501234567\"\n * strPhone('+1 (202) 555-0183'); // => \"+12025550183\"\n *\n * @example\n * // Invalid or ambiguous inputs\n * strPhone(''); // => null\n * strPhone('000123456'); // => null\n * strPhone('abcdefgh'); // => null\n * strPhone(null); // => null\n * strPhone(true); // => null\n *\n * @see isStr\n * @see strTrim\n *\n * @category String\n * @public\n * @since 2.0.0\n */\nexport function strPhone(value?: unknown, defaultCountry = '+7'): string | null {\n\tif (!isStr(value)) {\n\t\treturn null;\n\t}\n\tlet phone = strTrim(value).replace(/[\\s\\-().]/g, '');\n\n\tif (/^00\\d{8,15}$/.test(phone)) {\n\t\tphone = '+' + phone.slice(2);\n\t}\n\telse if (/^\\d{10}$/.test(phone)) {\n\t\tphone = defaultCountry + phone;\n\t}\n\telse if (/^\\d{9,15}$/.test(phone) && !phone.startsWith('0')) {\n\t\tphone = '+' + phone;\n\t}\n\treturn /^\\+\\d{10,15}$/.test(phone) ? phone : null;\n}\n","import { isStr } from '../index';\n\n\n/**\n * Trims, normalizes, and cleans up invisible characters from a string.\n *\n * @summary\n * Safely converts any input into a clean, Unicode-normalized string with all\n * leading/trailing whitespace removed and zero-width characters stripped out.\n * \n * Returns an empty string (`\"\"`) for all non-string inputs.\n *\n * @param value - Any value that may contain text or string-like content.\n *\n * @returns A normalized, trimmed string without invisible Unicode separators.\n * Returns an empty string if `value` is not a string.\n *\n * @remarks\n * ### Processing steps\n * 1. **Type check:** \n * Uses {@link isStr} to ensure the input is a string. \n * Non-strings are converted to `\"\"`.\n *\n * 2. **Trimming:** \n * Removes all leading and trailing whitespace (`String.prototype.trim()`).\n *\n * 3. **Unicode normalization:** \n * Applies `normalize('NFKC')` — Compatibility Composition — which:\n * - Converts full-width and compatibility forms into canonical ones. \n * Example: `\"ABC\"` → `\"ABC\"`.\n * - Normalizes composed characters (e.g., `\"é\"` vs `\"é\"`).\n *\n * 4. **Invisible character cleanup:** \n * Removes hidden zero-width Unicode characters commonly introduced by copy/paste:\n * - `U+200B` ZERO WIDTH SPACE \n * - `U+200C` ZERO WIDTH NON-JOINER \n * - `U+200D` ZERO WIDTH JOINER \n * - `U+FEFF` ZERO WIDTH NO-BREAK SPACE (BOM)\n *\n * 5. **Safe stringification:** \n * Non-string values are returned as empty string rather than `\"undefined\"` or `\"null\"`.\n *\n * ### Benefits\n * - Eliminates subtle text differences that break comparisons or hashing.\n * - Prevents user input issues caused by hidden characters.\n * - Safe to use in both frontend and backend environments.\n *\n * ### Performance\n * - Time complexity: **O(n)** — proportional to the input string length.\n * - Space complexity: **O(n)** — creates a new normalized copy.\n *\n * ### Common use cases\n * - Sanitizing user input before validation or storage.\n * - Cleaning keys, tags, and names from external data sources.\n * - Preparing values for strict equality or hashing.\n *\n * ### Examples\n *\n * @example\n * // Basic trimming\n * strTrim(' Hello '); // => \"Hello\"\n *\n * @example\n * // Removes zero-width characters\n * strTrim('word\\u200B'); // => \"word\"\n *\n * @example\n * // Unicode normalization\n * strTrim('ABC'); // => \"ABC\"\n * strTrim('e\\u0301'); // => \"é\"\n *\n * @example\n * // Non-string inputs\n * strTrim(123); // => \"\"\n * strTrim(null); // => \"\"\n * strTrim(undefined); // => \"\"\n * strTrim({ text: 'hi' }); // => \"\"\n *\n * @see isStr\n * @see String.prototype.normalize\n *\n * @category String\n * @public\n * @since 2.0.0\n */\nexport function strTrim(value: unknown): string {\n\treturn String(isStr(value) ? value.trim().normalize('NFKC').replace(/[\\u200B-\\u200D\\uFEFF]/g, '') : '');\t\n}\n","import { \n\tisStr,\n\tstrTrim,\n\tstrNull, \n} from '../index';\n\n/**\n * Converts `null` or empty (whitespace-only) strings into `undefined`.\n *\n * @summary\n * Normalizes optional values by replacing both `null` and blank strings\n * with `undefined`, while keeping all other values unchanged. \n * This is useful when preparing objects for APIs or serialization,\n * where `undefined` fields are automatically omitted or ignored.\n *\n * @param value - Any value that may be a string, `null`, or another type.\n *\n * @returns\n * - `undefined` if:\n * - The value is `null`, or\n * - The value is a string that becomes empty after trimming (via {@link strTrim}).\n * - Otherwise returns the original value.\n *\n * @remarks\n * ### Processing steps\n * 1. If `value` is `null`, return `undefined`.\n * 2. If `value` is a string:\n * - Trim using {@link strTrim} to remove whitespace and invisible characters.\n * - If trimmed result is empty, return `undefined`.\n * 3. Otherwise, return the original value unchanged.\n *\n * ### Behavior notes\n * - Non-string, non-null values (`0`, `false`, `{}`, `[]`, etc.) are **not modified**.\n * - The function is **non-mutating** — it never changes the original reference.\n * - It complements {@link strNull}, depending on whether your system\n * prefers `undefined` (omit field) or `null` (explicit empty value).\n *\n * ### Comparison with {@link strNull}\n * | Case | `strNull` | `strUndefined` |\n * |------|----------------|----------------------|\n * | `null` | `null` | `undefined` |\n * | `undefined` | `null` | `undefined` |\n * | `''` (empty string) | `null` | `undefined` |\n * | `'text'` | `'text'` | `'text'` |\n * | Non-string (e.g. `0`) | `0` | `0` |\n *\n * ### Use cases\n * - Preparing data before sending to REST or GraphQL APIs \n * (so empty fields are omitted during JSON serialization)\n * - Cleaning form input values before saving or validation\n * - Ensuring `undefined` consistency in optional object properties\n *\n * ### Performance\n * - Time complexity: **O(n)** (depends on string length)\n * - Space complexity: **O(n)** (due to string trimming)\n *\n * ### Examples\n *\n * @example\n * // Empty and whitespace-only strings\n * strUndefined(''); // => undefined\n * strUndefined(' '); // => undefined\n *\n * @example\n * // null is also normalized\n * strUndefined(null); // => undefined\n *\n * @example\n * // Non-empty strings remain unchanged\n * strUndefined('Hello'); // => \"Hello\"\n *\n * @example\n * // Non-string types are preserved\n * strUndefined(0); // => 0\n * strUndefined(false); // => false\n * strUndefined([]); // => []\n * strUndefined({}); // => {}\n *\n * @see isStr\n * @see strTrim\n * @see strNull\n *\n * @category String\n * @public\n * @since 2.0.0\n */\nexport function strUndefined(value: unknown) {\n\treturn ((isStr(value) && strTrim(value) === '') || value === null) ? undefined : value\n}\n","import { \n\tisStr,\n\tstrTrim, \n} from '../index';\n\nexport const strNormalize = (v: unknown) => {\n\tif (!isStr(v)) {\n\t\treturn v;\n\t}\n\tconst t = String(strTrim(v) || '');\n\t\n\treturn t === '' \n\t\t? null \n\t\t: t.toLowerCase();\n};\n","import type { UrlObj } from './types';\n\nexport function urlObj(value: string = ''): UrlObj {\n\treturn {} as UrlObj;\n}\n"]}
|