{"version":3,"sources":["../src/layout.ts","../src/utils.ts","../src/size.ts","../src/serialize.ts","../src/deserialize.ts","../src/fixedDynamic.ts","../src/discriminate.ts","../src/items.ts"],"sourcesContent":["export type NumType = number | bigint;\nexport type BytesType = Uint8Array;\nexport type PrimitiveType = NumType | BytesType;\n\n//used wherever an object is expected that sprung from the DeriveType type defined below\nexport type LayoutObject = { readonly [key: string]: any };\n\nexport const binaryLiterals = [\"int\", \"uint\", \"bytes\", \"array\", \"switch\"] as const;\nexport type BinaryLiterals = typeof binaryLiterals[number];\nexport type Endianness = \"little\" | \"big\";\nexport const defaultEndianness = \"big\";\n\nexport const numberMaxSize = 6; //Math.log2(Number.MAX_SAFE_INTEGER) / 8 = 6.625;\nexport type NumberSize = 1 | 2 | 3 | 4 | 5 | 6;\n\nexport type NumSizeToPrimitive<Size extends number> =\n  Size extends NumberSize\n  ? number\n  : Size & NumberSize extends never\n  ? bigint\n  : number | bigint;\n\nexport type FixedConversion<FromType extends PrimitiveType | LayoutObject, ToType> = {\n  readonly to: ToType,\n  readonly from: FromType,\n};\n\nexport type CustomConversion<FromType extends PrimitiveType | LayoutObject, ToType> = {\n  readonly to: (val: FromType) => ToType,\n  readonly from: (val: ToType) => FromType,\n};\n\nexport interface ItemBase<BL extends BinaryLiterals> {\n  readonly binary: BL,\n};\n\ninterface FixedOmittableCustom<T extends PrimitiveType> {\n  custom: T,\n  omit?: boolean\n};\n\n//length size: number of bytes used to encode the preceeding length field which in turn\n//  holds either the number of bytes (for bytes) or elements (for array)\nexport interface LengthPrefixed {\n  readonly lengthSize: NumberSize,\n  readonly lengthEndianness?: Endianness, //see defaultEndianness\n  // //restricts the datarange of lengthSize to a maximum value to prevent out of memory\n  // //  attacks/issues\n  // readonly maxLength?: number,\n}\n\n//size: number of bytes used to encode the item\ninterface NumItemBase<T extends NumType, Signed extends Boolean>\n    extends ItemBase<Signed extends true ? \"int\" : \"uint\"> {\n  size: T extends bigint ? number : NumberSize,\n  endianness?: Endianness, //see defaultEndianness\n};\n\nexport interface FixedPrimitiveNum<\n  T extends NumType,\n  Signed extends Boolean\n> extends NumItemBase<T, Signed>, FixedOmittableCustom<T> {};\n\nexport interface OptionalToFromNum<\n  T extends NumType,\n  Signed extends Boolean\n> extends NumItemBase<T, Signed> {\n  custom?: FixedConversion<T, any> | CustomConversion<T, any>\n};\n\nexport interface FixedPrimitiveBytes\n  extends ItemBase<\"bytes\">, FixedOmittableCustom<BytesType> {};\nexport interface FlexPureBytes extends ItemBase<\"bytes\"> {\n  readonly custom?: BytesType | FixedConversion<BytesType, any> | CustomConversion<BytesType, any>,\n};\n\nexport interface FlexLayoutBytes extends ItemBase<\"bytes\"> {\n  readonly custom?: FixedConversion<LayoutObject, any> | CustomConversion<LayoutObject, any>,\n  readonly layout: Layout,\n}\n\nexport interface ManualSizePureBytes extends FlexPureBytes {\n  readonly size: number,\n};\n\nexport interface LengthPrefixedPureBytes extends FlexPureBytes, LengthPrefixed {};\n\nexport interface ManualSizeLayoutBytes extends FlexLayoutBytes {\n  readonly size: number,\n};\n\nexport interface LengthPrefixedLayoutBytes extends FlexLayoutBytes, LengthPrefixed {};\n\ninterface ArrayItemBase extends ItemBase<\"array\"> {\n  readonly layout: Layout,\n};\n\nexport interface FixedLengthArray extends ArrayItemBase {\n  readonly length: number,\n};\n\nexport interface LengthPrefixedArray extends ArrayItemBase, LengthPrefixed {};\n\n//consumes the rest of the data on deserialization\nexport interface RemainderArray extends ArrayItemBase {};\n\ntype PlainId = number;\ntype ConversionId = readonly [number, unknown];\ntype IdProperLayoutPair<\n  Id extends PlainId | ConversionId,\n  P extends ProperLayout = ProperLayout\n> = readonly [Id, P];\ntype IdProperLayoutPairs =\n  readonly IdProperLayoutPair<PlainId>[] |\n  readonly IdProperLayoutPair<ConversionId>[];\ntype DistributiveAtLeast1<T> = T extends any ? readonly [T, ...T[]] : never;\nexport interface SwitchItem extends ItemBase<\"switch\"> {\n  readonly idSize: NumberSize,\n  readonly idEndianness?: Endianness, //see defaultEndianness\n  readonly idTag?: string,\n  readonly layouts:\n    DistributiveAtLeast1<IdProperLayoutPair<PlainId> | IdProperLayoutPair<ConversionId>>,\n}\n\nexport type NumItem<Signed extends boolean = boolean> =\n  //force distribution over union\n  Signed extends infer S extends boolean\n  ? FixedPrimitiveNum<number, S> |\n    OptionalToFromNum<number, S> |\n    FixedPrimitiveNum<bigint, S> |\n    OptionalToFromNum<bigint, S>\n  : never;\n\nexport type UintItem = NumItem<false>;\nexport type IntItem = NumItem<true>;\nexport type BytesItem =\n  FixedPrimitiveBytes |\n  FlexPureBytes |\n  ManualSizePureBytes |\n  LengthPrefixedPureBytes |\n  FlexLayoutBytes |\n  ManualSizeLayoutBytes |\n  LengthPrefixedLayoutBytes;\nexport type ArrayItem = FixedLengthArray | LengthPrefixedArray | RemainderArray;\nexport type Item = NumItem | BytesItem | ArrayItem | SwitchItem;\nexport type NamedItem = Item & { readonly name: string };\nexport type ProperLayout = readonly NamedItem[];\nexport type Layout = Item | ProperLayout;\n\ntype NameOrOmitted<T extends { name: string }> = T extends {omit: true} ? never : T[\"name\"];\n\nexport type DeriveType<L extends Layout> =\n  Layout extends L\n  ? unknown\n  : L extends infer LI extends Item\n  ? ItemToType<LI>\n  : L extends infer P extends ProperLayout\n  ? { readonly [I in P[number] as NameOrOmitted<I>]: ItemToType<I> }\n  : never;\n\ntype ItemToType<II extends Item> =\n  II extends infer I extends Item\n  ? I extends NumItem\n    ? NumItemToType<I>\n    : I extends BytesItem\n    ? BytesItemToType<I>\n    : I extends ArrayItem\n    ? ArrayItemToType<I>\n    : I extends SwitchItem\n    ? SwitchItemToType<I>\n    : never\n  : never;\n\n//---NumItem---\ntype NumItemToType<I extends NumItem> =\n  //we must infer FromType here to make sure we \"hit\" the correct type of the conversion\n  I[\"custom\"] extends CustomConversion<infer From extends NumType, infer To>\n  ? To\n  : I[\"custom\"] extends FixedConversion<infer From extends NumType, infer To>\n  ? To\n  : I[\"custom\"] extends undefined\n  ? NumSizeToPrimitive<I[\"size\"]>\n  : I[\"custom\"] extends NumType\n  ? I[\"custom\"]\n  : NumSizeToPrimitive<I[\"size\"]>;\n\n//---BytesItem---\ntype BytesItemToType<I extends BytesItem> =\n  I extends { layout: Layout }\n  ? I[\"custom\"] extends CustomConversion<infer From extends LayoutObject, infer To>\n    ? To\n    : I[\"custom\"] extends FixedConversion<infer From extends LayoutObject, infer To>\n    ? To\n    : DeriveType<I[\"layout\"]>\n  : I[\"custom\"] extends CustomConversion<BytesType, infer To>\n  ? To\n  : I[\"custom\"] extends FixedConversion<BytesType, infer To>\n  ? To\n  : BytesType;\n\n//---ArrayItem---\ntype TupleWithLength<T, L extends number, A extends T[] = []> =\n  A[\"length\"] extends L\n  ? A\n  : TupleWithLength<T, L, [...A, T]>;\n\ntype ArrayItemToType<I extends ArrayItem> =\n  DeriveType<I[\"layout\"]> extends infer DT\n  ? I extends { length: infer AL extends number }\n    ? number extends AL\n      ? readonly DT[]\n      : Readonly<TupleWithLength<DT, AL>>\n    : readonly DT[]\n  : never;\n\n//---SwitchItem---\ntype MaybeConvert<Id extends PlainId | ConversionId> =\n  Id extends readonly [number, infer Converted] ? Converted : Id;\n\ntype IdLayoutPairsToTypeUnion<A extends IdProperLayoutPairs, IdTag extends string> =\n  A extends infer V extends IdProperLayoutPairs\n  ? V extends readonly [infer Head,...infer Tail extends IdProperLayoutPairs]\n    ? Head extends IdProperLayoutPair<infer MaybeConversionId, infer P extends ProperLayout>\n      ? MaybeConvert<MaybeConversionId> extends infer Id\n        ? DeriveType<P> extends infer DT extends LayoutObject\n          ? { readonly [K in IdTag | keyof DT]: K extends keyof DT ? DT[K] : Id }\n            | IdLayoutPairsToTypeUnion<Tail, IdTag>\n          : never\n        : never\n      : never\n    : never\n  : never;\n\ntype SwitchItemToType<I extends SwitchItem> =\n  IdLayoutPairsToTypeUnion<\n    I[\"layouts\"],\n    I[\"idTag\"] extends infer ID extends string\n    ? ID extends undefined\n      ? \"id\"\n      : ID\n    : never\n  >;\n","import type {\n  Layout,\n  Item,\n  SwitchItem,\n  FixedConversion,\n  NumType,\n  BytesType,\n  PrimitiveType,\n  FlexLayoutBytes,\n  LengthPrefixedLayoutBytes,\n  ManualSizeLayoutBytes,\n} from \"./layout\";\nimport { binaryLiterals } from \"./layout\";\n\nexport const isNumType = (x: any): x is NumType =>\n  typeof x === \"number\" || typeof x === \"bigint\";\n\nexport const isBytesType = (x: any): x is BytesType => x instanceof Uint8Array;\n\nexport const isPrimitiveType = (x: any): x is PrimitiveType =>\n  isNumType(x) || isBytesType(x);\n\nexport const isItem = (x: any): x is Item => binaryLiterals.includes(x?.binary);\n\nexport const isLayout = (x: any): x is Layout =>\n  isItem(x) || Array.isArray(x) && x.every(isItem);\n\nconst isFixedNumberConversion = (custom: any): custom is FixedConversion<number, any> =>\n  typeof custom?.from === \"number\";\n\nconst isFixedBigintConversion = (custom: any): custom is FixedConversion<bigint, any> =>\n  typeof custom?.from === \"bigint\";\n\nexport const isFixedUintConversion = (custom: any): custom is\n    FixedConversion<number, any> | FixedConversion<bigint, any> =>\n  isFixedNumberConversion(custom) || isFixedBigintConversion(custom);\n\nexport const isFixedBytesConversion = (custom: any): custom is FixedConversion<BytesType, any> =>\n  isBytesType(custom?.from);\n\nexport const isFixedPrimitiveConversion = (custom: any): custom is\n    FixedConversion<number, any> | FixedConversion<bigint, any> | FixedConversion<BytesType, any> =>\n  isFixedUintConversion(custom) || isFixedBytesConversion(custom);\n\nexport const checkSize = (layoutSize: number, dataSize: number): number => {\n  if (layoutSize !== dataSize)\n    throw new Error(`size mismatch: layout size: ${layoutSize}, data size: ${dataSize}`);\n\n  return dataSize;\n}\n\n//In a better world, we wouldn't need this type guard and could just check for \"layout\" in bytesItem\n//  directly because no layout item actually allows for its layout property (if it has one) to be\n//  `undefined`.\n//\n//The problem arises in how TypeScript checks `satisfies` constraints that involve unions:\n//Consider:\n//```\n//const shouldBeIllegal = {\n//  binary: \"bytes\", layout: undefined,\n//} as const satisfies FlexPureBytes | FlexLayoutBytes;\n//```\n//\n//This should be illegal because `FlexPureBytes` does not specify a layout property, so its\n//  specification would be excessive and `FlexLayoutBytes` does not allow for its `layout` property\n//  to be `undefined`.\n//But when checking a `satisfies` constraint of unions of interfaces, excessive properties are\n//  actually ignored and so the `satisfies` constraint will be considered fulfilled, even though it\n//  neither member of the union by itself satisfies it - how utterly counterintuitive.\n//\n//Given that it is fairly natural - though strictly speaking incorrect - to write the following:\n//```\n//const someBytesTemplate = <const L extends Layout | undefined = undefined>(layout?: L) => ({\n//  binary: \"bytes\", layout: layout as L,\n//} as const satisfies Item);\n//```\n//and because TypeScript fails to alert us that it does in fact not satisfy any bytes item at all,\n//  we instead introduce an additional check in our implementation that not only is a layout\n//  property present but that it is also not `undefined`.\nexport const bytesItemHasLayout = (bytesItem: { readonly binary: \"bytes\" }):\n  bytesItem is FlexLayoutBytes | ManualSizeLayoutBytes | LengthPrefixedLayoutBytes =>\n    \"layout\" in bytesItem && bytesItem.layout !== undefined;\n\nexport const checkItemSize = (item: any, dataSize: number): number =>\n  (\"size\" in item && item.size !== undefined) ? checkSize(item.size, dataSize) : dataSize;\n\nexport const checkNumEquals = (custom: number | bigint, data: number | bigint): void => {\n  if (custom != data)\n    throw new Error(`value mismatch: (constant) layout value: ${custom}, data value: ${data}`);\n}\n\nexport const checkBytesTypeEqual = (\n  custom: BytesType,\n  data: BytesType,\n  opts?: {\n    customSlice?: number | readonly [number, number];\n    dataSlice?: number | readonly [number, number];\n  }): void => {\n  const toSlice = (bytes: BytesType, slice?: number | readonly [number, number]) =>\n    slice === undefined\n      ? [0, bytes.length] as const\n      : Array.isArray(slice)\n      ? slice\n      : [slice, bytes.length] as const;\n\n  const [customStart, customEnd] = toSlice(custom, opts?.customSlice);\n  const [dataStart, dataEnd] = toSlice(data, opts?.dataSlice);\n  const length = customEnd - customStart;\n  checkSize(length, dataEnd - dataStart);\n\n  for (let i = 0; i < custom.length; ++i)\n    if (custom[i + customStart] !== data[i + dataStart])\n      throw new Error(`binary data mismatch: ` +\n        `layout value: ${custom}, offset: ${customStart}, data value: ${data}, offset: ${dataStart}`\n      );\n}\n\nexport function findIdLayoutPair(item: SwitchItem, data: any) {\n  const id = data[item.idTag ?? \"id\"];\n  return (item.layouts as readonly any[]).find(([idOrConversionId]) =>\n    (Array.isArray(idOrConversionId) ? idOrConversionId[1] : idOrConversionId) == id\n  )!;\n}\n","import type {\n  Layout,\n  Item,\n  DeriveType,\n} from \"./layout\";\nimport {\n  findIdLayoutPair,\n  isBytesType,\n  isItem,\n  isFixedBytesConversion,\n  checkItemSize,\n  bytesItemHasLayout,\n} from \"./utils\";\n\nexport function calcSize<const L extends Layout>(layout: L, data: DeriveType<L>): number {\n  const size = internalCalcSize(layout, data);\n  if (size === null)\n    throw new Error(\n      `coding error: couldn't calculate layout size for layout ${layout} with data ${data}`\n    );\n\n  return size;\n}\n\n//no way to use overloading here:\n// export function calcSize<const L extends Layout>(layout: L): number | null;\n// export function calcSize<const L extends Layout>(layout: L, data: DeriveType<L>): number;\n// export function calcSize<const L extends Layout>(\n//   layout: L,\n//   data?: DeriveType<L>\n// ): number | null; //impl\n//results in \"instantiation too deep\" error.\n//\n//Trying to pack everything into a single function definition means we either can't narrow the\n//  return type correctly:\n// export function calcSize<const L extends Layout>(\n//   layout: L,\n//   data: DeriveType<L>,\n// ): number | null;\n//or we have to make data overly permissive via:\n// export function calcSize<\n//   L extends Layout,\n//   const D extends DeriveType<L> | undefined,\n//  >(\n//   layout: L,\n//   data?: D, //data can now contain additional properties\n// ): undefined extends D ? number | null : number;\n//so we're stuck with having to use to separate names\nexport function calcStaticSize(layout: Layout): number | null {\n  return internalCalcSize(layout, staticCalc);\n}\n\n// --- implementation ---\n\n//The implementation here shares code for calcSize and calcStaticSize. It's slightly less efficient\n//  from a runtime PoV but it avoids what would effectively be code duplication.\n//Since `undefined` is a valid \"to\" type for custom conversions, it can be a valid value for data.\n//  Therefore, we can't use it to differentiate between calcSize and calcStaticSize, where in the\n//  former we know that data will adhere to the layout, while in the latter data will not exist.\n//So, to mark data as \"does not exist\", i.e. we are in the static calc version, we use a\n//  local (and hence unique) symbol instead.\nconst staticCalc = Symbol(\"staticCalc\");\n\n//stores the results of custom.from calls for bytes items to avoid duplicated effort upon\n//  subsequent serialization\nexport function calcSizeForSerialization<const L extends Layout>(\n  layout: L,\n  data: DeriveType<L>\n): [number, any[]] {\n  const bytesConversions: any[] = [];\n  const size = internalCalcSize(layout, data, bytesConversions);\n  if (size === null)\n    throw new Error(\n      `coding error: couldn't calculate layout size for layout ${layout} with data ${data}`\n    );\n\n  return [size, bytesConversions];\n}\n\nfunction calcItemSize(item: Item, data: any, bytesConversions?: any[]): number | null {\n  const storeInCache = (cachedFrom: any) => {\n    if (bytesConversions !== undefined)\n      bytesConversions.push(cachedFrom);\n\n    return cachedFrom;\n  };\n\n  switch (item.binary) {\n    case \"int\":\n    case \"uint\":\n      return item.size;\n    case \"bytes\": {\n      if (\"size\" in item && data === staticCalc)\n        return item.size;\n\n      //items only have a size or a lengthSize, never both\n      const lengthSize = (\"lengthSize\" in item) ? item.lengthSize | 0 : 0;\n\n      if (bytesItemHasLayout(item)) {\n        const { custom } = item;\n        const layoutSize = internalCalcSize(\n          item.layout,\n          custom === undefined\n          ? data\n          : typeof custom.from === \"function\"\n          ? (data !== staticCalc ? storeInCache(custom.from(data)) : staticCalc)\n          : custom.from, //flex layout bytes only allows conversions, not fixed values\n          bytesConversions\n        );\n        if (layoutSize === null)\n          return (\"size\" in item ) ? item.size ?? null : null;\n\n        return lengthSize + checkItemSize(item, layoutSize);\n      }\n\n      const { custom } = item;\n      if (isBytesType(custom))\n        return lengthSize + custom.length; //assumed to equal item.size if it exists\n\n      if (isFixedBytesConversion(custom))\n        return lengthSize + custom.from.length; //assumed to equal item.size if it exists\n\n      if (data === staticCalc)\n        return null;\n\n      return lengthSize + checkItemSize(\n        item,\n        custom !== undefined\n        ? storeInCache(custom.from(data)).length\n        : data.length\n      );\n    }\n    case \"array\": {\n      const length = \"length\" in item ? item.length : undefined;\n      if (data === staticCalc) {\n        if (length !== undefined) {\n          const layoutSize = internalCalcSize(item.layout, staticCalc, bytesConversions);\n          return layoutSize !== null ? length * layoutSize: null;\n        }\n        return null;\n      }\n\n      let size = 0;\n      if (length !== undefined && length !== data.length)\n        throw new Error(\n          `array length mismatch: layout length: ${length}, data length: ${data.length}`\n        );\n      else if (\"lengthSize\" in item && item.lengthSize !== undefined)\n        size += item.lengthSize;\n\n      for (let i = 0; i < data.length; ++i) {\n        const entrySize = internalCalcSize(item.layout, data[i], bytesConversions);\n        if (entrySize === null)\n          return null;\n\n        size += entrySize;\n      }\n\n      return size;\n    }\n    case \"switch\": {\n      if (data !== staticCalc) {\n        const [_, layout] = findIdLayoutPair(item, data);\n        const layoutSize = internalCalcSize(layout, data, bytesConversions);\n        return layoutSize !== null ? item.idSize + layoutSize : null;\n      }\n\n      let size: number | null = null;\n      for (const [_, layout] of item.layouts) {\n        const layoutSize = internalCalcSize(layout, staticCalc, bytesConversions);\n        if (size === null)\n          size = layoutSize;\n        else if (layoutSize !== size)\n          return null;\n      }\n      return item.idSize + size!;\n    }\n  }\n}\n\nfunction internalCalcSize(layout: Layout, data: any, bytesConversions?: any[]): number | null {\n  if (isItem(layout))\n    return calcItemSize(layout as Item, data, bytesConversions);\n\n  let size = 0;\n  for (const item of layout) {\n    let itemData;\n    if (data === staticCalc)\n      itemData = staticCalc;\n    else if (!(\"omit\" in item) || !item.omit) {\n      if (!(item.name in data))\n        throw new Error(`missing data for layout item: ${item.name}`);\n\n      itemData = data[item.name];\n    }\n\n    const itemSize = calcItemSize(item, itemData, bytesConversions);\n    if (itemSize === null) {\n      if (data !== staticCalc)\n        throw new Error(`coding error: couldn't calculate size for layout item: ${item.name}`);\n\n      return null;\n    }\n    size += itemSize;\n  }\n  return size;\n}\n","import type {\n  Endianness,\n  Layout,\n  Item,\n  DeriveType,\n  CustomConversion,\n  NumType,\n  BytesType,\n  FixedConversion,\n  LayoutObject,\n  ItemBase\n} from \"./layout\";\nimport {\n  defaultEndianness,\n  numberMaxSize,\n} from \"./layout\";\nimport { calcSizeForSerialization } from \"./size\";\nimport {\n  checkItemSize,\n  checkBytesTypeEqual,\n  checkNumEquals,\n  findIdLayoutPair,\n  isFixedBytesConversion,\n  isItem,\n  isNumType,\n  isBytesType,\n  bytesItemHasLayout,\n} from \"./utils\";\n\ntype Cursor = {\n  bytes: BytesType;\n  offset: number;\n};\n\nconst cursorWrite = (cursor: Cursor, bytes: BytesType) => {\n  cursor.bytes.set(bytes, cursor.offset);\n  cursor.offset += bytes.length;\n}\n\ntype BytesConversionQueue = {\n  bytesConversions: any[],\n  position: number,\n}\n\nconst bcqGetNext = (bcq: BytesConversionQueue) => bcq.bytesConversions[bcq.position++];\n\n//returns a BytesType if no encoded data is provided, otherwise returns the number of bytes written\n//  to the provided Uint8Array. Callers should use Uint8Array.subarray if they want to serialize\n//  in place of a larger, pre-allocated Uint8Array.\nexport function serialize<\n  const L extends Layout,\n  E extends BytesType | undefined = undefined\n>(layout: L, data: DeriveType<L>, encoded?: E) {\n  const [size, bytesConversions] = calcSizeForSerialization(layout, data);\n  const cursor = { bytes: encoded ?? new Uint8Array(size), offset: 0 };\n  internalSerialize(layout, data, cursor, {bytesConversions, position: 0});\n  if (!encoded && cursor.offset !== cursor.bytes.length)\n    throw new Error(\n      `encoded data is shorter than expected: ${cursor.bytes.length} > ${cursor.offset}`\n    );\n\n  return (encoded ? cursor.offset : cursor.bytes) as E extends undefined ? BytesType : number;\n}\n\n//see numberMaxSize comment in layout.ts\nconst maxAllowedNumberVal = 2 ** (numberMaxSize * 8);\n\nexport function serializeNum(\n  val: NumType,\n  size: number,\n  cursor: Cursor,\n  endianness: Endianness = defaultEndianness,\n  signed: boolean = false,\n) {\n  if (!signed && val < 0)\n    throw new Error(`Value ${val} is negative but unsigned`);\n\n  if (typeof val === \"number\") {\n    if (!Number.isInteger(val))\n      throw new Error(`Value ${val} is not an integer`);\n\n    if (size > numberMaxSize) {\n      if (val >= maxAllowedNumberVal)\n        throw new Error(`Value ${val} is too large to be safely converted into an integer`);\n\n      if (signed && val < -maxAllowedNumberVal)\n        throw new Error(`Value ${val} is too small to be safely converted into an integer`);\n    }\n  }\n\n  const bound = 2n ** BigInt(size * 8 - (signed ? 1 : 0));\n  if (val >= bound)\n    throw new Error(`Value ${val} is too large for ${size} bytes`);\n\n  if (signed && val < -bound)\n    throw new Error(`Value ${val} is too small for ${size} bytes`);\n\n  //correctly handles both signed and unsigned values\n  for (let i = 0; i < size; ++i)\n    cursor.bytes[cursor.offset + i] =\n      Number((BigInt(val) >> BigInt(8 * (endianness === \"big\" ? size - i - 1 : i)) & 0xffn));\n\n  cursor.offset += size;\n}\n\nfunction internalSerialize(layout: Layout, data: any, cursor: Cursor, bcq: BytesConversionQueue) {\n  if (isItem(layout))\n    serializeItem(layout as Item, data, cursor, bcq);\n  else\n    for (const item of layout)\n      try {\n        serializeItem(item, data[item.name], cursor, bcq);\n      }\n      catch (e: any) {\n        e.message = `when serializing item '${item.name}': ${e.message}`;\n        throw e;\n      }\n}\n\nfunction serializeItem(item: Item, data: any, cursor: Cursor, bcq: BytesConversionQueue) {\n  switch (item.binary) {\n    case \"int\":\n    case \"uint\": {\n      const value = (() => {\n        if (isNumType(item.custom)) {\n          if (!(\"omit\" in item && item.omit))\n            checkNumEquals(item.custom, data);\n          return item.custom;\n        }\n\n        if (isNumType(item?.custom?.from))\n          //no proper way to deeply check equality of item.custom.to and data in JS\n          return item!.custom!.from;\n\n        type narrowedCustom = CustomConversion<number, any> | CustomConversion<bigint, any>;\n        return item.custom !== undefined ? (item.custom as narrowedCustom).from(data) : data;\n      })();\n\n      serializeNum(value, item.size, cursor, item.endianness, item.binary === \"int\");\n      break;\n    }\n    case \"bytes\": {\n      const offset = cursor.offset;\n      if (\"lengthSize\" in item && item.lengthSize !== undefined)\n        cursor.offset += item.lengthSize;\n\n      if (bytesItemHasLayout(item)) {\n        const { custom } = item;\n        let layoutData;\n        if (custom === undefined)\n          layoutData = data;\n        else if (typeof custom.from !== \"function\")\n          layoutData = custom.from;\n        else\n          layoutData = bcqGetNext(bcq);\n\n        internalSerialize(item.layout, layoutData, cursor, bcq);\n      }\n      else {\n        const { custom } = item;\n        if (isBytesType(custom)) {\n          if (!(\"omit\" in item && item.omit))\n            checkBytesTypeEqual(custom, data);\n\n          cursorWrite(cursor, custom);\n        }\n        else if (isFixedBytesConversion(custom))\n          //no proper way to deeply check equality of custom.to and data\n          cursorWrite(cursor, custom.from);\n        else\n          cursorWrite(cursor, custom !== undefined ? bcqGetNext(bcq) : data);\n      }\n\n      if (\"lengthSize\" in item && item.lengthSize !== undefined) {\n        const itemSize = cursor.offset - offset - item.lengthSize;\n        const curOffset = cursor.offset;\n        cursor.offset = offset;\n        serializeNum(itemSize, item.lengthSize, cursor, item.lengthEndianness);\n        cursor.offset = curOffset;\n      }\n      else\n        checkItemSize(item, cursor.offset - offset);\n\n      break;\n    }\n    case \"array\": {\n      if (\"length\" in item && item.length !== data.length)\n        throw new Error(\n          `array length mismatch: layout length: ${item.length}, data length: ${data.length}`\n        );\n\n      if (\"lengthSize\" in item && item.lengthSize !== undefined)\n        serializeNum(data.length, item.lengthSize, cursor, item.lengthEndianness);\n\n      for (let i = 0; i < data.length; ++i)\n        internalSerialize(item.layout, data[i], cursor, bcq);\n\n      break;\n    }\n    case \"switch\": {\n      const [idOrConversionId, layout] = findIdLayoutPair(item, data);\n      const idNum = (Array.isArray(idOrConversionId) ? idOrConversionId[0] : idOrConversionId);\n      serializeNum(idNum, item.idSize, cursor, item.idEndianness);\n      internalSerialize(layout, data, cursor, bcq);\n      break;\n    }\n  }\n};\n\n//slightly hacky, but the only way to ensure that we are actually deserializing the\n//  right data without having to re-serialize the layout every time\nexport function getCachedSerializedFrom(\n  item: ItemBase<\"bytes\"> & {layout: Layout; custom: FixedConversion<LayoutObject, any>}\n) {\n  const custom =\n    item.custom as FixedConversion<LayoutObject, any> & {cachedSerializedFrom?: BytesType};\n  if (!(\"cachedSerializedFrom\" in custom)) {\n    custom.cachedSerializedFrom = serialize(item.layout, custom.from);\n    if (\"size\" in item &&\n        item.size !== undefined &&\n        item.size !== custom.cachedSerializedFrom.length\n      )\n      throw new Error(\n        `Layout specification error: custom.from does not serialize to specified size`\n      );\n  }\n  return custom.cachedSerializedFrom!;\n}\n","import type {\n  Endianness,\n  Layout,\n  Item,\n  DeriveType,\n  CustomConversion,\n  NumSizeToPrimitive,\n  NumType,\n  BytesType,\n} from \"./layout\";\nimport { defaultEndianness, numberMaxSize } from \"./layout\";\n\nimport {\n  isNumType,\n  isBytesType,\n  isFixedBytesConversion,\n  checkBytesTypeEqual,\n  checkNumEquals,\n  bytesItemHasLayout,\n} from \"./utils\";\nimport { getCachedSerializedFrom } from \"./serialize\";\n\ntype DeserializeReturn<L extends Layout, B extends boolean> =\n  B extends true ? DeriveType<L> : readonly [DeriveType<L>, number];\n\nexport function deserialize<const L extends Layout, const B extends boolean = true>(\n  layout: L,\n  bytes: BytesType,\n  consumeAll?: B,\n): DeserializeReturn<L, B> {\n  const boolConsumeAll = consumeAll ?? true;\n  const encoded = {\n    bytes,\n    offset: 0,\n    end: bytes.length,\n  };\n  const decoded = internalDeserialize(layout, encoded);\n\n  if (boolConsumeAll && encoded.offset !== encoded.end)\n    throw new Error(`encoded data is longer than expected: ${encoded.end} > ${encoded.offset}`);\n\n  return (boolConsumeAll ? decoded : [decoded, encoded.offset]) as DeserializeReturn<L, B>;\n}\n\n// --- implementation ---\n\ntype BytesChunk = {\n  bytes: BytesType,\n  offset: number,\n  end: number,\n};\n\nfunction updateOffset(encoded: BytesChunk, size: number) {\n  const newOffset = encoded.offset + size;\n  if (newOffset > encoded.end)\n    throw new Error(`chunk is shorter than expected: ${encoded.end} < ${newOffset}`);\n\n  encoded.offset = newOffset;\n}\n\nfunction internalDeserialize(layout: Layout, encoded: BytesChunk): any {\n  if (!Array.isArray(layout))\n    return deserializeItem(layout as Item, encoded);\n\n  let decoded = {} as any;\n  for (const item of layout)\n    try {\n      ((item as any).omit ? {} : decoded)[item.name] = deserializeItem(item, encoded);\n    }\n    catch (e) {\n      (e as Error).message = `when deserializing item '${item.name}': ${(e as Error).message}`;\n      throw e;\n    }\n\n  return decoded;\n}\n\nfunction deserializeNum<S extends number>(\n  encoded: BytesChunk,\n  size: S,\n  endianness: Endianness = defaultEndianness,\n  signed: boolean = false,\n) {\n  let val = 0n;\n  for (let i = 0; i < size; ++i)\n    val |= BigInt(encoded.bytes[encoded.offset + i]!)\n        << BigInt(8 * (endianness === \"big\" ? size - i - 1 : i));\n\n  //check sign bit if value is indeed signed and adjust accordingly\n  if (signed && (encoded.bytes[encoded.offset + (endianness === \"big\" ? 0 : size - 1)]! & 0x80))\n    val -= 1n << BigInt(8 * size);\n\n  updateOffset(encoded, size);\n\n  return ((size > numberMaxSize) ? val : Number(val)) as NumSizeToPrimitive<S>;\n}\n\nfunction deserializeItem(item: Item, encoded: BytesChunk): any {\n  switch (item.binary) {\n    case \"int\":\n    case \"uint\": {\n      const value = deserializeNum(encoded, item.size, item.endianness, item.binary === \"int\");\n\n      const { custom } = item;\n      if (isNumType(custom)) {\n        checkNumEquals(custom, value);\n        return custom;\n      }\n      if (isNumType(custom?.from)) {\n        checkNumEquals(custom!.from, value);\n        return custom!.to;\n      }\n\n      //narrowing to CustomConversion<UintType, any> is a bit hacky here, since the true type\n      //  would be CustomConversion<number, any> | CustomConversion<bigint, any>, but then we'd\n      //  have to further tease that apart still for no real gain...\n      return custom !== undefined ? (custom as CustomConversion<NumType, any>).to(value) : value;\n    }\n    case \"bytes\": {\n      const expectedSize = (\"lengthSize\" in item && item.lengthSize !== undefined)\n        ? deserializeNum(encoded, item.lengthSize, item.lengthEndianness)\n        : (item as {size?: number})?.size;\n\n      if (bytesItemHasLayout(item)) { //handle layout conversions\n        const { custom } = item;\n        const offset = encoded.offset;\n        let layoutData;\n        if (expectedSize === undefined)\n          layoutData = internalDeserialize(item.layout, encoded);\n        else {\n          const subChunk = {...encoded, end: encoded.offset + expectedSize};\n          updateOffset(encoded, expectedSize);\n          layoutData = internalDeserialize(item.layout, subChunk);\n          if (subChunk.offset !== subChunk.end)\n            throw new Error(\n              `read less data than expected: ${subChunk.offset - encoded.offset} < ${expectedSize}`\n            );\n        }\n\n        if (custom !== undefined) {\n          if (typeof custom.from !== \"function\") {\n            checkBytesTypeEqual(\n              getCachedSerializedFrom(item as any),\n              encoded.bytes,\n              {dataSlice: [offset, encoded.offset]}\n            );\n            return custom.to;\n          }\n          return custom.to(layoutData);\n        }\n\n        return layoutData;\n      }\n\n      const { custom } = item;\n      { //handle fixed conversions\n        let fixedFrom;\n        let fixedTo;\n        if (isBytesType(custom))\n          fixedFrom = custom;\n        else if (isFixedBytesConversion(custom)) {\n          fixedFrom = custom.from;\n          fixedTo = custom.to;\n        }\n        if (fixedFrom !== undefined) {\n          const size = expectedSize ?? fixedFrom.length;\n          const value = encoded.bytes.subarray(encoded.offset, encoded.offset + size);\n          checkBytesTypeEqual(fixedFrom, value);\n          updateOffset(encoded, size);\n          return fixedTo ?? fixedFrom;\n        }\n      }\n\n      //handle no or custom conversions\n      const start = encoded.offset;\n      const end = (expectedSize !== undefined) ? encoded.offset + expectedSize : encoded.end;\n      updateOffset(encoded, end - start);\n\n      const value = encoded.bytes.subarray(start, end);\n      return custom !== undefined ? (custom as CustomConversion<BytesType, any>).to(value) : value;\n    }\n    case \"array\": {\n      let ret = [] as any[];\n      const { layout } = item;\n      const deserializeArrayItem = () => {\n        const deserializedItem = internalDeserialize(layout, encoded);\n        ret.push(deserializedItem);\n      }\n\n      let length: number | null = null;\n      if (\"length\" in item && item.length !== undefined)\n        length = item.length;\n      else if (\"lengthSize\" in item && item.lengthSize !== undefined)\n        length = deserializeNum(encoded, item.lengthSize, item.lengthEndianness);\n\n      if (length !== null)\n        for (let i = 0; i < length; ++i)\n          deserializeArrayItem();\n      else\n        while (encoded.offset < encoded.end)\n          deserializeArrayItem();\n\n      return ret;\n    }\n    case \"switch\": {\n      const id = deserializeNum(encoded, item.idSize, item.idEndianness);\n      const {layouts} = item;\n      if (layouts.length === 0)\n        throw new Error(`switch item has no layouts`);\n\n      const hasPlainIds = typeof layouts[0]![0] === \"number\";\n      const pair = (layouts as readonly any[]).find(([idOrConversionId]) =>\n        hasPlainIds ? idOrConversionId === id : (idOrConversionId)[0] === id);\n\n      if (pair === undefined)\n        throw new Error(`unknown id value: ${id}`);\n\n      const [idOrConversionId, idLayout] = pair;\n      const decoded = internalDeserialize(idLayout, encoded);\n      return {\n        [item.idTag ?? \"id\"]: hasPlainIds ? id : (idOrConversionId as any)[1],\n        ...decoded\n      };\n    }\n  }\n}\n","import type {\n  Layout,\n  ProperLayout,\n  Item,\n  NumItem,\n  BytesItem,\n  ArrayItem,\n  SwitchItem,\n  DeriveType,\n  NumType,\n  BytesType,\n  LayoutObject,\n  FixedConversion,\n  CustomConversion,\n} from \"./layout\";\n\nimport { isPrimitiveType, isItem, isFixedPrimitiveConversion, bytesItemHasLayout } from \"./utils\";\n\nexport type FixedItemsOf<L extends Layout> = StartFilterItemsOf<L, true>;\nexport type DynamicItemsOf<L extends Layout> = StartFilterItemsOf<L, false>;\n\nexport const fixedItemsOf = <const L extends Layout>(layout: L) =>\n  filterItemsOf(layout, true);\n\nexport const dynamicItemsOf = <const L extends Layout>(layout: L) =>\n  filterItemsOf(layout, false);\n\nexport function addFixedValues<const L extends Layout>(\n  layout: L,\n  dynamicValues: DeriveType<DynamicItemsOf<L>>,\n): DeriveType<L> {\n  return internalAddFixedValues(layout, dynamicValues) as DeriveType<L>;\n}\n\n// --- implementation ---\n\ntype NonEmpty = readonly [unknown, ...unknown[]];\n\ntype IPLPair = readonly [any, ProperLayout];\n\ntype FilterItemsOfIPLPairs<ILA extends readonly IPLPair[], Fixed extends boolean> =\n  ILA extends infer V extends readonly IPLPair[]\n  ? V extends readonly [infer H extends IPLPair, ...infer T extends readonly IPLPair[]]\n    ? FilterItemsOf<H[1], Fixed> extends infer P extends ProperLayout | void\n      ? P extends NonEmpty\n        ? [[H[0], P], ...FilterItemsOfIPLPairs<T, Fixed>]\n        : FilterItemsOfIPLPairs<T, Fixed>\n      : never\n    : []\n  : never;\n\ntype FilterLayoutOfItem<I extends { layout: Layout }, Fixed extends boolean> =\n  FilterItemsOf<I[\"layout\"], Fixed> extends infer L extends Item | NonEmpty\n  ? { readonly [K in keyof I]: K extends \"layout\" ? L : I[K] }\n  : void;\n\ntype FilterItem<II extends Item, Fixed extends boolean> =\n  II extends infer I extends Item\n  ? I extends NumItem\n    ? I[\"custom\"] extends NumType | FixedConversion<infer From extends NumType, infer To>\n      ? Fixed extends true ? I : void\n      : Fixed extends true ? void : I\n    : I extends ArrayItem\n    ? FilterLayoutOfItem<I, Fixed>\n    : I extends BytesItem & { layout: Layout }\n    ? I[\"custom\"] extends { custom: FixedConversion<infer From extends LayoutObject, infer To>}\n      ? Fixed extends true ? I : void\n      : I extends { custom: CustomConversion<infer From extends LayoutObject, infer To>}\n      ? Fixed extends true ? void : I\n      : FilterLayoutOfItem<I, Fixed>\n    : I extends BytesItem\n    ? I[\"custom\"] extends BytesType | FixedConversion<infer From extends BytesType, infer To>\n      ? Fixed extends true ? I : void\n      : Fixed extends true ? void : I\n    : I extends SwitchItem\n    ? { readonly [K in keyof I]:\n        K extends \"layouts\" ? FilterItemsOfIPLPairs<I[\"layouts\"], Fixed> : I[K]\n      }\n    : never\n  : never;\n\ntype FilterItemsOf<L extends Layout, Fixed extends boolean> =\n  L extends infer LI extends Item\n  ? FilterItem<LI, Fixed>\n  : L extends infer P extends ProperLayout\n  ? P extends readonly [infer H extends Item, ...infer T extends ProperLayout]\n    ? FilterItem<H, Fixed> extends infer NI\n      ? NI extends Item\n        // @ts-ignore TODO: figure out and fix this\n        ? [NI, ...FilterItemsOf<T, Fixed>]\n        : FilterItemsOf<T, Fixed>\n      : never\n    : []\n  : never;\n\ntype StartFilterItemsOf<L extends Layout, Fixed extends boolean> =\n  FilterItemsOf<L, Fixed> extends infer V extends Layout\n  ? V\n  : never;\n\nfunction filterItem(item: Item, fixed: boolean): Item | null {\n  switch (item.binary) {\n    // @ts-ignore - fallthrough is intentional\n    case \"bytes\": {\n      if (bytesItemHasLayout(item)) {\n        const { custom } = item;\n        if (custom === undefined) {\n          const { layout } = item;\n          if (isItem(layout))\n            return filterItem(layout, fixed);\n\n          const filteredItems = internalFilterItemsOfProperLayout(layout, fixed);\n          return (filteredItems.length > 0) ? { ...item, layout: filteredItems } : null;\n        }\n        const isFixedItem = typeof custom.from !== \"function\";\n        return (fixed && isFixedItem || !fixed && !isFixedItem) ? item : null;\n      }\n    }\n    case \"int\":\n    case \"uint\": {\n      const { custom } = item;\n      const isFixedItem = isPrimitiveType(custom) || isFixedPrimitiveConversion(custom);\n      return (fixed && isFixedItem || !fixed && !isFixedItem) ? item : null;\n    }\n    case \"array\": {\n      const filtered = internalFilterItemsOf(item.layout, fixed);\n      return (filtered !== null) ? { ...item, layout: filtered } : null;\n    }\n    case \"switch\": {\n      const filteredIdLayoutPairs = (item.layouts as readonly any[]).reduce(\n        (acc: any, [idOrConversionId, idLayout]: any) => {\n          const filteredItems = internalFilterItemsOfProperLayout(idLayout, fixed);\n          return filteredItems.length > 0\n            ? [...acc, [idOrConversionId, filteredItems]]\n            : acc;\n        },\n        [] as any[]\n      );\n      return { ...item, layouts: filteredIdLayoutPairs };\n    }\n  }\n}\n\nfunction internalFilterItemsOfProperLayout(proper: ProperLayout, fixed: boolean): ProperLayout {\n  return proper.reduce(\n    (acc, item) => {\n      const filtered = filterItem(item, fixed) as ProperLayout[number] | null;\n      return filtered !== null ? [...acc, filtered] : acc;\n    },\n    [] as ProperLayout\n  );\n}\n\nfunction internalFilterItemsOf(layout: Layout, fixed: boolean): any {\n  return (Array.isArray(layout)\n    ? internalFilterItemsOfProperLayout(layout, fixed)\n    : filterItem(layout as Item, fixed)\n   );\n}\n\nfunction filterItemsOf<L extends Layout, const Fixed extends boolean>(\n  layout: L,\n  fixed: Fixed\n): FilterItemsOf<L, Fixed> {\n  return internalFilterItemsOf(layout, fixed);\n}\n\nfunction internalAddFixedValuesItem(item: Item, dynamicValue: any): any {\n  switch (item.binary) {\n    // @ts-ignore - fallthrough is intentional\n    case \"bytes\": {\n      if (bytesItemHasLayout(item)) {\n        const { custom } = item;\n        if (custom === undefined || typeof custom.from !== \"function\")\n          return internalAddFixedValues(item.layout, custom ? custom.from : dynamicValue);\n\n        return dynamicValue;\n      }\n    }\n    case \"int\":\n    case \"uint\": {\n      const { custom } = item;\n      return (item as {omit?: boolean})?.omit\n        ? undefined\n        : isPrimitiveType(custom)\n        ? custom\n        : isFixedPrimitiveConversion(custom)\n        ? custom.to\n        : dynamicValue;\n    }\n    case \"array\":\n      return Array.isArray(dynamicValue)\n        ? dynamicValue.map(element => internalAddFixedValues(item.layout, element))\n        : undefined;\n    case \"switch\": {\n      const id = dynamicValue[item.idTag ?? \"id\"];\n      const [_, idLayout] = (item.layouts as readonly IPLPair[]).find(([idOrConversionId]) =>\n        (Array.isArray(idOrConversionId) ? idOrConversionId[1] : idOrConversionId) == id\n      )!;\n      return {\n        [item.idTag ?? \"id\"]: id,\n        ...internalAddFixedValues(idLayout, dynamicValue)\n      };\n    }\n  }\n}\n\nfunction internalAddFixedValues(layout: Layout, dynamicValues: any): any {\n  dynamicValues = dynamicValues ?? {};\n  if (isItem(layout))\n    return internalAddFixedValuesItem(layout as Item, dynamicValues);\n\n  const ret = {} as any;\n  for (const item of layout) {\n    const fixedVals = internalAddFixedValuesItem(\n      item,\n      dynamicValues[item.name as keyof typeof dynamicValues] ?? {}\n    );\n    if (fixedVals !== undefined)\n      ret[item.name] = fixedVals;\n  }\n  return ret;\n}\n","import type { Layout, Item, LengthPrefixed, BytesType } from \"./layout\";\nimport { serializeNum, getCachedSerializedFrom } from \"./serialize\";\nimport { isNumType, isBytesType, isFixedBytesConversion, bytesItemHasLayout } from \"./utils\";\nimport { calcStaticSize } from \"./size\";\n\ntype LayoutIndex = number;\n\nexport type Discriminator<B extends boolean = false> =\n  (encoded: BytesType) => B extends false ? LayoutIndex | null : readonly LayoutIndex[];\n\nexport function buildDiscriminator<B extends boolean = false>(\n  layouts: readonly Layout[],\n  allowAmbiguous?: B\n): Discriminator<B> {\n  const [distinguishable, discriminator] = internalBuildDiscriminator(layouts);\n  if (!distinguishable && !allowAmbiguous)\n    throw new Error(\"Cannot uniquely distinguished the given layouts\");\n\n  return (\n    !allowAmbiguous\n    ? (encoded: BytesType) => {\n      const layout = discriminator(encoded);\n      return layout.length === 0 ? null : layout[0];\n    }\n    : discriminator\n  ) as Discriminator<B>;\n}\n\n// --- implementation ---\n\ntype Uint = number;\ntype Bitset = bigint;\ntype Size = Uint;\ntype BytePos = Uint;\ntype ByteVal = Uint; //actually a uint8\ntype Candidates = Bitset;\ntype FixedBytes = (readonly [BytePos, BytesType])[];\n//using a Bounds type (even though currently the upper bound can only either be equal to the lower\n//  bound or Infinity) in anticipation of a future switch layout item that might contain multiple\n//  sublayouts which, unlike arrays currently, could all be bounded but potentially with\n//  different sizes\ntype Bounds = [Size, Size];\n\nfunction arrayToBitset(arr: readonly number[]): Bitset {\n  return arr.reduce((bit, i) => bit | BigInt(1) << BigInt(i), BigInt(0));\n}\n\nfunction bitsetToArray(bitset: Bitset): number[] {\n  const ret: number[] = [];\n  for (let i = 0n; bitset > 0n; bitset >>= 1n, ++i)\n    if (bitset & 1n)\n      ret.push(Number(i));\n\n  return ret;\n}\n\nfunction count(candidates: Candidates) {\n  let count = 0;\n  for (; candidates > 0n; candidates >>= 1n)\n    count += Number(candidates & 1n);\n  return count;\n}\n\nconst lengthSizeMax = (lengthSize: number) =>\n  lengthSize > 0 ? 2**(8 * lengthSize) - 1 : Infinity;\n\nfunction layoutItemMeta(\n  item: Item,\n  offset: BytePos | null,\n  fixedBytes: FixedBytes,\n): Bounds {\n  switch (item.binary) {\n    case \"int\":\n    case \"uint\": {\n      const fixedVal =\n        isNumType(item.custom)\n        ? item.custom\n        : isNumType(item?.custom?.from)\n        ? item!.custom!.from\n        : null;\n\n      if (fixedVal !== null && offset !== null) {\n        const cursor = {bytes: new Uint8Array(item.size), offset: 0};\n        serializeNum(fixedVal, item.size, cursor, item.endianness, item.binary === \"int\");\n        fixedBytes.push([offset, cursor.bytes]);\n      }\n\n      return [item.size, item.size];\n    }\n    case \"bytes\": {\n      const lengthSize = (\"lengthSize\" in item) ? item.lengthSize | 0 : 0;\n\n      let fixed;\n      let fixedSize;\n      if (bytesItemHasLayout(item)) {\n        const { custom } = item;\n        if (custom !== undefined && typeof custom.from !== \"function\") {\n          fixed = getCachedSerializedFrom(item as any);\n          fixedSize = fixed.length;\n        }\n        else {\n          const layoutSize = calcStaticSize(item.layout);\n          if (layoutSize !== null)\n            fixedSize = layoutSize;\n        }\n      }\n      else {\n        const { custom } = item;\n        if (isBytesType(custom)) {\n          fixed = custom;\n          fixedSize = custom.length;\n        }\n        else if (isFixedBytesConversion(custom)) {\n          fixed = custom.from;\n          fixedSize = custom.from.length;\n        }\n      }\n\n      if (lengthSize > 0 && offset !== null) {\n        if (fixedSize !== undefined) {\n          const cursor = {bytes: new Uint8Array(lengthSize), offset: 0};\n          const endianess = (item as LengthPrefixed).lengthEndianness;\n          serializeNum(fixedSize, lengthSize, cursor, endianess, false);\n          fixedBytes.push([offset, cursor.bytes]);\n        }\n        offset += lengthSize;\n      }\n\n      if (fixed !== undefined) {\n        if (offset !== null)\n          fixedBytes.push([offset, fixed]);\n\n        return [lengthSize + fixed.length, lengthSize + fixed.length];\n      }\n\n      //lengthSize must be 0 if size is defined\n      const ret = (\"size\" in item && item.size !== undefined)\n        ? [item.size, item.size] as Bounds\n        : undefined;\n\n      if (bytesItemHasLayout(item)) {\n        const lm = createLayoutMeta(item.layout, offset, fixedBytes)\n        return ret ?? [lengthSize + lm[0], lengthSize + lm[1]];\n      }\n\n      return ret ?? [lengthSize, lengthSizeMax(lengthSize)];\n    }\n    case \"array\": {\n      if (\"length\" in item) {\n        let localFixedBytes = [] as FixedBytes;\n        const itemSize = createLayoutMeta(item.layout, 0, localFixedBytes);\n        if (offset !== null) {\n          if (itemSize[0] !== itemSize[1]) {\n            //if the size of an array item is not fixed we can only add the fixed bytes of the\n            //  first item\n            if (item.length > 0)\n              for (const [o, s] of localFixedBytes)\n                fixedBytes.push([offset + o, s]);\n          }\n          else {\n            //otherwise we can add fixed know bytes for each array item\n            for (let i = 0; i < item.length; ++i)\n              for (const [o, s] of localFixedBytes)\n                fixedBytes.push([offset + o + i * itemSize[0], s]);\n          }\n        }\n\n        return [item.length * itemSize[0], item.length * itemSize[1]];\n      }\n      const lengthSize = (item as LengthPrefixed).lengthSize | 0;\n      return [lengthSize, lengthSizeMax(lengthSize)];\n    }\n    case \"switch\": {\n      const caseFixedBytes = item.layouts.map(_ => []) as FixedBytes[];\n      const {idSize, idEndianness} = item;\n      const caseBounds = item.layouts.map(([idOrConversionId, layout], caseIndex) => {\n        const idVal = Array.isArray(idOrConversionId) ? idOrConversionId[0] : idOrConversionId;\n        if (offset !== null) {\n          const cursor = {bytes: new Uint8Array(idSize), offset: 0};\n          serializeNum(idVal, idSize, cursor, idEndianness);\n          caseFixedBytes[caseIndex]!.push([0, cursor.bytes]);\n        }\n        const ret = createLayoutMeta(\n          layout,\n          offset !== null ? idSize : null,\n          caseFixedBytes[caseIndex]!\n        );\n        return [ret[0] + idSize, ret[1] + idSize] as Bounds;\n      });\n\n      if (offset !== null && caseFixedBytes.every(fbs => fbs.length > 0))\n        //find bytes that have the same value across all cases\n        //  (it's a lambda to enable early return from inner loops)\n        (() => {\n          //constrain search to the minimum length of all cases\n          const minLen = Math.min(\n            ...caseFixedBytes.map(fbs => fbs.at(-1)![0] + fbs.at(-1)![1].length)\n          );\n          //keep track of the current index in each case's fixed bytes array\n          const itIndexes = caseFixedBytes.map(_ => 0);\n\n          for (let bytePos = 0; bytePos < minLen;) {\n            let byteVal: number | null = null;\n            let caseIndex = 0;\n            while (caseIndex < caseFixedBytes.length) {\n              let curItIndex = itIndexes[caseIndex]!;\n              const curFixedBytes = caseFixedBytes[caseIndex]!;\n              const [curOffset, curSerialized] = curFixedBytes[curItIndex]!;\n              if (curOffset + curSerialized.length <= bytePos) {\n                //no fixed byte at this position in this case\n                ++curItIndex;\n\n                if (curItIndex === curFixedBytes.length)\n                  return; //we have exhausted all fixed bytes in at least one case\n\n                itIndexes[caseIndex] = curItIndex;\n                //jump to the next possible bytePos given the fixed bytes of the current case index\n                bytePos = curFixedBytes[curItIndex]![0];\n                break;\n              }\n\n              const curByteVal = curSerialized[bytePos - curOffset];\n              if (byteVal === null)\n                byteVal = curByteVal;\n\n              if (curByteVal !== byteVal) {\n                ++bytePos;\n                break;\n              }\n\n              ++caseIndex;\n            }\n\n            //only if we made it through all cases without breaking do we have a fixed byte\n            //  and hence add it to the list of fixed bytes\n            if (caseIndex === caseFixedBytes.length) {\n              fixedBytes.push([offset + bytePos, new Uint8Array([byteVal!])]);\n              ++bytePos;\n            }\n          }\n        })();\n\n      return [\n        Math.min(...caseBounds.map(([lower]) => lower)),\n        Math.max(...caseBounds.map(([_, upper]) => upper))\n      ] as Bounds;\n    }\n  }\n}\n\nfunction createLayoutMeta(\n  layout: Layout,\n  offset: BytePos | null,\n  fixedBytes: FixedBytes\n): Bounds {\n  if (!Array.isArray(layout))\n    return layoutItemMeta(layout as Item, offset, fixedBytes);\n\n  let bounds = [0, 0] as Bounds;\n  for (const item of layout) {\n    const itemSize = layoutItemMeta(item, offset, fixedBytes);\n    bounds[0] += itemSize[0];\n    bounds[1] += itemSize[1];\n    //if the bounds don't agree then we can't reliably predict the offset of subsequent items\n    if (offset !== null)\n      offset = itemSize[0] === itemSize[1] ? offset + itemSize[0] : null;\n  }\n  return bounds;\n}\n\nfunction buildAscendingBounds(sortedBounds: readonly (readonly [Bounds, LayoutIndex])[]) {\n  const ascendingBounds = new Map<Size, Candidates>();\n  //sortedCandidates tracks all layouts that have a size bound that contains the size that's\n  //  currently under consideration, sorted in ascending order of their respective upper bounds\n  let sortedCandidates = [] as (readonly [Size, LayoutIndex])[];\n  const closeCandidatesBefore = (before: number) => {\n    while (sortedCandidates.length > 0 && sortedCandidates[0]![0] < before) {\n      const end = sortedCandidates[0]![0] + 1;\n      //remove all candidates that end at the same position\n      const removeIndex = sortedCandidates.findIndex(([upper]) => end <= upper);\n      if (removeIndex === -1)\n        sortedCandidates = [];\n      else\n        sortedCandidates.splice(0, removeIndex);\n      //introduce a new bound that captures all candidates that can have a size of at least `end`\n      ascendingBounds.set(end, arrayToBitset(sortedCandidates.map(([, j]) => j)));\n    }\n  };\n\n  for (const [[lower, upper], i] of sortedBounds) {\n    closeCandidatesBefore(lower);\n    const insertIndex = sortedCandidates.findIndex(([u]) => u > upper);\n    if (insertIndex === -1)\n      sortedCandidates.push([upper, i]);\n    else\n      sortedCandidates.splice(insertIndex, 0, [upper, i]);\n\n    ascendingBounds.set(lower, arrayToBitset(sortedCandidates.map(([, j]) => j)));\n  }\n  closeCandidatesBefore(Infinity);\n\n  return ascendingBounds;\n}\n\n//Generates a greedy divide-and-conquer strategy to determine the layout (or set of layouts) that\n//  a given serialized byte array might conform to.\n//It leverages size bounds and known fixed bytes of layouts to quickly eliminate candidates, by\n//  (greedily) choosing the discriminator (byte or size) that eliminates the most candidates at\n//  each step.\n//Power is a relative measure of the strength of a discriminator given a set of layout candidates.\n//  It's in [0, candidate.length - 1] and states how many layouts of that set can _at least_ be\n//  eliminated when applying that discriminator.\n//Layout sizes are only tracked in terms of lower and upper bounds. This means that while a layout\n//  like an array of e.g. 2 byte uints can actually never have an odd size, the algorithm will\n//  simply treat it as having a size bound of [0, Infinity]. This means that the algorithm is\n//  \"lossy\" in the sense that it does not use all the information that it actually has available\n//  and will e.g. wrongly conclude that the aforementioned layout cannot be distinguished from a\n//  second layout that starts off with a one byte uint followed by an array of 2 byte uints (and\n//  would thus always have odd size). I.e. it would wrongly conclude that the power of the size\n//  discriminator is 0 when it should be 1.\n//The alternative to accepting this limitation is tracking all possible combinations of offsets,\n//  multiples, and their arbitrary composition which would be massively more complicated and\n//  also pointless in the general case because we'd have to figure out whether a given size can be\n//  expressed as some combination of offsets and array size multiples in which case it's almost\n//  certainly computationally cheaper to simply attempt to deserialize the given given data for the\n//  respective layout.\nfunction internalBuildDiscriminator(\n  layouts: readonly Layout[]\n): [boolean, (encoded: BytesType) => readonly LayoutIndex[]] {\n  //for debug output:\n  // const candStr = (candidate: Bitset) => candidate.toString(2).padStart(layouts.length, '0');\n\n  if (layouts.length === 0)\n    throw new Error(\"Cannot discriminate empty set of layouts\");\n\n  const emptySet = 0n;\n  const allLayouts = (1n << BigInt(layouts.length)) - 1n;\n\n  const fixedKnown = layouts.map(() => [] as FixedBytes);\n  const sizeBounds = layouts.map((l, i) => createLayoutMeta(l, 0, fixedKnown[i]!));\n  const sortedBounds = sizeBounds.map((b, i) => [b, i] as const).sort(([[l1]], [[l2]]) => l1 - l2);\n\n  const mustHaveByteAt = (() => {\n    let remaining = allLayouts;\n    const ret = new Map<Size, Candidates>();\n    for (const [[lower], i] of sortedBounds) {\n      remaining ^= 1n << BigInt(i); //delete the i-th bit\n      ret.set(lower, remaining);\n    }\n    return ret;\n  })();\n  const ascendingBounds = buildAscendingBounds(sortedBounds);\n  const sizePower = layouts.length - Math.max(\n    ...[...ascendingBounds.values()].map(candidates => count(candidates))\n  );\n  //we don't check sizePower here and bail early if it is perfect because we prefer perfect byte\n  //  discriminators over perfect size discriminators due to their faster lookup times (hash map\n  //  vs binary search (and actually currently everything is even implement using linear search))\n  //  and more predictable / lower complexity branching behavior.\n  const layoutsWithByteAt = (bytePos: BytePos) => {\n    let ret = allLayouts;\n    for (const [lower, candidates] of mustHaveByteAt) {\n      if (bytePos < lower)\n        break;\n\n      ret = candidates;\n    }\n    return ret;\n  };\n\n  const layoutsWithSize = (size: Size) => {\n    let ret = emptySet;\n    for (const [lower, candidates] of ascendingBounds) {\n      if (size < lower)\n        break;\n\n      ret = candidates;\n    }\n    return ret;\n  };\n\n  const fixedKnownBytes: readonly ((readonly [ByteVal, LayoutIndex])[])[] = Array.from({length:\n    Math.max(...fixedKnown.map(fkb => fkb.length > 0 ? fkb.at(-1)![0] + fkb.at(-1)![1].length : 0))\n  }).map(() => []);\n\n  for (let i = 0; i < fixedKnown.length; ++i)\n    for (const [offset, serialized] of fixedKnown[i]!)\n      for (let j = 0; j < serialized.length; ++j)\n        fixedKnownBytes[offset + j]!.push([serialized[j]!, i]);\n\n  //debug output:\n  // console.log(\"fixedKnownBytes:\",\n  //   fixedKnownBytes.map((v, i) => v.length > 0 ? [i, v] : undefined).filter(v => v !== undefined)\n  // );\n\n  let bestBytes: [number, BytePos, Candidates, Map<ByteVal, Candidates>, Candidates,][] = [];\n  for (const [bytePos, fixedKnownByte] of fixedKnownBytes.entries()) {\n    //the number of layouts with a given size is an upper bound on the discriminatory power of\n    //  a byte at a given position: If the encoded data is too short we can automatically\n    //  exclude all layouts whose minimum size is larger than it, nevermind those who expect\n    //  a known, fixed value at this position.\n    const lwba = layoutsWithByteAt(bytePos);\n    const anyValueLayouts = lwba ^ arrayToBitset(fixedKnownByte.map(([, layoutIdx]) => layoutIdx));\n    const outOfBoundsLayouts = allLayouts ^ lwba;\n    const distinctValues = new Map<BytePos, Candidates>();\n    //the following equation holds (after applying .length to each component):\n    //layouts = outOfBoundsLayouts + anyValueLayouts + fixedKnownByte\n    for (const [byteVal, candidate] of fixedKnownByte) {\n      if (!distinctValues.has(byteVal))\n        distinctValues.set(byteVal, emptySet);\n\n      distinctValues.set(byteVal, distinctValues.get(byteVal)! | 1n << BigInt(candidate));\n    }\n\n    let power = layouts.length - Math.max(count(anyValueLayouts), count(outOfBoundsLayouts));\n    for (const layoutsWithValue of distinctValues.values()) {\n      //if we find the byte value associated with this set of layouts, we can eliminate\n      //  all other layouts that don't have this value at this position and all layouts\n      //  that are too short to have a value in this position regardless\n      const curPower = fixedKnownByte.length - count(layoutsWithValue) + count(outOfBoundsLayouts);\n      power = Math.min(power, curPower);\n    }\n\n    //debug output:\n    // console.log(\n    //   \"bytePos:\", bytePos,\n    //   \"\\npower:\", power,\n    //   \"\\nfixedKnownByte:\", fixedKnownByte,\n    //   \"\\nlwba:\", candStr(lwba),\n    //   \"\\nanyValueLayouts:\", candStr(anyValueLayouts),\n    //   \"\\noutOfBoundsLayouts:\", candStr(outOfBoundsLayouts),\n    //   \"\\ndistinctValues:\", new Map([...distinctValues].map(([k, v]) => [k, candStr(v)]))\n    // );\n\n    if (power === 0)\n      continue;\n\n    if (power === layouts.length - 1)\n      //we have a perfect byte discriminator -> bail early\n      return [\n        true,\n        (encoded: BytesType) =>\n          bitsetToArray(\n            encoded.length <= bytePos\n            ? outOfBoundsLayouts\n            : distinctValues.get(encoded[bytePos]!) ?? emptySet\n          )\n      ];\n\n    bestBytes.push([power, bytePos, outOfBoundsLayouts, distinctValues, anyValueLayouts] as const);\n  }\n\n  //if we get here, we know we don't have a perfect byte discriminator so we now check wether we\n  //  we have a perfect size discriminator and bail early if so\n  if (sizePower === layouts.length - 1)\n    return [true, (encoded: BytesType) => bitsetToArray(layoutsWithSize(encoded.length))];\n\n  //sort in descending order of power\n  bestBytes.sort(([lhsPower], [rhsPower]) => rhsPower - lhsPower);\n  type BestBytes = typeof bestBytes;\n  type Strategy = [BytePos, Candidates, Map<number, Candidates>] | \"size\" | \"indistinguishable\";\n\n  let distinguishable = true;\n  const strategies = new Map<Candidates, Strategy>();\n  const candidatesBySize = new Map<Size, Candidates[]>();\n  const addStrategy = (candidates: Candidates, strategy: Strategy) => {\n    strategies.set(candidates, strategy);\n    if (!candidatesBySize.has(count(candidates)))\n      candidatesBySize.set(count(candidates), []);\n    candidatesBySize.get(count(candidates))!.push(candidates);\n  };\n\n  const recursivelyBuildStrategy = (\n    candidates: Candidates,\n    bestBytes: BestBytes,\n  ) => {\n    if (count(candidates) <= 1 || strategies.has(candidates))\n      return;\n\n    let sizePower = 0;\n    const narrowedBounds = new Map<Size, Candidates>();\n    for (const candidate of bitsetToArray(candidates)) {\n      const lower = sizeBounds[candidate]![0];\n      const overlap = ascendingBounds.get(lower)! & candidates;\n      narrowedBounds.set(lower, overlap)\n      sizePower = Math.max(sizePower, count(overlap));\n    }\n    sizePower = count(candidates) - sizePower;\n\n    const narrowedBestBytes = [] as BestBytes;\n    for (const [power, bytePos, outOfBoundsLayouts, distinctValues, anyValueLayouts] of bestBytes) {\n      const narrowedDistinctValues = new Map<ByteVal, Candidates>();\n      let fixedKnownCount = 0;\n      for (const [byteVal, layoutsWithValue] of distinctValues) {\n        const lwv = layoutsWithValue & candidates;\n        if (count(lwv) > 0) {\n          narrowedDistinctValues.set(byteVal, lwv);\n          fixedKnownCount += count(lwv);\n        }\n      }\n      const narrowedOutOfBoundsLayouts = outOfBoundsLayouts & candidates;\n\n      let narrowedPower = narrowedDistinctValues.size > 0 ? power : 0;\n      for (const layoutsWithValue of narrowedDistinctValues.values()) {\n        const curPower =\n          fixedKnownCount - count(layoutsWithValue) + count(narrowedOutOfBoundsLayouts);\n        narrowedPower = Math.min(narrowedPower, curPower);\n      }\n\n      if (narrowedPower === 0)\n        continue;\n\n      if (narrowedPower === count(candidates) - 1) {\n        //if we have a perfect byte discriminator, we can bail early\n        addStrategy(candidates, [bytePos, narrowedOutOfBoundsLayouts, narrowedDistinctValues]);\n        return;\n      }\n\n      narrowedBestBytes.push([\n        narrowedPower,\n        bytePos,\n        narrowedOutOfBoundsLayouts,\n        narrowedDistinctValues,\n        anyValueLayouts & candidates\n      ] as const);\n    }\n\n    if (sizePower === count(candidates) - 1) {\n      //if we have a perfect size discriminator, we can bail early\n      addStrategy(candidates, \"size\");\n      return;\n    }\n\n    narrowedBestBytes.sort(([lhsPower], [rhsPower]) => rhsPower - lhsPower);\n\n    //prefer byte discriminators over size discriminators\n    if (narrowedBestBytes.length > 0 && narrowedBestBytes[0]![0] >= sizePower) {\n      const [, bytePos, narrowedOutOfBoundsLayouts, narrowedDistinctValues, anyValueLayouts] =\n        narrowedBestBytes[0]!;\n      addStrategy(candidates, [bytePos, narrowedOutOfBoundsLayouts, narrowedDistinctValues]);\n      recursivelyBuildStrategy(narrowedOutOfBoundsLayouts, narrowedBestBytes);\n      for (const cand of narrowedDistinctValues.values())\n        recursivelyBuildStrategy(cand | anyValueLayouts, narrowedBestBytes.slice(1));\n\n      return;\n    }\n\n    if (sizePower > 0) {\n      addStrategy(candidates, \"size\");\n      for (const cands of narrowedBounds.values())\n        recursivelyBuildStrategy(cands, narrowedBestBytes);\n\n      return;\n    }\n\n    addStrategy(candidates, \"indistinguishable\");\n    distinguishable = false;\n  }\n\n  recursivelyBuildStrategy(allLayouts, bestBytes);\n\n  const findSmallestSuperSetStrategy = (candidates: Candidates) => {\n    for (let size = count(candidates) + 1; size < layouts.length - 2; ++size)\n      for (const larger of candidatesBySize.get(size) ?? [])\n        if ((candidates & larger) == candidates) //is subset?\n          return strategies.get(larger)!;\n\n    throw new Error(\"Implementation error in layout discrimination algorithm\");\n  };\n\n  //debug output:\n  // console.log(\"strategies:\", JSON.stringify(\n  //     new Map([...strategies].map(([cands, strat]) => [\n  //       candStr(cands),\n  //       typeof strat === \"string\"\n  //         ? strat\n  //         : [\n  //           strat[0], //bytePos\n  //           candStr(strat[1]), //outOfBoundsLayouts\n  //           new Map([...strat[2]].map(([value, cands]) => [value, candStr(cands)]))\n  //         ]\n  //     ]\n  //   ))\n  // ));\n\n  return [distinguishable, (encoded: BytesType) => {\n    let candidates = allLayouts;\n\n    let strategy = strategies.get(candidates)!;\n    while (strategy !== \"indistinguishable\") {\n      //debug output:\n      // console.log(\n      //   \"applying strategy\", strategy,\n      //   \"\\nfor remaining candidates:\", candStr(candidates)\n      // );\n      if (strategy === \"size\")\n        candidates &= layoutsWithSize(encoded.length);\n      else {\n        const [bytePos, outOfBoundsLayouts, distinctValues] = strategy;\n        if (encoded.length <= bytePos)\n          candidates &= outOfBoundsLayouts;\n        else {\n          const byteVal = encoded[bytePos];\n          for (const [val, cands] of distinctValues)\n            if (val !== byteVal)\n              candidates ^= candidates & cands; //= candidates - cands (set minus)\n\n          candidates ^= candidates & outOfBoundsLayouts;\n        }\n      }\n\n      if (count(candidates) <= 1)\n        break;\n\n      strategy = strategies.get(candidates) ?? findSmallestSuperSetStrategy(candidates)\n    }\n\n    //debug output:\n    // console.log(\"final candidates\", candStr(candidates));\n    return bitsetToArray(candidates);\n  }];\n}\n","import type {\n  Endianness,\n  NumberSize,\n  NumSizeToPrimitive,\n  DeriveType,\n  Layout,\n  BytesItem,\n  FixedConversion,\n  CustomConversion\n} from \"./layout\";\nimport { numberMaxSize } from \"./layout\";\nimport { isLayout, isFixedBytesConversion } from \"./utils\";\n\n//-------------------------------- customizableBytes --------------------------------\n\nexport type CustomizableBytes =\n  undefined |\n  Layout |\n  Uint8Array |\n  FixedConversion<Uint8Array, any> |\n  CustomConversion<Uint8Array, any> |\n  readonly [Layout, FixedConversion<any, any> | CustomConversion<any, any>];\n\nexport type BytesBase =\n  ( {} | { readonly name: string } ) & Omit<BytesItem, \"binary\" | \"custom\" | \"layout\">;\n\ntype CombineObjects<T, U> = {\n  readonly [K in keyof T | keyof U]: K extends keyof T ? T[K] : K extends keyof U ? U[K] : never;\n};\n\nexport type CustomizableBytesReturn<B extends BytesBase, P extends CustomizableBytes> =\n  CombineObjects<\n    B,\n    P extends undefined\n    ? { binary: \"bytes\" }\n    : P extends Layout\n    ? { binary: \"bytes\", layout: P }\n    : P extends Uint8Array | FixedConversion<Uint8Array, any> | CustomConversion<Uint8Array, any>\n    ? { binary: \"bytes\", custom: P }\n    : P extends readonly [Layout, FixedConversion<any, any> | CustomConversion<any, any>]\n    ? { binary: \"bytes\", layout: P[0], custom: P[1] }\n    : never\n  >;\n\nexport const customizableBytes = <\n  const B extends BytesBase,\n  const C extends CustomizableBytes\n>(base: B, spec?: C) => ({\n  ...base,\n  binary: \"bytes\",\n  ...(() => {\n    if (spec === undefined)\n      return {};\n\n    if (isLayout(spec))\n      return { layout: spec };\n\n    if (spec instanceof Uint8Array || isFixedBytesConversion(spec) || !Array.isArray(spec))\n      return { custom: spec };\n\n    return { layout: spec[0], custom: spec[1] };\n  })()\n} as CustomizableBytesReturn<B, C>);\n\n//-------------------------------- boolItem --------------------------------\n\nexport function boolItem(permissive: boolean = false) {\n  return {\n    binary: \"uint\",\n    size: 1,\n    custom: {\n      to: (encoded: number): boolean => {\n        if (encoded === 0)\n          return false;\n\n        if (permissive || encoded === 1)\n          return true;\n\n        throw new Error(`Invalid bool value: ${encoded}`);\n      },\n      from: (value: boolean): number => value ? 1 : 0,\n    }\n  } as const;\n}\n\n//-------------------------------- enumItem --------------------------------\n\nexport function enumItem<\n  const E extends readonly (readonly [string, number])[],\n  const S extends NumberSize = 1,\n  const EN extends Endianness = \"big\"\n>(entries: E, opts?: { size?: S, endianness?: EN }) {\n  const valueToName = Object.fromEntries(entries.map(([name, value]) => [value, name]));\n  const nameToValue = Object.fromEntries(entries);\n  return {\n    binary: \"uint\",\n    size: (opts?.size ?? 1) as S,\n    endianness: (opts?.endianness ?? \"big\") as EN,\n    custom: {\n      to: (encoded: number): E[number][0] => {\n        const name = valueToName[encoded];\n        if (name === undefined)\n          throw new Error(`Invalid enum value: ${encoded}`);\n\n        return name;\n      },\n      from: (name: E[number][0]) => nameToValue[name]!,\n    }\n  } as const;\n}\n\n//-------------------------------- optionItem --------------------------------\n\nconst baseOptionItem = <const T extends CustomizableBytes>(someType: T) => ({\n  binary: \"switch\",\n  idSize: 1,\n  idTag: \"isSome\",\n  layouts: [\n    [[0, false], []],\n    [[1, true ], [customizableBytes({ name: \"value\"}, someType)]],\n  ]\n} as const);\n\ntype BaseOptionItem<T extends CustomizableBytes> =\n  DeriveType<ReturnType<typeof baseOptionItem<T>>>;\n\ntype BaseOptionValue<T extends CustomizableBytes> =\n  DeriveType<CustomizableBytesReturn<{}, T>> | undefined;\n\nexport function optionItem<const T extends CustomizableBytes>(optVal: T) {\n  return {\n    binary: \"bytes\",\n    layout: baseOptionItem(optVal),\n    custom: {\n      to: (obj: BaseOptionItem<T>): BaseOptionValue<T> =>\n        obj.isSome === true\n        //typescript is not smart enough to narrow the outer type based on the inner type\n        ? (obj as Exclude<typeof obj, {isSome: false}>)[\"value\"]\n        : undefined,\n      from: (value: BaseOptionValue<T>): BaseOptionItem<T> =>\n        value === undefined\n        ? { isSome: false }\n        : { isSome: true, value } as any, //good luck narrowing this type\n    } satisfies CustomConversion<BaseOptionItem<T>, BaseOptionValue<T>>\n  } as const\n};\n\n//-------------------------------- bitsetItem --------------------------------\n\nexport type Bitset<B extends readonly (string | undefined)[]> =\n  {[K in B[number] as K extends \"\" | undefined ? never : K]: boolean};\n\ntype ByteSize = [\n  never,\n  1, 1, 1, 1, 1, 1, 1, 1,\n  2, 2, 2, 2, 2, 2, 2, 2,\n  3, 3, 3, 3, 3, 3, 3, 3,\n  4, 4, 4, 4, 4, 4, 4, 4,\n  5, 5, 5, 5, 5, 5, 5, 5,\n  6, 6, 6, 6, 6, 6, 6, 6,\n];\n\ntype BitsizeToBytesize<N extends number> = N extends keyof ByteSize ? ByteSize[N] : number;\n\nexport type BitsetItem<\n  B extends readonly (string | undefined)[],\n  S extends number = BitsizeToBytesize<B[\"length\"]>,\n> = {\n  binary: \"uint\";\n  size: S;\n  custom: {\n    to: (encoded: NumSizeToPrimitive<S>) => Bitset<B>;\n    from: (obj: Bitset<B>) => NumSizeToPrimitive<S>;\n  };\n};\n\nexport function bitsetItem<\n  const B extends readonly (string | undefined)[],\n  const S extends number = BitsizeToBytesize<B[\"length\"]>,\n>(bitnames: B, size?: S): BitsetItem<B, S> {\n  return {\n    binary: \"uint\",\n    size: (size ?? Math.ceil(bitnames.length / 8)) as S,\n    custom: {\n      to: (encoded: NumSizeToPrimitive<S>): Bitset<B> => {\n        const ret: Bitset<B> = {} as Bitset<B>;\n        for (let i = 0; i < bitnames.length; ++i)\n          if (bitnames[i]) //skip undefined and empty string\n            //always use bigint for simplicity\n            ret[bitnames[i] as keyof Bitset<B>] = (BigInt(encoded) & (1n << BigInt(i))) !== 0n;\n\n        return ret;\n      },\n      from: (obj: Bitset<B>): NumSizeToPrimitive<S> => {\n        let val = 0n;\n        for (let i = 0; i < bitnames.length; ++i)\n          if (bitnames[i] && obj[bitnames[i] as keyof Bitset<B>])\n            val |= 1n << BigInt(i);\n\n        return (bitnames.length > numberMaxSize ? val : Number(val)) as NumSizeToPrimitive<S>;\n      },\n    },\n  } as const\n}\n"],"mappings":"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","names":["custom","custom","value","idOrConversionId","count","bestBytes","sizePower"]}