{
  "format": "odb-inspection/1",
  "executed": false,
  "source": {
    "path": "components/ultrasound/recorded-data/1.0.0/source.ts",
    "sha256": "b1526b60b146665ea4035386016a5f1d92679aad147d0ed2a9e37c2b9e0d6d38",
    "build": "Built into the explicit recording host; no dynamic source evaluation.",
    "text": "// SPDX-License-Identifier: AGPL-3.0-or-later\n// Host-owned file I/O only. Journals are data and are never dispatched as commands.\nconst CHUNK = 65536, MAX_LINE = 262144, MAX_JSON = 96 * 1024 * 1024;\nexport interface Recording extends Blob { readonly name: string }\nfunction count(value: unknown): number {\n  if (!Number.isSafeInteger(value) || (value as number) < 0) throw Error(\"Invalid recording count\");\n  return value as number;\n}\nfunction data(row: any): Uint8Array {\n  const length = count(row?.bytes);\n  if (length > CHUNK || typeof row.base64 !== \"string\" || row.base64.length !== 4 * Math.ceil(length / 3) ||\n      !/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(row.base64)) throw Error(\"Invalid recorded DATA encoding or size\");\n  const decoded = atob(row.base64);\n  if (decoded.length !== length || btoa(decoded) !== row.base64) throw Error(\"Recorded DATA length or encoding mismatch\");\n  return Uint8Array.from(decoded, c => c.charCodeAt(0));\n}\nasync function* chunks(file: Blob, signal: AbortSignal) {\n  for (let offset = 0; offset < file.size; offset += CHUNK) {\n    signal.throwIfAborted();\n    const bytes = new Uint8Array(await file.slice(offset, offset + CHUNK).arrayBuffer());\n    signal.throwIfAborted(); yield bytes;\n  }\n}\nasync function* lines(file: Blob, signal: AbortSignal) {\n  const decoder = new TextDecoder(\"utf-8\", { fatal: true }); let tail = \"\";\n  for await (const bytes of chunks(file, signal)) {\n    tail += decoder.decode(bytes, { stream: true });\n    for (;;) {\n      const end = tail.indexOf(\"\\n\"); if (end < 0) break;\n      if (end > MAX_LINE) throw Error(\"Recording line exceeds 256 KiB\");\n      const line = tail.slice(0, end); tail = tail.slice(end + 1); yield line;\n    }\n    if (tail.length > MAX_LINE) throw Error(\"Recording line exceeds 256 KiB\");\n  }\n  tail += decoder.decode(); if (tail.length) yield tail;\n}\n/** Yield exact DATA bytes, in order, without loading a continuous archive into RAM. */\nexport async function* recordedProbeBytes(file: Recording, signal: AbortSignal): AsyncGenerator<Uint8Array> {\n  signal.throwIfAborted();\n  if (file.name.toLowerCase().endsWith(\".bin\")) { yield* chunks(file, signal); return; }\n  if (file.name.toLowerCase().endsWith(\".odb-capture\")) {\n    if (file.size > MAX_JSON) throw Error(\"Legacy capture exceeds 96 MiB; use a streaming .odb-stream recording\");\n    const archive = JSON.parse(await file.text()); signal.throwIfAborted();\n    if (archive?.format !== \"odb-probe-capture/1\" || !Array.isArray(archive.data_reads)) throw Error(\"Invalid capture archive\");\n    let total = 0;\n    // Validate the complete legacy container before yielding its first byte.\n    for (const [index, row] of archive.data_reads.entries()) {\n      if (row?.ordinal !== index + 1) throw Error(\"Recorded DATA ordinal gap or duplicate\");\n      total += data(row).length;\n    }\n    if (total !== count(archive.received_bytes)) throw Error(\"Capture byte total mismatch\");\n    for (const row of archive.data_reads) { signal.throwIfAborted(); yield data(row); }\n    return;\n  }\n  if (!file.name.toLowerCase().endsWith(\".odb-stream\")) throw Error(\"Choose a .bin, .odb-capture or .odb-stream recording\");\n  let header: any, ordinal = 0, total = 0;\n  for await (const line of lines(file, signal)) {\n    const row = JSON.parse(line);\n    if (!header) {\n      if (row?.format !== \"odb-probe-stream/1\") throw Error(\"Invalid stream archive header\");\n      count(row.snapshot_last_ordinal); count(row.stored_bytes);\n      if (row.omitted_bytes !== 0 || row.storage_error !== null) throw Error(\"Recording reports omitted bytes or a storage error\");\n      header = row; continue;\n    }\n    if (row?.ordinal !== ++ordinal || ordinal > header.snapshot_last_ordinal) throw Error(\"Stream ordinal gap, duplicate or trailing record\");\n    if (row.kind === \"data\") { const bytes = data(row); total += bytes.length; yield bytes; }\n    else if (row.kind !== \"journal\" && row.kind !== \"display\") throw Error(\"Unknown stream record kind\");\n  }\n  if (!header || ordinal !== header.snapshot_last_ordinal || total !== header.stored_bytes) throw Error(\"Truncated stream or byte total mismatch\");\n}\n"
  },
  "behavior": "Reads .bin in 64KiB chunks, legacy .odb-capture containers bounded to96MiB, or unbounded-length .odb-stream JSONL with bounded lines. Validates encoding, ordinals and totals. Rejects declared storage losses. Journal/display records never become device commands. File selection is runtime-only, excluded from compositions. The stream provides format candidates, not device identification or acoustic calibration.",
  "ports": {
    "bytes": {
      "direction": "out",
      "kind": "stream",
      "contract": "odb.usb.bytes/1"
    }
  },
  "parameters": {},
  "fixtures": [],
  "evidence": []
}