{"version":3,"file":"index.cjs","names":["isPlainObject","isServer","createMessage","isEqual","isPlainObject","errorMsg","createMessage","isPlainObject","isNonEmptyArray","safeStableStringify","isObjectOrArray","isEmptyArray","isArray","isNaN","isUndefined","safeJsonParse","createMessage"],"sources":["../../src/operations/copyText.ts","../../src/operations/findDuplicates.ts","../../src/operations/omitKeys.ts","../../src/operations/omitKeysDeep.ts"],"sourcesContent":["import { isPlainObject, isServer } from \"@/predicates\";\n\ntype CopyMethod = \"clipboard\" | \"fallback\" | \"manual\";\ntype CopyStatus = \"success\" | \"error\";\n\ntype CopyResult = {\n  /** ---------------------------------------------------------\n   * * ***Final operation status.***\n   * ----------------------------------------------------------\n   *\n   * ---\n   * Usually `\"success\"` when copy succeeds, otherwise `\"error\"`.\n   */\n  status: CopyStatus;\n\n  /** ---------------------------------------------------------\n   * * ***Indicates whether the operation succeeded.***\n   * ----------------------------------------------------------\n   *\n   * Usually `true` on successful copy operations.\n   */\n  success: boolean;\n\n  /** ---------------------------------------------------------\n   * * ***Copy mechanism that was used.***\n   * ----------------------------------------------------------\n   *\n   * - **Possible values:**\n   *     - `\"clipboard\"`.\n   *     - `\"fallback\"`.\n   *     - `\"manual\"`.\n   */\n  method: CopyMethod;\n\n  /**\n   * * ***Optional error object captured during execution.***\n   */\n  error?: unknown;\n\n  /** ---------------------------------------------------------\n   * * ***Optional failure or fallback reason.***\n   * ----------------------------------------------------------\n   *\n   * - **Possible values:**\n   *     - `\"no-browser\"`.\n   *     - `\"no-clipboard\"`.\n   *     - `\"clipboard-error\"`.\n   *     - `\"timeout\"`.\n   *     - `\"fallback-failed\"`.\n   */\n  reason?:\n    | \"no-browser\"\n    | \"no-clipboard\"\n    | \"clipboard-error\"\n    | \"timeout\"\n    | \"fallback-failed\";\n\n  /**\n   * * ***Total number of attempts performed.***\n   */\n  attempts: number;\n\n  /**\n   * * ***Total execution duration in milliseconds.***\n   */\n  duration: number;\n\n  /**\n   * * ***Unix timestamp of execution completion.***\n   */\n  timestamp: number;\n};\n\n/** ----------------------------------------------------------------------\n * * ***Type: `CopyOptions`.***\n * -----------------------------------------------------------------------\n * **Configuration options for the `copyText` utility.**\n *\n * ---\n * - **Behavior:**\n *     - Controls retry attempts and timeout handling.\n *     - Enables optional debug logging.\n *     - All properties are optional.\n */\ntype CopyOptions = {\n  /** -----------------------------------------------------------------------\n   * * ***Enables internal debug logging.***\n   * ------------------------------------------------------------------------\n   *\n   * @default false\n   */\n  debug?: boolean;\n\n  /** -----------------------------------------------------------------------\n   * * ***Number of retry attempts before fallback.***\n   * ------------------------------------------------------------------------\n   *\n   * @default 1\n   */\n  retries?: number;\n\n  /** -----------------------------------------------------------------------\n   * * ***Timeout duration (in milliseconds) for each Clipboard API attempt.***\n   * ------------------------------------------------------------------------\n   *\n   * @default 2000\n   */\n  timeout?: number;\n};\n\n/** ----------------------------------------------------------------------\n * * ***Utility: `copyText`.***\n * -----------------------------------------------------------------------\n * **Copies text to the user's clipboard with robust fallback handling.**\n *\n * ---\n * - **Behavior:**\n *     - Attempts to use the modern\n *       ***`navigator.clipboard.writeText`*** Clipboard API.\n *     - Automatically retries clipboard operations when configured.\n *     - Falls back to legacy\n *       ***`document.execCommand(\"copy\")`***\n *       if the Clipboard API is unavailable or fails.\n *     - As a last resort, programmatically selects the text\n *       to allow manual copying by the user.\n *     - Detects non-browser environments and safely exits\n *       without accessing browser-only APIs.\n *     - Returns detailed operation metadata including method,\n *       duration, attempts, and failure reason.\n *     - Does **not throw** on copy failure;\n *       instead returns a structured\n *       ***{@link CopyResult | `CopyResult`}*** object.\n *\n * ---\n * @param {string} text\n * The text content to copy to the clipboard.\n *\n * @param {CopyOptions} [options={}]\n * Optional configuration object.\n *\n * @param {boolean} [options.debug=false]\n * Enables internal debug logging.\n *\n * @param {number} [options.retries=1]\n * Number of additional retry attempts\n * after the initial Clipboard API attempt.\n *\n * @param {number} [options.timeout=2000]\n * Timeout duration (in milliseconds)\n * for each Clipboard API attempt.\n *\n * ---\n * @returns {Promise<CopyResult>}\n * A promise resolving to a\n * ***{@link CopyResult | `CopyResult`}*** object containing:\n *  - `status` ➔ `\"success\"` or `\"error\"`.\n *  - `success` ➔ Indicates whether the operation succeeded.\n *  - `method` ➔ Copy mechanism used\n *    (`\"clipboard\"`, `\"fallback\"`, or `\"manual\"`).\n *  - `reason` ➔ Optional failure or fallback reason.\n *  - `error` ➔ Optional thrown error object.\n *  - `attempts` ➔ Total number of attempts performed.\n *  - `duration` ➔ Execution duration in milliseconds.\n *  - `timestamp` ➔ Unix timestamp of execution.\n *\n * ---\n * @remarks\n * - The Clipboard API requires a secure context\n *   (`HTTPS` or `localhost`).\n * - Some browsers or mobile environments may restrict\n *   clipboard access without direct user interaction.\n * - Clipboard operations may fail due to browser permission\n *   policies or missing user interaction.\n * - Manual selection mode is only triggered when all\n *   programmatic copy strategies fail.\n * - In server-side environments,\n *   the utility returns `\"no-browser\"`\n *   without attempting DOM access.\n *\n * ---\n * @example\n * ```ts\n * const result = await copyText(\"Hello world\");\n *\n * if (result.success) {\n *   console.log(`Copied using ${result.method}`);\n * } else {\n *   console.error(result.reason);\n * }\n * ```\n *\n * ---\n * @example\n * ```ts\n * await copyText(\"Debug mode\", {\n *   debug: true,\n *   retries: 2\n * });\n * ```\n */\nexport async function copyText(\n  text: string,\n  options?: CopyOptions\n): Promise<CopyResult> {\n  if (!isPlainObject(options)) options = {};\n\n  const now = () =>\n    typeof performance !== \"undefined\" ? performance.now() : Date.now();\n  const start = now();\n  const timestamp = Date.now();\n  const isBrowser = !isServer();\n\n  if (!isBrowser) {\n    return {\n      status: \"error\",\n      success: false,\n      method: \"manual\",\n      reason: \"no-browser\",\n      attempts: 0,\n      duration: now() - start,\n      timestamp\n    };\n  }\n\n  const retries = Math.max(0, options.retries ?? 1);\n  const maxAttempts = retries + 1;\n  const timeout = options.timeout ?? 2000;\n\n  let attempts = 0;\n\n  const log = (...args: unknown[]) => {\n    if (options.debug) console.log(\"[@rzl-zone/utils-js:copyText]: \", ...args);\n  };\n\n  const withTimeout = async <T>(promise: Promise<T>) => {\n    let timer: ReturnType<typeof setTimeout> | undefined;\n\n    try {\n      return await Promise.race([\n        promise,\n        new Promise<never>((_, reject) => {\n          timer = setTimeout(() => reject(new Error(\"timeout\")), timeout);\n        })\n      ]);\n    } finally {\n      clearTimeout(timer);\n    }\n  };\n\n  const hasClipboard =\n    typeof navigator !== \"undefined\" && !!navigator.clipboard;\n\n  // === TRY CLIPBOARD API ===\n  if (hasClipboard) {\n    while (attempts < maxAttempts) {\n      attempts++;\n      try {\n        await withTimeout(navigator.clipboard.writeText(text));\n        log(\"Clipboard success\", { attempts });\n\n        return {\n          status: \"success\",\n          success: true,\n          method: \"clipboard\",\n          attempts,\n          duration: now() - start,\n          timestamp\n        };\n      } catch (error: unknown) {\n        log(\"Clipboard attempt failed\", error);\n\n        if (error instanceof Error && error?.message === \"timeout\") {\n          return {\n            status: \"error\",\n            success: false,\n            method: \"clipboard\",\n            error,\n            reason: \"timeout\",\n            attempts,\n            duration: now() - start,\n            timestamp\n          };\n        }\n      }\n    }\n\n    log(\"Clipboard exhausted ➔ fallback\");\n  } else {\n    log(\"No clipboard API\");\n  }\n\n  // === FALLBACK ===\n  attempts++;\n\n  try {\n    const ok = fallbackCopy(text);\n\n    if (ok) {\n      return {\n        status: \"success\",\n        success: true,\n        method: \"fallback\",\n        reason: hasClipboard ? \"clipboard-error\" : \"no-clipboard\",\n        attempts,\n        duration: now() - start,\n        timestamp\n      };\n    }\n  } catch (error) {\n    log(\"Fallback error\", error);\n  }\n\n  // === LAST RESORT: MANUAL SELECT ===\n  attempts++;\n\n  log(\"Fallback failed ➔ manual select\");\n\n  manualSelect(text);\n\n  return {\n    status: \"error\",\n    success: false,\n    method: \"manual\",\n    reason: \"fallback-failed\",\n    attempts,\n    duration: now() - start,\n    timestamp\n  };\n}\n\n// --- fallback ---\nfunction fallbackCopy(text: string): boolean {\n  const textarea = document.createElement(\"textarea\");\n  textarea.value = text;\n\n  textarea.setAttribute(\"readonly\", \"\");\n\n  textarea.style.position = \"fixed\";\n  textarea.style.top = \"-9999px\";\n  textarea.style.left = \"-9999px\";\n  textarea.style.opacity = \"0\";\n  textarea.style.fontSize = \"16px\";\n\n  document.body.appendChild(textarea);\n  textarea.focus();\n  textarea.select();\n\n  try {\n    return document.execCommand(\"copy\");\n  } finally {\n    textarea.blur();\n\n    setTimeout(() => {\n      textarea.remove();\n    }, 0);\n  }\n}\n\n// --- manual select ---\nfunction manualSelect(text: string) {\n  const textarea = document.createElement(\"textarea\");\n  textarea.value = text;\n\n  textarea.setAttribute(\"readonly\", \"\");\n\n  textarea.style.position = \"fixed\";\n  textarea.style.top = \"-9999px\";\n  textarea.style.left = \"-9999px\";\n  textarea.style.opacity = \"0\";\n  textarea.style.fontSize = \"16px\";\n\n  document.body.appendChild(textarea);\n\n  textarea.focus();\n  textarea.select();\n\n  setTimeout(() => {\n    textarea.blur();\n\n    textarea.remove();\n  }, 3000);\n}\n","import { createMessage } from \"@/_private/logger\";\n\nimport { isEqual } from \"@/predicates/is/isEqual\";\nimport { assertIsArray } from \"@/assertions/objects/assertIsArray\";\n\n/** ----------------------------------------------------------------------\n * * ***Utility: `findDuplicates`.***\n * -----------------------------------------------------------------------\n * **Finds duplicate values in an array by deep equality comparison.**\n *\n * ---\n * - **Behavior:**\n *     - Uses ***`isEqual` utility function*** to compare elements\n *       (handles objects, arrays, dates, NaN, etc.).\n *     - Returns a new array containing only the *first occurrences* of duplicated values.\n *     - Does **not mutate** the original array.\n *     - Throws ***{@link TypeError | `TypeError`}*** if input is not an array.\n *\n * ---\n * @template T Type of elements in the input array.\n *\n * ---\n * @param {T[]} values - The array to check for duplicates.\n *\n * ---\n * @throws **{@link TypeError | `TypeError`}** if the provided `values` argument is not an array.\n *\n * ---\n * @returns {T[]} An array of the duplicate values found in the input,\n *                preserving order of their first duplicate appearance.\n *\n * ---\n * @example\n * findDuplicates([1, 2, 2, 3, 4, 4]);\n * // ➔ [2, 4]\n * findDuplicates([\"apple\", \"banana\", \"apple\", \"orange\"]);\n * // ➔ [\"apple\"]\n * findDuplicates([{ a: 1 }, { a: 1 }, { a: 2 }]);\n * // ➔ [{ a: 1 }]\n * findDuplicates([NaN, NaN, 1]);\n * // ➔ [NaN]\n * findDuplicates([true, false, true]);\n * // ➔ [true]\n * findDuplicates([1, 2, 3]);\n * // ➔ []\n */\nexport const findDuplicates = <T>(values: T[]): T[] => {\n  assertIsArray(values, {\n    message: ({ currentType, validType }) =>\n      createMessage(\n        \"findDuplicates\",\n        `First parameter (\\`values\\`) must be of type \\`${validType}\\` (array literal or instance), but received: \\`${currentType}\\`.`\n      )\n  });\n\n  const duplicates: T[] = [];\n  values.forEach((item, index) => {\n    for (let i = index + 1; i < values.length; i++) {\n      if (isEqual(item, values[i])) {\n        if (!duplicates.some((dup) => isEqual(dup, item))) {\n          duplicates.push(item);\n        }\n        break;\n      }\n    }\n  });\n\n  return duplicates;\n};\n","import { createMessage } from \"@/_private/logger\";\n\nimport { isPlainObject } from \"@/predicates/is/isPlainObject\";\nimport { assertIsArray } from \"@/assertions/objects/assertIsArray\";\n\nimport { findDuplicates } from \"./findDuplicates\";\n\n/** -------------------------------------------------------------------------------\n * * ***Utility: `omitKeys`.***\n * --------------------------------------------------------------------------------\n * **This function creates a shallow copy of the given object omitting the\n *  specified keys.**\n *\n * ---\n * - **Behavior:**\n *     - It will return a new object without mutating the original.\n *     - It also validates that ***`keysToOmit`*** does not contain duplicate keys.\n *\n * ---\n * - **Internally:**\n *     - It uses ***`isEqual`*** to check for duplicates in\n *       the ***`keysToOmit`*** array.\n *\n * ---\n * @template I The type of the input object.\n * @template K The keys to omit from the object.\n *\n * ---\n * @param {I} object - The source object to omit keys from.\n * @param {K[]} keysToOmit - An array of keys to exclude from the returned object.\n *\n * ---\n * @throws **{@link TypeError | `TypeError`}** if `keysToOmit` is not an array.\n * @throws **{@link Error | `Error`}** if duplicate keys are found in `keysToOmit`.\n *\n * ---\n * @returns {Omit<I, K>} A new object without the specified keys.\n *\n * ---\n * @example\n * omitKeys({ a: 1, b: 2, c: 3 }, [\"b\", \"c\"]);\n * // ➔ { a: 1 }\n * omitKeys({ name: \"John\", age: 30 }, [\"age\"]);\n * // ➔ { name: \"John\" }\n * omitKeys({ a: 1, b: 2 }, []);\n * // ➔ { a: 1, b: 2 } (no changes)\n */\nexport const omitKeys = <I extends Record<string, unknown>, K extends keyof I>(\n  object: I,\n  keysToOmit: K[]\n): Omit<I, K> => {\n  if (!isPlainObject(object)) return {} as Omit<I, K>;\n\n  assertIsArray(keysToOmit, {\n    message: ({ currentType, validType }) =>\n      errorMsg(\n        `Second parameter (\\`keysToOmit\\`) must be of type \\`${validType}\\` (array literal or instance), but received: \\`${currentType}\\`.`\n      )\n  });\n\n  // Check for duplicate keys\n  const duplicates = findDuplicates(keysToOmit);\n  if (duplicates.length > 0) {\n    throw new Error(errorMsg(`Duplicate keys detected - \\`${duplicates}\\``));\n  }\n\n  // Remove specified keys\n  return Object.fromEntries(\n    Object.entries(object).filter(([key]) => !keysToOmit.includes(key as K))\n  ) as Omit<I, K>;\n};\n\n/**\n * @internal ***`Not part of the public API.`***\n */\nconst errorMsg = (msg: string) => createMessage(\"omitKeys\", msg);\n","import type { NumberRangeUnion } from \"@rzl-zone/ts-types-plus\";\n\nimport { createMessage } from \"@/_private/logger\";\n\nimport { assertIsArray } from \"@/assertions/objects/assertIsArray\";\n\nimport { safeJsonParse } from \"@/conversions/json/safeJsonParse\";\nimport { safeStableStringify } from \"@/conversions/stringify/safeStableStringify\";\n\nimport { isNaN } from \"@/predicates/is/isNaN\";\nimport { isArray } from \"@/predicates/is/isArray\";\nimport { isUndefined } from \"@/predicates/is/isUndefined\";\nimport { isEmptyArray } from \"@/predicates/is/isEmptyArray\";\nimport { isPlainObject } from \"@/predicates/is/isPlainObject\";\nimport { isNonEmptyArray } from \"@/predicates/is/isNonEmptyArray\";\nimport { isObjectOrArray } from \"@/predicates/is/isObjectOrArray\";\n\nimport { findDuplicates } from \"./findDuplicates\";\n\ntype IndexArray = NumberRangeUnion<0, 30>;\ntype DotPath<T, Prev extends string = \"\"> =\n  T extends Array<infer U>\n    ? DotPath<U, `${Prev}${Prev extends \"\" ? \"\" : \".\"}${IndexArray}`>\n    : T extends object\n      ? {\n          [K in keyof T & string]:\n            | `${Prev}${Prev extends \"\" ? \"\" : \".\"}${K}`\n            | DotPath<T[K], `${Prev}${Prev extends \"\" ? \"\" : \".\"}${K}`>;\n        }[keyof T & string]\n      : never;\n\n/** ------------------------------------------------------\n * * ***Utility: `omitKeysDeep`.***\n * -------------------------------------------------------\n * **Recursively omits properties from an object using dot notation paths.**\n *\n * ---\n * - **Behavior:**\n *     - Removes resulting empty objects (`{}`) and arrays (`[]`), cascading upwards\n *       to remove empty parents until root if needed.\n * ---\n * - **Be careful:**\n *     - If after omission an object or array becomes empty, it will be removed entirely\n *       including all the way up to the root if necessary, resulting in `{}`.\n * ---\n * - **Note:**\n *     - For array indices, TypeScript autocomplete only suggests `0`–`30`\n *       (to prevent editor lag on large unions).\n *       However, higher indices are still fully supported at runtime — you can\n *       manually type `\"arr.99.key\"` and it will work the same.\n *\n * ---\n * @template I - Type of the input object.\n *\n * ---\n * @param {I} object\n *  The object to process, should be a plain nested object or array structure.\n * @param {DotPath<I>[]} keysToOmit\n *  An array of string paths in dot notation indicating the properties to remove, paths\n *  can include numeric indices to target array elements, e.g. `\"arr.0.x\"` to\n *  remove `x` from the first object inside the `arr` array.\n *\n * ---\n * @throws **{@link TypeError | `TypeError`}** if `keysToOmit` is not an array.\n * @throws **{@link Error | `Error`}** if `keysToOmit` contains duplicate paths.\n *\n * ---\n * @returns {Partial<I>}\n *  A new deeply cloned object with the specified keys omitted, with resulting\n *  empty objects or arrays fully removed (even if it collapses to `{}`).\n *\n * ---\n * @example\n * omitKeysDeep({ arr: [{ a: 1 }] }, [\"arr.0.a\"]);\n * // ➔ {} (array becomes empty and removed)\n * omitKeysDeep({ a: { b: { c: 1 }, d: 2 }, e: 3 }, [\"a.b.c\"]);\n * // ➔ { a: { d: 2 }, e: 3 }\n * omitKeysDeep({ a: [{ b: 1 }, { c: 2 }] }, [\"a.0.b\"]);\n * // ➔ { a: [{ c: 2 }] }\n * omitKeysDeep({ a: [{ b: 1 }] }, [\"a.0.b\"]);\n * // ➔ {} (array becomes empty and removed)\n * omitKeysDeep({ complex: [{ deep: [{ x: 1, y: 2 }] }] }, [\"complex.0.deep.0.x\"]);\n * // ➔ { complex: [{ deep: [{ y: 2 }] }] }\n * omitKeysDeep({ complex: [{ deep: [{ x: 1 }] }] }, [\"complex.0.deep.0.x\"]);\n * // ➔ {} (deep chain emptied and collapsed)\n * omitKeysDeep({ data: [[{ foo: 1, bar: 2 }]] }, [\"data.0.0.foo\"]);\n * // ➔ { data: [[{ bar: 2 }]] }\n * omitKeysDeep({ data: [[{ foo: 1 }]] }, [\"data.0.0.foo\"]);\n * // ➔ {} (nested arrays emptied completely)\n * omitKeysDeep({ x: [{ y: [{ z: 1 }, { w: 2 }] }] }, [\"x.0.y.0.z\"]);\n * // ➔ { x: [{ y: [{ w: 2 }] }] }\n * omitKeysDeep({ x: [{ y: [{ z: 1 }] }] }, [\"x.0.y.0.z\"]);\n * // ➔ {} (entire nested arrays removed)\n * omitKeysDeep({ p: { q: { r: 5 } }, s: 6 }, [\"p.q.r\"]);\n * // ➔ { s: 6 } (`p` removed because it becomes empty)\n * omitKeysDeep({ arr: [{ a: 1, b: 2 }, { c: 3 }] }, [\"arr.0.a\"]);\n * // ➔ { arr: [{ b: 2 }, { c: 3 }] }\n * omitKeysDeep({ root: [{ sub: [{ leaf: 10 }] }] }, [\"root.0.sub.0.leaf\"]);\n * // ➔ {} (deep nested arrays emptied to root)\n * omitKeysDeep({ meta: { tags: [\"x\", \"y\"], count: 2 } }, [\"meta.count\"]);\n * // ➔ { meta: { tags: [\"x\", \"y\"] } }\n * omitKeysDeep({ arr: [[{ a: 1 }, { b: 2 }]] }, [\"arr.0.0.a\"]);\n * // ➔ { arr: [[{ b: 2 }]] }\n * omitKeysDeep({ arr: [[{ a: 1 }]] }, [\"arr.0.0.a\"]);\n * // ➔ {} (double nested emptied)\n * omitKeysDeep({ nested: [{ list: [{ id: 1, val: 2 }] }] }, [\"nested.0.list.0.val\"]);\n * // ➔ { nested: [{ list: [{ id: 1 }] }] }\n * omitKeysDeep({ nested: [{ list: [{ id: 1 }] }] }, [\"nested.0.list.0.id\"]);\n * // ➔ {} (full collapse to empty)\n * omitKeysDeep({ mixed: { a: [1, 2, 3], b: { c: 4 } } }, [\"mixed.b.c\"]);\n * // ➔ { mixed: { a: [1, 2, 3] } }\n */\nexport const omitKeysDeep = <I extends Record<string, unknown>>(\n  object: I,\n  keysToOmit: DotPath<I>[]\n): Partial<I> => {\n  if (!isPlainObject(object)) return {} as Partial<I>;\n\n  assertIsArray(keysToOmit, {\n    message: ({ currentType, validType }) =>\n      errorMsg(\n        `Second parameter (\\`keysToOmit\\`) must be of type \\`${validType}\\` (array literal or instance), but received: \\`${currentType}\\`.`\n      )\n  });\n\n  const duplicates = findDuplicates(keysToOmit);\n  if (isNonEmptyArray(duplicates)) {\n    throw new Error(\n      errorMsg(\n        `Duplicate keys detected - \\`${safeStableStringify(duplicates, {\n          keepUndefined: true\n        })}\\`.`\n      )\n    );\n  }\n\n  const omitAtPath = (obj: unknown, pathParts: string[]) => {\n    if (!isObjectOrArray(obj)) return obj;\n\n    const [current, ...rest] = pathParts;\n\n    if (isEmptyArray(rest) && current) {\n      if (isArray(obj)) {\n        // Support numeric index\n        const index = parseInt(current);\n        if (!isNaN(index) && index in obj) {\n          obj.splice(index, 1);\n        }\n      } else {\n        delete obj[current];\n      }\n    } else {\n      const next = current ? obj[current] : undefined;\n      if (isObjectOrArray(next) && current) {\n        obj[current] = omitAtPath(next, rest);\n      }\n    }\n    return obj;\n  };\n\n  const deepRemoveEmptyObjects = (obj: unknown): unknown => {\n    if (isArray(obj)) {\n      return obj\n        .map(deepRemoveEmptyObjects)\n        .filter(\n          (item) => !(isObjectOrArray(item) && Object.keys(item).length === 0)\n        );\n    }\n    if (isObjectOrArray(obj)) {\n      const cleaned = Object.fromEntries(\n        Object.entries(obj)\n          .map(([k, v]) => [k, deepRemoveEmptyObjects(v)])\n          .filter(\n            ([, v]) =>\n              !isUndefined(v) &&\n              !(isObjectOrArray(v) && Object.keys(v).length === 0)\n          )\n      );\n      return cleaned;\n    }\n    return obj;\n  };\n\n  const result = safeJsonParse(safeStableStringify(object)); // clone deep to avoid mutating original\n  for (const key of keysToOmit) {\n    const parts = key.split(\".\");\n    omitAtPath(result, parts);\n  }\n\n  return deepRemoveEmptyObjects(result) as Partial<I>;\n};\n\n/**\n * @internal ***`Not part of the public API.`***\n */\nconst errorMsg = (msg: string) => createMessage(\"omitKeysDeep\", msg);\n"],"mappings":"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"}
