{"version":3,"file":"drop.cjs","names":["purry","lazyIdentityEvaluator","SKIP_ITEM"],"sources":["../src/drop.ts"],"sourcesContent":["import type { IsInteger, IsNegative, Writable } from \"type-fest\";\nimport type { ClampedIntegerSubtract } from \"./internal/types/ClampedIntegerSubtract\";\nimport type { CoercedArray } from \"./internal/types/CoercedArray\";\nimport type { IterableContainer } from \"./internal/types/IterableContainer\";\nimport type { LazyEvaluator } from \"./internal/types/LazyEvaluator\";\nimport type { PartialArray } from \"./internal/types/PartialArray\";\nimport type { TupleParts } from \"./internal/types/TupleParts\";\nimport { SKIP_ITEM, lazyIdentityEvaluator } from \"./internal/utilityEvaluators\";\nimport { purry } from \"./purry\";\n\ntype Drop<T extends IterableContainer, N extends number> =\n  IsNegative<N> extends true\n    ? // Negative numbers result in nothing being dropped, we return a shallow\n      // clone of the array.\n      Writable<T>\n    : IsInteger<N> extends true\n      ? ClampedIntegerSubtract<\n          N,\n          TupleParts<T>[\"required\"][\"length\"]\n        > extends infer RemainingPrefix extends number\n        ? RemainingPrefix extends 0\n          ? // The drop will occur within the required part of the tuple, we\n            // simply remove those elements from it and reconstruct the rest of\n            // the tuple.\n            [\n              ...DropFixedTuple<TupleParts<T>[\"required\"], N>,\n              ...PartialArray<TupleParts<T>[\"optional\"]>,\n              ...CoercedArray<TupleParts<T>[\"item\"]>,\n              ...TupleParts<T>[\"suffix\"],\n            ]\n          : ClampedIntegerSubtract<\n                RemainingPrefix,\n                TupleParts<T>[\"optional\"][\"length\"]\n              > extends infer RemainingOptional extends number\n            ? RemainingOptional extends 0\n              ? // The drop will occur within the optional part of the tuple, we\n                // completely remove the required part, remove enough elements\n                // from the optional part, and reconstruct the rest of the\n                // tuple.\n                [\n                  ...PartialArray<\n                    DropFixedTuple<TupleParts<T>[\"optional\"], RemainingPrefix>\n                  >,\n                  ...CoercedArray<TupleParts<T>[\"item\"]>,\n                  ...TupleParts<T>[\"suffix\"],\n                ]\n              : // The drop will occur within the rest element or the suffix.\n                  // Because the suffix can contain any number of elements this\n                  // case adds more complexity as we need to consider all\n                  // possible (relevant) lengths. We start by considering the\n                  // case where there are enough elements within the rest\n                  // param; this means we still maintain the rest element as it\n                  // could contain even more elements, and we add the suffix\n                  // untouched.\n                  | [\n                      ...CoercedArray<TupleParts<T>[\"item\"]>,\n                      ...TupleParts<T>[\"suffix\"],\n                    ]\n                  // Additionally, we need to consider the case where the rest\n                  // element has up to the same number of elements as the\n                  // suffix; this will result in removing the rest element\n                  // entirely, and dropping elements from the suffix. We do this\n                  // for all possible values from 0 to N where N is the\n                  // remaining value after we handled the prefix. We can exclude\n                  // the 0 case because it is contained in the previous case.\n                  | Exclude<\n                      DropFixedTuple<\n                        TupleParts<T>[\"suffix\"],\n                        RemainingOptional,\n                        true /* IncludePrefixes */\n                      >,\n                      TupleParts<T>[\"suffix\"]\n                    >\n            : never\n        : never\n      : // We can't compute accurate types for non-integer numbers so we\n        // fallback to the \"legacy\" typing where we convert our output to a\n        // simple array. This is also the case when N is not a literal value\n        // (e.g. it is `number`).\n        // TODO: We can improve this type by returning a union of all possible dropped shapes (e.g. the equivalent of Drop<T, 1> | Drop<T, 2> | Drop<T, 3> | ...).\n        T[number][];\n\ntype DropFixedTuple<\n  T,\n  N,\n  // This flag controls if we want a union of all possible prefixes, or just the\n  // final tuple with all N items dropped.\n  IncludePrefixes = false,\n  Dropped extends unknown[] = [],\n> = Dropped[\"length\"] extends N\n  ? T\n  : T extends readonly [unknown, ...infer Rest]\n    ?\n        | DropFixedTuple<Rest, N, IncludePrefixes, [...Dropped, unknown]>\n        | (true extends IncludePrefixes ? T : never)\n    : [];\n\n/**\n * Removes first `n` elements from the `array`.\n *\n * @param array - The target array.\n * @param n - The number of elements to skip.\n * @signature\n *    drop(array, n)\n * @example\n *    drop([1, 2, 3, 4, 5], 2) // => [3, 4, 5]\n * @dataFirst\n * @lazy\n * @category Array\n */\nexport function drop<T extends IterableContainer, N extends number>(\n  array: T,\n  n: N,\n): Drop<T, N>;\n\n/**\n * Removes first `n` elements from the `array`.\n *\n * @param n - The number of elements to skip.\n * @signature\n *    drop(n)(array)\n * @example\n *    drop(2)([1, 2, 3, 4, 5]) // => [3, 4, 5]\n * @dataLast\n * @lazy\n * @category Array\n */\nexport function drop<N extends number>(\n  n: N,\n): <T extends IterableContainer>(array: T) => Drop<T, N>;\n\nexport function drop(...args: readonly unknown[]): unknown {\n  return purry(dropImplementation, args, lazyImplementation);\n}\n\nconst dropImplementation = <T extends IterableContainer>(\n  array: T,\n  n: number,\n): T[number][] => (n < 0 ? [...array] : array.slice(n));\n\nfunction lazyImplementation<T>(n: number): LazyEvaluator<T> {\n  if (n <= 0) {\n    return lazyIdentityEvaluator;\n  }\n\n  let left = n;\n  return (value) => {\n    if (left > 0) {\n      left -= 1;\n      return SKIP_ITEM;\n    }\n    return { done: false, hasNext: true, next: value };\n  };\n}\n"],"mappings":"gJAmIA,SAAgB,EAAK,GAAG,EAAmC,CACzD,OAAOA,EAAAA,MAAM,EAAoB,EAAM,EAAmB,CAG5D,MAAM,GACJ,EACA,IACiB,EAAI,EAAI,CAAC,GAAG,EAAM,CAAG,EAAM,MAAM,EAAE,CAEtD,SAAS,EAAsB,EAA6B,CAC1D,GAAI,GAAK,EACP,OAAOC,EAAAA,EAGT,IAAI,EAAO,EACX,MAAQ,IACF,EAAO,GACT,IACOC,EAAAA,GAEF,CAAE,KAAM,GAAO,QAAS,GAAM,KAAM,EAAO"}