{
  "version": 3,
  "sources": ["../src/node.ts", "../src/_layout.ts", "../src/ADR32.ts", "../src/ADR62.ts"],
  "sourcesContent": ["import { sha256 } from '@noble/hashes/sha256'\nimport { CID } from 'multiformats/cid'\nimport { create } from 'multiformats/hashes/digest'\nimport { CHUNK_SIZE_BYTES, MAX_CHILDREN_PER_NODE, hashV1WithLayout } from './_layout'\n\nexport type HashableContent = AsyncGenerator<Uint8Array> | AsyncIterable<Uint8Array> | Uint8Array\n\nconst SHA2_256_CODE = 0x12\n\nfunction isAsyncIterable(content: unknown): content is AsyncIterable<Uint8Array> {\n  return (\n    (typeof content === 'object' || typeof content === 'function') &&\n    content !== null &&\n    Symbol.asyncIterator in content\n  )\n}\n\n/**\n * Calculates a Qm prefixed hash for Decentraland (NOT CIDv0) from a readable stream\n *\n * @public\n * @deprecated use hashV1 instead, this function exists for backwards compatibility reasons.\n */\nexport async function hashV0(stream: HashableContent): Promise<string> {\n  const hash = sha256.create()\n\n  if (stream instanceof Uint8Array) {\n    hash.update(stream)\n  } else if (isAsyncIterable(stream)) {\n    for await (const chunk of stream) {\n      hash.update(chunk)\n    }\n  } else {\n    throw new Error(\n      'Invalid value provided to hashV0. Expected AsyncGenerator<Uint8Array> | AsyncIterable<Uint8Array> | Uint8Array'\n    )\n  }\n\n  return CID.createV0(create(SHA2_256_CODE, hash.digest())).toString()\n}\n\n/**\n * Calculates a CIDv1 from a readable stream\n * @public\n */\nexport async function hashV1(content: HashableContent): Promise<string> {\n  return hashV1WithLayout(content, {\n    chunkSize: CHUNK_SIZE_BYTES,\n    maxChildrenPerNode: MAX_CHILDREN_PER_NODE\n  })\n}\n", "import { encode, prepare } from '@ipld/dag-pb'\nimport { sha256 } from '@noble/hashes/sha256'\nimport { UnixFS } from 'ipfs-unixfs'\nimport { CID } from 'multiformats/cid'\nimport { create } from 'multiformats/hashes/digest'\nimport type { PBLink } from '@ipld/dag-pb'\n\n// Local alias kept structurally identical to `LayoutInput` in ./node so the\n// public type lives only in node.ts and this file's emitted .d.ts has no\n// cross-file references (it's only generated for the test-helper bundle).\ntype LayoutInput = AsyncGenerator<Uint8Array> | AsyncIterable<Uint8Array> | Uint8Array\n\n// Matches the defaults of ipfs-unixfs-importer's balanced layout so hashes are\n// bit-compatible: fixed-size 262144-byte chunks, up to 174 children per node.\nexport const CHUNK_SIZE_BYTES = 262_144\nexport const MAX_CHILDREN_PER_NODE = 174\n\nconst SHA2_256_CODE = 0x12\nconst RAW_CODEC = 0x55\nconst DAG_PB_CODEC = 0x70\n\ninterface DagNode {\n  cid: CID\n  fileSize: bigint\n  cumulativeSize: number\n}\n\nfunction isAsyncIterable(content: unknown): content is AsyncIterable<Uint8Array> {\n  return (\n    (typeof content === 'object' || typeof content === 'function') &&\n    content !== null &&\n    Symbol.asyncIterator in content\n  )\n}\n\nfunction sha256Digest(data: Uint8Array) {\n  return create(SHA2_256_CODE, sha256(data))\n}\n\nfunction rawLeaf(chunk: Uint8Array): DagNode {\n  return {\n    cid: CID.createV1(RAW_CODEC, sha256Digest(chunk)),\n    fileSize: BigInt(chunk.length),\n    cumulativeSize: chunk.length\n  }\n}\n\nfunction buildParent(children: DagNode[]): DagNode {\n  const file = new UnixFS({ type: 'file' })\n  const links: PBLink[] = new Array(children.length)\n  let cumulativeSize = 0\n  let fileSize = 0n\n\n  for (let i = 0; i < children.length; i++) {\n    const child = children[i]\n    file.addBlockSize(child.fileSize)\n    links[i] = { Name: '', Tsize: child.cumulativeSize, Hash: child.cid }\n    cumulativeSize += child.cumulativeSize\n    fileSize += child.fileSize\n  }\n\n  const block = encode(prepare({ Data: file.marshal(), Links: links }))\n  return {\n    cid: CID.createV1(DAG_PB_CODEC, sha256Digest(block)),\n    fileSize,\n    cumulativeSize: cumulativeSize + block.length\n  }\n}\n\nfunction* chunksFromBuffer(content: Uint8Array, chunkSize: number): Generator<Uint8Array> {\n  for (let offset = 0; offset < content.length; offset += chunkSize) {\n    yield content.subarray(offset, Math.min(offset + chunkSize, content.length))\n  }\n}\n\nasync function* chunksFromStream(content: AsyncIterable<Uint8Array>, chunkSize: number): AsyncGenerator<Uint8Array> {\n  const pending: Uint8Array[] = []\n  let pendingBytes = 0\n\n  for await (const incoming of content) {\n    if (incoming.length === 0) continue\n    pending.push(incoming)\n    pendingBytes += incoming.length\n\n    while (pendingBytes >= chunkSize) {\n      const chunk = new Uint8Array(chunkSize)\n      let written = 0\n      while (written < chunkSize) {\n        const head = pending[0]\n        const needed = chunkSize - written\n        if (head.length <= needed) {\n          chunk.set(head, written)\n          written += head.length\n          pending.shift()\n        } else {\n          chunk.set(head.subarray(0, needed), written)\n          pending[0] = head.subarray(needed)\n          written += needed\n        }\n      }\n      pendingBytes -= chunkSize\n      yield chunk\n    }\n  }\n\n  if (pendingBytes > 0) {\n    const chunk = new Uint8Array(pendingBytes)\n    let written = 0\n    for (const part of pending) {\n      chunk.set(part, written)\n      written += part.length\n    }\n    yield chunk\n  }\n}\n\n// Streaming balanced-tree builder. Mirrors the recursive batched algorithm used\n// by ipfs-unixfs-importer's balanced layout, but folds completed levels into\n// parents on the fly so memory stays bounded by tree depth \u00D7 maxChildrenPerNode\n// instead of the total number of leaves.\nclass BalancedTreeBuilder {\n  private readonly levels: DagNode[][] = [[]]\n  private leafCount = 0\n\n  constructor(private readonly maxChildrenPerNode: number) {}\n\n  addLeaf(chunk: Uint8Array): void {\n    this.leafCount++\n    this.pushAt(0, rawLeaf(chunk))\n  }\n\n  finalize(): DagNode {\n    if (this.leafCount === 0) {\n      return rawLeaf(new Uint8Array(0))\n    }\n    if (this.leafCount === 1) {\n      return this.levels[0][0]\n    }\n\n    let carry: DagNode | undefined\n    for (let i = 0; i < this.levels.length; i++) {\n      const level = this.levels[i]\n      if (carry !== undefined) level.push(carry)\n\n      if (level.length === 0) {\n        carry = undefined\n        continue\n      }\n\n      // The topmost level with a single node is already a complete root\n      // (e.g. all leaves fit under one balanced subtree, or stragglers were\n      // promoted up to it). Mirrors ipfs-unixfs-importer's \"return roots[0]\n      // when roots.length === 1\" guard, which avoids wrapping a single node\n      // in a redundant unary parent. Lower levels with a single node still\n      // get wrapped so the importer's \"promote lone straggler up the tree\"\n      // shape is preserved.\n      const isTopmost = i === this.levels.length - 1\n      carry = isTopmost && level.length === 1 ? level[0] : buildParent(level)\n    }\n\n    if (carry === undefined) {\n      throw new Error('hashV1: internal error \u2014 tree produced no root')\n    }\n    return carry\n  }\n\n  private pushAt(level: number, node: DagNode): void {\n    if (level === this.levels.length) this.levels.push([])\n    const bucket = this.levels[level]\n    bucket.push(node)\n\n    if (bucket.length === this.maxChildrenPerNode) {\n      const parent = buildParent(bucket)\n      bucket.length = 0\n      this.pushAt(level + 1, parent)\n    }\n  }\n}\n\nasync function hashChunks(\n  chunks: Iterable<Uint8Array> | AsyncIterable<Uint8Array>,\n  maxChildrenPerNode: number\n): Promise<string> {\n  const builder = new BalancedTreeBuilder(maxChildrenPerNode)\n  for await (const chunk of chunks) {\n    builder.addLeaf(chunk)\n  }\n  return builder.finalize().cid.toString()\n}\n\n/**\n * Internal entry point that exposes the UnixFS layout knobs so the balanced\n * tree can be exercised at small fan-outs (e.g. `maxChildrenPerNode: 3`) in\n * tests without needing the multi-GB inputs the production defaults would\n * otherwise require. Not part of the published surface \u2014 production callers\n * must use {@link hashV1}.\n */\nexport async function hashV1WithLayout(\n  content: LayoutInput,\n  options: { chunkSize: number; maxChildrenPerNode: number }\n): Promise<string> {\n  const { chunkSize, maxChildrenPerNode } = options\n\n  if (content instanceof Uint8Array && content.length <= chunkSize) {\n    return CID.createV1(RAW_CODEC, sha256Digest(content)).toString()\n  }\n\n  if (content instanceof Uint8Array) {\n    return hashChunks(chunksFromBuffer(content, chunkSize), maxChildrenPerNode)\n  }\n\n  if (isAsyncIterable(content)) {\n    return hashChunks(chunksFromStream(content, chunkSize), maxChildrenPerNode)\n  }\n\n  throw new Error(\n    'Invalid value provided to hashV1. Expected AsyncGenerator<Uint8Array> | AsyncIterable<Uint8Array> | Uint8Array'\n  )\n}\n", "import { hashV0, hashV1 } from './node'\n\nconst textEncoder = new TextEncoder()\n\n/**\n * EntityContent as specified in ADR32\n * @public\n */\nexport interface EntityContentItemReference {\n  file: string\n  hash: string\n}\n\nexport interface CalculateMultipleHashesResult {\n  data: Uint8Array\n  hash: string\n}\n\nexport function sortKeys(a: EntityContentItemReference, b: EntityContentItemReference): number {\n  return compareStrings(a.hash, b.hash) || compareStrings(a.file, b.file)\n}\n\nexport function compareStrings(a: string, b: string): number {\n  if (a < b) return -1\n  if (a > b) return 1\n  return 0\n}\n\nexport function prepareADR32Data(contents: EntityContentItemReference[], metadata?: unknown): Uint8Array {\n  return textEncoder.encode(\n    JSON.stringify({\n      content: contents.toSorted(sortKeys).map((entry) => ({ key: entry.file, hash: entry.hash })),\n      metadata\n    })\n  )\n}\n\n/**\n * Calculates the content hash of multiple files to be used consistently by the builder\n * and other content-based applications when hashes need to be stored on-chain.\n *\n * Returns the CIDv1 of the data prepared to sign\n * @public\n */\nexport async function calculateMultipleHashesADR32(\n  contents: EntityContentItemReference[],\n  metadata?: unknown\n): Promise<CalculateMultipleHashesResult> {\n  const data = prepareADR32Data(contents, metadata)\n\n  return {\n    data,\n    hash: await hashV1(data)\n  }\n}\n\n/**\n * Calculates the content hash of multiple files to be used consistently by the builder\n * and other content-based applications when hashes need to be stored on-chain.\n *\n * @deprecated this is maintained only for compatibility reasons with calculateBufferHash (Qm prefix)\n * @public\n */\nexport async function calculateMultipleHashesADR32LegacyQmHash(\n  contents: EntityContentItemReference[],\n  metadata?: unknown\n): Promise<CalculateMultipleHashesResult> {\n  const data = prepareADR32Data(contents, metadata)\n\n  return {\n    data,\n    hash: await hashV0(data)\n  }\n}\n", "import { keccak256 } from 'ethereum-cryptography/keccak.js'\nimport { toHex } from 'ethereum-cryptography/utils.js'\n\n/**\n * Calculates the metadata hash. Uses the keys to determine which fields of the metadata object will be used for the result.\n * @public\n */\nexport function keccak256Hash(metadata: Record<string, unknown>, keys: string[]): string {\n  const partialMetadata = JSON.stringify(pick(metadata, keys))\n  const data = new TextEncoder().encode(partialMetadata)\n  const hash = keccak256(data)\n  return toHex(hash)\n}\n\nconst pick = (obj: Record<string, unknown>, keys: string[]) =>\n  Object.fromEntries(keys.filter((key) => Object.hasOwn(obj, key)).map((key) => [key, obj[key]]))\n"],
  "mappings": "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",
  "names": ["sha256", "CID", "create", "SHA2_256_CODE", "isAsyncIterable", "sha256", "CID", "create"]
}
