@sekyro/web 0.1.0-rc.2 → 0.1.0-rc.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/{capture-session-v3-CAoWM8iT.d.cts → capture-session-v3-DEInCOUg.d.cts} +37 -7
  3. package/dist/{capture-session-v3-BJ8ciaWl.d.ts → capture-session-v3-uXJr1Wlm.d.ts} +37 -7
  4. package/dist/{chunk-LOTAJDRE.js → chunk-EWRNPKTR.js} +38 -9
  5. package/dist/chunk-EWRNPKTR.js.map +1 -0
  6. package/dist/{chunk-BPYVZUJA.js → chunk-TBANUT3X.js} +39 -6
  7. package/dist/chunk-TBANUT3X.js.map +1 -0
  8. package/dist/client/index.cjs.map +1 -1
  9. package/dist/client/index.d.cts +1 -1
  10. package/dist/client/index.d.ts +1 -1
  11. package/dist/core/index.cjs +37 -8
  12. package/dist/core/index.cjs.map +1 -1
  13. package/dist/core/index.d.cts +2 -2
  14. package/dist/core/index.d.ts +2 -2
  15. package/dist/core/index.js +1 -1
  16. package/dist/{create-verification-EnZ13uY4.d.cts → create-verification-Ce1y5kJR.d.ts} +26 -3
  17. package/dist/{create-verification-CjLnJ0w6.d.ts → create-verification-Dkb2tXuY.d.cts} +26 -3
  18. package/dist/{hosted-client-BpvBqu9f.d.cts → hosted-client-DWzCRYJK.d.cts} +14 -1
  19. package/dist/{hosted-client-BpvBqu9f.d.ts → hosted-client-DWzCRYJK.d.ts} +14 -1
  20. package/dist/index.cjs +74 -12
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.d.cts +3 -3
  23. package/dist/index.d.ts +3 -3
  24. package/dist/index.js +2 -2
  25. package/dist/internal/index.cjs +74 -12
  26. package/dist/internal/index.cjs.map +1 -1
  27. package/dist/internal/index.d.cts +4 -4
  28. package/dist/internal/index.d.ts +4 -4
  29. package/dist/internal/index.js +2 -2
  30. package/package.json +1 -1
  31. package/dist/chunk-BPYVZUJA.js.map +0 -1
  32. package/dist/chunk-LOTAJDRE.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/doc/doc-catalog.ts","../../src/core/v3/frame-quality.ts","../../src/core/doc/doc-gate-v1.ts","scanic-ml-stub:scanic-ml-stub","../../vendor/scanic/scanic.js","../../src/core/doc/detector-scanic.ts","../../src/internal/index.ts","../../src/core/doc/mrz-band.ts","../../src/core/doc/frame-analysis.ts","../../src/core/doc/feedback-aggregator.ts","../../src/core/media.ts","../../src/core/v3/device-profile.ts","../../src/core/doc/capture-session-doc.ts","../../src/core/capture-constraints.ts","../../src/core/clip-recorder.ts","../../src/core/keyframe.ts","../../src/core/v3/detector-blaze.ts","../../src/core/v3/detector-native.ts","../../src/core/v3/detector.ts","../../src/core/v3/detect-worker.ts","../../src/core/v3/detect-scheduler.ts","../../src/core/v3/face-gate-v3.ts","../../src/core/v3/capture-session-v3.ts","../../src/verification/emitter.ts","../../src/capture/create-liveness-capture.ts","../../src/client/errors.ts","../../src/client/hosted-client.ts","../../src/verification/result.ts","../../src/verification/liveness-flow.ts","../../src/verification/turnstile.ts","../../src/verification/create-verification.ts"],"sourcesContent":["// @sekyro/web/core — MR document catalog (Task 33 / D1 docTypes\n// facet, findings §4 verbatim). Pure DATA the hosted guided scanner reads\n// (which sides to prompt, where the MRZ band sits, portrait side, physical\n// aspect) and Phase 7's capability matrix joins. `docType` strings stay\n// VERBATIM with kyc-docs-v2's `document_type` — the doc executor branches on\n// them, no rename layer. `carte_residence` is intentionally ABSENT (DOC-6:\n// residence permits are out of MVP; the executor fails them `unreadable`).\n\n/** Physical geometry the scanner frames (ISO/IEC 7810 / ICAO 9303). */\nexport type DocFormat = \"ID-1\" | \"ID-3\";\n\nexport type DocSide = \"recto\" | \"verso\" | \"single\";\n\nexport interface DocCatalogEntry {\n /** kyc-docs-v2 `document_type`, verbatim. */\n docType: \"carte_identite\" | \"passport\";\n format: DocFormat;\n /** Capture sequence the hosted doc step walks, in order. */\n sides: readonly DocSide[];\n /** MRZ geometry: td1 = 3×30 (ID-1 verso), td3 = 2×44 (passport data page). */\n mrz: \"none\" | \"td1\" | \"td3\";\n /** Which side carries the holder photo (drives portrait expectations). */\n portraitSide: DocSide;\n /** Physical width/height ratio of the framed page. */\n aspectRatio: number;\n /** Where the subject identifier (NNI) is parsed from, when the doc carries one. */\n identifierSource?: \"mrz\";\n}\n\n/**\n * Plausibility aspect bands per format (Task 34 gate input): ID-1 cards are\n * 85.6×53.98mm → 1.586; an ID-3 passport DATA PAGE frames at ≈125×88mm → 1.42\n * (wider tolerance — page curl and hinge shadow skew the detected quad).\n */\nexport const ASPECT_BANDS: Record<DocFormat, { center: number; tolerance: number }> = {\n \"ID-1\": { center: 1.586, tolerance: 0.15 },\n \"ID-3\": { center: 1.42, tolerance: 0.2 },\n};\n\n/** Aspect band for a format — helper the DocGateV1 plausibility check calls. */\nexport function aspectBand(format: DocFormat): { center: number; tolerance: number } {\n return ASPECT_BANDS[format];\n}\n\n/** The MR docTypes facet (findings §4). Order = the hosted picker's display order. */\nexport const MR_DOC_CATALOG: readonly DocCatalogEntry[] = [\n {\n docType: \"carte_identite\",\n format: \"ID-1\",\n sides: [\"recto\", \"verso\"],\n mrz: \"td1\", // verso; carries the NNI with ICAO check digits (findings §6)\n portraitSide: \"recto\",\n aspectRatio: 1.586,\n identifierSource: \"mrz\",\n },\n {\n docType: \"passport\",\n format: \"ID-3\",\n sides: [\"single\"],\n mrz: \"td3\",\n portraitSide: \"single\", // data page\n aspectRatio: 1.42,\n identifierSource: \"mrz\",\n },\n];\n","// frame-quality (Task 8) — pure, deterministic image measures on a small\n// (≤96px) face crop. No canvas access here: callers hand in ImageData; that\n// keeps these functions golden-testable and worker-portable.\n\n/** Laplacian-variance normalization reference — crops whose edge variance\n * reaches this value (or beyond) count as fully sharp. */\nexport const SHARP_REF = 180;\n\n/** Mean-luma comfort band: inside → exposure 1; outside → linear falloff.\n * Dark bound raised 70→100 (operator ruling 2026-07-07): face crops in the\n * 70–100 range passed the gate but kept drawing dark-face review verdicts —\n * gating them here converts that into pre-capture more_light coaching. */\nexport const EXPOSURE_BAND: readonly [number, number] = [100, 190];\n\n/** Luma distance that zeroes the exposure factor (≈ one stop past the band). */\nconst EXPOSURE_FALLOFF = 64;\n\n/** Rec.601 luma. */\nfunction lumaAt(data: Uint8ClampedArray, index: number): number {\n return (\n 0.299 * (data[index] ?? 0) + 0.587 * (data[index + 1] ?? 0) + 0.114 * (data[index + 2] ?? 0)\n );\n}\n\nexport function meanLuma(image: ImageData): number {\n const { data, width, height } = image;\n const pixels = width * height;\n if (pixels === 0) return 0;\n let sum = 0;\n for (let i = 0; i < pixels; i += 1) sum += lumaAt(data, i * 4);\n return sum / pixels;\n}\n\n/**\n * Sharpness = variance of the 3×3 Laplacian (∇² kernel [0,1,0;1,−4,1;0,1,0])\n * over the interior pixels, normalized 0..1 against SHARP_REF. Flat crop → 0;\n * hard edges → 1 (clamped).\n */\nexport function sharpness(image: ImageData): number {\n const { data, width, height } = image;\n if (width < 3 || height < 3) return 0;\n const gray = new Float32Array(width * height);\n for (let i = 0; i < gray.length; i += 1) gray[i] = lumaAt(data, i * 4);\n let sum = 0;\n let sumSquares = 0;\n let count = 0;\n for (let y = 1; y < height - 1; y += 1) {\n for (let x = 1; x < width - 1; x += 1) {\n const i = y * width + x;\n const response =\n (gray[i - width] ?? 0) +\n (gray[i - 1] ?? 0) +\n (gray[i + 1] ?? 0) +\n (gray[i + width] ?? 0) -\n 4 * (gray[i] ?? 0);\n sum += response;\n sumSquares += response * response;\n count += 1;\n }\n }\n if (count === 0) return 0;\n const mean = sum / count;\n const variance = sumSquares / count - mean * mean;\n // VARIANCE against the reference (the plan's formula). Field lesson\n // (Salem's iPhone, 2026-07-07): sqrt(variance)/REF put every real face\n // crop at ~0.03-0.1 — permanently under the steady_camera threshold and\n // crushing q to zero, so the gate could never fire. Real crops have\n // Laplacian variance well above 180; a genuinely soft/blurred crop does not.\n return Math.min(1, Math.max(0, variance) / SHARP_REF);\n}\n\n/** Exposure factor: 1 inside the band; linear falloff to 0 over\n * EXPOSURE_FALLOFF luma outside it. */\nexport function exposure(image: ImageData): number {\n const mean = meanLuma(image);\n const [low, high] = EXPOSURE_BAND;\n const distance = mean < low ? low - mean : mean > high ? mean - high : 0;\n return Math.max(0, 1 - distance / EXPOSURE_FALLOFF);\n}\n","// DocGateV1 (Task 34) — the document twin of FaceGateV3: plausibility gate\n// (min-area / aspect band / edge-clip) + quality (sharpness/exposure on the\n// quad crop, same frame-quality measures) + an IoU stability streak. The gate\n// NEVER fires on the Task-20 spike's failure modes (too-far/degenerate quad,\n// low-contrast lock, chip-lock, edge-crop) — each yields its taxonomy guidance\n// key (`dcv1.*`) instead, mirroring the face gate's no-luck-firing posture.\n//\n// 100% deterministic: the clock is a tick INPUT (timestampMs); nothing here\n// reads Date.now or performance.now, and detection cost lives OUTSIDE (the\n// session schedules scanic at the device profile's cadence).\nimport { EXPOSURE_BAND } from \"../v3/frame-quality\";\nimport { aspectBand, type DocFormat } from \"./doc-catalog\";\n\n/** Detect-frame width the session downscales to (findings §1: 25ms median).\n * Lives HERE (not detector-scanic.ts) so the session can import it without\n * statically pulling the scanic chunk into host bundles. */\nexport const DOC_DETECT_WIDTH = 480;\n\nexport interface DocQuadPoint {\n x: number;\n y: number;\n}\n\n/** Detected document quad, image-space pixels (scanic CornerPoints shape). */\nexport interface DocQuad {\n topLeft: DocQuadPoint;\n topRight: DocQuadPoint;\n bottomRight: DocQuadPoint;\n bottomLeft: DocQuadPoint;\n}\n\nexport interface DocGateThresholds {\n /** Quad area / frame area below which the doc is too far. */\n MIN_AREA_FRAC: number;\n /** A corner this close to (or past) a frame edge counts as clipped. */\n EDGE_CLIP_MARGIN_PX: number;\n /** Consecutive stable plausible+quality ticks required to fire. */\n STABLE_TICKS: number;\n /** Quad-bbox IoU with the previous tick at/above which the streak holds. */\n IOU_STABLE_MIN: number;\n /** Integrator slopes, per second — mirrors FaceGateV3's gentle drain. */\n RISE_PER_S: number;\n FALL_PER_S: number;\n /** Quality guidance trigger levels (same semantics as the face gate). */\n GUIDE_EXPOSURE: number;\n GUIDE_SHARPNESS: number;\n /** ID-3 (MRZ-band mode): band width / frame width floor. */\n ID3_BAND_MIN_WIDTH_FRAC: number;\n /** ID-3 (MRZ-band mode): band aspect (w/h) sanity bounds. */\n ID3_BAND_ASPECT_MIN: number;\n ID3_BAND_ASPECT_MAX: number;\n}\n\n/** Frozen defaults (plan Task 34 — do not retune without a golden update). */\nexport const DOC_GATE_V1_DEFAULTS: Readonly<DocGateThresholds> = Object.freeze({\n MIN_AREA_FRAC: 0.15,\n EDGE_CLIP_MARGIN_PX: 4,\n STABLE_TICKS: 3,\n IOU_STABLE_MIN: 0.85,\n RISE_PER_S: 0.9,\n FALL_PER_S: 0.25,\n GUIDE_EXPOSURE: 0.6,\n GUIDE_SHARPNESS: 0.35,\n ID3_BAND_MIN_WIDTH_FRAC: 0.55,\n ID3_BAND_ASPECT_MIN: 4,\n ID3_BAND_ASPECT_MAX: 40,\n});\n\nexport interface DocGateQuality {\n /** frame-quality.sharpness on the quad crop. */\n sharpness: number;\n /** frame-quality.exposure on the quad crop. */\n exposure: number;\n /** Mean crop luma — picks more_light vs too_bright. */\n meanLuma: number;\n}\n\nexport interface DocGateTickInput {\n timestampMs: number;\n quad: DocQuad | null;\n quality: DocGateQuality;\n frameWidth: number;\n frameHeight: number;\n}\n\n/** Per-tick output — the scanner chrome contract. */\nexport interface DocGateTick {\n at: number;\n quad: DocQuad | null;\n /** Geometry passed: present × big enough × in frame × right shape. */\n plausible: boolean;\n /** Integrated progress 0..1 (the overlay ring). */\n p: number;\n /** dcv1.* message key (host translates; never prose). */\n guidanceKey: string;\n /** Fire signal: plausible × quality × STABLE_TICKS consecutive high-IoU ticks. */\n ready: boolean;\n /** Current stability streak length (diagnostics/telemetry). */\n stableTicks: number;\n}\n\nconst clamp01 = (value: number) => Math.min(1, Math.max(0, value));\n\n/** Shoelace area of the quad as a fraction of the frame area. */\nexport function quadAreaFrac(quad: DocQuad, frameWidth: number, frameHeight: number): number {\n const pts = [quad.topLeft, quad.topRight, quad.bottomRight, quad.bottomLeft];\n let doubled = 0;\n for (let i = 0; i < 4; i++) {\n const a = pts[i] as DocQuadPoint;\n const b = pts[(i + 1) % 4] as DocQuadPoint;\n doubled += a.x * b.y - b.x * a.y;\n }\n const frameArea = frameWidth * frameHeight;\n return frameArea > 0 ? Math.abs(doubled / 2) / frameArea : 0;\n}\n\n/** IoU of the two quads' axis-aligned bounding boxes (stability metric). */\nexport function quadIou(a: DocQuad, b: DocQuad): number {\n const boxA = bbox(a);\n const boxB = bbox(b);\n const x1 = Math.max(boxA.x1, boxB.x1);\n const y1 = Math.max(boxA.y1, boxB.y1);\n const x2 = Math.min(boxA.x2, boxB.x2);\n const y2 = Math.min(boxA.y2, boxB.y2);\n const inter = Math.max(0, x2 - x1) * Math.max(0, y2 - y1);\n const areaA = (boxA.x2 - boxA.x1) * (boxA.y2 - boxA.y1);\n const areaB = (boxB.x2 - boxB.x1) * (boxB.y2 - boxB.y1);\n const union = areaA + areaB - inter;\n return union > 0 ? inter / union : 0;\n}\n\n/** Axis-aligned bounds (width/height) of a quad — the ID-3 band-mode geometry. */\nexport function quadBounds(quad: DocQuad): { width: number; height: number } {\n const box = bbox(quad);\n return { width: box.x2 - box.x1, height: box.y2 - box.y1 };\n}\n\nfunction bbox(quad: DocQuad): { x1: number; y1: number; x2: number; y2: number } {\n const pts = [quad.topLeft, quad.topRight, quad.bottomRight, quad.bottomLeft];\n return {\n x1: Math.min(...pts.map((p) => p.x)),\n y1: Math.min(...pts.map((p) => p.y)),\n x2: Math.max(...pts.map((p) => p.x)),\n y2: Math.max(...pts.map((p) => p.y)),\n };\n}\n\n/** Orientation-agnostic aspect ratio (longer side pair / shorter side pair). */\nfunction quadAspect(quad: DocQuad): number {\n const top = Math.hypot(quad.topRight.x - quad.topLeft.x, quad.topRight.y - quad.topLeft.y);\n const bottom = Math.hypot(\n quad.bottomRight.x - quad.bottomLeft.x,\n quad.bottomRight.y - quad.bottomLeft.y,\n );\n const left = Math.hypot(quad.bottomLeft.x - quad.topLeft.x, quad.bottomLeft.y - quad.topLeft.y);\n const right = Math.hypot(\n quad.bottomRight.x - quad.topRight.x,\n quad.bottomRight.y - quad.topRight.y,\n );\n const horizontal = (top + bottom) / 2;\n const vertical = (left + right) / 2;\n if (horizontal <= 0 || vertical <= 0) return 0;\n return Math.max(horizontal, vertical) / Math.min(horizontal, vertical);\n}\n\nexport class DocGateV1 {\n private readonly t: DocGateThresholds;\n private readonly format: DocFormat;\n private p = 0;\n private lastTickAt: number | null = null;\n private lastQuad: DocQuad | null = null;\n private streak = 0;\n\n constructor(format: DocFormat, overrides: Partial<DocGateThresholds> = {}) {\n this.format = format;\n this.t = { ...DOC_GATE_V1_DEFAULTS, ...overrides };\n }\n\n reset(): void {\n this.p = 0;\n this.lastTickAt = null;\n this.lastQuad = null;\n this.streak = 0;\n }\n\n tick(input: DocGateTickInput): DocGateTick {\n const { quad, quality, timestampMs } = input;\n const dtSeconds =\n this.lastTickAt === null ? 0 : Math.max(0, (timestampMs - this.lastTickAt) / 1000);\n this.lastTickAt = timestampMs;\n\n // ── plausibility (geometry), taxonomy priority order ─────────────────────\n // ID-3 runs in MRZ-BAND mode (round 3): the \"quad\" is the detected MRZ\n // stroke band's rect — page-edge quads are unreliable on open booklets,\n // so the band IS the passport's detection signal. Geometry checks swap to\n // band semantics (width fraction instead of area; wide-aspect sanity).\n let geometryKey: string | null = null;\n if (quad === null) {\n geometryKey = \"dcv1.no_doc\";\n } else if (this.format === \"ID-3\") {\n const box = quadBounds(quad);\n const aspect = box.height > 0 ? box.width / box.height : 0;\n if (box.width < this.t.ID3_BAND_MIN_WIDTH_FRAC * input.frameWidth) {\n geometryKey = \"dcv1.come_closer\";\n } else if (this.edgeClipped(quad, input.frameWidth, input.frameHeight)) {\n geometryKey = \"dcv1.fit_document\";\n } else if (aspect < this.t.ID3_BAND_ASPECT_MIN || aspect > this.t.ID3_BAND_ASPECT_MAX) {\n geometryKey = \"dcv1.wrong_shape\";\n }\n } else if (quadAreaFrac(quad, input.frameWidth, input.frameHeight) < this.t.MIN_AREA_FRAC) {\n geometryKey = \"dcv1.come_closer\";\n } else if (this.edgeClipped(quad, input.frameWidth, input.frameHeight)) {\n geometryKey = \"dcv1.fit_document\";\n } else {\n const band = aspectBand(this.format);\n const aspect = quadAspect(quad);\n if (Math.abs(aspect - band.center) > band.tolerance) geometryKey = \"dcv1.wrong_shape\";\n }\n const plausible = geometryKey === null;\n\n // ── quality on the quad crop (same measures as the face gate) ────────────\n const exposureOk = clamp01(quality.exposure) >= this.t.GUIDE_EXPOSURE;\n const sharpnessOk = clamp01(quality.sharpness) >= this.t.GUIDE_SHARPNESS;\n const qualityOk = exposureOk && sharpnessOk;\n\n // ── stability streak: consecutive plausible+quality ticks with high IoU ──\n if (plausible && qualityOk && quad !== null) {\n const held = this.lastQuad === null || quadIou(quad, this.lastQuad) >= this.t.IOU_STABLE_MIN;\n this.streak = held ? this.streak + 1 : 1;\n } else {\n this.streak = 0;\n }\n this.lastQuad = quad;\n\n // ── integrator (gentle drain, FaceGateV3 shape) ───────────────────────────\n const good = plausible && qualityOk;\n this.p = clamp01(this.p + (good ? this.t.RISE_PER_S : -this.t.FALL_PER_S) * dtSeconds);\n\n const ready = good && this.streak >= this.t.STABLE_TICKS;\n\n // Guidance: geometry first (taxonomy priority), then light, then blur,\n // then \"hold still\" while the stability streak builds / holds.\n let guidanceKey: string;\n if (geometryKey !== null) {\n guidanceKey = geometryKey;\n } else if (!exposureOk) {\n const bandMid = (EXPOSURE_BAND[0] + EXPOSURE_BAND[1]) / 2;\n guidanceKey = quality.meanLuma < bandMid ? \"dcv1.more_light\" : \"dcv1.too_bright\";\n } else if (!sharpnessOk) {\n guidanceKey = \"dcv1.steady\";\n } else {\n guidanceKey = \"dcv1.hold_still\";\n }\n\n return { at: timestampMs, quad, plausible, p: this.p, guidanceKey, ready, stableTicks: this.streak };\n }\n\n private edgeClipped(quad: DocQuad, frameWidth: number, frameHeight: number): boolean {\n const margin = this.t.EDGE_CLIP_MARGIN_PX;\n const pts = [quad.topLeft, quad.topRight, quad.bottomRight, quad.bottomLeft];\n return pts.some(\n (p) =>\n p.x <= margin ||\n p.y <= margin ||\n p.x >= frameWidth - margin ||\n p.y >= frameHeight - margin,\n );\n }\n}\n","export function initMlDetector(){throw new Error(\"scanic ML detector is not vendored (classical pipeline only)\");}\nexport default {};\n","var A,I=1e3,g=10;function B(A,B={}){const t=B.width||Math.sqrt(A.length),i=B.height||A.length/t,E=void 0!==B.mode?B.mode:1,e=void 0!==B.method?B.method:2,o=B.minArea||I,n=t+2,a=i+2,s=new Int32Array(n*a);for(let I=0;I<i;I++)for(let g=0;g<t;g++)A[I*t+g]>0&&(s[(I+1)*n+(g+1)]=1);const c=[];let r=2;for(let I=1;I<=i;I++)for(let A=1;A<=t;A++){const B=s[I*n+A],t=s[I*n+(A-1)];let i=null,o=!1,h=-1;if(1===B&&0===t?(o=!0,i={x:A,y:I},h=2):0===B&&t>=1&&-1!==t&&1===t&&(o=!1,i={x:A-1,y:I},h=6),i){if(0===E&&!o){s[i.y*n+i.x]=-1;continue}const A=r++,I=C(s,n,a,i,h,A);if(I&&I.length>0){let B=I;2===e&&(B=Q(I));const C=B.map(A=>({x:A.x-1,y:A.y-1}));if(C.length>=(2===e?4:g)){const I={id:A,points:C,isOuter:o};c.push(I)}}else 1===s[i.y*n+i.x]&&(s[i.y*n+i.x]=A)}}c.forEach(A=>{A.area=function(A){let I=0;const g=A.length;if(g<3)return 0;for(let B=0;B<g;B++){const C=(B+1)%g;I+=A[B].x*A[C].y,I-=A[C].x*A[B].y}return Math.abs(I)/2}(A.points),A.boundingBox=function(A){if(0===A.length)return{minX:0,minY:0,maxX:0,maxY:0};let I=A[0].x,g=A[0].y,B=A[0].x,C=A[0].y;for(let Q=1;Q<A.length;Q++){const t=A[Q];I=Math.min(I,t.x),g=Math.min(g,t.y),B=Math.max(B,t.x),C=Math.max(C,t.y)}return{minX:I,minY:g,maxX:B,maxY:C}}(A.points)});const h=c.filter(A=>A.area>=o);return h.sort((A,I)=>I.area-A.area),B.debug&&(B.debug.labels=s,B.debug.rawContours=c,B.debug.finalContours=h),h}function C(A,I,g,B,C,Q){const t=[],i=/* @__PURE__ */new Set;let E=B.x,e=B.y;const o=E,n=e;let a=-1;A[n*I+o]=Q;let s=0;const c=I*g,r=[0,1,1,1,0,-1,-1,-1],h=[-1,-1,0,1,1,1,0,-1];for(;s++<c;){let B;if(-1===a){let Q=!1;for(let t=0;t<8;t++){B=C+t&7;const i=E+r[B],o=e+h[B];if(i>=0&&i<I&&o>=0&&o<g&&A[o*I+i]>0){Q=!0;break}}if(!Q)return null}else B=a+2&7;let s=-1,c=-1;for(let C=0;C<8;C++){const Q=B+C&7,t=E+r[Q],i=e+h[Q];if(t>=0&&t<I&&i>=0&&i<g&&A[i*I+t]>0){s=t,c=i,a=Q+4&7;break}}if(-1===s){0===t.length&&t.push({x:E,y:e});break}const l=e*I+E;if(i.has(l))return t;t.push({x:E,y:e}),i.add(l);const y=c*I+s;if(1===A[y]&&(A[y]=Q),E=s,e=c,E===o&&e===n)break}return s>=c?null:t}function Q(A){const I=A.length;if(I<=2)return A;const g=[],B=A[I-1],C=A[0];let Q=B,t=C,i=A[1],E=t.x-Q.x,e=t.y-Q.y,o=i.x-t.x,n=i.y-t.y;E*n!==e*o&&g.push(t);for(let a=1;a<I-1;a++)Q=A[a-1],t=A[a],i=A[a+1],E=t.x-Q.x,e=t.y-Q.y,o=i.x-t.x,n=i.y-t.y,E*n!==e*o&&g.push(t);if(Q=A[I-2],t=B,i=C,E=t.x-Q.x,e=t.y-Q.y,o=i.x-t.x,n=i.y-t.y,E*n!==e*o&&g.push(t),0===g.length){if(1===I)return[A[0]];if(2===I)return A;let g=0,B=1;const Q=C.x,t=C.y;for(let C=1;C<I;C++){const I=A[C],i=I.x-Q,E=I.y-t,e=i*i+E*E;e>g&&(g=e,B=C)}return[C,A[B]]}return g}function t(A,I=1){if(A.length<=2)return A;let g=0,B=0;const C=A[0],Q=A[A.length-1];for(let t=1;t<A.length-1;t++){const I=i(A[t],C,Q);I>g&&(g=I,B=t)}if(g>I){const g=t(A.slice(0,B+1),I),C=t(A.slice(B),I);return g.slice(0,-1).concat(C)}return[C,Q]}function i(A,I,g){const B=g.x-I.x,C=g.y-I.y,Q=B*B+C*C;if(0===Q)return Math.sqrt(Math.pow(A.x-I.x,2)+Math.pow(A.y-I.y,2));const t=((A.x-I.x)*B+(A.y-I.y)*C)/Q;let i,E;t<0?(i=I.x,E=I.y):t>1?(i=g.x,E=g.y):(i=I.x+t*B,E=I.y+t*C);const e=A.x-i,o=A.y-E;return Math.sqrt(e*e+o*o)}function E(A,I=.02){return t(A,I*function(A){let I=0;const g=A.length;if(g<2)return 0;for(let B=0;B<g;B++){const C=(B+1)%g,Q=A[B].x-A[C].x,t=A[B].y-A[C].y;I+=Math.sqrt(Q*Q+t*t)}return I}(A))}function e(A,I){return Math.hypot(I.x-A.x,I.y-A.y)}function o(A){let I=0,g=0;for(const B of A)I+=B.x,g+=B.y;return{x:I/A.length,y:g/A.length}}function n(A,I={}){if(!A||!A.points||A.points.length<4)return null;const g=I.epsilon||.02,B=function(A,I){if(!A||A.length<4)return null;const g=[I,1.3*I,1.6*I,2*I],B=/* @__PURE__ */new Set;for(const C of g){const I=Math.min(.12,C),g=I.toFixed(4);if(B.has(g))continue;B.add(g);const Q=a(E(A,I));if(Q&&4===Q.length)return Q}return null}(A.points,g);let C;return B&&4===B.length?C=function(A){if(4!==A.length)return null;const I=o(A),g=[...A].sort((A,g)=>Math.atan2(A.y-I.y,A.x-I.x)-Math.atan2(g.y-I.y,g.x-I.x));let B=1/0,C=0;for(let t=0;t<4;t++){const A=g[t].x+g[t].y;A<B&&(B=A,C=t)}const Q=[g[C],g[(C+1)%4],g[(C+2)%4],g[(C+3)%4]];return{topLeft:Q[0],topRight:Q[1],bottomRight:Q[2],bottomLeft:Q[3]}}(B):(C=function(A){if(!A||A.length<4)return null;const I=o(A);let g=null,B=null,C=null,Q=null,t=0,i=0,E=0,n=0;for(const o of A){const A=e(o,I);o.x<I.x&&o.y<I.y?A>t&&(g=o,t=A):o.x>I.x&&o.y<I.y?A>i&&(B=o,i=A):o.x>I.x&&o.y>I.y?A>E&&(C=o,E=A):o.x<I.x&&o.y>I.y&&A>n&&(Q=o,n=A)}return g&&B&&C&&Q?{topLeft:g,topRight:B,bottomRight:C,bottomLeft:Q}:null}(A.points),C&&C.topLeft&&C.topRight&&C.bottomRight&&C.bottomLeft||(C=function(A){if(!A||0===A.length)return null;let I=A[0],g=A[0],B=A[0],C=A[0],Q=I.x+I.y,t=g.x-g.y,i=B.x+B.y,E=C.x-C.y;for(let e=1;e<A.length;e++){const o=A[e],n=o.x+o.y,a=o.x-o.y;n<Q&&(Q=n,I=o),n>i&&(i=n,B=o),a>t&&(t=a,g=o),a<E&&(E=a,C=o)}return{topLeft:I,topRight:g,bottomRight:B,bottomLeft:C}}(A.points))),C&&C.topLeft&&C.topRight&&C.bottomRight&&C.bottomLeft?C:null}function a(A){if(!A||A.length<4)return null;if(4===A.length)return A;if(A.length>8)return null;let I=function(A,I){if(!A||0===A.length)return[];const g=[];for(const B of A)(0===g.length||e(B,g[g.length-1])>I)&&g.push(B);g.length>2&&e(g[0],g[g.length-1])<=I&&g.pop();return g}(A,6);return 4===I.length?I:(I.length,null)}var s=null;function c(){return null!==s&&0!==s.byteLength||(s=new Uint8Array(A.memory.buffer)),s}var r=0;function h(A,I){const g=I(1*A.length,1)>>>0;return c().set(A,g/1),r=A.length,g}function l(A,I){return A>>>=0,c().subarray(A/1,A/1+I)}var y=null;function D(){return null!==y&&0!==y.byteLength||(y=new Float32Array(A.memory.buffer)),y}function w(I,g,B,C,Q){const t=function(A,I){const g=I(4*A.length,4)>>>0;return D().set(A,g/4),r=A.length,g}(I,A.__wbindgen_malloc),i=r,E=A.hysteresis_thresholding(t,i,g,B,C,Q);var e=l(E[0],E[1]).slice();return A.__wbindgen_free(E[0],1*E[1],1),e}var d=null;function f(I,g){const B=g(2*I.length,2)>>>0;return(null!==d&&0!==d.byteLength||(d=new Uint16Array(A.memory.buffer)),d).set(I,B/2),r=I.length,B}function u(I,g,B,C,Q){const t=f(I,A.__wbindgen_malloc),i=r,E=f(g,A.__wbindgen_malloc),e=r,o=A.non_maximum_suppression(t,i,E,e,B,C,Q);var n,a,s=(n=o[0],a=o[1],n>>>=0,D().subarray(n/4,n/4+a)).slice();return A.__wbindgen_free(o[0],4*o[1],4),s}async function m(I){if(void 0!==A)return A;if(void 0!==I&&Object.getPrototypeOf(I)===Object.prototype&&({module_or_path:I}=I),void 0===I)throw new Error(\"scanic: WASM module bytes must be passed to init().\");const g=function(){const I={wbg:{}};return I.wbg.__wbindgen_init_externref_table=function(){const I=A.__wbindgen_export_0,g=I.grow(4);I.set(0,void 0),I.set(g+0,void 0),I.set(g+1,null),I.set(g+2,!0),I.set(g+3,!1)},I}();(\"string\"==typeof I||\"function\"==typeof Request&&I instanceof Request||\"function\"==typeof URL&&I instanceof URL)&&(I=fetch(I));const{instance:B,module:C}=await async function(A,I){if(\"function\"==typeof Response&&A instanceof Response){if(\"function\"==typeof WebAssembly.instantiateStreaming)try{return await WebAssembly.instantiateStreaming(A,I)}catch(g){if(\"application/wasm\"==A.headers.get(\"Content-Type\"))throw g}const B=await A.arrayBuffer();return await WebAssembly.instantiate(B,I)}{const g=await WebAssembly.instantiate(A,I);return g instanceof WebAssembly.Instance?{instance:g,module:A}:g}}(await I,g);return function(I,g){return A=I.exports,m.__wbindgen_wasm_module=g,y=null,d=null,s=null,A.__wbindgen_start(),A}(B,C)}var N=null,R=!1,p=null;function F(A){if(\"function\"==typeof atob){const I=atob(A),g=new Uint8Array(I.length);for(let A=0;A<I.length;A++)g[A]=I.charCodeAt(A);return g}return Uint8Array.from(Buffer.from(A,\"base64\"))}async function J(){if(!function(){if(null!==p)return p;let A=!1;if(\"object\"==typeof WebAssembly&&\"function\"==typeof WebAssembly.validate){const I=new Uint8Array([0,97,115,109,1,0,0,0,1,5,1,96,0,1,123,3,2,1,0,10,10,1,8,0,65,0,253,15,253,98,11]),g=new Uint8Array([0,97,115,109,1,0,0,0,1,5,1,96,0,1,111,3,2,1,0,10,6,1,4,0,208,111,11]);try{A=WebAssembly.validate(I)&&WebAssembly.validate(g)}catch{A=!1}}return p=A,A}())throw new Error(\"scanic: WebAssembly features required by the WASM module (reference-types, SIMD) are unavailable in this engine; using the JavaScript fallback.\");return await m({module_or_path:F(\"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JAAgAiABIAJqIgFLBEBBAEEAEC0ACyADQQRqIAAoAgAiAiAAKAIEQQggASACQQF0IgIgASACSxsiASABQQhNGyIBQQFBARARIAMoAgRBAUYEQCADKAIIIAMoAgwQLQALIAMoAgghAiAAIAE2AgAgACACNgIEIANBEGokAAt5AQF/IwBBIGsiAiQAAn8gACgCAEGAgICAeEcEQCABIAAoAgQgACgCCBAwDAELIAJBEGogACgCDCgCACIAQQhqKQIANwMAIAJBGGogAEEQaikCADcDACACIAApAgA3AwggASgCACABKAIEIAJBCGoQBwsgAkEgaiQAC2kBA38jAEEQayIBJAAgAUEEaiAAKAIAIgIgACgCBEEEIAJBAXQiAiACQQRNGyICQQRBBBARIAEoAgRBAUYEQCABKAIIIAEoAgwQLQALIAEoAgghAyAAIAI2AgAgACADNgIEIAFBEGokAAtpAQN/IwBBEGsiASQAIAFBBGogACgCACICIAAoAgRBBCACQQF0IgIgAkEETRsiAkEEQQgQESABKAIEQQFGBEAgASgCCCABKAIMEC0ACyABKAIIIQMgACACNgIAIAAgAzYCBCABQRBqJAALaQEDfyMAQRBrIgEkACABQQRqIAAoAgAiAiAAKAIEQQQgAkEBdCICIAJBBE0bIgJBAkECEBEgASgCBEEBRgRAIAEoAgggASgCDBAtAAsgASgCCCEDIAAgAjYCACAAIAM2AgQgAUEQaiQACxIAIwBBMGsiACQAIABBMGokAAtoAgF/AX4jAEEwayIDJAAgAyABNgIEIAMgADYCACADQQI2AgwgA0Hkl8AANgIIIANCAjcCFCADQoCAgIAwIgQgA62ENwMoIAMgBCADQQRqrYQ3AyAgAyADQSBqNgIQIANBCGogAhAmAAtHAQF/IAAoAgAgACgCCCIDayACSQRAIAAgAyACEBIgACgCCCEDCyACBEAgACgCBCADaiABIAL8CgAACyAAIAIgA2o2AghBAAtEAQJ/IAEoAgQhAiABKAIAIQNBCEEEEDUiAUUEQEEEQQgQOQALIAEgAjYCBCABIAM2AgAgAEHcksAANgIEIAAgATYCAAvGAgACQCAAIAJNBEAgACABTSABIAJLcg0BIwBBMGsiAiQAIAIgATYCBCACIAA2AgAgAkECNgIMIAJB2JbAADYCCCACQgI3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IAAAABwAEAAMAAAAEgAAABcAAAAcABAADAAAABcAAAAZAAAAHAAQAAwAAAAUAAAAGQAAABwAEAAMAAAAUQAAAB4AAAAcABAADAAAAFIAAAAeAAAATGF6eSBpbnN0YW5jZSBoYXMgcHJldmlvdXNseSBiZWVuIHBvaXNvbmVkAAA8CBAAKgAAAEgBEABaAAAACAMAABkAAAByZWVudHJhbnQgaW5pdAAAgAgQAA4AAABIARAAWgAAAHoCAAANAAAAfP2LMlfmV/kC30S/40jnr21dy9YsUOtjeEGmV3Ebi7ltZW1vcnkgYWxsb2NhdGlvbiBvZiAgYnl0ZXMgZmFpbGVkAADICBAAFQAAAN0IEAANAAAALwEQABgAAABkAQAACQAAAAQAAAAMAAAABAAAAAUAAAAGAAAABwAAAAAAAAAIAAAABAAAAAgAAAAJAAAACgAAAAsAAAAMAAAAEAAAAAQAAAANAAAADgAAAA8AAAAQAAAAAAAAAAgAAAAEAAAAEQAAAGFzc2VydGlvbiBmYWlsZWQ6IHBzaXplID49IHNpemUgKyBtaW5fb3ZlcmhlYWQAAAQBEAAqAAAAsQQAAAkAAABhc3NlcnRpb24gZmFpbGVkOiBwc2l6ZSA8PSBzaXplICsgbWF4X292ZXJoZWFkAAAEARAAKgAAALcEAAANAAAABAAAAAwAAAAEAAAAEgAAAGNhcGFjaXR5IG92ZXJmbG93AAAA/AkQABEAAADjABAAIAAAABwAAAAFAAAAMDAwMTAyMDMwNDA1MDYwNzA4MDkxMDExMTIxMzE0MTUxNjE3MTgxOTIwMjEyMjIzMjQyNTI2MjcyODI5MzAzMTMyMzMzNDM1MzYzNzM4Mzk0MDQxNDI0MzQ0NDU0NjQ3NDg0OTUwNTE1MjUzNTQ1NTU2NTc1ODU5NjA2MTYyNjM2NDY1NjY2NzY4Njk3MDcxNzI3Mzc0NzU3Njc3Nzg3OTgwODE4MjgzODQ4NTg2ODc4ODg5OTA5MTkyOTM5NDk1OTY5Nzk4OTlyYW5nZSBlbmQgaW5kZXggIG91dCBvZiByYW5nZSBmb3Igc2xpY2Ugb2YgbGVuZ3RoIAAA8AoQABAAAAAACxAAIgAAAHNsaWNlIGluZGV4IHN0YXJ0cyBhdCAgYnV0IGVuZHMgYXQgADQLEAAWAAAASgsQAA0AAAByYW5nZSBzdGFydCBpbmRleCAAAGgLEAASAAAAAAsQACIAAABhdHRlbXB0IHRvIGRpdmlkZSBieSB6ZXJvAAAAjAsQABkAAABpbmRleCBvdXQgb2YgYm91bmRzOiB0aGUgbGVuIGlzICBidXQgdGhlIGluZGV4IGlzIAAAsAsQACAAAADQCxAAEgAAAAAAAD8AAAC/AEGUmMAACwEBAHwJcHJvZHVjZXJzAghsYW5ndWFnZQEEUnVzdAAMcHJvY2Vzc2VkLWJ5AwVydXN0Yx0xLjkyLjAgKGRlZDVjMDZjZiAyMDI1LTEyLTA4KQZ3YWxydXMGMC4yMy4zDHdhc20tYmluZGdlbhMwLjIuMTAwICgyNDA1ZWMyYjQpAHQPdGFyZ2V0X2ZlYXR1cmVzBysPbXV0YWJsZS1nbG9iYWxzKxNub250cmFwcGluZy1mcHRvaW50KwdzaW1kMTI4KwtidWxrLW1lbW9yeSsIc2lnbi1leHQrD3JlZmVyZW5jZS10eXBlcysKbXVsdGl2YWx1ZQ==\")})}function G(){return N||(N=J().catch(A=>{throw N=null,A})),N}function k(A,I,g,B=5,C=0){0===C&&(C=.3*(.5*(B-1)-1)+.8);const Q=Math.floor(B/2),t=function(A,I){const g=new Float32Array(A),B=Math.floor(A/2);let C=0;for(let Q=0;Q<A;Q++){const A=Q-B;g[Q]=Math.exp(-A*A/(2*I*I)),C+=g[Q]}for(let Q=0;Q<A;Q++)g[Q]/=C;return g}(B,C),i=new Uint8ClampedArray(I*g),E=new Uint8ClampedArray(I*g);for(let e=0;e<g;e++){const g=e*I;for(let B=0;B<I;B++){let C=0;for(let i=-Q;i<=Q;i++){C+=A[g+Math.min(I-1,Math.max(0,B+i))]*t[Q+i]}i[g+B]=C}}for(let e=0;e<I;e++)for(let A=0;A<g;A++){let B=0;for(let C=-Q;C<=Q;C++){B+=i[Math.min(g-1,Math.max(0,A+C))*I+e]*t[Q+C]}E[A*I+e]=Math.round(B)}return E}function S(A,I,g,B,C){const Q=new Uint8Array(I*g),t=[];for(let e=1;e<g-1;e++)for(let g=1;g<I-1;g++){const i=e*I+g,E=A[i];E>=C?(Q[i]=2,t.push({x:g,y:e})):Q[i]=E>=B?0:1}for(let e=0;e<I;e++)Q[e]=1,Q[(g-1)*I+e]=1;for(let e=1;e<g-1;e++)Q[e*I]=1,Q[e*I+I-1]=1;const i=[-1,0,1,-1,1,-1,0,1],E=[-1,-1,-1,0,0,1,1,1];for(;t.length>0;){const{x:A,y:g}=t.pop();for(let B=0;B<8;B++){const C=A+i[B],e=g+E[B],o=e*I+C;0===Q[o]&&(Q[o]=2,t.push({x:C,y:e}))}}return Q}async function M(I,g={}){const B=!(!g.debug||g.debug._timingsOnly),C=[],Q=performance.now();let t,i,E;if(g.skipGrayscale||!1)t=g.width,i=g.height,E=I,B&&(g.debug.grayscale=E);else{t=I.width,i=I.height;let A=performance.now();E=function(A){const{width:I,height:g,data:B}=A,C=new Uint8ClampedArray(I*g);for(let Q=0,t=0;Q<B.length;Q+=4,t++)C[t]=54*B[Q]+183*B[Q+1]+19*B[Q+2]>>8;return C}(I);let Q=performance.now();C.push({step:\"Grayscale\",ms:(Q-A).toFixed(2)}),B&&(g.debug.grayscale=E)}let e=void 0!==g.lowThreshold?g.lowThreshold:null,o=void 0!==g.highThreshold?g.highThreshold:null;if(null===e||null===o){const A=1024,I=new Uint32Array(A);let g=0;for(let e=1;e<i-1;e++)for(let B=1;B<t-1;B++){const C=e*t+B,Q=-E[C-t-1]+E[C-t+1]-2*E[C-1]+2*E[C+1]-E[C+t-1]+E[C+t+1],i=-E[C-t-1]-2*E[C-t]-E[C-t+1]+E[C+t-1]+2*E[C+t]+E[C+t+1];let o=Math.abs(Q)+Math.abs(i);o>=A&&(o=A-1),o>0&&(I[o]++,g++)}const B=Math.round(.7*g);let C=0,Q=75;for(let t=1;t<A;t++)if(C+=I[t],C>=B){Q=t;break}null===e&&(e=Math.max(5,Math.round(.5*Q))),null===o&&(o=Math.min(500,Math.round(1.5*Q)))}const n=g.kernelSize||5,a=g.sigma||0,s=void 0!==g.L2gradient&&g.L2gradient,c=void 0===g.applyDilation||g.applyDilation,y=g.dilationKernelSize||5,D=void 0!==g.useWasmHysteresis&&g.useWasmHysteresis,d=void 0!==g.useWasmFullCanny&&g.useWasmFullCanny;if(e>=o&&([e,o]=[o,e]),d)try{await G();const I=performance.now(),D=new Uint8ClampedArray(function(I,g,B,C,Q,t,i,E,e,o){const n=h(I,A.__wbindgen_malloc),a=r,s=A.canny_edge_detector_full(n,a,g,B,C,Q,t,i,E,e,o);var c=l(s[0],s[1]).slice();return A.__wbindgen_free(s[0],1*s[1],1),c}(E,t,i,e,o,n,a,s,c,y)),w=(performance.now()-I).toFixed(2);C.push({step:\"Edge Processing (WASM)\",ms:w}),B&&(g.debug.finalEdges=D),g.debug?g.debug.timings=C:g.debug={timings:C};const d=performance.now();return C.unshift({step:\"Edge Detection Total\",ms:(d-Q).toFixed(2)}),D}catch(Y){if(!R){R=!0;Y instanceof Error?Y.message:String(Y)}}let f,m,N,p,F,J;f=performance.now();try{await G(),N=function(I,g,B,C,Q){const t=h(I,A.__wbindgen_malloc),i=r,E=A.blur(t,i,g,B,C,Q);var e=l(E[0],E[1]).slice();return A.__wbindgen_free(E[0],1*E[1],1),e}(E,t,i,n,a)}catch{N=k(E,t,i,n,a)}m=performance.now(),C.push({step:\"Gaussian Blur\",ms:(m-f).toFixed(2)}),B&&(g.debug.blurred=N),f=performance.now();{const A=function(A,I,g){const B=new Int16Array(I*g),C=new Int16Array(I*g);for(let Q=1;Q<g-1;Q++){const g=Q*I,t=(Q-1)*I,i=(Q+1)*I;for(let Q=1;Q<I-1;Q++){const I=g+Q,E=A[t+Q-1],e=A[t+Q],o=A[t+Q+1],n=A[g+Q-1],a=A[g+Q+1],s=A[i+Q-1],c=A[i+Q],r=A[i+Q+1],h=o-E+2*(a-n)+(r-s),l=s+2*c+r-(E+2*e+o);B[I]=h,C[I]=l}}return{dx:B,dy:C}}(N,t,i);p=A.dx,F=A.dy}m=performance.now(),C.push({step:\"Gradients\",ms:(m-f).toFixed(2)}),f=performance.now();try{await G(),J=await u(p,F,t,i,s)}catch{J=function(A,I,g,B,C){const Q=new Float32Array(g*B),t=new Float32Array(g*B);for(let i=0;i<A.length;i++){const g=A[i],B=I[i];Q[i]=C?Math.sqrt(g*g+B*B):Math.abs(g)+Math.abs(B)}for(let i=1;i<B-1;i++)for(let B=1;B<g-1;B++){const C=i*g+B,E=Q[C];if(0===E){t[C]=0;continue}const e=A[C],o=I[C];let n=0,a=0;const s=Math.abs(e),c=Math.abs(o);if(c>2.4142*s)n=Q[C-g],a=Q[C+g];else if(s>2.4142*c)n=Q[C-1],a=Q[C+1];else{const A=(e^o)<0?-1:1;o>0?(n=Q[(i-1)*g+(B-A)],a=Q[(i+1)*g+(B+A)]):(n=Q[(i+1)*g+(B-A)],a=Q[(i-1)*g+(B+A)]),e>0&&o>0||e<0&&o<0?(n=Q[(i-1)*g+(B+1)],a=Q[(i+1)*g+(B-1)]):(n=Q[(i-1)*g+(B-1)],a=Q[(i+1)*g+(B+1)])}t[C]=E>=n&&E>=a?E:0}return t}(p,F,t,i,s)}m=performance.now(),C.push({step:\"Non-Max Suppression\",ms:(m-f).toFixed(2)}),f=performance.now();const M=s?e*e:e,b=s?o*o:o;let L;if(D)try{await G(),L=w(J,t,i,M,b)}catch(q){L=S(J,t,i,M,b)}else L=S(J,t,i,M,b);m=performance.now(),C.push({step:\"Hysteresis\",ms:(m-f).toFixed(2)}),f=performance.now();const x=new Uint8ClampedArray(t*i);for(let A=0;A<L.length;A++)x[A]=2===L[A]?255:0;m=performance.now(),C.push({step:\"Binary Image\",ms:(m-f).toFixed(2)}),f=performance.now();let U=x;if(c)try{await G(),U=function(I,g,B,C){const Q=h(I,A.__wbindgen_malloc),t=r,i=A.dilate(Q,t,g,B,C);var E=l(i[0],i[1]).slice();return A.__wbindgen_free(i[0],1*i[1],1),E}(x,t,i,y)}catch{U=function(A,I,g,B=5){const C=Math.floor(B/2),Q=new Uint8ClampedArray(I*g),t=new Uint8ClampedArray(I*g);for(let i=0;i<g;i++){const g=i*I;for(let B=0;B<I;B++){let t=0;for(let Q=-C;Q<=C;Q++){const C=B+Q;if(C>=0&&C<I){const I=A[g+C];I>t&&(t=I)}}Q[g+B]=t}}for(let i=0;i<I;i++)for(let A=0;A<g;A++){let B=0;for(let t=-C;t<=C;t++){const C=A+t;if(C>=0&&C<g){const A=Q[C*I+i];A>B&&(B=A)}}t[A*I+i]=B}return t}(x,t,i,y)}if(m=performance.now(),C.push({step:\"Dilation\",ms:(m-f).toFixed(2)}),B){g.debug.dx=p,g.debug.dy=F;const A=new Float32Array(t*i);for(let I=0;I<p.length;I++){const g=p[I],B=F[I];A[I]=s?Math.sqrt(g*g+B*B):Math.abs(g)+Math.abs(B)}g.debug.magnitude=A,g.debug.suppressed=J,g.debug.edgeMap=L,g.debug.cannyEdges=x,g.debug.finalEdges=U}g.debug?g.debug.timings=C:g.debug||(g.debug={timings:C});const H=performance.now();return C.unshift({step:\"Edge Detection Total\",ms:(H-Q).toFixed(2)}),U}function b(A){return{topLeft:{x:A.topLeft.x,y:A.topLeft.y},topRight:{x:A.topRight.x,y:A.topRight.y},bottomRight:{x:A.bottomRight.x,y:A.bottomRight.y},bottomLeft:{x:A.bottomLeft.x,y:A.bottomLeft.y}}}function L(A,I){return Math.hypot(A.x-I.x,A.y-I.y)}function x(A,I=4){const g=[A?.topLeft,A?.topRight,A?.bottomRight,A?.bottomLeft];if(g.some(A=>!A||!Number.isFinite(A.x)||!Number.isFinite(A.y)))return!1;for(let B=0;B<g.length;B++)for(let A=B+1;A<g.length;A++)if(L(g[B],g[A])<I)return!1;return!0}function U(A){const I=[A.topLeft,A.topRight,A.bottomRight,A.bottomLeft],g=[];for(let C=0;C<I.length;C++){const A=I[C],B=I[(C+1)%I.length],Q=I[(C+2)%I.length],t=(B.x-A.x)*(Q.y-B.y)-(B.y-A.y)*(Q.x-B.x);Math.abs(t)<1e-6||g.push(Math.sign(t))}if(g.length<3)return!1;const B=g[0];return g.every(A=>A===B)}var H=\"scanic-corner-editor-styles\",Y='<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"3 4 3 10 9 10\"/><path d=\"M3.5 14a8.5 8.5 0 1 0 2-7.4L3 10\"/></svg>',q='<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/></svg>',v='<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"/></svg>',K='<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"4\" y1=\"21\" x2=\"4\" y2=\"14\"/><line x1=\"4\" y1=\"10\" x2=\"4\" y2=\"3\"/><line x1=\"12\" y1=\"21\" x2=\"12\" y2=\"12\"/><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"3\"/><line x1=\"20\" y1=\"21\" x2=\"20\" y2=\"16\"/><line x1=\"20\" y1=\"12\" x2=\"20\" y2=\"3\"/><line x1=\"1\" y1=\"14\" x2=\"7\" y2=\"14\"/><line x1=\"9\" y1=\"8\" x2=\"15\" y2=\"8\"/><line x1=\"17\" y1=\"16\" x2=\"23\" y2=\"16\"/></svg>';function T(A={}){const I=A.container;if(!I||\"function\"!=typeof I.appendChild)throw new Error(\"createCornerEditor requires a valid container element\");const g=I.ownerDocument||(\"undefined\"!=typeof document?document:null),B=\"undefined\"!=typeof window?window:globalThis,C=()=>B.performance&&\"function\"==typeof B.performance.now?B.performance.now():Date.now();!1!==A.injectStyles&&function(A){if(!A||\"function\"!=typeof A.getElementById)return;if(A.getElementById(H))return;const I=A.createElement(\"style\");I.id=H,I.textContent=\"\\n.scanic-corner-editor {\\n --scanic-accent: #6366f1;\\n --scanic-mask: rgba(15, 23, 42, 0.45);\\n --scanic-edge-color: var(--scanic-accent);\\n --scanic-edge-width: 2.5;\\n --scanic-handle-size: 20px;\\n --scanic-handle-hit: 44px;\\n --scanic-handle-color: #ffffff;\\n --scanic-handle-ring: 2px;\\n --scanic-handle-ring-color: var(--scanic-accent);\\n --scanic-handle-shadow: 0 1px 4px rgba(15, 23, 42, 0.45);\\n --scanic-handle-active-shadow: 0 8px 22px rgba(15, 23, 42, 0.5);\\n --scanic-handle-active-scale: 1.28;\\n --scanic-surface: rgba(15, 23, 42, 0.92);\\n --scanic-surface-fg: #e2e8f0;\\n --scanic-surface-radius: 12px;\\n}\\n.scanic-handle {\\n position: absolute;\\n box-sizing: border-box;\\n width: var(--scanic-handle-size);\\n height: var(--scanic-handle-size);\\n margin: 0;\\n padding: 0;\\n border: var(--scanic-handle-ring) solid var(--scanic-handle-ring-color);\\n border-radius: 50%;\\n background: var(--scanic-handle-color);\\n box-shadow: var(--scanic-handle-shadow);\\n transform: translate(-50%, -50%);\\n cursor: grab;\\n touch-action: none;\\n z-index: 2;\\n transition: transform 0.12s ease, box-shadow 0.12s ease,\\n background 0.12s ease, border-color 0.12s ease;\\n}\\n/* Enlarges the pointer/touch target without changing the visual size. */\\n.scanic-handle::after {\\n content: '';\\n position: absolute;\\n left: 50%;\\n top: 50%;\\n width: var(--scanic-handle-hit);\\n height: var(--scanic-handle-hit);\\n transform: translate(-50%, -50%);\\n border-radius: 50%;\\n}\\n/* Soft accent halo that blooms when a handle is grabbed. This is the \\\"depth\\\" layer. */\\n.scanic-handle::before {\\n content: '';\\n position: absolute;\\n left: 50%;\\n top: 50%;\\n width: 0;\\n height: 0;\\n border-radius: 50%;\\n background: var(--scanic-accent);\\n opacity: 0;\\n transform: translate(-50%, -50%);\\n transition: opacity 0.15s ease, width 0.15s ease, height 0.15s ease;\\n pointer-events: none;\\n}\\n.scanic-handle:hover {\\n transform: translate(-50%, -50%) scale(1.12);\\n}\\n.scanic-handle:focus-visible {\\n outline: none;\\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--scanic-accent) 45%, transparent),\\n var(--scanic-handle-shadow);\\n}\\n/* The currently selected corner: the target of nudges / keyboard. */\\n.scanic-handle.is-selected {\\n border-color: var(--scanic-accent);\\n transform: translate(-50%, -50%) scale(1.12);\\n}\\n.scanic-handle.is-selected::before {\\n opacity: 0.16;\\n width: calc(var(--scanic-handle-size) * 2);\\n height: calc(var(--scanic-handle-size) * 2);\\n}\\n.scanic-handle.is-active {\\n cursor: grabbing;\\n background: var(--scanic-accent);\\n border-color: #ffffff;\\n transform: translate(-50%, -50%) scale(var(--scanic-handle-active-scale));\\n box-shadow: var(--scanic-handle-active-shadow);\\n}\\n.scanic-handle.is-active::before {\\n opacity: 0.22;\\n width: calc(var(--scanic-handle-size) * 2.8);\\n height: calc(var(--scanic-handle-size) * 2.8);\\n}\\n.scanic-toolbar,\\n.scanic-nudges {\\n position: absolute;\\n z-index: 3;\\n display: flex;\\n gap: 4px;\\n padding: 5px;\\n background: var(--scanic-surface);\\n border-radius: var(--scanic-surface-radius);\\n -webkit-backdrop-filter: blur(8px);\\n backdrop-filter: blur(8px);\\n box-shadow: 0 6px 20px rgba(15, 23, 42, 0.35);\\n}\\n.scanic-toolbar {\\n left: 50%;\\n bottom: 12px;\\n transform: translateX(-50%);\\n}\\n.scanic-nudges {\\n top: 10px;\\n right: 10px;\\n display: grid;\\n grid-template-columns: repeat(4, auto);\\n gap: 3px;\\n}\\n.scanic-toolbar button,\\n.scanic-nudges button {\\n display: grid;\\n place-items: center;\\n margin: 0;\\n padding: 0;\\n font-family: inherit;\\n font-size: 15px;\\n font-weight: 600;\\n line-height: 1;\\n color: var(--scanic-surface-fg);\\n background: transparent;\\n border: 0;\\n border-radius: 8px;\\n cursor: pointer;\\n transition: background 0.12s ease, color 0.12s ease, filter 0.12s ease;\\n}\\n.scanic-toolbar button {\\n width: 34px;\\n height: 34px;\\n}\\n.scanic-nudges button {\\n width: 30px;\\n height: 30px;\\n}\\n.scanic-toolbar button svg {\\n width: 18px;\\n height: 18px;\\n display: block;\\n}\\n.scanic-toolbar button:hover,\\n.scanic-nudges button:hover {\\n background: rgba(255, 255, 255, 0.14);\\n}\\n.scanic-toolbar button:focus-visible,\\n.scanic-nudges button:focus-visible {\\n outline: 2px solid var(--scanic-accent);\\n outline-offset: 1px;\\n}\\n.scanic-toolbar .scanic-btn-apply {\\n background: var(--scanic-accent);\\n color: #ffffff;\\n}\\n.scanic-toolbar .scanic-btn-apply:hover {\\n background: var(--scanic-accent);\\n filter: brightness(1.1);\\n}\\n.scanic-toolbar .scanic-btn-expert.is-on {\\n background: color-mix(in srgb, var(--scanic-accent) 32%, transparent);\\n color: #ffffff;\\n}\\n\",(A.head||A.documentElement).appendChild(I)}(g);const{canvas:Q,width:t,height:i}=function(A){if(!A)throw new Error(\"No image provided\");const I=A&&\"number\"==typeof A.width&&\"number\"==typeof A.height&&A.data;let g=0,B=0;if(I?(g=A.width,B=A.height):(g=A.width||A.naturalWidth,B=A.height||A.naturalHeight),!g||!B)throw new Error(\"Image must be loaded before creating the corner editor\");const C=document.createElement(\"canvas\");C.width=g,C.height=B;const Q=C.getContext(\"2d\",{willReadFrequently:!0});if(!Q)throw new Error(\"Failed to create 2D canvas context for source image\");return I?Q.putImageData(A,0,0):Q.drawImage(A,0,0,g,B),{canvas:C,width:g,height:B}}(A.image),E=!I.classList.contains(\"scanic-corner-editor\");I.classList.add(\"scanic-corner-editor\"),A.classNames?.root&&I.classList.add(A.classNames.root);const e={position:I.style.position,minHeight:I.style.minHeight};let o=!1,n=!1;\"static\"===getComputedStyle(I).position&&(I.style.position=\"relative\",o=!0),P(A.theme);const a=g.createElement(\"canvas\");a.style.position=\"absolute\",a.style.top=\"0\",a.style.left=\"0\",a.style.display=\"block\",a.style.touchAction=\"none\",a.style.userSelect=\"none\",a.style.webkitUserSelect=\"none\",a.style.cursor=\"default\",I.appendChild(a);const s=a.getContext(\"2d\");if(!s)throw new Error(\"Failed to create 2D canvas context for corner editor\");const c={enabled:!1!==A.magnifier?.enabled,size:A.magnifier?.size||120,zoom:A.magnifier?.zoom||2,margin:A.magnifier?.margin||8,borderColor:A.magnifier?.borderColor||\"#ffffff\",borderWidth:A.magnifier?.borderWidth||2,crosshairColor:A.magnifier?.crosshairColor||\"#ffffff\",crosshairSize:A.magnifier?.crosshairSize||18},r={enabled:!!A.nudges?.enabled,steps:(A.nudges?.steps&&A.nudges.steps.length?A.nudges.steps:[1,10]).map(A=>Math.max(1,Math.round(A)))},h={enabled:!1!==A.toolbar?.enabled,reset:!1!==A.toolbar?.reset,cancel:!1!==A.toolbar?.cancel,apply:!1!==A.toolbar?.apply,labels:{reset:A.toolbar?.labels?.reset||\"Reset\",cancel:A.toolbar?.labels?.cancel||\"Cancel\",apply:A.toolbar?.labels?.apply||\"Apply\"}},l=!1!==A.keyboard,y=function(A,I,g=.08){const B=Math.max(8,Math.min(A,I)*g);return{topLeft:{x:B,y:B},topRight:{x:A-B,y:B},bottomRight:{x:A-B,y:I-B},bottomLeft:{x:B,y:I-B}}}(t,i),D=A.corners?b(A.corners):y;let w=x(D)&&U(D)?D:y;const d=b(w);let f=!1,u=null,m=\"topLeft\",N=null,R=null,p=null,F=null;const J=Math.max(24,A.handleHitArea||44);A.handleHitArea&&I.style.setProperty(\"--scanic-handle-hit\",J+\"px\");const G=[\"topLeft\",\"topRight\",\"bottomRight\",\"bottomLeft\"],k={topLeft:\"Top-left corner\",topRight:\"Top-right corner\",bottomRight:\"Bottom-right corner\",bottomLeft:\"Bottom-left corner\"};let S={scale:1,offsetX:0,offsetY:0,width:1,height:1};const M={mask:\"rgba(15,23,42,0.45)\",edgeColor:\"#6366f1\",edgeWidth:2.5},L={};for(const b of G){const B=g.createElement(\"button\");B.type=\"button\",B.className=\"scanic-handle\"+(A.classNames?.handle?\" \"+A.classNames.handle:\"\"),B.dataset.corner=b,B.setAttribute(\"aria-label\",k[b]),l||(B.tabIndex=-1),B.addEventListener(\"pointerdown\",A=>iA(b,A)),B.addEventListener(\"pointermove\",A=>EA(b,A)),B.addEventListener(\"pointerup\",A=>eA(b,A)),B.addEventListener(\"pointercancel\",A=>eA(b,A)),B.addEventListener(\"focus\",()=>{m=b,AA()}),l&&B.addEventListener(\"keydown\",A=>oA(b,A)),I.appendChild(B),L[b]=B}function T(A,I){const g=a.style.color;a.style.color=`var(${A}, ${I})`;const B=getComputedStyle(a).color||I;return a.style.color=g,B}function W(){M.mask=T(\"--scanic-mask\",\"rgba(15, 23, 42, 0.45)\"),M.edgeColor=T(\"--scanic-edge-color\",\"#6366f1\");const A=getComputedStyle(I).getPropertyValue(\"--scanic-edge-width\"),g=parseFloat(A);M.edgeWidth=Number.isFinite(g)&&g>0?g:2.5}function P(A){if(!A||\"object\"!=typeof A)return;const g=/* @__PURE__ */new Set([\"handleSize\",\"handleHit\"]);for(const[B,C]of Object.entries({accent:\"--scanic-accent\",mask:\"--scanic-mask\",edgeColor:\"--scanic-edge-color\",edgeWidth:\"--scanic-edge-width\",handleSize:\"--scanic-handle-size\",handleHit:\"--scanic-handle-hit\",handleColor:\"--scanic-handle-color\",handleRingColor:\"--scanic-handle-ring-color\",surface:\"--scanic-surface\",surfaceColor:\"--scanic-surface-fg\",radius:\"--scanic-surface-radius\"})){const Q=A[B];if(null==Q)continue;const t=\"number\"==typeof Q&&g.has(B)?`${Q}px`:String(Q);I.style.setProperty(C,t)}}function Z(){\"function\"==typeof A.onChange&&A.onChange(b(w))}let X=0,V=0;function j(){const A=Math.max(1,Math.round(I.clientWidth));let g=Math.round(I.clientHeight);if(g<80){const C=i/Math.max(1,t),Q=.7*(B.innerHeight||800);g=Math.max(240,Math.round(Math.min(A*C,Q))),I.style.minHeight=g+\"px\",n=!0}return{width:A,height:Math.max(1,g)}}function O(){const{width:A,height:I}=j(),g=B.devicePixelRatio||1;X=A,V=I,a.style.width=A+\"px\",a.style.height=I+\"px\";const C=Math.round(A*g),Q=Math.round(I*g);a.width!==C&&(a.width=C),a.height!==Q&&(a.height=Q),s.setTransform(g,0,0,g,0,0);const E=Math.max(1,A-24),e=Math.max(1,I-24),o=Math.min(E/t,e/i),n=t*o,c=i*o;S={scale:o,offsetX:Math.round((A-n)/2),offsetY:Math.round((I-c)/2),width:A,height:I},W()}function z(A){return{x:S.offsetX+A.x*S.scale,y:S.offsetY+A.y*S.scale}}function _(A){return x(A)&&U(A)}function $(A){const I=a.getBoundingClientRect();return{x:A.clientX-I.left,y:A.clientY-I.top}}function AA(){for(const A of G)L[A].classList.toggle(\"is-selected\",A===m)}function IA(){f||(s.clearRect(0,0,S.width,S.height),s.drawImage(Q,0,0,t,i,S.offsetX,S.offsetY,t*S.scale,i*S.scale),function(){const A=G.map(A=>z(w[A]));s.save(),s.fillStyle=M.mask,s.beginPath(),s.rect(0,0,S.width,S.height),s.moveTo(A[0].x,A[0].y);for(let I=1;I<A.length;I++)s.lineTo(A[I].x,A[I].y);s.closePath(),s.fill(\"evenodd\"),s.restore(),s.save(),s.strokeStyle=M.edgeColor,s.lineWidth=M.edgeWidth,s.lineJoin=\"round\",s.beginPath(),s.moveTo(A[0].x,A[0].y);for(let I=1;I<A.length;I++)s.lineTo(A[I].x,A[I].y);s.closePath(),s.stroke(),s.restore()}(),function(){if(!c.enabled||!u||!R)return;const A=w[u],I=c.size,g=I/2,B=Math.max(1.1,c.zoom),C=z(A);let E=C.x+g+c.margin,e=C.y-g-c.margin;E+g>S.width&&(E=C.x-g-c.margin),e-g<0&&(e=C.y+g+c.margin),E=Math.max(g+2,Math.min(S.width-g-2,E)),e=Math.max(g+2,Math.min(S.height-g-2,e));const o=I/B,n=A.x-o/2,a=A.y-o/2,r=Math.max(0,n),h=Math.max(0,a),l=Math.max(0,Math.min(t,n+o)-r),y=Math.max(0,Math.min(i,a+o)-h);if(s.save(),s.beginPath(),s.arc(E,e,g,0,2*Math.PI),s.clip(),s.fillStyle=M.mask,s.fillRect(E-g,e-g,I,I),l>0&&y>0){const A=E-g+(r-n)*B,I=e-g+(h-a)*B;s.drawImage(Q,r,h,l,y,A,I,l*B,y*B)}const D=c.crosshairSize/2;s.strokeStyle=c.crosshairColor,s.lineWidth=1.5,s.beginPath(),s.moveTo(E-D,e),s.lineTo(E+D,e),s.moveTo(E,e-D),s.lineTo(E,e+D),s.stroke(),s.restore(),s.save(),s.beginPath(),s.arc(E,e,g,0,2*Math.PI),s.lineWidth=c.borderWidth,s.strokeStyle=c.borderColor,s.stroke(),s.restore()}(),function(){for(const A of G){const I=z(w[A]),g=L[A];g.style.left=I.x+\"px\",g.style.top=I.y+\"px\"}}())}const gA=\"function\"==typeof B.requestAnimationFrame?B.requestAnimationFrame.bind(B):null,BA=\"function\"==typeof B.cancelAnimationFrame?B.cancelAnimationFrame.bind(B):null;let CA=null;function QA(){f||(gA?null===CA&&(CA=gA(()=>{CA=null,IA()})):IA())}function tA(A,I){const g=b(w);return g[A]={x:Math.max(0,Math.min(t,I.x)),y:Math.max(0,Math.min(i,I.y))},!!_(g)&&(w=g,m=A,AA(),Z(),QA(),!0)}function iA(A,I){if(!f){if(\"function\"==typeof I.preventDefault&&I.preventDefault(),u=A,m=A,AA(),N=I.pointerId,R=$(I),p=R,F=C(),L[A].classList.add(\"is-active\"),l&&\"function\"==typeof L[A].focus)try{L[A].focus({preventScroll:!0})}catch{L[A].focus()}if(L[A].setPointerCapture&&null!=I.pointerId)try{L[A].setPointerCapture(I.pointerId)}catch{}QA()}}function EA(A,I){if(f||u!==A)return;if(null!==N&&I.pointerId!==N)return;const g=$(I),B=g.x-p.x,Q=g.y-p.y,t=Math.max(1,C()-F),i=Math.hypot(B,Q)/t,E=Math.min(1,i/.8),e=.35+.65*(E*E*(3-2*E)),o=w[A];tA(A,{x:o.x+B*e/S.scale,y:o.y+Q*e/S.scale}),p=g,F=C(),R=g}function eA(A,I){if(u===A&&(null===N||I.pointerId===N)){if(L[A].releasePointerCapture&&null!=N)try{L[A].releasePointerCapture(N)}catch{}L[A].classList.remove(\"is-active\"),u=null,N=null,R=null,p=null,F=null,QA()}}function oA(A,I){if(f||!l)return;if(\"Enter\"===I.key)return I.preventDefault(),void yA();if(\"Escape\"===I.key)return I.preventDefault(),void DA();let g=0,B=0;if(\"ArrowLeft\"===I.key)g=-1;else if(\"ArrowRight\"===I.key)g=1;else if(\"ArrowUp\"===I.key)B=-1;else{if(\"ArrowDown\"!==I.key)return;B=1}I.preventDefault();const C=I.shiftKey?r.steps[r.steps.length-1]||10:1;tA(A,{x:w[A].x+g*C,y:w[A].y+B*C})}let nA=null,aA=null,sA=null,cA=!1;const rA=h.enabled&&r.enabled;function hA({html:A,text:I,title:B,className:C,onClick:Q}){const t=g.createElement(\"button\");return t.type=\"button\",null!=A?t.innerHTML=A:t.textContent=I,B&&(t.title=B,t.setAttribute(\"aria-label\",B)),C&&(t.className=C),t.addEventListener(\"click\",Q),t}let lA=null;function yA(){const I=b(w);return\"function\"==typeof A.onConfirm&&A.onConfirm(I),I}function DA(){\"function\"==typeof A.onCancel&&A.onCancel()}function wA(){w=b(d),Z(),QA()}const dA=\"undefined\"!=typeof ResizeObserver?new ResizeObserver(()=>{if(f)return;const A=j();A.width===X&&A.height===V||(O(),QA())}):null;return O(),h.enabled&&(h.reset||h.cancel||h.apply||rA)&&(nA=g.createElement(\"div\"),nA.className=\"scanic-toolbar\"+(A.classNames?.toolbar?\" \"+A.classNames.toolbar:\"\"),h.reset&&nA.appendChild(hA({html:Y,title:h.labels.reset,className:\"scanic-btn-reset\",onClick:()=>wA()})),rA&&(sA=hA({html:K,title:\"Precision nudge (expert)\",className:\"scanic-btn-expert\",onClick:()=>{return cA=A=!cA,aA&&(aA.style.display=A?\"\":\"none\"),void(sA&&(sA.classList.toggle(\"is-on\",A),sA.setAttribute(\"aria-pressed\",String(A))));var A}}),sA.setAttribute(\"aria-pressed\",\"false\"),nA.appendChild(sA)),h.cancel&&nA.appendChild(hA({html:q,title:h.labels.cancel,className:\"scanic-btn-cancel\",onClick:()=>DA()})),h.apply&&nA.appendChild(hA({html:v,title:h.labels.apply,className:\"scanic-btn-apply\",onClick:()=>yA()})),I.appendChild(nA)),function(){if(!r.enabled)return;aA=g.createElement(\"div\"),aA.className=\"scanic-nudges\"+(A.classNames?.nudges?\" \"+A.classNames.nudges:\"\");const B=(A,I,g,B,C)=>hA({text:A,title:I,className:\"scanic-btn-nudge\",onClick:()=>{const A=w[m];tA(m,{x:A.x+g*C,y:A.y+B*C})}});for(const A of r.steps)aA.appendChild(B(\"←\",`Move left ${A}px`,-1,0,A)),aA.appendChild(B(\"↑\",`Move up ${A}px`,0,-1,A)),aA.appendChild(B(\"↓\",`Move down ${A}px`,0,1,A)),aA.appendChild(B(\"→\",`Move right ${A}px`,1,0,A));I.appendChild(aA),rA&&(aA.style.display=\"none\")}(),function A(){if(\"function\"!=typeof B.matchMedia)return;lA&&lA();const I=B.devicePixelRatio||1,g=B.matchMedia(`(resolution: ${I}dppx)`),C=()=>{f||(O(),QA(),A())};\"function\"==typeof g.addEventListener?(g.addEventListener(\"change\",C),lA=()=>g.removeEventListener(\"change\",C)):\"function\"==typeof g.addListener?(g.addListener(C),lA=()=>g.removeListener(C)):lA=null}(),dA&&dA.observe(I),AA(),IA(),{getCorners:()=>b(w),setCorners:A=>!(!A||!_(A))&&(w=b(A),Z(),QA(),!0),reset(){wA()},nudge:(A,I,g,B=1)=>!!G.includes(A)&&tA(A,{x:w[A].x+I*B,y:w[A].y+g*B}),refreshTheme(A){P(A),W(),QA()},confirm:()=>yA(),cancel(){DA()},destroy(){if(!f){f=!0,null!==CA&&BA&&(BA(CA),CA=null),lA&&(lA(),lA=null),dA&&dA.disconnect();for(const A of G){const I=L[A];I&&I.parentNode&&I.parentNode.removeChild(I)}nA&&nA.parentNode&&nA.parentNode.removeChild(nA),aA&&aA.parentNode&&aA.parentNode.removeChild(aA),a.parentNode&&a.parentNode.removeChild(a),E&&I.classList.remove(\"scanic-corner-editor\"),A.classNames?.root&&I.classList.remove(A.classNames.root),o&&(I.style.position=e.position),n&&(I.style.minHeight=e.minHeight)}}}}async function W(){try{return await G()}catch{return null}}var P=class{constructor(A={}){this.defaultOptions={maxProcessingDimension:800,mode:\"detect\",output:\"canvas\",...A},this.initialized=!1}async initialize(){if(!this.initialized){if(\"ml\"===this.defaultOptions.detector)try{const{initializeMl:A}=await import(\"./scanic-mlDetector.js\");await A(this.defaultOptions.ml||{})}catch{}else try{await G()}catch{}this.initialized=!0}}async scan(A,I={}){return this.initialized||await this.initialize(),await IA(A,{...this.defaultOptions,...I})}async extract(A,I,g={}){return this.initialized||await this.initialize(),await AA(A,I,{...this.defaultOptions,...g})}};function Z(A){return A<=0?0:A>=1?1:A}function X(A,I){return Math.hypot(A.x-I.x,A.y-I.y)}function V(A){return[X(A.topLeft,A.topRight),X(A.topRight,A.bottomRight),X(A.bottomRight,A.bottomLeft),X(A.bottomLeft,A.topLeft)]}function j(A){const I=function(A){const I=[A.topLeft,A.topRight,A.bottomRight,A.bottomLeft],g=[];for(let B=0;B<I.length;B++){const A=I[(B+I.length-1)%I.length],C=I[B],Q=I[(B+1)%I.length],t=A.x-C.x,i=A.y-C.y,E=Q.x-C.x,e=Q.y-C.y,o=t*E+i*e,n=Math.max(1e-6,Math.hypot(t,i)*Math.hypot(E,e)),a=Math.max(-1,Math.min(1,o/n));g.push(180*Math.acos(a)/Math.PI)}return g}(A);let g=0;for(const B of I){g+=Z(1-Math.abs(B-90)/55)}return g/Math.max(1,I.length)}function O(A,I){const g=Number(I.isValid)-Number(A.isValid);if(0!==g)return g;const B=I.confidence-A.confidence;if(!(Math.abs(B)<.015)&&0!==B)return B;const C=Math.abs((A.approxCount??99)-4)-Math.abs((I.approxCount??99)-4);if(0!==C)return C;const Q=(I.rightAngleScore??0)-(A.rightAngleScore??0);if(Math.abs(Q)>1e-6)return Q;const t=Math.abs(1-(A.contourFitRatio??1))-Math.abs(1-(I.contourFitRatio??1));return Math.abs(t)>1e-6?t:B||I.score-A.score||I.coverageRatio-A.coverageRatio||I.area-A.area}function z(A,I,g,B,C={}){const Q=C.epsilon||.02,t=E(A.points,Q).length,i=n(A,{epsilon:Q});if(!i)return{contour:A,corners:null,score:0,confidence:0,isValid:!1,area:A.area||0,fillRatio:0,coverageRatio:0,cornersArea:0,approxCount:t,convex:!1,edgeSupport:0,aspectRatio:1/0,minSide:0,rightAngleScore:0,oppositeSideConsistency:0,contourFitRatio:0,contourFitScore:0};const e=g*B,o=A.area||0,a=A.boundingBox||{minX:0,minY:0,maxX:0,maxY:0},s=o/Math.max(1,(a.maxX-a.minX+1)*(a.maxY-a.minY+1)),c=function(A){if(!A)return 0;const I=[A.topLeft,A.topRight,A.bottomRight,A.bottomLeft];let g=0;for(let B=0;B<I.length;B++){const A=(B+1)%I.length;g+=I[B].x*I[A].y-I[A].x*I[B].y}return Math.abs(g)/2}(i),r=c/Math.max(1,e),h=V(i),l=Math.min(...h),y=(h[0]+h[2])/2,D=(h[1]+h[3])/2,w=y>D?y/Math.max(1e-6,D):D/Math.max(1e-6,y),d=function(A){const I=[A.topLeft,A.topRight,A.bottomRight,A.bottomLeft],g=[];for(let C=0;C<I.length;C++){const A=I[C],B=I[(C+1)%I.length],Q=I[(C+2)%I.length],t=(B.x-A.x)*(Q.y-B.y)-(B.y-A.y)*(Q.x-B.x);Math.abs(t)<1e-6||g.push(Math.sign(t))}if(g.length<3)return!1;const B=g[0];return g.every(A=>A===B)}(i),f=function(A,I,g,B){if(!A?.points||0===A.points.length)return 0;const C=Math.max(1,Math.floor(A.points.length/240));let Q=0,t=0;for(let i=0;i<A.points.length;i+=C){const C=A.points[i],E=Math.max(0,Math.min(g-1,0|C.x)),e=Math.max(0,Math.min(B-1,0|C.y));Q++;let o=!1;for(let A=-1;A<=1&&!o;A++){const C=e+A;if(!(C<0||C>=B))for(let A=-1;A<=1;A++){const B=E+A;if(!(B<0||B>=g)&&I[C*g+B]>0){o=!0;break}}}o&&t++}return 0===Q?0:t/Q}(A,I,g,B),u=j(i),m=function(A){const I=V(A);return(Math.min(I[0],I[2])/Math.max(1e-6,Math.max(I[0],I[2]))+Math.min(I[1],I[3])/Math.max(1e-6,Math.max(I[1],I[3])))/2}(i),N=o/Math.max(1,c),R=Z(1-Math.abs(N-1)/.55),p=4===t?1:5===t?.9:6===t?.7:t<=8?.5:.28,F=Z(o/Math.max(1,.4*e)),J=Z((s-.08)/.72),G=Z((r-.03)/.82),k=void 0!==C.minDocumentSideRatio?C.minDocumentSideRatio:.06,S=void 0!==C.minDocumentCoverageRatio?C.minDocumentCoverageRatio:.04,M=void 0!==C.maxDocumentAspectRatio?C.maxDocumentAspectRatio:8,b=void 0!==C.minDocumentFillRatio?C.minDocumentFillRatio:.07,L=void 0!==C.minContourFitRatio?C.minContourFitRatio:.11,x=void 0!==C.maxContourFitRatio?C.maxContourFitRatio:1.2,U=void 0!==C.minRightAngleScore?C.minRightAngleScore:.42,H=void 0!==C.minOppositeSideConsistency?C.minOppositeSideConsistency:.3,Y=Math.min(g,B)*k,q=function(A,I=6){const g=[A?.topLeft,A?.topRight,A?.bottomRight,A?.bottomLeft];if(g.some(A=>!A||!Number.isFinite(A.x)||!Number.isFinite(A.y)))return!1;for(let B=0;B<g.length;B++)for(let A=B+1;A<g.length;A++)if(X(g[B],g[A])<I)return!1;return!0}(i)&&d&&l>=Y&&r>=S&&w<=M&&s>=b&&N>=L&&N<=x&&u>=U&&m>=H,v=.22*F+.14*J+.15*p+.08*(d?1:0)+.08*f+.13*G+.1*u+.05*m+.05*R;return{contour:A,corners:i,score:v,confidence:q?v:.33*v,isValid:q,area:o,fillRatio:s,coverageRatio:r,cornersArea:c,approxCount:t,convex:d,edgeSupport:f,aspectRatio:w,minSide:l,rightAngleScore:u,oppositeSideConsistency:m,contourFitRatio:N,contourFitScore:R}}async function _(A,I,g,C,Q={}){const t=Q.debug?{}:{_timingsOnly:!0},i=[];t&&!t._timingsOnly&&(t.preprocessing={scaledDimensions:{width:I,height:g},scaleFactor:C,maxProcessingDimension:Q.maxProcessingDimension||800});const E=function(A={}){const I=A.dilationKernelSize||3,g=A.dilationIterations||1,B=void 0===A.applyDilation||A.applyDilation,C=[{name:\"default\",lowThreshold:A.lowThreshold,highThreshold:A.highThreshold,dilationKernelSize:I,dilationIterations:g,applyDilation:B}];if(!1===A.enableDetectionCascade)return C;C.push({name:\"connect-edges\",lowThreshold:A.lowThreshold,highThreshold:A.highThreshold,dilationKernelSize:Math.max(I,5),dilationIterations:Math.max(g,2),applyDilation:!0}),C.push({name:\"no-dilation\",lowThreshold:A.lowThreshold,highThreshold:A.highThreshold,dilationKernelSize:I,dilationIterations:g,applyDilation:!1}),void 0===A.lowThreshold&&void 0===A.highThreshold&&C.push({name:\"fixed-mid-thresholds\",lowThreshold:60,highThreshold:180,dilationKernelSize:I,dilationIterations:g,applyDilation:B});const Q=[],t=/* @__PURE__ */new Set;for(const i of C){const A=[i.lowThreshold,i.highThreshold,i.dilationKernelSize,i.dilationIterations,i.applyDilation].join(\":\");t.has(A)||(t.add(A),Q.push(i))}return Q}(Q),e=[],o=async(t,E)=>{const e=t.name||`pass-${E+1}`,o=0===E?\"\":` (${e})`,n=Q.debug?{}:{_timingsOnly:!0},a=await M(A,{width:I,height:g,lowThreshold:t.lowThreshold,highThreshold:t.highThreshold,dilationKernelSize:t.dilationKernelSize,dilationIterations:t.dilationIterations,applyDilation:t.applyDilation,debug:n,skipGrayscale:!0,useWasmBlur:!0,useWasmHysteresis:Q.useWasmHysteresis,useWasmFullCanny:Q.useWasmFullCanny});n.timings&&n.timings.forEach(A=>{\"Edge Detection Total\"!==A.step&&i.push({step:`${A.step}${o}`,ms:A.ms})});let s=performance.now();const c=B(a,{minArea:(Q.minArea||1e3)/(C*C),width:I,height:g});i.push({step:`Find Contours${o}`,ms:(performance.now()-s).toFixed(2)}),s=performance.now();const{best:r,candidates:h}=function(A,I,g,B,C={}){const Q=C.maxCandidateContours||12,t=A.slice(0,Q).map((A,Q)=>({rankByArea:Q,...z(A,I,g,B,C)})).sort(O);return{best:t[0]||null,candidates:t}}(c,a,I,g,Q);return i.push({step:`Corner Detection${o}`,ms:(performance.now()-s).toFixed(2)}),{name:e,params:{lowThreshold:t.lowThreshold,highThreshold:t.highThreshold,dilationKernelSize:t.dilationKernelSize,dilationIterations:t.dilationIterations,applyDilation:t.applyDilation},contours:c,best:r,candidates:h}},n=await o(E[0],0);if(e.push(n),function(A,I={}){if(!1===I.enableDetectionCascade)return!1;if(!A||!A.corners)return!0;const g=void 0!==I.minCascadeTriggerConfidence?I.minCascadeTriggerConfidence:.68;return!A.isValid||A.confidence<g||A.approxCount>5||A.rightAngleScore<.55||A.contourFitRatio<.14}(n.best,Q))for(let B=1;B<E.length;B++)e.push(await o(E[B],B));const a=[];for(const B of e)for(const A of B.candidates)a.push({...A,passName:B.name,passParams:B.params});a.sort(O);const s=a[0]||null,c=a;if(!s||!s.corners)return{success:!1,message:\"No document detected\",debug:t._timingsOnly?null:t,timings:i};t&&!t._timingsOnly&&(t.passes=e.map(A=>({name:A.name,params:A.params,contourCount:A.contours.length,bestCandidate:A.best?{score:A.best.score,confidence:A.best.confidence,isValid:A.best.isValid,approxCount:A.best.approxCount,coverageRatio:A.best.coverageRatio,fillRatio:A.best.fillRatio,rightAngleScore:A.best.rightAngleScore,contourFitRatio:A.best.contourFitRatio}:null})),t.candidates=c.map(A=>({passName:A.passName,rankByArea:A.rankByArea,area:A.area,fillRatio:A.fillRatio,coverageRatio:A.coverageRatio,cornersArea:A.cornersArea,approxCount:A.approxCount,convex:A.convex,edgeSupport:A.edgeSupport,aspectRatio:A.aspectRatio,minSide:A.minSide,rightAngleScore:A.rightAngleScore,oppositeSideConsistency:A.oppositeSideConsistency,contourFitRatio:A.contourFitRatio,contourFitScore:A.contourFitScore,score:A.score,confidence:A.confidence,isValid:A.isValid})),t.selectedCandidate=c[0]?{passName:c[0].passName,rankByArea:c[0].rankByArea,area:c[0].area,fillRatio:c[0].fillRatio,coverageRatio:c[0].coverageRatio,approxCount:c[0].approxCount,edgeSupport:c[0].edgeSupport,aspectRatio:c[0].aspectRatio,minSide:c[0].minSide,rightAngleScore:c[0].rightAngleScore,oppositeSideConsistency:c[0].oppositeSideConsistency,contourFitRatio:c[0].contourFitRatio,score:c[0].score,confidence:c[0].confidence,isValid:c[0].isValid}:null);const r=s.corners,h=s.contour;let l=r;return 1!==C&&(l={topLeft:{x:r.topLeft.x*C,y:r.topLeft.y*C},topRight:{x:r.topRight.x*C,y:r.topRight.y*C},bottomRight:{x:r.bottomRight.x*C,y:r.bottomRight.y*C},bottomLeft:{x:r.bottomLeft.x*C,y:r.bottomLeft.y*C}}),{success:!0,contour:h,corners:l,confidence:s.confidence,debug:t._timingsOnly?null:t,timings:i}}function $(A,I,g){const{topLeft:B,topRight:C,bottomRight:Q,bottomLeft:t}=g,i=Math.hypot(Q.x-t.x,Q.y-t.y),E=Math.hypot(C.x-B.x,C.y-B.y),e=Math.round(Math.max(i,E)),o=Math.hypot(C.x-Q.x,C.y-Q.y),n=Math.hypot(B.x-t.x,B.y-t.y),a=Math.round(Math.max(o,n));A.canvas.width=e,A.canvas.height=a,function(A,I,g,B,C){const Q=I&&\"number\"==typeof I.width&&\"number\"==typeof I.height&&I.data,t=I.width||I.naturalWidth,i=I.height||I.naturalHeight,E=document.createElement(\"canvas\");E.width=t,E.height=i;const e=E.getContext(\"2d\",{willReadFrequently:!0});Q?e.putImageData(I,0,0):e.drawImage(I,0,0,t,i);const o=e.getImageData(0,0,t,i).data,n=function(A){const I=A[0][0],g=A[0][1],B=A[0][2],C=A[1][0],Q=A[1][1],t=A[1][2],i=A[2][0],E=A[2][1],e=A[2][2],o=Q*e-t*E,n=-(C*e-t*i),a=C*E-Q*i,s=-(g*e-B*E),c=I*e-B*i,r=-(I*E-g*i),h=g*t-B*Q,l=-(I*t-B*C),y=I*Q-g*C,D=I*o+g*n+B*a;if(0===D)throw new Error(\"Singular matrix\");return[[o/D,s/D,h/D],[n/D,c/D,l/D],[a/D,r/D,y/D]]}(g),a=n[0][0],s=n[0][1],c=n[0][2],r=n[1][0],h=n[1][1],l=n[1][2],y=n[2][0],D=n[2][1],w=n[2][2],d=A.createImageData(B,C),f=d.data,u=t-1,m=i-1;for(let N=0;N<C;N++){const A=s*N+c,I=h*N+l,g=D*N+w;for(let C=0;C<B;C++){const Q=1/(y*C+g),i=(a*C+A)*Q,E=(r*C+I)*Q,e=i<0?0:i>u?u:i,n=E<0?0:E>m?m:E,s=0|e,c=0|n,h=s<u?s+1:s,l=c<m?c+1:c,D=e-s,w=n-c,d=1-D,R=1-w,p=d*R,F=D*R,J=d*w,G=D*w,k=c*t+s<<2,S=c*t+h<<2,M=l*t+s<<2,b=l*t+h<<2,L=N*B+C<<2;f[L]=o[k]*p+o[S]*F+o[M]*J+o[b]*G+.5|0,f[L+1]=o[k+1]*p+o[S+1]*F+o[M+1]*J+o[b+1]*G+.5|0,f[L+2]=o[k+2]*p+o[S+2]*F+o[M+2]*J+o[b+2]*G+.5|0,f[L+3]=255}}A.putImageData(d,0,0)}(A,I,function(A,I){const g=function(A,I){const g=A.length,B=A[0].length,C=A.map(A=>A.slice()),Q=I.slice();for(let i=0;i<B;i++){let A=i;for(let I=i+1;I<g;I++)Math.abs(C[I][i])>Math.abs(C[A][i])&&(A=I);[C[i],C[A]]=[C[A],C[i]],[Q[i],Q[A]]=[Q[A],Q[i]];for(let I=i+1;I<g;I++){const A=C[I][i]/C[i][i];for(let g=i;g<B;g++)C[I][g]-=A*C[i][g];Q[I]-=A*Q[i]}}const t=new Array(B);for(let i=B-1;i>=0;i--){let A=Q[i];for(let I=i+1;I<B;I++)A-=C[i][I]*t[I];t[i]=A/C[i][i]}return t}(function(A){const g=[];for(let B=0;B<4;B++){const[C,Q]=A[B];g.push([C,Q,1,0,0,0,-C*I[B][0],-Q*I[B][0]]),g.push([0,0,0,C,Q,1,-C*I[B][1],-Q*I[B][1]])}return g}(A),[I[0][0],I[0][1],I[1][0],I[1][1],I[2][0],I[2][1],I[3][0],I[3][1]]);return[[g[0],g[1],g[2]],[g[3],g[4],g[5]],[g[6],g[7],1]]}([[B.x,B.y],[C.x,C.y],[Q.x,Q.y],[t.x,t.y]],[[0,0],[e-1,0],[e-1,a-1],[0,a-1]]),e,a)}async function AA(A,I,g={}){const B=g.output||\"canvas\";if(!(I&&I.topLeft&&I.topRight&&I.bottomRight&&I.bottomLeft))return{output:null,corners:null,success:!1,message:\"Invalid corner points provided\"};try{const g=document.createElement(\"canvas\");let C;return $(g.getContext(\"2d\"),A,I),C=\"canvas\"===B?g:\"imagedata\"===B?g.getContext(\"2d\").getImageData(0,0,g.width,g.height):\"dataurl\"===B?g.toDataURL():g,{output:C,corners:I,success:!0,message:\"Document extracted successfully\"}}catch(C){return{output:null,corners:I,success:!1,message:`Extraction failed: ${C.message}`}}}async function IA(A,I={}){const g=[],B=performance.now(),C=I.mode||\"detect\",Q=I.output||\"canvas\",t=I.maxProcessingDimension||800;let i,E,e,o;if(\"ml\"===(I.detector||\"classical\")){E=performance.now();const{detectDocumentMl:B}=await import(\"./scanic-mlDetector.js\");i=await B(A,I.ml||{}),g.push({step:\"ML Detection Total\",ms:(performance.now()-E).toFixed(2)}),i.timings&&i.timings.forEach(A=>g.push(A))}else{E=performance.now();const{grayscaleData:B,scaleFactor:C,scaledDimensions:Q}=await async function(A,I=800){let g,B;const C=A&&\"number\"==typeof A.width&&\"number\"==typeof A.height&&A.data;if(C)g=A.width,B=A.height;else{if(!A)throw new Error(\"No image provided\");g=A.width||A.naturalWidth,B=A.height||A.naturalHeight}const Q=Math.max(g,B);let t,i,E;if(Q<=I)t=g,i=B,E=1;else{const A=I/Q;t=Math.round(g*A),i=Math.round(B*A),E=1/A}const e=\"undefined\"!=typeof OffscreenCanvas,o=e?new OffscreenCanvas(t,i):document.createElement(\"canvas\");e||(o.width=t,o.height=i);const n=o.getContext(\"2d\",{willReadFrequently:!0});if(n.imageSmoothingEnabled=!0,n.imageSmoothingQuality=\"medium\",C){const I=e?new OffscreenCanvas(g,B):document.createElement(\"canvas\");e||(I.width=g,I.height=B),I.getContext(\"2d\").putImageData(A,0,0),n.drawImage(I,0,0,g,B,0,0,t,i)}else n.drawImage(A,0,0,g,B,0,0,t,i);const a=n.getImageData(0,0,t,i),s=a.data,c=new Uint8ClampedArray(t*i);for(let r=0,h=0;r<s.length;r+=4,h++){const A=54*s[r]+183*s[r+1]+19*s[r+2]>>8;c[h]=A,s[r]=s[r+1]=s[r+2]=A}return{grayscaleData:c,imageData:a,scaleFactor:E,originalDimensions:{width:g,height:B},scaledDimensions:{width:t,height:i}}}(A,t);g.push({step:\"Image Prep + Scale + Gray\",ms:(performance.now()-E).toFixed(2)}),i=await _(B,Q.width,Q.height,C,I),i.timings&&i.timings.forEach(A=>g.push(A))}if(!i.success){const A=performance.now();return g.unshift({step:\"Total\",ms:(A-B).toFixed(2)}),{output:null,corners:null,contour:null,confidence:i.confidence||null,score:i.score??null,debug:i.debug,success:!1,message:i.message||\"No document detected\",timings:g}}\"detect\"===C?o=null:\"extract\"===C&&(E=performance.now(),e=document.createElement(\"canvas\"),$(e.getContext(\"2d\"),A,i.corners),g.push({step:\"Perspective Transform\",ms:(performance.now()-E).toFixed(2)})),\"detect\"!==C&&e&&(E=performance.now(),o=\"canvas\"===Q?e:\"imagedata\"===Q?e.getContext(\"2d\").getImageData(0,0,e.width,e.height):\"dataurl\"===Q?e.toDataURL():e,g.push({step:\"Output Conversion\",ms:(performance.now()-E).toFixed(2)}));const n=performance.now();return g.unshift({step:\"Total\",ms:(n-B).toFixed(2)}),{output:o,corners:i.corners,contour:i.contour??null,confidence:i.confidence||null,score:i.score??null,debug:i.debug,success:!0,message:\"Document detected\",timings:g}}export{P as Scanner,T as createCornerEditor,AA as extractDocument,W as initialize,IA as scanDocument};","// Quad detector over the VENDORED scanic 1.5.0 dist (Task 34). Vendoring\n// posture = models-v3: the dist is committed under vendor/scanic/ with a\n// sha256 manifest pinned by test/doc/scanic-manifest.test.ts — no registry\n// fetch at build time, no CDN at runtime (the Rust-WASM Canny pipeline is\n// base64-embedded in scanic.js; the optional ML detector chunk is never\n// requested because we pin `detector: 'classical'`).\nimport { scanDocument } from \"../../../vendor/scanic/scanic.js\";\nimport { DOC_DETECT_WIDTH, type DocQuad } from \"./doc-gate-v1\";\n\n/** Pinned vendored version — bump ONLY with a manifest + bench re-run. */\nexport const SCANIC_VERSION = \"1.5.0\";\n\nexport { DOC_DETECT_WIDTH };\n\n/**\n * Minimum scanic contour confidence to report a quad AT ALL (operator gate\n * feedback 2026-07-12: low-confidence contours drew corners well inside the\n * card — better to coach `no_doc` than to render a garbage quad the user\n * chases). Lowered 0.5→0.35 at gate round 2: passport data pages against the\n * booklet's own pages have weak edge contrast and 0.5 starved detection —\n * the gate's plausibility/stability checks stay the real filter.\n */\nexport const DOC_DETECT_MIN_CONFIDENCE = 0.35;\n\n/**\n * Detect the document quad on a (≤480px) snapshot. Returns the corner points\n * in the SNAPSHOT's pixel space, or null when scanic finds no plausible\n * document contour (or only a low-confidence one). Detection only — no\n * extraction/warp here (the session crops the full-res still itself).\n */\nexport async function detectQuad(image: ImageData): Promise<DocQuad | null> {\n const result = await scanDocument(image, {\n mode: \"detect\",\n detector: \"classical\",\n maxProcessingDimension: DOC_DETECT_WIDTH,\n });\n if (!result.success || result.corners === null) return null;\n if (typeof result.confidence === \"number\" && result.confidence < DOC_DETECT_MIN_CONFIDENCE) {\n return null;\n }\n return result.corners;\n}\n","/**\n * @internal — NOT part of the public @sekyro/web API. Consumed by Sekyro's own hosted page only\n * (document scanner + gate-debug geometry). No semver guarantees; may change in any release.\n *\n * detector-scanic is DELIBERATELY not re-exported here either: CaptureSessionDoc\n * lazy-imports it on the first detect tick so the ~39KiB-gz vendored chunk never\n * rides a host's session-shell bundle (route budget) — import\n * \"../core/doc/detector-scanic\" directly if you need bare detectQuad.\n */\nexport * from \"../core/doc/doc-catalog\";\nexport * from \"../core/doc/doc-gate-v1\";\nexport * from \"../core/doc/mrz-band\";\nexport * from \"../core/doc/frame-analysis\";\nexport * from \"../core/doc/feedback-aggregator\";\nexport * from \"../core/doc/capture-session-doc\";\nexport { CENTERED_FACTOR, CIRCLE_RADIUS_FACTOR, IN_CIRCLE_FACTOR } from \"../core/capture-constraints\";\n\n// ── Plan A Task 6: verification internals (seams, flow, mapping, Turnstile) ──\n// Consumed by Sekyro's own hosted page / @sekyro/react and the tests; the\n// public partner API is the root entry (`@sekyro/web`).\nexport {\n createLivenessCaptureInternal,\n mapEngineState,\n mapErrorKind,\n mapGuidanceHint,\n type CaptureEngine,\n type LivenessCaptureInternalHandle,\n type LivenessCaptureInternals,\n} from \"../capture/create-liveness-capture\";\nexport {\n createVerificationInternal,\n PROCESSING_POLL_DELAY_MS,\n PROCESSING_POLL_MAX,\n randomUuid,\n REGISTRY_RETRY_DELAY_MS,\n type VerificationInternals,\n} from \"../verification/create-verification\";\nexport {\n AttestationError,\n CLIP_MIME_ALLOWLIST,\n runLivenessFlow,\n runSubmission,\n TRANSPORT_REPLAY_ATTEMPTS,\n TRANSPORT_REPLAY_DELAY_MS,\n type HostedClientLike,\n type LivenessFlowDeps,\n type LivenessFlowOutcome,\n type SubmitExecutor,\n type SubmitRuntime,\n} from \"../verification/liveness-flow\";\nexport {\n frontierStep,\n isExecutable,\n isTerminalView,\n mapSessionResult,\n mergeSessionView,\n RETRYABLE_REASONS,\n stepOf,\n} from \"../verification/result\";\nexport {\n type ExecuteTurnstileOptions,\n executeTurnstile,\n loadTurnstile,\n resetTurnstileForTests,\n TURNSTILE_EXECUTE_TIMEOUT_MS,\n TURNSTILE_SCRIPT_SRC,\n type TurnstileApi,\n type TurnstileRenderParams,\n} from \"../verification/turnstile\";\n","// MRZ-band detector (Task 37 round 3) — the passport path's detection signal.\n//\n// WHY: edge/contour detection (scanic) fails on passport data pages — an open\n// booklet's page edges are white-on-white, so quads lock late or onto the\n// wrong rectangle (operator field finding, twice). The industry-standard\n// approach (Scanbot/Regula/Dynamsoft; PyImageSearch's classic blackhat\n// pipeline; YOLO-MRZ) is to detect the MRZ ITSELF: two 44-char lines of\n// high-contrast OCR-B strokes — the one feature of a passport that is\n// reliably detectable in any framing. This is the pure-JS analog of the\n// blackhat+gradient pipeline: per-row horizontal-stroke density with a\n// column-coverage requirement, then the tallest qualifying row run.\n//\n// Deterministic, allocation-light, no wasm: ~2ms on a 480px frame in node —\n// cheap enough to run at full doc cadence on LOW devices.\n\nexport interface MrzBand {\n x: number;\n y: number;\n width: number;\n height: number;\n /** Mean qualifying-row stroke density (diagnostics/telemetry). */\n density: number;\n}\n\nexport interface MrzBandThresholds {\n /** Luma step that counts as a text stroke edge. */\n EDGE_LUMA_DELTA: number;\n /** Min fraction of a row's pixels that are stroke edges to qualify. */\n MIN_ROW_DENSITY: number;\n /** Row must have stroke edges spread across ≥ this fraction of 12 columns. */\n MIN_COLUMN_COVERAGE: number;\n /** Band width (stroke x-extent) as a fraction of frame width. */\n MIN_WIDTH_FRAC: number;\n /** Band height bounds as fractions of frame height (2–3 OCR-B lines). */\n MIN_HEIGHT_FRAC: number;\n MAX_HEIGHT_FRAC: number;\n /** Rows this close together merge into one band (inter-line gap). */\n ROW_MERGE_GAP: number;\n}\n\n/** Frozen defaults (goldens in test/doc/mrz-band.test.ts — retune together). */\nexport const MRZ_BAND_DEFAULTS: Readonly<MrzBandThresholds> = Object.freeze({\n EDGE_LUMA_DELTA: 40,\n MIN_ROW_DENSITY: 0.08,\n MIN_COLUMN_COVERAGE: 0.6,\n MIN_WIDTH_FRAC: 0.55,\n MIN_HEIGHT_FRAC: 0.02,\n MAX_HEIGHT_FRAC: 0.16,\n ROW_MERGE_GAP: 18,\n});\n\nconst COLUMN_BUCKETS = 12;\n\n/**\n * Detect the MRZ stroke band on a (≤480px) grayscale-able frame. Returns the\n * tight band rect in frame pixels, or null when no qualifying band exists\n * (no MRZ in view, or only a partial/narrow slice of one).\n */\nexport function detectMrzBand(\n frame: ImageData,\n overrides: Partial<MrzBandThresholds> = {},\n): MrzBand | null {\n const t = { ...MRZ_BAND_DEFAULTS, ...overrides };\n const { data, width, height } = frame;\n if (width < 32 || height < 32) return null;\n\n // Per-row: stroke-edge count + column coverage + x-extent.\n const qualifies = new Array<boolean>(height).fill(false);\n const density = new Float32Array(height);\n const minX = new Int32Array(height).fill(width);\n const maxX = new Int32Array(height).fill(-1);\n\n const bucketWidth = width / COLUMN_BUCKETS;\n const buckets = new Array<boolean>(COLUMN_BUCKETS);\n for (let y = 0; y < height; y++) {\n let edges = 0;\n buckets.fill(false);\n const rowOffset = y * width * 4;\n let previousLuma =\n 0.299 * (data[rowOffset] ?? 0) +\n 0.587 * (data[rowOffset + 1] ?? 0) +\n 0.114 * (data[rowOffset + 2] ?? 0);\n for (let x = 1; x < width; x++) {\n const i = rowOffset + x * 4;\n const luma =\n 0.299 * (data[i] ?? 0) + 0.587 * (data[i + 1] ?? 0) + 0.114 * (data[i + 2] ?? 0);\n if (Math.abs(luma - previousLuma) >= t.EDGE_LUMA_DELTA) {\n edges += 1;\n buckets[Math.min(COLUMN_BUCKETS - 1, Math.floor(x / bucketWidth))] = true;\n if (x < (minX[y] as number)) minX[y] = x;\n if (x > (maxX[y] as number)) maxX[y] = x;\n }\n previousLuma = luma;\n }\n density[y] = edges / width;\n const coverage = buckets.filter(Boolean).length / COLUMN_BUCKETS;\n qualifies[y] =\n density[y]! >= t.MIN_ROW_DENSITY &&\n coverage >= t.MIN_COLUMN_COVERAGE &&\n (maxX[y] as number) - (minX[y] as number) >= t.MIN_WIDTH_FRAC * width;\n }\n\n // Merge qualifying rows across the inter-line gap; keep the best band.\n let best: { top: number; bottom: number; rows: number } | null = null;\n let runTop = -1;\n let lastQualifying = -1;\n let runRows = 0;\n const flush = (bottom: number) => {\n if (runTop < 0) return;\n const bandHeight = bottom - runTop + 1;\n if (\n bandHeight >= t.MIN_HEIGHT_FRAC * height &&\n bandHeight <= t.MAX_HEIGHT_FRAC * height &&\n runRows >= 4 && // at least a few real stroke rows, not a lone edge\n (best === null || runRows > best.rows)\n ) {\n best = { top: runTop, bottom, rows: runRows };\n }\n runTop = -1;\n runRows = 0;\n };\n for (let y = 0; y < height; y++) {\n if (qualifies[y]) {\n if (runTop < 0) runTop = y;\n else if (y - lastQualifying > t.ROW_MERGE_GAP) {\n flush(lastQualifying);\n runTop = y;\n }\n lastQualifying = y;\n runRows += 1;\n }\n }\n flush(lastQualifying);\n if (best === null) return null;\n const band = best as { top: number; bottom: number; rows: number };\n\n // Tight x-extent + mean density over the band's qualifying rows.\n let x1 = width;\n let x2 = -1;\n let densitySum = 0;\n let densityRows = 0;\n for (let y = band.top; y <= band.bottom; y++) {\n if (!qualifies[y]) continue;\n if ((minX[y] as number) < x1) x1 = minX[y] as number;\n if ((maxX[y] as number) > x2) x2 = maxX[y] as number;\n densitySum += density[y] as number;\n densityRows += 1;\n }\n if (x2 - x1 < t.MIN_WIDTH_FRAC * width) return null;\n return {\n x: x1,\n y: band.top,\n width: x2 - x1,\n height: band.bottom - band.top + 1,\n density: densityRows > 0 ? densitySum / densityRows : 0,\n };\n}\n","// Doc frame analysis (capture v2, Task-37 round 4) — the BlinkID-inspired\n// PER-FRAME status vector: independent framing / lighting / blur / glare /\n// tilt verdicts instead of a single collapsed guidance key. Pure and\n// deterministic: inputs are the detection (quad or MRZ band rect-as-quad),\n// the doc-region crop's quality measures, and static thresholds — no clocks,\n// no I/O. The FeedbackAggregator votes over these statuses; DocGateV1's\n// integrator/stability logic consumes `framingOk`/`qualityOk`.\nimport { EXPOSURE_BAND } from \"../v3/frame-quality\";\nimport { aspectBand, type DocFormat } from \"./doc-catalog\";\nimport {\n DOC_GATE_V1_DEFAULTS,\n type DocGateThresholds,\n type DocQuad,\n quadAreaFrac,\n quadBounds,\n} from \"./doc-gate-v1\";\n\nexport type FramingStatus =\n | \"no_document\"\n | \"too_far\"\n | \"too_close\"\n | \"edge_clipped\"\n | \"wrong_shape\"\n | \"tilted\"\n | \"ok\";\n\nexport type LightingStatus = \"too_dark\" | \"too_bright\" | \"ok\";\nexport type BlurStatus = \"blurry\" | \"ok\";\nexport type GlareStatus = \"glare\" | \"ok\";\n\n/** The per-frame analysis vector (every axis judged independently). */\nexport interface DocFrameAnalysis {\n framing: FramingStatus;\n lighting: LightingStatus;\n blur: BlurStatus;\n glare: GlareStatus;\n /** All-clear: every axis ok — the gate's integrator/stability input. */\n acceptable: boolean;\n}\n\nexport interface DocFrameMeasures {\n /** frame-quality sharpness on the doc-region crop (0..1). */\n sharpness: number;\n /** frame-quality exposure on the doc-region crop (0..1). */\n exposure: number;\n /** Mean crop luma (0..255) — picks too_dark vs too_bright. */\n meanLuma: number;\n /** Fraction of crop pixels at/above the specular ceiling (0..1). */\n specularFraction: number;\n}\n\n/** Analysis thresholds beyond the gate's — frozen defaults (round 4). */\nexport const DOC_ANALYSIS_DEFAULTS = Object.freeze({\n /** Doc area fraction above which the camera is too close (capture would crop). */\n MAX_AREA_FRAC: 0.92,\n /** Opposite-side length ratio beyond which the view is too oblique. */\n TILT_MAX_SIDE_RATIO: 1.3,\n /** Specular-pixel fraction at/above which the frame reads as glare. */\n GLARE_MAX_SPECULAR_FRAC: 0.025,\n});\n\n/** Fraction of crop pixels with luma ≥ 252 — cheap specular-highlight measure. */\nexport function specularFraction(crop: ImageData): number {\n const { data, width, height } = crop;\n const pixels = width * height;\n if (pixels === 0) return 0;\n let hot = 0;\n for (let i = 0; i < pixels; i++) {\n const o = i * 4;\n // Rec.601 luma, integer-ish — a specular blowout saturates all channels.\n const luma =\n 0.299 * (data[o] ?? 0) + 0.587 * (data[o + 1] ?? 0) + 0.114 * (data[o + 2] ?? 0);\n if (luma >= 252) hot++;\n }\n return hot / pixels;\n}\n\n/** Opposite-side length ratio of the quad (1 = fronto-parallel). */\nexport function quadTiltRatio(quad: DocQuad): number {\n const len = (a: { x: number; y: number }, b: { x: number; y: number }) =>\n Math.hypot(b.x - a.x, b.y - a.y);\n const top = len(quad.topLeft, quad.topRight);\n const bottom = len(quad.bottomLeft, quad.bottomRight);\n const left = len(quad.topLeft, quad.bottomLeft);\n const right = len(quad.topRight, quad.bottomRight);\n const h = Math.max(top, bottom) / Math.max(1e-6, Math.min(top, bottom));\n const v = Math.max(left, right) / Math.max(1e-6, Math.min(left, right));\n return Math.max(h, v);\n}\n\n/**\n * Judge one frame. `detectionMode` mirrors the gate: ID-1 quads carry\n * area/aspect/tilt semantics; ID-3 MRZ bands carry width-fraction semantics\n * (band rects are axis-aligned, so tilt/aspect checks are band-specific).\n */\nexport function analyzeDocFrame(input: {\n format: DocFormat;\n quad: DocQuad | null;\n frameWidth: number;\n frameHeight: number;\n measures: DocFrameMeasures;\n thresholds?: Partial<DocGateThresholds>;\n}): DocFrameAnalysis {\n const t = { ...DOC_GATE_V1_DEFAULTS, ...input.thresholds };\n const a = DOC_ANALYSIS_DEFAULTS;\n const { quad, frameWidth, frameHeight, measures } = input;\n const bandMode = input.format === \"ID-3\";\n\n let framing: FramingStatus = \"ok\";\n if (quad === null) {\n framing = \"no_document\";\n } else if (bandMode) {\n const bounds = quadBounds(quad);\n const widthFrac = frameWidth > 0 ? bounds.width / frameWidth : 0;\n const aspect = bounds.height > 0 ? bounds.width / bounds.height : 0;\n if (widthFrac < t.ID3_BAND_MIN_WIDTH_FRAC) framing = \"too_far\";\n else if (edgeClipped(quad, frameWidth, frameHeight, t.EDGE_CLIP_MARGIN_PX)) {\n framing = \"edge_clipped\";\n } else if (aspect < t.ID3_BAND_ASPECT_MIN || aspect > t.ID3_BAND_ASPECT_MAX) {\n framing = \"wrong_shape\";\n }\n } else {\n const areaFrac = quadAreaFrac(quad, frameWidth, frameHeight);\n const band = aspectBand(input.format);\n const bounds = quadBounds(quad);\n const aspect =\n Math.max(bounds.width, bounds.height) / Math.max(1e-6, Math.min(bounds.width, bounds.height));\n if (areaFrac < t.MIN_AREA_FRAC) framing = \"too_far\";\n else if (areaFrac > a.MAX_AREA_FRAC) framing = \"too_close\";\n else if (edgeClipped(quad, frameWidth, frameHeight, t.EDGE_CLIP_MARGIN_PX)) {\n framing = \"edge_clipped\";\n } else if (Math.abs(aspect - band.center) > band.tolerance) framing = \"wrong_shape\";\n else if (quadTiltRatio(quad) > a.TILT_MAX_SIDE_RATIO) framing = \"tilted\";\n }\n\n const lighting: LightingStatus =\n measures.exposure >= t.GUIDE_EXPOSURE\n ? \"ok\"\n : measures.meanLuma < (EXPOSURE_BAND[0] + EXPOSURE_BAND[1]) / 2\n ? \"too_dark\"\n : \"too_bright\";\n const blur: BlurStatus = measures.sharpness >= t.GUIDE_SHARPNESS ? \"ok\" : \"blurry\";\n const glare: GlareStatus =\n measures.specularFraction >= a.GLARE_MAX_SPECULAR_FRAC ? \"glare\" : \"ok\";\n\n return {\n framing,\n lighting,\n blur,\n glare,\n acceptable: framing === \"ok\" && lighting === \"ok\" && blur === \"ok\" && glare === \"ok\",\n };\n}\n\nfunction edgeClipped(\n quad: DocQuad,\n frameWidth: number,\n frameHeight: number,\n margin: number,\n): boolean {\n const pts = [quad.topLeft, quad.topRight, quad.bottomRight, quad.bottomLeft];\n return pts.some(\n (p) => p.x <= margin || p.y <= margin || p.x >= frameWidth - margin || p.y >= frameHeight - margin,\n );\n}\n","// Feedback aggregator (capture v2, Task-37 round 4) — the BlinkID-inspired\n// anti-flicker layer between per-frame analysis and the UI: each frame VOTES\n// for a feedback state; votes decay exponentially over a sliding window and\n// the DOMINANT state wins, but never before the current state's minimum\n// display duration has elapsed. Success states bypass voting entirely.\n//\n// 100% deterministic: the clock is an input (`nowMs`), the decay math is\n// closed-form — golden-testable tick sequences, no timers.\nimport type { DocFrameAnalysis } from \"./frame-analysis\";\n\n/** Feedback vocabulary (dcv2.* message keys on the hosted side). */\nexport type DocFeedbackKey =\n | \"sensing\"\n | \"too_far\"\n | \"too_close\"\n | \"edge_clipped\"\n | \"wrong_shape\"\n | \"tilted\"\n | \"too_dark\"\n | \"too_bright\"\n | \"blurry\"\n | \"glare\"\n | \"hold_still\"\n | \"processing\"\n | \"side_captured\"\n | \"captured\";\n\n/** Reticle rendering mode per feedback state (the stage maps to visuals). */\nexport type ReticleType = \"searching\" | \"coaching\" | \"locking\" | \"processing\" | \"flip\" | \"done\";\n\nexport interface DocFeedbackState {\n key: DocFeedbackKey;\n reticle: ReticleType;\n /** The state holds the UI at least this long (ms) before a switch. */\n minDurationMs: number;\n}\n\nexport const DOC_FEEDBACK_STATES: Readonly<Record<DocFeedbackKey, DocFeedbackState>> =\n Object.freeze({\n sensing: { key: \"sensing\", reticle: \"searching\", minDurationMs: 900 },\n too_far: { key: \"too_far\", reticle: \"coaching\", minDurationMs: 1400 },\n too_close: { key: \"too_close\", reticle: \"coaching\", minDurationMs: 1400 },\n edge_clipped: { key: \"edge_clipped\", reticle: \"coaching\", minDurationMs: 1400 },\n wrong_shape: { key: \"wrong_shape\", reticle: \"coaching\", minDurationMs: 1400 },\n tilted: { key: \"tilted\", reticle: \"coaching\", minDurationMs: 1400 },\n too_dark: { key: \"too_dark\", reticle: \"coaching\", minDurationMs: 1400 },\n too_bright: { key: \"too_bright\", reticle: \"coaching\", minDurationMs: 1400 },\n blurry: { key: \"blurry\", reticle: \"coaching\", minDurationMs: 1400 },\n glare: { key: \"glare\", reticle: \"coaching\", minDurationMs: 1400 },\n hold_still: { key: \"hold_still\", reticle: \"locking\", minDurationMs: 900 },\n processing: { key: \"processing\", reticle: \"processing\", minDurationMs: 800 },\n side_captured: { key: \"side_captured\", reticle: \"flip\", minDurationMs: 2600 },\n captured: { key: \"captured\", reticle: \"done\", minDurationMs: 800 },\n });\n\n/** Frame analysis → the feedback vote it casts (worst axis speaks). */\nexport function feedbackVoteOf(analysis: DocFrameAnalysis): DocFeedbackKey {\n if (analysis.framing === \"no_document\") return \"sensing\";\n if (analysis.framing === \"too_far\") return \"too_far\";\n if (analysis.framing === \"too_close\") return \"too_close\";\n if (analysis.framing === \"edge_clipped\") return \"edge_clipped\";\n if (analysis.framing === \"wrong_shape\") return \"wrong_shape\";\n if (analysis.framing === \"tilted\") return \"tilted\";\n if (analysis.lighting === \"too_dark\") return \"too_dark\";\n if (analysis.lighting === \"too_bright\") return \"too_bright\";\n if (analysis.glare === \"glare\") return \"glare\";\n if (analysis.blur === \"blurry\") return \"blurry\";\n return \"hold_still\";\n}\n\ninterface Vote {\n key: DocFeedbackKey;\n atMs: number;\n}\n\n/** Sliding vote window + exponential decay + per-state minimum hold. */\nexport class DocFeedbackAggregator {\n private votes: Vote[] = [];\n private current: DocFeedbackState = DOC_FEEDBACK_STATES.sensing;\n private currentSinceMs: number | null = null;\n\n constructor(\n private readonly windowMs = 2600,\n /** Per-second decay factor — recent frames outvote stale ones. */\n private readonly decayPerSecond = 0.35,\n ) {}\n\n reset(): void {\n this.votes = [];\n this.current = DOC_FEEDBACK_STATES.sensing;\n this.currentSinceMs = null;\n }\n\n /** Force a terminal/choreography state (capture fired, side flip, upload). */\n force(key: Extract<DocFeedbackKey, \"processing\" | \"side_captured\" | \"captured\">, nowMs: number): DocFeedbackState {\n this.votes = [];\n this.current = DOC_FEEDBACK_STATES[key];\n this.currentSinceMs = nowMs;\n return this.current;\n }\n\n /** Cast this frame's vote and return the (possibly held) winning state. */\n tick(vote: DocFeedbackKey, nowMs: number): DocFeedbackState {\n if (this.currentSinceMs === null) this.currentSinceMs = nowMs;\n this.votes.push({ key: vote, atMs: nowMs });\n this.votes = this.votes.filter((v) => nowMs - v.atMs <= this.windowMs);\n\n // Hold the current state through its minimum display duration.\n if (nowMs - this.currentSinceMs < this.current.minDurationMs) return this.current;\n\n const scores = new Map<DocFeedbackKey, number>();\n for (const v of this.votes) {\n const ageSeconds = (nowMs - v.atMs) / 1000;\n const weight = this.decayPerSecond ** ageSeconds; // 1 now → decays with age\n scores.set(v.key, (scores.get(v.key) ?? 0) + weight);\n }\n let winner: DocFeedbackKey = this.current.key;\n let best = -1;\n for (const [key, score] of scores) {\n if (score > best) {\n best = score;\n winner = key;\n }\n }\n if (winner !== this.current.key) {\n this.current = DOC_FEEDBACK_STATES[winner];\n this.currentSinceMs = nowMs;\n }\n return this.current;\n }\n}\n","// PORTED byte-identical from kyc-ibtikar/lib/faceCaptureV2/media.ts (calibration-pinned\n// capture contract — spec §6 / risk 1). Do NOT edit without a calibration re-validation.\n\n// Pure, framework-free helpers for FaceCaptureV2. No React, minimal DOM.\n\n/** MP4-first ladder: one container (H.264 MP4) covers iOS/macOS Safari + Chrome 130+.\n * WebM/VP9→VP8 only as the Firefox/older-Chromium fallback. */\nexport const MIME_CANDIDATES = [\n \"video/mp4;codecs=avc1.42E01E,mp4a.40.2\",\n \"video/mp4;codecs=avc1.42E01E\",\n \"video/mp4\",\n \"video/webm;codecs=vp9,opus\",\n \"video/webm;codecs=vp9\",\n \"video/webm;codecs=vp8,opus\",\n \"video/webm;codecs=vp8\",\n \"video/webm\",\n] as const;\n\nexport type CameraErrorKind =\n | \"permission\"\n | \"notfound\"\n | \"inuse\"\n | \"overconstrained\"\n | \"insecure\"\n | \"unsupported\"\n | \"generic\";\n\n/** First supported candidate, or \"\" to let the browser pick its own default. */\nexport function pickMimeType(): string {\n const MR = (globalThis as unknown as { MediaRecorder?: { isTypeSupported?: (t: string) => boolean } })\n .MediaRecorder;\n if (!MR || typeof MR.isTypeSupported !== \"function\") return \"\";\n return MIME_CANDIDATES.find((t) => MR.isTypeSupported!(t)) ?? \"\";\n}\n\n/** Default clip container when pickMimeType() === \"\" — NEVER .bin/octet-stream (REVIEW FIX 5).\n * Prefer the first webm in the ladder the browser most likely defaults to. */\nexport const DEFAULT_CLIP_MIME = \"video/webm\";\n\n/** Branch on err.name (never the message). TypeError ⇒ navigator.mediaDevices was undefined\n * (insecure/unsupported context) — surfaced as \"insecure\". */\nexport function mapGetUserMediaError(err: unknown): CameraErrorKind {\n if (err instanceof TypeError) return \"insecure\";\n const name = (err as { name?: string })?.name ?? \"\";\n switch (name) {\n case \"NotAllowedError\":\n case \"PermissionDeniedError\":\n return \"permission\";\n case \"NotFoundError\":\n case \"DevicesNotFoundError\":\n return \"notfound\";\n case \"NotReadableError\":\n case \"TrackStartError\":\n return \"inuse\";\n case \"OverconstrainedError\":\n case \"ConstraintNotSatisfiedError\":\n return \"overconstrained\";\n default:\n return \"generic\";\n }\n}\n\nexport function cameraPreflight(): \"INSECURE_CONTEXT\" | \"UNSUPPORTED\" | \"OK\" {\n const w = globalThis as unknown as { window?: { isSecureContext?: boolean }; navigator?: Navigator };\n if (typeof w.window !== \"undefined\" && w.window.isSecureContext === false)\n return \"INSECURE_CONTEXT\";\n const md = (w.navigator as Navigator | undefined)?.mediaDevices as\n | { getUserMedia?: unknown }\n | undefined;\n if (!md || typeof md.getUserMedia !== \"function\") return \"UNSUPPORTED\";\n return \"OK\";\n}\n\n/** iOS Safari (and any browser) may lack MediaRecorder entirely — detect BEFORE prompting\n * for the camera so we can fall back to the v1 single-photo path (REVIEW FIX 1). */\nexport function isMediaRecorderSupported(): boolean {\n const MR = (globalThis as unknown as { MediaRecorder?: { isTypeSupported?: unknown } }).MediaRecorder;\n return typeof MR !== \"undefined\" && typeof (MR as { isTypeSupported?: unknown }).isTypeSupported === \"function\";\n}\n\nexport const MAX_CLIP_BYTES = 8 * 1024 * 1024; // 8 MB hard cap (shared with the /api/liveness/v2 contract)\nexport function isClipTooLarge(blob: Blob): boolean {\n return blob.size > MAX_CLIP_BYTES;\n}\n\nexport function extForMime(mime: string): string {\n const m = (mime || \"\").toLowerCase();\n if (m.startsWith(\"image/jpeg\")) return \"jpg\";\n if (m.startsWith(\"video/mp4\")) return \"mp4\";\n if (m.startsWith(\"video/webm\")) return \"webm\";\n // Never .bin — default to the clip container we actually record (REVIEW FIX 5).\n return \"webm\";\n}\n\n/** Build the exact multipart body /api/liveness/v2 expects: fields `token`, files `clip` + `keyframe`.\n * Caller must NOT set Content-Type — the browser adds the boundary. */\nexport function buildLivenessV2FormData(args: {\n token: string;\n clip: Blob;\n keyframe: Blob;\n ts?: number;\n}): FormData {\n const { token, clip, keyframe } = args;\n const ts = args.ts ?? Date.now();\n const clipType = clip.type || DEFAULT_CLIP_MIME;\n const kfType = keyframe.type || \"image/jpeg\";\n const fd = new FormData();\n fd.append(\"token\", token);\n fd.append(\"clip\", new File([clip], `liveness-${ts}.${extForMime(clipType)}`, { type: clipType }));\n fd.append(\"keyframe\", new File([keyframe], `keyframe-${ts}.${extForMime(kfType)}`, { type: kfType }));\n return fd;\n}\n","// Device profiles (Task 9) — LOW/MID/HIGH from a boot probe, refined by the\n// first measured detect times. Profiles adapt DETECTION cost only (cadence,\n// downscale input width, animation richness): clip constraints are NOT here —\n// the 720p/2.5Mbps floor is global (locked decision 1) and lives in the v1\n// constraint builder both engines share.\n\nexport type DeviceClass = \"LOW\" | \"MID\" | \"HIGH\";\n\nexport interface DeviceProfile {\n /** Detection cadence — the scheduler's pace. */\n cadenceHz: number;\n /** Downscaled snapshot width handed to the detector. */\n inputWidth: number;\n /** Chrome hint: 'reduced' tones down ticks/breathe on LOW even without\n * prefers-reduced-motion. */\n animations: \"full\" | \"reduced\";\n}\n\nexport const DEVICE_PROFILES: Readonly<Record<DeviceClass, Readonly<DeviceProfile>>> =\n Object.freeze({\n LOW: Object.freeze({ cadenceHz: 5, inputWidth: 128, animations: \"reduced\" as const }),\n MID: Object.freeze({ cadenceHz: 8, inputWidth: 160, animations: \"full\" as const }),\n HIGH: Object.freeze({ cadenceHz: 10, inputWidth: 192, animations: \"full\" as const }),\n });\n\nexport interface DeviceProbe {\n cores: number;\n /** null where the UA hides it — iOS Safari NEVER exposes deviceMemory\n * (field lesson: a 2GB default classified every iPhone LOW). Unknown is\n * treated as NEUTRAL (4GB): never demotes to LOW on its own, never\n * promotes to HIGH; the dynamic profiler corrects truly slow devices. */\n memGB: number | null;\n /** WebAssembly SIMD available (informs wasm-tier expectations/telemetry). */\n simd: boolean;\n}\n\n/** Canonical WASM SIMD feature-test module (validates only where SIMD is\n * supported) — the standard wasm-feature-detect bytes. */\nconst SIMD_TEST_BYTES = new Uint8Array([\n 0, 97, 115, 109, 1, 0, 0, 0, 1, 5, 1, 96, 0, 1, 123, 3, 2, 1, 0, 10, 10, 1, 8, 0, 65, 0, 253,\n 15, 253, 98, 11,\n]);\n\nexport function probeDevice(): DeviceProbe {\n const nav = typeof navigator === \"undefined\" ? undefined : navigator;\n let simd = false;\n try {\n simd = typeof WebAssembly !== \"undefined\" && WebAssembly.validate(SIMD_TEST_BYTES);\n } catch {\n simd = false;\n }\n return {\n cores: nav?.hardwareConcurrency ?? 2,\n memGB: (nav as { deviceMemory?: number } | undefined)?.deviceMemory ?? null,\n simd,\n };\n}\n\n/** Static class: LOW (<4 cores or <3GB), HIGH (≥8 cores AND ≥6GB), else MID.\n * Unknown memory counts as a neutral 4GB (see DeviceProbe.memGB). */\nexport function classifyDevice(probe: DeviceProbe): DeviceClass {\n const memGB = probe.memGB ?? 4;\n if (probe.cores < 4 || memGB < 3) return \"LOW\";\n if (probe.cores >= 8 && memGB >= 6) return \"HIGH\";\n return \"MID\";\n}\n\nconst ORDER: DeviceClass[] = [\"LOW\", \"MID\", \"HIGH\"];\n\n/** Dynamic refinement: after the FIRST 10 measured detect ticks, a mean over\n * 70ms demotes straight to LOW; under 25ms promotes ONE class — at most one\n * adjustment ever (no oscillation). */\nexport class DeviceProfiler {\n private current: DeviceClass;\n private readonly samples: number[] = [];\n private adjusted = false;\n\n constructor(initial: DeviceClass) {\n this.current = initial;\n }\n\n get deviceClass(): DeviceClass {\n return this.current;\n }\n\n get profile(): DeviceProfile {\n return DEVICE_PROFILES[this.current];\n }\n\n record(detectMs: number): DeviceClass {\n if (this.adjusted || this.samples.length >= 10) return this.current;\n this.samples.push(detectMs);\n if (this.samples.length < 10) return this.current;\n this.adjusted = true;\n const mean = this.samples.reduce((sum, value) => sum + value, 0) / this.samples.length;\n if (mean > 70) {\n this.current = \"LOW\";\n } else if (mean < 25) {\n const index = ORDER.indexOf(this.current);\n this.current = ORDER[Math.min(ORDER.length - 1, index + 1)] ?? this.current;\n }\n return this.current;\n }\n}\n","// CaptureSessionDoc (Task 34) — the THIN document twin of CaptureSessionV3:\n// environment-facing camera, a 480px detect snapshot at the device profile's\n// cadence, DocGateV1 ticks, and on `ready` an UNCROPPED full-resolution still\n// (gate round 2: client-side quad cropping cut the MRZ when corners were off;\n// kyc-docs-v2 runs its own detector/warp — the client's job is timing, not\n// geometry). Same event contract SHAPE as CaptureSessionV3\n// (`statechange | checks | guidance | artifacts | error`) so hosts bind it\n// with the same hook pattern. Every effect is seam-injectable for tests; the\n// gate itself stays 100% deterministic (clock = tick input).\nimport { mapGetUserMediaError } from \"../media\";\nimport type { CaptureArtifacts, CaptureErrorKind, CaptureState } from \"../types\";\nimport { classifyDevice, type DeviceClass, probeDevice } from \"../v3/device-profile\";\nimport { exposure, meanLuma, sharpness } from \"../v3/frame-quality\";\nimport {\n DocFeedbackAggregator,\n type DocFeedbackState,\n feedbackVoteOf,\n} from \"./feedback-aggregator\";\nimport { analyzeDocFrame, type DocFrameAnalysis, specularFraction } from \"./frame-analysis\";\nimport type { DocFormat, DocSide } from \"./doc-catalog\";\nimport {\n DOC_DETECT_WIDTH,\n DocGateV1,\n type DocGateThresholds,\n type DocGateTick,\n type DocQuad,\n} from \"./doc-gate-v1\";\nimport { detectMrzBand } from \"./mrz-band\";\n\n/**\n * LAZY scanic load (route-budget contract): the vendored detector is ~39KiB gz\n * and must NOT ride the host's session-shell bundle — it is dynamically\n * imported on the FIRST detect tick (the camera-permission prompt gives the\n * fetch plenty of cover). Tests inject `opts.detect` and never touch this.\n */\nlet scanicDetect: ((image: ImageData) => Promise<DocQuad | null>) | null = null;\nasync function lazyScanicDetect(image: ImageData): Promise<DocQuad | null> {\n if (scanicDetect === null) {\n const module_ = await import(\"./detector-scanic\");\n scanicDetect = module_.detectQuad;\n }\n return scanicDetect(image);\n}\n\n/**\n * ID-3 detection (round 3): the MRZ stroke band, NOT page-edge quads — an\n * open booklet's page edges are white-on-white and defeat contour detection\n * (operator field finding, twice). The band rect becomes the gate's \"quad\"\n * (ID-3 band-mode geometry). Pure JS — no scanic on the passport path.\n */\nasync function mrzBandDetect(image: ImageData): Promise<DocQuad | null> {\n const band = detectMrzBand(image);\n if (band === null) return null;\n return {\n topLeft: { x: band.x, y: band.y },\n topRight: { x: band.x + band.width, y: band.y },\n bottomRight: { x: band.x + band.width, y: band.y + band.height },\n bottomLeft: { x: band.x, y: band.y + band.height },\n };\n}\n\n/**\n * Pre-fetch + cache the scanic chunk (call when the scan surface MOUNTS, before\n * the camera is even granted) so the first detect tick pays no chunk-fetch\n * latency. Fire-and-forget; failures fall back to the lazy path.\n */\nexport function warmDocDetector(): void {\n if (scanicDetect !== null) return;\n void import(\"./detector-scanic\")\n .then((module_) => {\n scanicDetect = module_.detectQuad;\n })\n .catch(() => undefined);\n}\n\n/** Doc detect cadence per device class — scanic @480px is ~3–8× a face tick,\n * so the doc loop paces slower than the face profiles (findings §1: 2–5 Hz). */\nexport const DOC_CADENCE_HZ: Readonly<Record<DeviceClass, number>> = Object.freeze({\n LOW: 3,\n MID: 5,\n HIGH: 6,\n});\n\nexport interface DocChecksPayload {\n engine: \"docv1\";\n /** Gate integrator 0..1 — the overlay ring. */\n p: number;\n plausible: boolean;\n stableTicks: number;\n quad: DocQuad | null;\n /** Detect-frame size the quad coordinates live in (overlay scaling). */\n frameWidth: number;\n frameHeight: number;\n /** Capture-v2 per-frame status vector (framing/lighting/blur/glare). */\n analysis: DocFrameAnalysis;\n}\n\n/** Artifacts: `keyframe` = the full-res still of the framed side (JPEG). */\nexport type DocArtifacts = CaptureArtifacts & { side?: DocSide };\n\nexport interface CaptureSessionDocEvents {\n statechange: { state: CaptureState };\n checks: DocChecksPayload;\n /** dcv1.* message KEY — hosts translate; never prose. Deduped. */\n guidance: { key: string };\n /** Capture-v2 AGGREGATED feedback (time-decay voted, min-duration held) —\n * the stage's message + reticle channel. Deduped on state key. */\n feedback: DocFeedbackState;\n artifacts: DocArtifacts;\n error: { kind: CaptureErrorKind; retryable: boolean };\n}\n\nexport interface CaptureSessionDocOptions {\n /** Host-owned <video playsInline muted>. */\n video: HTMLVideoElement;\n format?: DocFormat;\n /** Side label stamped on the artifacts event (recto→verso sequencing). */\n side?: DocSide;\n thresholds?: Partial<DocGateThresholds>;\n deviceClass?: DeviceClass;\n // ── seams (production defaults in parens) ─────────────────────────────────\n /** (navigator.mediaDevices.getUserMedia — environment camera) */\n getUserMedia?: (constraints: MediaStreamConstraints) => Promise<MediaStream>;\n /** (vendored scanic detectQuad) */\n detect?: (image: ImageData) => Promise<DocQuad | null>;\n /** (canvas downscale of the live video to the 480px detect frame) */\n grabDetectFrame?: (video: HTMLVideoElement, targetWidth: number) => ImageData | null;\n /** (full-res canvas still → JPEG blob + preview; quad passed for telemetry) */\n captureStill?: (\n video: HTMLVideoElement,\n quad: DocQuad,\n detectSize: { width: number; height: number },\n ) => Promise<{ blob: Blob; previewDataUrl: string }>;\n /** (performance.now) */\n now?: () => number;\n /** (setTimeout/clearTimeout) — the cadence pacer. */\n setTimer?: (fn: () => void, ms: number) => ReturnType<typeof setTimeout>;\n clearTimer?: (id: ReturnType<typeof setTimeout>) => void;\n}\n\ntype Handler<K extends keyof CaptureSessionDocEvents> = (\n payload: CaptureSessionDocEvents[K],\n) => void;\n\nexport class CaptureSessionDoc {\n private readonly opts: CaptureSessionDocOptions;\n private readonly gate: DocGateV1;\n private readonly cadenceMs: number;\n private readonly handlers = new Map<string, Set<(payload: never) => void>>();\n private stream: MediaStream | null = null;\n private timer: ReturnType<typeof setTimeout> | null = null;\n private state: CaptureState = \"idle\";\n private lastGuidance: string | null = null;\n private attempt = 0;\n private capturing = false;\n private readonly feedback = new DocFeedbackAggregator();\n private lastFeedbackKey: string | null = null;\n\n constructor(opts: CaptureSessionDocOptions) {\n this.opts = opts;\n this.gate = new DocGateV1(opts.format ?? \"ID-1\", opts.thresholds);\n const deviceClass = opts.deviceClass ?? classifyDevice(probeDevice());\n this.cadenceMs = 1000 / DOC_CADENCE_HZ[deviceClass];\n }\n\n on<K extends keyof CaptureSessionDocEvents>(event: K, handler: Handler<K>): () => void {\n let set = this.handlers.get(event);\n if (!set) {\n set = new Set();\n this.handlers.set(event, set);\n }\n set.add(handler as (payload: never) => void);\n return () => set?.delete(handler as (payload: never) => void);\n }\n\n private emit<K extends keyof CaptureSessionDocEvents>(\n event: K,\n payload: CaptureSessionDocEvents[K],\n ): void {\n for (const handler of [...(this.handlers.get(event) ?? [])]) {\n (handler as Handler<K>)(payload);\n }\n }\n\n async start(): Promise<void> {\n const attempt = ++this.attempt;\n this.gate.reset();\n this.feedback.reset();\n this.lastFeedbackKey = null;\n this.lastGuidance = null;\n this.capturing = false;\n this.setState(\"preflight\");\n try {\n const getUserMedia =\n this.opts.getUserMedia ??\n ((constraints: MediaStreamConstraints) =>\n navigator.mediaDevices.getUserMedia(constraints));\n this.setState(\"acquiring\");\n this.stream = await getUserMedia({\n audio: false,\n video: {\n facingMode: { ideal: \"environment\" },\n width: { ideal: 1920 },\n height: { ideal: 1080 },\n },\n });\n if (attempt !== this.attempt) {\n for (const track of this.stream.getTracks()) track.stop();\n return;\n }\n this.opts.video.srcObject = this.stream;\n await this.opts.video.play().catch(() => undefined);\n this.setState(\"positioning\");\n this.scheduleTick(attempt);\n } catch (err) {\n const kind = mapGetUserMediaError(err);\n this.setState(\"error\");\n this.emit(\"error\", { kind, retryable: true });\n }\n }\n\n /** Restart the gate for another side / a retake (same stream). */\n rearm(side?: DocSide): void {\n if (side !== undefined) this.opts.side = side;\n this.gate.reset();\n this.feedback.reset();\n this.lastFeedbackKey = null;\n this.lastGuidance = null;\n this.capturing = false;\n if (this.state === \"captured\") {\n this.setState(\"positioning\");\n this.scheduleTick(this.attempt);\n }\n }\n\n destroy(): void {\n this.attempt += 1;\n if (this.timer !== null) (this.opts.clearTimer ?? clearTimeout)(this.timer);\n this.timer = null;\n if (this.stream) for (const track of this.stream.getTracks()) track.stop();\n this.stream = null;\n this.opts.video.srcObject = null;\n }\n\n private setState(state: CaptureState): void {\n this.state = state;\n this.emit(\"statechange\", { state });\n }\n\n private scheduleTick(attempt: number): void {\n const setTimer = this.opts.setTimer ?? setTimeout;\n this.timer = setTimer(() => void this.tick(attempt), this.cadenceMs);\n }\n\n private async tick(attempt: number): Promise<void> {\n if (attempt !== this.attempt || this.state !== \"positioning\" || this.capturing) return;\n const now = this.opts.now ?? (() => performance.now());\n const grab = this.opts.grabDetectFrame ?? defaultGrabDetectFrame;\n const detect =\n this.opts.detect ??\n ((this.opts.format ?? \"ID-1\") === \"ID-3\" ? mrzBandDetect : lazyScanicDetect);\n\n const frame = grab(this.opts.video, DOC_DETECT_WIDTH);\n if (frame === null) {\n this.scheduleTick(attempt);\n return;\n }\n let quad: DocQuad | null = null;\n try {\n quad = await detect(frame);\n } catch {\n quad = null; // a detector hiccup is a no-doc tick, never a crash\n }\n if (attempt !== this.attempt) return;\n\n const crop = quad !== null ? cropQuadRegion(frame, quad) : frame;\n const atMs = now();\n const measures = {\n sharpness: sharpness(crop),\n exposure: exposure(crop),\n meanLuma: meanLuma(crop),\n specularFraction: specularFraction(crop),\n };\n const analysis = analyzeDocFrame({\n format: this.opts.format ?? \"ID-1\",\n quad,\n frameWidth: frame.width,\n frameHeight: frame.height,\n measures,\n ...(this.opts.thresholds !== undefined ? { thresholds: this.opts.thresholds } : {}),\n });\n const tick = this.gate.tick({\n timestampMs: atMs,\n quad,\n quality: measures,\n frameWidth: frame.width,\n frameHeight: frame.height,\n });\n this.emit(\"checks\", {\n engine: \"docv1\",\n p: tick.p,\n plausible: tick.plausible,\n stableTicks: tick.stableTicks,\n quad: tick.quad,\n frameWidth: frame.width,\n frameHeight: frame.height,\n analysis,\n });\n // Capture-v2 feedback: time-decay voted + min-duration held (anti-flicker).\n const feedbackState = this.feedback.tick(feedbackVoteOf(analysis), atMs);\n if (feedbackState.key !== this.lastFeedbackKey) {\n this.lastFeedbackKey = feedbackState.key;\n this.emit(\"feedback\", feedbackState);\n }\n if (tick.guidanceKey !== this.lastGuidance) {\n this.lastGuidance = tick.guidanceKey;\n this.emit(\"guidance\", { key: tick.guidanceKey });\n }\n\n if (tick.ready && quad !== null) {\n const processing = this.feedback.force(\"processing\", atMs);\n this.lastFeedbackKey = processing.key;\n this.emit(\"feedback\", processing);\n await this.fire(attempt, quad, {\n width: frame.width,\n height: frame.height,\n tickSharpness: measures.sharpness,\n });\n return;\n }\n this.scheduleTick(attempt);\n }\n\n /**\n * BEST-FRAME capture window (capture-v2): the first ready tick captures a\n * candidate immediately, then up to CAPTURE_EXTRA_CANDIDATES more stills are\n * taken at CAPTURE_CANDIDATE_SPACING_MS while the user holds — each scored\n * by the live detect-tick sharpness at its capture moment — and the SHARPEST\n * wins. Beats first-acceptable-frame capture without decoding stills.\n */\n private async fire(\n attempt: number,\n quad: DocQuad,\n detectSize: { width: number; height: number; tickSharpness: number },\n ): Promise<void> {\n this.capturing = true;\n const capture = this.opts.captureStill ?? defaultCaptureStill;\n const grab = this.opts.grabDetectFrame ?? defaultGrabDetectFrame;\n const setTimer = this.opts.setTimer ?? setTimeout;\n const size = { width: detectSize.width, height: detectSize.height };\n try {\n let best = {\n still: await capture(this.opts.video, quad, size),\n sharpness: detectSize.tickSharpness,\n };\n for (let i = 0; i < CAPTURE_EXTRA_CANDIDATES; i++) {\n await new Promise<void>((resolve) => {\n setTimer(() => resolve(), CAPTURE_CANDIDATE_SPACING_MS);\n });\n if (attempt !== this.attempt) return;\n const frame = grab(this.opts.video, DOC_DETECT_WIDTH);\n if (frame === null) continue;\n const candidateSharpness = sharpness(cropQuadRegion(frame, quad));\n if (candidateSharpness > best.sharpness * CAPTURE_IMPROVEMENT_MIN_RATIO) {\n const still = await capture(this.opts.video, quad, size);\n if (attempt !== this.attempt) return;\n best = { still, sharpness: candidateSharpness };\n }\n }\n if (attempt !== this.attempt) return;\n this.setState(\"captured\");\n this.emit(\"artifacts\", {\n keyframe: best.still.blob,\n previewDataUrl: best.still.previewDataUrl,\n ...(this.opts.side !== undefined ? { side: this.opts.side } : {}),\n });\n } catch {\n if (attempt !== this.attempt) return;\n // Still capture failed (canvas/encode) — rearm the gate and keep coaching.\n this.capturing = false;\n this.gate.reset();\n this.scheduleTick(attempt);\n }\n }\n}\n\n/** Best-frame window: 2 extra candidates, 260ms apart, ≥8% sharper to replace. */\nexport const CAPTURE_EXTRA_CANDIDATES = 2;\nexport const CAPTURE_CANDIDATE_SPACING_MS = 260;\nconst CAPTURE_IMPROVEMENT_MIN_RATIO = 1.08;\n\n/** Downscale the live video to the detect width (aspect preserved). */\nfunction defaultGrabDetectFrame(video: HTMLVideoElement, targetWidth: number): ImageData | null {\n const vw = video.videoWidth;\n const vh = video.videoHeight;\n if (vw === 0 || vh === 0) return null;\n const scale = Math.min(1, targetWidth / vw);\n const width = Math.round(vw * scale);\n const height = Math.round(vh * scale);\n const canvas = document.createElement(\"canvas\");\n canvas.width = width;\n canvas.height = height;\n const context = canvas.getContext(\"2d\", { willReadFrequently: true });\n if (context === null) return null;\n context.drawImage(video, 0, 0, width, height);\n return context.getImageData(0, 0, width, height);\n}\n\n/**\n * Capture the FULL-RES frame (gate-timed, UNCROPPED — operator gate round 2):\n * client-side quad cropping cut the MRZ whenever the detected corners were\n * slightly off, and kyc-docs-v2 runs its OWN detector/warp on the server —\n * the client's job is TIMING (fire when framed/steady), not geometry. The\n * quad/detectSize params stay in the seam signature for telemetry/tests.\n */\nasync function defaultCaptureStill(\n video: HTMLVideoElement,\n _quad: DocQuad,\n _detectSize: { width: number; height: number },\n): Promise<{ blob: Blob; previewDataUrl: string }> {\n const canvas = document.createElement(\"canvas\");\n canvas.width = Math.max(1, video.videoWidth);\n canvas.height = Math.max(1, video.videoHeight);\n const context = canvas.getContext(\"2d\");\n if (context === null) throw new Error(\"2d context unavailable\");\n context.drawImage(video, 0, 0, canvas.width, canvas.height);\n const blob = await new Promise<Blob>((resolve, reject) => {\n canvas.toBlob((b) => (b ? resolve(b) : reject(new Error(\"toBlob failed\"))), \"image/jpeg\", 0.92);\n });\n return { blob, previewDataUrl: canvas.toDataURL(\"image/jpeg\", 0.85) };\n}\n\n/** Quad-bbox crop of the DETECT frame — the quality measures run on this. */\nfunction cropQuadRegion(frame: ImageData, quad: DocQuad): ImageData {\n const xs = [quad.topLeft.x, quad.topRight.x, quad.bottomRight.x, quad.bottomLeft.x];\n const ys = [quad.topLeft.y, quad.topRight.y, quad.bottomRight.y, quad.bottomLeft.y];\n const x1 = Math.max(0, Math.floor(Math.min(...xs)));\n const y1 = Math.max(0, Math.floor(Math.min(...ys)));\n const x2 = Math.min(frame.width, Math.ceil(Math.max(...xs)));\n const y2 = Math.min(frame.height, Math.ceil(Math.max(...ys)));\n const width = Math.max(1, x2 - x1);\n const height = Math.max(1, y2 - y1);\n const data = new Uint8ClampedArray(width * height * 4);\n for (let row = 0; row < height; row++) {\n const src = ((y1 + row) * frame.width + x1) * 4;\n data.set(frame.data.subarray(src, src + width * 4), row * width * 4);\n }\n return { data, width, height, colorSpace: frame.colorSpace } as ImageData;\n}\n","// Shared capture helpers — used by BOTH the (now sole) v3 engine and the\n// hosted gate-debug overlay. Extracted from the former v1 capture-session.ts\n// when the v1 engine was removed: the camera constraint tier + the mobile\n// heuristic are engine-agnostic, and the gate-geometry factors feed the\n// hosted debug overlay's tolerance rings. Zero React, calibration-pinned.\n\n/** getUserMedia constraint tier — 720p-class on every device since 2026-07-06.\n * The v2 FAS-CLIP liveness head loses its texture cues below ~720p: the SAME\n * genuine clip scores heads 0.0001 at 720x1280 vs 0.355 at the old 480x360\n * mobile tier, which pushed real users into review (first observed live on\n * staging 2026-07-06; falsified on corpus clips the same day). Dimensions are\n * sensor-relative (landscape); mobile browsers deliver portrait via rotation\n * metadata, which the liveness service's decoder applies (cv2\n * ORIENTATION_AUTO). `isMobile` is kept for call-site compat and future\n * divergence — both tiers are 720p today. Bitrate pairs with VIDEO_BPS in\n * clip-recorder.ts (2.5 Mbps). */\nexport function buildCaptureConstraints(\n isMobile: boolean,\n facingMode: \"user\" | \"environment\",\n): MediaStreamConstraints {\n void isMobile;\n return {\n video: {\n width: { ideal: 1280, max: 1280 },\n height: { ideal: 720, max: 720 },\n facingMode: facingMode,\n frameRate: { ideal: 24, max: 30 },\n },\n audio: false,\n };\n}\n\n/** v1 mobile heuristic (FaceCaptureV2.tsx L216-224). */\nexport function detectIsMobile(): boolean {\n if (typeof window === \"undefined\" || typeof navigator === \"undefined\") return false;\n return (\n window.innerWidth <= 768 ||\n /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(\n String(navigator.userAgent ?? \"\"),\n )\n );\n}\n\n// ── gate geometry factors ─────────────────────────────────────────────────────\n// The calibration-pinned gate math the hosted `?debug=gate` overlay derives its\n// tolerance rings from (lib/gate-geometry-constants.ts). Kept exported here after\n// the v1 FaceGate was removed so the overlay never restates them as literals.\n\n/** Gate radius as a fraction of the guidance circle (v1 L501: circleSize × 0.45). */\nexport const CIRCLE_RADIUS_FACTOR = 0.45;\n/** `inCircle` tolerance as a fraction of the gate radius (v1 L508: r × 0.9). */\nexport const IN_CIRCLE_FACTOR = 0.9;\n/** `centered` tolerance as a fraction of the gate radius (v1 L509: r × 0.4). */\nexport const CENTERED_FACTOR = 0.4;\n","// De-hooked port of kyc-ibtikar/lib/faceCaptureV2/useClipRecorder.ts (calibration-pinned\n// capture contract — spec §6 / risk 1). Framework-free class: useRef → private fields,\n// useCallback(start) → record(), stopAndCleanup + the unmount useEffect → stop().\n// Behavior is the v1 hook's, VERBATIM (iOS workarounds included). Source line references\n// (kyc-ibtikar/lib/faceCaptureV2/useClipRecorder.ts):\n// - constants CLIP_MS / TIMESLICE_MS / STOP_GRACE_MS / VIDEO_BPS ............ L10-13\n// - ClipError(kind, msg?) .................................................. L15-21\n// - guarded double MediaRecorder construction (REVIEW FIX 1) ............... L47-63\n// - single-settle guard + timer clearing ................................... L66-71\n// - finalize: Blob(type = recorder.mimeType || picked || DEFAULT_CLIP_MIME)\n// + post-hoc size-cap check .............................................. L73-82\n// - incremental 8MB cap enforcement on dataavailable (REVIEW FIX 7) ........ L84-100\n// - onstop → finalize, onerror → generic, guarded start(TIMESLICE_MS) ...... L101-109\n// - hard stop at CLIP_MS + iOS stop-grace finalize (REVIEW FIX 3) .......... L111-124\n// - teardown: clear timers, stop recorder, stop ALL tracks (REVIEW FIX 8) .. L128-145\n// V2 additions on top of the verbatim behavior (both zero-impact on clip bytes, both\n// required because a class instance outlives one recording where v1's hook state was\n// remounted fresh): a re-entrancy guard in record(), and clearing stale timers when a\n// new recording starts. See the record() JSDoc.\n// Do NOT edit without a calibration re-validation.\nimport {\n pickMimeType,\n isClipTooLarge,\n MAX_CLIP_BYTES,\n DEFAULT_CLIP_MIME,\n type CameraErrorKind,\n} from \"./media\";\n\nexport const CLIP_MS = 2500; // 2.5s, within the 2.0–3.0s target window\nexport const TIMESLICE_MS = 1000; // periodic dataavailable — iOS reliability workaround\nexport const STOP_GRACE_MS = 1500; // iOS: if onstop never fires, finalize from chunks\n// 2.5 Mbps pairs with the 720p capture tier (capture-session.ts): 1.5 Mbps at\n// 720p over-compresses exactly the texture the FAS-CLIP head needs. ~0.8MB per\n// 2.5s clip — well under the 8MB client cap / 15MB server caps.\nexport const VIDEO_BPS = 2_500_000;\n\nexport type ClipErrorKind = CameraErrorKind | \"cliptoolarge\";\n\nexport class ClipError extends Error {\n kind: ClipErrorKind;\n constructor(kind: ClipErrorKind, msg?: string) {\n super(msg ?? kind);\n this.kind = kind;\n }\n}\n\nexport interface ClipResult {\n blob: Blob;\n /** Container mime the clip was finalized with (recorder.mimeType || picked || DEFAULT_CLIP_MIME). */\n mimeType: string;\n}\n\nexport class ClipRecorder {\n private recorder: MediaRecorder | null = null;\n private stream: MediaStream | null = null; // own field so teardown can stop tracks (REVIEW FIX 8)\n private chunks: Blob[] = [];\n private bytes = 0;\n private hardStopTimer: ReturnType<typeof setTimeout> | null = null;\n private graceTimer: ReturnType<typeof setTimeout> | null = null;\n private settled = false;\n\n private clearTimers(): void {\n if (this.hardStopTimer) clearTimeout(this.hardStopTimer);\n if (this.graceTimer) clearTimeout(this.graceTimer);\n this.hardStopTimer = null;\n this.graceTimer = null;\n }\n\n /** Records CLIP_MS of the stream. Resolves with the clip blob + its container mime;\n * rejects with ClipError. Behavior contract is the v1 hook's `start`, verbatim\n * (iOS workarounds included).\n *\n * ONE RECORDING AT A TIME: chunk/byte/timer state is shared per instance, so a\n * second record() while one is in flight rejects ClipError(\"generic\") instead of\n * corrupting the in-flight clip. (v2 guard — v1's hook was gated by its owning\n * component; a class API invites reuse. Zero impact on clip bytes.)\n *\n * `onStopped` (optional) fires ONCE the moment the CLIP_MS recording window\n * elapses (the hard-stop), BEFORE finalize — which on iOS can lag up to\n * STOP_GRACE_MS while onstop flushes the last chunk. It lets the host freeze\n * the display on the already-captured keyframe the instant recording ends,\n * instead of waiting for the blob. PURE NOTIFICATION — it does not touch\n * timers, chunks, or the finalize path, so it is calibration-neutral (no\n * effect on clip bytes). Never fires on a rejected capture (error /\n * cliptoolarge settle before the hard-stop and clear the timer). */\n record(stream: MediaStream, onStopped?: () => void): Promise<ClipResult> {\n if (this.recorder && !this.settled) {\n return Promise.reject(\n new ClipError(\n \"generic\",\n \"record() called while a recording is in flight — ClipRecorder handles one recording at a time\",\n ),\n );\n }\n this.recorder = null; // so a failed construction below never blocks a retry\n // De-hooking correction (zero impact on clip bytes): v1 got fresh refs per hook\n // mount, so a previous recording's post-settle grace timer (the hard-stop callback\n // arms it AFTER settle cleared timers — v1-verbatim) could never leak into a new\n // one. On a reused instance it would fire mid-flight, settle the fresh state, and\n // clear the new hard-stop timer — so drop stale timers before starting.\n this.clearTimers();\n this.chunks = [];\n this.bytes = 0;\n this.settled = false;\n this.stream = stream;\n const picked = pickMimeType();\n\n return new Promise<ClipResult>((resolve, reject) => {\n // Guarded construction — iOS Safari may lack MediaRecorder entirely (REVIEW FIX 1).\n let recorder: MediaRecorder;\n try {\n recorder = new MediaRecorder(\n stream,\n picked\n ? { mimeType: picked, videoBitsPerSecond: VIDEO_BPS }\n : { videoBitsPerSecond: VIDEO_BPS },\n );\n } catch {\n try {\n recorder = new MediaRecorder(stream); // last resort: browser defaults\n } catch {\n reject(new ClipError(\"unsupported\"));\n return;\n }\n }\n this.recorder = recorder;\n\n const settle = (fn: () => void) => {\n if (this.settled) return;\n this.settled = true;\n this.clearTimers();\n fn();\n };\n\n const finalize = () =>\n settle(() => {\n const type = recorder.mimeType || picked || DEFAULT_CLIP_MIME;\n const blob = new Blob(this.chunks, { type });\n if (isClipTooLarge(blob)) {\n reject(new ClipError(\"cliptoolarge\"));\n return;\n }\n resolve({ blob, mimeType: type });\n });\n\n recorder.ondataavailable = (e: BlobEvent) => {\n if (e.data && e.data.size) {\n this.chunks.push(e.data);\n this.bytes += e.data.size;\n // Enforce the 8MB cap INCREMENTALLY — stop + reject as soon as exceeded (REVIEW FIX 7).\n if (this.bytes > MAX_CLIP_BYTES) {\n settle(() => {\n try {\n if (recorder.state !== \"inactive\") recorder.stop();\n } catch {\n /* noop */\n }\n reject(new ClipError(\"cliptoolarge\"));\n });\n }\n }\n };\n recorder.onstop = finalize;\n recorder.onerror = () => settle(() => reject(new ClipError(\"generic\")));\n\n try {\n recorder.start(TIMESLICE_MS);\n } catch {\n settle(() => reject(new ClipError(\"generic\")));\n return;\n }\n\n // Hard stop at CLIP_MS; gate on state, not on frame count.\n this.hardStopTimer = setTimeout(() => {\n // Recording window elapsed — the clip is DONE. Notify BEFORE finalize\n // (which may lag on iOS) so the host can freeze on the keyframe now.\n // Guarded by `settled`: an error/cliptoolarge before the hard-stop has\n // already cleared this timer, so this only runs for a real stop.\n if (!this.settled) onStopped?.();\n if (recorder.state !== \"inactive\") {\n try {\n recorder.stop();\n } catch {\n finalize();\n }\n // iOS safety-net: onstop may never fire — finalize from chunks (REVIEW FIX 3).\n this.graceTimer = setTimeout(finalize, STOP_GRACE_MS);\n } else {\n finalize();\n }\n }, CLIP_MS);\n });\n }\n\n /** Idempotent teardown: stop recorder + ALL tracks (v1 `stopAndCleanup` + the unmount\n * effect). Optional `stream` override mirrors v1's `stopAndCleanup(stream?)`.\n *\n * MID-RECORDING SEMANTICS (verbatim v1): calling stop() while a record() is in\n * flight may LATER resolve the pending promise with a TRUNCATED clip (recorder.stop()\n * fires onstop → finalize from whatever chunks arrived so far), or — because this\n * method clears the hard-stop/grace timers — never settle it at all if onstop never\n * fires (the iOS grace path has been torn down). Callers MUST NOT treat a resolution\n * arriving after stop() as a full CLIP_MS clip, and must not await a record()\n * promise past stop() without their own timeout. (Task 4's CaptureSession owns\n * sequencing on top of this contract.) */\n stop(stream?: MediaStream | null): void {\n this.clearTimers();\n const rec = this.recorder;\n if (rec && rec.state !== \"inactive\") {\n try {\n rec.stop();\n } catch {\n /* noop */\n }\n }\n this.recorder = null;\n const s = stream ?? this.stream;\n s?.getTracks().forEach((t) => t.stop());\n this.stream = null;\n }\n}\n","// PORTED byte-identical from kyc-ibtikar/lib/faceCaptureV2/keyframe.ts (calibration-pinned\n// capture contract — spec §6 / risk 1). Do NOT edit without a calibration re-validation.\n\n// Grab ONE mirrored frontal keyframe from the live <video> into a JPEG Blob (a file part,\n// not a dataURL). Mirror matches the selfie preview (front camera), same as FaceCapture v1.\nexport function captureMirroredKeyframe(\n video: HTMLVideoElement,\n canvas: HTMLCanvasElement,\n quality = 0.92,\n): Promise<Blob> {\n return new Promise((resolve, reject) => {\n const w = video.videoWidth;\n const h = video.videoHeight;\n if (!w || !h) {\n reject(new Error(\"video-not-ready\"));\n return;\n }\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n reject(new Error(\"no-2d-context\"));\n return;\n }\n canvas.width = w;\n canvas.height = h;\n ctx.scale(-1, 1);\n ctx.drawImage(video, -w, 0);\n canvas.toBlob(\n (blob) => (blob ? resolve(blob) : reject(new Error(\"empty-keyframe\"))),\n \"image/jpeg\",\n quality,\n );\n });\n}\n","// BlazeFace short-range tier (Task 7) — MediaPipe tasks-vision FaceDetector,\n// the modern default: strong on large/close faces, ~15–40ms on low-end\n// WASM+SIMD. tasks-vision is imported LAZILY (only when this tier is\n// selected) and every asset is SELF-HOSTED under the v3 asset base (hosted\n// CSP is connect-src 'self' — no CDN): the wasm fileset via\n// FilesetResolver.forVisionTasks(base) and the model at\n// `${base}/blaze_face_short_range.tflite` (synced by\n// identity-hosted/scripts/sync-models-v3.mjs, sha256-manifested).\n//\n// DELEGATE = 'CPU' (2026-07-09, capture-v3 hardening — the load-bearing fix):\n// tasks-vision defaults `baseOptions.delegate` to the WebGL/GPU delegate,\n// which HANGS on iOS Safari — every field capture blew the 10s init deadline\n// (`blaze:blaze_init_timeout`) and silently fell to the deprecated face-api\n// floor at ~2.4fps. BlazeFace short-range is tiny (~229 KB) and fast on the\n// WASM+SIMD CPU delegate, so we pin CPU UNCONDITIONALLY: reliability across\n// iOS Safari + Chrome beats the marginal desktop-GPU speedup (and the GPU\n// path is exactly the bug). A GPU-first-with-CPU-fallback dance would only\n// re-introduce the hang risk inside the init budget for no real win.\nimport { type Detector, type FaceObservation, intrinsicSize, toStreamPixels } from \"./detector\";\n\n/** createFromOptions must resolve within this window or the ladder falls\n * through with `blaze_init_timeout` (overridable via CreateDetectorOptions).\n * Raised 5s→10s: on iOS Safari the COLD wasm SIMD compile of tasks-vision can\n * exceed 5s on the FIRST (unwarmed) capture. Since the face-api floor was\n * dropped (2026-07-09), blowing this deadline is now a HARD capture failure\n * (error{kind:'models'} — retryable), not a silent degrade, so the CPU\n * delegate above (which makes init actually complete on iOS) is what keeps\n * this deadline reachable. The hosted warm path\n * (identity-hosted/lib/warm-models.ts) pre-warms this tier in idle time so\n * capture usually reuses a hot instance; this larger deadline only covers the\n * un-warmed fallback (Data-Saver, deep-link straight to liveness). */\nexport const BLAZE_INIT_TIMEOUT_MS = 10_000;\n\ninterface TasksVisionDetection {\n boundingBox?: { originX: number; originY: number; width: number; height: number };\n categories: Array<{ score: number }>;\n /** NORMALIZED to the input image (0..1) — tasks-vision docs; index 0 =\n * right eye, 1 = left eye (SUBJECT perspective). We re-order by image-x\n * (the FaceObservation convention), so the doc order is informative only. */\n keypoints?: Array<{ x: number; y: number }>;\n}\n\ninterface TasksVisionFaceDetector {\n detect(source: unknown): { detections: TasksVisionDetection[] };\n close(): void;\n}\n\nexport class BlazeDetector implements Detector {\n readonly tier = \"blaze\" as const;\n readonly fallbackReason?: string;\n private readonly inner: TasksVisionFaceDetector;\n\n private constructor(inner: TasksVisionFaceDetector, fallbackReason?: string) {\n this.inner = inner;\n if (fallbackReason !== undefined) this.fallbackReason = fallbackReason;\n }\n\n static async create(assetBaseUrl: string, fallbackReason?: string): Promise<BlazeDetector> {\n const vision = await import(\"@mediapipe/tasks-vision\");\n const fileset = await vision.FilesetResolver.forVisionTasks(assetBaseUrl);\n const inner = (await vision.FaceDetector.createFromOptions(fileset, {\n baseOptions: {\n modelAssetPath: `${assetBaseUrl}/blaze_face_short_range.tflite`,\n // CPU delegate — the iOS-Safari-safe path (see header). NEVER 'GPU'.\n delegate: \"CPU\",\n },\n runningMode: \"IMAGE\",\n })) as unknown as TasksVisionFaceDetector;\n return new BlazeDetector(inner, fallbackReason);\n }\n\n async detect(\n source: CanvasImageSource,\n sourceWidth: number,\n sourceHeight: number,\n ): Promise<FaceObservation | null> {\n let detections: TasksVisionDetection[];\n try {\n detections = this.inner.detect(source).detections;\n } catch {\n return null; // never rejects mid-loop\n }\n const best = pickMostConfident(detections);\n if (best?.boundingBox === undefined) return null;\n const size = intrinsicSize(source);\n const eyes = extractEyes(best.keypoints, size);\n const observation: FaceObservation = {\n box: {\n x: best.boundingBox.originX,\n y: best.boundingBox.originY,\n width: best.boundingBox.width,\n height: best.boundingBox.height,\n },\n ...(eyes !== undefined ? { eyes } : {}),\n score: best.categories[0]?.score ?? 0,\n };\n return toStreamPixels(observation, source, sourceWidth, sourceHeight);\n }\n\n destroy(): void {\n try {\n this.inner.close();\n } catch {\n // wasm teardown failures are inert\n }\n }\n}\n\nfunction pickMostConfident(detections: TasksVisionDetection[]): TasksVisionDetection | undefined {\n let best: TasksVisionDetection | undefined;\n let bestScore = -1;\n for (const detection of detections) {\n const score = detection.categories[0]?.score ?? 0;\n if (score > bestScore) {\n best = detection;\n bestScore = score;\n }\n }\n return best;\n}\n\n/** Keypoints 0/1 (the eye pair) — normalized → SOURCE px, ordered by image-x. */\nfunction extractEyes(\n keypoints: Array<{ x: number; y: number }> | undefined,\n size: { width: number; height: number },\n): FaceObservation[\"eyes\"] | undefined {\n const a = keypoints?.[0];\n const b = keypoints?.[1];\n if (a === undefined || b === undefined) return undefined;\n const toSource = (p: { x: number; y: number }) => ({ x: p.x * size.width, y: p.y * size.height });\n const [pa, pb] = [toSource(a), toSource(b)];\n return pa.x <= pb.x ? { left: pa, right: pb } : { left: pb, right: pa };\n}\n","// Native FaceDetector tier (Task 6) — the Shape Detection API: free,\n// hardware-backed where implemented (Chrome/Android, some WebViews). Probed\n// with a 1-frame smoke detect because several browsers EXPOSE the constructor\n// but throw `Face detection service unavailable` at runtime.\nimport { type Detector, type FaceObservation, toStreamPixels } from \"./detector\";\n\ninterface NativeLandmark {\n type: string;\n locations: Array<{ x: number; y: number }>;\n}\n\ninterface NativeDetectedFace {\n boundingBox: { x: number; y: number; width: number; height: number };\n landmarks?: NativeLandmark[];\n}\n\nexport interface NativeFaceDetectorLike {\n detect(source: CanvasImageSource): Promise<NativeDetectedFace[]>;\n}\n\ntype NativeGlobal = typeof globalThis & {\n FaceDetector?: new (options: { fastMode: boolean; maxDetectedFaces: number }) => NativeFaceDetectorLike;\n};\n\nfunction smokeSource(): CanvasImageSource {\n if (typeof OffscreenCanvas === \"function\") return new OffscreenCanvas(2, 2);\n const canvas = document.createElement(\"canvas\");\n canvas.width = 2;\n canvas.height = 2;\n return canvas;\n}\n\n/** Constructor + 1-frame smoke detect (must not throw; result irrelevant). */\nexport async function probeNativeDetector(): Promise<\n { ok: true; instance: NativeFaceDetectorLike } | { ok: false; reason: string }\n> {\n const ctor = (globalThis as NativeGlobal).FaceDetector;\n if (typeof ctor !== \"function\") return { ok: false, reason: \"unsupported\" };\n try {\n const instance = new ctor({ fastMode: true, maxDetectedFaces: 1 });\n await instance.detect(smokeSource());\n return { ok: true, instance };\n } catch (err) {\n return { ok: false, reason: `smoke_failed:${err instanceof Error ? err.message : String(err)}` };\n }\n}\n\nexport class NativeDetector implements Detector {\n readonly tier = \"native\" as const;\n readonly fallbackReason?: string;\n private readonly inner: NativeFaceDetectorLike;\n\n constructor(inner: NativeFaceDetectorLike, fallbackReason?: string) {\n this.inner = inner;\n if (fallbackReason !== undefined) this.fallbackReason = fallbackReason;\n }\n\n async detect(\n source: CanvasImageSource,\n sourceWidth: number,\n sourceHeight: number,\n ): Promise<FaceObservation | null> {\n let faces: NativeDetectedFace[];\n try {\n faces = await this.inner.detect(source);\n } catch {\n return null; // never rejects mid-loop\n }\n const face = faces[0];\n if (face === undefined) return null;\n const eyes = extractEyes(face.landmarks);\n const observation: FaceObservation = {\n box: {\n x: face.boundingBox.x,\n y: face.boundingBox.y,\n width: face.boundingBox.width,\n height: face.boundingBox.height,\n },\n ...(eyes !== undefined ? { eyes } : {}),\n // The Shape Detection API exposes no confidence — the smoke-tested\n // native tier treats any detection as confident.\n score: 1,\n };\n return toStreamPixels(observation, source, sourceWidth, sourceHeight);\n }\n\n destroy(): void {\n // The native detector holds no resources the page must release.\n }\n}\n\n/** Two `eye` landmarks → {left, right} by image-x (see FaceObservation). */\nfunction extractEyes(\n landmarks: NativeLandmark[] | undefined,\n): FaceObservation[\"eyes\"] | undefined {\n if (landmarks === undefined) return undefined;\n const eyePoints = landmarks\n .filter((landmark) => landmark.type === \"eye\")\n .map((landmark) => landmark.locations[0])\n .filter((point): point is { x: number; y: number } => point !== undefined);\n const [a, b] = eyePoints;\n if (a === undefined || b === undefined) return undefined;\n return a.x <= b.x ? { left: a, right: b } : { left: b, right: a };\n}\n","// v3 Detector abstraction (capture program Task 6) — one detection seam with\n// capability-probed tiers. NEW parallel module: nothing in the v1 core\n// imports from v3/*, and the calibration-pinned v1 gate math is untouched.\n//\n// Ladder (DEFAULT_TIER_ORDER): `native` (the browser's FaceDetector — free,\n// hardware-backed where it exists) → `blaze` (MediaPipe BlazeFace short-range,\n// Task 7). The legacy `faceapi` floor was DROPPED (2026-07-09, capture-v3\n// hardening): field telemetry showed BlazeFace never initialized (the GPU\n// delegate hung on iOS → `blaze_init_timeout`) so EVERY capture silently ran\n// the deprecated ~2.4fps face-api floor. With the CPU-delegate blaze fix,\n// face-api is dead weight — and a floor that masks a blaze regression is worse\n// than none, so the ladder is now native→blaze with NO fallback.\n//\n// Contract change: createDetector still never throws while a tier can be\n// built, but with no floor it REJECTS (DetectorLadderError) once the ladder is\n// exhausted — a CLEAN, non-hanging failure carrying the per-tier reasons.\n// CaptureSessionV3.run() maps that rejection to error{kind:'models'}\n// (retryable; the hosted UI renders a retry). A skipped tier still records a\n// `fallbackReason` (exposed on the returned Detector) so a native→blaze\n// fall-through stays observable in telemetry.\nimport { BLAZE_INIT_TIMEOUT_MS, BlazeDetector } from \"./detector-blaze\";\nimport { NativeDetector, probeNativeDetector } from \"./detector-native\";\n\nexport interface FaceObservation {\n /** Stream-pixel box. */\n box: { x: number; y: number; width: number; height: number };\n /** Stream-pixel eye centers when the tier provides them (native:\n * landmarks?, blaze: keypoints). Convention: `left` = smaller x in IMAGE\n * coordinates — gate math only uses the midpoint and |roll|, so the\n * person-left/image-left distinction never matters. */\n eyes?: { left: { x: number; y: number }; right: { x: number; y: number } };\n score: number;\n}\n\nexport interface Detector {\n readonly tier: \"native\" | \"blaze\";\n /** Why higher tiers were skipped (telemetry) — absent when the first\n * preference won. */\n readonly fallbackReason?: string;\n /** Detect on a (possibly downscaled) snapshot; `sourceWidth/Height` are the\n * STREAM dimensions the observation must be normalized to. Returns the\n * single most-confident face or null; NEVER rejects. */\n detect(\n source: CanvasImageSource,\n sourceWidth: number,\n sourceHeight: number,\n ): Promise<FaceObservation | null>;\n destroy(): void;\n}\n\nexport interface CreateDetectorOptions {\n /** v3 self-hosted assets base (tasks-vision wasm + blaze tflite) — hosted\n * serves `/models-v3`, a sha256-manifested directory. */\n v3AssetBaseUrl?: string;\n preferred?: Detector[\"tier\"][];\n /** Test/tuning override for the blaze init deadline. */\n blazeInitTimeoutMs?: number;\n}\n\nexport const DEFAULT_V3_ASSET_BASE_URL = \"/models-v3\";\n\nexport const DEFAULT_TIER_ORDER: Detector[\"tier\"][] = [\"native\", \"blaze\"];\n\n/** Thrown by createDetector when the ENTIRE tier ladder is exhausted. Since the\n * face-api floor was dropped (2026-07-09) there is no last resort, so blaze\n * failing on an already-native-less platform leaves NO detector. Carries the\n * joined per-tier reasons ('native:unsupported; blaze:blaze_init_timeout') as\n * `fallbackReason` for telemetry. Callers MUST map this to a retryable models\n * error — never a hang (CaptureSessionV3.run → error{kind:'models'}). */\nexport class DetectorLadderError extends Error {\n readonly fallbackReason: string;\n constructor(fallbackReason: string) {\n super(`no detector tier available (${fallbackReason})`);\n this.name = \"DetectorLadderError\";\n this.fallbackReason = fallbackReason;\n }\n}\n\n/** Intrinsic pixel size of a snapshot source (video → videoWidth, image →\n * naturalWidth, canvas/bitmap → width). Property-sniffed so worker-side\n * sources (OffscreenCanvas, ImageBitmap) work without instanceof. */\nexport function intrinsicSize(source: CanvasImageSource): { width: number; height: number } {\n const candidate = source as {\n videoWidth?: number;\n videoHeight?: number;\n naturalWidth?: number;\n naturalHeight?: number;\n width?: number | { baseVal?: { value?: number } };\n height?: number | { baseVal?: { value?: number } };\n };\n if (typeof candidate.videoWidth === \"number\" && candidate.videoWidth > 0) {\n return { width: candidate.videoWidth, height: candidate.videoHeight ?? 0 };\n }\n if (typeof candidate.naturalWidth === \"number\" && candidate.naturalWidth > 0) {\n return { width: candidate.naturalWidth, height: candidate.naturalHeight ?? 0 };\n }\n const width = typeof candidate.width === \"number\" ? candidate.width : 0;\n const height = typeof candidate.height === \"number\" ? candidate.height : 0;\n return { width, height };\n}\n\n/** Scale a source-space observation to stream px. Exported for adapters. */\nexport function toStreamPixels(\n observation: FaceObservation,\n source: CanvasImageSource,\n streamWidth: number,\n streamHeight: number,\n): FaceObservation {\n const size = intrinsicSize(source);\n const scaleX = size.width > 0 ? streamWidth / size.width : 1;\n const scaleY = size.height > 0 ? streamHeight / size.height : 1;\n const scalePoint = (p: { x: number; y: number }) => ({ x: p.x * scaleX, y: p.y * scaleY });\n return {\n box: {\n x: observation.box.x * scaleX,\n y: observation.box.y * scaleY,\n width: observation.box.width * scaleX,\n height: observation.box.height * scaleY,\n },\n ...(observation.eyes !== undefined\n ? { eyes: { left: scalePoint(observation.eyes.left), right: scalePoint(observation.eyes.right) } }\n : {}),\n score: observation.score,\n };\n}\n\nfunction describeError(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\nexport async function createDetector(options: CreateDetectorOptions): Promise<Detector> {\n const order = options.preferred ?? DEFAULT_TIER_ORDER;\n const reasons: string[] = [];\n for (const tier of order) {\n if (tier === \"native\") {\n const probed = await probeNativeDetector();\n if (probed.ok) {\n return new NativeDetector(probed.instance, reasonOf(reasons));\n }\n reasons.push(`native:${probed.reason}`);\n continue;\n }\n // tier === \"blaze\": smoke test = createFromOptions resolving within the\n // deadline (wasm fetch/compile can hang on hostile networks — never stall\n // the ladder).\n try {\n return await withTimeout(\n BlazeDetector.create(\n options.v3AssetBaseUrl ?? DEFAULT_V3_ASSET_BASE_URL,\n reasonOf(reasons),\n ),\n options.blazeInitTimeoutMs ?? BLAZE_INIT_TIMEOUT_MS,\n );\n } catch (err) {\n reasons.push(\n err instanceof InitTimeoutError\n ? \"blaze:blaze_init_timeout\"\n : `blaze:${describeError(err)}`,\n );\n }\n }\n // Ladder exhausted — the face-api floor is gone, so there is NO fallback.\n // REJECT cleanly with the recorded reasons; CaptureSessionV3.run() maps this\n // to a retryable error{kind:'models'} (a bounded failure the hosted UI\n // retries) rather than hanging. NEVER return a null-yielding detector here.\n throw new DetectorLadderError(reasonOf(reasons) ?? \"no_tier_available\");\n}\n\nfunction reasonOf(reasons: string[]): string | undefined {\n return reasons.length > 0 ? reasons.join(\"; \") : undefined;\n}\n\nclass InitTimeoutError extends Error {}\n\nfunction withTimeout<T extends { destroy(): void }>(\n promise: Promise<T>,\n deadlineMs: number,\n): Promise<T> {\n return new Promise<T>((resolvePromise, rejectPromise) => {\n const timer = setTimeout(() => {\n rejectPromise(new InitTimeoutError(`init exceeded ${deadlineMs}ms`));\n // A late resolution after the deadline is an orphan (wasm/GPU\n // delegate) — release it instead of leaking until navigation.\n promise.then(\n (value) => value.destroy(),\n () => undefined,\n );\n }, deadlineMs);\n promise.then(\n (value) => {\n clearTimeout(timer);\n resolvePromise(value);\n },\n (err) => {\n clearTimeout(timer);\n rejectPromise(err);\n },\n );\n });\n}\n","// Worker offload (Task 9) — detection off the main thread when the platform\n// allows (OffscreenCanvas + createImageBitmap + Worker). BOTH protocol sides\n// live in this file so the tiny versioned protocol (v:1) can never drift:\n// - installWorkerDetectorHost: runs INSIDE the worker (auto-installed when\n// this module loads in a DedicatedWorkerGlobalScope; tsup builds it as\n// its own entry so hosts can `new Worker(new URL(...))` the dist file);\n// - WorkerDetectorProxy: main-thread Detector implementation that posts\n// ImageBitmap frames as transferables and resolves results by id.\nimport {\n type CreateDetectorOptions,\n createDetector as defaultCreateDetector,\n type Detector,\n type FaceObservation,\n} from \"./detector\";\n\nexport const WORKER_PROTOCOL_VERSION = 1;\n\ninterface InitMessage {\n v: typeof WORKER_PROTOCOL_VERSION;\n type: \"init\";\n options: CreateDetectorOptions;\n}\ninterface DetectMessage {\n v: typeof WORKER_PROTOCOL_VERSION;\n type: \"detect\";\n id: number;\n bitmap: ImageBitmap;\n streamWidth: number;\n streamHeight: number;\n}\ninterface ReadyMessage {\n v: typeof WORKER_PROTOCOL_VERSION;\n type: \"ready\";\n tier: Detector[\"tier\"];\n fallbackReason?: string;\n}\ninterface ResultMessage {\n v: typeof WORKER_PROTOCOL_VERSION;\n type: \"result\";\n id: number;\n observation: FaceObservation | null;\n}\n\ntype ToWorker = InitMessage | DetectMessage;\ntype ToMain = ReadyMessage | ResultMessage;\n\n/** The slice of Worker/scope surface the protocol needs — test-stubbable. */\nexport interface WorkerScopeLike {\n onmessage: ((event: { data: unknown }) => void) | null;\n postMessage(data: unknown): void;\n}\nexport interface WorkerLike {\n postMessage(data: unknown, transfer?: Transferable[]): void;\n addEventListener(type: \"message\", listener: (event: { data: unknown }) => void): void;\n removeEventListener(type: \"message\", listener: (event: { data: unknown }) => void): void;\n terminate(): void;\n}\n\n/** Feature gate: bitmap capture + transfer + workers must all exist. */\nexport function workerOffloadSupported(): boolean {\n return (\n typeof OffscreenCanvas === \"function\" &&\n typeof createImageBitmap === \"function\" &&\n typeof Worker === \"function\"\n );\n}\n\n/** Worker-side message host. `deps.createDetector` is a test seam. */\nexport function installWorkerDetectorHost(\n scope: WorkerScopeLike,\n deps: { createDetector?: (options: CreateDetectorOptions) => Promise<Detector> } = {},\n): void {\n const create = deps.createDetector ?? defaultCreateDetector;\n let detector: Detector | null = null;\n scope.onmessage = (event) => {\n const message = event.data as ToWorker;\n if (message.v !== WORKER_PROTOCOL_VERSION) {\n // Ignore unknown versions — but never strand a transferred bitmap.\n (message as { bitmap?: { close?: () => void } }).bitmap?.close?.();\n return;\n }\n if (message.type === \"init\") {\n void create(message.options).then((created) => {\n detector = created;\n const ready: ReadyMessage = {\n v: WORKER_PROTOCOL_VERSION,\n type: \"ready\",\n tier: created.tier,\n ...(created.fallbackReason !== undefined\n ? { fallbackReason: created.fallbackReason }\n : {}),\n };\n scope.postMessage(ready);\n });\n return;\n }\n if (message.type === \"detect\") {\n const respond = (observation: FaceObservation | null) => {\n const result: ResultMessage = {\n v: WORKER_PROTOCOL_VERSION,\n type: \"result\",\n id: message.id,\n observation,\n };\n scope.postMessage(result);\n (message.bitmap as { close?: () => void }).close?.();\n };\n if (detector === null) {\n respond(null);\n return;\n }\n void detector\n .detect(message.bitmap, message.streamWidth, message.streamHeight)\n .then(respond, () => respond(null));\n }\n };\n}\n\n// Auto-install when this module IS the worker entry (DedicatedWorkerGlobalScope\n// has importScripts; window does not). Inert in main-thread bundles/tests.\ndeclare const self: (WorkerScopeLike & { importScripts?: unknown }) | undefined;\nif (typeof self !== \"undefined\" && typeof self.importScripts === \"function\") {\n installWorkerDetectorHost(self);\n}\n\n/** Main-side Detector over the worker protocol. Same interface as the\n * in-thread detectors — Task 10's engine cannot tell the difference. */\nexport class WorkerDetectorProxy implements Detector {\n readonly tier: Detector[\"tier\"];\n readonly fallbackReason?: string;\n private readonly worker: WorkerLike;\n private readonly pending = new Map<number, (observation: FaceObservation | null) => void>();\n private nextId = 1;\n\n private constructor(worker: WorkerLike, ready: ReadyMessage) {\n this.worker = worker;\n this.tier = ready.tier;\n if (ready.fallbackReason !== undefined) this.fallbackReason = ready.fallbackReason;\n worker.addEventListener(\"message\", (event) => {\n const message = event.data as ToMain;\n if (message.v !== WORKER_PROTOCOL_VERSION || message.type !== \"result\") return;\n const resolve = this.pending.get(message.id);\n this.pending.delete(message.id);\n resolve?.(message.observation);\n });\n }\n\n static create(\n worker: WorkerLike,\n options: CreateDetectorOptions,\n readyTimeoutMs = 10_000,\n ): Promise<WorkerDetectorProxy> {\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n worker.removeEventListener(\"message\", onReady);\n worker.terminate();\n reject(new Error(`worker detector not ready within ${readyTimeoutMs}ms`));\n }, readyTimeoutMs);\n const onReady = (event: { data: unknown }) => {\n const message = event.data as ToMain;\n if (message.v !== WORKER_PROTOCOL_VERSION || message.type !== \"ready\") return;\n clearTimeout(timer);\n worker.removeEventListener(\"message\", onReady);\n resolve(new WorkerDetectorProxy(worker, message));\n };\n worker.addEventListener(\"message\", onReady);\n const init: InitMessage = { v: WORKER_PROTOCOL_VERSION, type: \"init\", options };\n worker.postMessage(init);\n });\n }\n\n async detect(\n source: CanvasImageSource,\n sourceWidth: number,\n sourceHeight: number,\n ): Promise<FaceObservation | null> {\n // Only ImageBitmap is Transferable — convert other sources (video,\n // canvas) via createImageBitmap (the feature gate guarantees it). A\n // failed conversion yields null, never a DataCloneError.\n let bitmap: ImageBitmap;\n try {\n if (typeof ImageBitmap !== \"undefined\" && source instanceof ImageBitmap) {\n bitmap = source;\n } else if (typeof createImageBitmap === \"function\") {\n bitmap = await createImageBitmap(source as ImageBitmapSource);\n } else {\n // No conversion surface (stubbed environments) — trust the caller.\n bitmap = source as ImageBitmap;\n }\n } catch {\n return null;\n }\n const id = this.nextId;\n this.nextId += 1;\n return new Promise((resolve) => {\n this.pending.set(id, resolve);\n const message: DetectMessage = {\n v: WORKER_PROTOCOL_VERSION,\n type: \"detect\",\n id,\n bitmap,\n streamWidth: sourceWidth,\n streamHeight: sourceHeight,\n };\n this.worker.postMessage(message, [bitmap]);\n });\n }\n\n destroy(): void {\n // Settle in-flight detects (an awaiting scheduler run must not hang\n // busy=true forever) before tearing the worker down.\n for (const resolve of this.pending.values()) resolve(null);\n this.pending.clear();\n this.worker.terminate();\n }\n}\n","// Detect scheduler (Task 9) — paces the detection pass at the profile's\n// cadence, preferring requestVideoFrameCallback (runs only when a REAL camera\n// frame arrived) with a plain interval fallback. A tick whose predecessor is\n// still in flight is SKIPPED — never queued (no backlog on a slow device) —\n// and counted as a degrade for telemetry.\n\nexport interface DetectSchedulerOptions {\n /** Ticks per second (profile cadenceHz). */\n cadenceHz: number;\n /** One detection pass — the scheduler awaits it and measures wall time. */\n run: () => Promise<void>;\n /** When provided AND it exposes requestVideoFrameCallback, ticks ride real\n * camera frames (throttled to the cadence) instead of a timer. */\n video?: HTMLVideoElement;\n /** Injectable clock (tests) — defaults to performance.now. */\n now?: () => number;\n}\n\ninterface VideoFrameCallbackTarget {\n requestVideoFrameCallback?: (callback: () => void) => number;\n cancelVideoFrameCallback?: (id: number) => void;\n}\n\n/** Rolling window for meanDetectMs. */\nconst STATS_WINDOW = 20;\n\nexport class DetectScheduler {\n private readonly options: DetectSchedulerOptions;\n private readonly periodMs: number;\n private timer: ReturnType<typeof setInterval> | null = null;\n private frameCallbackId: number | null = null;\n private running = false;\n private busy = false;\n private lastRunAt = Number.NEGATIVE_INFINITY;\n private degradeCount = 0;\n private readonly durations: number[] = [];\n\n constructor(options: DetectSchedulerOptions) {\n this.options = options;\n this.periodMs = 1000 / options.cadenceHz;\n }\n\n start(): void {\n if (this.running) return;\n this.running = true;\n const video = this.options.video as VideoFrameCallbackTarget | undefined;\n if (typeof video?.requestVideoFrameCallback === \"function\") {\n const loop = () => {\n if (!this.running) return;\n this.frameCallbackId = video.requestVideoFrameCallback?.(() => {\n this.frameCallbackId = null;\n // Throttle: camera frames arrive faster than the cadence.\n if (this.now() - this.lastRunAt >= this.periodMs) this.tick();\n loop();\n }) as number;\n };\n loop();\n return;\n }\n this.timer = setInterval(() => this.tick(), this.periodMs);\n }\n\n stop(): void {\n this.running = false;\n if (this.timer !== null) {\n clearInterval(this.timer);\n this.timer = null;\n }\n if (this.frameCallbackId !== null) {\n (this.options.video as VideoFrameCallbackTarget | undefined)?.cancelVideoFrameCallback?.(\n this.frameCallbackId,\n );\n this.frameCallbackId = null;\n }\n }\n\n stats(): { degradeCount: number; meanDetectMs: number } {\n const meanDetectMs =\n this.durations.length === 0\n ? 0\n : this.durations.reduce((sum, value) => sum + value, 0) / this.durations.length;\n return { degradeCount: this.degradeCount, meanDetectMs };\n }\n\n private now(): number {\n return this.options.now?.() ?? performance.now();\n }\n\n private tick(): void {\n if (!this.running) return;\n if (this.busy) {\n // Skip-when-busy: no queue growth on slow devices; telemetry counts it.\n this.degradeCount += 1;\n return;\n }\n this.busy = true;\n this.lastRunAt = this.now();\n const startedAt = this.now();\n this.options\n .run()\n .catch(() => undefined) // a failed pass must never kill the loop\n .finally(() => {\n this.busy = false;\n this.durations.push(this.now() - startedAt);\n if (this.durations.length > STATS_WINDOW) this.durations.shift();\n });\n }\n}\n","// FaceGateV3 (Task 8) — the v3 gate: scale-invariant, landmark-aware,\n// continuous-quality, gentle-drain. PARALLEL to the calibration-pinned v1\n// FaceGate (face-gate.ts) — nothing here feeds or alters v1's math.\n//\n// Design deltas vs v1 (the two field complaints this kills):\n// - the gate point is the EYE MIDPOINT when the tier provides eyes (humans\n// center their EYES, detectors center their BBOX — v1's bbox-center gate\n// read a centered face as \"high\"); box-only tiers get a documented\n// 0.12×height upward shift instead;\n// - progress is a CONTINUOUS integrator (rise 0.9/s on good quality, fall\n// 0.25/s on bad) instead of v1's ±counters — a wobble dips the progress\n// slightly instead of resetting the attempt.\n//\n// q AGGREGATION = MIN over factors (operator ruling 2026-07-12, replacing\n// the original 7-factor PRODUCT). Field finding: with a product, seven\n// factors each at a decent 0.85 gave q≈0.32 — progress DRAINED while every\n// factor sat above its guidance threshold, so the chrome said \"hold still\"\n// and the only discoverable escape was leaning unnaturally close (size,\n// centering falloff (∝IOD) and crop sharpness all improve together with\n// proximity). min() makes q the same quantity guidance reasons about — the\n// worst factor — so \"no complaint\" ⇔ \"progress rises\" by construction, one\n// genuinely bad factor still blocks (non-compensatory), and many mediocre\n// factors (the low-end-device reality: noisy sensor, dim room, wide FOV)\n// are no longer multiplied into failure.\n//\n// 100% deterministic: the clock is a tick INPUT (timestampMs); nothing here\n// reads Date.now or performance.now.\nimport type { FaceObservation } from \"./detector\";\nimport { EXPOSURE_BAND } from \"./frame-quality\";\n\nexport interface V3GateThresholds {\n /** q at/above which progress rises; below it progress falls. */\n Q_GOOD: number;\n /** Integrator slopes, per second. */\n RISE_PER_S: number;\n FALL_PER_S: number;\n /** Centering falloff radius = this × IOD (scale-invariant). The plan's\n * formula is 0.45 × IOD × 3 — the 0.45 echoes v1's CIRCLE_RADIUS_FACTOR\n * heritage — folded here to 1.35 × IOD. */\n CENTER_FALLOFF_IOD_MULTIPLE: number;\n /** Box-only tiers: gate point = bbox center shifted UP by this × height\n * (the documented bbox-vs-eyes offset heuristic). */\n BOX_EYE_OFFSET_FACTOR: number;\n /** Box-only IOD proxy = this × box width. */\n IOD_BOX_PROXY_FACTOR: number;\n /** IOD / frame short side: ideal band + hard limits. */\n SIZE_IDEAL_MIN: number;\n SIZE_IDEAL_MAX: number;\n SIZE_HARD_MIN: number;\n SIZE_HARD_MAX: number;\n /** Eye-line roll (deg) that zeroes the pose factor. */\n ROLL_MAX_DEG: number;\n /** Center velocity that zeroes the motion factor, in IOD-per-second. */\n MOTION_VELOCITY_IOD_PER_S: number;\n /** Velocity-EMA time constant (seconds) — the EMA weight is derived per\n * tick as 1−exp(−dt/τ), so the smoothing HORIZON is cadence-invariant:\n * a LOW device detecting at 5 Hz gets the same effective smoothing as a\n * HIGH device at 10 Hz (a fixed per-sample alpha under-smoothed exactly\n * the jittery low-cadence ticks that needed it most). */\n MOTION_TAU_S: number;\n /** Velocities at/below this (IOD/s) count as stillness — absorbs detector\n * box jitter (largest on LOW's 128px input) before it reaches the EMA. */\n MOTION_DEADBAND_IOD_PER_S: number;\n /** ready = p ≥ 1 AND mean q over this window ≥ READY_MEAN_Q. The mean is\n * TRIMMED: with ≥3 samples in the window the single worst is dropped, so\n * one flaky tick (5 Hz LOW cadence = only 2–3 samples per window) cannot\n * veto an otherwise-ready user. */\n READY_WINDOW_MS: number;\n READY_MEAN_Q: number;\n /** Per-factor guidance trigger levels (lowest failing factor speaks). */\n GUIDE_SIZE: number;\n GUIDE_CENTERING: number;\n GUIDE_POSE: number;\n GUIDE_EXPOSURE: number;\n GUIDE_SHARPNESS: number;\n GUIDE_MOTION: number;\n}\n\n/** Defaults — retuned 2026-07-12 (operator ruling superseding the 2026-07\n * freeze; the capture Task-15 refit set must be split at this boundary):\n * Q_GOOD 0.55→0.6 so it aligns with the 0.6 guidance thresholds under\n * min-q (\"no complaint\" ⇔ \"progress rises\"); SIZE_IDEAL_MIN 0.16→0.12 —\n * wide-FOV front cameras (common low-end) put an arm's-length face below\n * 0.16, silently forcing lean-in; the 720p clip floor keeps a 0.12-IOD\n * face fully resolvable server-side. */\nexport const V3_GATE_DEFAULTS: Readonly<V3GateThresholds> = Object.freeze({\n Q_GOOD: 0.6,\n RISE_PER_S: 0.9,\n FALL_PER_S: 0.25,\n CENTER_FALLOFF_IOD_MULTIPLE: 1.35,\n BOX_EYE_OFFSET_FACTOR: 0.12,\n IOD_BOX_PROXY_FACTOR: 0.42,\n SIZE_IDEAL_MIN: 0.12,\n SIZE_IDEAL_MAX: 0.3,\n SIZE_HARD_MIN: 0.08,\n SIZE_HARD_MAX: 0.45,\n ROLL_MAX_DEG: 25,\n MOTION_VELOCITY_IOD_PER_S: 0.5,\n MOTION_TAU_S: 0.4,\n MOTION_DEADBAND_IOD_PER_S: 0.1,\n READY_WINDOW_MS: 500,\n // 0.7→0.75 with the trimmed window: trimming forgives exactly ONE flaky\n // tick; the raised mean keeps a SECOND bad tick (a real sustained wobble)\n // from diluting through at 10 Hz cadences.\n READY_MEAN_Q: 0.75,\n GUIDE_SIZE: 0.6,\n GUIDE_CENTERING: 0.6,\n GUIDE_POSE: 0.6,\n GUIDE_EXPOSURE: 0.6,\n GUIDE_SHARPNESS: 0.35,\n GUIDE_MOTION: 0.5,\n});\n\nexport interface V3GateQuality {\n /** From frame-quality.sharpness on the face crop. */\n sharpness: number;\n /** From frame-quality.exposure on the face crop. */\n exposure: number;\n /** Mean crop luma — picks more_light vs too_bright guidance. */\n meanLuma: number;\n}\n\nexport interface V3GateTickInput {\n timestampMs: number;\n observation: FaceObservation | null;\n quality: V3GateQuality;\n frameWidth: number;\n frameHeight: number;\n}\n\nexport type V3GateFactor =\n | \"presence\"\n | \"centering\"\n | \"size\"\n | \"pose\"\n | \"sharpness\"\n | \"exposure\"\n | \"motion\";\n\n/** Per-tick output — the telemetry + chrome contract. */\nexport interface V3GateTick {\n at: number;\n /** Instantaneous quality 0..1 (MIN over the factors — the worst factor). */\n q: number;\n /** Integrated progress 0..1. */\n p: number;\n factors: Record<V3GateFactor, number>;\n /** fcv3.* message key for the lowest failing factor (host translates). */\n guidanceKey: string;\n /** Fire signal: p ≥ 1 AND the READY_WINDOW mean q ≥ READY_MEAN_Q. */\n ready: boolean;\n}\n\nconst clamp01 = (value: number) => Math.min(1, Math.max(0, value));\n\nexport class FaceGateV3 {\n private readonly t: V3GateThresholds;\n private p = 0;\n private lastTickAt: number | null = null;\n private lastCenter: { x: number; y: number; at: number } | null = null;\n private velocityEma = 0;\n private qWindow: Array<{ at: number; q: number }> = [];\n\n constructor(overrides: Partial<V3GateThresholds> = {}) {\n this.t = { ...V3_GATE_DEFAULTS, ...overrides };\n }\n\n reset(): void {\n this.p = 0;\n this.lastTickAt = null;\n this.lastCenter = null;\n this.velocityEma = 0;\n this.qWindow = [];\n this.lastSizeDirection = \"ideal\";\n }\n\n tick(input: V3GateTickInput): V3GateTick {\n const { observation, quality, timestampMs } = input;\n const dtSeconds =\n this.lastTickAt === null\n ? 0\n : Math.max(0, (timestampMs - this.lastTickAt) / 1000);\n this.lastTickAt = timestampMs;\n\n const factors: Record<V3GateFactor, number> = {\n presence: 0,\n centering: 0,\n size: 0,\n pose: 0,\n sharpness: clamp01(quality.sharpness),\n exposure: clamp01(quality.exposure),\n motion: 1,\n };\n\n if (observation !== null) {\n factors.presence = 1;\n const geometry = this.geometryOf(observation, input);\n factors.centering = geometry.centering;\n factors.size = geometry.size;\n factors.pose = geometry.pose;\n factors.motion = this.motionOf(\n geometry.center,\n geometry.iod,\n timestampMs,\n );\n } else {\n // No face: the motion history must not survive to the next sighting\n // (a re-acquired face \"jumping\" from its old position is not motion,\n // and a stale pre-loss velocity EMA must not penalize re-acquisition).\n this.lastCenter = null;\n this.velocityEma = 0;\n }\n\n // Worst factor IS the quality (see header) — presence 0 zeroes it exactly\n // as the old product did; the compensatory many-mediocre penalty is gone.\n const q = Math.min(\n factors.presence,\n factors.centering,\n factors.size,\n factors.pose,\n factors.sharpness,\n factors.exposure,\n factors.motion,\n );\n\n // Integrator: gentle drain — bad ticks pull p down at FALL×(1−q), never\n // reset it (the v1 counter-reset feel this replaces).\n this.p = clamp01(\n this.p +\n (q >= this.t.Q_GOOD\n ? this.t.RISE_PER_S * q\n : -this.t.FALL_PER_S * (1 - q)) *\n dtSeconds,\n );\n\n // Sustained-quality window (prevents luck-firing through a wobble).\n // TRIMMED mean: with ≥3 samples the single worst is dropped — at LOW's\n // 5 Hz cadence a window holds 2–3 ticks, and one jittery detection must\n // not veto a user who is otherwise steadily ready.\n this.qWindow.push({ at: timestampMs, q });\n this.qWindow = this.qWindow.filter(\n (entry) => entry.at >= timestampMs - this.t.READY_WINDOW_MS,\n );\n let windowSamples = this.qWindow.map((entry) => entry.q);\n if (windowSamples.length >= 3) {\n const worst = Math.min(...windowSamples);\n const worstIndex = windowSamples.indexOf(worst);\n windowSamples = windowSamples.filter((_, index) => index !== worstIndex);\n }\n const windowMean =\n windowSamples.reduce((sum, value) => sum + value, 0) /\n Math.max(1, windowSamples.length);\n const ready = this.p >= 1 && windowMean >= this.t.READY_MEAN_Q;\n\n return {\n at: timestampMs,\n q,\n p: this.p,\n factors,\n guidanceKey: this.guidanceOf(factors, quality, q),\n ready,\n };\n }\n\n private geometryOf(\n observation: FaceObservation,\n input: V3GateTickInput,\n ): {\n center: { x: number; y: number };\n iod: number;\n centering: number;\n size: number;\n pose: number;\n } {\n const { box, eyes } = observation;\n const frameCenter = { x: input.frameWidth / 2, y: input.frameHeight / 2 };\n const shortSide = Math.min(input.frameWidth, input.frameHeight);\n\n // Gate point: eye midpoint, or the bbox center shifted UP so box-only\n // tiers behave like eye tiers (BOX_EYE_OFFSET heuristic).\n const center =\n eyes !== undefined\n ? {\n x: (eyes.left.x + eyes.right.x) / 2,\n y: (eyes.left.y + eyes.right.y) / 2,\n }\n : {\n x: box.x + box.width / 2,\n y:\n box.y +\n box.height / 2 -\n this.t.BOX_EYE_OFFSET_FACTOR * box.height,\n };\n const iod =\n eyes !== undefined\n ? Math.hypot(eyes.right.x - eyes.left.x, eyes.right.y - eyes.left.y)\n : this.t.IOD_BOX_PROXY_FACTOR * box.width;\n\n // Smooth, SCALE-INVARIANT centering falloff: distance measured in IODs.\n const distance = Math.hypot(\n center.x - frameCenter.x,\n center.y - frameCenter.y,\n );\n const centering =\n iod <= 0\n ? 0\n : 1 - clamp01(distance / (this.t.CENTER_FALLOFF_IOD_MULTIPLE * iod));\n\n // Size factor from IOD relative to the frame short side.\n const ratio = shortSide > 0 ? iod / shortSide : 0;\n this.lastSizeDirection =\n ratio < this.t.SIZE_IDEAL_MIN\n ? \"far\"\n : ratio > this.t.SIZE_IDEAL_MAX\n ? \"close\"\n : \"ideal\";\n let size: number;\n if (ratio < this.t.SIZE_HARD_MIN || ratio > this.t.SIZE_HARD_MAX) {\n size = 0;\n } else if (ratio < this.t.SIZE_IDEAL_MIN) {\n size =\n (ratio - this.t.SIZE_HARD_MIN) /\n (this.t.SIZE_IDEAL_MIN - this.t.SIZE_HARD_MIN);\n } else if (ratio > this.t.SIZE_IDEAL_MAX) {\n size =\n (this.t.SIZE_HARD_MAX - ratio) /\n (this.t.SIZE_HARD_MAX - this.t.SIZE_IDEAL_MAX);\n } else {\n size = 1;\n }\n\n // Pose from the eye-line roll; box-only tiers stay neutral (no signal).\n let pose = 1;\n if (eyes !== undefined) {\n const rollDeg =\n (Math.abs(\n Math.atan2(eyes.right.y - eyes.left.y, eyes.right.x - eyes.left.x),\n ) *\n 180) /\n Math.PI;\n pose = 1 - clamp01(rollDeg / this.t.ROLL_MAX_DEG);\n }\n\n return { center, iod, centering, size, pose };\n }\n\n private motionOf(\n center: { x: number; y: number },\n iod: number,\n at: number,\n ): number {\n const previous = this.lastCenter;\n this.lastCenter = { ...center, at };\n if (previous === null || iod <= 0) return 1;\n const dtSeconds = (at - previous.at) / 1000;\n if (dtSeconds <= 0) return 1;\n let velocityIodPerS =\n Math.hypot(center.x - previous.x, center.y - previous.y) /\n iod /\n dtSeconds;\n // Deadband: sub-jitter velocities are stillness. Detector boxes quantize\n // hardest on LOW's 128px input, where a ±1px wobble at 5 Hz reads as\n // ~0.25 IOD/s — half the zeroing velocity — despite a rock-steady user.\n if (velocityIodPerS <= this.t.MOTION_DEADBAND_IOD_PER_S)\n velocityIodPerS = 0;\n // Time-constant EMA: alpha derived from dt so the smoothing horizon is\n // the same at 5 Hz and 10 Hz (see MOTION_TAU_S).\n const alpha = 1 - Math.exp(-dtSeconds / this.t.MOTION_TAU_S);\n this.velocityEma = alpha * velocityIodPerS + (1 - alpha) * this.velocityEma;\n return 1 - clamp01(this.velocityEma / this.t.MOTION_VELOCITY_IOD_PER_S);\n }\n\n /** Lowest failing factor speaks — fixed priority (diagnostic, incl. light):\n * presence → size → centering → pose → exposure → sharpness → hold.\n *\n * HONESTY FALLBACK (operator ruling 2026-07-12): when every factor clears\n * its guide threshold but q (= min factor) is still below Q_GOOD — i.e.\n * progress is DRAINING — \"hold still\" would be a lie (\"Perfect\" while\n * nothing advances; the field symptom was users discovering by accident\n * that only leaning in fires the gate). In that state the WORST factor\n * speaks even though it passed its guide level, so the user always hears\n * the change that actually unblocks recording. */\n private guidanceOf(\n factors: Record<V3GateFactor, number>,\n quality: V3GateQuality,\n q: number,\n ): string {\n if (factors.presence <= 0) return \"fcv3.no_face\";\n if (factors.size < this.t.GUIDE_SIZE) return this.sizeGuidance();\n if (factors.centering < this.t.GUIDE_CENTERING) return \"fcv3.center_face\";\n if (factors.pose < this.t.GUIDE_POSE) return \"fcv3.straighten\";\n if (factors.exposure < this.t.GUIDE_EXPOSURE)\n return this.exposureGuidance(quality);\n if (factors.sharpness < this.t.GUIDE_SHARPNESS) return \"fcv3.steady_camera\";\n if (factors.motion < this.t.GUIDE_MOTION) return \"fcv3.hold_still\";\n if (q < this.t.Q_GOOD) {\n // All guides pass but progress drains — coach the worst factor anyway.\n const coachable: Array<[V3GateFactor, string]> = [\n [\"size\", this.sizeGuidance()],\n [\"centering\", \"fcv3.center_face\"],\n [\"pose\", \"fcv3.straighten\"],\n [\"exposure\", this.exposureGuidance(quality)],\n [\"sharpness\", \"fcv3.steady_camera\"],\n [\"motion\", \"fcv3.hold_still\"],\n ];\n let worst = coachable[0] as [V3GateFactor, string];\n for (const entry of coachable) {\n if (factors[entry[0]] < factors[worst[0]]) worst = entry;\n }\n return worst[1];\n }\n return \"fcv3.hold_still\";\n }\n\n /** Direction from the size band set THIS tick (never inverted at the hard\n * limits: past SIZE_HARD_MAX the direction is 'close' → move_back). */\n private sizeGuidance(): string {\n return this.lastSizeDirection === \"far\"\n ? \"fcv3.come_closer\"\n : \"fcv3.move_back\";\n }\n\n /** Band midpoint — direction only (tracks EXPOSURE_BAND automatically). */\n private exposureGuidance(quality: V3GateQuality): string {\n const bandMid = (EXPOSURE_BAND[0] + EXPOSURE_BAND[1]) / 2;\n return quality.meanLuma < bandMid ? \"fcv3.more_light\" : \"fcv3.too_bright\";\n }\n\n /** Which side of the ideal band the last size measurement fell on. */\n private lastSizeDirection: \"far\" | \"close\" | \"ideal\" = \"ideal\";\n}\n","// CaptureSessionV3 (Task 10) — the v3 engine behind the v1 event surface\n// (`statechange | guidance | checks | artifacts | error`), plus ONE v3-only\n// chrome event (`frozen`, fired at recording-stop so the host can freeze the\n// display on the keyframe before the clip finalizes), so hosts bind it with\n// minimal changes. PARALLEL module: it REUSES v1's building blocks AS\n// IMPORTS — ClipRecorder (the 720p/2.5Mbps clip floor lives in ONE place),\n// captureMirroredKeyframe, buildCaptureConstraints, the camera error taxonomy\n// — and touches no v1 file.\n//\n// v3 deltas: detector LADDER (native → blaze; the face-api floor was dropped\n// 2026-07-09) on an adaptive scheduler with device profiles; FaceGateV3\n// (eye-midpoint, continuous\n// integrator); keyframe BEST-OF-N (sharpest of up to 4 candidates in the\n// first 600ms of the capture window); `checks` carries a v3 payload\n// discriminated on `engine: 'v3'` (no v1 counters).\n//\n// Supersession: retry()/switchCamera()/destroy() bump the attempt token —\n// in-flight async continuations from an old attempt observe the bump and\n// stop (the v1 pattern, ported; see capture-session.ts header).\nimport { buildCaptureConstraints, detectIsMobile } from \"../capture-constraints\";\nimport { ClipRecorder, type ClipResult } from \"../clip-recorder\";\nimport { captureMirroredKeyframe } from \"../keyframe\";\nimport { cameraPreflight, isClipTooLarge, mapGetUserMediaError } from \"../media\";\nimport type { CaptureArtifacts, CaptureErrorKind, CaptureState } from \"../types\";\nimport {\n createDetector as createLadderDetector,\n type Detector,\n DetectorLadderError,\n intrinsicSize,\n} from \"./detector\";\nimport { WorkerDetectorProxy, type WorkerLike, workerOffloadSupported } from \"./detect-worker\";\nimport {\n classifyDevice,\n type DeviceClass,\n DeviceProfiler,\n probeDevice,\n} from \"./device-profile\";\nimport { DetectScheduler } from \"./detect-scheduler\";\nimport {\n FaceGateV3,\n type V3GateFactor,\n type V3GateQuality,\n type V3GateThresholds,\n} from \"./face-gate-v3\";\nimport { exposure, meanLuma, sharpness } from \"./frame-quality\";\n\n/** Best-of-N keyframe window: up to 4 candidates over the first 600ms. */\nexport const KEYFRAME_CANDIDATES = 4;\nexport const KEYFRAME_WINDOW_MS = 600;\n\nexport interface V3ChecksPayload {\n engine: \"v3\";\n /** Gate integrator 0..1 — the ring drives off this directly. */\n progress: number;\n /** Instantaneous quality 0..1. */\n q: number;\n factors: Record<V3GateFactor, number>;\n /** Attempt ordinal (bumps on retry/switchCamera). */\n attempt: number;\n}\n\nexport interface CaptureSessionV3Events {\n statechange: { state: CaptureState };\n checks: V3ChecksPayload;\n /** fcv3.* message KEY — hosts translate; never prose. Deduped. */\n guidance: { key: string };\n artifacts: CaptureArtifacts;\n error: { kind: CaptureErrorKind; retryable: boolean };\n /** v3-only, CHROME-only (no data flows here): fires the instant the clip\n * recording window ends — BEFORE the blob finalizes (iOS onstop can lag up\n * to STOP_GRACE_MS). Carries the already-captured keyframe's JPEG data URL so\n * the host can freeze the display on the still immediately instead of leaving\n * the live feed running while the clip flushes. Clip mode only (photo mode\n * goes straight to `artifacts`). A host that ignores it is unaffected. */\n frozen: { previewDataUrl: string };\n}\n\nexport type V3TelemetryEvent =\n | { type: \"detector\"; tier: Detector[\"tier\"]; fallbackReason?: string }\n | { type: \"profile\"; staticClass: DeviceClass; activeClass: DeviceClass; simd: boolean }\n | { type: \"fired\"; timeToGateMs: number; degradeCount: number; meanDetectMs: number }\n | { type: \"error\"; kind: CaptureErrorKind; fallbackReason?: string };\n\ninterface KeyframeCandidate {\n blob: Blob;\n previewDataUrl: string;\n sharpness: number;\n}\n\n/** Challenge-clip artifact for the Phase 3 escalation path. */\nexport interface EscalationClipArtifact {\n clip: Blob;\n clipMimeType: string;\n}\n\n/** INERT Phase 3 seam (docs/superpowers/specs/2026-07-07-active-liveness-\n * escalation-spec.md): when the server settles a liveness verdict in the\n * REVIEW band it may mint ONE gesture challenge; the host then asks the\n * engine for a challenge clip through this hook. Typed and documented NOW so\n * capture-v3+ starts from a design — NEVER invoked anywhere in the current\n * flow (pinned by a test). */\nexport interface EscalationHook {\n onBorderline(challenge: \"blink\" | \"turn\"): Promise<EscalationClipArtifact>;\n}\n\nexport interface CaptureSessionV3Options {\n /** Host-owned <video playsInline muted> — same iOS contract as v1. */\n video: HTMLVideoElement;\n /** v3 assets base (tasks-vision wasm + tflite); default /models-v3. */\n v3AssetBaseUrl?: string;\n mode?: \"clip\" | \"photo\";\n /** FaceGateV3 threshold overrides (Phase 2 tuning). */\n thresholds?: Partial<V3GateThresholds>;\n telemetry?: (event: V3TelemetryEvent) => void;\n facingMode?: \"user\" | \"environment\";\n /** Static class override (tests / host pinning); default = boot probe. */\n deviceClass?: DeviceClass;\n // ── seams (production defaults in parens) ─────────────────────────────────\n /** (detector ladder) */\n createDetector?: () => Promise<Detector>;\n /** (fresh ClipRecorder per attempt) */\n createRecorder?: () => Pick<ClipRecorder, \"record\" | \"stop\">;\n /** (navigator.mediaDevices.getUserMedia) */\n getUserMedia?: (constraints: MediaStreamConstraints) => Promise<MediaStream>;\n /** (mirrored canvas keyframe + downscaled Laplacian sharpness) */\n captureKeyframe?: (video: HTMLVideoElement) => Promise<KeyframeCandidate>;\n /** (downscaled face-crop sharpness/exposure via canvas) */\n measureQuality?: (\n video: HTMLVideoElement,\n box: { x: number; y: number; width: number; height: number },\n ) => V3GateQuality;\n /** (reused canvas at profile.inputWidth; falls back to the raw video where\n * canvas is unavailable) */\n makeSnapshot?: (video: HTMLVideoElement, targetWidth: number) => CanvasImageSource;\n /** Worker offload opt-in (Task 9): when provided AND the platform supports\n * it (OffscreenCanvas + createImageBitmap + Worker), detection runs\n * worker-side through WorkerDetectorProxy. Hosts own Worker construction\n * (bundler-specific `new Worker(new URL(...))`). */\n createWorker?: () => WorkerLike;\n /** INERT (Phase 3 escalation seam — see EscalationHook). Accepted and\n * retained, never called in Phases 1–2. */\n escalation?: EscalationHook;\n /** (performance.now) */\n now?: () => number;\n}\n\ntype Handler<K extends keyof CaptureSessionV3Events> = (\n payload: CaptureSessionV3Events[K],\n) => void;\n\nconst NEUTRAL_QUALITY: V3GateQuality = { sharpness: 1, exposure: 1, meanLuma: 128 };\n\nexport class CaptureSessionV3 {\n private readonly options: CaptureSessionV3Options;\n private readonly handlers = new Map<string, Set<(payload: never) => void>>();\n private stateValue: CaptureState = \"idle\";\n private attempt = 0;\n private facing: \"user\" | \"environment\";\n private stream: MediaStream | null = null;\n private detector: Detector | null = null;\n private scheduler: DetectScheduler | null = null;\n private gate: FaceGateV3 | null = null;\n private profiler: DeviceProfiler | null = null;\n private lastGuidanceKey: string | null = null;\n private positioningStartedAt = 0;\n private fired = false;\n private carriedDegrade = 0;\n private carriedMeans: number[] = [];\n\n constructor(options: CaptureSessionV3Options) {\n this.options = options;\n this.facing = options.facingMode ?? \"user\";\n }\n\n get state(): CaptureState {\n return this.stateValue;\n }\n\n on<K extends keyof CaptureSessionV3Events>(event: K, handler: Handler<K>): () => void {\n let set = this.handlers.get(event);\n if (!set) {\n set = new Set();\n this.handlers.set(event, set);\n }\n set.add(handler as (payload: never) => void);\n return () => set?.delete(handler as (payload: never) => void);\n }\n\n private emit<K extends keyof CaptureSessionV3Events>(\n event: K,\n payload: CaptureSessionV3Events[K],\n ): void {\n for (const handler of [...(this.handlers.get(event) ?? [])]) {\n (handler as Handler<K>)(payload);\n }\n }\n\n async start(): Promise<void> {\n this.attempt += 1;\n await this.run(this.attempt);\n }\n\n /** Full reset + camera restart — the documented recovery path (v1 parity). */\n retry(): void {\n this.teardownAttempt();\n void this.start();\n }\n\n switchCamera(): void {\n this.facing = this.facing === \"user\" ? \"environment\" : \"user\";\n this.teardownAttempt();\n void this.start();\n }\n\n destroy(): void {\n this.attempt += 1; // supersede in-flight continuations\n this.teardownAttempt();\n this.detector?.destroy();\n this.detector = null;\n this.options.video.srcObject = null;\n }\n\n // ── attempt lifecycle ──────────────────────────────────────────────────────\n\n private async run(attempt: number): Promise<void> {\n const { options } = this;\n this.fired = false;\n this.lastGuidanceKey = null;\n this.carriedDegrade = 0;\n this.carriedMeans = [];\n this.setState(\"preflight\");\n const preflight = cameraPreflight();\n if (preflight !== \"OK\") {\n this.fail(preflight === \"INSECURE_CONTEXT\" ? \"insecure\" : \"unsupported\");\n return;\n }\n\n this.setState(\"acquiring\");\n const getUserMedia =\n options.getUserMedia ??\n ((constraints: MediaStreamConstraints) => navigator.mediaDevices.getUserMedia(constraints));\n let stream: MediaStream;\n try {\n // The 720p/2.5Mbps floor: v1's constraint builder, imported — never forked.\n stream = await getUserMedia(buildCaptureConstraints(detectIsMobile(), this.facing));\n } catch (err) {\n if (attempt !== this.attempt) return;\n this.fail(mapGetUserMediaError(err));\n return;\n }\n if (attempt !== this.attempt) {\n for (const track of stream.getTracks()) track.stop();\n return;\n }\n this.stream = stream;\n options.video.srcObject = stream;\n await options.video.play().catch(() => undefined);\n // play() awaited — a retry/destroy may have superseded this attempt while\n // it was suspended; continuing would overwrite the LIVE attempt's\n // profiler/gate/scheduler with stale ones (review S2-2).\n if (attempt !== this.attempt) return;\n\n if (this.detector === null) {\n const ladderOptions = {\n ...(options.v3AssetBaseUrl !== undefined\n ? { v3AssetBaseUrl: options.v3AssetBaseUrl }\n : {}),\n };\n const create =\n options.createDetector ??\n (options.createWorker !== undefined && workerOffloadSupported()\n ? async () => {\n // Worker offload (Task 9): the ladder runs WORKER-side; a\n // failed/hung init falls back to the in-thread ladder.\n try {\n return await WorkerDetectorProxy.create(\n (options.createWorker as () => WorkerLike)(),\n ladderOptions,\n );\n } catch {\n return createLadderDetector(ladderOptions);\n }\n }\n : () => createLadderDetector(ladderOptions));\n let created: Detector;\n try {\n created = await create();\n } catch (err) {\n // With the face-api floor gone, the ladder REJECTS once exhausted\n // (DetectorLadderError) — and any throwing seam is likewise a models\n // failure. Surface a retryable error{kind:'models'} (never a hang),\n // carrying the per-tier reasons for telemetry so a blaze init failure\n // stays observable in the field.\n if (attempt === this.attempt) {\n this.fail(\n \"models\",\n err instanceof DetectorLadderError ? err.fallbackReason : describeError(err),\n );\n }\n return;\n }\n // Resolve into a LOCAL first: assigning a detector into a superseded\n // (or destroyed) session would leak it — destroy() already nulled the\n // field, and a racing attempt may have created its own (review S2-3).\n if (attempt !== this.attempt) {\n created.destroy();\n return;\n }\n this.detector = created;\n this.options.telemetry?.({\n type: \"detector\",\n tier: created.tier,\n ...(created.fallbackReason !== undefined\n ? { fallbackReason: created.fallbackReason }\n : {}),\n });\n }\n\n const probe = probeDevice();\n const staticClass = options.deviceClass ?? classifyDevice(probe);\n this.profiler = new DeviceProfiler(staticClass);\n this.options.telemetry?.({\n type: \"profile\",\n staticClass,\n activeClass: this.profiler.deviceClass,\n simd: probe.simd,\n });\n\n this.gate = new FaceGateV3(options.thresholds ?? {});\n this.setState(\"positioning\");\n this.positioningStartedAt = this.now();\n this.startScheduler(attempt);\n }\n\n /** Chrome hint (Task 11): 'reduced' on LOW even without the media query. */\n get animations(): \"full\" | \"reduced\" {\n return this.profiler?.profile.animations ?? \"full\";\n }\n\n private startScheduler(attempt: number): void {\n const profiler = this.profiler;\n if (profiler === null) return;\n if (this.scheduler !== null) {\n // A dynamic profile change replaces the scheduler — carry its stats so\n // the `fired` telemetry keeps the PRE-adjustment struggle visible.\n const stats = this.scheduler.stats();\n this.carriedDegrade += stats.degradeCount;\n if (stats.meanDetectMs > 0) this.carriedMeans.push(stats.meanDetectMs);\n this.scheduler.stop();\n }\n const scheduler = new DetectScheduler({\n cadenceHz: profiler.profile.cadenceHz,\n video: this.options.video,\n ...(this.options.now !== undefined ? { now: this.options.now } : {}),\n run: () => this.detectTick(attempt),\n });\n this.scheduler = scheduler;\n scheduler.start();\n }\n\n private async detectTick(attempt: number): Promise<void> {\n const { detector, gate, profiler } = this;\n const video = this.options.video;\n if (attempt !== this.attempt || detector === null || gate === null || profiler === null)\n return;\n if (this.fired || video.videoWidth === 0) return;\n\n const before = profiler.deviceClass;\n const t0 = this.now();\n // Profile-adaptive DOWNSCALE: the detector sees an inputWidth-wide\n // snapshot, never the full 720p frame (the profile system's perf win);\n // stream-px normalization scales the observation back up.\n const source =\n this.options.makeSnapshot?.(video, profiler.profile.inputWidth) ??\n this.defaultSnapshot(video, profiler.profile.inputWidth);\n let observation: Awaited<ReturnType<Detector[\"detect\"]>> = null;\n try {\n observation = await detector.detect(source, video.videoWidth, video.videoHeight);\n } catch {\n observation = null; // detectors never reject by contract; belt-and-braces\n }\n if (attempt !== this.attempt || this.fired) return;\n profiler.record(this.now() - t0);\n if (profiler.deviceClass !== before) this.startScheduler(attempt); // cadence follows the class\n\n const quality =\n observation === null\n ? NEUTRAL_QUALITY\n : (this.options.measureQuality?.(video, observation.box) ??\n this.defaultQuality(video, observation.box));\n\n const tick = gate.tick({\n timestampMs: this.now(),\n observation,\n quality,\n frameWidth: video.videoWidth,\n frameHeight: video.videoHeight,\n });\n this.emit(\"checks\", {\n engine: \"v3\",\n progress: tick.p,\n q: tick.q,\n factors: tick.factors,\n attempt,\n });\n if (tick.guidanceKey !== this.lastGuidanceKey) {\n this.lastGuidanceKey = tick.guidanceKey;\n this.emit(\"guidance\", { key: tick.guidanceKey });\n }\n if (tick.ready && this.stateValue === \"positioning\") {\n this.fired = true;\n void this.fire(attempt);\n }\n }\n\n private async fire(attempt: number): Promise<void> {\n const { options } = this;\n const scheduler = this.scheduler;\n scheduler?.stop();\n const stats = scheduler?.stats() ?? { degradeCount: 0, meanDetectMs: 0 };\n const means = [...this.carriedMeans, ...(stats.meanDetectMs > 0 ? [stats.meanDetectMs] : [])];\n options.telemetry?.({\n type: \"fired\",\n timeToGateMs: this.now() - this.positioningStartedAt,\n degradeCount: this.carriedDegrade + stats.degradeCount,\n meanDetectMs:\n means.length === 0 ? 0 : means.reduce((sum, value) => sum + value, 0) / means.length,\n });\n\n const mode = options.mode ?? \"clip\";\n const bestOf = this.collectKeyframes(attempt);\n if (mode === \"photo\") {\n const best = await bestOf;\n if (attempt !== this.attempt) return;\n if (best === null) {\n this.fail(\"generic\");\n return;\n }\n this.finishCapture({ keyframe: best.blob, previewDataUrl: best.previewDataUrl });\n return;\n }\n\n this.setState(\"recording\");\n const recorder = options.createRecorder?.() ?? new ClipRecorder();\n const stream = this.stream;\n if (stream === null) {\n this.fail(\"generic\");\n return;\n }\n // The keyframe (the face_match selfie) resolves within the first 600ms —\n // well before the 2.5s clip ends. Latch it so the recording-STOP callback\n // below can emit `frozen` immediately, letting the host freeze the display\n // on the still without waiting for the clip blob to finalize (iOS lag).\n let frozenBest: KeyframeCandidate | null = null;\n void bestOf.then(\n (candidate) => {\n frozenBest = candidate;\n },\n () => {},\n );\n const onRecordingStopped = (): void => {\n if (attempt !== this.attempt) return; // superseded (retry/switch/destroy)\n if (frozenBest !== null) {\n this.emit(\"frozen\", { previewDataUrl: frozenBest.previewDataUrl });\n }\n };\n let clip: ClipResult;\n let best: KeyframeCandidate | null;\n try {\n [clip, best] = await Promise.all([recorder.record(stream, onRecordingStopped), bestOf]);\n } catch (err) {\n if (attempt !== this.attempt) return;\n const kind = (err as { kind?: CaptureErrorKind }).kind;\n this.fail(kind === \"cliptoolarge\" ? \"cliptoolarge\" : \"recorder\");\n return;\n }\n if (attempt !== this.attempt) return;\n if (isClipTooLarge(clip.blob)) {\n this.fail(\"cliptoolarge\");\n return;\n }\n if (best === null) {\n this.fail(\"generic\");\n return;\n }\n this.finishCapture({\n clip: clip.blob,\n clipMimeType: clip.mimeType,\n keyframe: best.blob,\n previewDataUrl: best.previewDataUrl,\n });\n }\n\n /** Up to KEYFRAME_CANDIDATES mirrored frames over KEYFRAME_WINDOW_MS —\n * sharpest wins (reuses frame-quality.sharpness via the capture seam). */\n private async collectKeyframes(attempt: number): Promise<KeyframeCandidate | null> {\n const capture = this.options.captureKeyframe ?? ((video) => this.defaultKeyframe(video));\n const stepMs = KEYFRAME_WINDOW_MS / (KEYFRAME_CANDIDATES - 1);\n let best: KeyframeCandidate | null = null;\n for (let i = 0; i < KEYFRAME_CANDIDATES; i += 1) {\n if (attempt !== this.attempt) return best;\n try {\n const candidate = await capture(this.options.video);\n if (best === null || candidate.sharpness > best.sharpness) best = candidate;\n } catch {\n // a failed candidate never sinks the capture — keep the best so far\n }\n if (i < KEYFRAME_CANDIDATES - 1) await delay(stepMs);\n }\n return best;\n }\n\n private finishCapture(artifacts: CaptureArtifacts): void {\n this.stopTracks(); // privacy posture: camera off the moment we have artifacts\n this.setState(\"captured\");\n this.emit(\"artifacts\", artifacts);\n }\n\n // ── defaults for the canvas-bound seams ────────────────────────────────────\n\n private async defaultKeyframe(video: HTMLVideoElement): Promise<KeyframeCandidate> {\n const canvas = document.createElement(\"canvas\");\n const blob = await captureMirroredKeyframe(video, canvas);\n const previewDataUrl = canvas.toDataURL(\"image/jpeg\", 0.92);\n return { blob, previewDataUrl, sharpness: this.centerSharpness(video) };\n }\n\n /** Reused downscale canvas — falls back to the raw video where canvas 2D\n * is unavailable (jsdom) so tests and exotic hosts keep detecting. */\n private snapshotCanvas: HTMLCanvasElement | null = null;\n private defaultSnapshot(video: HTMLVideoElement, targetWidth: number): CanvasImageSource {\n try {\n const canvas = this.snapshotCanvas ?? document.createElement(\"canvas\");\n const scale = targetWidth / Math.max(1, video.videoWidth);\n const width = Math.max(1, Math.round(video.videoWidth * scale));\n const height = Math.max(1, Math.round(video.videoHeight * scale));\n const ctx = canvas.getContext(\"2d\");\n if (ctx === null) return video;\n if (canvas.width !== width) canvas.width = width;\n if (canvas.height !== height) canvas.height = height;\n ctx.drawImage(video, 0, 0, width, height);\n this.snapshotCanvas = canvas;\n return canvas;\n } catch {\n return video;\n }\n }\n\n private defaultQuality(\n video: HTMLVideoElement,\n box: { x: number; y: number; width: number; height: number },\n ): V3GateQuality {\n const crop = cropImageData(video, box, 96);\n if (crop === null) return NEUTRAL_QUALITY;\n return { sharpness: sharpness(crop), exposure: exposure(crop), meanLuma: meanLuma(crop) };\n }\n\n private centerSharpness(video: HTMLVideoElement): number {\n const size = intrinsicSize(video);\n const crop = cropImageData(\n video,\n { x: size.width * 0.25, y: size.height * 0.25, width: size.width * 0.5, height: size.height * 0.5 },\n 96,\n );\n return crop === null ? 0 : sharpness(crop);\n }\n\n // ── teardown ──────────────────────────────────────────────────────────────\n\n private teardownAttempt(): void {\n // No token bump here: retry()/switchCamera() call start() synchronously\n // right after, and START's own bump supersedes; destroy() bumps itself.\n this.scheduler?.stop();\n this.scheduler = null;\n this.gate = null;\n this.stopTracks();\n }\n\n private stopTracks(): void {\n if (this.stream === null) return;\n for (const track of this.stream.getTracks()) track.stop();\n this.stream = null;\n }\n\n private fail(kind: CaptureErrorKind, fallbackReason?: string): void {\n this.scheduler?.stop();\n this.stopTracks();\n this.setState(\"error\");\n this.options.telemetry?.({\n type: \"error\",\n kind,\n ...(fallbackReason !== undefined ? { fallbackReason } : {}),\n });\n // v1 canRetry semantics (capture-session.ts L424).\n this.emit(\"error\", { kind, retryable: kind !== \"insecure\" && kind !== \"unsupported\" });\n }\n\n private setState(state: CaptureState): void {\n this.stateValue = state;\n this.emit(\"statechange\", { state });\n }\n\n private now(): number {\n return this.options.now?.() ?? performance.now();\n }\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction describeError(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\n/** Downscaled face-crop ImageData for the quality measures; null where canvas\n * is unavailable (jsdom) — callers fall back to neutral quality. */\nfunction cropImageData(\n video: HTMLVideoElement,\n box: { x: number; y: number; width: number; height: number },\n targetWidth: number,\n): ImageData | null {\n try {\n const canvas = document.createElement(\"canvas\");\n const scale = targetWidth / Math.max(1, box.width);\n canvas.width = Math.max(1, Math.round(box.width * scale));\n canvas.height = Math.max(1, Math.round(box.height * scale));\n const ctx = canvas.getContext(\"2d\");\n if (ctx === null) return null;\n ctx.drawImage(\n video,\n box.x,\n box.y,\n box.width,\n box.height,\n 0,\n 0,\n canvas.width,\n canvas.height,\n );\n return ctx.getImageData(0, 0, canvas.width, canvas.height);\n } catch {\n return null;\n }\n}\n","// Tiny typed emitter (zero deps). Handlers are snapshotted before dispatch so an\n// unsubscribe from inside a handler never skips a sibling.\n\nexport interface Emitter<Events extends object> {\n on<K extends keyof Events>(event: K, handler: (payload: Events[K]) => void): () => void;\n emit<K extends keyof Events>(event: K, payload: Events[K]): void;\n clear(): void;\n}\n\nexport function createEmitter<Events extends object>(): Emitter<Events> {\n const handlers = new Map<keyof Events, Set<(payload: never) => void>>();\n return {\n on(event, handler) {\n let set = handlers.get(event);\n if (set === undefined) {\n set = new Set();\n handlers.set(event, set);\n }\n const h = handler as (payload: never) => void;\n set.add(h);\n return () => {\n set?.delete(h);\n };\n },\n emit(event, payload) {\n const set = handlers.get(event);\n if (set === undefined) return;\n for (const handler of [...set]) {\n (handler as (p: Events[typeof event]) => void)(payload);\n }\n },\n clear() {\n handlers.clear();\n },\n };\n}\n","// createLivenessCapture — the public, framework-free capture handle (spec\n// §3.1) over the calibration-pinned CaptureSessionV3 engine. It MAPS the\n// engine's event surface (statechange / checks / guidance / artifacts / error /\n// frozen) onto the partner contract (state / gate / captured / error) and owns\n// the NO_RECORDER degrade (photo mode → keyframe-only `captured`). Pinned\n// capture constants stay inside the engine — nothing here is configurable.\nimport { detectIsMobile } from \"../core/capture-constraints\";\nimport { isMediaRecorderSupported } from \"../core/media\";\nimport type { CaptureErrorKind as EngineErrorKind, CaptureState as EngineState } from \"../core/types\";\nimport {\n CaptureSessionV3,\n type CaptureSessionV3Events,\n type CaptureSessionV3Options,\n} from \"../core/v3/capture-session-v3\";\nimport { createEmitter } from \"../verification/emitter\";\nimport type {\n CaptureErrorKind,\n CaptureState,\n GateHint,\n LivenessCaptureEvents,\n LivenessCaptureHandle,\n LivenessCaptureOptions,\n} from \"../verification/types\";\n\n/** The engine surface the handle binds — CaptureSessionV3 or a test double. */\nexport interface CaptureEngine {\n readonly state: EngineState;\n on<K extends keyof CaptureSessionV3Events>(\n event: K,\n handler: (payload: CaptureSessionV3Events[K]) => void,\n ): () => void;\n start(): Promise<void>;\n retry(): void;\n switchCamera(): void;\n destroy(): void;\n /** Device-profile chrome hint (LOW class → `'reduced'`); absent on doubles. */\n readonly animations?: \"full\" | \"reduced\";\n}\n\n/** Internal construction seams (tests; Sekyro's own hosted page). */\nexport interface LivenessCaptureInternals {\n /** Replace the engine constructor (default: `new CaptureSessionV3(options)`). */\n createEngine?: (options: CaptureSessionV3Options) => CaptureEngine;\n /** Extra engine options merged in (worker offload, warmed detector, telemetry). */\n engineOptions?: Partial<\n Pick<CaptureSessionV3Options, \"createDetector\" | \"createWorker\" | \"telemetry\" | \"deviceClass\">\n >;\n /** Clock (default `performance.now`). */\n now?: () => number;\n}\n\n/** fcv3.* guidance key → public gate hint code. */\nexport function mapGuidanceHint(key: string): GateHint | null {\n switch (key) {\n case \"fcv3.no_face\":\n case \"fcv3.center_face\":\n case \"fcv3.straighten\":\n return \"center\";\n case \"fcv3.come_closer\":\n return \"closer\";\n case \"fcv3.move_back\":\n return \"farther\";\n case \"fcv3.more_light\":\n case \"fcv3.too_bright\":\n return \"light\";\n case \"fcv3.hold_still\":\n case \"fcv3.steady_camera\":\n return \"still\";\n default:\n return null;\n }\n}\n\n/** Engine state → public state (`preflight|acquiring → starting`, `positioning → gating`). */\nexport function mapEngineState(state: EngineState): CaptureState {\n switch (state) {\n case \"preflight\":\n case \"acquiring\":\n return \"starting\";\n case \"positioning\":\n return \"gating\";\n case \"idle\":\n case \"recording\":\n case \"captured\":\n case \"error\":\n return state;\n default: {\n const unhandled: never = state;\n throw new Error(`mapEngineState: unhandled state ${unhandled as string}`);\n }\n }\n}\n\n/** Engine error kinds → the public six (`models|cliptoolarge|recorder|overconstrained → generic`). */\nexport function mapErrorKind(kind: EngineErrorKind): CaptureErrorKind {\n switch (kind) {\n case \"permission\":\n case \"notfound\":\n case \"inuse\":\n case \"insecure\":\n case \"unsupported\":\n return kind;\n case \"overconstrained\":\n case \"generic\":\n case \"models\":\n case \"cliptoolarge\":\n case \"recorder\":\n return \"generic\";\n default: {\n const unhandled: never = kind;\n throw new Error(`mapErrorKind: unhandled kind ${unhandled as string}`);\n }\n }\n}\n\n/** Handle + the hooks the verification layer uses to drive the flow states. */\nexport interface LivenessCaptureInternalHandle {\n handle: LivenessCaptureHandle;\n /** Push a post-capture state (`uploading | checking | done`). */\n setFlowState(state: Extract<CaptureState, \"uploading\" | \"checking\" | \"done\">): void;\n}\n\nexport function createLivenessCaptureInternal(\n options: LivenessCaptureOptions,\n internals: LivenessCaptureInternals = {},\n): LivenessCaptureInternalHandle {\n const now = internals.now ?? (() => performance.now());\n const emitter = createEmitter<LivenessCaptureEvents>();\n // NO_RECORDER degrade: no MediaRecorder → photo mode (keyframe only). Decided\n // ONCE at construction; the artifacts carry the flag.\n const degraded = !isMediaRecorderSupported();\n const engineOptions: CaptureSessionV3Options = {\n video: options.video,\n mode: degraded ? \"photo\" : \"clip\",\n ...(options.facing !== undefined ? { facingMode: options.facing } : {}),\n ...(options.assetBaseUrl !== undefined ? { v3AssetBaseUrl: options.assetBaseUrl } : {}),\n ...(internals.engineOptions ?? {}),\n };\n const engine: CaptureEngine =\n internals.createEngine?.(engineOptions) ?? new CaptureSessionV3(engineOptions);\n\n let state: CaptureState = \"idle\";\n let hint: GateHint | null = null;\n let progress = 0;\n let faceDetected = false;\n let animations: \"full\" | \"reduced\" = \"full\";\n let recordingStartedAt: number | null = null;\n let frozenAt: number | null = null;\n\n const setState = (next: CaptureState): void => {\n state = next;\n emitter.emit(\"state\", next);\n };\n const emitGate = (): void => emitter.emit(\"gate\", { progress, hint, faceDetected });\n // The LOW-profile hint settles once the engine probes (statechange) and may\n // flip mid-positioning on a dynamic demotion (per checks tick) — emit on change.\n const syncProfile = (): void => {\n const next = engine.animations ?? \"full\";\n if (next === animations) return;\n animations = next;\n emitter.emit(\"profile\", { animations });\n };\n\n const unsubscribes = [\n engine.on(\"statechange\", ({ state: engineState }) => {\n const next = mapEngineState(engineState);\n if (next === \"starting\" && state !== \"starting\") {\n // Fresh attempt: gate chrome resets.\n hint = null;\n progress = 0;\n faceDetected = false;\n recordingStartedAt = null;\n frozenAt = null;\n }\n setState(next);\n syncProfile();\n if (next === \"recording\") {\n recordingStartedAt = now();\n hint = \"hold\";\n progress = 1;\n emitGate();\n }\n }),\n engine.on(\"checks\", (payload) => {\n progress = payload.progress;\n faceDetected = payload.factors.presence > 0;\n emitGate();\n syncProfile();\n }),\n engine.on(\"guidance\", ({ key }) => {\n hint = mapGuidanceHint(key);\n emitGate();\n }),\n engine.on(\"frozen\", ({ previewDataUrl }) => {\n frozenAt = now();\n emitter.emit(\"frozen\", { previewDataUrl });\n }),\n engine.on(\"artifacts\", (artifacts) => {\n const clipMs =\n recordingStartedAt !== null && frozenAt !== null\n ? Math.max(0, Math.round(frozenAt - recordingStartedAt))\n : undefined;\n emitter.emit(\"captured\", {\n keyframe: artifacts.keyframe,\n ...(artifacts.clip !== undefined ? { clip: artifacts.clip } : {}),\n ...(artifacts.clipMimeType !== undefined ? { clipMime: artifacts.clipMimeType } : {}),\n width: options.video.videoWidth,\n height: options.video.videoHeight,\n ...(clipMs !== undefined ? { clipMs } : {}),\n captureChannel: detectIsMobile() ? \"mobile\" : \"desktop\",\n ...(degraded ? { degraded: \"NO_RECORDER\" as const } : {}),\n });\n }),\n engine.on(\"error\", ({ kind, retryable }) => {\n emitter.emit(\"error\", { kind: mapErrorKind(kind), retryable });\n }),\n ];\n\n const handle: LivenessCaptureHandle = {\n get state() {\n return state;\n },\n on: (event, handler) => emitter.on(event, handler),\n start: () => engine.start(),\n retry: () => engine.retry(),\n switchCamera: () => engine.switchCamera(),\n destroy: () => {\n for (const unsubscribe of unsubscribes) unsubscribe();\n engine.destroy();\n emitter.clear();\n },\n };\n\n return {\n handle,\n setFlowState: (next) => {\n if (state !== next) setState(next);\n },\n };\n}\n\n/**\n * Create a standalone liveness capture (no upload — pair it with your own\n * submission, or use {@link Verification.liveness} for the full flow).\n */\nexport function createLivenessCapture(options: LivenessCaptureOptions): LivenessCaptureHandle {\n return createLivenessCaptureInternal(options).handle;\n}\n","// Public error map for the session-token surface (Plan 6 Task 5).\n//\n// The backend's AllExceptionsFilter (audience 'public') emits the FLAT envelope\n// `{code, message}` — no details, no request_id, no traceId. `code` is the\n// snake_cased `error` key of the thrown HttpException body (extractError →\n// camelToSnake). 429 responses additionally carry a `Retry-After` header in\n// SECONDS (SessionTokenGuard / RateLimitGuard).\n//\n// KNOWN_CODES below is the VERIFIED set reachable through the five hosted\n// endpoints (grep of `error: '…'` sites in identity-backend @ Tasks 0+1+2 —\n// hosted.controller, checks.controller, media.{controller,service},\n// sessions.service submit flow, session-token.guard, valibot.pipe,\n// check-executor registry, idempotency.interceptor, attestation mapping),\n// plus four CLIENT-SYNTHESIZED codes that never come from the backend:\n// - 'unknown_error' — a response body that was not parseable JSON (proxy HTML\n// on an error, or a malformed 2xx body)\n// - 'upload_failed' — the bare Spaces PUT answered non-2xx (S3 XML, no envelope)\n// - 'network_error' — fetch itself rejected: connection drop / DNS / CORS /\n// mid-transfer failure (status: 0 — no response arrived)\n// - 'timeout' — the request's AbortSignal.timeout fired (status: 0)\n// Task 7's error-copy map must carry entries for all four from day one.\n//\n// Deliberately EXCLUDED (verified unreachable on this surface today):\n// - payment_required / account_suspended — BillingInterceptor gates only\n// handlers decorated @BillableCheck, and no handler is decorated yet.\n// - not_found — the generic unmatched-route 404; a correctly configured client\n// never produces it. Unknown codes route through `isKnownCode() === false`.\n\n/**\n * Every error code the hosted page can receive from the session-token surface.\n * A closed string-literal union — switch over {@link KnownCode} with a `never`\n * default arm for compile-checked exhaustiveness.\n */\nexport const KNOWN_CODES = [\n // auth / addressing (session-token.guard, controllers' own-session guards)\n \"session_token_invalid\", // 401 — missing/invalid/expired/revoked token\n \"session_token_required\", // 403 — non-session-token principal on a hosted route (defensive)\n \"session_token_session_mismatch\", // 403 — route :id differs from the token's bound session\n \"session_not_found\", // 404 — token's session missing/foreign (findOwned)\n // rate limiting (session-token.guard — per-token + per-IP buckets)\n \"rate_limit_exceeded\", // 429 + Retry-After header (seconds)\n // consent gate (Task 0 — submit AND media presign/complete)\n \"consent_required\", // 409 — record consent before uploading/submitting\n // submit flow (sessions.service.submitCheck)\n \"session_not_active\", // 409 — session is terminal/review; no further submissions\n \"check_not_found\", // 404 — session has no such checkType\n \"check_already_finalized\", // 409 — re-submit of a terminal/review check\n \"check_out_of_order\", // 409 — only the frontier check accepts a submission\n \"check_type_unsupported\", // 400 — no registered executor for the checkType\n \"force_outcome_forbidden\", // 403 — forceOutcome on a live session (plan D-C)\n \"attestation_invalid\", // 400 (Task 1) — Turnstile/attestation failed; reload and retry\n \"nni_locked\", // 409 (Plan A Task 2) — session is bound to a server-provided NNI; a different client NNI was sent\n // media (media.service)\n \"media_content_type_not_allowed\", // 400 — outside the per-kind MIME allowlist\n \"media_too_large\", // 413 — over the per-kind byte cap\n \"media_key_invalid\", // 400 — not a well-formed pending key\n \"media_key_forbidden\", // 403 — key names another session's pending space\n \"media_not_found\", // 404 — no uploaded object behind the key\n \"media_unreadable\", // 422 — magic-byte sniff rejected the object\n \"media_session_invalid\", // 400 — sessionId unusable as a key segment (never in practice)\n // idempotency (idempotency.interceptor — Task 2)\n \"idempotency_key_collision\", // 409 — same key, different body hash\n \"idempotency_in_progress\", // 409 — concurrent identical request mid-flight (client auto-retries)\n \"idempotency_key_required\", // 400 — only on @Idempotent({required:true}) routes (none hosted yet)\n // validation + fallback\n \"validation_error\", // 400 — ValibotPipe rejection (camelToSnake of 'ValidationError')\n \"internal_error\", // 500 — unhandled server error\n // client-synthesized (never sent by the backend)\n \"unknown_error\", // unparseable (non-JSON) response body — error OR 2xx (defensive)\n \"upload_failed\", // the bare Spaces PUT answered non-2xx\n \"network_error\", // fetch rejected: connection drop / DNS / CORS / mid-transfer (status 0)\n \"timeout\", // AbortSignal.timeout fired — API calls 30 s default, Spaces PUT 15 min (status 0)\n] as const;\n\n/** Closed union of {@link KNOWN_CODES} — exhaustively switchable. */\nexport type KnownCode = (typeof KNOWN_CODES)[number];\n\n/** Narrow an arbitrary wire code to the known union (unknown codes stay `string`). */\nexport function isKnownCode(code: string): code is KnownCode {\n return (KNOWN_CODES as readonly string[]).includes(code);\n}\n\n/**\n * Typed transport error: EVERY failure surfaces as one of these — non-2xx\n * responses, rejected fetches, timeouts, and unparseable bodies alike. The\n * hosted page never sees a raw TypeError/DOMException from the client.\n *\n * - `code` — the public envelope's `code`, or a client-synthesized fallback\n * ('unknown_error' / 'upload_failed' / 'network_error' / 'timeout'). Typed\n * `string` because the wire may grow codes; narrow with {@link isKnownCode}\n * before an exhaustive switch.\n * - `status` — the HTTP status, or 0 when no response arrived at all\n * ('network_error' / 'timeout').\n * - `retryAfterSeconds` — parsed from the `Retry-After` header when present\n * (rate-limit 429s always set it).\n */\nexport class HostedApiError extends Error {\n readonly status: number;\n readonly code: string;\n readonly retryAfterSeconds?: number;\n\n constructor(args: { status: number; code: string; message: string; retryAfterSeconds?: number }) {\n super(args.message);\n this.name = \"HostedApiError\";\n this.status = args.status;\n this.code = args.code;\n if (args.retryAfterSeconds !== undefined) this.retryAfterSeconds = args.retryAfterSeconds;\n }\n}\n","// Typed API client for the hosted session-token surface (Plan 6 Task 5).\n// Framework-free browser code — fetch + AbortSignal only, same zero-React rule\n// as core/. Hand-authored against the CURRENT identity-backend (Tasks 0+1+2);\n// see types.ts / errors.ts for the verified wire shapes.\nimport { HostedApiError } from \"./errors\";\nimport type {\n CheckInputByType,\n CheckType,\n CompleteMediaResult,\n ConsentLocale,\n HostedSessionView,\n MediaKind,\n PresignRequest,\n PresignUploadResult,\n RecordConsentResult,\n SessionView,\n SubmitCheckBody,\n} from \"./types\";\n\n/** Default per-request timeout on API calls (override via `requestTimeoutMs`). */\nconst DEFAULT_REQUEST_TIMEOUT_MS = 30_000;\n\n/**\n * Timeout on the Spaces PUT — matches the presign TTL (900 s): the signature is\n * unusable after that anyway, and a 15 MB clip at 20 KB/s still finishes in\n * ~13 min. Bounds a stalled in-flight socket (the TTL alone only bounds when a\n * PUT can START, not how long a hung transfer may sit).\n */\nconst SPACES_PUT_TIMEOUT_MS = 900_000;\n\n/** Max chars of an S3 error body quoted into an upload_failed message. */\nconst UPLOAD_ERROR_SNIPPET_CHARS = 200;\n\n/** Bounded auto-retry defaults for 409 `idempotency_in_progress` (retries AFTER the first try). */\nconst IN_PROGRESS_RETRY_ATTEMPTS = 5;\nconst IN_PROGRESS_RETRY_DELAY_MS = 400;\n\n/**\n * Strip MIME parameters: `video/webm;codecs=vp8,opus` → `video/webm`.\n *\n * The capture engine (Task 4) emits `clipMimeType` WITH codec parameters, but\n * the presign allowlist holds BARE types only (['video/webm','video/mp4'] /\n * ['image/jpeg','image/png']) and the presigned PUT signs the exact declared\n * Content-Type. Exported so pages can normalize once and stay byte-consistent\n * between presign and PUT.\n */\nexport function stripMimeParams(contentType: string): string {\n return (contentType.split(\";\")[0] ?? \"\").trim();\n}\n\n/** Media-bearing check types → the input field the promoted key goes into. */\nconst MEDIA_INPUT_FIELD = {\n liveness: \"clipKey\",\n face_match: \"imageKey\",\n doc_ocr: \"imageKey\",\n} as const;\n\n/** Check types that take an uploaded media key (population_registry does not). */\nexport type MediaCheckType = keyof typeof MEDIA_INPUT_FIELD;\n\nexport interface SubmitOptions {\n /**\n * Sent as `x-idempotency-key` (the header IdempotencyInterceptor reads).\n * One key per LOGICAL submit — a flaky-network retry with the same key\n * replays the first response without burning another attempt.\n */\n idempotencyKey?: string;\n /** SANDBOX-ONLY deterministic override (plan D-C); a live session 403s it. */\n forceOutcome?: \"pass\" | \"fail\";\n}\n\nexport interface UploadMedia {\n kind: MediaKind;\n blob: Blob;\n /** May carry codec params (engine `clipMimeType`) — stripped before presign AND PUT. */\n contentType: string;\n}\n\nexport interface HostedClientOptions {\n /** API origin, e.g. `https://api.sekyro.ai` — paths are `${apiOrigin}/api/v2/...`. */\n apiOrigin: string;\n /** The raw session token from the hosted URL (short code; legacy `cst_` during its TTL) — sent as `x-session-token` on every API call. */\n sessionToken: string;\n /** Injection seam (tests / non-window contexts). Defaults to `globalThis.fetch`. */\n fetch?: typeof globalThis.fetch;\n /** Per-request timeout for API calls (NOT the Spaces PUT). Default 30 000 ms. */\n requestTimeoutMs?: number;\n /**\n * Tuning for the ONLY automatic retry the client performs: 409\n * `idempotency_in_progress` (a concurrent identical request is mid-flight\n * server-side; the real response lands once it finishes). `attempts` counts\n * retries AFTER the first try. Defaults: 5 × 400 ms.\n */\n inProgressRetry?: { attempts?: number; delayMs?: number };\n}\n\n/**\n * Hand-authored typed client for the five session-token endpoints:\n *\n * GET /api/v2/hosted/session → {@link getSession}\n * POST /api/v2/hosted/consent → {@link recordConsent}\n * POST /api/v2/sessions/:id/media → {@link presign}\n * POST /api/v2/sessions/:id/media/complete → {@link completeMedia}\n * POST /api/v2/sessions/:id/checks/:checkType → {@link submitCheck}\n *\n * plus the bare presigned Spaces PUT ({@link uploadToSpaces}) and the\n * presign→PUT→complete→submit composition ({@link uploadAndSubmit}).\n *\n * Envelopes (verified against sessions-docs.e2e-spec.ts):\n * - success: `{success: true, data}` — unwrapped here, methods return the payload;\n * - error: flat `{code, message}` → thrown as {@link HostedApiError}.\n *\n * The media/checks routes are `:id`-addressed while the token itself is the\n * only credential the page starts with — the client learns its sessionId from\n * `GET /hosted/session` (token-addressed) and lazily bootstraps it when a\n * `:id` route is called first.\n *\n * No automatic retry EXCEPT bounded short-delay retry on 409\n * `idempotency_in_progress`. Everything else — including 429 with its parsed\n * `retryAfterSeconds` — is surfaced to the page to handle.\n */\nexport class HostedClient {\n private readonly apiOrigin: string;\n private readonly sessionToken: string;\n private readonly fetchImpl: typeof globalThis.fetch;\n private readonly requestTimeoutMs: number;\n private readonly retryAttempts: number;\n private readonly retryDelayMs: number;\n\n private sessionId: string | null = null;\n private bootstrap: Promise<HostedSessionView> | null = null;\n\n constructor(opts: HostedClientOptions) {\n this.apiOrigin = opts.apiOrigin.replace(/\\/+$/, \"\");\n this.sessionToken = opts.sessionToken;\n // Always wrap and `.call(globalThis, …)`: browsers throw \"Illegal\n // invocation\" when fetch runs with a `this` that isn't the global — both\n // for the default AND for an injected `window.fetch`.\n const impl = opts.fetch;\n this.fetchImpl = (input, init) => (impl ?? globalThis.fetch).call(globalThis, input, init);\n this.requestTimeoutMs = opts.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;\n this.retryAttempts = opts.inProgressRetry?.attempts ?? IN_PROGRESS_RETRY_ATTEMPTS;\n this.retryDelayMs = opts.inProgressRetry?.delayMs ?? IN_PROGRESS_RETRY_DELAY_MS;\n }\n\n /** Token-addressed bootstrap — the hosted page's first call. Caches the sessionId. */\n async getSession(): Promise<HostedSessionView> {\n const view = await this.api<HostedSessionView>(\"GET\", \"/hosted/session\");\n this.sessionId = view.sessionId;\n return view;\n }\n\n /**\n * Record consent once (201; an idempotent replay answers 200 with\n * `alreadyRecorded: true`). Until recorded, media presign/complete AND check\n * submission answer 409 `consent_required`.\n */\n async recordConsent(locale: ConsentLocale): Promise<RecordConsentResult> {\n return this.api<RecordConsentResult>(\"POST\", \"/hosted/consent\", { body: { locale } });\n }\n\n /**\n * Presign a Spaces PUT for a new pending object. `contentType` is stripped of\n * MIME parameters defensively (the allowlist holds bare types; the engine's\n * `clipMimeType` carries codec params) — PUT with the SAME bare type, or the\n * signed-header check rejects the upload.\n */\n async presign(\n kind: MediaKind,\n contentType: string,\n contentLength: number,\n ): Promise<PresignUploadResult> {\n const id = await this.ensureSessionId();\n const body: PresignRequest = { kind, contentType: stripMimeParams(contentType), contentLength };\n return this.api<PresignUploadResult>(\"POST\", `/sessions/${id}/media`, { body });\n }\n\n /**\n * Bare PUT to the presigned Spaces URL: EXACTLY the signed headers — the\n * declared Content-Type and the blob body. NO `x-session-token` (the\n * signature IS the credential; an extra header breaks nothing but leaks the\n * token to a third-party host) and no JSON envelope.\n *\n * `contentType` is param-stripped here too (idempotent for bare types): the\n * presign strips internally, so a caller composing manually with the engine's\n * parameterful `clipMimeType` would otherwise sign `video/webm` but PUT\n * `video/webm;codecs=…` — a signed-header mismatch S3 rejects at runtime.\n *\n * Timeout: 15 min (`AbortSignal.timeout(900_000)`, matching the presign TTL)\n * rather than the API calls' 30 s — a 15 MB clip on a slow link legitimately\n * exceeds 30 s, but a stalled in-flight socket must still be bounded (the TTL\n * alone only bounds when a PUT can START).\n *\n * Failures are ALWAYS typed: non-2xx throws {@link HostedApiError} with the\n * client-synthesized `upload_failed` (message carries a truncated S3 body\n * snippet — e.g. SignatureDoesNotMatch); a mid-transfer drop → `network_error`;\n * the timeout → `timeout`.\n */\n async uploadToSpaces(uploadUrl: string, blob: Blob, contentType: string): Promise<void> {\n let res: Response;\n try {\n res = await this.fetchImpl(uploadUrl, {\n method: \"PUT\",\n headers: { \"content-type\": stripMimeParams(contentType) },\n body: blob,\n signal: AbortSignal.timeout(SPACES_PUT_TIMEOUT_MS),\n });\n } catch (err) {\n throw asTransportError(err);\n }\n if (!res.ok) {\n const snippet = (await res.text().catch(() => \"\")).slice(0, UPLOAD_ERROR_SNIPPET_CHARS);\n throw new HostedApiError({\n status: res.status,\n code: \"upload_failed\",\n message: `media upload failed (HTTP ${res.status})${snippet ? `: ${snippet}` : \"\"}`,\n });\n }\n }\n\n /** Finalize an upload: the backend sniffs + promotes; returns the PROMOTED key to submit. */\n async completeMedia(key: string): Promise<CompleteMediaResult> {\n const id = await this.ensureSessionId();\n return this.api<CompleteMediaResult>(\"POST\", `/sessions/${id}/media/complete`, {\n body: { key },\n });\n }\n\n /**\n * Submit one check. Sends `{input, forceOutcome?}` (SubmitCheckSchema) and the\n * optional `x-idempotency-key` header. Returns the whitelisted SessionView.\n */\n async submitCheck<T extends CheckType>(\n checkType: T,\n input: CheckInputByType[T],\n opts: SubmitOptions = {},\n ): Promise<SessionView> {\n const id = await this.ensureSessionId();\n const body: SubmitCheckBody = {\n input: input as unknown as Record<string, unknown>,\n ...(opts.forceOutcome !== undefined ? { forceOutcome: opts.forceOutcome } : {}),\n };\n return this.api<SessionView>(\"POST\", `/sessions/${id}/checks/${checkType}`, {\n body,\n ...(opts.idempotencyKey !== undefined ? { idempotencyKey: opts.idempotencyKey } : {}),\n });\n }\n\n /**\n * Convenience composition: presign → PUT → complete → submit, passing the\n * PROMOTED key (from complete's response — never the pending presign key)\n * into the check's media input field (`clipKey` for liveness, `imageKey` for\n * face_match/doc_ocr). `extraInput` carries the remaining input fields\n * (liveness `attestation`, doc_ocr `side`). The media content type is\n * param-stripped ONCE and used for both presign and PUT, so the signed\n * header always matches.\n */\n async uploadAndSubmit<T extends MediaCheckType>(\n checkType: T,\n media: UploadMedia,\n extraInput: Omit<CheckInputByType[T], (typeof MEDIA_INPUT_FIELD)[T]>,\n opts: SubmitOptions = {},\n ): Promise<SessionView> {\n const bareType = stripMimeParams(media.contentType);\n const presigned = await this.presign(media.kind, bareType, media.blob.size);\n await this.uploadToSpaces(presigned.uploadUrl, media.blob, bareType);\n const completed = await this.completeMedia(presigned.key);\n const input = {\n ...extraInput,\n [MEDIA_INPUT_FIELD[checkType]]: completed.key,\n } as unknown as CheckInputByType[T];\n return this.submitCheck(checkType, input, opts);\n }\n\n // ── transport ──────────────────────────────────────────────────────────────\n\n /** The token's own sessionId — cached from getSession(), lazily bootstrapped. */\n private async ensureSessionId(): Promise<string> {\n if (this.sessionId !== null) return this.sessionId;\n // Dedupe concurrent bootstraps; reset on settle so a failure can be retried.\n this.bootstrap ??= this.getSession().finally(() => {\n this.bootstrap = null;\n });\n return (await this.bootstrap).sessionId;\n }\n\n /**\n * One API request: `${apiOrigin}/api/v2${path}`, `x-session-token` always,\n * AbortSignal timeout (30 s default), `{success, data}` unwrap on 2xx, flat\n * `{code, message}` → {@link HostedApiError} on non-2xx. EVERY failure is\n * typed: a rejected fetch → `network_error`, the timeout → `timeout`, an\n * unparseable 2xx body → `unknown_error` — the page never sees a raw\n * TypeError/DOMException. The ONLY automatic retry is 409\n * `idempotency_in_progress` (bounded, short delay).\n */\n private async api<T>(\n method: \"GET\" | \"POST\",\n path: string,\n opts: { body?: unknown; idempotencyKey?: string } = {},\n ): Promise<T> {\n const url = `${this.apiOrigin}/api/v2${path}`;\n const headers: Record<string, string> = { \"x-session-token\": this.sessionToken };\n if (opts.body !== undefined) headers[\"content-type\"] = \"application/json\";\n if (opts.idempotencyKey !== undefined) headers[\"x-idempotency-key\"] = opts.idempotencyKey;\n\n for (let attempt = 0; ; attempt++) {\n let res: Response;\n try {\n res = await this.fetchImpl(url, {\n method,\n headers,\n ...(opts.body !== undefined ? { body: JSON.stringify(opts.body) } : {}),\n signal: AbortSignal.timeout(this.requestTimeoutMs),\n });\n } catch (err) {\n throw asTransportError(err);\n }\n\n if (res.ok) {\n let raw: unknown;\n try {\n raw = await res.json();\n } catch {\n throw new HostedApiError({\n status: res.status,\n code: \"unknown_error\",\n message: `response body was not valid JSON (HTTP ${res.status})`,\n });\n }\n return unwrap<T>(raw);\n }\n\n const err = await parseErrorResponse(res);\n if (err.code === \"idempotency_in_progress\" && attempt < this.retryAttempts) {\n if (this.retryDelayMs > 0) await sleep(this.retryDelayMs);\n continue;\n }\n throw err;\n }\n }\n}\n\n/**\n * Normalize a rejected fetch into the typed contract (status 0 — no response\n * arrived): AbortSignal.timeout aborts with a DOMException named 'TimeoutError'\n * → `timeout`; everything else (TypeError on connection drop / DNS / CORS /\n * mid-transfer failure) → `network_error`. Duck-typed on `.name` because\n * DOMException does not inherit Error in every environment (e.g. jsdom).\n */\nfunction asTransportError(err: unknown): HostedApiError {\n const name = typeof err === \"object\" && err !== null ? (err as { name?: unknown }).name : undefined;\n if (name === \"TimeoutError\") {\n return new HostedApiError({ status: 0, code: \"timeout\", message: \"request timed out\" });\n }\n const detail = err instanceof Error ? err.message : String(err);\n return new HostedApiError({\n status: 0,\n code: \"network_error\",\n message: `network request failed: ${detail}`,\n });\n}\n\n/**\n * Unwrap the global success envelope `{success: true, data}` (ResponseTransform-\n * Interceptor wraps every object body that lacks a `success` key). Defensive:\n * a body without the envelope is returned as-is.\n */\nfunction unwrap<T>(raw: unknown): T {\n if (raw !== null && typeof raw === \"object\" && \"success\" in raw && \"data\" in raw) {\n return (raw as { data: T }).data;\n }\n return raw as T;\n}\n\n/**\n * Parse a non-2xx response into a {@link HostedApiError}: the public envelope\n * is flat `{code, message}`; a non-JSON body (proxy HTML, etc.) degrades to the\n * client-synthesized `unknown_error`. `Retry-After` (seconds) is parsed when\n * present — rate-limit 429s always set it.\n */\nasync function parseErrorResponse(res: Response): Promise<HostedApiError> {\n let code = \"unknown_error\";\n let message = `request failed (HTTP ${res.status})`;\n try {\n const body: unknown = await res.json();\n if (body !== null && typeof body === \"object\") {\n const env = body as { code?: unknown; message?: unknown };\n if (typeof env.code === \"string\" && env.code.length > 0) code = env.code;\n if (typeof env.message === \"string\" && env.message.length > 0) message = env.message;\n }\n } catch {\n // Not JSON — keep the defensive fallback.\n }\n const retryAfterRaw = res.headers.get(\"retry-after\");\n const retryAfter = retryAfterRaw === null ? Number.NaN : Number.parseInt(retryAfterRaw, 10);\n return new HostedApiError({\n status: res.status,\n code,\n message,\n ...(Number.isFinite(retryAfter) && retryAfter >= 0 ? { retryAfterSeconds: retryAfter } : {}),\n });\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","// Result mapping: server view → the public VerificationResult (spec §3.1) plus\n// the view helpers the flow needs (frontier, terminal, view merge).\nimport type {\n CheckReason,\n CheckType,\n HostedSessionView,\n HostedStepView,\n SessionView,\n} from \"../client/types\";\nimport type { ReasonCode, VerificationResult } from \"./types\";\n\n/**\n * Reasons the backend parks at `input_required` while attempts remain\n * (identity-backend/src/checks/check-reasons.ts isRetryable tables — the single\n * source of truth; identity-hosted/lib/reason-copy.ts mirrors the same rows).\n */\nexport const RETRYABLE_REASONS: ReadonlySet<CheckReason> = new Set<CheckReason>([\n \"no_face\",\n \"media_unreadable\",\n \"clip_too_short\",\n \"no_face_source\",\n \"side_missing\",\n \"unreadable\",\n \"registry_unavailable\",\n \"otp_mismatch\",\n \"otp_expired\",\n \"otp_send_failed\",\n]);\n\n/** The two checks one biometric capture feeds. */\nconst BIOMETRIC_CHECKS: ReadonlySet<CheckType> = new Set<CheckType>([\"liveness\", \"face_match\"]);\n\n/** A check the browser may still submit. */\nexport function isExecutable(step: HostedStepView | undefined): boolean {\n return step !== undefined && (step.state === \"pending\" || step.state === \"input_required\");\n}\n\n/** The session accepts no further submissions. */\nexport function isTerminalView(view: Pick<HostedSessionView, \"status\">): boolean {\n return view.status !== \"created\" && view.status !== \"in_progress\";\n}\n\n/** First step in `steps[]` order with state `pending | input_required` (the backend's frontier). */\nexport function frontierStep(view: HostedSessionView): HostedStepView | undefined {\n return view.steps.find((step) => isExecutable(step));\n}\n\nexport function stepOf(view: HostedSessionView, checkType: CheckType): HostedStepView | undefined {\n return view.steps.find((step) => step.checkType === checkType);\n}\n\n/**\n * Fold a submit response (partner `SessionView`: no attemptsRemaining) into the\n * hosted view: status/outcome/step states+reasons come from the response; the\n * submitted check's `attemptsRemaining` is decremented locally (every accepted\n * submit consumes exactly one attempt server-side — `max(0, cap - attempts)`).\n * This keeps the happy path free of extra `GET /hosted/session` round-trips.\n */\nexport function mergeSessionView(\n prev: HostedSessionView,\n next: SessionView,\n submitted: CheckType,\n): HostedSessionView {\n const byType = new Map(prev.steps.map((step) => [step.checkType, step] as const));\n const steps: HostedStepView[] = next.steps.map((step) => {\n const before = byType.get(step.checkType);\n const attemptsBefore = before?.attemptsRemaining ?? 0;\n const merged: HostedStepView = {\n ...(before ?? {}),\n checkType: step.checkType,\n state: step.state,\n attemptsRemaining:\n step.checkType === submitted ? Math.max(0, attemptsBefore - 1) : attemptsBefore,\n };\n if (step.reason !== undefined) merged.reason = step.reason;\n else delete merged.reason;\n return merged;\n });\n return { ...prev, status: next.status, outcome: next.outcome, steps, expiresAt: next.expiresAt };\n}\n\nexport function unavailable(sessionId: string, reason?: ReasonCode): VerificationResult {\n return reason === undefined\n ? { sessionId, status: \"unavailable\" }\n : { sessionId, status: \"unavailable\", reason };\n}\n\nfunction withReason(\n sessionId: string,\n status: VerificationResult[\"status\"],\n reason: CheckReason | undefined,\n): VerificationResult {\n return reason === undefined ? { sessionId, status } : { sessionId, status, reason };\n}\n\n/**\n * Map the session view to the public result:\n * - `completed/approved → approved`, `completed/review` or `review_pending → review`,\n * `failed` or `completed/rejected → rejected` (reason = the deciding step's);\n * - `expired → unavailable` (no reason);\n * - in flight: a biometric step parked at `input_required` with a retryable\n * reason → `retry` when `autoRetry` and attempts remain, else `rejected`\n * (the partner opted out of retries — this capture was refused); a step in\n * `review` with nothing executable left → `review`; otherwise `unavailable`\n * (a non-biometric frontier the SDK cannot drive, or still processing).\n */\nexport function mapSessionResult(\n view: HostedSessionView,\n opts: { autoRetry: boolean },\n): VerificationResult {\n const { sessionId } = view;\n switch (view.status) {\n case \"completed\":\n if (view.outcome === \"approved\") return { sessionId, status: \"approved\" };\n if (view.outcome === \"review\") return withReason(sessionId, \"review\", reasonIn(view, \"review\"));\n return withReason(sessionId, \"rejected\", reasonIn(view, \"failed\"));\n case \"failed\":\n return withReason(sessionId, \"rejected\", reasonIn(view, \"failed\"));\n case \"review_pending\":\n return withReason(sessionId, \"review\", reasonIn(view, \"review\"));\n case \"expired\":\n return unavailable(sessionId);\n case \"created\":\n case \"in_progress\":\n break;\n default: {\n const unhandled: never = view.status;\n throw new Error(`mapSessionResult: unhandled status ${unhandled as string}`);\n }\n }\n\n const parked = view.steps.find(\n (step) =>\n BIOMETRIC_CHECKS.has(step.checkType) &&\n step.state === \"input_required\" &&\n step.reason !== undefined,\n );\n if (parked?.reason !== undefined) {\n const canRetry =\n opts.autoRetry && RETRYABLE_REASONS.has(parked.reason) && parked.attemptsRemaining > 0;\n return {\n sessionId,\n status: canRetry ? \"retry\" : \"rejected\",\n reason: parked.reason,\n attemptsRemaining: parked.attemptsRemaining,\n };\n }\n if (frontierStep(view) === undefined && view.steps.some((step) => step.state === \"review\")) {\n return withReason(sessionId, \"review\", reasonIn(view, \"review\"));\n }\n return unavailable(sessionId);\n}\n\n/** Reason of the first step in the given state (the deciding check). */\nfunction reasonIn(view: HostedSessionView, state: HostedStepView[\"state\"]): CheckReason | undefined {\n return view.steps.find((step) => step.state === state && step.reason !== undefined)?.reason;\n}\n","// The post-capture flow, driven by the CURRENT hosted frontier: when `liveness`\n// is the frontier → upload the clip → attestation → submit `liveness`, then\n// `face_match` from this capture's keyframe; when liveness already settled and\n// `face_match` is the frontier → keyframe + `face_match` only; nothing the SDK\n// can drive → settled (the caller maps the view). A RESYNC 409\n// (check_already_finalized / check_out_of_order / stale frontier) re-GETs the\n// view and RE-ENTERS the same frontier logic (bounded) instead of giving up —\n// a liveness that passed under an earlier run still gets its face_match.\n// Logic ported (not the React) from\n// identity-hosted/lib/use-submit.ts (idempotency-key lifecycle, same-key\n// transport replay, one-shot consent_required recovery) and\n// lib/use-capture-submission.ts + components/steps/liveness-step.tsx (the\n// `buildSubmit` executor closures and the face_match chain).\n//\n// Per-submission caches (promoted media key, attestation) are CLOSURE LOCALS of\n// each executor: a same-key replay re-runs the executor with the caches intact\n// (byte-identical body — a re-presign or a fresh token under the same key would\n// be an idempotency_key_collision); fresh artifacts build fresh closures.\nimport { HostedApiError } from \"../client/errors\";\nimport { type HostedClient, stripMimeParams } from \"../client/hosted-client\";\nimport type {\n AttestationInput,\n CheckType,\n HostedSessionView,\n SessionView,\n} from \"../client/types\";\nimport { frontierStep, isTerminalView, stepOf } from \"./result\";\nimport type { CapturedArtifacts, SdkFailureReason } from \"./types\";\n\n/** The client surface the flow needs — `HostedClient` or a test fake. */\nexport type HostedClientLike = Pick<\n HostedClient,\n \"getSession\" | \"recordConsent\" | \"presign\" | \"uploadToSpaces\" | \"completeMedia\" | \"submitCheck\"\n>;\n\n/** The presign policy allowlist for `kind: 'clip'` (media.policy.ts mirror). */\nexport const CLIP_MIME_ALLOWLIST: readonly string[] = [\"video/webm\", \"video/mp4\"];\n\n/** The engine's keyframe encode (captureMirroredKeyframe → canvas JPEG). */\nconst KEYFRAME_MIME = \"image/jpeg\";\n\n/** Same-key transport replays AFTER the first try, and the pause between them. */\nexport const TRANSPORT_REPLAY_ATTEMPTS = 2;\nexport const TRANSPORT_REPLAY_DELAY_MS = 1_000;\n/** Cap on honouring a 429's Retry-After before giving up on this capture. */\nconst MAX_RETRY_AFTER_MS = 10_000;\n/**\n * Bound on frontier re-entries after a RESYNC code per capture (each re-entry\n * re-GETs the view; each executable check is submitted at most once per capture).\n */\nexport const RESYNC_REENTRY_MAX = 3;\n\n/** No (usable) response arrived — a same-key replay can succeed. */\nconst TRANSPORT_CODES: ReadonlySet<string> = new Set([\n \"network_error\",\n \"timeout\",\n \"upload_failed\",\n \"unknown_error\",\n \"rate_limit_exceeded\",\n]);\n\n/** The server moved past what we hold — re-GET and map from truth. */\nconst RESYNC_CODES: ReadonlySet<string> = new Set([\n \"session_not_active\",\n \"check_not_found\",\n \"check_already_finalized\",\n \"check_out_of_order\",\n]);\n\n/** A Turnstile challenge failed client-side (load / render / error-callback / timeout). */\nexport class AttestationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"AttestationError\";\n }\n}\n\n/** One logical submission: receives the client and ITS idempotency key. */\nexport type SubmitExecutor = (\n client: HostedClientLike,\n idempotencyKey: string,\n) => Promise<SessionView>;\n\nexport interface SubmitRuntime {\n client: HostedClientLike;\n /** Force-record consent (the server just said it is missing). */\n ensureConsent(opts: { force: true }): Promise<void>;\n sleep(ms: number): Promise<void>;\n uuid(): string;\n}\n\n/**\n * Run one logical submission (ported use-submit semantics):\n * - a fresh `crypto.randomUUID()` key per logical submission;\n * - a transport-class failure replays the SAME executor under the SAME key\n * (bounded) — the backend's IdempotencyInterceptor returns the first\n * response instead of burning another attempt;\n * - ONE `consent_required` recovery: force-record consent and re-run under a\n * FRESH key (the 409 envelope is idempotency-cached under the old one);\n * - ONE attestation retry (client-side Turnstile failure or a server\n * `attestation_invalid`): `onAttestationInvalid` drops the cached token and\n * the executor re-runs under a fresh key.\n * Throws the final error otherwise.\n */\nexport async function runSubmission(\n rt: SubmitRuntime,\n executor: SubmitExecutor,\n hooks: { onAttestationInvalid?: () => void } = {},\n): Promise<SessionView> {\n let key = rt.uuid();\n let consentRecovered = false;\n let attestationRetried = false;\n let transportReplays = 0;\n for (;;) {\n try {\n return await executor(rt.client, key);\n } catch (err) {\n if (err instanceof AttestationError) {\n if (attestationRetried) throw err;\n attestationRetried = true;\n hooks.onAttestationInvalid?.();\n key = rt.uuid();\n continue;\n }\n if (!(err instanceof HostedApiError)) throw err;\n if (err.code === \"consent_required\" && !consentRecovered) {\n consentRecovered = true;\n await rt.ensureConsent({ force: true });\n key = rt.uuid();\n continue;\n }\n if (err.code === \"attestation_invalid\" && !attestationRetried) {\n attestationRetried = true;\n hooks.onAttestationInvalid?.();\n key = rt.uuid();\n continue;\n }\n if (TRANSPORT_CODES.has(err.code) && transportReplays < TRANSPORT_REPLAY_ATTEMPTS) {\n transportReplays += 1;\n const retryAfterMs =\n err.retryAfterSeconds !== undefined ? err.retryAfterSeconds * 1000 : undefined;\n await rt.sleep(\n retryAfterMs !== undefined\n ? Math.min(retryAfterMs, MAX_RETRY_AFTER_MS)\n : TRANSPORT_REPLAY_DELAY_MS,\n );\n continue;\n }\n throw err;\n }\n }\n}\n\nexport interface LivenessFlowDeps extends SubmitRuntime {\n artifacts: CapturedArtifacts;\n /** Fresh attestation per call (Turnstile execute, or `{sandbox: true}`). */\n getAttestation(): Promise<AttestationInput>;\n /** Latest hosted view (frontier decisions). */\n getView(): HostedSessionView;\n /** Re-GET the view from the server (after a RESYNC code) and fold it in. */\n refreshView(): Promise<HostedSessionView>;\n /** Fold a submit response into the view. */\n applySubmit(view: SessionView, submitted: CheckType): void;\n /** Flow-state hook for the capture handle. */\n onPhase(phase: \"uploading\" | \"checking\"): void;\n /** The verification was destroyed (the only thing that cancels a chain). */\n isCancelled(): boolean;\n}\n\nexport type LivenessFlowOutcome =\n | { kind: \"settled\" }\n | { kind: \"resync\" }\n | { kind: \"unavailable\"; reason: SdkFailureReason }\n | { kind: \"cancelled\" };\n\n/** Liveness states after which THIS capture's keyframe may feed face_match. */\nconst LIVENESS_CHAINABLE: ReadonlySet<string> = new Set([\"passed\", \"review\", \"processing\", \"skipped\"]);\n\n/**\n * Run the biometric submissions the CURRENT frontier allows, re-evaluating\n * after every submit and after every RESYNC re-GET:\n * - frontier `liveness` → clip upload + attestation + `liveness` (once per capture);\n * - frontier `face_match` → keyframe upload + `face_match` (once per capture),\n * allowed when liveness was NOT part of this capture (it had already\n * settled — any state, incl. `failed`: the selfie-fallback case, where this\n * capture only feeds face_match) or settled chainable from this capture\n * (passed / review / processing / skipped — or absent);\n * - anything else (terminal view, a non-biometric frontier, a check this\n * capture already submitted) → `settled` for the caller to map the view.\n * A RESYNC code re-GETs the view and re-enters (at most {@link RESYNC_REENTRY_MAX}\n * times); the final RESYNC surfaces as `resync` for the caller to map.\n */\nexport async function runLivenessFlow(deps: LivenessFlowDeps): Promise<LivenessFlowOutcome> {\n const { artifacts } = deps;\n const clip = artifacts.clip;\n const bareMime = stripMimeParams(artifacts.clipMime ?? \"\");\n if (\n artifacts.degraded === \"NO_RECORDER\" ||\n clip === undefined ||\n !CLIP_MIME_ALLOWLIST.includes(bareMime)\n ) {\n // No clip, or a container outside the presign allowlist (never sign an\n // off-allowlist type): v2 cannot run THIS capture.\n return { kind: \"unavailable\", reason: \"no_recorder\" };\n }\n\n // Per-capture executors: their closure caches (promoted media key,\n // attestation) survive a same-key transport replay; each is run at most once.\n const submitLiveness = buildLivenessSubmit(deps, clip, bareMime);\n const submitFaceMatch = buildFaceMatchSubmit(deps, artifacts.keyframe);\n let livenessSubmitted = false;\n let faceMatchSubmitted = false;\n let livenessChainable = true;\n let resyncs = 0;\n\n for (;;) {\n if (deps.isCancelled()) return { kind: \"cancelled\" };\n const view = deps.getView();\n if (isTerminalView(view)) return { kind: \"settled\" };\n const frontier = frontierStep(view)?.checkType;\n const next =\n frontier === \"liveness\" && !livenessSubmitted\n ? \"liveness\"\n : frontier === \"face_match\" && !faceMatchSubmitted && livenessChainable\n ? \"face_match\"\n : null;\n if (next === null) return { kind: \"settled\" };\n try {\n if (next === \"liveness\") {\n livenessSubmitted = true;\n const response = await submitLiveness();\n if (deps.isCancelled()) return { kind: \"cancelled\" };\n deps.applySubmit(response, \"liveness\");\n const state = stepOf(deps.getView(), \"liveness\")?.state;\n livenessChainable = state === undefined || LIVENESS_CHAINABLE.has(state);\n } else {\n faceMatchSubmitted = true;\n const response = await submitFaceMatch();\n if (deps.isCancelled()) return { kind: \"cancelled\" };\n deps.applySubmit(response, \"face_match\");\n }\n } catch (err) {\n if (deps.isCancelled()) return { kind: \"cancelled\" };\n const outcome = classifyFailure(err);\n if (outcome.kind !== \"resync\" || resyncs >= RESYNC_REENTRY_MAX) return outcome;\n resyncs += 1;\n // The server moved past what we hold: re-GET and re-enter from truth.\n await deps.refreshView();\n }\n }\n}\n\nfunction buildLivenessSubmit(\n deps: LivenessFlowDeps,\n clip: Blob,\n bareMime: string,\n): () => Promise<SessionView> {\n let clipKey: string | null = null;\n let attestation: AttestationInput | null = null;\n return () =>\n runSubmission(\n deps,\n async (client, idempotencyKey) => {\n if (clipKey === null) {\n deps.onPhase(\"uploading\");\n const presigned = await client.presign(\"clip\", bareMime, clip.size);\n await client.uploadToSpaces(presigned.uploadUrl, clip, bareMime);\n clipKey = (await client.completeMedia(presigned.key)).key;\n }\n // Attestation AFTER the upload settles (token stays fresh), cached\n // for the same-key replay.\n if (attestation === null) {\n try {\n attestation = await deps.getAttestation();\n } catch (err) {\n throw new AttestationError(err instanceof Error ? err.message : String(err));\n }\n }\n deps.onPhase(\"checking\");\n return client.submitCheck(\n \"liveness\",\n { clipKey, attestation, captureChannel: deps.artifacts.captureChannel },\n { idempotencyKey },\n );\n },\n {\n onAttestationInvalid: () => {\n attestation = null;\n },\n },\n );\n}\n\nfunction buildFaceMatchSubmit(deps: LivenessFlowDeps, keyframe: Blob): () => Promise<SessionView> {\n let imageKey: string | null = null;\n return () =>\n runSubmission(deps, async (client, idempotencyKey) => {\n if (imageKey === null) {\n deps.onPhase(\"uploading\");\n const presigned = await client.presign(\"image\", KEYFRAME_MIME, keyframe.size);\n await client.uploadToSpaces(presigned.uploadUrl, keyframe, KEYFRAME_MIME);\n imageKey = (await client.completeMedia(presigned.key)).key;\n }\n deps.onPhase(\"checking\");\n return client.submitCheck(\"face_match\", { imageKey }, { idempotencyKey });\n });\n}\n\nfunction classifyFailure(err: unknown): LivenessFlowOutcome {\n if (err instanceof AttestationError) return { kind: \"unavailable\", reason: \"attestation\" };\n if (err instanceof HostedApiError) {\n if (err.code === \"attestation_invalid\") return { kind: \"unavailable\", reason: \"attestation\" };\n if (RESYNC_CODES.has(err.code)) return { kind: \"resync\" };\n }\n return { kind: \"unavailable\", reason: \"network\" };\n}\n","// Cloudflare Turnstile: lazy script loader + execute-mode invisible challenge.\n// Ported from identity-hosted/lib/turnstile.ts (Plan 6 Task 10 AC4) — same\n// behaviour: the script loads ONCE, lazily, only when a liveness submit first\n// needs a token; each token request renders a fresh execute-mode widget,\n// resolves the callback token, and removes the widget. Hosts' CSP must allow\n// challenges.cloudflare.com.\n//\n// The site key is RUNTIME data (`HostedSessionView.turnstileSiteKey`); when it\n// is null the verification sends `{sandbox: true}` instead of calling this.\n\nexport const TURNSTILE_SCRIPT_SRC = \"https://challenges.cloudflare.com/turnstile/v0/api.js\";\n\n/** Bound on a single execute round-trip (challenge fetch + solve). */\nexport const TURNSTILE_EXECUTE_TIMEOUT_MS = 30_000;\n\nexport interface TurnstileRenderParams {\n sitekey: string;\n callback: (token: string) => void;\n \"error-callback\"?: (code?: string) => void;\n execution?: \"render\" | \"execute\";\n appearance?: \"always\" | \"execute\" | \"interaction-only\";\n}\n\n/** The subset of the Turnstile JS API this module uses. */\nexport interface TurnstileApi {\n render(container: HTMLElement, params: TurnstileRenderParams): string | undefined;\n execute(widgetId: string): void;\n remove(widgetId: string): void;\n}\n\n/** `window.turnstile` without augmenting the global Window type for consumers. */\nfunction installedApi(): TurnstileApi | undefined {\n return (window as unknown as { turnstile?: TurnstileApi }).turnstile;\n}\n\nlet loaderPromise: Promise<TurnstileApi> | null = null;\n\n/** Test-only: reset the module singleton between cases. */\nexport function resetTurnstileForTests(): void {\n loaderPromise = null;\n}\n\n/** Load the Turnstile script once (singleton; a load failure resets it so a\n * retry can re-attempt). */\nexport function loadTurnstile(): Promise<TurnstileApi> {\n loaderPromise ??= new Promise<TurnstileApi>((resolve, reject) => {\n const present = installedApi();\n if (present) {\n resolve(present);\n return;\n }\n const script = document.createElement(\"script\");\n script.src = TURNSTILE_SCRIPT_SRC;\n script.async = true;\n script.onload = () => {\n const api = installedApi();\n if (api) {\n resolve(api);\n } else {\n loaderPromise = null;\n reject(new Error(\"Turnstile script loaded but exposed no API\"));\n }\n };\n script.onerror = () => {\n loaderPromise = null;\n script.remove(); // a retry appends a fresh tag\n reject(new Error(\"Turnstile script failed to load\"));\n };\n document.head.appendChild(script);\n });\n return loaderPromise;\n}\n\n/** Options of {@link executeTurnstile}. */\nexport interface ExecuteTurnstileOptions {\n /** Bound on the challenge round-trip; default {@link TURNSTILE_EXECUTE_TIMEOUT_MS}. */\n timeoutMs?: number;\n /**\n * Aborts the challenge: the promise rejects and the widget, its container and\n * the timeout are cleaned up at once. `createVerification().destroy()` passes\n * its own signal so a torn-down verification never leaves a widget behind.\n */\n signal?: AbortSignal;\n}\n\nfunction abortError(): Error {\n return new Error(\"Turnstile challenge aborted\");\n}\n\n/**\n * Run one invisible execute-mode challenge and resolve its token. Rejects on\n * challenge error, on `signal` abort, or after {@link TURNSTILE_EXECUTE_TIMEOUT_MS}\n * — the verification maps a failure to `result {status:'unavailable',\n * reason:'attestation'}` after one retry.\n */\nexport async function executeTurnstile(\n siteKey: string,\n opts: ExecuteTurnstileOptions = {},\n): Promise<string> {\n const timeoutMs = opts.timeoutMs ?? TURNSTILE_EXECUTE_TIMEOUT_MS;\n const signal = opts.signal;\n if (signal?.aborted) throw abortError();\n const api = await loadTurnstile();\n if (signal?.aborted) throw abortError();\n const container = document.createElement(\"div\");\n document.body.appendChild(container);\n let widgetId: string | undefined;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let onAbort: (() => void) | undefined;\n try {\n return await new Promise<string>((resolve, reject) => {\n timer = setTimeout(\n () => reject(new Error(`Turnstile challenge timed out (${timeoutMs} ms)`)),\n timeoutMs,\n );\n if (signal !== undefined) {\n onAbort = () => reject(abortError());\n signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n widgetId = api.render(container, {\n sitekey: siteKey,\n execution: \"execute\",\n appearance: \"execute\",\n callback: resolve,\n \"error-callback\": (code) => {\n reject(new Error(`Turnstile challenge failed${code ? ` (${code})` : \"\"}`));\n },\n });\n if (widgetId === undefined) {\n reject(new Error(\"Turnstile render returned no widget id\"));\n return;\n }\n api.execute(widgetId);\n });\n } finally {\n // ONE cleanup path for every outcome (token / challenge error / timeout /\n // abort / render failure): the challenge timer and the abort listener must\n // never leak past settlement.\n clearTimeout(timer);\n if (signal !== undefined && onAbort !== undefined) signal.removeEventListener(\"abort\", onAbort);\n if (widgetId !== undefined) {\n try {\n api.remove(widgetId);\n } catch {\n // widget already gone — nothing to clean\n }\n }\n container.remove();\n }\n}\n","// createVerification — composes the hosted client, consent, the early registry\n// submit, the capture handle and the post-capture flow behind the public\n// contract (spec §3.1). Framework-free; the only state is the latest hosted\n// view (re-emitted on every update via `on('view')`).\nimport { HostedClient } from \"../client/hosted-client\";\nimport type { AttestationInput, CheckType, HostedSessionView, SessionView } from \"../client/types\";\nimport {\n createLivenessCaptureInternal,\n type LivenessCaptureInternalHandle,\n type LivenessCaptureInternals,\n} from \"../capture/create-liveness-capture\";\nimport { createEmitter } from \"./emitter\";\nimport {\n type HostedClientLike,\n runLivenessFlow,\n runSubmission,\n type SubmitRuntime,\n} from \"./liveness-flow\";\nimport {\n frontierStep,\n isTerminalView,\n mapSessionResult,\n mergeSessionView,\n stepOf,\n unavailable,\n} from \"./result\";\nimport { executeTurnstile } from \"./turnstile\";\nimport type {\n CapturedArtifacts,\n LivenessCaptureHandle,\n LivenessCaptureOptions,\n Verification,\n VerificationEvents,\n VerificationOptions,\n VerificationResult,\n} from \"./types\";\n\n/** Production API origin — the `apiOrigin` default. */\nexport const DEFAULT_API_ORIGIN = \"https://api.sekyro.ai\";\n\n/** Pause before the single `registry_unavailable` re-submit. */\nexport const REGISTRY_RETRY_DELAY_MS = 5_000;\n\n/** Bounded poll while a biometric verdict is still `processing` after the submits. */\nexport const PROCESSING_POLL_DELAY_MS = 1_500;\nexport const PROCESSING_POLL_MAX = 10;\n\n/**\n * Construction seams — tests and Sekyro's own hosted page (`@sekyro/web/internal`).\n * Not part of the partner contract.\n */\nexport interface VerificationInternals {\n /** Replace the HTTP client (default: `new HostedClient({...})`). */\n client?: HostedClientLike;\n /**\n * Replace the Turnstile challenge (default: {@link executeTurnstile}). The\n * `signal` aborts when the verification is destroyed (M1).\n */\n getTurnstileToken?: (siteKey: string, opts: { signal: AbortSignal }) => Promise<string>;\n /** Capture-engine seams forwarded to {@link createLivenessCaptureInternal}. */\n capture?: LivenessCaptureInternals;\n sleep?: (ms: number) => Promise<void>;\n uuid?: () => string;\n}\n\nfunction defaultSleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/** `crypto.randomUUID()` with a v4 fallback for hosts that lack it. */\nexport function randomUuid(): string {\n const c = (globalThis as { crypto?: Crypto }).crypto;\n if (c !== undefined && typeof c.randomUUID === \"function\") return c.randomUUID();\n const bytes = new Uint8Array(16);\n if (c !== undefined && typeof c.getRandomValues === \"function\") c.getRandomValues(bytes);\n else for (let i = 0; i < 16; i += 1) bytes[i] = Math.floor(Math.random() * 256);\n bytes[6] = ((bytes[6] ?? 0) & 0x0f) | 0x40;\n bytes[8] = ((bytes[8] ?? 0) & 0x3f) | 0x80;\n const hex = [...bytes].map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n}\n\n/**\n * Create a verification bound to one session (spec §3.1):\n * `consent()` → `startRegistry()` → `liveness({video})` → `on('result')`.\n */\nexport function createVerification(options: VerificationOptions): Verification {\n return createVerificationInternal(options, {});\n}\n\n/** {@link createVerification} with construction seams (tests / Sekyro-internal hosts). */\nexport function createVerificationInternal(\n options: VerificationOptions,\n internals: VerificationInternals,\n): Verification {\n const apiOrigin = options.apiOrigin ?? DEFAULT_API_ORIGIN;\n const autoRetry = options.autoRetry ?? true;\n const rearm = options.rearm ?? \"auto\";\n const client: HostedClientLike =\n internals.client ??\n new HostedClient({\n apiOrigin,\n sessionToken: options.clientToken,\n ...(options.fetch !== undefined ? { fetch: options.fetch } : {}),\n });\n const sleep = internals.sleep ?? defaultSleep;\n const uuid = internals.uuid ?? randomUuid;\n const getTurnstileToken = internals.getTurnstileToken ?? executeTurnstile;\n const emitter = createEmitter<VerificationEvents>();\n\n let destroyed = false;\n // Aborts an in-flight Turnstile challenge on destroy() (widget + timer clean up).\n const lifetime = new AbortController();\n\n // ── view ───────────────────────────────────────────────────────────────────\n let view: HostedSessionView | null = null;\n let bootstrap: Promise<HostedSessionView> | null = null;\n const setView = (next: HostedSessionView): void => {\n view = next;\n emitter.emit(\"view\", next);\n };\n const ensureView = (): Promise<HostedSessionView> => {\n if (view !== null) return Promise.resolve(view);\n bootstrap ??= client\n .getSession()\n .then((next) => {\n setView(next);\n return next;\n })\n .finally(() => {\n bootstrap = null;\n });\n return bootstrap;\n };\n const refreshView = async (): Promise<HostedSessionView> => {\n const next = await client.getSession();\n setView(next);\n return next;\n };\n const applySubmit = (response: SessionView, submitted: CheckType): void => {\n if (view !== null) setView(mergeSessionView(view, response, submitted));\n };\n\n // ── consent (idempotent; `force` after a server consent_required) ──────────\n let consentInFlight: Promise<void> | null = null;\n const recordConsent = async (force: boolean): Promise<void> => {\n const current = await ensureView();\n if (!force && current.consentRecorded) return;\n await client.recordConsent(options.locale);\n if (view !== null) setView({ ...view, consentRecorded: true });\n };\n const ensureConsent = (opts?: { force?: boolean }): Promise<void> => {\n if (opts?.force === true) return recordConsent(true);\n consentInFlight ??= recordConsent(false).finally(() => {\n consentInFlight = null;\n });\n return consentInFlight;\n };\n\n const runtime: SubmitRuntime = {\n client,\n ensureConsent: (opts) => ensureConsent(opts),\n sleep,\n uuid,\n };\n\n // ── result emission ────────────────────────────────────────────────────────\n // A session verdict is emitted ONCE (the registry may settle it before any\n // capture); `retry` / `unavailable` are per capture.\n let terminalEmitted = false;\n const emitResult = (result: VerificationResult): void => {\n if (result.status === \"approved\" || result.status === \"rejected\" || result.status === \"review\") {\n if (terminalEmitted) return;\n terminalEmitted = true;\n }\n emitter.emit(\"result\", result);\n };\n\n // ── early registry ─────────────────────────────────────────────────────────\n let registry: Promise<void> | null = null;\n let registryFailed = false;\n // The frontier is population_registry on a session minted WITHOUT a bound\n // NNI: the SDK has nothing to submit (and must never guess one).\n let registryUnbound = false;\n const submitRegistry = (): Promise<SessionView> =>\n runSubmission(runtime, (c, idempotencyKey) =>\n // `{}` input: the session is bound to a SERVER-provided NNI (Plan A Task 2).\n c.submitCheck(\"population_registry\", {}, { idempotencyKey }),\n );\n const runRegistry = async (): Promise<void> => {\n try {\n const current = await ensureView();\n if (isTerminalView(current) || frontierStep(current)?.checkType !== \"population_registry\") {\n return;\n }\n if (current.nniBound !== true) {\n registryUnbound = true;\n return;\n }\n await ensureConsent();\n applySubmit(await submitRegistry(), \"population_registry\");\n const step = view === null ? undefined : stepOf(view, \"population_registry\");\n if (\n step?.state === \"input_required\" &&\n step.reason === \"registry_unavailable\" &&\n step.attemptsRemaining > 0\n ) {\n await sleep(REGISTRY_RETRY_DELAY_MS);\n if (destroyed) return;\n applySubmit(await submitRegistry(), \"population_registry\");\n }\n } catch {\n // Never throws (incl. 409 nni_locked / transport failures): the flow\n // surfaces it through result mapping.\n registryFailed = true;\n return;\n }\n if (view !== null && isTerminalView(view)) emitResult(mapSessionResult(view, { autoRetry }));\n };\n const startRegistry = (): Promise<void> => {\n registry ??= runRegistry();\n return registry;\n };\n\n // ── attestation ────────────────────────────────────────────────────────────\n // The SDK echoes the site key it rendered (`siteKey`) so the backend selects\n // the matching widget secret deterministically — Turnstile tokens are\n // single-use, so the verifier never retries with another secret (C1).\n const getAttestation = async (): Promise<AttestationInput> => {\n const current = await ensureView();\n const siteKey = current.turnstileSiteKey;\n if (siteKey === null) return { sandbox: true };\n return {\n channel: \"hosted_web\",\n siteKey,\n turnstileToken: await getTurnstileToken(siteKey, { signal: lifetime.signal }),\n };\n };\n\n // ── capture + flow ─────────────────────────────────────────────────────────\n // Submission chains are SERIALIZED: a new capture (incl. a host remount that\n // destroyed the old handle mid-upload) never abandons an in-flight chain — it\n // queues behind it and then evaluates the CURRENT frontier. Only destroy() of\n // the verification cancels. Handle side effects (flow states, auto re-arm)\n // reach the handle only while it is alive and still on the attempt that\n // produced the artifacts.\n interface BoundCapture {\n capture: LivenessCaptureInternalHandle;\n alive: boolean;\n /** Engine attempt counter (bumped on every `starting`). */\n attempt: number;\n }\n let active: BoundCapture | null = null;\n let chain: Promise<void> = Promise.resolve();\n let chainDepth = 0;\n\n const settleProcessing = async (): Promise<HostedSessionView> => {\n let current = await ensureView();\n for (\n let i = 0;\n i < PROCESSING_POLL_MAX &&\n !destroyed &&\n !isTerminalView(current) &&\n frontierStep(current) === undefined &&\n current.steps.some((step) => step.state === \"processing\");\n i += 1\n ) {\n await sleep(PROCESSING_POLL_DELAY_MS);\n if (destroyed) break;\n current = await refreshView();\n }\n return current;\n };\n\n const runFlow = async (\n bound: BoundCapture,\n artifacts: CapturedArtifacts,\n capturedAttempt: number,\n ): Promise<void> => {\n const { capture } = bound;\n const isCancelled = (): boolean => destroyed;\n // The handle still shows the attempt these artifacts came from (not\n // destroyed by a remount, no retry()/switchCamera() since).\n const ownsHandle = (): boolean => bound.alive && bound.attempt === capturedAttempt;\n const setPhase = (phase: \"uploading\" | \"checking\" | \"done\"): void => {\n if (ownsHandle()) capture.setFlowState(phase);\n };\n const finish = (result: VerificationResult): void => {\n if (isCancelled()) return;\n emitResult(result);\n if (!ownsHandle()) return;\n if (result.status === \"retry\" && rearm === \"auto\") {\n // Re-arm: the engine restarts and the next `captured` runs a new flow.\n capture.handle.retry();\n return;\n }\n // `done` (incl. a manual-rearm `retry`): the host calls `retry()` on the\n // handle when the user is ready — the engine restarts from there.\n capture.setFlowState(\"done\");\n };\n\n if (artifacts.degraded === \"NO_RECORDER\") {\n // No MediaRecorder: nothing is submitted (no liveness, no face_match).\n const sessionId = view?.sessionId ?? (await ensureView().catch(() => null))?.sessionId ?? \"\";\n finish(unavailable(sessionId, \"no_recorder\"));\n return;\n }\n\n setPhase(\"uploading\");\n try {\n // Registry first: it records consent itself only when it actually\n // submits — an unbound / failed registry frontier ends the flow below\n // without recording a consent nothing was submitted under.\n await startRegistry();\n if (isCancelled()) return;\n let current = await ensureView();\n if (!isTerminalView(current)) {\n if (frontierStep(current)?.checkType === \"population_registry\") {\n // The registry never passed (outage after the retry, or a request-\n // level failure): the biometric checks cannot be submitted.\n finish(\n unavailable(\n current.sessionId,\n registryUnbound ? \"nni_unbound\" : registryFailed ? \"network\" : \"registry_unavailable\",\n ),\n );\n return;\n }\n await ensureConsent();\n if (isCancelled()) return;\n const outcome = await runLivenessFlow({\n ...runtime,\n artifacts,\n getAttestation,\n getView: () => view ?? current,\n refreshView,\n applySubmit,\n onPhase: setPhase,\n isCancelled,\n });\n if (isCancelled()) return;\n if (outcome.kind === \"unavailable\") {\n finish(unavailable(current.sessionId, outcome.reason));\n return;\n }\n if (outcome.kind === \"resync\") await refreshView();\n current = await settleProcessing();\n }\n finish(mapSessionResult(current, { autoRetry }));\n } catch {\n if (isCancelled()) return;\n finish(unavailable(view?.sessionId ?? \"\", \"network\"));\n }\n };\n\n const enqueueFlow = (bound: BoundCapture, artifacts: CapturedArtifacts): void => {\n const capturedAttempt = bound.attempt;\n if (chainDepth > 0 && bound.alive) {\n // Queued behind an in-flight chain: the host sees `uploading` meanwhile.\n bound.capture.setFlowState(\"uploading\");\n }\n chainDepth += 1;\n chain = chain\n .then(() => runFlow(bound, artifacts, capturedAttempt))\n .finally(() => {\n chainDepth -= 1;\n })\n // runFlow never rejects (it maps failures to results); a rejection must\n // still never poison the chain for the captures queued after it.\n .catch(() => undefined);\n };\n\n const liveness = (captureOptions: LivenessCaptureOptions): LivenessCaptureHandle => {\n // Camera teardown of the previous handle (its chain, if any, survives).\n active?.capture.handle.destroy();\n if (active !== null) active.alive = false;\n const capture = createLivenessCaptureInternal(captureOptions, internals.capture);\n const bound: BoundCapture = { capture, alive: true, attempt: 0 };\n active = bound;\n capture.handle.on(\"state\", (state) => {\n // A fresh engine attempt: in-flight flows for older artifacts complete,\n // but no longer push states into (or re-arm) this handle.\n if (state === \"starting\") bound.attempt += 1;\n });\n capture.handle.on(\"captured\", (artifacts) => {\n // Partners' own `captured` handlers run first (the event fires BEFORE\n // any upload); the flow starts on the next microtask, after any\n // in-flight chain.\n void Promise.resolve().then(() => enqueueFlow(bound, artifacts));\n });\n const inner = capture.handle;\n return {\n get state() {\n return inner.state;\n },\n on: (event, handler) => inner.on(event, handler),\n start: () => inner.start(),\n retry: () => inner.retry(),\n switchCamera: () => inner.switchCamera(),\n destroy: () => {\n bound.alive = false;\n if (active === bound) active = null;\n inner.destroy();\n },\n };\n };\n\n return {\n consent: () => ensureConsent(),\n startRegistry,\n liveness,\n on: (event, handler) => emitter.on(event, handler),\n destroy: () => {\n destroyed = true;\n lifetime.abort();\n if (active !== null) {\n active.alive = false;\n active.capture.handle.destroy();\n active = null;\n }\n emitter.clear();\n },\n };\n}\n"],"mappings":"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","names":["i","y","i","a","p","A","B","t","i","E","e","o","n","a","s","I","g","c","r","h","C","Q","l","y","D","d","w","f","m","N","p","F","J","M","u","R","G","k","S","t","y","i","i","o","a","h","t","p","t","w","i","e","s","t","w","h","a","p","extractEyes","a","p","clamp01","_","describeError","best","i","h","err","c","i","sleep","c","i"]}
1
+ {"version":3,"sources":["../../src/core/doc/doc-catalog.ts","../../src/core/v3/frame-quality.ts","../../src/core/doc/doc-gate-v1.ts","scanic-ml-stub:scanic-ml-stub","../../vendor/scanic/scanic.js","../../src/core/doc/detector-scanic.ts","../../src/internal/index.ts","../../src/core/doc/mrz-band.ts","../../src/core/doc/frame-analysis.ts","../../src/core/doc/feedback-aggregator.ts","../../src/core/media.ts","../../src/core/v3/device-profile.ts","../../src/core/doc/capture-session-doc.ts","../../src/core/capture-constraints.ts","../../src/core/clip-recorder.ts","../../src/core/keyframe.ts","../../src/core/v3/detector-blaze.ts","../../src/core/v3/detector-native.ts","../../src/core/v3/detector.ts","../../src/core/v3/detect-worker.ts","../../src/core/v3/detect-scheduler.ts","../../src/core/v3/face-gate-v3.ts","../../src/core/v3/capture-session-v3.ts","../../src/verification/emitter.ts","../../src/capture/create-liveness-capture.ts","../../src/client/errors.ts","../../src/client/hosted-client.ts","../../src/verification/result.ts","../../src/verification/liveness-flow.ts","../../src/verification/turnstile.ts","../../src/verification/create-verification.ts"],"sourcesContent":["// @sekyro/web/core — MR document catalog (Task 33 / D1 docTypes\n// facet, findings §4 verbatim). Pure DATA the hosted guided scanner reads\n// (which sides to prompt, where the MRZ band sits, portrait side, physical\n// aspect) and Phase 7's capability matrix joins. `docType` strings stay\n// VERBATIM with kyc-docs-v2's `document_type` — the doc executor branches on\n// them, no rename layer. `carte_residence` is intentionally ABSENT (DOC-6:\n// residence permits are out of MVP; the executor fails them `unreadable`).\n\n/** Physical geometry the scanner frames (ISO/IEC 7810 / ICAO 9303). */\nexport type DocFormat = \"ID-1\" | \"ID-3\";\n\nexport type DocSide = \"recto\" | \"verso\" | \"single\";\n\nexport interface DocCatalogEntry {\n /** kyc-docs-v2 `document_type`, verbatim. */\n docType: \"carte_identite\" | \"passport\";\n format: DocFormat;\n /** Capture sequence the hosted doc step walks, in order. */\n sides: readonly DocSide[];\n /** MRZ geometry: td1 = 3×30 (ID-1 verso), td3 = 2×44 (passport data page). */\n mrz: \"none\" | \"td1\" | \"td3\";\n /** Which side carries the holder photo (drives portrait expectations). */\n portraitSide: DocSide;\n /** Physical width/height ratio of the framed page. */\n aspectRatio: number;\n /** Where the subject identifier (NNI) is parsed from, when the doc carries one. */\n identifierSource?: \"mrz\";\n}\n\n/**\n * Plausibility aspect bands per format (Task 34 gate input): ID-1 cards are\n * 85.6×53.98mm → 1.586; an ID-3 passport DATA PAGE frames at ≈125×88mm → 1.42\n * (wider tolerance — page curl and hinge shadow skew the detected quad).\n */\nexport const ASPECT_BANDS: Record<DocFormat, { center: number; tolerance: number }> = {\n \"ID-1\": { center: 1.586, tolerance: 0.15 },\n \"ID-3\": { center: 1.42, tolerance: 0.2 },\n};\n\n/** Aspect band for a format — helper the DocGateV1 plausibility check calls. */\nexport function aspectBand(format: DocFormat): { center: number; tolerance: number } {\n return ASPECT_BANDS[format];\n}\n\n/** The MR docTypes facet (findings §4). Order = the hosted picker's display order. */\nexport const MR_DOC_CATALOG: readonly DocCatalogEntry[] = [\n {\n docType: \"carte_identite\",\n format: \"ID-1\",\n sides: [\"recto\", \"verso\"],\n mrz: \"td1\", // verso; carries the NNI with ICAO check digits (findings §6)\n portraitSide: \"recto\",\n aspectRatio: 1.586,\n identifierSource: \"mrz\",\n },\n {\n docType: \"passport\",\n format: \"ID-3\",\n sides: [\"single\"],\n mrz: \"td3\",\n portraitSide: \"single\", // data page\n aspectRatio: 1.42,\n identifierSource: \"mrz\",\n },\n];\n","// frame-quality (Task 8) — pure, deterministic image measures on a small\n// (≤96px) face crop. No canvas access here: callers hand in ImageData; that\n// keeps these functions golden-testable and worker-portable.\n\n/** Laplacian-variance normalization reference — crops whose edge variance\n * reaches this value (or beyond) count as fully sharp. */\nexport const SHARP_REF = 180;\n\n/** Mean-luma comfort band: inside → exposure 1; outside → linear falloff.\n * Dark bound raised 70→100 (operator ruling 2026-07-07): face crops in the\n * 70–100 range passed the gate but kept drawing dark-face review verdicts —\n * gating them here converts that into pre-capture more_light coaching. */\nexport const EXPOSURE_BAND: readonly [number, number] = [100, 190];\n\n/** Luma distance that zeroes the exposure factor (≈ one stop past the band). */\nconst EXPOSURE_FALLOFF = 64;\n\n/** Rec.601 luma. */\nfunction lumaAt(data: Uint8ClampedArray, index: number): number {\n return (\n 0.299 * (data[index] ?? 0) + 0.587 * (data[index + 1] ?? 0) + 0.114 * (data[index + 2] ?? 0)\n );\n}\n\nexport function meanLuma(image: ImageData): number {\n const { data, width, height } = image;\n const pixels = width * height;\n if (pixels === 0) return 0;\n let sum = 0;\n for (let i = 0; i < pixels; i += 1) sum += lumaAt(data, i * 4);\n return sum / pixels;\n}\n\n/**\n * Sharpness = variance of the 3×3 Laplacian (∇² kernel [0,1,0;1,−4,1;0,1,0])\n * over the interior pixels, normalized 0..1 against SHARP_REF. Flat crop → 0;\n * hard edges → 1 (clamped).\n */\nexport function sharpness(image: ImageData): number {\n const { data, width, height } = image;\n if (width < 3 || height < 3) return 0;\n const gray = new Float32Array(width * height);\n for (let i = 0; i < gray.length; i += 1) gray[i] = lumaAt(data, i * 4);\n let sum = 0;\n let sumSquares = 0;\n let count = 0;\n for (let y = 1; y < height - 1; y += 1) {\n for (let x = 1; x < width - 1; x += 1) {\n const i = y * width + x;\n const response =\n (gray[i - width] ?? 0) +\n (gray[i - 1] ?? 0) +\n (gray[i + 1] ?? 0) +\n (gray[i + width] ?? 0) -\n 4 * (gray[i] ?? 0);\n sum += response;\n sumSquares += response * response;\n count += 1;\n }\n }\n if (count === 0) return 0;\n const mean = sum / count;\n const variance = sumSquares / count - mean * mean;\n // VARIANCE against the reference (the plan's formula). Field lesson\n // (Salem's iPhone, 2026-07-07): sqrt(variance)/REF put every real face\n // crop at ~0.03-0.1 — permanently under the steady_camera threshold and\n // crushing q to zero, so the gate could never fire. Real crops have\n // Laplacian variance well above 180; a genuinely soft/blurred crop does not.\n return Math.min(1, Math.max(0, variance) / SHARP_REF);\n}\n\n/** Exposure factor: 1 inside the band; linear falloff to 0 over\n * EXPOSURE_FALLOFF luma outside it. */\nexport function exposure(image: ImageData): number {\n const mean = meanLuma(image);\n const [low, high] = EXPOSURE_BAND;\n const distance = mean < low ? low - mean : mean > high ? mean - high : 0;\n return Math.max(0, 1 - distance / EXPOSURE_FALLOFF);\n}\n","// DocGateV1 (Task 34) — the document twin of FaceGateV3: plausibility gate\n// (min-area / aspect band / edge-clip) + quality (sharpness/exposure on the\n// quad crop, same frame-quality measures) + an IoU stability streak. The gate\n// NEVER fires on the Task-20 spike's failure modes (too-far/degenerate quad,\n// low-contrast lock, chip-lock, edge-crop) — each yields its taxonomy guidance\n// key (`dcv1.*`) instead, mirroring the face gate's no-luck-firing posture.\n//\n// 100% deterministic: the clock is a tick INPUT (timestampMs); nothing here\n// reads Date.now or performance.now, and detection cost lives OUTSIDE (the\n// session schedules scanic at the device profile's cadence).\nimport { EXPOSURE_BAND } from \"../v3/frame-quality\";\nimport { aspectBand, type DocFormat } from \"./doc-catalog\";\n\n/** Detect-frame width the session downscales to (findings §1: 25ms median).\n * Lives HERE (not detector-scanic.ts) so the session can import it without\n * statically pulling the scanic chunk into host bundles. */\nexport const DOC_DETECT_WIDTH = 480;\n\nexport interface DocQuadPoint {\n x: number;\n y: number;\n}\n\n/** Detected document quad, image-space pixels (scanic CornerPoints shape). */\nexport interface DocQuad {\n topLeft: DocQuadPoint;\n topRight: DocQuadPoint;\n bottomRight: DocQuadPoint;\n bottomLeft: DocQuadPoint;\n}\n\nexport interface DocGateThresholds {\n /** Quad area / frame area below which the doc is too far. */\n MIN_AREA_FRAC: number;\n /** A corner this close to (or past) a frame edge counts as clipped. */\n EDGE_CLIP_MARGIN_PX: number;\n /** Consecutive stable plausible+quality ticks required to fire. */\n STABLE_TICKS: number;\n /** Quad-bbox IoU with the previous tick at/above which the streak holds. */\n IOU_STABLE_MIN: number;\n /** Integrator slopes, per second — mirrors FaceGateV3's gentle drain. */\n RISE_PER_S: number;\n FALL_PER_S: number;\n /** Quality guidance trigger levels (same semantics as the face gate). */\n GUIDE_EXPOSURE: number;\n GUIDE_SHARPNESS: number;\n /** ID-3 (MRZ-band mode): band width / frame width floor. */\n ID3_BAND_MIN_WIDTH_FRAC: number;\n /** ID-3 (MRZ-band mode): band aspect (w/h) sanity bounds. */\n ID3_BAND_ASPECT_MIN: number;\n ID3_BAND_ASPECT_MAX: number;\n}\n\n/** Frozen defaults (plan Task 34 — do not retune without a golden update). */\nexport const DOC_GATE_V1_DEFAULTS: Readonly<DocGateThresholds> = Object.freeze({\n MIN_AREA_FRAC: 0.15,\n EDGE_CLIP_MARGIN_PX: 4,\n STABLE_TICKS: 3,\n IOU_STABLE_MIN: 0.85,\n RISE_PER_S: 0.9,\n FALL_PER_S: 0.25,\n GUIDE_EXPOSURE: 0.6,\n GUIDE_SHARPNESS: 0.35,\n ID3_BAND_MIN_WIDTH_FRAC: 0.55,\n ID3_BAND_ASPECT_MIN: 4,\n ID3_BAND_ASPECT_MAX: 40,\n});\n\nexport interface DocGateQuality {\n /** frame-quality.sharpness on the quad crop. */\n sharpness: number;\n /** frame-quality.exposure on the quad crop. */\n exposure: number;\n /** Mean crop luma — picks more_light vs too_bright. */\n meanLuma: number;\n}\n\nexport interface DocGateTickInput {\n timestampMs: number;\n quad: DocQuad | null;\n quality: DocGateQuality;\n frameWidth: number;\n frameHeight: number;\n}\n\n/** Per-tick output — the scanner chrome contract. */\nexport interface DocGateTick {\n at: number;\n quad: DocQuad | null;\n /** Geometry passed: present × big enough × in frame × right shape. */\n plausible: boolean;\n /** Integrated progress 0..1 (the overlay ring). */\n p: number;\n /** dcv1.* message key (host translates; never prose). */\n guidanceKey: string;\n /** Fire signal: plausible × quality × STABLE_TICKS consecutive high-IoU ticks. */\n ready: boolean;\n /** Current stability streak length (diagnostics/telemetry). */\n stableTicks: number;\n}\n\nconst clamp01 = (value: number) => Math.min(1, Math.max(0, value));\n\n/** Shoelace area of the quad as a fraction of the frame area. */\nexport function quadAreaFrac(quad: DocQuad, frameWidth: number, frameHeight: number): number {\n const pts = [quad.topLeft, quad.topRight, quad.bottomRight, quad.bottomLeft];\n let doubled = 0;\n for (let i = 0; i < 4; i++) {\n const a = pts[i] as DocQuadPoint;\n const b = pts[(i + 1) % 4] as DocQuadPoint;\n doubled += a.x * b.y - b.x * a.y;\n }\n const frameArea = frameWidth * frameHeight;\n return frameArea > 0 ? Math.abs(doubled / 2) / frameArea : 0;\n}\n\n/** IoU of the two quads' axis-aligned bounding boxes (stability metric). */\nexport function quadIou(a: DocQuad, b: DocQuad): number {\n const boxA = bbox(a);\n const boxB = bbox(b);\n const x1 = Math.max(boxA.x1, boxB.x1);\n const y1 = Math.max(boxA.y1, boxB.y1);\n const x2 = Math.min(boxA.x2, boxB.x2);\n const y2 = Math.min(boxA.y2, boxB.y2);\n const inter = Math.max(0, x2 - x1) * Math.max(0, y2 - y1);\n const areaA = (boxA.x2 - boxA.x1) * (boxA.y2 - boxA.y1);\n const areaB = (boxB.x2 - boxB.x1) * (boxB.y2 - boxB.y1);\n const union = areaA + areaB - inter;\n return union > 0 ? inter / union : 0;\n}\n\n/** Axis-aligned bounds (width/height) of a quad — the ID-3 band-mode geometry. */\nexport function quadBounds(quad: DocQuad): { width: number; height: number } {\n const box = bbox(quad);\n return { width: box.x2 - box.x1, height: box.y2 - box.y1 };\n}\n\nfunction bbox(quad: DocQuad): { x1: number; y1: number; x2: number; y2: number } {\n const pts = [quad.topLeft, quad.topRight, quad.bottomRight, quad.bottomLeft];\n return {\n x1: Math.min(...pts.map((p) => p.x)),\n y1: Math.min(...pts.map((p) => p.y)),\n x2: Math.max(...pts.map((p) => p.x)),\n y2: Math.max(...pts.map((p) => p.y)),\n };\n}\n\n/** Orientation-agnostic aspect ratio (longer side pair / shorter side pair). */\nfunction quadAspect(quad: DocQuad): number {\n const top = Math.hypot(quad.topRight.x - quad.topLeft.x, quad.topRight.y - quad.topLeft.y);\n const bottom = Math.hypot(\n quad.bottomRight.x - quad.bottomLeft.x,\n quad.bottomRight.y - quad.bottomLeft.y,\n );\n const left = Math.hypot(quad.bottomLeft.x - quad.topLeft.x, quad.bottomLeft.y - quad.topLeft.y);\n const right = Math.hypot(\n quad.bottomRight.x - quad.topRight.x,\n quad.bottomRight.y - quad.topRight.y,\n );\n const horizontal = (top + bottom) / 2;\n const vertical = (left + right) / 2;\n if (horizontal <= 0 || vertical <= 0) return 0;\n return Math.max(horizontal, vertical) / Math.min(horizontal, vertical);\n}\n\nexport class DocGateV1 {\n private readonly t: DocGateThresholds;\n private readonly format: DocFormat;\n private p = 0;\n private lastTickAt: number | null = null;\n private lastQuad: DocQuad | null = null;\n private streak = 0;\n\n constructor(format: DocFormat, overrides: Partial<DocGateThresholds> = {}) {\n this.format = format;\n this.t = { ...DOC_GATE_V1_DEFAULTS, ...overrides };\n }\n\n reset(): void {\n this.p = 0;\n this.lastTickAt = null;\n this.lastQuad = null;\n this.streak = 0;\n }\n\n tick(input: DocGateTickInput): DocGateTick {\n const { quad, quality, timestampMs } = input;\n const dtSeconds =\n this.lastTickAt === null ? 0 : Math.max(0, (timestampMs - this.lastTickAt) / 1000);\n this.lastTickAt = timestampMs;\n\n // ── plausibility (geometry), taxonomy priority order ─────────────────────\n // ID-3 runs in MRZ-BAND mode (round 3): the \"quad\" is the detected MRZ\n // stroke band's rect — page-edge quads are unreliable on open booklets,\n // so the band IS the passport's detection signal. Geometry checks swap to\n // band semantics (width fraction instead of area; wide-aspect sanity).\n let geometryKey: string | null = null;\n if (quad === null) {\n geometryKey = \"dcv1.no_doc\";\n } else if (this.format === \"ID-3\") {\n const box = quadBounds(quad);\n const aspect = box.height > 0 ? box.width / box.height : 0;\n if (box.width < this.t.ID3_BAND_MIN_WIDTH_FRAC * input.frameWidth) {\n geometryKey = \"dcv1.come_closer\";\n } else if (this.edgeClipped(quad, input.frameWidth, input.frameHeight)) {\n geometryKey = \"dcv1.fit_document\";\n } else if (aspect < this.t.ID3_BAND_ASPECT_MIN || aspect > this.t.ID3_BAND_ASPECT_MAX) {\n geometryKey = \"dcv1.wrong_shape\";\n }\n } else if (quadAreaFrac(quad, input.frameWidth, input.frameHeight) < this.t.MIN_AREA_FRAC) {\n geometryKey = \"dcv1.come_closer\";\n } else if (this.edgeClipped(quad, input.frameWidth, input.frameHeight)) {\n geometryKey = \"dcv1.fit_document\";\n } else {\n const band = aspectBand(this.format);\n const aspect = quadAspect(quad);\n if (Math.abs(aspect - band.center) > band.tolerance) geometryKey = \"dcv1.wrong_shape\";\n }\n const plausible = geometryKey === null;\n\n // ── quality on the quad crop (same measures as the face gate) ────────────\n const exposureOk = clamp01(quality.exposure) >= this.t.GUIDE_EXPOSURE;\n const sharpnessOk = clamp01(quality.sharpness) >= this.t.GUIDE_SHARPNESS;\n const qualityOk = exposureOk && sharpnessOk;\n\n // ── stability streak: consecutive plausible+quality ticks with high IoU ──\n if (plausible && qualityOk && quad !== null) {\n const held = this.lastQuad === null || quadIou(quad, this.lastQuad) >= this.t.IOU_STABLE_MIN;\n this.streak = held ? this.streak + 1 : 1;\n } else {\n this.streak = 0;\n }\n this.lastQuad = quad;\n\n // ── integrator (gentle drain, FaceGateV3 shape) ───────────────────────────\n const good = plausible && qualityOk;\n this.p = clamp01(this.p + (good ? this.t.RISE_PER_S : -this.t.FALL_PER_S) * dtSeconds);\n\n const ready = good && this.streak >= this.t.STABLE_TICKS;\n\n // Guidance: geometry first (taxonomy priority), then light, then blur,\n // then \"hold still\" while the stability streak builds / holds.\n let guidanceKey: string;\n if (geometryKey !== null) {\n guidanceKey = geometryKey;\n } else if (!exposureOk) {\n const bandMid = (EXPOSURE_BAND[0] + EXPOSURE_BAND[1]) / 2;\n guidanceKey = quality.meanLuma < bandMid ? \"dcv1.more_light\" : \"dcv1.too_bright\";\n } else if (!sharpnessOk) {\n guidanceKey = \"dcv1.steady\";\n } else {\n guidanceKey = \"dcv1.hold_still\";\n }\n\n return { at: timestampMs, quad, plausible, p: this.p, guidanceKey, ready, stableTicks: this.streak };\n }\n\n private edgeClipped(quad: DocQuad, frameWidth: number, frameHeight: number): boolean {\n const margin = this.t.EDGE_CLIP_MARGIN_PX;\n const pts = [quad.topLeft, quad.topRight, quad.bottomRight, quad.bottomLeft];\n return pts.some(\n (p) =>\n p.x <= margin ||\n p.y <= margin ||\n p.x >= frameWidth - margin ||\n p.y >= frameHeight - margin,\n );\n }\n}\n","export function initMlDetector(){throw new Error(\"scanic ML detector is not vendored (classical pipeline only)\");}\nexport default {};\n","var A,I=1e3,g=10;function B(A,B={}){const t=B.width||Math.sqrt(A.length),i=B.height||A.length/t,E=void 0!==B.mode?B.mode:1,e=void 0!==B.method?B.method:2,o=B.minArea||I,n=t+2,a=i+2,s=new Int32Array(n*a);for(let I=0;I<i;I++)for(let g=0;g<t;g++)A[I*t+g]>0&&(s[(I+1)*n+(g+1)]=1);const c=[];let r=2;for(let I=1;I<=i;I++)for(let A=1;A<=t;A++){const B=s[I*n+A],t=s[I*n+(A-1)];let i=null,o=!1,h=-1;if(1===B&&0===t?(o=!0,i={x:A,y:I},h=2):0===B&&t>=1&&-1!==t&&1===t&&(o=!1,i={x:A-1,y:I},h=6),i){if(0===E&&!o){s[i.y*n+i.x]=-1;continue}const A=r++,I=C(s,n,a,i,h,A);if(I&&I.length>0){let B=I;2===e&&(B=Q(I));const C=B.map(A=>({x:A.x-1,y:A.y-1}));if(C.length>=(2===e?4:g)){const I={id:A,points:C,isOuter:o};c.push(I)}}else 1===s[i.y*n+i.x]&&(s[i.y*n+i.x]=A)}}c.forEach(A=>{A.area=function(A){let I=0;const g=A.length;if(g<3)return 0;for(let B=0;B<g;B++){const C=(B+1)%g;I+=A[B].x*A[C].y,I-=A[C].x*A[B].y}return Math.abs(I)/2}(A.points),A.boundingBox=function(A){if(0===A.length)return{minX:0,minY:0,maxX:0,maxY:0};let I=A[0].x,g=A[0].y,B=A[0].x,C=A[0].y;for(let Q=1;Q<A.length;Q++){const t=A[Q];I=Math.min(I,t.x),g=Math.min(g,t.y),B=Math.max(B,t.x),C=Math.max(C,t.y)}return{minX:I,minY:g,maxX:B,maxY:C}}(A.points)});const h=c.filter(A=>A.area>=o);return h.sort((A,I)=>I.area-A.area),B.debug&&(B.debug.labels=s,B.debug.rawContours=c,B.debug.finalContours=h),h}function C(A,I,g,B,C,Q){const t=[],i=/* @__PURE__ */new Set;let E=B.x,e=B.y;const o=E,n=e;let a=-1;A[n*I+o]=Q;let s=0;const c=I*g,r=[0,1,1,1,0,-1,-1,-1],h=[-1,-1,0,1,1,1,0,-1];for(;s++<c;){let B;if(-1===a){let Q=!1;for(let t=0;t<8;t++){B=C+t&7;const i=E+r[B],o=e+h[B];if(i>=0&&i<I&&o>=0&&o<g&&A[o*I+i]>0){Q=!0;break}}if(!Q)return null}else B=a+2&7;let s=-1,c=-1;for(let C=0;C<8;C++){const Q=B+C&7,t=E+r[Q],i=e+h[Q];if(t>=0&&t<I&&i>=0&&i<g&&A[i*I+t]>0){s=t,c=i,a=Q+4&7;break}}if(-1===s){0===t.length&&t.push({x:E,y:e});break}const l=e*I+E;if(i.has(l))return t;t.push({x:E,y:e}),i.add(l);const y=c*I+s;if(1===A[y]&&(A[y]=Q),E=s,e=c,E===o&&e===n)break}return s>=c?null:t}function Q(A){const I=A.length;if(I<=2)return A;const g=[],B=A[I-1],C=A[0];let Q=B,t=C,i=A[1],E=t.x-Q.x,e=t.y-Q.y,o=i.x-t.x,n=i.y-t.y;E*n!==e*o&&g.push(t);for(let a=1;a<I-1;a++)Q=A[a-1],t=A[a],i=A[a+1],E=t.x-Q.x,e=t.y-Q.y,o=i.x-t.x,n=i.y-t.y,E*n!==e*o&&g.push(t);if(Q=A[I-2],t=B,i=C,E=t.x-Q.x,e=t.y-Q.y,o=i.x-t.x,n=i.y-t.y,E*n!==e*o&&g.push(t),0===g.length){if(1===I)return[A[0]];if(2===I)return A;let g=0,B=1;const Q=C.x,t=C.y;for(let C=1;C<I;C++){const I=A[C],i=I.x-Q,E=I.y-t,e=i*i+E*E;e>g&&(g=e,B=C)}return[C,A[B]]}return g}function t(A,I=1){if(A.length<=2)return A;let g=0,B=0;const C=A[0],Q=A[A.length-1];for(let t=1;t<A.length-1;t++){const I=i(A[t],C,Q);I>g&&(g=I,B=t)}if(g>I){const g=t(A.slice(0,B+1),I),C=t(A.slice(B),I);return g.slice(0,-1).concat(C)}return[C,Q]}function i(A,I,g){const B=g.x-I.x,C=g.y-I.y,Q=B*B+C*C;if(0===Q)return Math.sqrt(Math.pow(A.x-I.x,2)+Math.pow(A.y-I.y,2));const t=((A.x-I.x)*B+(A.y-I.y)*C)/Q;let i,E;t<0?(i=I.x,E=I.y):t>1?(i=g.x,E=g.y):(i=I.x+t*B,E=I.y+t*C);const e=A.x-i,o=A.y-E;return Math.sqrt(e*e+o*o)}function E(A,I=.02){return t(A,I*function(A){let I=0;const g=A.length;if(g<2)return 0;for(let B=0;B<g;B++){const C=(B+1)%g,Q=A[B].x-A[C].x,t=A[B].y-A[C].y;I+=Math.sqrt(Q*Q+t*t)}return I}(A))}function e(A,I){return Math.hypot(I.x-A.x,I.y-A.y)}function o(A){let I=0,g=0;for(const B of A)I+=B.x,g+=B.y;return{x:I/A.length,y:g/A.length}}function n(A,I={}){if(!A||!A.points||A.points.length<4)return null;const g=I.epsilon||.02,B=function(A,I){if(!A||A.length<4)return null;const g=[I,1.3*I,1.6*I,2*I],B=/* @__PURE__ */new Set;for(const C of g){const I=Math.min(.12,C),g=I.toFixed(4);if(B.has(g))continue;B.add(g);const Q=a(E(A,I));if(Q&&4===Q.length)return Q}return null}(A.points,g);let C;return B&&4===B.length?C=function(A){if(4!==A.length)return null;const I=o(A),g=[...A].sort((A,g)=>Math.atan2(A.y-I.y,A.x-I.x)-Math.atan2(g.y-I.y,g.x-I.x));let B=1/0,C=0;for(let t=0;t<4;t++){const A=g[t].x+g[t].y;A<B&&(B=A,C=t)}const Q=[g[C],g[(C+1)%4],g[(C+2)%4],g[(C+3)%4]];return{topLeft:Q[0],topRight:Q[1],bottomRight:Q[2],bottomLeft:Q[3]}}(B):(C=function(A){if(!A||A.length<4)return null;const I=o(A);let g=null,B=null,C=null,Q=null,t=0,i=0,E=0,n=0;for(const o of A){const A=e(o,I);o.x<I.x&&o.y<I.y?A>t&&(g=o,t=A):o.x>I.x&&o.y<I.y?A>i&&(B=o,i=A):o.x>I.x&&o.y>I.y?A>E&&(C=o,E=A):o.x<I.x&&o.y>I.y&&A>n&&(Q=o,n=A)}return g&&B&&C&&Q?{topLeft:g,topRight:B,bottomRight:C,bottomLeft:Q}:null}(A.points),C&&C.topLeft&&C.topRight&&C.bottomRight&&C.bottomLeft||(C=function(A){if(!A||0===A.length)return null;let I=A[0],g=A[0],B=A[0],C=A[0],Q=I.x+I.y,t=g.x-g.y,i=B.x+B.y,E=C.x-C.y;for(let e=1;e<A.length;e++){const o=A[e],n=o.x+o.y,a=o.x-o.y;n<Q&&(Q=n,I=o),n>i&&(i=n,B=o),a>t&&(t=a,g=o),a<E&&(E=a,C=o)}return{topLeft:I,topRight:g,bottomRight:B,bottomLeft:C}}(A.points))),C&&C.topLeft&&C.topRight&&C.bottomRight&&C.bottomLeft?C:null}function a(A){if(!A||A.length<4)return null;if(4===A.length)return A;if(A.length>8)return null;let I=function(A,I){if(!A||0===A.length)return[];const g=[];for(const B of A)(0===g.length||e(B,g[g.length-1])>I)&&g.push(B);g.length>2&&e(g[0],g[g.length-1])<=I&&g.pop();return g}(A,6);return 4===I.length?I:(I.length,null)}var s=null;function c(){return null!==s&&0!==s.byteLength||(s=new Uint8Array(A.memory.buffer)),s}var r=0;function h(A,I){const g=I(1*A.length,1)>>>0;return c().set(A,g/1),r=A.length,g}function l(A,I){return A>>>=0,c().subarray(A/1,A/1+I)}var y=null;function D(){return null!==y&&0!==y.byteLength||(y=new Float32Array(A.memory.buffer)),y}function w(I,g,B,C,Q){const t=function(A,I){const g=I(4*A.length,4)>>>0;return D().set(A,g/4),r=A.length,g}(I,A.__wbindgen_malloc),i=r,E=A.hysteresis_thresholding(t,i,g,B,C,Q);var e=l(E[0],E[1]).slice();return A.__wbindgen_free(E[0],1*E[1],1),e}var d=null;function f(I,g){const B=g(2*I.length,2)>>>0;return(null!==d&&0!==d.byteLength||(d=new Uint16Array(A.memory.buffer)),d).set(I,B/2),r=I.length,B}function u(I,g,B,C,Q){const t=f(I,A.__wbindgen_malloc),i=r,E=f(g,A.__wbindgen_malloc),e=r,o=A.non_maximum_suppression(t,i,E,e,B,C,Q);var n,a,s=(n=o[0],a=o[1],n>>>=0,D().subarray(n/4,n/4+a)).slice();return A.__wbindgen_free(o[0],4*o[1],4),s}async function m(I){if(void 0!==A)return A;if(void 0!==I&&Object.getPrototypeOf(I)===Object.prototype&&({module_or_path:I}=I),void 0===I)throw new Error(\"scanic: WASM module bytes must be passed to init().\");const g=function(){const I={wbg:{}};return I.wbg.__wbindgen_init_externref_table=function(){const I=A.__wbindgen_export_0,g=I.grow(4);I.set(0,void 0),I.set(g+0,void 0),I.set(g+1,null),I.set(g+2,!0),I.set(g+3,!1)},I}();(\"string\"==typeof I||\"function\"==typeof Request&&I instanceof Request||\"function\"==typeof URL&&I instanceof URL)&&(I=fetch(I));const{instance:B,module:C}=await async function(A,I){if(\"function\"==typeof Response&&A instanceof Response){if(\"function\"==typeof WebAssembly.instantiateStreaming)try{return await WebAssembly.instantiateStreaming(A,I)}catch(g){if(\"application/wasm\"==A.headers.get(\"Content-Type\"))throw g}const B=await A.arrayBuffer();return await WebAssembly.instantiate(B,I)}{const g=await WebAssembly.instantiate(A,I);return g instanceof WebAssembly.Instance?{instance:g,module:A}:g}}(await I,g);return function(I,g){return A=I.exports,m.__wbindgen_wasm_module=g,y=null,d=null,s=null,A.__wbindgen_start(),A}(B,C)}var N=null,R=!1,p=null;function F(A){if(\"function\"==typeof atob){const I=atob(A),g=new Uint8Array(I.length);for(let A=0;A<I.length;A++)g[A]=I.charCodeAt(A);return g}return Uint8Array.from(Buffer.from(A,\"base64\"))}async function J(){if(!function(){if(null!==p)return p;let A=!1;if(\"object\"==typeof WebAssembly&&\"function\"==typeof WebAssembly.validate){const I=new Uint8Array([0,97,115,109,1,0,0,0,1,5,1,96,0,1,123,3,2,1,0,10,10,1,8,0,65,0,253,15,253,98,11]),g=new Uint8Array([0,97,115,109,1,0,0,0,1,5,1,96,0,1,111,3,2,1,0,10,6,1,4,0,208,111,11]);try{A=WebAssembly.validate(I)&&WebAssembly.validate(g)}catch{A=!1}}return p=A,A}())throw new Error(\"scanic: WebAssembly features required by the WASM module (reference-types, SIMD) are unavailable in this engine; using the JavaScript fallback.\");return await m({module_or_path:F(\"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JAAgAiABIAJqIgFLBEBBAEEAEC0ACyADQQRqIAAoAgAiAiAAKAIEQQggASACQQF0IgIgASACSxsiASABQQhNGyIBQQFBARARIAMoAgRBAUYEQCADKAIIIAMoAgwQLQALIAMoAgghAiAAIAE2AgAgACACNgIEIANBEGokAAt5AQF/IwBBIGsiAiQAAn8gACgCAEGAgICAeEcEQCABIAAoAgQgACgCCBAwDAELIAJBEGogACgCDCgCACIAQQhqKQIANwMAIAJBGGogAEEQaikCADcDACACIAApAgA3AwggASgCACABKAIEIAJBCGoQBwsgAkEgaiQAC2kBA38jAEEQayIBJAAgAUEEaiAAKAIAIgIgACgCBEEEIAJBAXQiAiACQQRNGyICQQRBBBARIAEoAgRBAUYEQCABKAIIIAEoAgwQLQALIAEoAgghAyAAIAI2AgAgACADNgIEIAFBEGokAAtpAQN/IwBBEGsiASQAIAFBBGogACgCACICIAAoAgRBBCACQQF0IgIgAkEETRsiAkEEQQgQESABKAIEQQFGBEAgASgCCCABKAIMEC0ACyABKAIIIQMgACACNgIAIAAgAzYCBCABQRBqJAALaQEDfyMAQRBrIgEkACABQQRqIAAoAgAiAiAAKAIEQQQgAkEBdCICIAJBBE0bIgJBAkECEBEgASgCBEEBRgRAIAEoAgggASgCDBAtAAsgASgCCCEDIAAgAjYCACAAIAM2AgQgAUEQaiQACxIAIwBBMGsiACQAIABBMGokAAtoAgF/AX4jAEEwayIDJAAgAyABNgIEIAMgADYCACADQQI2AgwgA0Hkl8AANgIIIANCAjcCFCADQoCAgIAwIgQgA62ENwMoIAMgBCADQQRqrYQ3AyAgAyADQSBqNgIQIANBCGogAhAmAAtHAQF/IAAoAgAgACgCCCIDayACSQRAIAAgAyACEBIgACgCCCEDCyACBEAgACgCBCADaiABIAL8CgAACyAAIAIgA2o2AghBAAtEAQJ/IAEoAgQhAiABKAIAIQNBCEEEEDUiAUUEQEEEQQgQOQALIAEgAjYCBCABIAM2AgAgAEHcksAANgIEIAAgATYCAAvGAgACQCAAIAJNBEAgACABTSABIAJLcg0BIwBBMGsiAiQAIAIgATYCBCACIAA2AgAgAkECNgIMIAJB2JbAADYCCCACQgI3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IAAAABwAEAAMAAAAEgAAABcAAAAcABAADAAAABcAAAAZAAAAHAAQAAwAAAAUAAAAGQAAABwAEAAMAAAAUQAAAB4AAAAcABAADAAAAFIAAAAeAAAATGF6eSBpbnN0YW5jZSBoYXMgcHJldmlvdXNseSBiZWVuIHBvaXNvbmVkAAA8CBAAKgAAAEgBEABaAAAACAMAABkAAAByZWVudHJhbnQgaW5pdAAAgAgQAA4AAABIARAAWgAAAHoCAAANAAAAfP2LMlfmV/kC30S/40jnr21dy9YsUOtjeEGmV3Ebi7ltZW1vcnkgYWxsb2NhdGlvbiBvZiAgYnl0ZXMgZmFpbGVkAADICBAAFQAAAN0IEAANAAAALwEQABgAAABkAQAACQAAAAQAAAAMAAAABAAAAAUAAAAGAAAABwAAAAAAAAAIAAAABAAAAAgAAAAJAAAACgAAAAsAAAAMAAAAEAAAAAQAAAANAAAADgAAAA8AAAAQAAAAAAAAAAgAAAAEAAAAEQAAAGFzc2VydGlvbiBmYWlsZWQ6IHBzaXplID49IHNpemUgKyBtaW5fb3ZlcmhlYWQAAAQBEAAqAAAAsQQAAAkAAABhc3NlcnRpb24gZmFpbGVkOiBwc2l6ZSA8PSBzaXplICsgbWF4X292ZXJoZWFkAAAEARAAKgAAALcEAAANAAAABAAAAAwAAAAEAAAAEgAAAGNhcGFjaXR5IG92ZXJmbG93AAAA/AkQABEAAADjABAAIAAAABwAAAAFAAAAMDAwMTAyMDMwNDA1MDYwNzA4MDkxMDExMTIxMzE0MTUxNjE3MTgxOTIwMjEyMjIzMjQyNTI2MjcyODI5MzAzMTMyMzMzNDM1MzYzNzM4Mzk0MDQxNDI0MzQ0NDU0NjQ3NDg0OTUwNTE1MjUzNTQ1NTU2NTc1ODU5NjA2MTYyNjM2NDY1NjY2NzY4Njk3MDcxNzI3Mzc0NzU3Njc3Nzg3OTgwODE4MjgzODQ4NTg2ODc4ODg5OTA5MTkyOTM5NDk1OTY5Nzk4OTlyYW5nZSBlbmQgaW5kZXggIG91dCBvZiByYW5nZSBmb3Igc2xpY2Ugb2YgbGVuZ3RoIAAA8AoQABAAAAAACxAAIgAAAHNsaWNlIGluZGV4IHN0YXJ0cyBhdCAgYnV0IGVuZHMgYXQgADQLEAAWAAAASgsQAA0AAAByYW5nZSBzdGFydCBpbmRleCAAAGgLEAASAAAAAAsQACIAAABhdHRlbXB0IHRvIGRpdmlkZSBieSB6ZXJvAAAAjAsQABkAAABpbmRleCBvdXQgb2YgYm91bmRzOiB0aGUgbGVuIGlzICBidXQgdGhlIGluZGV4IGlzIAAAsAsQACAAAADQCxAAEgAAAAAAAD8AAAC/AEGUmMAACwEBAHwJcHJvZHVjZXJzAghsYW5ndWFnZQEEUnVzdAAMcHJvY2Vzc2VkLWJ5AwVydXN0Yx0xLjkyLjAgKGRlZDVjMDZjZiAyMDI1LTEyLTA4KQZ3YWxydXMGMC4yMy4zDHdhc20tYmluZGdlbhMwLjIuMTAwICgyNDA1ZWMyYjQpAHQPdGFyZ2V0X2ZlYXR1cmVzBysPbXV0YWJsZS1nbG9iYWxzKxNub250cmFwcGluZy1mcHRvaW50KwdzaW1kMTI4KwtidWxrLW1lbW9yeSsIc2lnbi1leHQrD3JlZmVyZW5jZS10eXBlcysKbXVsdGl2YWx1ZQ==\")})}function G(){return N||(N=J().catch(A=>{throw N=null,A})),N}function k(A,I,g,B=5,C=0){0===C&&(C=.3*(.5*(B-1)-1)+.8);const Q=Math.floor(B/2),t=function(A,I){const g=new Float32Array(A),B=Math.floor(A/2);let C=0;for(let Q=0;Q<A;Q++){const A=Q-B;g[Q]=Math.exp(-A*A/(2*I*I)),C+=g[Q]}for(let Q=0;Q<A;Q++)g[Q]/=C;return g}(B,C),i=new Uint8ClampedArray(I*g),E=new Uint8ClampedArray(I*g);for(let e=0;e<g;e++){const g=e*I;for(let B=0;B<I;B++){let C=0;for(let i=-Q;i<=Q;i++){C+=A[g+Math.min(I-1,Math.max(0,B+i))]*t[Q+i]}i[g+B]=C}}for(let e=0;e<I;e++)for(let A=0;A<g;A++){let B=0;for(let C=-Q;C<=Q;C++){B+=i[Math.min(g-1,Math.max(0,A+C))*I+e]*t[Q+C]}E[A*I+e]=Math.round(B)}return E}function S(A,I,g,B,C){const Q=new Uint8Array(I*g),t=[];for(let e=1;e<g-1;e++)for(let g=1;g<I-1;g++){const i=e*I+g,E=A[i];E>=C?(Q[i]=2,t.push({x:g,y:e})):Q[i]=E>=B?0:1}for(let e=0;e<I;e++)Q[e]=1,Q[(g-1)*I+e]=1;for(let e=1;e<g-1;e++)Q[e*I]=1,Q[e*I+I-1]=1;const i=[-1,0,1,-1,1,-1,0,1],E=[-1,-1,-1,0,0,1,1,1];for(;t.length>0;){const{x:A,y:g}=t.pop();for(let B=0;B<8;B++){const C=A+i[B],e=g+E[B],o=e*I+C;0===Q[o]&&(Q[o]=2,t.push({x:C,y:e}))}}return Q}async function M(I,g={}){const B=!(!g.debug||g.debug._timingsOnly),C=[],Q=performance.now();let t,i,E;if(g.skipGrayscale||!1)t=g.width,i=g.height,E=I,B&&(g.debug.grayscale=E);else{t=I.width,i=I.height;let A=performance.now();E=function(A){const{width:I,height:g,data:B}=A,C=new Uint8ClampedArray(I*g);for(let Q=0,t=0;Q<B.length;Q+=4,t++)C[t]=54*B[Q]+183*B[Q+1]+19*B[Q+2]>>8;return C}(I);let Q=performance.now();C.push({step:\"Grayscale\",ms:(Q-A).toFixed(2)}),B&&(g.debug.grayscale=E)}let e=void 0!==g.lowThreshold?g.lowThreshold:null,o=void 0!==g.highThreshold?g.highThreshold:null;if(null===e||null===o){const A=1024,I=new Uint32Array(A);let g=0;for(let e=1;e<i-1;e++)for(let B=1;B<t-1;B++){const C=e*t+B,Q=-E[C-t-1]+E[C-t+1]-2*E[C-1]+2*E[C+1]-E[C+t-1]+E[C+t+1],i=-E[C-t-1]-2*E[C-t]-E[C-t+1]+E[C+t-1]+2*E[C+t]+E[C+t+1];let o=Math.abs(Q)+Math.abs(i);o>=A&&(o=A-1),o>0&&(I[o]++,g++)}const B=Math.round(.7*g);let C=0,Q=75;for(let t=1;t<A;t++)if(C+=I[t],C>=B){Q=t;break}null===e&&(e=Math.max(5,Math.round(.5*Q))),null===o&&(o=Math.min(500,Math.round(1.5*Q)))}const n=g.kernelSize||5,a=g.sigma||0,s=void 0!==g.L2gradient&&g.L2gradient,c=void 0===g.applyDilation||g.applyDilation,y=g.dilationKernelSize||5,D=void 0!==g.useWasmHysteresis&&g.useWasmHysteresis,d=void 0!==g.useWasmFullCanny&&g.useWasmFullCanny;if(e>=o&&([e,o]=[o,e]),d)try{await G();const I=performance.now(),D=new Uint8ClampedArray(function(I,g,B,C,Q,t,i,E,e,o){const n=h(I,A.__wbindgen_malloc),a=r,s=A.canny_edge_detector_full(n,a,g,B,C,Q,t,i,E,e,o);var c=l(s[0],s[1]).slice();return A.__wbindgen_free(s[0],1*s[1],1),c}(E,t,i,e,o,n,a,s,c,y)),w=(performance.now()-I).toFixed(2);C.push({step:\"Edge Processing (WASM)\",ms:w}),B&&(g.debug.finalEdges=D),g.debug?g.debug.timings=C:g.debug={timings:C};const d=performance.now();return C.unshift({step:\"Edge Detection Total\",ms:(d-Q).toFixed(2)}),D}catch(Y){if(!R){R=!0;Y instanceof Error?Y.message:String(Y)}}let f,m,N,p,F,J;f=performance.now();try{await G(),N=function(I,g,B,C,Q){const t=h(I,A.__wbindgen_malloc),i=r,E=A.blur(t,i,g,B,C,Q);var e=l(E[0],E[1]).slice();return A.__wbindgen_free(E[0],1*E[1],1),e}(E,t,i,n,a)}catch{N=k(E,t,i,n,a)}m=performance.now(),C.push({step:\"Gaussian Blur\",ms:(m-f).toFixed(2)}),B&&(g.debug.blurred=N),f=performance.now();{const A=function(A,I,g){const B=new Int16Array(I*g),C=new Int16Array(I*g);for(let Q=1;Q<g-1;Q++){const g=Q*I,t=(Q-1)*I,i=(Q+1)*I;for(let Q=1;Q<I-1;Q++){const I=g+Q,E=A[t+Q-1],e=A[t+Q],o=A[t+Q+1],n=A[g+Q-1],a=A[g+Q+1],s=A[i+Q-1],c=A[i+Q],r=A[i+Q+1],h=o-E+2*(a-n)+(r-s),l=s+2*c+r-(E+2*e+o);B[I]=h,C[I]=l}}return{dx:B,dy:C}}(N,t,i);p=A.dx,F=A.dy}m=performance.now(),C.push({step:\"Gradients\",ms:(m-f).toFixed(2)}),f=performance.now();try{await G(),J=await u(p,F,t,i,s)}catch{J=function(A,I,g,B,C){const Q=new Float32Array(g*B),t=new Float32Array(g*B);for(let i=0;i<A.length;i++){const g=A[i],B=I[i];Q[i]=C?Math.sqrt(g*g+B*B):Math.abs(g)+Math.abs(B)}for(let i=1;i<B-1;i++)for(let B=1;B<g-1;B++){const C=i*g+B,E=Q[C];if(0===E){t[C]=0;continue}const e=A[C],o=I[C];let n=0,a=0;const s=Math.abs(e),c=Math.abs(o);if(c>2.4142*s)n=Q[C-g],a=Q[C+g];else if(s>2.4142*c)n=Q[C-1],a=Q[C+1];else{const A=(e^o)<0?-1:1;o>0?(n=Q[(i-1)*g+(B-A)],a=Q[(i+1)*g+(B+A)]):(n=Q[(i+1)*g+(B-A)],a=Q[(i-1)*g+(B+A)]),e>0&&o>0||e<0&&o<0?(n=Q[(i-1)*g+(B+1)],a=Q[(i+1)*g+(B-1)]):(n=Q[(i-1)*g+(B-1)],a=Q[(i+1)*g+(B+1)])}t[C]=E>=n&&E>=a?E:0}return t}(p,F,t,i,s)}m=performance.now(),C.push({step:\"Non-Max Suppression\",ms:(m-f).toFixed(2)}),f=performance.now();const M=s?e*e:e,b=s?o*o:o;let L;if(D)try{await G(),L=w(J,t,i,M,b)}catch(q){L=S(J,t,i,M,b)}else L=S(J,t,i,M,b);m=performance.now(),C.push({step:\"Hysteresis\",ms:(m-f).toFixed(2)}),f=performance.now();const x=new Uint8ClampedArray(t*i);for(let A=0;A<L.length;A++)x[A]=2===L[A]?255:0;m=performance.now(),C.push({step:\"Binary Image\",ms:(m-f).toFixed(2)}),f=performance.now();let U=x;if(c)try{await G(),U=function(I,g,B,C){const Q=h(I,A.__wbindgen_malloc),t=r,i=A.dilate(Q,t,g,B,C);var E=l(i[0],i[1]).slice();return A.__wbindgen_free(i[0],1*i[1],1),E}(x,t,i,y)}catch{U=function(A,I,g,B=5){const C=Math.floor(B/2),Q=new Uint8ClampedArray(I*g),t=new Uint8ClampedArray(I*g);for(let i=0;i<g;i++){const g=i*I;for(let B=0;B<I;B++){let t=0;for(let Q=-C;Q<=C;Q++){const C=B+Q;if(C>=0&&C<I){const I=A[g+C];I>t&&(t=I)}}Q[g+B]=t}}for(let i=0;i<I;i++)for(let A=0;A<g;A++){let B=0;for(let t=-C;t<=C;t++){const C=A+t;if(C>=0&&C<g){const A=Q[C*I+i];A>B&&(B=A)}}t[A*I+i]=B}return t}(x,t,i,y)}if(m=performance.now(),C.push({step:\"Dilation\",ms:(m-f).toFixed(2)}),B){g.debug.dx=p,g.debug.dy=F;const A=new Float32Array(t*i);for(let I=0;I<p.length;I++){const g=p[I],B=F[I];A[I]=s?Math.sqrt(g*g+B*B):Math.abs(g)+Math.abs(B)}g.debug.magnitude=A,g.debug.suppressed=J,g.debug.edgeMap=L,g.debug.cannyEdges=x,g.debug.finalEdges=U}g.debug?g.debug.timings=C:g.debug||(g.debug={timings:C});const H=performance.now();return C.unshift({step:\"Edge Detection Total\",ms:(H-Q).toFixed(2)}),U}function b(A){return{topLeft:{x:A.topLeft.x,y:A.topLeft.y},topRight:{x:A.topRight.x,y:A.topRight.y},bottomRight:{x:A.bottomRight.x,y:A.bottomRight.y},bottomLeft:{x:A.bottomLeft.x,y:A.bottomLeft.y}}}function L(A,I){return Math.hypot(A.x-I.x,A.y-I.y)}function x(A,I=4){const g=[A?.topLeft,A?.topRight,A?.bottomRight,A?.bottomLeft];if(g.some(A=>!A||!Number.isFinite(A.x)||!Number.isFinite(A.y)))return!1;for(let B=0;B<g.length;B++)for(let A=B+1;A<g.length;A++)if(L(g[B],g[A])<I)return!1;return!0}function U(A){const I=[A.topLeft,A.topRight,A.bottomRight,A.bottomLeft],g=[];for(let C=0;C<I.length;C++){const A=I[C],B=I[(C+1)%I.length],Q=I[(C+2)%I.length],t=(B.x-A.x)*(Q.y-B.y)-(B.y-A.y)*(Q.x-B.x);Math.abs(t)<1e-6||g.push(Math.sign(t))}if(g.length<3)return!1;const B=g[0];return g.every(A=>A===B)}var H=\"scanic-corner-editor-styles\",Y='<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"3 4 3 10 9 10\"/><path d=\"M3.5 14a8.5 8.5 0 1 0 2-7.4L3 10\"/></svg>',q='<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/></svg>',v='<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"/></svg>',K='<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"4\" y1=\"21\" x2=\"4\" y2=\"14\"/><line x1=\"4\" y1=\"10\" x2=\"4\" y2=\"3\"/><line x1=\"12\" y1=\"21\" x2=\"12\" y2=\"12\"/><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"3\"/><line x1=\"20\" y1=\"21\" x2=\"20\" y2=\"16\"/><line x1=\"20\" y1=\"12\" x2=\"20\" y2=\"3\"/><line x1=\"1\" y1=\"14\" x2=\"7\" y2=\"14\"/><line x1=\"9\" y1=\"8\" x2=\"15\" y2=\"8\"/><line x1=\"17\" y1=\"16\" x2=\"23\" y2=\"16\"/></svg>';function T(A={}){const I=A.container;if(!I||\"function\"!=typeof I.appendChild)throw new Error(\"createCornerEditor requires a valid container element\");const g=I.ownerDocument||(\"undefined\"!=typeof document?document:null),B=\"undefined\"!=typeof window?window:globalThis,C=()=>B.performance&&\"function\"==typeof B.performance.now?B.performance.now():Date.now();!1!==A.injectStyles&&function(A){if(!A||\"function\"!=typeof A.getElementById)return;if(A.getElementById(H))return;const I=A.createElement(\"style\");I.id=H,I.textContent=\"\\n.scanic-corner-editor {\\n --scanic-accent: #6366f1;\\n --scanic-mask: rgba(15, 23, 42, 0.45);\\n --scanic-edge-color: var(--scanic-accent);\\n --scanic-edge-width: 2.5;\\n --scanic-handle-size: 20px;\\n --scanic-handle-hit: 44px;\\n --scanic-handle-color: #ffffff;\\n --scanic-handle-ring: 2px;\\n --scanic-handle-ring-color: var(--scanic-accent);\\n --scanic-handle-shadow: 0 1px 4px rgba(15, 23, 42, 0.45);\\n --scanic-handle-active-shadow: 0 8px 22px rgba(15, 23, 42, 0.5);\\n --scanic-handle-active-scale: 1.28;\\n --scanic-surface: rgba(15, 23, 42, 0.92);\\n --scanic-surface-fg: #e2e8f0;\\n --scanic-surface-radius: 12px;\\n}\\n.scanic-handle {\\n position: absolute;\\n box-sizing: border-box;\\n width: var(--scanic-handle-size);\\n height: var(--scanic-handle-size);\\n margin: 0;\\n padding: 0;\\n border: var(--scanic-handle-ring) solid var(--scanic-handle-ring-color);\\n border-radius: 50%;\\n background: var(--scanic-handle-color);\\n box-shadow: var(--scanic-handle-shadow);\\n transform: translate(-50%, -50%);\\n cursor: grab;\\n touch-action: none;\\n z-index: 2;\\n transition: transform 0.12s ease, box-shadow 0.12s ease,\\n background 0.12s ease, border-color 0.12s ease;\\n}\\n/* Enlarges the pointer/touch target without changing the visual size. */\\n.scanic-handle::after {\\n content: '';\\n position: absolute;\\n left: 50%;\\n top: 50%;\\n width: var(--scanic-handle-hit);\\n height: var(--scanic-handle-hit);\\n transform: translate(-50%, -50%);\\n border-radius: 50%;\\n}\\n/* Soft accent halo that blooms when a handle is grabbed. This is the \\\"depth\\\" layer. */\\n.scanic-handle::before {\\n content: '';\\n position: absolute;\\n left: 50%;\\n top: 50%;\\n width: 0;\\n height: 0;\\n border-radius: 50%;\\n background: var(--scanic-accent);\\n opacity: 0;\\n transform: translate(-50%, -50%);\\n transition: opacity 0.15s ease, width 0.15s ease, height 0.15s ease;\\n pointer-events: none;\\n}\\n.scanic-handle:hover {\\n transform: translate(-50%, -50%) scale(1.12);\\n}\\n.scanic-handle:focus-visible {\\n outline: none;\\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--scanic-accent) 45%, transparent),\\n var(--scanic-handle-shadow);\\n}\\n/* The currently selected corner: the target of nudges / keyboard. */\\n.scanic-handle.is-selected {\\n border-color: var(--scanic-accent);\\n transform: translate(-50%, -50%) scale(1.12);\\n}\\n.scanic-handle.is-selected::before {\\n opacity: 0.16;\\n width: calc(var(--scanic-handle-size) * 2);\\n height: calc(var(--scanic-handle-size) * 2);\\n}\\n.scanic-handle.is-active {\\n cursor: grabbing;\\n background: var(--scanic-accent);\\n border-color: #ffffff;\\n transform: translate(-50%, -50%) scale(var(--scanic-handle-active-scale));\\n box-shadow: var(--scanic-handle-active-shadow);\\n}\\n.scanic-handle.is-active::before {\\n opacity: 0.22;\\n width: calc(var(--scanic-handle-size) * 2.8);\\n height: calc(var(--scanic-handle-size) * 2.8);\\n}\\n.scanic-toolbar,\\n.scanic-nudges {\\n position: absolute;\\n z-index: 3;\\n display: flex;\\n gap: 4px;\\n padding: 5px;\\n background: var(--scanic-surface);\\n border-radius: var(--scanic-surface-radius);\\n -webkit-backdrop-filter: blur(8px);\\n backdrop-filter: blur(8px);\\n box-shadow: 0 6px 20px rgba(15, 23, 42, 0.35);\\n}\\n.scanic-toolbar {\\n left: 50%;\\n bottom: 12px;\\n transform: translateX(-50%);\\n}\\n.scanic-nudges {\\n top: 10px;\\n right: 10px;\\n display: grid;\\n grid-template-columns: repeat(4, auto);\\n gap: 3px;\\n}\\n.scanic-toolbar button,\\n.scanic-nudges button {\\n display: grid;\\n place-items: center;\\n margin: 0;\\n padding: 0;\\n font-family: inherit;\\n font-size: 15px;\\n font-weight: 600;\\n line-height: 1;\\n color: var(--scanic-surface-fg);\\n background: transparent;\\n border: 0;\\n border-radius: 8px;\\n cursor: pointer;\\n transition: background 0.12s ease, color 0.12s ease, filter 0.12s ease;\\n}\\n.scanic-toolbar button {\\n width: 34px;\\n height: 34px;\\n}\\n.scanic-nudges button {\\n width: 30px;\\n height: 30px;\\n}\\n.scanic-toolbar button svg {\\n width: 18px;\\n height: 18px;\\n display: block;\\n}\\n.scanic-toolbar button:hover,\\n.scanic-nudges button:hover {\\n background: rgba(255, 255, 255, 0.14);\\n}\\n.scanic-toolbar button:focus-visible,\\n.scanic-nudges button:focus-visible {\\n outline: 2px solid var(--scanic-accent);\\n outline-offset: 1px;\\n}\\n.scanic-toolbar .scanic-btn-apply {\\n background: var(--scanic-accent);\\n color: #ffffff;\\n}\\n.scanic-toolbar .scanic-btn-apply:hover {\\n background: var(--scanic-accent);\\n filter: brightness(1.1);\\n}\\n.scanic-toolbar .scanic-btn-expert.is-on {\\n background: color-mix(in srgb, var(--scanic-accent) 32%, transparent);\\n color: #ffffff;\\n}\\n\",(A.head||A.documentElement).appendChild(I)}(g);const{canvas:Q,width:t,height:i}=function(A){if(!A)throw new Error(\"No image provided\");const I=A&&\"number\"==typeof A.width&&\"number\"==typeof A.height&&A.data;let g=0,B=0;if(I?(g=A.width,B=A.height):(g=A.width||A.naturalWidth,B=A.height||A.naturalHeight),!g||!B)throw new Error(\"Image must be loaded before creating the corner editor\");const C=document.createElement(\"canvas\");C.width=g,C.height=B;const Q=C.getContext(\"2d\",{willReadFrequently:!0});if(!Q)throw new Error(\"Failed to create 2D canvas context for source image\");return I?Q.putImageData(A,0,0):Q.drawImage(A,0,0,g,B),{canvas:C,width:g,height:B}}(A.image),E=!I.classList.contains(\"scanic-corner-editor\");I.classList.add(\"scanic-corner-editor\"),A.classNames?.root&&I.classList.add(A.classNames.root);const e={position:I.style.position,minHeight:I.style.minHeight};let o=!1,n=!1;\"static\"===getComputedStyle(I).position&&(I.style.position=\"relative\",o=!0),P(A.theme);const a=g.createElement(\"canvas\");a.style.position=\"absolute\",a.style.top=\"0\",a.style.left=\"0\",a.style.display=\"block\",a.style.touchAction=\"none\",a.style.userSelect=\"none\",a.style.webkitUserSelect=\"none\",a.style.cursor=\"default\",I.appendChild(a);const s=a.getContext(\"2d\");if(!s)throw new Error(\"Failed to create 2D canvas context for corner editor\");const c={enabled:!1!==A.magnifier?.enabled,size:A.magnifier?.size||120,zoom:A.magnifier?.zoom||2,margin:A.magnifier?.margin||8,borderColor:A.magnifier?.borderColor||\"#ffffff\",borderWidth:A.magnifier?.borderWidth||2,crosshairColor:A.magnifier?.crosshairColor||\"#ffffff\",crosshairSize:A.magnifier?.crosshairSize||18},r={enabled:!!A.nudges?.enabled,steps:(A.nudges?.steps&&A.nudges.steps.length?A.nudges.steps:[1,10]).map(A=>Math.max(1,Math.round(A)))},h={enabled:!1!==A.toolbar?.enabled,reset:!1!==A.toolbar?.reset,cancel:!1!==A.toolbar?.cancel,apply:!1!==A.toolbar?.apply,labels:{reset:A.toolbar?.labels?.reset||\"Reset\",cancel:A.toolbar?.labels?.cancel||\"Cancel\",apply:A.toolbar?.labels?.apply||\"Apply\"}},l=!1!==A.keyboard,y=function(A,I,g=.08){const B=Math.max(8,Math.min(A,I)*g);return{topLeft:{x:B,y:B},topRight:{x:A-B,y:B},bottomRight:{x:A-B,y:I-B},bottomLeft:{x:B,y:I-B}}}(t,i),D=A.corners?b(A.corners):y;let w=x(D)&&U(D)?D:y;const d=b(w);let f=!1,u=null,m=\"topLeft\",N=null,R=null,p=null,F=null;const J=Math.max(24,A.handleHitArea||44);A.handleHitArea&&I.style.setProperty(\"--scanic-handle-hit\",J+\"px\");const G=[\"topLeft\",\"topRight\",\"bottomRight\",\"bottomLeft\"],k={topLeft:\"Top-left corner\",topRight:\"Top-right corner\",bottomRight:\"Bottom-right corner\",bottomLeft:\"Bottom-left corner\"};let S={scale:1,offsetX:0,offsetY:0,width:1,height:1};const M={mask:\"rgba(15,23,42,0.45)\",edgeColor:\"#6366f1\",edgeWidth:2.5},L={};for(const b of G){const B=g.createElement(\"button\");B.type=\"button\",B.className=\"scanic-handle\"+(A.classNames?.handle?\" \"+A.classNames.handle:\"\"),B.dataset.corner=b,B.setAttribute(\"aria-label\",k[b]),l||(B.tabIndex=-1),B.addEventListener(\"pointerdown\",A=>iA(b,A)),B.addEventListener(\"pointermove\",A=>EA(b,A)),B.addEventListener(\"pointerup\",A=>eA(b,A)),B.addEventListener(\"pointercancel\",A=>eA(b,A)),B.addEventListener(\"focus\",()=>{m=b,AA()}),l&&B.addEventListener(\"keydown\",A=>oA(b,A)),I.appendChild(B),L[b]=B}function T(A,I){const g=a.style.color;a.style.color=`var(${A}, ${I})`;const B=getComputedStyle(a).color||I;return a.style.color=g,B}function W(){M.mask=T(\"--scanic-mask\",\"rgba(15, 23, 42, 0.45)\"),M.edgeColor=T(\"--scanic-edge-color\",\"#6366f1\");const A=getComputedStyle(I).getPropertyValue(\"--scanic-edge-width\"),g=parseFloat(A);M.edgeWidth=Number.isFinite(g)&&g>0?g:2.5}function P(A){if(!A||\"object\"!=typeof A)return;const g=/* @__PURE__ */new Set([\"handleSize\",\"handleHit\"]);for(const[B,C]of Object.entries({accent:\"--scanic-accent\",mask:\"--scanic-mask\",edgeColor:\"--scanic-edge-color\",edgeWidth:\"--scanic-edge-width\",handleSize:\"--scanic-handle-size\",handleHit:\"--scanic-handle-hit\",handleColor:\"--scanic-handle-color\",handleRingColor:\"--scanic-handle-ring-color\",surface:\"--scanic-surface\",surfaceColor:\"--scanic-surface-fg\",radius:\"--scanic-surface-radius\"})){const Q=A[B];if(null==Q)continue;const t=\"number\"==typeof Q&&g.has(B)?`${Q}px`:String(Q);I.style.setProperty(C,t)}}function Z(){\"function\"==typeof A.onChange&&A.onChange(b(w))}let X=0,V=0;function j(){const A=Math.max(1,Math.round(I.clientWidth));let g=Math.round(I.clientHeight);if(g<80){const C=i/Math.max(1,t),Q=.7*(B.innerHeight||800);g=Math.max(240,Math.round(Math.min(A*C,Q))),I.style.minHeight=g+\"px\",n=!0}return{width:A,height:Math.max(1,g)}}function O(){const{width:A,height:I}=j(),g=B.devicePixelRatio||1;X=A,V=I,a.style.width=A+\"px\",a.style.height=I+\"px\";const C=Math.round(A*g),Q=Math.round(I*g);a.width!==C&&(a.width=C),a.height!==Q&&(a.height=Q),s.setTransform(g,0,0,g,0,0);const E=Math.max(1,A-24),e=Math.max(1,I-24),o=Math.min(E/t,e/i),n=t*o,c=i*o;S={scale:o,offsetX:Math.round((A-n)/2),offsetY:Math.round((I-c)/2),width:A,height:I},W()}function z(A){return{x:S.offsetX+A.x*S.scale,y:S.offsetY+A.y*S.scale}}function _(A){return x(A)&&U(A)}function $(A){const I=a.getBoundingClientRect();return{x:A.clientX-I.left,y:A.clientY-I.top}}function AA(){for(const A of G)L[A].classList.toggle(\"is-selected\",A===m)}function IA(){f||(s.clearRect(0,0,S.width,S.height),s.drawImage(Q,0,0,t,i,S.offsetX,S.offsetY,t*S.scale,i*S.scale),function(){const A=G.map(A=>z(w[A]));s.save(),s.fillStyle=M.mask,s.beginPath(),s.rect(0,0,S.width,S.height),s.moveTo(A[0].x,A[0].y);for(let I=1;I<A.length;I++)s.lineTo(A[I].x,A[I].y);s.closePath(),s.fill(\"evenodd\"),s.restore(),s.save(),s.strokeStyle=M.edgeColor,s.lineWidth=M.edgeWidth,s.lineJoin=\"round\",s.beginPath(),s.moveTo(A[0].x,A[0].y);for(let I=1;I<A.length;I++)s.lineTo(A[I].x,A[I].y);s.closePath(),s.stroke(),s.restore()}(),function(){if(!c.enabled||!u||!R)return;const A=w[u],I=c.size,g=I/2,B=Math.max(1.1,c.zoom),C=z(A);let E=C.x+g+c.margin,e=C.y-g-c.margin;E+g>S.width&&(E=C.x-g-c.margin),e-g<0&&(e=C.y+g+c.margin),E=Math.max(g+2,Math.min(S.width-g-2,E)),e=Math.max(g+2,Math.min(S.height-g-2,e));const o=I/B,n=A.x-o/2,a=A.y-o/2,r=Math.max(0,n),h=Math.max(0,a),l=Math.max(0,Math.min(t,n+o)-r),y=Math.max(0,Math.min(i,a+o)-h);if(s.save(),s.beginPath(),s.arc(E,e,g,0,2*Math.PI),s.clip(),s.fillStyle=M.mask,s.fillRect(E-g,e-g,I,I),l>0&&y>0){const A=E-g+(r-n)*B,I=e-g+(h-a)*B;s.drawImage(Q,r,h,l,y,A,I,l*B,y*B)}const D=c.crosshairSize/2;s.strokeStyle=c.crosshairColor,s.lineWidth=1.5,s.beginPath(),s.moveTo(E-D,e),s.lineTo(E+D,e),s.moveTo(E,e-D),s.lineTo(E,e+D),s.stroke(),s.restore(),s.save(),s.beginPath(),s.arc(E,e,g,0,2*Math.PI),s.lineWidth=c.borderWidth,s.strokeStyle=c.borderColor,s.stroke(),s.restore()}(),function(){for(const A of G){const I=z(w[A]),g=L[A];g.style.left=I.x+\"px\",g.style.top=I.y+\"px\"}}())}const gA=\"function\"==typeof B.requestAnimationFrame?B.requestAnimationFrame.bind(B):null,BA=\"function\"==typeof B.cancelAnimationFrame?B.cancelAnimationFrame.bind(B):null;let CA=null;function QA(){f||(gA?null===CA&&(CA=gA(()=>{CA=null,IA()})):IA())}function tA(A,I){const g=b(w);return g[A]={x:Math.max(0,Math.min(t,I.x)),y:Math.max(0,Math.min(i,I.y))},!!_(g)&&(w=g,m=A,AA(),Z(),QA(),!0)}function iA(A,I){if(!f){if(\"function\"==typeof I.preventDefault&&I.preventDefault(),u=A,m=A,AA(),N=I.pointerId,R=$(I),p=R,F=C(),L[A].classList.add(\"is-active\"),l&&\"function\"==typeof L[A].focus)try{L[A].focus({preventScroll:!0})}catch{L[A].focus()}if(L[A].setPointerCapture&&null!=I.pointerId)try{L[A].setPointerCapture(I.pointerId)}catch{}QA()}}function EA(A,I){if(f||u!==A)return;if(null!==N&&I.pointerId!==N)return;const g=$(I),B=g.x-p.x,Q=g.y-p.y,t=Math.max(1,C()-F),i=Math.hypot(B,Q)/t,E=Math.min(1,i/.8),e=.35+.65*(E*E*(3-2*E)),o=w[A];tA(A,{x:o.x+B*e/S.scale,y:o.y+Q*e/S.scale}),p=g,F=C(),R=g}function eA(A,I){if(u===A&&(null===N||I.pointerId===N)){if(L[A].releasePointerCapture&&null!=N)try{L[A].releasePointerCapture(N)}catch{}L[A].classList.remove(\"is-active\"),u=null,N=null,R=null,p=null,F=null,QA()}}function oA(A,I){if(f||!l)return;if(\"Enter\"===I.key)return I.preventDefault(),void yA();if(\"Escape\"===I.key)return I.preventDefault(),void DA();let g=0,B=0;if(\"ArrowLeft\"===I.key)g=-1;else if(\"ArrowRight\"===I.key)g=1;else if(\"ArrowUp\"===I.key)B=-1;else{if(\"ArrowDown\"!==I.key)return;B=1}I.preventDefault();const C=I.shiftKey?r.steps[r.steps.length-1]||10:1;tA(A,{x:w[A].x+g*C,y:w[A].y+B*C})}let nA=null,aA=null,sA=null,cA=!1;const rA=h.enabled&&r.enabled;function hA({html:A,text:I,title:B,className:C,onClick:Q}){const t=g.createElement(\"button\");return t.type=\"button\",null!=A?t.innerHTML=A:t.textContent=I,B&&(t.title=B,t.setAttribute(\"aria-label\",B)),C&&(t.className=C),t.addEventListener(\"click\",Q),t}let lA=null;function yA(){const I=b(w);return\"function\"==typeof A.onConfirm&&A.onConfirm(I),I}function DA(){\"function\"==typeof A.onCancel&&A.onCancel()}function wA(){w=b(d),Z(),QA()}const dA=\"undefined\"!=typeof ResizeObserver?new ResizeObserver(()=>{if(f)return;const A=j();A.width===X&&A.height===V||(O(),QA())}):null;return O(),h.enabled&&(h.reset||h.cancel||h.apply||rA)&&(nA=g.createElement(\"div\"),nA.className=\"scanic-toolbar\"+(A.classNames?.toolbar?\" \"+A.classNames.toolbar:\"\"),h.reset&&nA.appendChild(hA({html:Y,title:h.labels.reset,className:\"scanic-btn-reset\",onClick:()=>wA()})),rA&&(sA=hA({html:K,title:\"Precision nudge (expert)\",className:\"scanic-btn-expert\",onClick:()=>{return cA=A=!cA,aA&&(aA.style.display=A?\"\":\"none\"),void(sA&&(sA.classList.toggle(\"is-on\",A),sA.setAttribute(\"aria-pressed\",String(A))));var A}}),sA.setAttribute(\"aria-pressed\",\"false\"),nA.appendChild(sA)),h.cancel&&nA.appendChild(hA({html:q,title:h.labels.cancel,className:\"scanic-btn-cancel\",onClick:()=>DA()})),h.apply&&nA.appendChild(hA({html:v,title:h.labels.apply,className:\"scanic-btn-apply\",onClick:()=>yA()})),I.appendChild(nA)),function(){if(!r.enabled)return;aA=g.createElement(\"div\"),aA.className=\"scanic-nudges\"+(A.classNames?.nudges?\" \"+A.classNames.nudges:\"\");const B=(A,I,g,B,C)=>hA({text:A,title:I,className:\"scanic-btn-nudge\",onClick:()=>{const A=w[m];tA(m,{x:A.x+g*C,y:A.y+B*C})}});for(const A of r.steps)aA.appendChild(B(\"←\",`Move left ${A}px`,-1,0,A)),aA.appendChild(B(\"↑\",`Move up ${A}px`,0,-1,A)),aA.appendChild(B(\"↓\",`Move down ${A}px`,0,1,A)),aA.appendChild(B(\"→\",`Move right ${A}px`,1,0,A));I.appendChild(aA),rA&&(aA.style.display=\"none\")}(),function A(){if(\"function\"!=typeof B.matchMedia)return;lA&&lA();const I=B.devicePixelRatio||1,g=B.matchMedia(`(resolution: ${I}dppx)`),C=()=>{f||(O(),QA(),A())};\"function\"==typeof g.addEventListener?(g.addEventListener(\"change\",C),lA=()=>g.removeEventListener(\"change\",C)):\"function\"==typeof g.addListener?(g.addListener(C),lA=()=>g.removeListener(C)):lA=null}(),dA&&dA.observe(I),AA(),IA(),{getCorners:()=>b(w),setCorners:A=>!(!A||!_(A))&&(w=b(A),Z(),QA(),!0),reset(){wA()},nudge:(A,I,g,B=1)=>!!G.includes(A)&&tA(A,{x:w[A].x+I*B,y:w[A].y+g*B}),refreshTheme(A){P(A),W(),QA()},confirm:()=>yA(),cancel(){DA()},destroy(){if(!f){f=!0,null!==CA&&BA&&(BA(CA),CA=null),lA&&(lA(),lA=null),dA&&dA.disconnect();for(const A of G){const I=L[A];I&&I.parentNode&&I.parentNode.removeChild(I)}nA&&nA.parentNode&&nA.parentNode.removeChild(nA),aA&&aA.parentNode&&aA.parentNode.removeChild(aA),a.parentNode&&a.parentNode.removeChild(a),E&&I.classList.remove(\"scanic-corner-editor\"),A.classNames?.root&&I.classList.remove(A.classNames.root),o&&(I.style.position=e.position),n&&(I.style.minHeight=e.minHeight)}}}}async function W(){try{return await G()}catch{return null}}var P=class{constructor(A={}){this.defaultOptions={maxProcessingDimension:800,mode:\"detect\",output:\"canvas\",...A},this.initialized=!1}async initialize(){if(!this.initialized){if(\"ml\"===this.defaultOptions.detector)try{const{initializeMl:A}=await import(\"./scanic-mlDetector.js\");await A(this.defaultOptions.ml||{})}catch{}else try{await G()}catch{}this.initialized=!0}}async scan(A,I={}){return this.initialized||await this.initialize(),await IA(A,{...this.defaultOptions,...I})}async extract(A,I,g={}){return this.initialized||await this.initialize(),await AA(A,I,{...this.defaultOptions,...g})}};function Z(A){return A<=0?0:A>=1?1:A}function X(A,I){return Math.hypot(A.x-I.x,A.y-I.y)}function V(A){return[X(A.topLeft,A.topRight),X(A.topRight,A.bottomRight),X(A.bottomRight,A.bottomLeft),X(A.bottomLeft,A.topLeft)]}function j(A){const I=function(A){const I=[A.topLeft,A.topRight,A.bottomRight,A.bottomLeft],g=[];for(let B=0;B<I.length;B++){const A=I[(B+I.length-1)%I.length],C=I[B],Q=I[(B+1)%I.length],t=A.x-C.x,i=A.y-C.y,E=Q.x-C.x,e=Q.y-C.y,o=t*E+i*e,n=Math.max(1e-6,Math.hypot(t,i)*Math.hypot(E,e)),a=Math.max(-1,Math.min(1,o/n));g.push(180*Math.acos(a)/Math.PI)}return g}(A);let g=0;for(const B of I){g+=Z(1-Math.abs(B-90)/55)}return g/Math.max(1,I.length)}function O(A,I){const g=Number(I.isValid)-Number(A.isValid);if(0!==g)return g;const B=I.confidence-A.confidence;if(!(Math.abs(B)<.015)&&0!==B)return B;const C=Math.abs((A.approxCount??99)-4)-Math.abs((I.approxCount??99)-4);if(0!==C)return C;const Q=(I.rightAngleScore??0)-(A.rightAngleScore??0);if(Math.abs(Q)>1e-6)return Q;const t=Math.abs(1-(A.contourFitRatio??1))-Math.abs(1-(I.contourFitRatio??1));return Math.abs(t)>1e-6?t:B||I.score-A.score||I.coverageRatio-A.coverageRatio||I.area-A.area}function z(A,I,g,B,C={}){const Q=C.epsilon||.02,t=E(A.points,Q).length,i=n(A,{epsilon:Q});if(!i)return{contour:A,corners:null,score:0,confidence:0,isValid:!1,area:A.area||0,fillRatio:0,coverageRatio:0,cornersArea:0,approxCount:t,convex:!1,edgeSupport:0,aspectRatio:1/0,minSide:0,rightAngleScore:0,oppositeSideConsistency:0,contourFitRatio:0,contourFitScore:0};const e=g*B,o=A.area||0,a=A.boundingBox||{minX:0,minY:0,maxX:0,maxY:0},s=o/Math.max(1,(a.maxX-a.minX+1)*(a.maxY-a.minY+1)),c=function(A){if(!A)return 0;const I=[A.topLeft,A.topRight,A.bottomRight,A.bottomLeft];let g=0;for(let B=0;B<I.length;B++){const A=(B+1)%I.length;g+=I[B].x*I[A].y-I[A].x*I[B].y}return Math.abs(g)/2}(i),r=c/Math.max(1,e),h=V(i),l=Math.min(...h),y=(h[0]+h[2])/2,D=(h[1]+h[3])/2,w=y>D?y/Math.max(1e-6,D):D/Math.max(1e-6,y),d=function(A){const I=[A.topLeft,A.topRight,A.bottomRight,A.bottomLeft],g=[];for(let C=0;C<I.length;C++){const A=I[C],B=I[(C+1)%I.length],Q=I[(C+2)%I.length],t=(B.x-A.x)*(Q.y-B.y)-(B.y-A.y)*(Q.x-B.x);Math.abs(t)<1e-6||g.push(Math.sign(t))}if(g.length<3)return!1;const B=g[0];return g.every(A=>A===B)}(i),f=function(A,I,g,B){if(!A?.points||0===A.points.length)return 0;const C=Math.max(1,Math.floor(A.points.length/240));let Q=0,t=0;for(let i=0;i<A.points.length;i+=C){const C=A.points[i],E=Math.max(0,Math.min(g-1,0|C.x)),e=Math.max(0,Math.min(B-1,0|C.y));Q++;let o=!1;for(let A=-1;A<=1&&!o;A++){const C=e+A;if(!(C<0||C>=B))for(let A=-1;A<=1;A++){const B=E+A;if(!(B<0||B>=g)&&I[C*g+B]>0){o=!0;break}}}o&&t++}return 0===Q?0:t/Q}(A,I,g,B),u=j(i),m=function(A){const I=V(A);return(Math.min(I[0],I[2])/Math.max(1e-6,Math.max(I[0],I[2]))+Math.min(I[1],I[3])/Math.max(1e-6,Math.max(I[1],I[3])))/2}(i),N=o/Math.max(1,c),R=Z(1-Math.abs(N-1)/.55),p=4===t?1:5===t?.9:6===t?.7:t<=8?.5:.28,F=Z(o/Math.max(1,.4*e)),J=Z((s-.08)/.72),G=Z((r-.03)/.82),k=void 0!==C.minDocumentSideRatio?C.minDocumentSideRatio:.06,S=void 0!==C.minDocumentCoverageRatio?C.minDocumentCoverageRatio:.04,M=void 0!==C.maxDocumentAspectRatio?C.maxDocumentAspectRatio:8,b=void 0!==C.minDocumentFillRatio?C.minDocumentFillRatio:.07,L=void 0!==C.minContourFitRatio?C.minContourFitRatio:.11,x=void 0!==C.maxContourFitRatio?C.maxContourFitRatio:1.2,U=void 0!==C.minRightAngleScore?C.minRightAngleScore:.42,H=void 0!==C.minOppositeSideConsistency?C.minOppositeSideConsistency:.3,Y=Math.min(g,B)*k,q=function(A,I=6){const g=[A?.topLeft,A?.topRight,A?.bottomRight,A?.bottomLeft];if(g.some(A=>!A||!Number.isFinite(A.x)||!Number.isFinite(A.y)))return!1;for(let B=0;B<g.length;B++)for(let A=B+1;A<g.length;A++)if(X(g[B],g[A])<I)return!1;return!0}(i)&&d&&l>=Y&&r>=S&&w<=M&&s>=b&&N>=L&&N<=x&&u>=U&&m>=H,v=.22*F+.14*J+.15*p+.08*(d?1:0)+.08*f+.13*G+.1*u+.05*m+.05*R;return{contour:A,corners:i,score:v,confidence:q?v:.33*v,isValid:q,area:o,fillRatio:s,coverageRatio:r,cornersArea:c,approxCount:t,convex:d,edgeSupport:f,aspectRatio:w,minSide:l,rightAngleScore:u,oppositeSideConsistency:m,contourFitRatio:N,contourFitScore:R}}async function _(A,I,g,C,Q={}){const t=Q.debug?{}:{_timingsOnly:!0},i=[];t&&!t._timingsOnly&&(t.preprocessing={scaledDimensions:{width:I,height:g},scaleFactor:C,maxProcessingDimension:Q.maxProcessingDimension||800});const E=function(A={}){const I=A.dilationKernelSize||3,g=A.dilationIterations||1,B=void 0===A.applyDilation||A.applyDilation,C=[{name:\"default\",lowThreshold:A.lowThreshold,highThreshold:A.highThreshold,dilationKernelSize:I,dilationIterations:g,applyDilation:B}];if(!1===A.enableDetectionCascade)return C;C.push({name:\"connect-edges\",lowThreshold:A.lowThreshold,highThreshold:A.highThreshold,dilationKernelSize:Math.max(I,5),dilationIterations:Math.max(g,2),applyDilation:!0}),C.push({name:\"no-dilation\",lowThreshold:A.lowThreshold,highThreshold:A.highThreshold,dilationKernelSize:I,dilationIterations:g,applyDilation:!1}),void 0===A.lowThreshold&&void 0===A.highThreshold&&C.push({name:\"fixed-mid-thresholds\",lowThreshold:60,highThreshold:180,dilationKernelSize:I,dilationIterations:g,applyDilation:B});const Q=[],t=/* @__PURE__ */new Set;for(const i of C){const A=[i.lowThreshold,i.highThreshold,i.dilationKernelSize,i.dilationIterations,i.applyDilation].join(\":\");t.has(A)||(t.add(A),Q.push(i))}return Q}(Q),e=[],o=async(t,E)=>{const e=t.name||`pass-${E+1}`,o=0===E?\"\":` (${e})`,n=Q.debug?{}:{_timingsOnly:!0},a=await M(A,{width:I,height:g,lowThreshold:t.lowThreshold,highThreshold:t.highThreshold,dilationKernelSize:t.dilationKernelSize,dilationIterations:t.dilationIterations,applyDilation:t.applyDilation,debug:n,skipGrayscale:!0,useWasmBlur:!0,useWasmHysteresis:Q.useWasmHysteresis,useWasmFullCanny:Q.useWasmFullCanny});n.timings&&n.timings.forEach(A=>{\"Edge Detection Total\"!==A.step&&i.push({step:`${A.step}${o}`,ms:A.ms})});let s=performance.now();const c=B(a,{minArea:(Q.minArea||1e3)/(C*C),width:I,height:g});i.push({step:`Find Contours${o}`,ms:(performance.now()-s).toFixed(2)}),s=performance.now();const{best:r,candidates:h}=function(A,I,g,B,C={}){const Q=C.maxCandidateContours||12,t=A.slice(0,Q).map((A,Q)=>({rankByArea:Q,...z(A,I,g,B,C)})).sort(O);return{best:t[0]||null,candidates:t}}(c,a,I,g,Q);return i.push({step:`Corner Detection${o}`,ms:(performance.now()-s).toFixed(2)}),{name:e,params:{lowThreshold:t.lowThreshold,highThreshold:t.highThreshold,dilationKernelSize:t.dilationKernelSize,dilationIterations:t.dilationIterations,applyDilation:t.applyDilation},contours:c,best:r,candidates:h}},n=await o(E[0],0);if(e.push(n),function(A,I={}){if(!1===I.enableDetectionCascade)return!1;if(!A||!A.corners)return!0;const g=void 0!==I.minCascadeTriggerConfidence?I.minCascadeTriggerConfidence:.68;return!A.isValid||A.confidence<g||A.approxCount>5||A.rightAngleScore<.55||A.contourFitRatio<.14}(n.best,Q))for(let B=1;B<E.length;B++)e.push(await o(E[B],B));const a=[];for(const B of e)for(const A of B.candidates)a.push({...A,passName:B.name,passParams:B.params});a.sort(O);const s=a[0]||null,c=a;if(!s||!s.corners)return{success:!1,message:\"No document detected\",debug:t._timingsOnly?null:t,timings:i};t&&!t._timingsOnly&&(t.passes=e.map(A=>({name:A.name,params:A.params,contourCount:A.contours.length,bestCandidate:A.best?{score:A.best.score,confidence:A.best.confidence,isValid:A.best.isValid,approxCount:A.best.approxCount,coverageRatio:A.best.coverageRatio,fillRatio:A.best.fillRatio,rightAngleScore:A.best.rightAngleScore,contourFitRatio:A.best.contourFitRatio}:null})),t.candidates=c.map(A=>({passName:A.passName,rankByArea:A.rankByArea,area:A.area,fillRatio:A.fillRatio,coverageRatio:A.coverageRatio,cornersArea:A.cornersArea,approxCount:A.approxCount,convex:A.convex,edgeSupport:A.edgeSupport,aspectRatio:A.aspectRatio,minSide:A.minSide,rightAngleScore:A.rightAngleScore,oppositeSideConsistency:A.oppositeSideConsistency,contourFitRatio:A.contourFitRatio,contourFitScore:A.contourFitScore,score:A.score,confidence:A.confidence,isValid:A.isValid})),t.selectedCandidate=c[0]?{passName:c[0].passName,rankByArea:c[0].rankByArea,area:c[0].area,fillRatio:c[0].fillRatio,coverageRatio:c[0].coverageRatio,approxCount:c[0].approxCount,edgeSupport:c[0].edgeSupport,aspectRatio:c[0].aspectRatio,minSide:c[0].minSide,rightAngleScore:c[0].rightAngleScore,oppositeSideConsistency:c[0].oppositeSideConsistency,contourFitRatio:c[0].contourFitRatio,score:c[0].score,confidence:c[0].confidence,isValid:c[0].isValid}:null);const r=s.corners,h=s.contour;let l=r;return 1!==C&&(l={topLeft:{x:r.topLeft.x*C,y:r.topLeft.y*C},topRight:{x:r.topRight.x*C,y:r.topRight.y*C},bottomRight:{x:r.bottomRight.x*C,y:r.bottomRight.y*C},bottomLeft:{x:r.bottomLeft.x*C,y:r.bottomLeft.y*C}}),{success:!0,contour:h,corners:l,confidence:s.confidence,debug:t._timingsOnly?null:t,timings:i}}function $(A,I,g){const{topLeft:B,topRight:C,bottomRight:Q,bottomLeft:t}=g,i=Math.hypot(Q.x-t.x,Q.y-t.y),E=Math.hypot(C.x-B.x,C.y-B.y),e=Math.round(Math.max(i,E)),o=Math.hypot(C.x-Q.x,C.y-Q.y),n=Math.hypot(B.x-t.x,B.y-t.y),a=Math.round(Math.max(o,n));A.canvas.width=e,A.canvas.height=a,function(A,I,g,B,C){const Q=I&&\"number\"==typeof I.width&&\"number\"==typeof I.height&&I.data,t=I.width||I.naturalWidth,i=I.height||I.naturalHeight,E=document.createElement(\"canvas\");E.width=t,E.height=i;const e=E.getContext(\"2d\",{willReadFrequently:!0});Q?e.putImageData(I,0,0):e.drawImage(I,0,0,t,i);const o=e.getImageData(0,0,t,i).data,n=function(A){const I=A[0][0],g=A[0][1],B=A[0][2],C=A[1][0],Q=A[1][1],t=A[1][2],i=A[2][0],E=A[2][1],e=A[2][2],o=Q*e-t*E,n=-(C*e-t*i),a=C*E-Q*i,s=-(g*e-B*E),c=I*e-B*i,r=-(I*E-g*i),h=g*t-B*Q,l=-(I*t-B*C),y=I*Q-g*C,D=I*o+g*n+B*a;if(0===D)throw new Error(\"Singular matrix\");return[[o/D,s/D,h/D],[n/D,c/D,l/D],[a/D,r/D,y/D]]}(g),a=n[0][0],s=n[0][1],c=n[0][2],r=n[1][0],h=n[1][1],l=n[1][2],y=n[2][0],D=n[2][1],w=n[2][2],d=A.createImageData(B,C),f=d.data,u=t-1,m=i-1;for(let N=0;N<C;N++){const A=s*N+c,I=h*N+l,g=D*N+w;for(let C=0;C<B;C++){const Q=1/(y*C+g),i=(a*C+A)*Q,E=(r*C+I)*Q,e=i<0?0:i>u?u:i,n=E<0?0:E>m?m:E,s=0|e,c=0|n,h=s<u?s+1:s,l=c<m?c+1:c,D=e-s,w=n-c,d=1-D,R=1-w,p=d*R,F=D*R,J=d*w,G=D*w,k=c*t+s<<2,S=c*t+h<<2,M=l*t+s<<2,b=l*t+h<<2,L=N*B+C<<2;f[L]=o[k]*p+o[S]*F+o[M]*J+o[b]*G+.5|0,f[L+1]=o[k+1]*p+o[S+1]*F+o[M+1]*J+o[b+1]*G+.5|0,f[L+2]=o[k+2]*p+o[S+2]*F+o[M+2]*J+o[b+2]*G+.5|0,f[L+3]=255}}A.putImageData(d,0,0)}(A,I,function(A,I){const g=function(A,I){const g=A.length,B=A[0].length,C=A.map(A=>A.slice()),Q=I.slice();for(let i=0;i<B;i++){let A=i;for(let I=i+1;I<g;I++)Math.abs(C[I][i])>Math.abs(C[A][i])&&(A=I);[C[i],C[A]]=[C[A],C[i]],[Q[i],Q[A]]=[Q[A],Q[i]];for(let I=i+1;I<g;I++){const A=C[I][i]/C[i][i];for(let g=i;g<B;g++)C[I][g]-=A*C[i][g];Q[I]-=A*Q[i]}}const t=new Array(B);for(let i=B-1;i>=0;i--){let A=Q[i];for(let I=i+1;I<B;I++)A-=C[i][I]*t[I];t[i]=A/C[i][i]}return t}(function(A){const g=[];for(let B=0;B<4;B++){const[C,Q]=A[B];g.push([C,Q,1,0,0,0,-C*I[B][0],-Q*I[B][0]]),g.push([0,0,0,C,Q,1,-C*I[B][1],-Q*I[B][1]])}return g}(A),[I[0][0],I[0][1],I[1][0],I[1][1],I[2][0],I[2][1],I[3][0],I[3][1]]);return[[g[0],g[1],g[2]],[g[3],g[4],g[5]],[g[6],g[7],1]]}([[B.x,B.y],[C.x,C.y],[Q.x,Q.y],[t.x,t.y]],[[0,0],[e-1,0],[e-1,a-1],[0,a-1]]),e,a)}async function AA(A,I,g={}){const B=g.output||\"canvas\";if(!(I&&I.topLeft&&I.topRight&&I.bottomRight&&I.bottomLeft))return{output:null,corners:null,success:!1,message:\"Invalid corner points provided\"};try{const g=document.createElement(\"canvas\");let C;return $(g.getContext(\"2d\"),A,I),C=\"canvas\"===B?g:\"imagedata\"===B?g.getContext(\"2d\").getImageData(0,0,g.width,g.height):\"dataurl\"===B?g.toDataURL():g,{output:C,corners:I,success:!0,message:\"Document extracted successfully\"}}catch(C){return{output:null,corners:I,success:!1,message:`Extraction failed: ${C.message}`}}}async function IA(A,I={}){const g=[],B=performance.now(),C=I.mode||\"detect\",Q=I.output||\"canvas\",t=I.maxProcessingDimension||800;let i,E,e,o;if(\"ml\"===(I.detector||\"classical\")){E=performance.now();const{detectDocumentMl:B}=await import(\"./scanic-mlDetector.js\");i=await B(A,I.ml||{}),g.push({step:\"ML Detection Total\",ms:(performance.now()-E).toFixed(2)}),i.timings&&i.timings.forEach(A=>g.push(A))}else{E=performance.now();const{grayscaleData:B,scaleFactor:C,scaledDimensions:Q}=await async function(A,I=800){let g,B;const C=A&&\"number\"==typeof A.width&&\"number\"==typeof A.height&&A.data;if(C)g=A.width,B=A.height;else{if(!A)throw new Error(\"No image provided\");g=A.width||A.naturalWidth,B=A.height||A.naturalHeight}const Q=Math.max(g,B);let t,i,E;if(Q<=I)t=g,i=B,E=1;else{const A=I/Q;t=Math.round(g*A),i=Math.round(B*A),E=1/A}const e=\"undefined\"!=typeof OffscreenCanvas,o=e?new OffscreenCanvas(t,i):document.createElement(\"canvas\");e||(o.width=t,o.height=i);const n=o.getContext(\"2d\",{willReadFrequently:!0});if(n.imageSmoothingEnabled=!0,n.imageSmoothingQuality=\"medium\",C){const I=e?new OffscreenCanvas(g,B):document.createElement(\"canvas\");e||(I.width=g,I.height=B),I.getContext(\"2d\").putImageData(A,0,0),n.drawImage(I,0,0,g,B,0,0,t,i)}else n.drawImage(A,0,0,g,B,0,0,t,i);const a=n.getImageData(0,0,t,i),s=a.data,c=new Uint8ClampedArray(t*i);for(let r=0,h=0;r<s.length;r+=4,h++){const A=54*s[r]+183*s[r+1]+19*s[r+2]>>8;c[h]=A,s[r]=s[r+1]=s[r+2]=A}return{grayscaleData:c,imageData:a,scaleFactor:E,originalDimensions:{width:g,height:B},scaledDimensions:{width:t,height:i}}}(A,t);g.push({step:\"Image Prep + Scale + Gray\",ms:(performance.now()-E).toFixed(2)}),i=await _(B,Q.width,Q.height,C,I),i.timings&&i.timings.forEach(A=>g.push(A))}if(!i.success){const A=performance.now();return g.unshift({step:\"Total\",ms:(A-B).toFixed(2)}),{output:null,corners:null,contour:null,confidence:i.confidence||null,score:i.score??null,debug:i.debug,success:!1,message:i.message||\"No document detected\",timings:g}}\"detect\"===C?o=null:\"extract\"===C&&(E=performance.now(),e=document.createElement(\"canvas\"),$(e.getContext(\"2d\"),A,i.corners),g.push({step:\"Perspective Transform\",ms:(performance.now()-E).toFixed(2)})),\"detect\"!==C&&e&&(E=performance.now(),o=\"canvas\"===Q?e:\"imagedata\"===Q?e.getContext(\"2d\").getImageData(0,0,e.width,e.height):\"dataurl\"===Q?e.toDataURL():e,g.push({step:\"Output Conversion\",ms:(performance.now()-E).toFixed(2)}));const n=performance.now();return g.unshift({step:\"Total\",ms:(n-B).toFixed(2)}),{output:o,corners:i.corners,contour:i.contour??null,confidence:i.confidence||null,score:i.score??null,debug:i.debug,success:!0,message:\"Document detected\",timings:g}}export{P as Scanner,T as createCornerEditor,AA as extractDocument,W as initialize,IA as scanDocument};","// Quad detector over the VENDORED scanic 1.5.0 dist (Task 34). Vendoring\n// posture = models-v3: the dist is committed under vendor/scanic/ with a\n// sha256 manifest pinned by test/doc/scanic-manifest.test.ts — no registry\n// fetch at build time, no CDN at runtime (the Rust-WASM Canny pipeline is\n// base64-embedded in scanic.js; the optional ML detector chunk is never\n// requested because we pin `detector: 'classical'`).\nimport { scanDocument } from \"../../../vendor/scanic/scanic.js\";\nimport { DOC_DETECT_WIDTH, type DocQuad } from \"./doc-gate-v1\";\n\n/** Pinned vendored version — bump ONLY with a manifest + bench re-run. */\nexport const SCANIC_VERSION = \"1.5.0\";\n\nexport { DOC_DETECT_WIDTH };\n\n/**\n * Minimum scanic contour confidence to report a quad AT ALL (operator gate\n * feedback 2026-07-12: low-confidence contours drew corners well inside the\n * card — better to coach `no_doc` than to render a garbage quad the user\n * chases). Lowered 0.5→0.35 at gate round 2: passport data pages against the\n * booklet's own pages have weak edge contrast and 0.5 starved detection —\n * the gate's plausibility/stability checks stay the real filter.\n */\nexport const DOC_DETECT_MIN_CONFIDENCE = 0.35;\n\n/**\n * Detect the document quad on a (≤480px) snapshot. Returns the corner points\n * in the SNAPSHOT's pixel space, or null when scanic finds no plausible\n * document contour (or only a low-confidence one). Detection only — no\n * extraction/warp here (the session crops the full-res still itself).\n */\nexport async function detectQuad(image: ImageData): Promise<DocQuad | null> {\n const result = await scanDocument(image, {\n mode: \"detect\",\n detector: \"classical\",\n maxProcessingDimension: DOC_DETECT_WIDTH,\n });\n if (!result.success || result.corners === null) return null;\n if (typeof result.confidence === \"number\" && result.confidence < DOC_DETECT_MIN_CONFIDENCE) {\n return null;\n }\n return result.corners;\n}\n","/**\n * @internal — NOT part of the public @sekyro/web API. Consumed by Sekyro's own hosted page only\n * (document scanner + gate-debug geometry). No semver guarantees; may change in any release.\n *\n * detector-scanic is DELIBERATELY not re-exported here either: CaptureSessionDoc\n * lazy-imports it on the first detect tick so the ~39KiB-gz vendored chunk never\n * rides a host's session-shell bundle (route budget) — import\n * \"../core/doc/detector-scanic\" directly if you need bare detectQuad.\n */\nexport * from \"../core/doc/doc-catalog\";\nexport * from \"../core/doc/doc-gate-v1\";\nexport * from \"../core/doc/mrz-band\";\nexport * from \"../core/doc/frame-analysis\";\nexport * from \"../core/doc/feedback-aggregator\";\nexport * from \"../core/doc/capture-session-doc\";\nexport { CENTERED_FACTOR, CIRCLE_RADIUS_FACTOR, IN_CIRCLE_FACTOR } from \"../core/capture-constraints\";\n\n// ── Plan A Task 6: verification internals (seams, flow, mapping, Turnstile) ──\n// Consumed by Sekyro's own hosted page / @sekyro/react and the tests; the\n// public partner API is the root entry (`@sekyro/web`).\nexport {\n createLivenessCaptureInternal,\n mapEngineState,\n mapErrorKind,\n mapGuidanceHint,\n type CaptureEngine,\n type LivenessCaptureInternalHandle,\n type LivenessCaptureInternals,\n} from \"../capture/create-liveness-capture\";\nexport {\n createVerificationInternal,\n PROCESSING_POLL_DELAY_MS,\n PROCESSING_POLL_MAX,\n randomUuid,\n REGISTRY_RETRY_DELAY_MS,\n type VerificationInternals,\n} from \"../verification/create-verification\";\nexport {\n AttestationError,\n CLIP_MIME_ALLOWLIST,\n runLivenessFlow,\n runSubmission,\n TRANSPORT_REPLAY_ATTEMPTS,\n TRANSPORT_REPLAY_DELAY_MS,\n type HostedClientLike,\n type LivenessFlowDeps,\n type LivenessFlowOutcome,\n type SubmitExecutor,\n type SubmitRuntime,\n} from \"../verification/liveness-flow\";\nexport {\n frontierStep,\n isExecutable,\n isTerminalView,\n mapSessionResult,\n mergeSessionView,\n RETRYABLE_REASONS,\n stepOf,\n} from \"../verification/result\";\nexport {\n type ExecuteTurnstileOptions,\n executeTurnstile,\n loadTurnstile,\n resetTurnstileForTests,\n TURNSTILE_EXECUTE_TIMEOUT_MS,\n TURNSTILE_SCRIPT_SRC,\n type TurnstileApi,\n type TurnstileRenderParams,\n} from \"../verification/turnstile\";\n","// MRZ-band detector (Task 37 round 3) — the passport path's detection signal.\n//\n// WHY: edge/contour detection (scanic) fails on passport data pages — an open\n// booklet's page edges are white-on-white, so quads lock late or onto the\n// wrong rectangle (operator field finding, twice). The industry-standard\n// approach (Scanbot/Regula/Dynamsoft; PyImageSearch's classic blackhat\n// pipeline; YOLO-MRZ) is to detect the MRZ ITSELF: two 44-char lines of\n// high-contrast OCR-B strokes — the one feature of a passport that is\n// reliably detectable in any framing. This is the pure-JS analog of the\n// blackhat+gradient pipeline: per-row horizontal-stroke density with a\n// column-coverage requirement, then the tallest qualifying row run.\n//\n// Deterministic, allocation-light, no wasm: ~2ms on a 480px frame in node —\n// cheap enough to run at full doc cadence on LOW devices.\n\nexport interface MrzBand {\n x: number;\n y: number;\n width: number;\n height: number;\n /** Mean qualifying-row stroke density (diagnostics/telemetry). */\n density: number;\n}\n\nexport interface MrzBandThresholds {\n /** Luma step that counts as a text stroke edge. */\n EDGE_LUMA_DELTA: number;\n /** Min fraction of a row's pixels that are stroke edges to qualify. */\n MIN_ROW_DENSITY: number;\n /** Row must have stroke edges spread across ≥ this fraction of 12 columns. */\n MIN_COLUMN_COVERAGE: number;\n /** Band width (stroke x-extent) as a fraction of frame width. */\n MIN_WIDTH_FRAC: number;\n /** Band height bounds as fractions of frame height (2–3 OCR-B lines). */\n MIN_HEIGHT_FRAC: number;\n MAX_HEIGHT_FRAC: number;\n /** Rows this close together merge into one band (inter-line gap). */\n ROW_MERGE_GAP: number;\n}\n\n/** Frozen defaults (goldens in test/doc/mrz-band.test.ts — retune together). */\nexport const MRZ_BAND_DEFAULTS: Readonly<MrzBandThresholds> = Object.freeze({\n EDGE_LUMA_DELTA: 40,\n MIN_ROW_DENSITY: 0.08,\n MIN_COLUMN_COVERAGE: 0.6,\n MIN_WIDTH_FRAC: 0.55,\n MIN_HEIGHT_FRAC: 0.02,\n MAX_HEIGHT_FRAC: 0.16,\n ROW_MERGE_GAP: 18,\n});\n\nconst COLUMN_BUCKETS = 12;\n\n/**\n * Detect the MRZ stroke band on a (≤480px) grayscale-able frame. Returns the\n * tight band rect in frame pixels, or null when no qualifying band exists\n * (no MRZ in view, or only a partial/narrow slice of one).\n */\nexport function detectMrzBand(\n frame: ImageData,\n overrides: Partial<MrzBandThresholds> = {},\n): MrzBand | null {\n const t = { ...MRZ_BAND_DEFAULTS, ...overrides };\n const { data, width, height } = frame;\n if (width < 32 || height < 32) return null;\n\n // Per-row: stroke-edge count + column coverage + x-extent.\n const qualifies = new Array<boolean>(height).fill(false);\n const density = new Float32Array(height);\n const minX = new Int32Array(height).fill(width);\n const maxX = new Int32Array(height).fill(-1);\n\n const bucketWidth = width / COLUMN_BUCKETS;\n const buckets = new Array<boolean>(COLUMN_BUCKETS);\n for (let y = 0; y < height; y++) {\n let edges = 0;\n buckets.fill(false);\n const rowOffset = y * width * 4;\n let previousLuma =\n 0.299 * (data[rowOffset] ?? 0) +\n 0.587 * (data[rowOffset + 1] ?? 0) +\n 0.114 * (data[rowOffset + 2] ?? 0);\n for (let x = 1; x < width; x++) {\n const i = rowOffset + x * 4;\n const luma =\n 0.299 * (data[i] ?? 0) + 0.587 * (data[i + 1] ?? 0) + 0.114 * (data[i + 2] ?? 0);\n if (Math.abs(luma - previousLuma) >= t.EDGE_LUMA_DELTA) {\n edges += 1;\n buckets[Math.min(COLUMN_BUCKETS - 1, Math.floor(x / bucketWidth))] = true;\n if (x < (minX[y] as number)) minX[y] = x;\n if (x > (maxX[y] as number)) maxX[y] = x;\n }\n previousLuma = luma;\n }\n density[y] = edges / width;\n const coverage = buckets.filter(Boolean).length / COLUMN_BUCKETS;\n qualifies[y] =\n density[y]! >= t.MIN_ROW_DENSITY &&\n coverage >= t.MIN_COLUMN_COVERAGE &&\n (maxX[y] as number) - (minX[y] as number) >= t.MIN_WIDTH_FRAC * width;\n }\n\n // Merge qualifying rows across the inter-line gap; keep the best band.\n let best: { top: number; bottom: number; rows: number } | null = null;\n let runTop = -1;\n let lastQualifying = -1;\n let runRows = 0;\n const flush = (bottom: number) => {\n if (runTop < 0) return;\n const bandHeight = bottom - runTop + 1;\n if (\n bandHeight >= t.MIN_HEIGHT_FRAC * height &&\n bandHeight <= t.MAX_HEIGHT_FRAC * height &&\n runRows >= 4 && // at least a few real stroke rows, not a lone edge\n (best === null || runRows > best.rows)\n ) {\n best = { top: runTop, bottom, rows: runRows };\n }\n runTop = -1;\n runRows = 0;\n };\n for (let y = 0; y < height; y++) {\n if (qualifies[y]) {\n if (runTop < 0) runTop = y;\n else if (y - lastQualifying > t.ROW_MERGE_GAP) {\n flush(lastQualifying);\n runTop = y;\n }\n lastQualifying = y;\n runRows += 1;\n }\n }\n flush(lastQualifying);\n if (best === null) return null;\n const band = best as { top: number; bottom: number; rows: number };\n\n // Tight x-extent + mean density over the band's qualifying rows.\n let x1 = width;\n let x2 = -1;\n let densitySum = 0;\n let densityRows = 0;\n for (let y = band.top; y <= band.bottom; y++) {\n if (!qualifies[y]) continue;\n if ((minX[y] as number) < x1) x1 = minX[y] as number;\n if ((maxX[y] as number) > x2) x2 = maxX[y] as number;\n densitySum += density[y] as number;\n densityRows += 1;\n }\n if (x2 - x1 < t.MIN_WIDTH_FRAC * width) return null;\n return {\n x: x1,\n y: band.top,\n width: x2 - x1,\n height: band.bottom - band.top + 1,\n density: densityRows > 0 ? densitySum / densityRows : 0,\n };\n}\n","// Doc frame analysis (capture v2, Task-37 round 4) — the BlinkID-inspired\n// PER-FRAME status vector: independent framing / lighting / blur / glare /\n// tilt verdicts instead of a single collapsed guidance key. Pure and\n// deterministic: inputs are the detection (quad or MRZ band rect-as-quad),\n// the doc-region crop's quality measures, and static thresholds — no clocks,\n// no I/O. The FeedbackAggregator votes over these statuses; DocGateV1's\n// integrator/stability logic consumes `framingOk`/`qualityOk`.\nimport { EXPOSURE_BAND } from \"../v3/frame-quality\";\nimport { aspectBand, type DocFormat } from \"./doc-catalog\";\nimport {\n DOC_GATE_V1_DEFAULTS,\n type DocGateThresholds,\n type DocQuad,\n quadAreaFrac,\n quadBounds,\n} from \"./doc-gate-v1\";\n\nexport type FramingStatus =\n | \"no_document\"\n | \"too_far\"\n | \"too_close\"\n | \"edge_clipped\"\n | \"wrong_shape\"\n | \"tilted\"\n | \"ok\";\n\nexport type LightingStatus = \"too_dark\" | \"too_bright\" | \"ok\";\nexport type BlurStatus = \"blurry\" | \"ok\";\nexport type GlareStatus = \"glare\" | \"ok\";\n\n/** The per-frame analysis vector (every axis judged independently). */\nexport interface DocFrameAnalysis {\n framing: FramingStatus;\n lighting: LightingStatus;\n blur: BlurStatus;\n glare: GlareStatus;\n /** All-clear: every axis ok — the gate's integrator/stability input. */\n acceptable: boolean;\n}\n\nexport interface DocFrameMeasures {\n /** frame-quality sharpness on the doc-region crop (0..1). */\n sharpness: number;\n /** frame-quality exposure on the doc-region crop (0..1). */\n exposure: number;\n /** Mean crop luma (0..255) — picks too_dark vs too_bright. */\n meanLuma: number;\n /** Fraction of crop pixels at/above the specular ceiling (0..1). */\n specularFraction: number;\n}\n\n/** Analysis thresholds beyond the gate's — frozen defaults (round 4). */\nexport const DOC_ANALYSIS_DEFAULTS = Object.freeze({\n /** Doc area fraction above which the camera is too close (capture would crop). */\n MAX_AREA_FRAC: 0.92,\n /** Opposite-side length ratio beyond which the view is too oblique. */\n TILT_MAX_SIDE_RATIO: 1.3,\n /** Specular-pixel fraction at/above which the frame reads as glare. */\n GLARE_MAX_SPECULAR_FRAC: 0.025,\n});\n\n/** Fraction of crop pixels with luma ≥ 252 — cheap specular-highlight measure. */\nexport function specularFraction(crop: ImageData): number {\n const { data, width, height } = crop;\n const pixels = width * height;\n if (pixels === 0) return 0;\n let hot = 0;\n for (let i = 0; i < pixels; i++) {\n const o = i * 4;\n // Rec.601 luma, integer-ish — a specular blowout saturates all channels.\n const luma =\n 0.299 * (data[o] ?? 0) + 0.587 * (data[o + 1] ?? 0) + 0.114 * (data[o + 2] ?? 0);\n if (luma >= 252) hot++;\n }\n return hot / pixels;\n}\n\n/** Opposite-side length ratio of the quad (1 = fronto-parallel). */\nexport function quadTiltRatio(quad: DocQuad): number {\n const len = (a: { x: number; y: number }, b: { x: number; y: number }) =>\n Math.hypot(b.x - a.x, b.y - a.y);\n const top = len(quad.topLeft, quad.topRight);\n const bottom = len(quad.bottomLeft, quad.bottomRight);\n const left = len(quad.topLeft, quad.bottomLeft);\n const right = len(quad.topRight, quad.bottomRight);\n const h = Math.max(top, bottom) / Math.max(1e-6, Math.min(top, bottom));\n const v = Math.max(left, right) / Math.max(1e-6, Math.min(left, right));\n return Math.max(h, v);\n}\n\n/**\n * Judge one frame. `detectionMode` mirrors the gate: ID-1 quads carry\n * area/aspect/tilt semantics; ID-3 MRZ bands carry width-fraction semantics\n * (band rects are axis-aligned, so tilt/aspect checks are band-specific).\n */\nexport function analyzeDocFrame(input: {\n format: DocFormat;\n quad: DocQuad | null;\n frameWidth: number;\n frameHeight: number;\n measures: DocFrameMeasures;\n thresholds?: Partial<DocGateThresholds>;\n}): DocFrameAnalysis {\n const t = { ...DOC_GATE_V1_DEFAULTS, ...input.thresholds };\n const a = DOC_ANALYSIS_DEFAULTS;\n const { quad, frameWidth, frameHeight, measures } = input;\n const bandMode = input.format === \"ID-3\";\n\n let framing: FramingStatus = \"ok\";\n if (quad === null) {\n framing = \"no_document\";\n } else if (bandMode) {\n const bounds = quadBounds(quad);\n const widthFrac = frameWidth > 0 ? bounds.width / frameWidth : 0;\n const aspect = bounds.height > 0 ? bounds.width / bounds.height : 0;\n if (widthFrac < t.ID3_BAND_MIN_WIDTH_FRAC) framing = \"too_far\";\n else if (edgeClipped(quad, frameWidth, frameHeight, t.EDGE_CLIP_MARGIN_PX)) {\n framing = \"edge_clipped\";\n } else if (aspect < t.ID3_BAND_ASPECT_MIN || aspect > t.ID3_BAND_ASPECT_MAX) {\n framing = \"wrong_shape\";\n }\n } else {\n const areaFrac = quadAreaFrac(quad, frameWidth, frameHeight);\n const band = aspectBand(input.format);\n const bounds = quadBounds(quad);\n const aspect =\n Math.max(bounds.width, bounds.height) / Math.max(1e-6, Math.min(bounds.width, bounds.height));\n if (areaFrac < t.MIN_AREA_FRAC) framing = \"too_far\";\n else if (areaFrac > a.MAX_AREA_FRAC) framing = \"too_close\";\n else if (edgeClipped(quad, frameWidth, frameHeight, t.EDGE_CLIP_MARGIN_PX)) {\n framing = \"edge_clipped\";\n } else if (Math.abs(aspect - band.center) > band.tolerance) framing = \"wrong_shape\";\n else if (quadTiltRatio(quad) > a.TILT_MAX_SIDE_RATIO) framing = \"tilted\";\n }\n\n const lighting: LightingStatus =\n measures.exposure >= t.GUIDE_EXPOSURE\n ? \"ok\"\n : measures.meanLuma < (EXPOSURE_BAND[0] + EXPOSURE_BAND[1]) / 2\n ? \"too_dark\"\n : \"too_bright\";\n const blur: BlurStatus = measures.sharpness >= t.GUIDE_SHARPNESS ? \"ok\" : \"blurry\";\n const glare: GlareStatus =\n measures.specularFraction >= a.GLARE_MAX_SPECULAR_FRAC ? \"glare\" : \"ok\";\n\n return {\n framing,\n lighting,\n blur,\n glare,\n acceptable: framing === \"ok\" && lighting === \"ok\" && blur === \"ok\" && glare === \"ok\",\n };\n}\n\nfunction edgeClipped(\n quad: DocQuad,\n frameWidth: number,\n frameHeight: number,\n margin: number,\n): boolean {\n const pts = [quad.topLeft, quad.topRight, quad.bottomRight, quad.bottomLeft];\n return pts.some(\n (p) => p.x <= margin || p.y <= margin || p.x >= frameWidth - margin || p.y >= frameHeight - margin,\n );\n}\n","// Feedback aggregator (capture v2, Task-37 round 4) — the BlinkID-inspired\n// anti-flicker layer between per-frame analysis and the UI: each frame VOTES\n// for a feedback state; votes decay exponentially over a sliding window and\n// the DOMINANT state wins, but never before the current state's minimum\n// display duration has elapsed. Success states bypass voting entirely.\n//\n// 100% deterministic: the clock is an input (`nowMs`), the decay math is\n// closed-form — golden-testable tick sequences, no timers.\nimport type { DocFrameAnalysis } from \"./frame-analysis\";\n\n/** Feedback vocabulary (dcv2.* message keys on the hosted side). */\nexport type DocFeedbackKey =\n | \"sensing\"\n | \"too_far\"\n | \"too_close\"\n | \"edge_clipped\"\n | \"wrong_shape\"\n | \"tilted\"\n | \"too_dark\"\n | \"too_bright\"\n | \"blurry\"\n | \"glare\"\n | \"hold_still\"\n | \"processing\"\n | \"side_captured\"\n | \"captured\";\n\n/** Reticle rendering mode per feedback state (the stage maps to visuals). */\nexport type ReticleType = \"searching\" | \"coaching\" | \"locking\" | \"processing\" | \"flip\" | \"done\";\n\nexport interface DocFeedbackState {\n key: DocFeedbackKey;\n reticle: ReticleType;\n /** The state holds the UI at least this long (ms) before a switch. */\n minDurationMs: number;\n}\n\nexport const DOC_FEEDBACK_STATES: Readonly<Record<DocFeedbackKey, DocFeedbackState>> =\n Object.freeze({\n sensing: { key: \"sensing\", reticle: \"searching\", minDurationMs: 900 },\n too_far: { key: \"too_far\", reticle: \"coaching\", minDurationMs: 1400 },\n too_close: { key: \"too_close\", reticle: \"coaching\", minDurationMs: 1400 },\n edge_clipped: { key: \"edge_clipped\", reticle: \"coaching\", minDurationMs: 1400 },\n wrong_shape: { key: \"wrong_shape\", reticle: \"coaching\", minDurationMs: 1400 },\n tilted: { key: \"tilted\", reticle: \"coaching\", minDurationMs: 1400 },\n too_dark: { key: \"too_dark\", reticle: \"coaching\", minDurationMs: 1400 },\n too_bright: { key: \"too_bright\", reticle: \"coaching\", minDurationMs: 1400 },\n blurry: { key: \"blurry\", reticle: \"coaching\", minDurationMs: 1400 },\n glare: { key: \"glare\", reticle: \"coaching\", minDurationMs: 1400 },\n hold_still: { key: \"hold_still\", reticle: \"locking\", minDurationMs: 900 },\n processing: { key: \"processing\", reticle: \"processing\", minDurationMs: 800 },\n side_captured: { key: \"side_captured\", reticle: \"flip\", minDurationMs: 2600 },\n captured: { key: \"captured\", reticle: \"done\", minDurationMs: 800 },\n });\n\n/** Frame analysis → the feedback vote it casts (worst axis speaks). */\nexport function feedbackVoteOf(analysis: DocFrameAnalysis): DocFeedbackKey {\n if (analysis.framing === \"no_document\") return \"sensing\";\n if (analysis.framing === \"too_far\") return \"too_far\";\n if (analysis.framing === \"too_close\") return \"too_close\";\n if (analysis.framing === \"edge_clipped\") return \"edge_clipped\";\n if (analysis.framing === \"wrong_shape\") return \"wrong_shape\";\n if (analysis.framing === \"tilted\") return \"tilted\";\n if (analysis.lighting === \"too_dark\") return \"too_dark\";\n if (analysis.lighting === \"too_bright\") return \"too_bright\";\n if (analysis.glare === \"glare\") return \"glare\";\n if (analysis.blur === \"blurry\") return \"blurry\";\n return \"hold_still\";\n}\n\ninterface Vote {\n key: DocFeedbackKey;\n atMs: number;\n}\n\n/** Sliding vote window + exponential decay + per-state minimum hold. */\nexport class DocFeedbackAggregator {\n private votes: Vote[] = [];\n private current: DocFeedbackState = DOC_FEEDBACK_STATES.sensing;\n private currentSinceMs: number | null = null;\n\n constructor(\n private readonly windowMs = 2600,\n /** Per-second decay factor — recent frames outvote stale ones. */\n private readonly decayPerSecond = 0.35,\n ) {}\n\n reset(): void {\n this.votes = [];\n this.current = DOC_FEEDBACK_STATES.sensing;\n this.currentSinceMs = null;\n }\n\n /** Force a terminal/choreography state (capture fired, side flip, upload). */\n force(key: Extract<DocFeedbackKey, \"processing\" | \"side_captured\" | \"captured\">, nowMs: number): DocFeedbackState {\n this.votes = [];\n this.current = DOC_FEEDBACK_STATES[key];\n this.currentSinceMs = nowMs;\n return this.current;\n }\n\n /** Cast this frame's vote and return the (possibly held) winning state. */\n tick(vote: DocFeedbackKey, nowMs: number): DocFeedbackState {\n if (this.currentSinceMs === null) this.currentSinceMs = nowMs;\n this.votes.push({ key: vote, atMs: nowMs });\n this.votes = this.votes.filter((v) => nowMs - v.atMs <= this.windowMs);\n\n // Hold the current state through its minimum display duration.\n if (nowMs - this.currentSinceMs < this.current.minDurationMs) return this.current;\n\n const scores = new Map<DocFeedbackKey, number>();\n for (const v of this.votes) {\n const ageSeconds = (nowMs - v.atMs) / 1000;\n const weight = this.decayPerSecond ** ageSeconds; // 1 now → decays with age\n scores.set(v.key, (scores.get(v.key) ?? 0) + weight);\n }\n let winner: DocFeedbackKey = this.current.key;\n let best = -1;\n for (const [key, score] of scores) {\n if (score > best) {\n best = score;\n winner = key;\n }\n }\n if (winner !== this.current.key) {\n this.current = DOC_FEEDBACK_STATES[winner];\n this.currentSinceMs = nowMs;\n }\n return this.current;\n }\n}\n","// PORTED byte-identical from kyc-ibtikar/lib/faceCaptureV2/media.ts (calibration-pinned\n// capture contract — spec §6 / risk 1). Do NOT edit without a calibration re-validation.\n\n// Pure, framework-free helpers for FaceCaptureV2. No React, minimal DOM.\n\n/** MP4-first ladder: one container (H.264 MP4) covers iOS/macOS Safari + Chrome 130+.\n * WebM/VP9→VP8 only as the Firefox/older-Chromium fallback. */\nexport const MIME_CANDIDATES = [\n \"video/mp4;codecs=avc1.42E01E,mp4a.40.2\",\n \"video/mp4;codecs=avc1.42E01E\",\n \"video/mp4\",\n \"video/webm;codecs=vp9,opus\",\n \"video/webm;codecs=vp9\",\n \"video/webm;codecs=vp8,opus\",\n \"video/webm;codecs=vp8\",\n \"video/webm\",\n] as const;\n\nexport type CameraErrorKind =\n | \"permission\"\n | \"notfound\"\n | \"inuse\"\n | \"overconstrained\"\n | \"insecure\"\n | \"unsupported\"\n | \"generic\";\n\n/** First supported candidate, or \"\" to let the browser pick its own default. */\nexport function pickMimeType(): string {\n const MR = (globalThis as unknown as { MediaRecorder?: { isTypeSupported?: (t: string) => boolean } })\n .MediaRecorder;\n if (!MR || typeof MR.isTypeSupported !== \"function\") return \"\";\n return MIME_CANDIDATES.find((t) => MR.isTypeSupported!(t)) ?? \"\";\n}\n\n/** Default clip container when pickMimeType() === \"\" — NEVER .bin/octet-stream (REVIEW FIX 5).\n * Prefer the first webm in the ladder the browser most likely defaults to. */\nexport const DEFAULT_CLIP_MIME = \"video/webm\";\n\n/** Branch on err.name (never the message). TypeError ⇒ navigator.mediaDevices was undefined\n * (insecure/unsupported context) — surfaced as \"insecure\". */\nexport function mapGetUserMediaError(err: unknown): CameraErrorKind {\n if (err instanceof TypeError) return \"insecure\";\n const name = (err as { name?: string })?.name ?? \"\";\n switch (name) {\n case \"NotAllowedError\":\n case \"PermissionDeniedError\":\n return \"permission\";\n case \"NotFoundError\":\n case \"DevicesNotFoundError\":\n return \"notfound\";\n case \"NotReadableError\":\n case \"TrackStartError\":\n return \"inuse\";\n case \"OverconstrainedError\":\n case \"ConstraintNotSatisfiedError\":\n return \"overconstrained\";\n default:\n return \"generic\";\n }\n}\n\nexport function cameraPreflight(): \"INSECURE_CONTEXT\" | \"UNSUPPORTED\" | \"OK\" {\n const w = globalThis as unknown as { window?: { isSecureContext?: boolean }; navigator?: Navigator };\n if (typeof w.window !== \"undefined\" && w.window.isSecureContext === false)\n return \"INSECURE_CONTEXT\";\n const md = (w.navigator as Navigator | undefined)?.mediaDevices as\n | { getUserMedia?: unknown }\n | undefined;\n if (!md || typeof md.getUserMedia !== \"function\") return \"UNSUPPORTED\";\n return \"OK\";\n}\n\n/** iOS Safari (and any browser) may lack MediaRecorder entirely — detect BEFORE prompting\n * for the camera so we can fall back to the v1 single-photo path (REVIEW FIX 1). */\nexport function isMediaRecorderSupported(): boolean {\n const MR = (globalThis as unknown as { MediaRecorder?: { isTypeSupported?: unknown } }).MediaRecorder;\n return typeof MR !== \"undefined\" && typeof (MR as { isTypeSupported?: unknown }).isTypeSupported === \"function\";\n}\n\nexport const MAX_CLIP_BYTES = 8 * 1024 * 1024; // 8 MB hard cap (shared with the /api/liveness/v2 contract)\nexport function isClipTooLarge(blob: Blob): boolean {\n return blob.size > MAX_CLIP_BYTES;\n}\n\nexport function extForMime(mime: string): string {\n const m = (mime || \"\").toLowerCase();\n if (m.startsWith(\"image/jpeg\")) return \"jpg\";\n if (m.startsWith(\"video/mp4\")) return \"mp4\";\n if (m.startsWith(\"video/webm\")) return \"webm\";\n // Never .bin — default to the clip container we actually record (REVIEW FIX 5).\n return \"webm\";\n}\n\n/** Build the exact multipart body /api/liveness/v2 expects: fields `token`, files `clip` + `keyframe`.\n * Caller must NOT set Content-Type — the browser adds the boundary. */\nexport function buildLivenessV2FormData(args: {\n token: string;\n clip: Blob;\n keyframe: Blob;\n ts?: number;\n}): FormData {\n const { token, clip, keyframe } = args;\n const ts = args.ts ?? Date.now();\n const clipType = clip.type || DEFAULT_CLIP_MIME;\n const kfType = keyframe.type || \"image/jpeg\";\n const fd = new FormData();\n fd.append(\"token\", token);\n fd.append(\"clip\", new File([clip], `liveness-${ts}.${extForMime(clipType)}`, { type: clipType }));\n fd.append(\"keyframe\", new File([keyframe], `keyframe-${ts}.${extForMime(kfType)}`, { type: kfType }));\n return fd;\n}\n","// Device profiles (Task 9) — LOW/MID/HIGH from a boot probe, refined by the\n// first measured detect times. Profiles adapt DETECTION cost only (cadence,\n// downscale input width, animation richness): clip constraints are NOT here —\n// the 720p/2.5Mbps floor is global (locked decision 1) and lives in the v1\n// constraint builder both engines share.\n\nexport type DeviceClass = \"LOW\" | \"MID\" | \"HIGH\";\n\nexport interface DeviceProfile {\n /** Detection cadence — the scheduler's pace. */\n cadenceHz: number;\n /** Downscaled snapshot width handed to the detector. */\n inputWidth: number;\n /** Chrome hint: 'reduced' tones down ticks/breathe on LOW even without\n * prefers-reduced-motion. */\n animations: \"full\" | \"reduced\";\n}\n\nexport const DEVICE_PROFILES: Readonly<Record<DeviceClass, Readonly<DeviceProfile>>> =\n Object.freeze({\n LOW: Object.freeze({ cadenceHz: 5, inputWidth: 128, animations: \"reduced\" as const }),\n MID: Object.freeze({ cadenceHz: 8, inputWidth: 160, animations: \"full\" as const }),\n HIGH: Object.freeze({ cadenceHz: 10, inputWidth: 192, animations: \"full\" as const }),\n });\n\nexport interface DeviceProbe {\n cores: number;\n /** null where the UA hides it — iOS Safari NEVER exposes deviceMemory\n * (field lesson: a 2GB default classified every iPhone LOW). Unknown is\n * treated as NEUTRAL (4GB): never demotes to LOW on its own, never\n * promotes to HIGH; the dynamic profiler corrects truly slow devices. */\n memGB: number | null;\n /** WebAssembly SIMD available (informs wasm-tier expectations/telemetry). */\n simd: boolean;\n}\n\n/** Canonical WASM SIMD feature-test module (validates only where SIMD is\n * supported) — the standard wasm-feature-detect bytes. */\nconst SIMD_TEST_BYTES = new Uint8Array([\n 0, 97, 115, 109, 1, 0, 0, 0, 1, 5, 1, 96, 0, 1, 123, 3, 2, 1, 0, 10, 10, 1, 8, 0, 65, 0, 253,\n 15, 253, 98, 11,\n]);\n\nexport function probeDevice(): DeviceProbe {\n const nav = typeof navigator === \"undefined\" ? undefined : navigator;\n let simd = false;\n try {\n simd = typeof WebAssembly !== \"undefined\" && WebAssembly.validate(SIMD_TEST_BYTES);\n } catch {\n simd = false;\n }\n return {\n cores: nav?.hardwareConcurrency ?? 2,\n memGB: (nav as { deviceMemory?: number } | undefined)?.deviceMemory ?? null,\n simd,\n };\n}\n\n/** Static class: LOW (<4 cores or <3GB), HIGH (≥8 cores AND ≥6GB), else MID.\n * Unknown memory counts as a neutral 4GB (see DeviceProbe.memGB). */\nexport function classifyDevice(probe: DeviceProbe): DeviceClass {\n const memGB = probe.memGB ?? 4;\n if (probe.cores < 4 || memGB < 3) return \"LOW\";\n if (probe.cores >= 8 && memGB >= 6) return \"HIGH\";\n return \"MID\";\n}\n\nconst ORDER: DeviceClass[] = [\"LOW\", \"MID\", \"HIGH\"];\n\n/** Dynamic refinement: after the FIRST 10 measured detect ticks, a mean over\n * 70ms demotes straight to LOW; under 25ms promotes ONE class — at most one\n * adjustment ever (no oscillation). */\nexport class DeviceProfiler {\n private current: DeviceClass;\n private readonly samples: number[] = [];\n private adjusted = false;\n\n constructor(initial: DeviceClass) {\n this.current = initial;\n }\n\n get deviceClass(): DeviceClass {\n return this.current;\n }\n\n get profile(): DeviceProfile {\n return DEVICE_PROFILES[this.current];\n }\n\n record(detectMs: number): DeviceClass {\n if (this.adjusted || this.samples.length >= 10) return this.current;\n this.samples.push(detectMs);\n if (this.samples.length < 10) return this.current;\n this.adjusted = true;\n const mean = this.samples.reduce((sum, value) => sum + value, 0) / this.samples.length;\n if (mean > 70) {\n this.current = \"LOW\";\n } else if (mean < 25) {\n const index = ORDER.indexOf(this.current);\n this.current = ORDER[Math.min(ORDER.length - 1, index + 1)] ?? this.current;\n }\n return this.current;\n }\n}\n","// CaptureSessionDoc (Task 34) — the THIN document twin of CaptureSessionV3:\n// environment-facing camera, a 480px detect snapshot at the device profile's\n// cadence, DocGateV1 ticks, and on `ready` an UNCROPPED full-resolution still\n// (gate round 2: client-side quad cropping cut the MRZ when corners were off;\n// kyc-docs-v2 runs its own detector/warp — the client's job is timing, not\n// geometry). Same event contract SHAPE as CaptureSessionV3\n// (`statechange | checks | guidance | artifacts | error`) so hosts bind it\n// with the same hook pattern. Every effect is seam-injectable for tests; the\n// gate itself stays 100% deterministic (clock = tick input).\nimport { mapGetUserMediaError } from \"../media\";\nimport type { CaptureArtifacts, CaptureErrorKind, CaptureState } from \"../types\";\nimport { classifyDevice, type DeviceClass, probeDevice } from \"../v3/device-profile\";\nimport { exposure, meanLuma, sharpness } from \"../v3/frame-quality\";\nimport {\n DocFeedbackAggregator,\n type DocFeedbackState,\n feedbackVoteOf,\n} from \"./feedback-aggregator\";\nimport { analyzeDocFrame, type DocFrameAnalysis, specularFraction } from \"./frame-analysis\";\nimport type { DocFormat, DocSide } from \"./doc-catalog\";\nimport {\n DOC_DETECT_WIDTH,\n DocGateV1,\n type DocGateThresholds,\n type DocGateTick,\n type DocQuad,\n} from \"./doc-gate-v1\";\nimport { detectMrzBand } from \"./mrz-band\";\n\n/**\n * LAZY scanic load (route-budget contract): the vendored detector is ~39KiB gz\n * and must NOT ride the host's session-shell bundle — it is dynamically\n * imported on the FIRST detect tick (the camera-permission prompt gives the\n * fetch plenty of cover). Tests inject `opts.detect` and never touch this.\n */\nlet scanicDetect: ((image: ImageData) => Promise<DocQuad | null>) | null = null;\nasync function lazyScanicDetect(image: ImageData): Promise<DocQuad | null> {\n if (scanicDetect === null) {\n const module_ = await import(\"./detector-scanic\");\n scanicDetect = module_.detectQuad;\n }\n return scanicDetect(image);\n}\n\n/**\n * ID-3 detection (round 3): the MRZ stroke band, NOT page-edge quads — an\n * open booklet's page edges are white-on-white and defeat contour detection\n * (operator field finding, twice). The band rect becomes the gate's \"quad\"\n * (ID-3 band-mode geometry). Pure JS — no scanic on the passport path.\n */\nasync function mrzBandDetect(image: ImageData): Promise<DocQuad | null> {\n const band = detectMrzBand(image);\n if (band === null) return null;\n return {\n topLeft: { x: band.x, y: band.y },\n topRight: { x: band.x + band.width, y: band.y },\n bottomRight: { x: band.x + band.width, y: band.y + band.height },\n bottomLeft: { x: band.x, y: band.y + band.height },\n };\n}\n\n/**\n * Pre-fetch + cache the scanic chunk (call when the scan surface MOUNTS, before\n * the camera is even granted) so the first detect tick pays no chunk-fetch\n * latency. Fire-and-forget; failures fall back to the lazy path.\n */\nexport function warmDocDetector(): void {\n if (scanicDetect !== null) return;\n void import(\"./detector-scanic\")\n .then((module_) => {\n scanicDetect = module_.detectQuad;\n })\n .catch(() => undefined);\n}\n\n/** Doc detect cadence per device class — scanic @480px is ~3–8× a face tick,\n * so the doc loop paces slower than the face profiles (findings §1: 2–5 Hz). */\nexport const DOC_CADENCE_HZ: Readonly<Record<DeviceClass, number>> = Object.freeze({\n LOW: 3,\n MID: 5,\n HIGH: 6,\n});\n\nexport interface DocChecksPayload {\n engine: \"docv1\";\n /** Gate integrator 0..1 — the overlay ring. */\n p: number;\n plausible: boolean;\n stableTicks: number;\n quad: DocQuad | null;\n /** Detect-frame size the quad coordinates live in (overlay scaling). */\n frameWidth: number;\n frameHeight: number;\n /** Capture-v2 per-frame status vector (framing/lighting/blur/glare). */\n analysis: DocFrameAnalysis;\n}\n\n/** Artifacts: `keyframe` = the full-res still of the framed side (JPEG). */\nexport type DocArtifacts = CaptureArtifacts & { side?: DocSide };\n\nexport interface CaptureSessionDocEvents {\n statechange: { state: CaptureState };\n checks: DocChecksPayload;\n /** dcv1.* message KEY — hosts translate; never prose. Deduped. */\n guidance: { key: string };\n /** Capture-v2 AGGREGATED feedback (time-decay voted, min-duration held) —\n * the stage's message + reticle channel. Deduped on state key. */\n feedback: DocFeedbackState;\n artifacts: DocArtifacts;\n error: { kind: CaptureErrorKind; retryable: boolean };\n}\n\nexport interface CaptureSessionDocOptions {\n /** Host-owned <video playsInline muted>. */\n video: HTMLVideoElement;\n format?: DocFormat;\n /** Side label stamped on the artifacts event (recto→verso sequencing). */\n side?: DocSide;\n thresholds?: Partial<DocGateThresholds>;\n deviceClass?: DeviceClass;\n // ── seams (production defaults in parens) ─────────────────────────────────\n /** (navigator.mediaDevices.getUserMedia — environment camera) */\n getUserMedia?: (constraints: MediaStreamConstraints) => Promise<MediaStream>;\n /** (vendored scanic detectQuad) */\n detect?: (image: ImageData) => Promise<DocQuad | null>;\n /** (canvas downscale of the live video to the 480px detect frame) */\n grabDetectFrame?: (video: HTMLVideoElement, targetWidth: number) => ImageData | null;\n /** (full-res canvas still → JPEG blob + preview; quad passed for telemetry) */\n captureStill?: (\n video: HTMLVideoElement,\n quad: DocQuad,\n detectSize: { width: number; height: number },\n ) => Promise<{ blob: Blob; previewDataUrl: string }>;\n /** (performance.now) */\n now?: () => number;\n /** (setTimeout/clearTimeout) — the cadence pacer. */\n setTimer?: (fn: () => void, ms: number) => ReturnType<typeof setTimeout>;\n clearTimer?: (id: ReturnType<typeof setTimeout>) => void;\n}\n\ntype Handler<K extends keyof CaptureSessionDocEvents> = (\n payload: CaptureSessionDocEvents[K],\n) => void;\n\nexport class CaptureSessionDoc {\n private readonly opts: CaptureSessionDocOptions;\n private readonly gate: DocGateV1;\n private readonly cadenceMs: number;\n private readonly handlers = new Map<string, Set<(payload: never) => void>>();\n private stream: MediaStream | null = null;\n private timer: ReturnType<typeof setTimeout> | null = null;\n private state: CaptureState = \"idle\";\n private lastGuidance: string | null = null;\n private attempt = 0;\n private capturing = false;\n private readonly feedback = new DocFeedbackAggregator();\n private lastFeedbackKey: string | null = null;\n\n constructor(opts: CaptureSessionDocOptions) {\n this.opts = opts;\n this.gate = new DocGateV1(opts.format ?? \"ID-1\", opts.thresholds);\n const deviceClass = opts.deviceClass ?? classifyDevice(probeDevice());\n this.cadenceMs = 1000 / DOC_CADENCE_HZ[deviceClass];\n }\n\n on<K extends keyof CaptureSessionDocEvents>(event: K, handler: Handler<K>): () => void {\n let set = this.handlers.get(event);\n if (!set) {\n set = new Set();\n this.handlers.set(event, set);\n }\n set.add(handler as (payload: never) => void);\n return () => set?.delete(handler as (payload: never) => void);\n }\n\n private emit<K extends keyof CaptureSessionDocEvents>(\n event: K,\n payload: CaptureSessionDocEvents[K],\n ): void {\n for (const handler of [...(this.handlers.get(event) ?? [])]) {\n (handler as Handler<K>)(payload);\n }\n }\n\n async start(): Promise<void> {\n const attempt = ++this.attempt;\n this.gate.reset();\n this.feedback.reset();\n this.lastFeedbackKey = null;\n this.lastGuidance = null;\n this.capturing = false;\n this.setState(\"preflight\");\n try {\n const getUserMedia =\n this.opts.getUserMedia ??\n ((constraints: MediaStreamConstraints) =>\n navigator.mediaDevices.getUserMedia(constraints));\n this.setState(\"acquiring\");\n this.stream = await getUserMedia({\n audio: false,\n video: {\n facingMode: { ideal: \"environment\" },\n width: { ideal: 1920 },\n height: { ideal: 1080 },\n },\n });\n if (attempt !== this.attempt) {\n for (const track of this.stream.getTracks()) track.stop();\n return;\n }\n this.opts.video.srcObject = this.stream;\n await this.opts.video.play().catch(() => undefined);\n this.setState(\"positioning\");\n this.scheduleTick(attempt);\n } catch (err) {\n const kind = mapGetUserMediaError(err);\n this.setState(\"error\");\n this.emit(\"error\", { kind, retryable: true });\n }\n }\n\n /** Restart the gate for another side / a retake (same stream). */\n rearm(side?: DocSide): void {\n if (side !== undefined) this.opts.side = side;\n this.gate.reset();\n this.feedback.reset();\n this.lastFeedbackKey = null;\n this.lastGuidance = null;\n this.capturing = false;\n if (this.state === \"captured\") {\n this.setState(\"positioning\");\n this.scheduleTick(this.attempt);\n }\n }\n\n destroy(): void {\n this.attempt += 1;\n if (this.timer !== null) (this.opts.clearTimer ?? clearTimeout)(this.timer);\n this.timer = null;\n if (this.stream) for (const track of this.stream.getTracks()) track.stop();\n this.stream = null;\n this.opts.video.srcObject = null;\n }\n\n private setState(state: CaptureState): void {\n this.state = state;\n this.emit(\"statechange\", { state });\n }\n\n private scheduleTick(attempt: number): void {\n const setTimer = this.opts.setTimer ?? setTimeout;\n this.timer = setTimer(() => void this.tick(attempt), this.cadenceMs);\n }\n\n private async tick(attempt: number): Promise<void> {\n if (attempt !== this.attempt || this.state !== \"positioning\" || this.capturing) return;\n const now = this.opts.now ?? (() => performance.now());\n const grab = this.opts.grabDetectFrame ?? defaultGrabDetectFrame;\n const detect =\n this.opts.detect ??\n ((this.opts.format ?? \"ID-1\") === \"ID-3\" ? mrzBandDetect : lazyScanicDetect);\n\n const frame = grab(this.opts.video, DOC_DETECT_WIDTH);\n if (frame === null) {\n this.scheduleTick(attempt);\n return;\n }\n let quad: DocQuad | null = null;\n try {\n quad = await detect(frame);\n } catch {\n quad = null; // a detector hiccup is a no-doc tick, never a crash\n }\n if (attempt !== this.attempt) return;\n\n const crop = quad !== null ? cropQuadRegion(frame, quad) : frame;\n const atMs = now();\n const measures = {\n sharpness: sharpness(crop),\n exposure: exposure(crop),\n meanLuma: meanLuma(crop),\n specularFraction: specularFraction(crop),\n };\n const analysis = analyzeDocFrame({\n format: this.opts.format ?? \"ID-1\",\n quad,\n frameWidth: frame.width,\n frameHeight: frame.height,\n measures,\n ...(this.opts.thresholds !== undefined ? { thresholds: this.opts.thresholds } : {}),\n });\n const tick = this.gate.tick({\n timestampMs: atMs,\n quad,\n quality: measures,\n frameWidth: frame.width,\n frameHeight: frame.height,\n });\n this.emit(\"checks\", {\n engine: \"docv1\",\n p: tick.p,\n plausible: tick.plausible,\n stableTicks: tick.stableTicks,\n quad: tick.quad,\n frameWidth: frame.width,\n frameHeight: frame.height,\n analysis,\n });\n // Capture-v2 feedback: time-decay voted + min-duration held (anti-flicker).\n const feedbackState = this.feedback.tick(feedbackVoteOf(analysis), atMs);\n if (feedbackState.key !== this.lastFeedbackKey) {\n this.lastFeedbackKey = feedbackState.key;\n this.emit(\"feedback\", feedbackState);\n }\n if (tick.guidanceKey !== this.lastGuidance) {\n this.lastGuidance = tick.guidanceKey;\n this.emit(\"guidance\", { key: tick.guidanceKey });\n }\n\n if (tick.ready && quad !== null) {\n const processing = this.feedback.force(\"processing\", atMs);\n this.lastFeedbackKey = processing.key;\n this.emit(\"feedback\", processing);\n await this.fire(attempt, quad, {\n width: frame.width,\n height: frame.height,\n tickSharpness: measures.sharpness,\n });\n return;\n }\n this.scheduleTick(attempt);\n }\n\n /**\n * BEST-FRAME capture window (capture-v2): the first ready tick captures a\n * candidate immediately, then up to CAPTURE_EXTRA_CANDIDATES more stills are\n * taken at CAPTURE_CANDIDATE_SPACING_MS while the user holds — each scored\n * by the live detect-tick sharpness at its capture moment — and the SHARPEST\n * wins. Beats first-acceptable-frame capture without decoding stills.\n */\n private async fire(\n attempt: number,\n quad: DocQuad,\n detectSize: { width: number; height: number; tickSharpness: number },\n ): Promise<void> {\n this.capturing = true;\n const capture = this.opts.captureStill ?? defaultCaptureStill;\n const grab = this.opts.grabDetectFrame ?? defaultGrabDetectFrame;\n const setTimer = this.opts.setTimer ?? setTimeout;\n const size = { width: detectSize.width, height: detectSize.height };\n try {\n let best = {\n still: await capture(this.opts.video, quad, size),\n sharpness: detectSize.tickSharpness,\n };\n for (let i = 0; i < CAPTURE_EXTRA_CANDIDATES; i++) {\n await new Promise<void>((resolve) => {\n setTimer(() => resolve(), CAPTURE_CANDIDATE_SPACING_MS);\n });\n if (attempt !== this.attempt) return;\n const frame = grab(this.opts.video, DOC_DETECT_WIDTH);\n if (frame === null) continue;\n const candidateSharpness = sharpness(cropQuadRegion(frame, quad));\n if (candidateSharpness > best.sharpness * CAPTURE_IMPROVEMENT_MIN_RATIO) {\n const still = await capture(this.opts.video, quad, size);\n if (attempt !== this.attempt) return;\n best = { still, sharpness: candidateSharpness };\n }\n }\n if (attempt !== this.attempt) return;\n this.setState(\"captured\");\n this.emit(\"artifacts\", {\n keyframe: best.still.blob,\n previewDataUrl: best.still.previewDataUrl,\n ...(this.opts.side !== undefined ? { side: this.opts.side } : {}),\n });\n } catch {\n if (attempt !== this.attempt) return;\n // Still capture failed (canvas/encode) — rearm the gate and keep coaching.\n this.capturing = false;\n this.gate.reset();\n this.scheduleTick(attempt);\n }\n }\n}\n\n/** Best-frame window: 2 extra candidates, 260ms apart, ≥8% sharper to replace. */\nexport const CAPTURE_EXTRA_CANDIDATES = 2;\nexport const CAPTURE_CANDIDATE_SPACING_MS = 260;\nconst CAPTURE_IMPROVEMENT_MIN_RATIO = 1.08;\n\n/** Downscale the live video to the detect width (aspect preserved). */\nfunction defaultGrabDetectFrame(video: HTMLVideoElement, targetWidth: number): ImageData | null {\n const vw = video.videoWidth;\n const vh = video.videoHeight;\n if (vw === 0 || vh === 0) return null;\n const scale = Math.min(1, targetWidth / vw);\n const width = Math.round(vw * scale);\n const height = Math.round(vh * scale);\n const canvas = document.createElement(\"canvas\");\n canvas.width = width;\n canvas.height = height;\n const context = canvas.getContext(\"2d\", { willReadFrequently: true });\n if (context === null) return null;\n context.drawImage(video, 0, 0, width, height);\n return context.getImageData(0, 0, width, height);\n}\n\n/**\n * Capture the FULL-RES frame (gate-timed, UNCROPPED — operator gate round 2):\n * client-side quad cropping cut the MRZ whenever the detected corners were\n * slightly off, and kyc-docs-v2 runs its OWN detector/warp on the server —\n * the client's job is TIMING (fire when framed/steady), not geometry. The\n * quad/detectSize params stay in the seam signature for telemetry/tests.\n */\nasync function defaultCaptureStill(\n video: HTMLVideoElement,\n _quad: DocQuad,\n _detectSize: { width: number; height: number },\n): Promise<{ blob: Blob; previewDataUrl: string }> {\n const canvas = document.createElement(\"canvas\");\n canvas.width = Math.max(1, video.videoWidth);\n canvas.height = Math.max(1, video.videoHeight);\n const context = canvas.getContext(\"2d\");\n if (context === null) throw new Error(\"2d context unavailable\");\n context.drawImage(video, 0, 0, canvas.width, canvas.height);\n const blob = await new Promise<Blob>((resolve, reject) => {\n canvas.toBlob((b) => (b ? resolve(b) : reject(new Error(\"toBlob failed\"))), \"image/jpeg\", 0.92);\n });\n return { blob, previewDataUrl: canvas.toDataURL(\"image/jpeg\", 0.85) };\n}\n\n/** Quad-bbox crop of the DETECT frame — the quality measures run on this. */\nfunction cropQuadRegion(frame: ImageData, quad: DocQuad): ImageData {\n const xs = [quad.topLeft.x, quad.topRight.x, quad.bottomRight.x, quad.bottomLeft.x];\n const ys = [quad.topLeft.y, quad.topRight.y, quad.bottomRight.y, quad.bottomLeft.y];\n const x1 = Math.max(0, Math.floor(Math.min(...xs)));\n const y1 = Math.max(0, Math.floor(Math.min(...ys)));\n const x2 = Math.min(frame.width, Math.ceil(Math.max(...xs)));\n const y2 = Math.min(frame.height, Math.ceil(Math.max(...ys)));\n const width = Math.max(1, x2 - x1);\n const height = Math.max(1, y2 - y1);\n const data = new Uint8ClampedArray(width * height * 4);\n for (let row = 0; row < height; row++) {\n const src = ((y1 + row) * frame.width + x1) * 4;\n data.set(frame.data.subarray(src, src + width * 4), row * width * 4);\n }\n return { data, width, height, colorSpace: frame.colorSpace } as ImageData;\n}\n","// Shared capture helpers — used by BOTH the (now sole) v3 engine and the\n// hosted gate-debug overlay. Extracted from the former v1 capture-session.ts\n// when the v1 engine was removed: the camera constraint tier + the mobile\n// heuristic are engine-agnostic, and the gate-geometry factors feed the\n// hosted debug overlay's tolerance rings. Zero React, calibration-pinned.\n\n/** getUserMedia constraint tier — 720p-class on every device since 2026-07-06.\n * The v2 FAS-CLIP liveness head loses its texture cues below ~720p: the SAME\n * genuine clip scores heads 0.0001 at 720x1280 vs 0.355 at the old 480x360\n * mobile tier, which pushed real users into review (first observed live on\n * staging 2026-07-06; falsified on corpus clips the same day). Dimensions are\n * sensor-relative (landscape); mobile browsers deliver portrait via rotation\n * metadata, which the liveness service's decoder applies (cv2\n * ORIENTATION_AUTO). `isMobile` is kept for call-site compat and future\n * divergence — both tiers are 720p today. Bitrate pairs with VIDEO_BPS in\n * clip-recorder.ts (2.5 Mbps). */\nexport function buildCaptureConstraints(\n isMobile: boolean,\n facingMode: \"user\" | \"environment\",\n): MediaStreamConstraints {\n void isMobile;\n return {\n video: {\n width: { ideal: 1280, max: 1280 },\n height: { ideal: 720, max: 720 },\n facingMode: facingMode,\n frameRate: { ideal: 24, max: 30 },\n },\n audio: false,\n };\n}\n\n/** v1 mobile heuristic (FaceCaptureV2.tsx L216-224). */\nexport function detectIsMobile(): boolean {\n if (typeof window === \"undefined\" || typeof navigator === \"undefined\") return false;\n return (\n window.innerWidth <= 768 ||\n /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(\n String(navigator.userAgent ?? \"\"),\n )\n );\n}\n\n// ── gate geometry factors ─────────────────────────────────────────────────────\n// The calibration-pinned gate math the hosted `?debug=gate` overlay derives its\n// tolerance rings from (lib/gate-geometry-constants.ts). Kept exported here after\n// the v1 FaceGate was removed so the overlay never restates them as literals.\n\n/** Gate radius as a fraction of the guidance circle (v1 L501: circleSize × 0.45). */\nexport const CIRCLE_RADIUS_FACTOR = 0.45;\n/** `inCircle` tolerance as a fraction of the gate radius (v1 L508: r × 0.9). */\nexport const IN_CIRCLE_FACTOR = 0.9;\n/** `centered` tolerance as a fraction of the gate radius (v1 L509: r × 0.4). */\nexport const CENTERED_FACTOR = 0.4;\n","// De-hooked port of kyc-ibtikar/lib/faceCaptureV2/useClipRecorder.ts (calibration-pinned\n// capture contract — spec §6 / risk 1). Framework-free class: useRef → private fields,\n// useCallback(start) → record(), stopAndCleanup + the unmount useEffect → stop().\n// Behavior is the v1 hook's, VERBATIM (iOS workarounds included). Source line references\n// (kyc-ibtikar/lib/faceCaptureV2/useClipRecorder.ts):\n// - constants CLIP_MS / TIMESLICE_MS / STOP_GRACE_MS / VIDEO_BPS ............ L10-13\n// - ClipError(kind, msg?) .................................................. L15-21\n// - guarded double MediaRecorder construction (REVIEW FIX 1) ............... L47-63\n// - single-settle guard + timer clearing ................................... L66-71\n// - finalize: Blob(type = recorder.mimeType || picked || DEFAULT_CLIP_MIME)\n// + post-hoc size-cap check .............................................. L73-82\n// - incremental 8MB cap enforcement on dataavailable (REVIEW FIX 7) ........ L84-100\n// - onstop → finalize, onerror → generic, guarded start(TIMESLICE_MS) ...... L101-109\n// - hard stop at CLIP_MS + iOS stop-grace finalize (REVIEW FIX 3) .......... L111-124\n// - teardown: clear timers, stop recorder, stop ALL tracks (REVIEW FIX 8) .. L128-145\n// V2 additions on top of the verbatim behavior (both zero-impact on clip bytes, both\n// required because a class instance outlives one recording where v1's hook state was\n// remounted fresh): a re-entrancy guard in record(), and clearing stale timers when a\n// new recording starts. See the record() JSDoc.\n// Do NOT edit without a calibration re-validation.\nimport {\n pickMimeType,\n isClipTooLarge,\n MAX_CLIP_BYTES,\n DEFAULT_CLIP_MIME,\n type CameraErrorKind,\n} from \"./media\";\n\nexport const CLIP_MS = 2500; // 2.5s, within the 2.0–3.0s target window\nexport const TIMESLICE_MS = 1000; // periodic dataavailable — iOS reliability workaround\nexport const STOP_GRACE_MS = 1500; // iOS: if onstop never fires, finalize from chunks\n// 2.5 Mbps pairs with the 720p capture tier (capture-session.ts): 1.5 Mbps at\n// 720p over-compresses exactly the texture the FAS-CLIP head needs. ~0.8MB per\n// 2.5s clip — well under the 8MB client cap / 15MB server caps.\nexport const VIDEO_BPS = 2_500_000;\n\nexport type ClipErrorKind = CameraErrorKind | \"cliptoolarge\";\n\nexport class ClipError extends Error {\n kind: ClipErrorKind;\n constructor(kind: ClipErrorKind, msg?: string) {\n super(msg ?? kind);\n this.kind = kind;\n }\n}\n\nexport interface ClipResult {\n blob: Blob;\n /** Container mime the clip was finalized with (recorder.mimeType || picked || DEFAULT_CLIP_MIME). */\n mimeType: string;\n}\n\nexport class ClipRecorder {\n private recorder: MediaRecorder | null = null;\n private stream: MediaStream | null = null; // own field so teardown can stop tracks (REVIEW FIX 8)\n private chunks: Blob[] = [];\n private bytes = 0;\n private hardStopTimer: ReturnType<typeof setTimeout> | null = null;\n private graceTimer: ReturnType<typeof setTimeout> | null = null;\n private settled = false;\n\n private clearTimers(): void {\n if (this.hardStopTimer) clearTimeout(this.hardStopTimer);\n if (this.graceTimer) clearTimeout(this.graceTimer);\n this.hardStopTimer = null;\n this.graceTimer = null;\n }\n\n /** Records CLIP_MS of the stream. Resolves with the clip blob + its container mime;\n * rejects with ClipError. Behavior contract is the v1 hook's `start`, verbatim\n * (iOS workarounds included).\n *\n * ONE RECORDING AT A TIME: chunk/byte/timer state is shared per instance, so a\n * second record() while one is in flight rejects ClipError(\"generic\") instead of\n * corrupting the in-flight clip. (v2 guard — v1's hook was gated by its owning\n * component; a class API invites reuse. Zero impact on clip bytes.)\n *\n * `onStopped` (optional) fires ONCE the moment the CLIP_MS recording window\n * elapses (the hard-stop), BEFORE finalize — which on iOS can lag up to\n * STOP_GRACE_MS while onstop flushes the last chunk. It lets the host freeze\n * the display on the already-captured keyframe the instant recording ends,\n * instead of waiting for the blob. PURE NOTIFICATION — it does not touch\n * timers, chunks, or the finalize path, so it is calibration-neutral (no\n * effect on clip bytes). Never fires on a rejected capture (error /\n * cliptoolarge settle before the hard-stop and clear the timer). */\n record(stream: MediaStream, onStopped?: () => void): Promise<ClipResult> {\n if (this.recorder && !this.settled) {\n return Promise.reject(\n new ClipError(\n \"generic\",\n \"record() called while a recording is in flight — ClipRecorder handles one recording at a time\",\n ),\n );\n }\n this.recorder = null; // so a failed construction below never blocks a retry\n // De-hooking correction (zero impact on clip bytes): v1 got fresh refs per hook\n // mount, so a previous recording's post-settle grace timer (the hard-stop callback\n // arms it AFTER settle cleared timers — v1-verbatim) could never leak into a new\n // one. On a reused instance it would fire mid-flight, settle the fresh state, and\n // clear the new hard-stop timer — so drop stale timers before starting.\n this.clearTimers();\n this.chunks = [];\n this.bytes = 0;\n this.settled = false;\n this.stream = stream;\n const picked = pickMimeType();\n\n return new Promise<ClipResult>((resolve, reject) => {\n // Guarded construction — iOS Safari may lack MediaRecorder entirely (REVIEW FIX 1).\n let recorder: MediaRecorder;\n try {\n recorder = new MediaRecorder(\n stream,\n picked\n ? { mimeType: picked, videoBitsPerSecond: VIDEO_BPS }\n : { videoBitsPerSecond: VIDEO_BPS },\n );\n } catch {\n try {\n recorder = new MediaRecorder(stream); // last resort: browser defaults\n } catch {\n reject(new ClipError(\"unsupported\"));\n return;\n }\n }\n this.recorder = recorder;\n\n const settle = (fn: () => void) => {\n if (this.settled) return;\n this.settled = true;\n this.clearTimers();\n fn();\n };\n\n const finalize = () =>\n settle(() => {\n const type = recorder.mimeType || picked || DEFAULT_CLIP_MIME;\n const blob = new Blob(this.chunks, { type });\n if (isClipTooLarge(blob)) {\n reject(new ClipError(\"cliptoolarge\"));\n return;\n }\n resolve({ blob, mimeType: type });\n });\n\n recorder.ondataavailable = (e: BlobEvent) => {\n if (e.data && e.data.size) {\n this.chunks.push(e.data);\n this.bytes += e.data.size;\n // Enforce the 8MB cap INCREMENTALLY — stop + reject as soon as exceeded (REVIEW FIX 7).\n if (this.bytes > MAX_CLIP_BYTES) {\n settle(() => {\n try {\n if (recorder.state !== \"inactive\") recorder.stop();\n } catch {\n /* noop */\n }\n reject(new ClipError(\"cliptoolarge\"));\n });\n }\n }\n };\n recorder.onstop = finalize;\n recorder.onerror = () => settle(() => reject(new ClipError(\"generic\")));\n\n try {\n recorder.start(TIMESLICE_MS);\n } catch {\n settle(() => reject(new ClipError(\"generic\")));\n return;\n }\n\n // Hard stop at CLIP_MS; gate on state, not on frame count.\n this.hardStopTimer = setTimeout(() => {\n // Recording window elapsed — the clip is DONE. Notify BEFORE finalize\n // (which may lag on iOS) so the host can freeze on the keyframe now.\n // Guarded by `settled`: an error/cliptoolarge before the hard-stop has\n // already cleared this timer, so this only runs for a real stop.\n if (!this.settled) onStopped?.();\n if (recorder.state !== \"inactive\") {\n try {\n recorder.stop();\n } catch {\n finalize();\n }\n // iOS safety-net: onstop may never fire — finalize from chunks (REVIEW FIX 3).\n this.graceTimer = setTimeout(finalize, STOP_GRACE_MS);\n } else {\n finalize();\n }\n }, CLIP_MS);\n });\n }\n\n /** Idempotent teardown: stop recorder + ALL tracks (v1 `stopAndCleanup` + the unmount\n * effect). Optional `stream` override mirrors v1's `stopAndCleanup(stream?)`.\n *\n * MID-RECORDING SEMANTICS (verbatim v1): calling stop() while a record() is in\n * flight may LATER resolve the pending promise with a TRUNCATED clip (recorder.stop()\n * fires onstop → finalize from whatever chunks arrived so far), or — because this\n * method clears the hard-stop/grace timers — never settle it at all if onstop never\n * fires (the iOS grace path has been torn down). Callers MUST NOT treat a resolution\n * arriving after stop() as a full CLIP_MS clip, and must not await a record()\n * promise past stop() without their own timeout. (Task 4's CaptureSession owns\n * sequencing on top of this contract.) */\n stop(stream?: MediaStream | null): void {\n this.clearTimers();\n const rec = this.recorder;\n if (rec && rec.state !== \"inactive\") {\n try {\n rec.stop();\n } catch {\n /* noop */\n }\n }\n this.recorder = null;\n const s = stream ?? this.stream;\n s?.getTracks().forEach((t) => t.stop());\n this.stream = null;\n }\n}\n","// PORTED byte-identical from kyc-ibtikar/lib/faceCaptureV2/keyframe.ts (calibration-pinned\n// capture contract — spec §6 / risk 1). Do NOT edit without a calibration re-validation.\n\n// Grab ONE mirrored frontal keyframe from the live <video> into a JPEG Blob (a file part,\n// not a dataURL). Mirror matches the selfie preview (front camera), same as FaceCapture v1.\nexport function captureMirroredKeyframe(\n video: HTMLVideoElement,\n canvas: HTMLCanvasElement,\n quality = 0.92,\n): Promise<Blob> {\n return new Promise((resolve, reject) => {\n const w = video.videoWidth;\n const h = video.videoHeight;\n if (!w || !h) {\n reject(new Error(\"video-not-ready\"));\n return;\n }\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n reject(new Error(\"no-2d-context\"));\n return;\n }\n canvas.width = w;\n canvas.height = h;\n ctx.scale(-1, 1);\n ctx.drawImage(video, -w, 0);\n canvas.toBlob(\n (blob) => (blob ? resolve(blob) : reject(new Error(\"empty-keyframe\"))),\n \"image/jpeg\",\n quality,\n );\n });\n}\n","// BlazeFace short-range tier (Task 7) — MediaPipe tasks-vision FaceDetector,\n// the modern default: strong on large/close faces, ~15–40ms on low-end\n// WASM+SIMD. tasks-vision is imported LAZILY (only when this tier is\n// selected) and every asset is SELF-HOSTED under the v3 asset base (hosted\n// CSP is connect-src 'self' — no CDN): the wasm fileset via\n// FilesetResolver.forVisionTasks(base) and the model at\n// `${base}/blaze_face_short_range.tflite` (synced by\n// identity-hosted/scripts/sync-models-v3.mjs, sha256-manifested).\n//\n// DELEGATE = 'CPU' (2026-07-09, capture-v3 hardening — the load-bearing fix):\n// tasks-vision defaults `baseOptions.delegate` to the WebGL/GPU delegate,\n// which HANGS on iOS Safari — every field capture blew the 10s init deadline\n// (`blaze:blaze_init_timeout`) and silently fell to the deprecated face-api\n// floor at ~2.4fps. BlazeFace short-range is tiny (~229 KB) and fast on the\n// WASM+SIMD CPU delegate, so we pin CPU UNCONDITIONALLY: reliability across\n// iOS Safari + Chrome beats the marginal desktop-GPU speedup (and the GPU\n// path is exactly the bug). A GPU-first-with-CPU-fallback dance would only\n// re-introduce the hang risk inside the init budget for no real win.\nimport { type Detector, type FaceObservation, intrinsicSize, toStreamPixels } from \"./detector\";\n\n/** createFromOptions must resolve within this window or the ladder falls\n * through with `blaze_init_timeout` (overridable via CreateDetectorOptions).\n * Raised 5s→10s: on iOS Safari the COLD wasm SIMD compile of tasks-vision can\n * exceed 5s on the FIRST (unwarmed) capture. Since the face-api floor was\n * dropped (2026-07-09), blowing this deadline is now a HARD capture failure\n * (error{kind:'models'} — retryable), not a silent degrade, so the CPU\n * delegate above (which makes init actually complete on iOS) is what keeps\n * this deadline reachable. The hosted warm path\n * (identity-hosted/lib/warm-models.ts) pre-warms this tier in idle time so\n * capture usually reuses a hot instance; this larger deadline only covers the\n * un-warmed fallback (Data-Saver, deep-link straight to liveness). */\nexport const BLAZE_INIT_TIMEOUT_MS = 10_000;\n\ninterface TasksVisionDetection {\n boundingBox?: { originX: number; originY: number; width: number; height: number };\n categories: Array<{ score: number }>;\n /** NORMALIZED to the input image (0..1) — tasks-vision docs; index 0 =\n * right eye, 1 = left eye (SUBJECT perspective). We re-order by image-x\n * (the FaceObservation convention), so the doc order is informative only. */\n keypoints?: Array<{ x: number; y: number }>;\n}\n\ninterface TasksVisionFaceDetector {\n detect(source: unknown): { detections: TasksVisionDetection[] };\n close(): void;\n}\n\nexport class BlazeDetector implements Detector {\n readonly tier = \"blaze\" as const;\n readonly fallbackReason?: string;\n private readonly inner: TasksVisionFaceDetector;\n\n private constructor(inner: TasksVisionFaceDetector, fallbackReason?: string) {\n this.inner = inner;\n if (fallbackReason !== undefined) this.fallbackReason = fallbackReason;\n }\n\n static async create(assetBaseUrl: string, fallbackReason?: string): Promise<BlazeDetector> {\n const vision = await import(\"@mediapipe/tasks-vision\");\n const fileset = await vision.FilesetResolver.forVisionTasks(assetBaseUrl);\n const inner = (await vision.FaceDetector.createFromOptions(fileset, {\n baseOptions: {\n modelAssetPath: `${assetBaseUrl}/blaze_face_short_range.tflite`,\n // CPU delegate — the iOS-Safari-safe path (see header). NEVER 'GPU'.\n delegate: \"CPU\",\n },\n runningMode: \"IMAGE\",\n })) as unknown as TasksVisionFaceDetector;\n return new BlazeDetector(inner, fallbackReason);\n }\n\n async detect(\n source: CanvasImageSource,\n sourceWidth: number,\n sourceHeight: number,\n ): Promise<FaceObservation | null> {\n let detections: TasksVisionDetection[];\n try {\n detections = this.inner.detect(source).detections;\n } catch {\n return null; // never rejects mid-loop\n }\n const best = pickMostConfident(detections);\n if (best?.boundingBox === undefined) return null;\n const size = intrinsicSize(source);\n const eyes = extractEyes(best.keypoints, size);\n const observation: FaceObservation = {\n box: {\n x: best.boundingBox.originX,\n y: best.boundingBox.originY,\n width: best.boundingBox.width,\n height: best.boundingBox.height,\n },\n ...(eyes !== undefined ? { eyes } : {}),\n score: best.categories[0]?.score ?? 0,\n };\n return toStreamPixels(observation, source, sourceWidth, sourceHeight);\n }\n\n destroy(): void {\n try {\n this.inner.close();\n } catch {\n // wasm teardown failures are inert\n }\n }\n}\n\nfunction pickMostConfident(detections: TasksVisionDetection[]): TasksVisionDetection | undefined {\n let best: TasksVisionDetection | undefined;\n let bestScore = -1;\n for (const detection of detections) {\n const score = detection.categories[0]?.score ?? 0;\n if (score > bestScore) {\n best = detection;\n bestScore = score;\n }\n }\n return best;\n}\n\n/** Keypoints 0/1 (the eye pair) — normalized → SOURCE px, ordered by image-x. */\nfunction extractEyes(\n keypoints: Array<{ x: number; y: number }> | undefined,\n size: { width: number; height: number },\n): FaceObservation[\"eyes\"] | undefined {\n const a = keypoints?.[0];\n const b = keypoints?.[1];\n if (a === undefined || b === undefined) return undefined;\n const toSource = (p: { x: number; y: number }) => ({ x: p.x * size.width, y: p.y * size.height });\n const [pa, pb] = [toSource(a), toSource(b)];\n return pa.x <= pb.x ? { left: pa, right: pb } : { left: pb, right: pa };\n}\n","// Native FaceDetector tier (Task 6) — the Shape Detection API: free,\n// hardware-backed where implemented (Chrome/Android, some WebViews). Probed\n// with a 1-frame smoke detect because several browsers EXPOSE the constructor\n// but throw `Face detection service unavailable` at runtime.\nimport { type Detector, type FaceObservation, toStreamPixels } from \"./detector\";\n\ninterface NativeLandmark {\n type: string;\n locations: Array<{ x: number; y: number }>;\n}\n\ninterface NativeDetectedFace {\n boundingBox: { x: number; y: number; width: number; height: number };\n landmarks?: NativeLandmark[];\n}\n\nexport interface NativeFaceDetectorLike {\n detect(source: CanvasImageSource): Promise<NativeDetectedFace[]>;\n}\n\ntype NativeGlobal = typeof globalThis & {\n FaceDetector?: new (options: { fastMode: boolean; maxDetectedFaces: number }) => NativeFaceDetectorLike;\n};\n\nfunction smokeSource(): CanvasImageSource {\n if (typeof OffscreenCanvas === \"function\") return new OffscreenCanvas(2, 2);\n const canvas = document.createElement(\"canvas\");\n canvas.width = 2;\n canvas.height = 2;\n return canvas;\n}\n\n/** Constructor + 1-frame smoke detect (must not throw; result irrelevant). */\nexport async function probeNativeDetector(): Promise<\n { ok: true; instance: NativeFaceDetectorLike } | { ok: false; reason: string }\n> {\n const ctor = (globalThis as NativeGlobal).FaceDetector;\n if (typeof ctor !== \"function\") return { ok: false, reason: \"unsupported\" };\n try {\n const instance = new ctor({ fastMode: true, maxDetectedFaces: 1 });\n await instance.detect(smokeSource());\n return { ok: true, instance };\n } catch (err) {\n return { ok: false, reason: `smoke_failed:${err instanceof Error ? err.message : String(err)}` };\n }\n}\n\nexport class NativeDetector implements Detector {\n readonly tier = \"native\" as const;\n readonly fallbackReason?: string;\n private readonly inner: NativeFaceDetectorLike;\n\n constructor(inner: NativeFaceDetectorLike, fallbackReason?: string) {\n this.inner = inner;\n if (fallbackReason !== undefined) this.fallbackReason = fallbackReason;\n }\n\n async detect(\n source: CanvasImageSource,\n sourceWidth: number,\n sourceHeight: number,\n ): Promise<FaceObservation | null> {\n let faces: NativeDetectedFace[];\n try {\n faces = await this.inner.detect(source);\n } catch {\n return null; // never rejects mid-loop\n }\n const face = faces[0];\n if (face === undefined) return null;\n const eyes = extractEyes(face.landmarks);\n const observation: FaceObservation = {\n box: {\n x: face.boundingBox.x,\n y: face.boundingBox.y,\n width: face.boundingBox.width,\n height: face.boundingBox.height,\n },\n ...(eyes !== undefined ? { eyes } : {}),\n // The Shape Detection API exposes no confidence — the smoke-tested\n // native tier treats any detection as confident.\n score: 1,\n };\n return toStreamPixels(observation, source, sourceWidth, sourceHeight);\n }\n\n destroy(): void {\n // The native detector holds no resources the page must release.\n }\n}\n\n/** Two `eye` landmarks → {left, right} by image-x (see FaceObservation). */\nfunction extractEyes(\n landmarks: NativeLandmark[] | undefined,\n): FaceObservation[\"eyes\"] | undefined {\n if (landmarks === undefined) return undefined;\n const eyePoints = landmarks\n .filter((landmark) => landmark.type === \"eye\")\n .map((landmark) => landmark.locations[0])\n .filter((point): point is { x: number; y: number } => point !== undefined);\n const [a, b] = eyePoints;\n if (a === undefined || b === undefined) return undefined;\n return a.x <= b.x ? { left: a, right: b } : { left: b, right: a };\n}\n","// v3 Detector abstraction (capture program Task 6) — one detection seam with\n// capability-probed tiers. NEW parallel module: nothing in the v1 core\n// imports from v3/*, and the calibration-pinned v1 gate math is untouched.\n//\n// Ladder (DEFAULT_TIER_ORDER): `native` (the browser's FaceDetector — free,\n// hardware-backed where it exists) → `blaze` (MediaPipe BlazeFace short-range,\n// Task 7). The legacy `faceapi` floor was DROPPED (2026-07-09, capture-v3\n// hardening): field telemetry showed BlazeFace never initialized (the GPU\n// delegate hung on iOS → `blaze_init_timeout`) so EVERY capture silently ran\n// the deprecated ~2.4fps face-api floor. With the CPU-delegate blaze fix,\n// face-api is dead weight — and a floor that masks a blaze regression is worse\n// than none, so the ladder is now native→blaze with NO fallback.\n//\n// Contract change: createDetector still never throws while a tier can be\n// built, but with no floor it REJECTS (DetectorLadderError) once the ladder is\n// exhausted — a CLEAN, non-hanging failure carrying the per-tier reasons.\n// CaptureSessionV3.run() maps that rejection to error{kind:'models'}\n// (retryable; the hosted UI renders a retry). A skipped tier still records a\n// `fallbackReason` (exposed on the returned Detector) so a native→blaze\n// fall-through stays observable in telemetry.\nimport { BLAZE_INIT_TIMEOUT_MS, BlazeDetector } from \"./detector-blaze\";\nimport { NativeDetector, probeNativeDetector } from \"./detector-native\";\n\nexport interface FaceObservation {\n /** Stream-pixel box. */\n box: { x: number; y: number; width: number; height: number };\n /** Stream-pixel eye centers when the tier provides them (native:\n * landmarks?, blaze: keypoints). Convention: `left` = smaller x in IMAGE\n * coordinates — gate math only uses the midpoint and |roll|, so the\n * person-left/image-left distinction never matters. */\n eyes?: { left: { x: number; y: number }; right: { x: number; y: number } };\n score: number;\n}\n\nexport interface Detector {\n readonly tier: \"native\" | \"blaze\";\n /** Why higher tiers were skipped (telemetry) — absent when the first\n * preference won. */\n readonly fallbackReason?: string;\n /** Detect on a (possibly downscaled) snapshot; `sourceWidth/Height` are the\n * STREAM dimensions the observation must be normalized to. Returns the\n * single most-confident face or null; NEVER rejects. */\n detect(\n source: CanvasImageSource,\n sourceWidth: number,\n sourceHeight: number,\n ): Promise<FaceObservation | null>;\n destroy(): void;\n}\n\nexport interface CreateDetectorOptions {\n /** v3 self-hosted assets base (tasks-vision wasm + blaze tflite) — hosted\n * serves `/models-v3`, a sha256-manifested directory. */\n v3AssetBaseUrl?: string;\n preferred?: Detector[\"tier\"][];\n /** Test/tuning override for the blaze init deadline. */\n blazeInitTimeoutMs?: number;\n}\n\nexport const DEFAULT_V3_ASSET_BASE_URL = \"/models-v3\";\n\nexport const DEFAULT_TIER_ORDER: Detector[\"tier\"][] = [\"native\", \"blaze\"];\n\n/** Thrown by createDetector when the ENTIRE tier ladder is exhausted. Since the\n * face-api floor was dropped (2026-07-09) there is no last resort, so blaze\n * failing on an already-native-less platform leaves NO detector. Carries the\n * joined per-tier reasons ('native:unsupported; blaze:blaze_init_timeout') as\n * `fallbackReason` for telemetry. Callers MUST map this to a retryable models\n * error — never a hang (CaptureSessionV3.run → error{kind:'models'}). */\nexport class DetectorLadderError extends Error {\n readonly fallbackReason: string;\n constructor(fallbackReason: string) {\n super(`no detector tier available (${fallbackReason})`);\n this.name = \"DetectorLadderError\";\n this.fallbackReason = fallbackReason;\n }\n}\n\n/** Intrinsic pixel size of a snapshot source (video → videoWidth, image →\n * naturalWidth, canvas/bitmap → width). Property-sniffed so worker-side\n * sources (OffscreenCanvas, ImageBitmap) work without instanceof. */\nexport function intrinsicSize(source: CanvasImageSource): { width: number; height: number } {\n const candidate = source as {\n videoWidth?: number;\n videoHeight?: number;\n naturalWidth?: number;\n naturalHeight?: number;\n width?: number | { baseVal?: { value?: number } };\n height?: number | { baseVal?: { value?: number } };\n };\n if (typeof candidate.videoWidth === \"number\" && candidate.videoWidth > 0) {\n return { width: candidate.videoWidth, height: candidate.videoHeight ?? 0 };\n }\n if (typeof candidate.naturalWidth === \"number\" && candidate.naturalWidth > 0) {\n return { width: candidate.naturalWidth, height: candidate.naturalHeight ?? 0 };\n }\n const width = typeof candidate.width === \"number\" ? candidate.width : 0;\n const height = typeof candidate.height === \"number\" ? candidate.height : 0;\n return { width, height };\n}\n\n/** Scale a source-space observation to stream px. Exported for adapters. */\nexport function toStreamPixels(\n observation: FaceObservation,\n source: CanvasImageSource,\n streamWidth: number,\n streamHeight: number,\n): FaceObservation {\n const size = intrinsicSize(source);\n const scaleX = size.width > 0 ? streamWidth / size.width : 1;\n const scaleY = size.height > 0 ? streamHeight / size.height : 1;\n const scalePoint = (p: { x: number; y: number }) => ({ x: p.x * scaleX, y: p.y * scaleY });\n return {\n box: {\n x: observation.box.x * scaleX,\n y: observation.box.y * scaleY,\n width: observation.box.width * scaleX,\n height: observation.box.height * scaleY,\n },\n ...(observation.eyes !== undefined\n ? { eyes: { left: scalePoint(observation.eyes.left), right: scalePoint(observation.eyes.right) } }\n : {}),\n score: observation.score,\n };\n}\n\nfunction describeError(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\nexport async function createDetector(options: CreateDetectorOptions): Promise<Detector> {\n const order = options.preferred ?? DEFAULT_TIER_ORDER;\n const reasons: string[] = [];\n for (const tier of order) {\n if (tier === \"native\") {\n const probed = await probeNativeDetector();\n if (probed.ok) {\n return new NativeDetector(probed.instance, reasonOf(reasons));\n }\n reasons.push(`native:${probed.reason}`);\n continue;\n }\n // tier === \"blaze\": smoke test = createFromOptions resolving within the\n // deadline (wasm fetch/compile can hang on hostile networks — never stall\n // the ladder).\n try {\n return await withTimeout(\n BlazeDetector.create(\n options.v3AssetBaseUrl ?? DEFAULT_V3_ASSET_BASE_URL,\n reasonOf(reasons),\n ),\n options.blazeInitTimeoutMs ?? BLAZE_INIT_TIMEOUT_MS,\n );\n } catch (err) {\n reasons.push(\n err instanceof InitTimeoutError\n ? \"blaze:blaze_init_timeout\"\n : `blaze:${describeError(err)}`,\n );\n }\n }\n // Ladder exhausted — the face-api floor is gone, so there is NO fallback.\n // REJECT cleanly with the recorded reasons; CaptureSessionV3.run() maps this\n // to a retryable error{kind:'models'} (a bounded failure the hosted UI\n // retries) rather than hanging. NEVER return a null-yielding detector here.\n throw new DetectorLadderError(reasonOf(reasons) ?? \"no_tier_available\");\n}\n\nfunction reasonOf(reasons: string[]): string | undefined {\n return reasons.length > 0 ? reasons.join(\"; \") : undefined;\n}\n\nclass InitTimeoutError extends Error {}\n\nfunction withTimeout<T extends { destroy(): void }>(\n promise: Promise<T>,\n deadlineMs: number,\n): Promise<T> {\n return new Promise<T>((resolvePromise, rejectPromise) => {\n const timer = setTimeout(() => {\n rejectPromise(new InitTimeoutError(`init exceeded ${deadlineMs}ms`));\n // A late resolution after the deadline is an orphan (wasm/GPU\n // delegate) — release it instead of leaking until navigation.\n promise.then(\n (value) => value.destroy(),\n () => undefined,\n );\n }, deadlineMs);\n promise.then(\n (value) => {\n clearTimeout(timer);\n resolvePromise(value);\n },\n (err) => {\n clearTimeout(timer);\n rejectPromise(err);\n },\n );\n });\n}\n","// Worker offload (Task 9) — detection off the main thread when the platform\n// allows (OffscreenCanvas + createImageBitmap + Worker). BOTH protocol sides\n// live in this file so the tiny versioned protocol (v:1) can never drift:\n// - installWorkerDetectorHost: runs INSIDE the worker (auto-installed when\n// this module loads in a DedicatedWorkerGlobalScope; tsup builds it as\n// its own entry so hosts can `new Worker(new URL(...))` the dist file);\n// - WorkerDetectorProxy: main-thread Detector implementation that posts\n// ImageBitmap frames as transferables and resolves results by id.\nimport {\n type CreateDetectorOptions,\n createDetector as defaultCreateDetector,\n type Detector,\n type FaceObservation,\n} from \"./detector\";\n\nexport const WORKER_PROTOCOL_VERSION = 1;\n\ninterface InitMessage {\n v: typeof WORKER_PROTOCOL_VERSION;\n type: \"init\";\n options: CreateDetectorOptions;\n}\ninterface DetectMessage {\n v: typeof WORKER_PROTOCOL_VERSION;\n type: \"detect\";\n id: number;\n bitmap: ImageBitmap;\n streamWidth: number;\n streamHeight: number;\n}\ninterface ReadyMessage {\n v: typeof WORKER_PROTOCOL_VERSION;\n type: \"ready\";\n tier: Detector[\"tier\"];\n fallbackReason?: string;\n}\ninterface ResultMessage {\n v: typeof WORKER_PROTOCOL_VERSION;\n type: \"result\";\n id: number;\n observation: FaceObservation | null;\n}\n\ntype ToWorker = InitMessage | DetectMessage;\ntype ToMain = ReadyMessage | ResultMessage;\n\n/** The slice of Worker/scope surface the protocol needs — test-stubbable. */\nexport interface WorkerScopeLike {\n onmessage: ((event: { data: unknown }) => void) | null;\n postMessage(data: unknown): void;\n}\nexport interface WorkerLike {\n postMessage(data: unknown, transfer?: Transferable[]): void;\n addEventListener(type: \"message\", listener: (event: { data: unknown }) => void): void;\n removeEventListener(type: \"message\", listener: (event: { data: unknown }) => void): void;\n terminate(): void;\n}\n\n/** Feature gate: bitmap capture + transfer + workers must all exist. */\nexport function workerOffloadSupported(): boolean {\n return (\n typeof OffscreenCanvas === \"function\" &&\n typeof createImageBitmap === \"function\" &&\n typeof Worker === \"function\"\n );\n}\n\n/** Worker-side message host. `deps.createDetector` is a test seam. */\nexport function installWorkerDetectorHost(\n scope: WorkerScopeLike,\n deps: { createDetector?: (options: CreateDetectorOptions) => Promise<Detector> } = {},\n): void {\n const create = deps.createDetector ?? defaultCreateDetector;\n let detector: Detector | null = null;\n scope.onmessage = (event) => {\n const message = event.data as ToWorker;\n if (message.v !== WORKER_PROTOCOL_VERSION) {\n // Ignore unknown versions — but never strand a transferred bitmap.\n (message as { bitmap?: { close?: () => void } }).bitmap?.close?.();\n return;\n }\n if (message.type === \"init\") {\n void create(message.options).then((created) => {\n detector = created;\n const ready: ReadyMessage = {\n v: WORKER_PROTOCOL_VERSION,\n type: \"ready\",\n tier: created.tier,\n ...(created.fallbackReason !== undefined\n ? { fallbackReason: created.fallbackReason }\n : {}),\n };\n scope.postMessage(ready);\n });\n return;\n }\n if (message.type === \"detect\") {\n const respond = (observation: FaceObservation | null) => {\n const result: ResultMessage = {\n v: WORKER_PROTOCOL_VERSION,\n type: \"result\",\n id: message.id,\n observation,\n };\n scope.postMessage(result);\n (message.bitmap as { close?: () => void }).close?.();\n };\n if (detector === null) {\n respond(null);\n return;\n }\n void detector\n .detect(message.bitmap, message.streamWidth, message.streamHeight)\n .then(respond, () => respond(null));\n }\n };\n}\n\n// Auto-install when this module IS the worker entry (DedicatedWorkerGlobalScope\n// has importScripts; window does not). Inert in main-thread bundles/tests.\ndeclare const self: (WorkerScopeLike & { importScripts?: unknown }) | undefined;\nif (typeof self !== \"undefined\" && typeof self.importScripts === \"function\") {\n installWorkerDetectorHost(self);\n}\n\n/** Main-side Detector over the worker protocol. Same interface as the\n * in-thread detectors — Task 10's engine cannot tell the difference. */\nexport class WorkerDetectorProxy implements Detector {\n readonly tier: Detector[\"tier\"];\n readonly fallbackReason?: string;\n private readonly worker: WorkerLike;\n private readonly pending = new Map<number, (observation: FaceObservation | null) => void>();\n private nextId = 1;\n\n private constructor(worker: WorkerLike, ready: ReadyMessage) {\n this.worker = worker;\n this.tier = ready.tier;\n if (ready.fallbackReason !== undefined) this.fallbackReason = ready.fallbackReason;\n worker.addEventListener(\"message\", (event) => {\n const message = event.data as ToMain;\n if (message.v !== WORKER_PROTOCOL_VERSION || message.type !== \"result\") return;\n const resolve = this.pending.get(message.id);\n this.pending.delete(message.id);\n resolve?.(message.observation);\n });\n }\n\n static create(\n worker: WorkerLike,\n options: CreateDetectorOptions,\n readyTimeoutMs = 10_000,\n ): Promise<WorkerDetectorProxy> {\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n worker.removeEventListener(\"message\", onReady);\n worker.terminate();\n reject(new Error(`worker detector not ready within ${readyTimeoutMs}ms`));\n }, readyTimeoutMs);\n const onReady = (event: { data: unknown }) => {\n const message = event.data as ToMain;\n if (message.v !== WORKER_PROTOCOL_VERSION || message.type !== \"ready\") return;\n clearTimeout(timer);\n worker.removeEventListener(\"message\", onReady);\n resolve(new WorkerDetectorProxy(worker, message));\n };\n worker.addEventListener(\"message\", onReady);\n const init: InitMessage = { v: WORKER_PROTOCOL_VERSION, type: \"init\", options };\n worker.postMessage(init);\n });\n }\n\n async detect(\n source: CanvasImageSource,\n sourceWidth: number,\n sourceHeight: number,\n ): Promise<FaceObservation | null> {\n // Only ImageBitmap is Transferable — convert other sources (video,\n // canvas) via createImageBitmap (the feature gate guarantees it). A\n // failed conversion yields null, never a DataCloneError.\n let bitmap: ImageBitmap;\n try {\n if (typeof ImageBitmap !== \"undefined\" && source instanceof ImageBitmap) {\n bitmap = source;\n } else if (typeof createImageBitmap === \"function\") {\n bitmap = await createImageBitmap(source as ImageBitmapSource);\n } else {\n // No conversion surface (stubbed environments) — trust the caller.\n bitmap = source as ImageBitmap;\n }\n } catch {\n return null;\n }\n const id = this.nextId;\n this.nextId += 1;\n return new Promise((resolve) => {\n this.pending.set(id, resolve);\n const message: DetectMessage = {\n v: WORKER_PROTOCOL_VERSION,\n type: \"detect\",\n id,\n bitmap,\n streamWidth: sourceWidth,\n streamHeight: sourceHeight,\n };\n this.worker.postMessage(message, [bitmap]);\n });\n }\n\n destroy(): void {\n // Settle in-flight detects (an awaiting scheduler run must not hang\n // busy=true forever) before tearing the worker down.\n for (const resolve of this.pending.values()) resolve(null);\n this.pending.clear();\n this.worker.terminate();\n }\n}\n","// Detect scheduler (Task 9) — paces the detection pass at the profile's\n// cadence, preferring requestVideoFrameCallback (runs only when a REAL camera\n// frame arrived) with a plain interval fallback. A tick whose predecessor is\n// still in flight is SKIPPED — never queued (no backlog on a slow device) —\n// and counted as a degrade for telemetry.\n\nexport interface DetectSchedulerOptions {\n /** Ticks per second (profile cadenceHz). */\n cadenceHz: number;\n /** One detection pass — the scheduler awaits it and measures wall time. */\n run: () => Promise<void>;\n /** When provided AND it exposes requestVideoFrameCallback, ticks ride real\n * camera frames (throttled to the cadence) instead of a timer. */\n video?: HTMLVideoElement;\n /** Injectable clock (tests) — defaults to performance.now. */\n now?: () => number;\n}\n\ninterface VideoFrameCallbackTarget {\n requestVideoFrameCallback?: (callback: () => void) => number;\n cancelVideoFrameCallback?: (id: number) => void;\n}\n\n/** Rolling window for meanDetectMs. */\nconst STATS_WINDOW = 20;\n\nexport class DetectScheduler {\n private readonly options: DetectSchedulerOptions;\n private readonly periodMs: number;\n private timer: ReturnType<typeof setInterval> | null = null;\n private frameCallbackId: number | null = null;\n private running = false;\n private busy = false;\n private lastRunAt = Number.NEGATIVE_INFINITY;\n private degradeCount = 0;\n private readonly durations: number[] = [];\n\n constructor(options: DetectSchedulerOptions) {\n this.options = options;\n this.periodMs = 1000 / options.cadenceHz;\n }\n\n start(): void {\n if (this.running) return;\n this.running = true;\n const video = this.options.video as VideoFrameCallbackTarget | undefined;\n if (typeof video?.requestVideoFrameCallback === \"function\") {\n const loop = () => {\n if (!this.running) return;\n this.frameCallbackId = video.requestVideoFrameCallback?.(() => {\n this.frameCallbackId = null;\n // Throttle: camera frames arrive faster than the cadence.\n if (this.now() - this.lastRunAt >= this.periodMs) this.tick();\n loop();\n }) as number;\n };\n loop();\n return;\n }\n this.timer = setInterval(() => this.tick(), this.periodMs);\n }\n\n stop(): void {\n this.running = false;\n if (this.timer !== null) {\n clearInterval(this.timer);\n this.timer = null;\n }\n if (this.frameCallbackId !== null) {\n (this.options.video as VideoFrameCallbackTarget | undefined)?.cancelVideoFrameCallback?.(\n this.frameCallbackId,\n );\n this.frameCallbackId = null;\n }\n }\n\n stats(): { degradeCount: number; meanDetectMs: number } {\n const meanDetectMs =\n this.durations.length === 0\n ? 0\n : this.durations.reduce((sum, value) => sum + value, 0) / this.durations.length;\n return { degradeCount: this.degradeCount, meanDetectMs };\n }\n\n private now(): number {\n return this.options.now?.() ?? performance.now();\n }\n\n private tick(): void {\n if (!this.running) return;\n if (this.busy) {\n // Skip-when-busy: no queue growth on slow devices; telemetry counts it.\n this.degradeCount += 1;\n return;\n }\n this.busy = true;\n this.lastRunAt = this.now();\n const startedAt = this.now();\n this.options\n .run()\n .catch(() => undefined) // a failed pass must never kill the loop\n .finally(() => {\n this.busy = false;\n this.durations.push(this.now() - startedAt);\n if (this.durations.length > STATS_WINDOW) this.durations.shift();\n });\n }\n}\n","// FaceGateV3 (Task 8) — the v3 gate: scale-invariant, landmark-aware,\n// continuous-quality, gentle-drain. PARALLEL to the calibration-pinned v1\n// FaceGate (face-gate.ts) — nothing here feeds or alters v1's math.\n//\n// Design deltas vs v1 (the two field complaints this kills):\n// - the gate point is the EYE MIDPOINT when the tier provides eyes (humans\n// center their EYES, detectors center their BBOX — v1's bbox-center gate\n// read a centered face as \"high\"); box-only tiers get a documented\n// 0.12×height upward shift instead;\n// - progress is a CONTINUOUS integrator (rise 0.9/s on good quality, fall\n// 0.25/s on bad) instead of v1's ±counters — a wobble dips the progress\n// slightly instead of resetting the attempt.\n//\n// q AGGREGATION = MIN over factors (operator ruling 2026-07-12, replacing\n// the original 7-factor PRODUCT). Field finding: with a product, seven\n// factors each at a decent 0.85 gave q≈0.32 — progress DRAINED while every\n// factor sat above its guidance threshold, so the chrome said \"hold still\"\n// and the only discoverable escape was leaning unnaturally close (size,\n// centering falloff (∝IOD) and crop sharpness all improve together with\n// proximity). min() makes q the same quantity guidance reasons about — the\n// worst factor — so \"no complaint\" ⇔ \"progress rises\" by construction, one\n// genuinely bad factor still blocks (non-compensatory), and many mediocre\n// factors (the low-end-device reality: noisy sensor, dim room, wide FOV)\n// are no longer multiplied into failure.\n//\n// 100% deterministic: the clock is a tick INPUT (timestampMs); nothing here\n// reads Date.now or performance.now.\nimport type { FaceObservation } from \"./detector\";\nimport { EXPOSURE_BAND } from \"./frame-quality\";\n\nexport interface V3GateThresholds {\n /** q at/above which progress rises; below it progress falls. */\n Q_GOOD: number;\n /** Integrator slopes, per second. */\n RISE_PER_S: number;\n FALL_PER_S: number;\n /** Centering falloff radius = this × IOD (scale-invariant). The plan's\n * formula is 0.45 × IOD × 3 — the 0.45 echoes v1's CIRCLE_RADIUS_FACTOR\n * heritage — folded here to 1.35 × IOD. */\n CENTER_FALLOFF_IOD_MULTIPLE: number;\n /** Box-only tiers: gate point = bbox center shifted UP by this × height\n * (the documented bbox-vs-eyes offset heuristic). */\n BOX_EYE_OFFSET_FACTOR: number;\n /** Box-only IOD proxy = this × box width. */\n IOD_BOX_PROXY_FACTOR: number;\n /** IOD / frame short side: ideal band + hard limits. */\n SIZE_IDEAL_MIN: number;\n SIZE_IDEAL_MAX: number;\n SIZE_HARD_MIN: number;\n SIZE_HARD_MAX: number;\n /** Eye-line roll (deg) that zeroes the pose factor. */\n ROLL_MAX_DEG: number;\n /** Center velocity that zeroes the motion factor, in IOD-per-second. */\n MOTION_VELOCITY_IOD_PER_S: number;\n /** Velocity-EMA time constant (seconds) — the EMA weight is derived per\n * tick as 1−exp(−dt/τ), so the smoothing HORIZON is cadence-invariant:\n * a LOW device detecting at 5 Hz gets the same effective smoothing as a\n * HIGH device at 10 Hz (a fixed per-sample alpha under-smoothed exactly\n * the jittery low-cadence ticks that needed it most). */\n MOTION_TAU_S: number;\n /** Velocities at/below this (IOD/s) count as stillness — absorbs detector\n * box jitter (largest on LOW's 128px input) before it reaches the EMA. */\n MOTION_DEADBAND_IOD_PER_S: number;\n /** ready = p ≥ 1 AND no bad tick (q < Q_GOOD) left in this window after\n * TRIMMING: with ≥3 samples the single worst is dropped, so one flaky tick\n * (5 Hz LOW cadence = only 2–3 samples per window) cannot veto an\n * otherwise-ready user, while a SECOND bad tick (a real sustained wobble)\n * still blocks. The readiness bar is Q_GOOD itself — the level the\n * integrator rises on — so any input that fills the ring also fires it. */\n READY_WINDOW_MS: number;\n /** Per-factor guidance trigger levels (lowest failing factor speaks). */\n GUIDE_SIZE: number;\n GUIDE_CENTERING: number;\n GUIDE_POSE: number;\n GUIDE_EXPOSURE: number;\n GUIDE_SHARPNESS: number;\n GUIDE_MOTION: number;\n}\n\n/** Defaults — retuned 2026-07-12 (operator ruling superseding the 2026-07\n * freeze; the capture Task-15 refit set must be split at this boundary):\n * Q_GOOD 0.55→0.6 so it aligns with the 0.6 guidance thresholds under\n * min-q (\"no complaint\" ⇔ \"progress rises\"); SIZE_IDEAL_MIN 0.16→0.12 —\n * wide-FOV front cameras (common low-end) put an arm's-length face below\n * 0.16, silently forcing lean-in; the 720p clip floor keeps a 0.12-IOD\n * face fully resolvable server-side. */\nexport const V3_GATE_DEFAULTS: Readonly<V3GateThresholds> = Object.freeze({\n Q_GOOD: 0.6,\n RISE_PER_S: 0.9,\n FALL_PER_S: 0.25,\n CENTER_FALLOFF_IOD_MULTIPLE: 1.35,\n BOX_EYE_OFFSET_FACTOR: 0.12,\n IOD_BOX_PROXY_FACTOR: 0.42,\n SIZE_IDEAL_MIN: 0.12,\n SIZE_IDEAL_MAX: 0.3,\n SIZE_HARD_MIN: 0.08,\n SIZE_HARD_MAX: 0.45,\n ROLL_MAX_DEG: 25,\n MOTION_VELOCITY_IOD_PER_S: 0.5,\n MOTION_TAU_S: 0.4,\n MOTION_DEADBAND_IOD_PER_S: 0.1,\n READY_WINDOW_MS: 500,\n // (READY_MEAN_Q, the former 0.75 window MEAN, is gone — 2026-10-17 field\n // bug: a steady q anywhere in [Q_GOOD, 0.75) saturated p at 1, passed every\n // guide (\"hold still\") and could never reach the mean, so the ring sat full\n // and green with nothing recording. Readiness now checks the window against\n // Q_GOOD, which keeps the one-flaky-tick forgiveness and the second-bad-tick\n // block without a dead band above the rise threshold.)\n GUIDE_SIZE: 0.6,\n GUIDE_CENTERING: 0.6,\n GUIDE_POSE: 0.6,\n GUIDE_EXPOSURE: 0.6,\n GUIDE_SHARPNESS: 0.35,\n GUIDE_MOTION: 0.5,\n});\n\nexport interface V3GateQuality {\n /** From frame-quality.sharpness on the face crop. */\n sharpness: number;\n /** From frame-quality.exposure on the face crop. */\n exposure: number;\n /** Mean crop luma — picks more_light vs too_bright guidance. */\n meanLuma: number;\n}\n\nexport interface V3GateTickInput {\n timestampMs: number;\n observation: FaceObservation | null;\n quality: V3GateQuality;\n frameWidth: number;\n frameHeight: number;\n}\n\nexport type V3GateFactor =\n | \"presence\"\n | \"centering\"\n | \"size\"\n | \"pose\"\n | \"sharpness\"\n | \"exposure\"\n | \"motion\";\n\n/** Per-tick output — the telemetry + chrome contract. */\nexport interface V3GateTick {\n at: number;\n /** Instantaneous quality 0..1 (MIN over the factors — the worst factor). */\n q: number;\n /** Integrated progress 0..1. */\n p: number;\n factors: Record<V3GateFactor, number>;\n /** fcv3.* message key for the lowest failing factor (host translates). */\n guidanceKey: string;\n /** Fire signal: p ≥ 1 AND no second bad tick (q < Q_GOOD) in READY_WINDOW_MS. */\n ready: boolean;\n /** The face on THIS tick is ACCEPTED by the gate — present and every factor\n * (size, centering, pose, sharpness, exposure, motion) good enough that the\n * integrator RISES (q ≥ Q_GOOD). The engine's \"first accepted face\" mark. */\n accepted: boolean;\n}\n\nconst clamp01 = (value: number) => Math.min(1, Math.max(0, value));\n\nexport class FaceGateV3 {\n private readonly t: V3GateThresholds;\n private p = 0;\n private lastTickAt: number | null = null;\n private lastCenter: { x: number; y: number; at: number } | null = null;\n private velocityEma = 0;\n private qWindow: Array<{ at: number; q: number }> = [];\n\n constructor(overrides: Partial<V3GateThresholds> = {}) {\n this.t = { ...V3_GATE_DEFAULTS, ...overrides };\n }\n\n reset(): void {\n this.p = 0;\n this.lastTickAt = null;\n this.lastCenter = null;\n this.velocityEma = 0;\n this.qWindow = [];\n this.lastSizeDirection = \"ideal\";\n }\n\n tick(input: V3GateTickInput): V3GateTick {\n const { observation, quality, timestampMs } = input;\n const dtSeconds =\n this.lastTickAt === null\n ? 0\n : Math.max(0, (timestampMs - this.lastTickAt) / 1000);\n this.lastTickAt = timestampMs;\n\n const factors: Record<V3GateFactor, number> = {\n presence: 0,\n centering: 0,\n size: 0,\n pose: 0,\n sharpness: clamp01(quality.sharpness),\n exposure: clamp01(quality.exposure),\n motion: 1,\n };\n\n if (observation !== null) {\n factors.presence = 1;\n const geometry = this.geometryOf(observation, input);\n factors.centering = geometry.centering;\n factors.size = geometry.size;\n factors.pose = geometry.pose;\n factors.motion = this.motionOf(\n geometry.center,\n geometry.iod,\n timestampMs,\n );\n } else {\n // No face: the motion history must not survive to the next sighting\n // (a re-acquired face \"jumping\" from its old position is not motion,\n // and a stale pre-loss velocity EMA must not penalize re-acquisition).\n this.lastCenter = null;\n this.velocityEma = 0;\n }\n\n // Worst factor IS the quality (see header) — presence 0 zeroes it exactly\n // as the old product did; the compensatory many-mediocre penalty is gone.\n const q = Math.min(\n factors.presence,\n factors.centering,\n factors.size,\n factors.pose,\n factors.sharpness,\n factors.exposure,\n factors.motion,\n );\n\n // Integrator: gentle drain — bad ticks pull p down at FALL×(1−q), never\n // reset it (the v1 counter-reset feel this replaces).\n this.p = clamp01(\n this.p +\n (q >= this.t.Q_GOOD\n ? this.t.RISE_PER_S * q\n : -this.t.FALL_PER_S * (1 - q)) *\n dtSeconds,\n );\n\n // Sustained-quality window (prevents luck-firing through a wobble).\n // TRIMMED: with ≥3 samples the single worst is dropped — at LOW's 5 Hz\n // cadence a window holds 2–3 ticks, and one jittery detection must not\n // veto a user who is otherwise steadily ready. Every remaining sample must\n // be a GOOD tick (q ≥ Q_GOOD, the integrator's own rise level): a second\n // bad tick blocks, and — by construction — any steady input that fills\n // the ring is ready the moment the window is clean (no dead band where\n // p = 1, guidance says hold_still and nothing fires; 2026-10-17).\n this.qWindow.push({ at: timestampMs, q });\n this.qWindow = this.qWindow.filter(\n (entry) => entry.at >= timestampMs - this.t.READY_WINDOW_MS,\n );\n let windowSamples = this.qWindow.map((entry) => entry.q);\n if (windowSamples.length >= 3) {\n const worst = Math.min(...windowSamples);\n const worstIndex = windowSamples.indexOf(worst);\n windowSamples = windowSamples.filter((_, index) => index !== worstIndex);\n }\n const ready =\n this.p >= 1 && windowSamples.every((sample) => sample >= this.t.Q_GOOD);\n\n return {\n at: timestampMs,\n q,\n p: this.p,\n factors,\n guidanceKey: this.guidanceOf(factors, quality, q),\n ready,\n accepted: q >= this.t.Q_GOOD,\n };\n }\n\n private geometryOf(\n observation: FaceObservation,\n input: V3GateTickInput,\n ): {\n center: { x: number; y: number };\n iod: number;\n centering: number;\n size: number;\n pose: number;\n } {\n const { box, eyes } = observation;\n const frameCenter = { x: input.frameWidth / 2, y: input.frameHeight / 2 };\n const shortSide = Math.min(input.frameWidth, input.frameHeight);\n\n // Gate point: eye midpoint, or the bbox center shifted UP so box-only\n // tiers behave like eye tiers (BOX_EYE_OFFSET heuristic).\n const center =\n eyes !== undefined\n ? {\n x: (eyes.left.x + eyes.right.x) / 2,\n y: (eyes.left.y + eyes.right.y) / 2,\n }\n : {\n x: box.x + box.width / 2,\n y:\n box.y +\n box.height / 2 -\n this.t.BOX_EYE_OFFSET_FACTOR * box.height,\n };\n const iod =\n eyes !== undefined\n ? Math.hypot(eyes.right.x - eyes.left.x, eyes.right.y - eyes.left.y)\n : this.t.IOD_BOX_PROXY_FACTOR * box.width;\n\n // Smooth, SCALE-INVARIANT centering falloff: distance measured in IODs.\n const distance = Math.hypot(\n center.x - frameCenter.x,\n center.y - frameCenter.y,\n );\n const centering =\n iod <= 0\n ? 0\n : 1 - clamp01(distance / (this.t.CENTER_FALLOFF_IOD_MULTIPLE * iod));\n\n // Size factor from IOD relative to the frame short side.\n const ratio = shortSide > 0 ? iod / shortSide : 0;\n this.lastSizeDirection =\n ratio < this.t.SIZE_IDEAL_MIN\n ? \"far\"\n : ratio > this.t.SIZE_IDEAL_MAX\n ? \"close\"\n : \"ideal\";\n let size: number;\n if (ratio < this.t.SIZE_HARD_MIN || ratio > this.t.SIZE_HARD_MAX) {\n size = 0;\n } else if (ratio < this.t.SIZE_IDEAL_MIN) {\n size =\n (ratio - this.t.SIZE_HARD_MIN) /\n (this.t.SIZE_IDEAL_MIN - this.t.SIZE_HARD_MIN);\n } else if (ratio > this.t.SIZE_IDEAL_MAX) {\n size =\n (this.t.SIZE_HARD_MAX - ratio) /\n (this.t.SIZE_HARD_MAX - this.t.SIZE_IDEAL_MAX);\n } else {\n size = 1;\n }\n\n // Pose from the eye-line roll; box-only tiers stay neutral (no signal).\n let pose = 1;\n if (eyes !== undefined) {\n const rollDeg =\n (Math.abs(\n Math.atan2(eyes.right.y - eyes.left.y, eyes.right.x - eyes.left.x),\n ) *\n 180) /\n Math.PI;\n pose = 1 - clamp01(rollDeg / this.t.ROLL_MAX_DEG);\n }\n\n return { center, iod, centering, size, pose };\n }\n\n private motionOf(\n center: { x: number; y: number },\n iod: number,\n at: number,\n ): number {\n const previous = this.lastCenter;\n this.lastCenter = { ...center, at };\n if (previous === null || iod <= 0) return 1;\n const dtSeconds = (at - previous.at) / 1000;\n if (dtSeconds <= 0) return 1;\n let velocityIodPerS =\n Math.hypot(center.x - previous.x, center.y - previous.y) /\n iod /\n dtSeconds;\n // Deadband: sub-jitter velocities are stillness. Detector boxes quantize\n // hardest on LOW's 128px input, where a ±1px wobble at 5 Hz reads as\n // ~0.25 IOD/s — half the zeroing velocity — despite a rock-steady user.\n if (velocityIodPerS <= this.t.MOTION_DEADBAND_IOD_PER_S)\n velocityIodPerS = 0;\n // Time-constant EMA: alpha derived from dt so the smoothing horizon is\n // the same at 5 Hz and 10 Hz (see MOTION_TAU_S).\n const alpha = 1 - Math.exp(-dtSeconds / this.t.MOTION_TAU_S);\n this.velocityEma = alpha * velocityIodPerS + (1 - alpha) * this.velocityEma;\n return 1 - clamp01(this.velocityEma / this.t.MOTION_VELOCITY_IOD_PER_S);\n }\n\n /** Lowest failing factor speaks — fixed priority (diagnostic, incl. light):\n * presence → size → centering → pose → exposure → sharpness → hold.\n *\n * HONESTY FALLBACK (operator ruling 2026-07-12): when every factor clears\n * its guide threshold but q (= min factor) is still below Q_GOOD — i.e.\n * progress is DRAINING — \"hold still\" would be a lie (\"Perfect\" while\n * nothing advances; the field symptom was users discovering by accident\n * that only leaning in fires the gate). In that state the WORST factor\n * speaks even though it passed its guide level, so the user always hears\n * the change that actually unblocks recording. */\n private guidanceOf(\n factors: Record<V3GateFactor, number>,\n quality: V3GateQuality,\n q: number,\n ): string {\n if (factors.presence <= 0) return \"fcv3.no_face\";\n if (factors.size < this.t.GUIDE_SIZE) return this.sizeGuidance();\n if (factors.centering < this.t.GUIDE_CENTERING) return \"fcv3.center_face\";\n if (factors.pose < this.t.GUIDE_POSE) return \"fcv3.straighten\";\n if (factors.exposure < this.t.GUIDE_EXPOSURE)\n return this.exposureGuidance(quality);\n if (factors.sharpness < this.t.GUIDE_SHARPNESS) return \"fcv3.steady_camera\";\n if (factors.motion < this.t.GUIDE_MOTION) return \"fcv3.hold_still\";\n if (q < this.t.Q_GOOD) {\n // All guides pass but progress drains — coach the worst factor anyway.\n const coachable: Array<[V3GateFactor, string]> = [\n [\"size\", this.sizeGuidance()],\n [\"centering\", \"fcv3.center_face\"],\n [\"pose\", \"fcv3.straighten\"],\n [\"exposure\", this.exposureGuidance(quality)],\n [\"sharpness\", \"fcv3.steady_camera\"],\n [\"motion\", \"fcv3.hold_still\"],\n ];\n let worst = coachable[0] as [V3GateFactor, string];\n for (const entry of coachable) {\n if (factors[entry[0]] < factors[worst[0]]) worst = entry;\n }\n return worst[1];\n }\n return \"fcv3.hold_still\";\n }\n\n /** Direction from the size band set THIS tick (never inverted at the hard\n * limits: past SIZE_HARD_MAX the direction is 'close' → move_back). */\n private sizeGuidance(): string {\n return this.lastSizeDirection === \"far\"\n ? \"fcv3.come_closer\"\n : \"fcv3.move_back\";\n }\n\n /** Band midpoint — direction only (tracks EXPOSURE_BAND automatically). */\n private exposureGuidance(quality: V3GateQuality): string {\n const bandMid = (EXPOSURE_BAND[0] + EXPOSURE_BAND[1]) / 2;\n return quality.meanLuma < bandMid ? \"fcv3.more_light\" : \"fcv3.too_bright\";\n }\n\n /** Which side of the ideal band the last size measurement fell on. */\n private lastSizeDirection: \"far\" | \"close\" | \"ideal\" = \"ideal\";\n}\n","// CaptureSessionV3 (Task 10) — the v3 engine behind the v1 event surface\n// (`statechange | guidance | checks | artifacts | error`), plus ONE v3-only\n// chrome event (`frozen`, fired at recording-stop so the host can freeze the\n// display on the keyframe before the clip finalizes), so hosts bind it with\n// minimal changes. PARALLEL module: it REUSES v1's building blocks AS\n// IMPORTS — ClipRecorder (the 720p/2.5Mbps clip floor lives in ONE place),\n// captureMirroredKeyframe, buildCaptureConstraints, the camera error taxonomy\n// — and touches no v1 file.\n//\n// v3 deltas: detector LADDER (native → blaze; the face-api floor was dropped\n// 2026-07-09) on an adaptive scheduler with device profiles; FaceGateV3\n// (eye-midpoint, continuous\n// integrator); keyframe BEST-OF-N (sharpest of up to 4 candidates in the\n// first 600ms of the capture window); `checks` carries a v3 payload\n// discriminated on `engine: 'v3'` (no v1 counters).\n//\n// Supersession: retry()/switchCamera()/destroy() bump the attempt token —\n// in-flight async continuations from an old attempt observe the bump and\n// stop (the v1 pattern, ported; see capture-session.ts header).\nimport { buildCaptureConstraints, detectIsMobile } from \"../capture-constraints\";\nimport { ClipRecorder, type ClipResult } from \"../clip-recorder\";\nimport { captureMirroredKeyframe } from \"../keyframe\";\nimport { cameraPreflight, isClipTooLarge, mapGetUserMediaError } from \"../media\";\nimport type { CaptureArtifacts, CaptureErrorKind, CaptureState, CaptureTiming } from \"../types\";\nimport {\n createDetector as createLadderDetector,\n type Detector,\n DetectorLadderError,\n intrinsicSize,\n} from \"./detector\";\nimport { WorkerDetectorProxy, type WorkerLike, workerOffloadSupported } from \"./detect-worker\";\nimport {\n classifyDevice,\n type DeviceClass,\n DeviceProfiler,\n probeDevice,\n} from \"./device-profile\";\nimport { DetectScheduler } from \"./detect-scheduler\";\nimport {\n FaceGateV3,\n type V3GateFactor,\n type V3GateQuality,\n type V3GateThresholds,\n} from \"./face-gate-v3\";\nimport { exposure, meanLuma, sharpness } from \"./frame-quality\";\n\n/** Best-of-N keyframe window: up to 4 candidates over the first 600ms. */\nexport const KEYFRAME_CANDIDATES = 4;\nexport const KEYFRAME_WINDOW_MS = 600;\n\nexport interface V3ChecksPayload {\n engine: \"v3\";\n /** Gate integrator 0..1 — the ring drives off this directly. */\n progress: number;\n /** Instantaneous quality 0..1. */\n q: number;\n factors: Record<V3GateFactor, number>;\n /** Attempt ordinal (bumps on retry/switchCamera). */\n attempt: number;\n}\n\nexport interface CaptureSessionV3Events {\n statechange: { state: CaptureState };\n checks: V3ChecksPayload;\n /** fcv3.* message KEY — hosts translate; never prose. Deduped. */\n guidance: { key: string };\n artifacts: CaptureArtifacts;\n error: { kind: CaptureErrorKind; retryable: boolean };\n /** v3-only, CHROME-only (no data flows here): fires the instant the clip\n * recording window ends — BEFORE the blob finalizes (iOS onstop can lag up\n * to STOP_GRACE_MS). Carries the already-captured keyframe's JPEG data URL so\n * the host can freeze the display on the still immediately instead of leaving\n * the live feed running while the clip flushes. Clip mode only (photo mode\n * goes straight to `artifacts`). A host that ignores it is unaffected. */\n frozen: { previewDataUrl: string };\n}\n\nexport type V3TelemetryEvent =\n | { type: \"detector\"; tier: Detector[\"tier\"]; fallbackReason?: string }\n | { type: \"profile\"; staticClass: DeviceClass; activeClass: DeviceClass; simd: boolean }\n | { type: \"fired\"; timeToGateMs: number; degradeCount: number; meanDetectMs: number }\n | { type: \"error\"; kind: CaptureErrorKind; fallbackReason?: string };\n\ninterface KeyframeCandidate {\n blob: Blob;\n previewDataUrl: string;\n sharpness: number;\n}\n\n/** Challenge-clip artifact for the Phase 3 escalation path. */\nexport interface EscalationClipArtifact {\n clip: Blob;\n clipMimeType: string;\n}\n\n/** INERT Phase 3 seam (docs/superpowers/specs/2026-07-07-active-liveness-\n * escalation-spec.md): when the server settles a liveness verdict in the\n * REVIEW band it may mint ONE gesture challenge; the host then asks the\n * engine for a challenge clip through this hook. Typed and documented NOW so\n * capture-v3+ starts from a design — NEVER invoked anywhere in the current\n * flow (pinned by a test). */\nexport interface EscalationHook {\n onBorderline(challenge: \"blink\" | \"turn\"): Promise<EscalationClipArtifact>;\n}\n\nexport interface CaptureSessionV3Options {\n /** Host-owned <video playsInline muted> — same iOS contract as v1. */\n video: HTMLVideoElement;\n /** v3 assets base (tasks-vision wasm + tflite); default /models-v3. */\n v3AssetBaseUrl?: string;\n mode?: \"clip\" | \"photo\";\n /** FaceGateV3 threshold overrides (Phase 2 tuning). */\n thresholds?: Partial<V3GateThresholds>;\n telemetry?: (event: V3TelemetryEvent) => void;\n facingMode?: \"user\" | \"environment\";\n /** Static class override (tests / host pinning); default = boot probe. */\n deviceClass?: DeviceClass;\n // ── seams (production defaults in parens) ─────────────────────────────────\n /** (detector ladder) */\n createDetector?: () => Promise<Detector>;\n /** (fresh ClipRecorder per attempt) */\n createRecorder?: () => Pick<ClipRecorder, \"record\" | \"stop\">;\n /** (navigator.mediaDevices.getUserMedia) */\n getUserMedia?: (constraints: MediaStreamConstraints) => Promise<MediaStream>;\n /** (mirrored canvas keyframe + downscaled Laplacian sharpness) */\n captureKeyframe?: (video: HTMLVideoElement) => Promise<KeyframeCandidate>;\n /** (downscaled face-crop sharpness/exposure via canvas) */\n measureQuality?: (\n video: HTMLVideoElement,\n box: { x: number; y: number; width: number; height: number },\n ) => V3GateQuality;\n /** (reused canvas at profile.inputWidth; falls back to the raw video where\n * canvas is unavailable) */\n makeSnapshot?: (video: HTMLVideoElement, targetWidth: number) => CanvasImageSource;\n /** Worker offload opt-in (Task 9): when provided AND the platform supports\n * it (OffscreenCanvas + createImageBitmap + Worker), detection runs\n * worker-side through WorkerDetectorProxy. Hosts own Worker construction\n * (bundler-specific `new Worker(new URL(...))`). */\n createWorker?: () => WorkerLike;\n /** INERT (Phase 3 escalation seam — see EscalationHook). Accepted and\n * retained, never called in Phases 1–2. */\n escalation?: EscalationHook;\n /** (performance.now) */\n now?: () => number;\n}\n\ntype Handler<K extends keyof CaptureSessionV3Events> = (\n payload: CaptureSessionV3Events[K],\n) => void;\n\nconst NEUTRAL_QUALITY: V3GateQuality = { sharpness: 1, exposure: 1, meanLuma: 128 };\n\nexport class CaptureSessionV3 {\n private readonly options: CaptureSessionV3Options;\n private readonly handlers = new Map<string, Set<(payload: never) => void>>();\n private stateValue: CaptureState = \"idle\";\n private attempt = 0;\n private facing: \"user\" | \"environment\";\n private stream: MediaStream | null = null;\n private detector: Detector | null = null;\n private scheduler: DetectScheduler | null = null;\n private gate: FaceGateV3 | null = null;\n private profiler: DeviceProfiler | null = null;\n private lastGuidanceKey: string | null = null;\n private positioningStartedAt = 0;\n // Face-capture timing marks of the CURRENT attempt (engine clock; reset per run).\n private cameraRequestedAt: number | null = null;\n private cameraReadyAt: number | null = null;\n private faceAcquiredAt: number | null = null;\n private captureCompleteAt: number | null = null;\n private fired = false;\n private carriedDegrade = 0;\n private carriedMeans: number[] = [];\n\n constructor(options: CaptureSessionV3Options) {\n this.options = options;\n this.facing = options.facingMode ?? \"user\";\n }\n\n get state(): CaptureState {\n return this.stateValue;\n }\n\n on<K extends keyof CaptureSessionV3Events>(event: K, handler: Handler<K>): () => void {\n let set = this.handlers.get(event);\n if (!set) {\n set = new Set();\n this.handlers.set(event, set);\n }\n set.add(handler as (payload: never) => void);\n return () => set?.delete(handler as (payload: never) => void);\n }\n\n private emit<K extends keyof CaptureSessionV3Events>(\n event: K,\n payload: CaptureSessionV3Events[K],\n ): void {\n for (const handler of [...(this.handlers.get(event) ?? [])]) {\n (handler as Handler<K>)(payload);\n }\n }\n\n async start(): Promise<void> {\n this.attempt += 1;\n await this.run(this.attempt);\n }\n\n /** Full reset + camera restart — the documented recovery path (v1 parity). */\n retry(): void {\n this.teardownAttempt();\n void this.start();\n }\n\n switchCamera(): void {\n this.facing = this.facing === \"user\" ? \"environment\" : \"user\";\n this.teardownAttempt();\n void this.start();\n }\n\n destroy(): void {\n this.attempt += 1; // supersede in-flight continuations\n this.teardownAttempt();\n this.detector?.destroy();\n this.detector = null;\n this.options.video.srcObject = null;\n }\n\n // ── attempt lifecycle ──────────────────────────────────────────────────────\n\n private async run(attempt: number): Promise<void> {\n const { options } = this;\n this.fired = false;\n this.lastGuidanceKey = null;\n this.carriedDegrade = 0;\n this.carriedMeans = [];\n this.cameraRequestedAt = null;\n this.cameraReadyAt = null;\n this.faceAcquiredAt = null;\n this.captureCompleteAt = null;\n this.setState(\"preflight\");\n const preflight = cameraPreflight();\n if (preflight !== \"OK\") {\n this.fail(preflight === \"INSECURE_CONTEXT\" ? \"insecure\" : \"unsupported\");\n return;\n }\n\n this.setState(\"acquiring\");\n const getUserMedia =\n options.getUserMedia ??\n ((constraints: MediaStreamConstraints) => navigator.mediaDevices.getUserMedia(constraints));\n let stream: MediaStream;\n this.cameraRequestedAt = this.now();\n try {\n // The 720p/2.5Mbps floor: v1's constraint builder, imported — never forked.\n stream = await getUserMedia(buildCaptureConstraints(detectIsMobile(), this.facing));\n } catch (err) {\n if (attempt !== this.attempt) return;\n this.fail(mapGetUserMediaError(err));\n return;\n }\n if (attempt !== this.attempt) {\n for (const track of stream.getTracks()) track.stop();\n return;\n }\n this.stream = stream;\n options.video.srcObject = stream;\n await options.video.play().catch(() => undefined);\n // play() awaited — a retry/destroy may have superseded this attempt while\n // it was suspended; continuing would overwrite the LIVE attempt's\n // profiler/gate/scheduler with stale ones (review S2-2).\n if (attempt !== this.attempt) return;\n // Camera ready: stream attached + preview playing (the detector may still\n // be loading — that wait is part of the capture phase, not the camera's).\n this.cameraReadyAt = this.now();\n\n if (this.detector === null) {\n const ladderOptions = {\n ...(options.v3AssetBaseUrl !== undefined\n ? { v3AssetBaseUrl: options.v3AssetBaseUrl }\n : {}),\n };\n const create =\n options.createDetector ??\n (options.createWorker !== undefined && workerOffloadSupported()\n ? async () => {\n // Worker offload (Task 9): the ladder runs WORKER-side; a\n // failed/hung init falls back to the in-thread ladder.\n try {\n return await WorkerDetectorProxy.create(\n (options.createWorker as () => WorkerLike)(),\n ladderOptions,\n );\n } catch {\n return createLadderDetector(ladderOptions);\n }\n }\n : () => createLadderDetector(ladderOptions));\n let created: Detector;\n try {\n created = await create();\n } catch (err) {\n // With the face-api floor gone, the ladder REJECTS once exhausted\n // (DetectorLadderError) — and any throwing seam is likewise a models\n // failure. Surface a retryable error{kind:'models'} (never a hang),\n // carrying the per-tier reasons for telemetry so a blaze init failure\n // stays observable in the field.\n if (attempt === this.attempt) {\n this.fail(\n \"models\",\n err instanceof DetectorLadderError ? err.fallbackReason : describeError(err),\n );\n }\n return;\n }\n // Resolve into a LOCAL first: assigning a detector into a superseded\n // (or destroyed) session would leak it — destroy() already nulled the\n // field, and a racing attempt may have created its own (review S2-3).\n if (attempt !== this.attempt) {\n created.destroy();\n return;\n }\n this.detector = created;\n this.options.telemetry?.({\n type: \"detector\",\n tier: created.tier,\n ...(created.fallbackReason !== undefined\n ? { fallbackReason: created.fallbackReason }\n : {}),\n });\n }\n\n const probe = probeDevice();\n const staticClass = options.deviceClass ?? classifyDevice(probe);\n this.profiler = new DeviceProfiler(staticClass);\n this.options.telemetry?.({\n type: \"profile\",\n staticClass,\n activeClass: this.profiler.deviceClass,\n simd: probe.simd,\n });\n\n this.gate = new FaceGateV3(options.thresholds ?? {});\n this.setState(\"positioning\");\n this.positioningStartedAt = this.now();\n this.startScheduler(attempt);\n }\n\n /** Chrome hint (Task 11): 'reduced' on LOW even without the media query. */\n get animations(): \"full\" | \"reduced\" {\n return this.profiler?.profile.animations ?? \"full\";\n }\n\n private startScheduler(attempt: number): void {\n const profiler = this.profiler;\n if (profiler === null) return;\n if (this.scheduler !== null) {\n // A dynamic profile change replaces the scheduler — carry its stats so\n // the `fired` telemetry keeps the PRE-adjustment struggle visible.\n const stats = this.scheduler.stats();\n this.carriedDegrade += stats.degradeCount;\n if (stats.meanDetectMs > 0) this.carriedMeans.push(stats.meanDetectMs);\n this.scheduler.stop();\n }\n const scheduler = new DetectScheduler({\n cadenceHz: profiler.profile.cadenceHz,\n video: this.options.video,\n ...(this.options.now !== undefined ? { now: this.options.now } : {}),\n run: () => this.detectTick(attempt),\n });\n this.scheduler = scheduler;\n scheduler.start();\n }\n\n private async detectTick(attempt: number): Promise<void> {\n const { detector, gate, profiler } = this;\n const video = this.options.video;\n if (attempt !== this.attempt || detector === null || gate === null || profiler === null)\n return;\n if (this.fired || video.videoWidth === 0) return;\n\n const before = profiler.deviceClass;\n const t0 = this.now();\n // Profile-adaptive DOWNSCALE: the detector sees an inputWidth-wide\n // snapshot, never the full 720p frame (the profile system's perf win);\n // stream-px normalization scales the observation back up.\n const source =\n this.options.makeSnapshot?.(video, profiler.profile.inputWidth) ??\n this.defaultSnapshot(video, profiler.profile.inputWidth);\n let observation: Awaited<ReturnType<Detector[\"detect\"]>> = null;\n try {\n observation = await detector.detect(source, video.videoWidth, video.videoHeight);\n } catch {\n observation = null; // detectors never reject by contract; belt-and-braces\n }\n if (attempt !== this.attempt || this.fired) return;\n profiler.record(this.now() - t0);\n if (profiler.deviceClass !== before) this.startScheduler(attempt); // cadence follows the class\n\n const quality =\n observation === null\n ? NEUTRAL_QUALITY\n : (this.options.measureQuality?.(video, observation.box) ??\n this.defaultQuality(video, observation.box));\n\n const tick = gate.tick({\n timestampMs: this.now(),\n observation,\n quality,\n frameWidth: video.videoWidth,\n frameHeight: video.videoHeight,\n });\n // First face ACCEPTED by the gate (size / centering / quality all good —\n // the integrator rises), not merely detected. Set once; a later loss and\n // re-acquisition never moves it.\n if (tick.accepted && this.faceAcquiredAt === null) this.faceAcquiredAt = tick.at;\n this.emit(\"checks\", {\n engine: \"v3\",\n progress: tick.p,\n q: tick.q,\n factors: tick.factors,\n attempt,\n });\n if (tick.guidanceKey !== this.lastGuidanceKey) {\n this.lastGuidanceKey = tick.guidanceKey;\n this.emit(\"guidance\", { key: tick.guidanceKey });\n }\n if (tick.ready && this.stateValue === \"positioning\") {\n this.fired = true;\n this.captureCompleteAt = tick.at; // gate progress 100 % — capture complete\n void this.fire(attempt);\n }\n }\n\n private async fire(attempt: number): Promise<void> {\n const { options } = this;\n const scheduler = this.scheduler;\n scheduler?.stop();\n const stats = scheduler?.stats() ?? { degradeCount: 0, meanDetectMs: 0 };\n const means = [...this.carriedMeans, ...(stats.meanDetectMs > 0 ? [stats.meanDetectMs] : [])];\n options.telemetry?.({\n type: \"fired\",\n timeToGateMs: this.now() - this.positioningStartedAt,\n degradeCount: this.carriedDegrade + stats.degradeCount,\n meanDetectMs:\n means.length === 0 ? 0 : means.reduce((sum, value) => sum + value, 0) / means.length,\n });\n\n const mode = options.mode ?? \"clip\";\n const bestOf = this.collectKeyframes(attempt);\n if (mode === \"photo\") {\n const best = await bestOf;\n if (attempt !== this.attempt) return;\n if (best === null) {\n this.fail(\"generic\");\n return;\n }\n this.finishCapture({ keyframe: best.blob, previewDataUrl: best.previewDataUrl });\n return;\n }\n\n this.setState(\"recording\");\n const recorder = options.createRecorder?.() ?? new ClipRecorder();\n const stream = this.stream;\n if (stream === null) {\n this.fail(\"generic\");\n return;\n }\n // The keyframe (the face_match selfie) resolves within the first 600ms —\n // well before the 2.5s clip ends. Latch it so the recording-STOP callback\n // below can emit `frozen` immediately, letting the host freeze the display\n // on the still without waiting for the clip blob to finalize (iOS lag).\n let frozenBest: KeyframeCandidate | null = null;\n void bestOf.then(\n (candidate) => {\n frozenBest = candidate;\n },\n () => {},\n );\n const onRecordingStopped = (): void => {\n if (attempt !== this.attempt) return; // superseded (retry/switch/destroy)\n if (frozenBest !== null) {\n this.emit(\"frozen\", { previewDataUrl: frozenBest.previewDataUrl });\n }\n };\n let clip: ClipResult;\n let best: KeyframeCandidate | null;\n try {\n [clip, best] = await Promise.all([recorder.record(stream, onRecordingStopped), bestOf]);\n } catch (err) {\n if (attempt !== this.attempt) return;\n const kind = (err as { kind?: CaptureErrorKind }).kind;\n this.fail(kind === \"cliptoolarge\" ? \"cliptoolarge\" : \"recorder\");\n return;\n }\n if (attempt !== this.attempt) return;\n if (isClipTooLarge(clip.blob)) {\n this.fail(\"cliptoolarge\");\n return;\n }\n if (best === null) {\n this.fail(\"generic\");\n return;\n }\n this.finishCapture({\n clip: clip.blob,\n clipMimeType: clip.mimeType,\n keyframe: best.blob,\n previewDataUrl: best.previewDataUrl,\n });\n }\n\n /** Up to KEYFRAME_CANDIDATES mirrored frames over KEYFRAME_WINDOW_MS —\n * sharpest wins (reuses frame-quality.sharpness via the capture seam). */\n private async collectKeyframes(attempt: number): Promise<KeyframeCandidate | null> {\n const capture = this.options.captureKeyframe ?? ((video) => this.defaultKeyframe(video));\n const stepMs = KEYFRAME_WINDOW_MS / (KEYFRAME_CANDIDATES - 1);\n let best: KeyframeCandidate | null = null;\n for (let i = 0; i < KEYFRAME_CANDIDATES; i += 1) {\n if (attempt !== this.attempt) return best;\n try {\n const candidate = await capture(this.options.video);\n if (best === null || candidate.sharpness > best.sharpness) best = candidate;\n } catch {\n // a failed candidate never sinks the capture — keep the best so far\n }\n if (i < KEYFRAME_CANDIDATES - 1) await delay(stepMs);\n }\n return best;\n }\n\n private finishCapture(artifacts: CaptureArtifacts): void {\n this.stopTracks(); // privacy posture: camera off the moment we have artifacts\n this.setState(\"captured\");\n const timing = this.captureTiming();\n this.emit(\"artifacts\", timing === undefined ? artifacts : { ...artifacts, timing });\n }\n\n /** The attempt's capture-phase timing (whole ms, ≥ 0); undefined when no mark landed. */\n private captureTiming(): CaptureTiming | undefined {\n const span = (from: number | null, to: number | null): number | undefined =>\n from !== null && to !== null ? Math.max(0, Math.round(to - from)) : undefined;\n const cameraReadyMs = span(this.cameraRequestedAt, this.cameraReadyAt);\n const faceAcquireMs = span(this.cameraReadyAt, this.faceAcquiredAt);\n // Product definition: from the FIRST accepted face (a later loss /\n // re-acquisition never moves the start) until the gate reached 100 %.\n const captureMs = span(this.faceAcquiredAt, this.captureCompleteAt);\n const timing: CaptureTiming = {\n ...(cameraReadyMs !== undefined ? { cameraReadyMs } : {}),\n ...(faceAcquireMs !== undefined ? { faceAcquireMs } : {}),\n ...(captureMs !== undefined ? { captureMs } : {}),\n };\n return Object.keys(timing).length > 0 ? timing : undefined;\n }\n\n // ── defaults for the canvas-bound seams ────────────────────────────────────\n\n private async defaultKeyframe(video: HTMLVideoElement): Promise<KeyframeCandidate> {\n const canvas = document.createElement(\"canvas\");\n const blob = await captureMirroredKeyframe(video, canvas);\n const previewDataUrl = canvas.toDataURL(\"image/jpeg\", 0.92);\n return { blob, previewDataUrl, sharpness: this.centerSharpness(video) };\n }\n\n /** Reused downscale canvas — falls back to the raw video where canvas 2D\n * is unavailable (jsdom) so tests and exotic hosts keep detecting. */\n private snapshotCanvas: HTMLCanvasElement | null = null;\n private defaultSnapshot(video: HTMLVideoElement, targetWidth: number): CanvasImageSource {\n try {\n const canvas = this.snapshotCanvas ?? document.createElement(\"canvas\");\n const scale = targetWidth / Math.max(1, video.videoWidth);\n const width = Math.max(1, Math.round(video.videoWidth * scale));\n const height = Math.max(1, Math.round(video.videoHeight * scale));\n const ctx = canvas.getContext(\"2d\");\n if (ctx === null) return video;\n if (canvas.width !== width) canvas.width = width;\n if (canvas.height !== height) canvas.height = height;\n ctx.drawImage(video, 0, 0, width, height);\n this.snapshotCanvas = canvas;\n return canvas;\n } catch {\n return video;\n }\n }\n\n private defaultQuality(\n video: HTMLVideoElement,\n box: { x: number; y: number; width: number; height: number },\n ): V3GateQuality {\n const crop = cropImageData(video, box, 96);\n if (crop === null) return NEUTRAL_QUALITY;\n return { sharpness: sharpness(crop), exposure: exposure(crop), meanLuma: meanLuma(crop) };\n }\n\n private centerSharpness(video: HTMLVideoElement): number {\n const size = intrinsicSize(video);\n const crop = cropImageData(\n video,\n { x: size.width * 0.25, y: size.height * 0.25, width: size.width * 0.5, height: size.height * 0.5 },\n 96,\n );\n return crop === null ? 0 : sharpness(crop);\n }\n\n // ── teardown ──────────────────────────────────────────────────────────────\n\n private teardownAttempt(): void {\n // No token bump here: retry()/switchCamera() call start() synchronously\n // right after, and START's own bump supersedes; destroy() bumps itself.\n this.scheduler?.stop();\n this.scheduler = null;\n this.gate = null;\n this.stopTracks();\n }\n\n private stopTracks(): void {\n if (this.stream === null) return;\n for (const track of this.stream.getTracks()) track.stop();\n this.stream = null;\n }\n\n private fail(kind: CaptureErrorKind, fallbackReason?: string): void {\n this.scheduler?.stop();\n this.stopTracks();\n this.setState(\"error\");\n this.options.telemetry?.({\n type: \"error\",\n kind,\n ...(fallbackReason !== undefined ? { fallbackReason } : {}),\n });\n // v1 canRetry semantics (capture-session.ts L424).\n this.emit(\"error\", { kind, retryable: kind !== \"insecure\" && kind !== \"unsupported\" });\n }\n\n private setState(state: CaptureState): void {\n this.stateValue = state;\n this.emit(\"statechange\", { state });\n }\n\n private now(): number {\n return this.options.now?.() ?? performance.now();\n }\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction describeError(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\n/** Downscaled face-crop ImageData for the quality measures; null where canvas\n * is unavailable (jsdom) — callers fall back to neutral quality. */\nfunction cropImageData(\n video: HTMLVideoElement,\n box: { x: number; y: number; width: number; height: number },\n targetWidth: number,\n): ImageData | null {\n try {\n const canvas = document.createElement(\"canvas\");\n const scale = targetWidth / Math.max(1, box.width);\n canvas.width = Math.max(1, Math.round(box.width * scale));\n canvas.height = Math.max(1, Math.round(box.height * scale));\n const ctx = canvas.getContext(\"2d\");\n if (ctx === null) return null;\n ctx.drawImage(\n video,\n box.x,\n box.y,\n box.width,\n box.height,\n 0,\n 0,\n canvas.width,\n canvas.height,\n );\n return ctx.getImageData(0, 0, canvas.width, canvas.height);\n } catch {\n return null;\n }\n}\n","// Tiny typed emitter (zero deps). Handlers are snapshotted before dispatch so an\n// unsubscribe from inside a handler never skips a sibling.\n\nexport interface Emitter<Events extends object> {\n on<K extends keyof Events>(event: K, handler: (payload: Events[K]) => void): () => void;\n emit<K extends keyof Events>(event: K, payload: Events[K]): void;\n clear(): void;\n}\n\nexport function createEmitter<Events extends object>(): Emitter<Events> {\n const handlers = new Map<keyof Events, Set<(payload: never) => void>>();\n return {\n on(event, handler) {\n let set = handlers.get(event);\n if (set === undefined) {\n set = new Set();\n handlers.set(event, set);\n }\n const h = handler as (payload: never) => void;\n set.add(h);\n return () => {\n set?.delete(h);\n };\n },\n emit(event, payload) {\n const set = handlers.get(event);\n if (set === undefined) return;\n for (const handler of [...set]) {\n (handler as (p: Events[typeof event]) => void)(payload);\n }\n },\n clear() {\n handlers.clear();\n },\n };\n}\n","// createLivenessCapture — the public, framework-free capture handle (spec\n// §3.1) over the calibration-pinned CaptureSessionV3 engine. It MAPS the\n// engine's event surface (statechange / checks / guidance / artifacts / error /\n// frozen) onto the partner contract (state / gate / captured / error) and owns\n// the NO_RECORDER degrade (photo mode → keyframe-only `captured`). Pinned\n// capture constants stay inside the engine — nothing here is configurable.\nimport { detectIsMobile } from \"../core/capture-constraints\";\nimport { isMediaRecorderSupported } from \"../core/media\";\nimport type { CaptureErrorKind as EngineErrorKind, CaptureState as EngineState } from \"../core/types\";\nimport {\n CaptureSessionV3,\n type CaptureSessionV3Events,\n type CaptureSessionV3Options,\n} from \"../core/v3/capture-session-v3\";\nimport { createEmitter } from \"../verification/emitter\";\nimport type {\n CaptureErrorKind,\n CaptureState,\n GateHint,\n LivenessCaptureEvents,\n LivenessCaptureHandle,\n LivenessCaptureOptions,\n} from \"../verification/types\";\n\n/** The engine surface the handle binds — CaptureSessionV3 or a test double. */\nexport interface CaptureEngine {\n readonly state: EngineState;\n on<K extends keyof CaptureSessionV3Events>(\n event: K,\n handler: (payload: CaptureSessionV3Events[K]) => void,\n ): () => void;\n start(): Promise<void>;\n retry(): void;\n switchCamera(): void;\n destroy(): void;\n /** Device-profile chrome hint (LOW class → `'reduced'`); absent on doubles. */\n readonly animations?: \"full\" | \"reduced\";\n}\n\n/** Internal construction seams (tests; Sekyro's own hosted page). */\nexport interface LivenessCaptureInternals {\n /** Replace the engine constructor (default: `new CaptureSessionV3(options)`). */\n createEngine?: (options: CaptureSessionV3Options) => CaptureEngine;\n /** Extra engine options merged in (worker offload, warmed detector, telemetry). */\n engineOptions?: Partial<\n Pick<CaptureSessionV3Options, \"createDetector\" | \"createWorker\" | \"telemetry\" | \"deviceClass\">\n >;\n /** Clock (default `performance.now`). */\n now?: () => number;\n}\n\n/** fcv3.* guidance key → public gate hint code. */\nexport function mapGuidanceHint(key: string): GateHint | null {\n switch (key) {\n case \"fcv3.no_face\":\n case \"fcv3.center_face\":\n case \"fcv3.straighten\":\n return \"center\";\n case \"fcv3.come_closer\":\n return \"closer\";\n case \"fcv3.move_back\":\n return \"farther\";\n case \"fcv3.more_light\":\n case \"fcv3.too_bright\":\n return \"light\";\n case \"fcv3.hold_still\":\n case \"fcv3.steady_camera\":\n return \"still\";\n default:\n return null;\n }\n}\n\n/** Engine state → public state (`preflight|acquiring → starting`, `positioning → gating`). */\nexport function mapEngineState(state: EngineState): CaptureState {\n switch (state) {\n case \"preflight\":\n case \"acquiring\":\n return \"starting\";\n case \"positioning\":\n return \"gating\";\n case \"idle\":\n case \"recording\":\n case \"captured\":\n case \"error\":\n return state;\n default: {\n const unhandled: never = state;\n throw new Error(`mapEngineState: unhandled state ${unhandled as string}`);\n }\n }\n}\n\n/** Engine error kinds → the public six (`models|cliptoolarge|recorder|overconstrained → generic`). */\nexport function mapErrorKind(kind: EngineErrorKind): CaptureErrorKind {\n switch (kind) {\n case \"permission\":\n case \"notfound\":\n case \"inuse\":\n case \"insecure\":\n case \"unsupported\":\n return kind;\n case \"overconstrained\":\n case \"generic\":\n case \"models\":\n case \"cliptoolarge\":\n case \"recorder\":\n return \"generic\";\n default: {\n const unhandled: never = kind;\n throw new Error(`mapErrorKind: unhandled kind ${unhandled as string}`);\n }\n }\n}\n\n/** Handle + the hooks the verification layer uses to drive the flow states. */\nexport interface LivenessCaptureInternalHandle {\n handle: LivenessCaptureHandle;\n /** Push a post-capture state (`uploading | checking | done`). */\n setFlowState(state: Extract<CaptureState, \"uploading\" | \"checking\" | \"done\">): void;\n}\n\nexport function createLivenessCaptureInternal(\n options: LivenessCaptureOptions,\n internals: LivenessCaptureInternals = {},\n): LivenessCaptureInternalHandle {\n const now = internals.now ?? (() => performance.now());\n const emitter = createEmitter<LivenessCaptureEvents>();\n // NO_RECORDER degrade: no MediaRecorder → photo mode (keyframe only). Decided\n // ONCE at construction; the artifacts carry the flag.\n const degraded = !isMediaRecorderSupported();\n const engineOptions: CaptureSessionV3Options = {\n video: options.video,\n mode: degraded ? \"photo\" : \"clip\",\n ...(options.facing !== undefined ? { facingMode: options.facing } : {}),\n ...(options.assetBaseUrl !== undefined ? { v3AssetBaseUrl: options.assetBaseUrl } : {}),\n ...(internals.engineOptions ?? {}),\n };\n const engine: CaptureEngine =\n internals.createEngine?.(engineOptions) ?? new CaptureSessionV3(engineOptions);\n\n let state: CaptureState = \"idle\";\n let hint: GateHint | null = null;\n let progress = 0;\n let faceDetected = false;\n let animations: \"full\" | \"reduced\" = \"full\";\n let recordingStartedAt: number | null = null;\n let frozenAt: number | null = null;\n // Frame size latched while the stream is LIVE: the engine stops the tracks\n // before it emits `artifacts`, and iOS Safari then reports videoWidth /\n // videoHeight as 0 (field: comparison records with width 0 / height 0).\n let frameWidth = 0;\n let frameHeight = 0;\n const latchFrameSize = (): void => {\n if (options.video.videoWidth > 0 && options.video.videoHeight > 0) {\n frameWidth = options.video.videoWidth;\n frameHeight = options.video.videoHeight;\n }\n };\n\n const setState = (next: CaptureState): void => {\n state = next;\n emitter.emit(\"state\", next);\n };\n const emitGate = (): void => emitter.emit(\"gate\", { progress, hint, faceDetected });\n // The LOW-profile hint settles once the engine probes (statechange) and may\n // flip mid-positioning on a dynamic demotion (per checks tick) — emit on change.\n const syncProfile = (): void => {\n const next = engine.animations ?? \"full\";\n if (next === animations) return;\n animations = next;\n emitter.emit(\"profile\", { animations });\n };\n\n const unsubscribes = [\n engine.on(\"statechange\", ({ state: engineState }) => {\n const next = mapEngineState(engineState);\n if (next === \"starting\" && state !== \"starting\") {\n // Fresh attempt: gate chrome resets.\n hint = null;\n progress = 0;\n faceDetected = false;\n recordingStartedAt = null;\n frozenAt = null;\n frameWidth = 0;\n frameHeight = 0;\n }\n setState(next);\n syncProfile();\n if (next === \"recording\") {\n latchFrameSize();\n recordingStartedAt = now();\n hint = \"hold\";\n progress = 1;\n emitGate();\n }\n }),\n engine.on(\"checks\", (payload) => {\n latchFrameSize(); // the engine only ticks on a live frame (videoWidth > 0)\n progress = payload.progress;\n faceDetected = payload.factors.presence > 0;\n emitGate();\n syncProfile();\n }),\n engine.on(\"guidance\", ({ key }) => {\n hint = mapGuidanceHint(key);\n emitGate();\n }),\n engine.on(\"frozen\", ({ previewDataUrl }) => {\n frozenAt = now();\n emitter.emit(\"frozen\", { previewDataUrl });\n }),\n engine.on(\"artifacts\", (artifacts) => {\n const clipMs =\n recordingStartedAt !== null && frozenAt !== null\n ? Math.max(0, Math.round(frozenAt - recordingStartedAt))\n : undefined;\n emitter.emit(\"captured\", {\n keyframe: artifacts.keyframe,\n ...(artifacts.clip !== undefined ? { clip: artifacts.clip } : {}),\n ...(artifacts.clipMimeType !== undefined ? { clipMime: artifacts.clipMimeType } : {}),\n width: options.video.videoWidth || frameWidth,\n height: options.video.videoHeight || frameHeight,\n ...(clipMs !== undefined ? { clipMs } : {}),\n captureChannel: detectIsMobile() ? \"mobile\" : \"desktop\",\n ...(degraded ? { degraded: \"NO_RECORDER\" as const } : {}),\n engine: \"v3\",\n // Face-capture timing: the engine's marks, forwarded flat (absent → absent).\n ...(artifacts.timing?.cameraReadyMs !== undefined\n ? { cameraReadyMs: artifacts.timing.cameraReadyMs }\n : {}),\n ...(artifacts.timing?.faceAcquireMs !== undefined\n ? { faceAcquireMs: artifacts.timing.faceAcquireMs }\n : {}),\n ...(artifacts.timing?.captureMs !== undefined\n ? { captureMs: artifacts.timing.captureMs }\n : {}),\n });\n }),\n engine.on(\"error\", ({ kind, retryable }) => {\n emitter.emit(\"error\", { kind: mapErrorKind(kind), retryable });\n }),\n ];\n\n const handle: LivenessCaptureHandle = {\n get state() {\n return state;\n },\n on: (event, handler) => emitter.on(event, handler),\n start: () => engine.start(),\n retry: () => engine.retry(),\n switchCamera: () => engine.switchCamera(),\n destroy: () => {\n for (const unsubscribe of unsubscribes) unsubscribe();\n engine.destroy();\n emitter.clear();\n },\n };\n\n return {\n handle,\n setFlowState: (next) => {\n if (state !== next) setState(next);\n },\n };\n}\n\n/**\n * Create a standalone liveness capture (no upload — pair it with your own\n * submission, or use {@link Verification.liveness} for the full flow).\n */\nexport function createLivenessCapture(options: LivenessCaptureOptions): LivenessCaptureHandle {\n return createLivenessCaptureInternal(options).handle;\n}\n","// Public error map for the session-token surface (Plan 6 Task 5).\n//\n// The backend's AllExceptionsFilter (audience 'public') emits the FLAT envelope\n// `{code, message}` — no details, no request_id, no traceId. `code` is the\n// snake_cased `error` key of the thrown HttpException body (extractError →\n// camelToSnake). 429 responses additionally carry a `Retry-After` header in\n// SECONDS (SessionTokenGuard / RateLimitGuard).\n//\n// KNOWN_CODES below is the VERIFIED set reachable through the five hosted\n// endpoints (grep of `error: '…'` sites in identity-backend @ Tasks 0+1+2 —\n// hosted.controller, checks.controller, media.{controller,service},\n// sessions.service submit flow, session-token.guard, valibot.pipe,\n// check-executor registry, idempotency.interceptor, attestation mapping),\n// plus four CLIENT-SYNTHESIZED codes that never come from the backend:\n// - 'unknown_error' — a response body that was not parseable JSON (proxy HTML\n// on an error, or a malformed 2xx body)\n// - 'upload_failed' — the bare Spaces PUT answered non-2xx (S3 XML, no envelope)\n// - 'network_error' — fetch itself rejected: connection drop / DNS / CORS /\n// mid-transfer failure (status: 0 — no response arrived)\n// - 'timeout' — the request's AbortSignal.timeout fired (status: 0)\n// Task 7's error-copy map must carry entries for all four from day one.\n//\n// Deliberately EXCLUDED (verified unreachable on this surface today):\n// - payment_required / account_suspended — BillingInterceptor gates only\n// handlers decorated @BillableCheck, and no handler is decorated yet.\n// - not_found — the generic unmatched-route 404; a correctly configured client\n// never produces it. Unknown codes route through `isKnownCode() === false`.\n\n/**\n * Every error code the hosted page can receive from the session-token surface.\n * A closed string-literal union — switch over {@link KnownCode} with a `never`\n * default arm for compile-checked exhaustiveness.\n */\nexport const KNOWN_CODES = [\n // auth / addressing (session-token.guard, controllers' own-session guards)\n \"session_token_invalid\", // 401 — missing/invalid/expired/revoked token\n \"session_token_required\", // 403 — non-session-token principal on a hosted route (defensive)\n \"session_token_session_mismatch\", // 403 — route :id differs from the token's bound session\n \"session_not_found\", // 404 — token's session missing/foreign (findOwned)\n // rate limiting (session-token.guard — per-token + per-IP buckets)\n \"rate_limit_exceeded\", // 429 + Retry-After header (seconds)\n // consent gate (Task 0 — submit AND media presign/complete)\n \"consent_required\", // 409 — record consent before uploading/submitting\n // submit flow (sessions.service.submitCheck)\n \"session_not_active\", // 409 — session is terminal/review; no further submissions\n \"check_not_found\", // 404 — session has no such checkType\n \"check_already_finalized\", // 409 — re-submit of a terminal/review check\n \"check_out_of_order\", // 409 — only the frontier check accepts a submission\n \"check_type_unsupported\", // 400 — no registered executor for the checkType\n \"force_outcome_forbidden\", // 403 — forceOutcome on a live session (plan D-C)\n \"attestation_invalid\", // 400 (Task 1) — Turnstile/attestation failed; reload and retry\n \"nni_locked\", // 409 (Plan A Task 2) — session is bound to a server-provided NNI; a different client NNI was sent\n // media (media.service)\n \"media_content_type_not_allowed\", // 400 — outside the per-kind MIME allowlist\n \"media_too_large\", // 413 — over the per-kind byte cap\n \"media_key_invalid\", // 400 — not a well-formed pending key\n \"media_key_forbidden\", // 403 — key names another session's pending space\n \"media_not_found\", // 404 — no uploaded object behind the key\n \"media_unreadable\", // 422 — magic-byte sniff rejected the object\n \"media_session_invalid\", // 400 — sessionId unusable as a key segment (never in practice)\n // idempotency (idempotency.interceptor — Task 2)\n \"idempotency_key_collision\", // 409 — same key, different body hash\n \"idempotency_in_progress\", // 409 — concurrent identical request mid-flight (client auto-retries)\n \"idempotency_key_required\", // 400 — only on @Idempotent({required:true}) routes (none hosted yet)\n // validation + fallback\n \"validation_error\", // 400 — ValibotPipe rejection (camelToSnake of 'ValidationError')\n \"internal_error\", // 500 — unhandled server error\n // client-synthesized (never sent by the backend)\n \"unknown_error\", // unparseable (non-JSON) response body — error OR 2xx (defensive)\n \"upload_failed\", // the bare Spaces PUT answered non-2xx\n \"network_error\", // fetch rejected: connection drop / DNS / CORS / mid-transfer (status 0)\n \"timeout\", // AbortSignal.timeout fired — API calls 30 s default, Spaces PUT 15 min (status 0)\n] as const;\n\n/** Closed union of {@link KNOWN_CODES} — exhaustively switchable. */\nexport type KnownCode = (typeof KNOWN_CODES)[number];\n\n/** Narrow an arbitrary wire code to the known union (unknown codes stay `string`). */\nexport function isKnownCode(code: string): code is KnownCode {\n return (KNOWN_CODES as readonly string[]).includes(code);\n}\n\n/**\n * Typed transport error: EVERY failure surfaces as one of these — non-2xx\n * responses, rejected fetches, timeouts, and unparseable bodies alike. The\n * hosted page never sees a raw TypeError/DOMException from the client.\n *\n * - `code` — the public envelope's `code`, or a client-synthesized fallback\n * ('unknown_error' / 'upload_failed' / 'network_error' / 'timeout'). Typed\n * `string` because the wire may grow codes; narrow with {@link isKnownCode}\n * before an exhaustive switch.\n * - `status` — the HTTP status, or 0 when no response arrived at all\n * ('network_error' / 'timeout').\n * - `retryAfterSeconds` — parsed from the `Retry-After` header when present\n * (rate-limit 429s always set it).\n */\nexport class HostedApiError extends Error {\n readonly status: number;\n readonly code: string;\n readonly retryAfterSeconds?: number;\n\n constructor(args: { status: number; code: string; message: string; retryAfterSeconds?: number }) {\n super(args.message);\n this.name = \"HostedApiError\";\n this.status = args.status;\n this.code = args.code;\n if (args.retryAfterSeconds !== undefined) this.retryAfterSeconds = args.retryAfterSeconds;\n }\n}\n","// Typed API client for the hosted session-token surface (Plan 6 Task 5).\n// Framework-free browser code — fetch + AbortSignal only, same zero-React rule\n// as core/. Hand-authored against the CURRENT identity-backend (Tasks 0+1+2);\n// see types.ts / errors.ts for the verified wire shapes.\nimport { HostedApiError } from \"./errors\";\nimport type {\n CheckInputByType,\n CheckType,\n CompleteMediaResult,\n ConsentLocale,\n HostedSessionView,\n MediaKind,\n PresignRequest,\n PresignUploadResult,\n RecordConsentResult,\n SessionView,\n SubmitCheckBody,\n} from \"./types\";\n\n/** Default per-request timeout on API calls (override via `requestTimeoutMs`). */\nconst DEFAULT_REQUEST_TIMEOUT_MS = 30_000;\n\n/**\n * Timeout on the Spaces PUT — matches the presign TTL (900 s): the signature is\n * unusable after that anyway, and a 15 MB clip at 20 KB/s still finishes in\n * ~13 min. Bounds a stalled in-flight socket (the TTL alone only bounds when a\n * PUT can START, not how long a hung transfer may sit).\n */\nconst SPACES_PUT_TIMEOUT_MS = 900_000;\n\n/** Max chars of an S3 error body quoted into an upload_failed message. */\nconst UPLOAD_ERROR_SNIPPET_CHARS = 200;\n\n/** Bounded auto-retry defaults for 409 `idempotency_in_progress` (retries AFTER the first try). */\nconst IN_PROGRESS_RETRY_ATTEMPTS = 5;\nconst IN_PROGRESS_RETRY_DELAY_MS = 400;\n\n/**\n * Strip MIME parameters: `video/webm;codecs=vp8,opus` → `video/webm`.\n *\n * The capture engine (Task 4) emits `clipMimeType` WITH codec parameters, but\n * the presign allowlist holds BARE types only (['video/webm','video/mp4'] /\n * ['image/jpeg','image/png']) and the presigned PUT signs the exact declared\n * Content-Type. Exported so pages can normalize once and stay byte-consistent\n * between presign and PUT.\n */\nexport function stripMimeParams(contentType: string): string {\n return (contentType.split(\";\")[0] ?? \"\").trim();\n}\n\n/** Media-bearing check types → the input field the promoted key goes into. */\nconst MEDIA_INPUT_FIELD = {\n liveness: \"clipKey\",\n face_match: \"imageKey\",\n doc_ocr: \"imageKey\",\n} as const;\n\n/** Check types that take an uploaded media key (population_registry does not). */\nexport type MediaCheckType = keyof typeof MEDIA_INPUT_FIELD;\n\nexport interface SubmitOptions {\n /**\n * Sent as `x-idempotency-key` (the header IdempotencyInterceptor reads).\n * One key per LOGICAL submit — a flaky-network retry with the same key\n * replays the first response without burning another attempt.\n */\n idempotencyKey?: string;\n /** SANDBOX-ONLY deterministic override (plan D-C); a live session 403s it. */\n forceOutcome?: \"pass\" | \"fail\";\n}\n\nexport interface UploadMedia {\n kind: MediaKind;\n blob: Blob;\n /** May carry codec params (engine `clipMimeType`) — stripped before presign AND PUT. */\n contentType: string;\n}\n\nexport interface HostedClientOptions {\n /** API origin, e.g. `https://api.sekyro.ai` — paths are `${apiOrigin}/api/v2/...`. */\n apiOrigin: string;\n /** The raw session token from the hosted URL (short code; legacy `cst_` during its TTL) — sent as `x-session-token` on every API call. */\n sessionToken: string;\n /** Injection seam (tests / non-window contexts). Defaults to `globalThis.fetch`. */\n fetch?: typeof globalThis.fetch;\n /** Per-request timeout for API calls (NOT the Spaces PUT). Default 30 000 ms. */\n requestTimeoutMs?: number;\n /**\n * Tuning for the ONLY automatic retry the client performs: 409\n * `idempotency_in_progress` (a concurrent identical request is mid-flight\n * server-side; the real response lands once it finishes). `attempts` counts\n * retries AFTER the first try. Defaults: 5 × 400 ms.\n */\n inProgressRetry?: { attempts?: number; delayMs?: number };\n}\n\n/**\n * Hand-authored typed client for the five session-token endpoints:\n *\n * GET /api/v2/hosted/session → {@link getSession}\n * POST /api/v2/hosted/consent → {@link recordConsent}\n * POST /api/v2/sessions/:id/media → {@link presign}\n * POST /api/v2/sessions/:id/media/complete → {@link completeMedia}\n * POST /api/v2/sessions/:id/checks/:checkType → {@link submitCheck}\n *\n * plus the bare presigned Spaces PUT ({@link uploadToSpaces}) and the\n * presign→PUT→complete→submit composition ({@link uploadAndSubmit}).\n *\n * Envelopes (verified against sessions-docs.e2e-spec.ts):\n * - success: `{success: true, data}` — unwrapped here, methods return the payload;\n * - error: flat `{code, message}` → thrown as {@link HostedApiError}.\n *\n * The media/checks routes are `:id`-addressed while the token itself is the\n * only credential the page starts with — the client learns its sessionId from\n * `GET /hosted/session` (token-addressed) and lazily bootstraps it when a\n * `:id` route is called first.\n *\n * No automatic retry EXCEPT bounded short-delay retry on 409\n * `idempotency_in_progress`. Everything else — including 429 with its parsed\n * `retryAfterSeconds` — is surfaced to the page to handle.\n */\nexport class HostedClient {\n private readonly apiOrigin: string;\n private readonly sessionToken: string;\n private readonly fetchImpl: typeof globalThis.fetch;\n private readonly requestTimeoutMs: number;\n private readonly retryAttempts: number;\n private readonly retryDelayMs: number;\n\n private sessionId: string | null = null;\n private bootstrap: Promise<HostedSessionView> | null = null;\n\n constructor(opts: HostedClientOptions) {\n this.apiOrigin = opts.apiOrigin.replace(/\\/+$/, \"\");\n this.sessionToken = opts.sessionToken;\n // Always wrap and `.call(globalThis, …)`: browsers throw \"Illegal\n // invocation\" when fetch runs with a `this` that isn't the global — both\n // for the default AND for an injected `window.fetch`.\n const impl = opts.fetch;\n this.fetchImpl = (input, init) => (impl ?? globalThis.fetch).call(globalThis, input, init);\n this.requestTimeoutMs = opts.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;\n this.retryAttempts = opts.inProgressRetry?.attempts ?? IN_PROGRESS_RETRY_ATTEMPTS;\n this.retryDelayMs = opts.inProgressRetry?.delayMs ?? IN_PROGRESS_RETRY_DELAY_MS;\n }\n\n /** Token-addressed bootstrap — the hosted page's first call. Caches the sessionId. */\n async getSession(): Promise<HostedSessionView> {\n const view = await this.api<HostedSessionView>(\"GET\", \"/hosted/session\");\n this.sessionId = view.sessionId;\n return view;\n }\n\n /**\n * Record consent once (201; an idempotent replay answers 200 with\n * `alreadyRecorded: true`). Until recorded, media presign/complete AND check\n * submission answer 409 `consent_required`.\n */\n async recordConsent(locale: ConsentLocale): Promise<RecordConsentResult> {\n return this.api<RecordConsentResult>(\"POST\", \"/hosted/consent\", { body: { locale } });\n }\n\n /**\n * Presign a Spaces PUT for a new pending object. `contentType` is stripped of\n * MIME parameters defensively (the allowlist holds bare types; the engine's\n * `clipMimeType` carries codec params) — PUT with the SAME bare type, or the\n * signed-header check rejects the upload.\n */\n async presign(\n kind: MediaKind,\n contentType: string,\n contentLength: number,\n ): Promise<PresignUploadResult> {\n const id = await this.ensureSessionId();\n const body: PresignRequest = { kind, contentType: stripMimeParams(contentType), contentLength };\n return this.api<PresignUploadResult>(\"POST\", `/sessions/${id}/media`, { body });\n }\n\n /**\n * Bare PUT to the presigned Spaces URL: EXACTLY the signed headers — the\n * declared Content-Type and the blob body. NO `x-session-token` (the\n * signature IS the credential; an extra header breaks nothing but leaks the\n * token to a third-party host) and no JSON envelope.\n *\n * `contentType` is param-stripped here too (idempotent for bare types): the\n * presign strips internally, so a caller composing manually with the engine's\n * parameterful `clipMimeType` would otherwise sign `video/webm` but PUT\n * `video/webm;codecs=…` — a signed-header mismatch S3 rejects at runtime.\n *\n * Timeout: 15 min (`AbortSignal.timeout(900_000)`, matching the presign TTL)\n * rather than the API calls' 30 s — a 15 MB clip on a slow link legitimately\n * exceeds 30 s, but a stalled in-flight socket must still be bounded (the TTL\n * alone only bounds when a PUT can START).\n *\n * Failures are ALWAYS typed: non-2xx throws {@link HostedApiError} with the\n * client-synthesized `upload_failed` (message carries a truncated S3 body\n * snippet — e.g. SignatureDoesNotMatch); a mid-transfer drop → `network_error`;\n * the timeout → `timeout`.\n */\n async uploadToSpaces(uploadUrl: string, blob: Blob, contentType: string): Promise<void> {\n let res: Response;\n try {\n res = await this.fetchImpl(uploadUrl, {\n method: \"PUT\",\n headers: { \"content-type\": stripMimeParams(contentType) },\n body: blob,\n signal: AbortSignal.timeout(SPACES_PUT_TIMEOUT_MS),\n });\n } catch (err) {\n throw asTransportError(err);\n }\n if (!res.ok) {\n const snippet = (await res.text().catch(() => \"\")).slice(0, UPLOAD_ERROR_SNIPPET_CHARS);\n throw new HostedApiError({\n status: res.status,\n code: \"upload_failed\",\n message: `media upload failed (HTTP ${res.status})${snippet ? `: ${snippet}` : \"\"}`,\n });\n }\n }\n\n /** Finalize an upload: the backend sniffs + promotes; returns the PROMOTED key to submit. */\n async completeMedia(key: string): Promise<CompleteMediaResult> {\n const id = await this.ensureSessionId();\n return this.api<CompleteMediaResult>(\"POST\", `/sessions/${id}/media/complete`, {\n body: { key },\n });\n }\n\n /**\n * Submit one check. Sends `{input, forceOutcome?}` (SubmitCheckSchema) and the\n * optional `x-idempotency-key` header. Returns the whitelisted SessionView.\n */\n async submitCheck<T extends CheckType>(\n checkType: T,\n input: CheckInputByType[T],\n opts: SubmitOptions = {},\n ): Promise<SessionView> {\n const id = await this.ensureSessionId();\n const body: SubmitCheckBody = {\n input: input as unknown as Record<string, unknown>,\n ...(opts.forceOutcome !== undefined ? { forceOutcome: opts.forceOutcome } : {}),\n };\n return this.api<SessionView>(\"POST\", `/sessions/${id}/checks/${checkType}`, {\n body,\n ...(opts.idempotencyKey !== undefined ? { idempotencyKey: opts.idempotencyKey } : {}),\n });\n }\n\n /**\n * Convenience composition: presign → PUT → complete → submit, passing the\n * PROMOTED key (from complete's response — never the pending presign key)\n * into the check's media input field (`clipKey` for liveness, `imageKey` for\n * face_match/doc_ocr). `extraInput` carries the remaining input fields\n * (liveness `attestation`, doc_ocr `side`). The media content type is\n * param-stripped ONCE and used for both presign and PUT, so the signed\n * header always matches.\n */\n async uploadAndSubmit<T extends MediaCheckType>(\n checkType: T,\n media: UploadMedia,\n extraInput: Omit<CheckInputByType[T], (typeof MEDIA_INPUT_FIELD)[T]>,\n opts: SubmitOptions = {},\n ): Promise<SessionView> {\n const bareType = stripMimeParams(media.contentType);\n const presigned = await this.presign(media.kind, bareType, media.blob.size);\n await this.uploadToSpaces(presigned.uploadUrl, media.blob, bareType);\n const completed = await this.completeMedia(presigned.key);\n const input = {\n ...extraInput,\n [MEDIA_INPUT_FIELD[checkType]]: completed.key,\n } as unknown as CheckInputByType[T];\n return this.submitCheck(checkType, input, opts);\n }\n\n // ── transport ──────────────────────────────────────────────────────────────\n\n /** The token's own sessionId — cached from getSession(), lazily bootstrapped. */\n private async ensureSessionId(): Promise<string> {\n if (this.sessionId !== null) return this.sessionId;\n // Dedupe concurrent bootstraps; reset on settle so a failure can be retried.\n this.bootstrap ??= this.getSession().finally(() => {\n this.bootstrap = null;\n });\n return (await this.bootstrap).sessionId;\n }\n\n /**\n * One API request: `${apiOrigin}/api/v2${path}`, `x-session-token` always,\n * AbortSignal timeout (30 s default), `{success, data}` unwrap on 2xx, flat\n * `{code, message}` → {@link HostedApiError} on non-2xx. EVERY failure is\n * typed: a rejected fetch → `network_error`, the timeout → `timeout`, an\n * unparseable 2xx body → `unknown_error` — the page never sees a raw\n * TypeError/DOMException. The ONLY automatic retry is 409\n * `idempotency_in_progress` (bounded, short delay).\n */\n private async api<T>(\n method: \"GET\" | \"POST\",\n path: string,\n opts: { body?: unknown; idempotencyKey?: string } = {},\n ): Promise<T> {\n const url = `${this.apiOrigin}/api/v2${path}`;\n const headers: Record<string, string> = { \"x-session-token\": this.sessionToken };\n if (opts.body !== undefined) headers[\"content-type\"] = \"application/json\";\n if (opts.idempotencyKey !== undefined) headers[\"x-idempotency-key\"] = opts.idempotencyKey;\n\n for (let attempt = 0; ; attempt++) {\n let res: Response;\n try {\n res = await this.fetchImpl(url, {\n method,\n headers,\n ...(opts.body !== undefined ? { body: JSON.stringify(opts.body) } : {}),\n signal: AbortSignal.timeout(this.requestTimeoutMs),\n });\n } catch (err) {\n throw asTransportError(err);\n }\n\n if (res.ok) {\n let raw: unknown;\n try {\n raw = await res.json();\n } catch {\n throw new HostedApiError({\n status: res.status,\n code: \"unknown_error\",\n message: `response body was not valid JSON (HTTP ${res.status})`,\n });\n }\n return unwrap<T>(raw);\n }\n\n const err = await parseErrorResponse(res);\n if (err.code === \"idempotency_in_progress\" && attempt < this.retryAttempts) {\n if (this.retryDelayMs > 0) await sleep(this.retryDelayMs);\n continue;\n }\n throw err;\n }\n }\n}\n\n/**\n * Normalize a rejected fetch into the typed contract (status 0 — no response\n * arrived): AbortSignal.timeout aborts with a DOMException named 'TimeoutError'\n * → `timeout`; everything else (TypeError on connection drop / DNS / CORS /\n * mid-transfer failure) → `network_error`. Duck-typed on `.name` because\n * DOMException does not inherit Error in every environment (e.g. jsdom).\n */\nfunction asTransportError(err: unknown): HostedApiError {\n const name = typeof err === \"object\" && err !== null ? (err as { name?: unknown }).name : undefined;\n if (name === \"TimeoutError\") {\n return new HostedApiError({ status: 0, code: \"timeout\", message: \"request timed out\" });\n }\n const detail = err instanceof Error ? err.message : String(err);\n return new HostedApiError({\n status: 0,\n code: \"network_error\",\n message: `network request failed: ${detail}`,\n });\n}\n\n/**\n * Unwrap the global success envelope `{success: true, data}` (ResponseTransform-\n * Interceptor wraps every object body that lacks a `success` key). Defensive:\n * a body without the envelope is returned as-is.\n */\nfunction unwrap<T>(raw: unknown): T {\n if (raw !== null && typeof raw === \"object\" && \"success\" in raw && \"data\" in raw) {\n return (raw as { data: T }).data;\n }\n return raw as T;\n}\n\n/**\n * Parse a non-2xx response into a {@link HostedApiError}: the public envelope\n * is flat `{code, message}`; a non-JSON body (proxy HTML, etc.) degrades to the\n * client-synthesized `unknown_error`. `Retry-After` (seconds) is parsed when\n * present — rate-limit 429s always set it.\n */\nasync function parseErrorResponse(res: Response): Promise<HostedApiError> {\n let code = \"unknown_error\";\n let message = `request failed (HTTP ${res.status})`;\n try {\n const body: unknown = await res.json();\n if (body !== null && typeof body === \"object\") {\n const env = body as { code?: unknown; message?: unknown };\n if (typeof env.code === \"string\" && env.code.length > 0) code = env.code;\n if (typeof env.message === \"string\" && env.message.length > 0) message = env.message;\n }\n } catch {\n // Not JSON — keep the defensive fallback.\n }\n const retryAfterRaw = res.headers.get(\"retry-after\");\n const retryAfter = retryAfterRaw === null ? Number.NaN : Number.parseInt(retryAfterRaw, 10);\n return new HostedApiError({\n status: res.status,\n code,\n message,\n ...(Number.isFinite(retryAfter) && retryAfter >= 0 ? { retryAfterSeconds: retryAfter } : {}),\n });\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","// Result mapping: server view → the public VerificationResult (spec §3.1) plus\n// the view helpers the flow needs (frontier, terminal, view merge).\nimport type {\n CheckReason,\n CheckType,\n HostedSessionView,\n HostedStepView,\n SessionView,\n} from \"../client/types\";\nimport type { ReasonCode, VerificationResult } from \"./types\";\n\n/**\n * Reasons the backend parks at `input_required` while attempts remain\n * (identity-backend/src/checks/check-reasons.ts isRetryable tables — the single\n * source of truth; identity-hosted/lib/reason-copy.ts mirrors the same rows).\n */\nexport const RETRYABLE_REASONS: ReadonlySet<CheckReason> = new Set<CheckReason>([\n \"no_face\",\n \"media_unreadable\",\n \"clip_too_short\",\n \"no_face_source\",\n \"side_missing\",\n \"unreadable\",\n \"registry_unavailable\",\n \"otp_mismatch\",\n \"otp_expired\",\n \"otp_send_failed\",\n]);\n\n/** The two checks one biometric capture feeds. */\nconst BIOMETRIC_CHECKS: ReadonlySet<CheckType> = new Set<CheckType>([\"liveness\", \"face_match\"]);\n\n/** A check the browser may still submit. */\nexport function isExecutable(step: HostedStepView | undefined): boolean {\n return step !== undefined && (step.state === \"pending\" || step.state === \"input_required\");\n}\n\n/** The session accepts no further submissions. */\nexport function isTerminalView(view: Pick<HostedSessionView, \"status\">): boolean {\n return view.status !== \"created\" && view.status !== \"in_progress\";\n}\n\n/** First step in `steps[]` order with state `pending | input_required` (the backend's frontier). */\nexport function frontierStep(view: HostedSessionView): HostedStepView | undefined {\n return view.steps.find((step) => isExecutable(step));\n}\n\nexport function stepOf(view: HostedSessionView, checkType: CheckType): HostedStepView | undefined {\n return view.steps.find((step) => step.checkType === checkType);\n}\n\n/**\n * Fold a submit response (partner `SessionView`: no attemptsRemaining) into the\n * hosted view: status/outcome/step states+reasons come from the response; the\n * submitted check's `attemptsRemaining` is decremented locally (every accepted\n * submit consumes exactly one attempt server-side — `max(0, cap - attempts)`).\n * This keeps the happy path free of extra `GET /hosted/session` round-trips.\n */\nexport function mergeSessionView(\n prev: HostedSessionView,\n next: SessionView,\n submitted: CheckType,\n): HostedSessionView {\n const byType = new Map(prev.steps.map((step) => [step.checkType, step] as const));\n const steps: HostedStepView[] = next.steps.map((step) => {\n const before = byType.get(step.checkType);\n const attemptsBefore = before?.attemptsRemaining ?? 0;\n const merged: HostedStepView = {\n ...(before ?? {}),\n checkType: step.checkType,\n state: step.state,\n attemptsRemaining:\n step.checkType === submitted ? Math.max(0, attemptsBefore - 1) : attemptsBefore,\n };\n if (step.reason !== undefined) merged.reason = step.reason;\n else delete merged.reason;\n return merged;\n });\n return { ...prev, status: next.status, outcome: next.outcome, steps, expiresAt: next.expiresAt };\n}\n\nexport function unavailable(sessionId: string, reason?: ReasonCode): VerificationResult {\n return reason === undefined\n ? { sessionId, status: \"unavailable\" }\n : { sessionId, status: \"unavailable\", reason };\n}\n\nfunction withReason(\n sessionId: string,\n status: VerificationResult[\"status\"],\n reason: CheckReason | undefined,\n): VerificationResult {\n return reason === undefined ? { sessionId, status } : { sessionId, status, reason };\n}\n\n/**\n * Map the session view to the public result:\n * - `completed/approved → approved`, `completed/review` or `review_pending → review`,\n * `failed` or `completed/rejected → rejected` (reason = the deciding step's);\n * - `expired → unavailable` (no reason);\n * - in flight: a biometric step parked at `input_required` with a retryable\n * reason → `retry` when `autoRetry` and attempts remain, else `rejected`\n * (the partner opted out of retries — this capture was refused); a step in\n * `review` with nothing executable left → `review`; otherwise `unavailable`\n * (a non-biometric frontier the SDK cannot drive, or still processing).\n */\nexport function mapSessionResult(\n view: HostedSessionView,\n opts: { autoRetry: boolean },\n): VerificationResult {\n const { sessionId } = view;\n switch (view.status) {\n case \"completed\":\n if (view.outcome === \"approved\") return { sessionId, status: \"approved\" };\n if (view.outcome === \"review\") return withReason(sessionId, \"review\", reasonIn(view, \"review\"));\n return withReason(sessionId, \"rejected\", reasonIn(view, \"failed\"));\n case \"failed\":\n return withReason(sessionId, \"rejected\", reasonIn(view, \"failed\"));\n case \"review_pending\":\n return withReason(sessionId, \"review\", reasonIn(view, \"review\"));\n case \"expired\":\n return unavailable(sessionId);\n case \"created\":\n case \"in_progress\":\n break;\n default: {\n const unhandled: never = view.status;\n throw new Error(`mapSessionResult: unhandled status ${unhandled as string}`);\n }\n }\n\n const parked = view.steps.find(\n (step) =>\n BIOMETRIC_CHECKS.has(step.checkType) &&\n step.state === \"input_required\" &&\n step.reason !== undefined,\n );\n if (parked?.reason !== undefined) {\n const canRetry =\n opts.autoRetry && RETRYABLE_REASONS.has(parked.reason) && parked.attemptsRemaining > 0;\n return {\n sessionId,\n status: canRetry ? \"retry\" : \"rejected\",\n reason: parked.reason,\n attemptsRemaining: parked.attemptsRemaining,\n };\n }\n if (frontierStep(view) === undefined && view.steps.some((step) => step.state === \"review\")) {\n return withReason(sessionId, \"review\", reasonIn(view, \"review\"));\n }\n return unavailable(sessionId);\n}\n\n/** Reason of the first step in the given state (the deciding check). */\nfunction reasonIn(view: HostedSessionView, state: HostedStepView[\"state\"]): CheckReason | undefined {\n return view.steps.find((step) => step.state === state && step.reason !== undefined)?.reason;\n}\n","// The post-capture flow, driven by the CURRENT hosted frontier: when `liveness`\n// is the frontier → upload the clip → attestation → submit `liveness`, then\n// `face_match` from this capture's keyframe; when liveness already settled and\n// `face_match` is the frontier → keyframe + `face_match` only; nothing the SDK\n// can drive → settled (the caller maps the view). A RESYNC 409\n// (check_already_finalized / check_out_of_order / stale frontier) re-GETs the\n// view and RE-ENTERS the same frontier logic (bounded) instead of giving up —\n// a liveness that passed under an earlier run still gets its face_match.\n// Logic ported (not the React) from\n// identity-hosted/lib/use-submit.ts (idempotency-key lifecycle, same-key\n// transport replay, one-shot consent_required recovery) and\n// lib/use-capture-submission.ts + components/steps/liveness-step.tsx (the\n// `buildSubmit` executor closures and the face_match chain).\n//\n// Per-submission caches (promoted media key, attestation) are CLOSURE LOCALS of\n// each executor: a same-key replay re-runs the executor with the caches intact\n// (byte-identical body — a re-presign or a fresh token under the same key would\n// be an idempotency_key_collision); fresh artifacts build fresh closures.\nimport { HostedApiError } from \"../client/errors\";\nimport { type HostedClient, stripMimeParams } from \"../client/hosted-client\";\nimport type {\n AttestationInput,\n CheckType,\n HostedSessionView,\n LivenessCaptureInput,\n SessionView,\n} from \"../client/types\";\nimport { frontierStep, isTerminalView, stepOf } from \"./result\";\nimport type { CapturedArtifacts, SdkFailureReason } from \"./types\";\n\n/** The client surface the flow needs — `HostedClient` or a test fake. */\nexport type HostedClientLike = Pick<\n HostedClient,\n \"getSession\" | \"recordConsent\" | \"presign\" | \"uploadToSpaces\" | \"completeMedia\" | \"submitCheck\"\n>;\n\n/** The presign policy allowlist for `kind: 'clip'` (media.policy.ts mirror). */\nexport const CLIP_MIME_ALLOWLIST: readonly string[] = [\"video/webm\", \"video/mp4\"];\n\n/** The engine's keyframe encode (captureMirroredKeyframe → canvas JPEG). */\nconst KEYFRAME_MIME = \"image/jpeg\";\n\n/** Same-key transport replays AFTER the first try, and the pause between them. */\nexport const TRANSPORT_REPLAY_ATTEMPTS = 2;\nexport const TRANSPORT_REPLAY_DELAY_MS = 1_000;\n/** Cap on honouring a 429's Retry-After before giving up on this capture. */\nconst MAX_RETRY_AFTER_MS = 10_000;\n/**\n * Bound on frontier re-entries after a RESYNC code per capture (each re-entry\n * re-GETs the view; each executable check is submitted at most once per capture).\n */\nexport const RESYNC_REENTRY_MAX = 3;\n\n/** No (usable) response arrived — a same-key replay can succeed. */\nconst TRANSPORT_CODES: ReadonlySet<string> = new Set([\n \"network_error\",\n \"timeout\",\n \"upload_failed\",\n \"unknown_error\",\n \"rate_limit_exceeded\",\n]);\n\n/** The server moved past what we hold — re-GET and map from truth. */\nconst RESYNC_CODES: ReadonlySet<string> = new Set([\n \"session_not_active\",\n \"check_not_found\",\n \"check_already_finalized\",\n \"check_out_of_order\",\n]);\n\n/** A Turnstile challenge failed client-side (load / render / error-callback / timeout). */\nexport class AttestationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"AttestationError\";\n }\n}\n\n/** One logical submission: receives the client and ITS idempotency key. */\nexport type SubmitExecutor = (\n client: HostedClientLike,\n idempotencyKey: string,\n) => Promise<SessionView>;\n\nexport interface SubmitRuntime {\n client: HostedClientLike;\n /** Force-record consent (the server just said it is missing). */\n ensureConsent(opts: { force: true }): Promise<void>;\n sleep(ms: number): Promise<void>;\n uuid(): string;\n}\n\n/**\n * Run one logical submission (ported use-submit semantics):\n * - a fresh `crypto.randomUUID()` key per logical submission;\n * - a transport-class failure replays the SAME executor under the SAME key\n * (bounded) — the backend's IdempotencyInterceptor returns the first\n * response instead of burning another attempt;\n * - ONE `consent_required` recovery: force-record consent and re-run under a\n * FRESH key (the 409 envelope is idempotency-cached under the old one);\n * - ONE attestation retry (client-side Turnstile failure or a server\n * `attestation_invalid`): `onAttestationInvalid` drops the cached token and\n * the executor re-runs under a fresh key.\n * Throws the final error otherwise.\n */\nexport async function runSubmission(\n rt: SubmitRuntime,\n executor: SubmitExecutor,\n hooks: { onAttestationInvalid?: () => void } = {},\n): Promise<SessionView> {\n let key = rt.uuid();\n let consentRecovered = false;\n let attestationRetried = false;\n let transportReplays = 0;\n for (;;) {\n try {\n return await executor(rt.client, key);\n } catch (err) {\n if (err instanceof AttestationError) {\n if (attestationRetried) throw err;\n attestationRetried = true;\n hooks.onAttestationInvalid?.();\n key = rt.uuid();\n continue;\n }\n if (!(err instanceof HostedApiError)) throw err;\n if (err.code === \"consent_required\" && !consentRecovered) {\n consentRecovered = true;\n await rt.ensureConsent({ force: true });\n key = rt.uuid();\n continue;\n }\n if (err.code === \"attestation_invalid\" && !attestationRetried) {\n attestationRetried = true;\n hooks.onAttestationInvalid?.();\n key = rt.uuid();\n continue;\n }\n if (TRANSPORT_CODES.has(err.code) && transportReplays < TRANSPORT_REPLAY_ATTEMPTS) {\n transportReplays += 1;\n const retryAfterMs =\n err.retryAfterSeconds !== undefined ? err.retryAfterSeconds * 1000 : undefined;\n await rt.sleep(\n retryAfterMs !== undefined\n ? Math.min(retryAfterMs, MAX_RETRY_AFTER_MS)\n : TRANSPORT_REPLAY_DELAY_MS,\n );\n continue;\n }\n throw err;\n }\n }\n}\n\nexport interface LivenessFlowDeps extends SubmitRuntime {\n artifacts: CapturedArtifacts;\n /** Fresh attestation per call (Turnstile execute, or `{sandbox: true}`). */\n getAttestation(): Promise<AttestationInput>;\n /** Latest hosted view (frontier decisions). */\n getView(): HostedSessionView;\n /** Re-GET the view from the server (after a RESYNC code) and fold it in. */\n refreshView(): Promise<HostedSessionView>;\n /** Fold a submit response into the view. */\n applySubmit(view: SessionView, submitted: CheckType): void;\n /** Flow-state hook for the capture handle. */\n onPhase(phase: \"uploading\" | \"checking\"): void;\n /** The verification was destroyed (the only thing that cancels a chain). */\n isCancelled(): boolean;\n}\n\nexport type LivenessFlowOutcome =\n | { kind: \"settled\" }\n | { kind: \"resync\" }\n | { kind: \"unavailable\"; reason: SdkFailureReason }\n | { kind: \"cancelled\" };\n\n/** Liveness states after which THIS capture's keyframe may feed face_match. */\nconst LIVENESS_CHAINABLE: ReadonlySet<string> = new Set([\"passed\", \"review\", \"processing\", \"skipped\"]);\n\n/**\n * Run the biometric submissions the CURRENT frontier allows, re-evaluating\n * after every submit and after every RESYNC re-GET:\n * - frontier `liveness` → clip upload + attestation + `liveness` (once per capture);\n * - frontier `face_match` → keyframe upload + `face_match` (once per capture),\n * allowed when liveness was NOT part of this capture (it had already\n * settled — any state, incl. `failed`: the selfie-fallback case, where this\n * capture only feeds face_match) or settled chainable from this capture\n * (passed / review / processing / skipped — or absent);\n * - anything else (terminal view, a non-biometric frontier, a check this\n * capture already submitted) → `settled` for the caller to map the view.\n * A RESYNC code re-GETs the view and re-enters (at most {@link RESYNC_REENTRY_MAX}\n * times); the final RESYNC surfaces as `resync` for the caller to map.\n */\nexport async function runLivenessFlow(deps: LivenessFlowDeps): Promise<LivenessFlowOutcome> {\n const { artifacts } = deps;\n const clip = artifacts.clip;\n const bareMime = stripMimeParams(artifacts.clipMime ?? \"\");\n if (\n artifacts.degraded === \"NO_RECORDER\" ||\n clip === undefined ||\n !CLIP_MIME_ALLOWLIST.includes(bareMime)\n ) {\n // No clip, or a container outside the presign allowlist (never sign an\n // off-allowlist type): v2 cannot run THIS capture.\n return { kind: \"unavailable\", reason: \"no_recorder\" };\n }\n\n // Per-capture executors: their closure caches (promoted media key,\n // attestation) survive a same-key transport replay; each is run at most once.\n const submitLiveness = buildLivenessSubmit(deps, clip, bareMime);\n const submitFaceMatch = buildFaceMatchSubmit(deps, artifacts.keyframe);\n let livenessSubmitted = false;\n let faceMatchSubmitted = false;\n let livenessChainable = true;\n let resyncs = 0;\n\n for (;;) {\n if (deps.isCancelled()) return { kind: \"cancelled\" };\n const view = deps.getView();\n if (isTerminalView(view)) return { kind: \"settled\" };\n const frontier = frontierStep(view)?.checkType;\n const next =\n frontier === \"liveness\" && !livenessSubmitted\n ? \"liveness\"\n : frontier === \"face_match\" && !faceMatchSubmitted && livenessChainable\n ? \"face_match\"\n : null;\n if (next === null) return { kind: \"settled\" };\n try {\n if (next === \"liveness\") {\n livenessSubmitted = true;\n const response = await submitLiveness();\n if (deps.isCancelled()) return { kind: \"cancelled\" };\n deps.applySubmit(response, \"liveness\");\n const state = stepOf(deps.getView(), \"liveness\")?.state;\n livenessChainable = state === undefined || LIVENESS_CHAINABLE.has(state);\n } else {\n faceMatchSubmitted = true;\n const response = await submitFaceMatch();\n if (deps.isCancelled()) return { kind: \"cancelled\" };\n deps.applySubmit(response, \"face_match\");\n }\n } catch (err) {\n if (deps.isCancelled()) return { kind: \"cancelled\" };\n const outcome = classifyFailure(err);\n if (outcome.kind !== \"resync\" || resyncs >= RESYNC_REENTRY_MAX) return outcome;\n resyncs += 1;\n // The server moved past what we hold: re-GET and re-enter from truth.\n await deps.refreshView();\n }\n }\n}\n\nfunction buildLivenessSubmit(\n deps: LivenessFlowDeps,\n clip: Blob,\n bareMime: string,\n): () => Promise<SessionView> {\n let clipKey: string | null = null;\n let attestation: AttestationInput | null = null;\n return () =>\n runSubmission(\n deps,\n async (client, idempotencyKey) => {\n if (clipKey === null) {\n deps.onPhase(\"uploading\");\n const presigned = await client.presign(\"clip\", bareMime, clip.size);\n await client.uploadToSpaces(presigned.uploadUrl, clip, bareMime);\n clipKey = (await client.completeMedia(presigned.key)).key;\n }\n // Attestation AFTER the upload settles (token stays fresh), cached\n // for the same-key replay.\n if (attestation === null) {\n try {\n attestation = await deps.getAttestation();\n } catch (err) {\n throw new AttestationError(err instanceof Error ? err.message : String(err));\n }\n }\n deps.onPhase(\"checking\");\n return client.submitCheck(\n \"liveness\",\n {\n clipKey,\n attestation,\n captureChannel: deps.artifacts.captureChannel,\n capture: captureInputOf(deps.artifacts),\n },\n { idempotencyKey },\n );\n },\n {\n onAttestationInvalid: () => {\n attestation = null;\n },\n },\n );\n}\n\n/**\n * The `input.capture` block of the liveness submission: the engine id, the\n * stream dimensions, the clip length and the face-capture timing from the\n * `captured` event — exactly the backend's capture-metadata allowlist\n * (identity-backend `capture-metadata.ts`). Never media, never tokens.\n */\nexport function captureInputOf(artifacts: CapturedArtifacts): LivenessCaptureInput {\n return {\n ...(artifacts.engine !== undefined ? { engine: artifacts.engine } : {}),\n width: artifacts.width,\n height: artifacts.height,\n ...(artifacts.clipMs !== undefined ? { clipMs: artifacts.clipMs } : {}),\n ...(artifacts.cameraReadyMs !== undefined ? { cameraReadyMs: artifacts.cameraReadyMs } : {}),\n ...(artifacts.faceAcquireMs !== undefined ? { faceAcquireMs: artifacts.faceAcquireMs } : {}),\n ...(artifacts.captureMs !== undefined ? { captureMs: artifacts.captureMs } : {}),\n };\n}\n\nfunction buildFaceMatchSubmit(deps: LivenessFlowDeps, keyframe: Blob): () => Promise<SessionView> {\n let imageKey: string | null = null;\n return () =>\n runSubmission(deps, async (client, idempotencyKey) => {\n if (imageKey === null) {\n deps.onPhase(\"uploading\");\n const presigned = await client.presign(\"image\", KEYFRAME_MIME, keyframe.size);\n await client.uploadToSpaces(presigned.uploadUrl, keyframe, KEYFRAME_MIME);\n imageKey = (await client.completeMedia(presigned.key)).key;\n }\n deps.onPhase(\"checking\");\n return client.submitCheck(\"face_match\", { imageKey }, { idempotencyKey });\n });\n}\n\nfunction classifyFailure(err: unknown): LivenessFlowOutcome {\n if (err instanceof AttestationError) return { kind: \"unavailable\", reason: \"attestation\" };\n if (err instanceof HostedApiError) {\n if (err.code === \"attestation_invalid\") return { kind: \"unavailable\", reason: \"attestation\" };\n if (RESYNC_CODES.has(err.code)) return { kind: \"resync\" };\n }\n return { kind: \"unavailable\", reason: \"network\" };\n}\n","// Cloudflare Turnstile: lazy script loader + execute-mode invisible challenge.\n// Ported from identity-hosted/lib/turnstile.ts (Plan 6 Task 10 AC4) — same\n// behaviour: the script loads ONCE, lazily, only when a liveness submit first\n// needs a token; each token request renders a fresh execute-mode widget,\n// resolves the callback token, and removes the widget. Hosts' CSP must allow\n// challenges.cloudflare.com.\n//\n// The site key is RUNTIME data (`HostedSessionView.turnstileSiteKey`); when it\n// is null the verification sends `{sandbox: true}` instead of calling this.\n\nexport const TURNSTILE_SCRIPT_SRC = \"https://challenges.cloudflare.com/turnstile/v0/api.js\";\n\n/** Bound on a single execute round-trip (challenge fetch + solve). */\nexport const TURNSTILE_EXECUTE_TIMEOUT_MS = 30_000;\n\nexport interface TurnstileRenderParams {\n sitekey: string;\n callback: (token: string) => void;\n \"error-callback\"?: (code?: string) => void;\n execution?: \"render\" | \"execute\";\n appearance?: \"always\" | \"execute\" | \"interaction-only\";\n}\n\n/** The subset of the Turnstile JS API this module uses. */\nexport interface TurnstileApi {\n render(container: HTMLElement, params: TurnstileRenderParams): string | undefined;\n execute(widgetId: string): void;\n remove(widgetId: string): void;\n}\n\n/** `window.turnstile` without augmenting the global Window type for consumers. */\nfunction installedApi(): TurnstileApi | undefined {\n return (window as unknown as { turnstile?: TurnstileApi }).turnstile;\n}\n\nlet loaderPromise: Promise<TurnstileApi> | null = null;\n\n/** Test-only: reset the module singleton between cases. */\nexport function resetTurnstileForTests(): void {\n loaderPromise = null;\n}\n\n/** Load the Turnstile script once (singleton; a load failure resets it so a\n * retry can re-attempt). */\nexport function loadTurnstile(): Promise<TurnstileApi> {\n loaderPromise ??= new Promise<TurnstileApi>((resolve, reject) => {\n const present = installedApi();\n if (present) {\n resolve(present);\n return;\n }\n const script = document.createElement(\"script\");\n script.src = TURNSTILE_SCRIPT_SRC;\n script.async = true;\n script.onload = () => {\n const api = installedApi();\n if (api) {\n resolve(api);\n } else {\n loaderPromise = null;\n reject(new Error(\"Turnstile script loaded but exposed no API\"));\n }\n };\n script.onerror = () => {\n loaderPromise = null;\n script.remove(); // a retry appends a fresh tag\n reject(new Error(\"Turnstile script failed to load\"));\n };\n document.head.appendChild(script);\n });\n return loaderPromise;\n}\n\n/** Options of {@link executeTurnstile}. */\nexport interface ExecuteTurnstileOptions {\n /** Bound on the challenge round-trip; default {@link TURNSTILE_EXECUTE_TIMEOUT_MS}. */\n timeoutMs?: number;\n /**\n * Aborts the challenge: the promise rejects and the widget, its container and\n * the timeout are cleaned up at once. `createVerification().destroy()` passes\n * its own signal so a torn-down verification never leaves a widget behind.\n */\n signal?: AbortSignal;\n}\n\nfunction abortError(): Error {\n return new Error(\"Turnstile challenge aborted\");\n}\n\n/**\n * Run one invisible execute-mode challenge and resolve its token. Rejects on\n * challenge error, on `signal` abort, or after {@link TURNSTILE_EXECUTE_TIMEOUT_MS}\n * — the verification maps a failure to `result {status:'unavailable',\n * reason:'attestation'}` after one retry.\n */\nexport async function executeTurnstile(\n siteKey: string,\n opts: ExecuteTurnstileOptions = {},\n): Promise<string> {\n const timeoutMs = opts.timeoutMs ?? TURNSTILE_EXECUTE_TIMEOUT_MS;\n const signal = opts.signal;\n if (signal?.aborted) throw abortError();\n const api = await loadTurnstile();\n if (signal?.aborted) throw abortError();\n const container = document.createElement(\"div\");\n document.body.appendChild(container);\n let widgetId: string | undefined;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let onAbort: (() => void) | undefined;\n try {\n return await new Promise<string>((resolve, reject) => {\n timer = setTimeout(\n () => reject(new Error(`Turnstile challenge timed out (${timeoutMs} ms)`)),\n timeoutMs,\n );\n if (signal !== undefined) {\n onAbort = () => reject(abortError());\n signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n widgetId = api.render(container, {\n sitekey: siteKey,\n execution: \"execute\",\n appearance: \"execute\",\n callback: resolve,\n \"error-callback\": (code) => {\n reject(new Error(`Turnstile challenge failed${code ? ` (${code})` : \"\"}`));\n },\n });\n if (widgetId === undefined) {\n reject(new Error(\"Turnstile render returned no widget id\"));\n return;\n }\n api.execute(widgetId);\n });\n } finally {\n // ONE cleanup path for every outcome (token / challenge error / timeout /\n // abort / render failure): the challenge timer and the abort listener must\n // never leak past settlement.\n clearTimeout(timer);\n if (signal !== undefined && onAbort !== undefined) signal.removeEventListener(\"abort\", onAbort);\n if (widgetId !== undefined) {\n try {\n api.remove(widgetId);\n } catch {\n // widget already gone — nothing to clean\n }\n }\n container.remove();\n }\n}\n","// createVerification — composes the hosted client, consent, the early registry\n// submit, the capture handle and the post-capture flow behind the public\n// contract (spec §3.1). Framework-free; the only state is the latest hosted\n// view (re-emitted on every update via `on('view')`).\nimport { HostedClient } from \"../client/hosted-client\";\nimport type { AttestationInput, CheckType, HostedSessionView, SessionView } from \"../client/types\";\nimport {\n createLivenessCaptureInternal,\n type LivenessCaptureInternalHandle,\n type LivenessCaptureInternals,\n} from \"../capture/create-liveness-capture\";\nimport { createEmitter } from \"./emitter\";\nimport {\n type HostedClientLike,\n runLivenessFlow,\n runSubmission,\n type SubmitRuntime,\n} from \"./liveness-flow\";\nimport {\n frontierStep,\n isTerminalView,\n mapSessionResult,\n mergeSessionView,\n stepOf,\n unavailable,\n} from \"./result\";\nimport { executeTurnstile } from \"./turnstile\";\nimport type {\n CapturedArtifacts,\n LivenessCaptureHandle,\n LivenessCaptureOptions,\n Verification,\n VerificationEvents,\n VerificationOptions,\n VerificationResult,\n} from \"./types\";\n\n/** Production API origin — the `apiOrigin` default. */\nexport const DEFAULT_API_ORIGIN = \"https://api.sekyro.ai\";\n\n/** Pause before the single `registry_unavailable` re-submit. */\nexport const REGISTRY_RETRY_DELAY_MS = 5_000;\n\n/** Bounded poll while a biometric verdict is still `processing` after the submits. */\nexport const PROCESSING_POLL_DELAY_MS = 1_500;\nexport const PROCESSING_POLL_MAX = 10;\n\n/**\n * Construction seams — tests and Sekyro's own hosted page (`@sekyro/web/internal`).\n * Not part of the partner contract.\n */\nexport interface VerificationInternals {\n /** Replace the HTTP client (default: `new HostedClient({...})`). */\n client?: HostedClientLike;\n /**\n * Replace the Turnstile challenge (default: {@link executeTurnstile}). The\n * `signal` aborts when the verification is destroyed (M1).\n */\n getTurnstileToken?: (siteKey: string, opts: { signal: AbortSignal }) => Promise<string>;\n /** Capture-engine seams forwarded to {@link createLivenessCaptureInternal}. */\n capture?: LivenessCaptureInternals;\n sleep?: (ms: number) => Promise<void>;\n uuid?: () => string;\n}\n\nfunction defaultSleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/** `crypto.randomUUID()` with a v4 fallback for hosts that lack it. */\nexport function randomUuid(): string {\n const c = (globalThis as { crypto?: Crypto }).crypto;\n if (c !== undefined && typeof c.randomUUID === \"function\") return c.randomUUID();\n const bytes = new Uint8Array(16);\n if (c !== undefined && typeof c.getRandomValues === \"function\") c.getRandomValues(bytes);\n else for (let i = 0; i < 16; i += 1) bytes[i] = Math.floor(Math.random() * 256);\n bytes[6] = ((bytes[6] ?? 0) & 0x0f) | 0x40;\n bytes[8] = ((bytes[8] ?? 0) & 0x3f) | 0x80;\n const hex = [...bytes].map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n}\n\n/**\n * Create a verification bound to one session (spec §3.1):\n * `consent()` → `startRegistry()` → `liveness({video})` → `on('result')`.\n */\nexport function createVerification(options: VerificationOptions): Verification {\n return createVerificationInternal(options, {});\n}\n\n/** {@link createVerification} with construction seams (tests / Sekyro-internal hosts). */\nexport function createVerificationInternal(\n options: VerificationOptions,\n internals: VerificationInternals,\n): Verification {\n const apiOrigin = options.apiOrigin ?? DEFAULT_API_ORIGIN;\n const autoRetry = options.autoRetry ?? true;\n const rearm = options.rearm ?? \"auto\";\n const client: HostedClientLike =\n internals.client ??\n new HostedClient({\n apiOrigin,\n sessionToken: options.clientToken,\n ...(options.fetch !== undefined ? { fetch: options.fetch } : {}),\n });\n const sleep = internals.sleep ?? defaultSleep;\n const uuid = internals.uuid ?? randomUuid;\n const getTurnstileToken = internals.getTurnstileToken ?? executeTurnstile;\n const emitter = createEmitter<VerificationEvents>();\n\n let destroyed = false;\n // Aborts an in-flight Turnstile challenge on destroy() (widget + timer clean up).\n const lifetime = new AbortController();\n\n // ── view ───────────────────────────────────────────────────────────────────\n let view: HostedSessionView | null = null;\n let bootstrap: Promise<HostedSessionView> | null = null;\n const setView = (next: HostedSessionView): void => {\n view = next;\n emitter.emit(\"view\", next);\n };\n const ensureView = (): Promise<HostedSessionView> => {\n if (view !== null) return Promise.resolve(view);\n bootstrap ??= client\n .getSession()\n .then((next) => {\n setView(next);\n return next;\n })\n .finally(() => {\n bootstrap = null;\n });\n return bootstrap;\n };\n const refreshView = async (): Promise<HostedSessionView> => {\n const next = await client.getSession();\n setView(next);\n return next;\n };\n const applySubmit = (response: SessionView, submitted: CheckType): void => {\n if (view !== null) setView(mergeSessionView(view, response, submitted));\n };\n\n // ── consent (idempotent; `force` after a server consent_required) ──────────\n let consentInFlight: Promise<void> | null = null;\n const recordConsent = async (force: boolean): Promise<void> => {\n const current = await ensureView();\n if (!force && current.consentRecorded) return;\n await client.recordConsent(options.locale);\n if (view !== null) setView({ ...view, consentRecorded: true });\n };\n const ensureConsent = (opts?: { force?: boolean }): Promise<void> => {\n if (opts?.force === true) return recordConsent(true);\n consentInFlight ??= recordConsent(false).finally(() => {\n consentInFlight = null;\n });\n return consentInFlight;\n };\n\n const runtime: SubmitRuntime = {\n client,\n ensureConsent: (opts) => ensureConsent(opts),\n sleep,\n uuid,\n };\n\n // ── result emission ────────────────────────────────────────────────────────\n // A session verdict is emitted ONCE (the registry may settle it before any\n // capture); `retry` / `unavailable` are per capture.\n let terminalEmitted = false;\n const emitResult = (result: VerificationResult): void => {\n if (result.status === \"approved\" || result.status === \"rejected\" || result.status === \"review\") {\n if (terminalEmitted) return;\n terminalEmitted = true;\n }\n emitter.emit(\"result\", result);\n };\n\n // ── early registry ─────────────────────────────────────────────────────────\n let registry: Promise<void> | null = null;\n let registryFailed = false;\n // The frontier is population_registry on a session minted WITHOUT a bound\n // NNI: the SDK has nothing to submit (and must never guess one).\n let registryUnbound = false;\n const submitRegistry = (): Promise<SessionView> =>\n runSubmission(runtime, (c, idempotencyKey) =>\n // `{}` input: the session is bound to a SERVER-provided NNI (Plan A Task 2).\n c.submitCheck(\"population_registry\", {}, { idempotencyKey }),\n );\n const runRegistry = async (): Promise<void> => {\n try {\n const current = await ensureView();\n if (isTerminalView(current) || frontierStep(current)?.checkType !== \"population_registry\") {\n return;\n }\n if (current.nniBound !== true) {\n registryUnbound = true;\n return;\n }\n await ensureConsent();\n applySubmit(await submitRegistry(), \"population_registry\");\n const step = view === null ? undefined : stepOf(view, \"population_registry\");\n if (\n step?.state === \"input_required\" &&\n step.reason === \"registry_unavailable\" &&\n step.attemptsRemaining > 0\n ) {\n await sleep(REGISTRY_RETRY_DELAY_MS);\n if (destroyed) return;\n applySubmit(await submitRegistry(), \"population_registry\");\n }\n } catch {\n // Never throws (incl. 409 nni_locked / transport failures): the flow\n // surfaces it through result mapping.\n registryFailed = true;\n return;\n }\n if (view !== null && isTerminalView(view)) emitResult(mapSessionResult(view, { autoRetry }));\n };\n const startRegistry = (): Promise<void> => {\n registry ??= runRegistry();\n return registry;\n };\n\n // ── attestation ────────────────────────────────────────────────────────────\n // The SDK echoes the site key it rendered (`siteKey`) so the backend selects\n // the matching widget secret deterministically — Turnstile tokens are\n // single-use, so the verifier never retries with another secret (C1).\n const getAttestation = async (): Promise<AttestationInput> => {\n const current = await ensureView();\n const siteKey = current.turnstileSiteKey;\n if (siteKey === null) return { sandbox: true };\n return {\n channel: \"hosted_web\",\n siteKey,\n turnstileToken: await getTurnstileToken(siteKey, { signal: lifetime.signal }),\n };\n };\n\n // ── capture + flow ─────────────────────────────────────────────────────────\n // Submission chains are SERIALIZED: a new capture (incl. a host remount that\n // destroyed the old handle mid-upload) never abandons an in-flight chain — it\n // queues behind it and then evaluates the CURRENT frontier. Only destroy() of\n // the verification cancels. Handle side effects (flow states, auto re-arm)\n // reach the handle only while it is alive and still on the attempt that\n // produced the artifacts.\n interface BoundCapture {\n capture: LivenessCaptureInternalHandle;\n alive: boolean;\n /** Engine attempt counter (bumped on every `starting`). */\n attempt: number;\n }\n let active: BoundCapture | null = null;\n let chain: Promise<void> = Promise.resolve();\n let chainDepth = 0;\n\n const settleProcessing = async (): Promise<HostedSessionView> => {\n let current = await ensureView();\n for (\n let i = 0;\n i < PROCESSING_POLL_MAX &&\n !destroyed &&\n !isTerminalView(current) &&\n frontierStep(current) === undefined &&\n current.steps.some((step) => step.state === \"processing\");\n i += 1\n ) {\n await sleep(PROCESSING_POLL_DELAY_MS);\n if (destroyed) break;\n current = await refreshView();\n }\n return current;\n };\n\n const runFlow = async (\n bound: BoundCapture,\n artifacts: CapturedArtifacts,\n capturedAttempt: number,\n ): Promise<void> => {\n const { capture } = bound;\n const isCancelled = (): boolean => destroyed;\n // The handle still shows the attempt these artifacts came from (not\n // destroyed by a remount, no retry()/switchCamera() since).\n const ownsHandle = (): boolean => bound.alive && bound.attempt === capturedAttempt;\n const setPhase = (phase: \"uploading\" | \"checking\" | \"done\"): void => {\n if (ownsHandle()) capture.setFlowState(phase);\n };\n const finish = (result: VerificationResult): void => {\n if (isCancelled()) return;\n emitResult(result);\n if (!ownsHandle()) return;\n if (result.status === \"retry\" && rearm === \"auto\") {\n // Re-arm: the engine restarts and the next `captured` runs a new flow.\n capture.handle.retry();\n return;\n }\n // `done` (incl. a manual-rearm `retry`): the host calls `retry()` on the\n // handle when the user is ready — the engine restarts from there.\n capture.setFlowState(\"done\");\n };\n\n if (artifacts.degraded === \"NO_RECORDER\") {\n // No MediaRecorder: nothing is submitted (no liveness, no face_match).\n const sessionId = view?.sessionId ?? (await ensureView().catch(() => null))?.sessionId ?? \"\";\n finish(unavailable(sessionId, \"no_recorder\"));\n return;\n }\n\n setPhase(\"uploading\");\n try {\n // Registry first: it records consent itself only when it actually\n // submits — an unbound / failed registry frontier ends the flow below\n // without recording a consent nothing was submitted under.\n await startRegistry();\n if (isCancelled()) return;\n let current = await ensureView();\n if (!isTerminalView(current)) {\n if (frontierStep(current)?.checkType === \"population_registry\") {\n // The registry never passed (outage after the retry, or a request-\n // level failure): the biometric checks cannot be submitted.\n finish(\n unavailable(\n current.sessionId,\n registryUnbound ? \"nni_unbound\" : registryFailed ? \"network\" : \"registry_unavailable\",\n ),\n );\n return;\n }\n await ensureConsent();\n if (isCancelled()) return;\n const outcome = await runLivenessFlow({\n ...runtime,\n artifacts,\n getAttestation,\n getView: () => view ?? current,\n refreshView,\n applySubmit,\n onPhase: setPhase,\n isCancelled,\n });\n if (isCancelled()) return;\n if (outcome.kind === \"unavailable\") {\n finish(unavailable(current.sessionId, outcome.reason));\n return;\n }\n if (outcome.kind === \"resync\") await refreshView();\n current = await settleProcessing();\n }\n finish(mapSessionResult(current, { autoRetry }));\n } catch {\n if (isCancelled()) return;\n finish(unavailable(view?.sessionId ?? \"\", \"network\"));\n }\n };\n\n const enqueueFlow = (bound: BoundCapture, artifacts: CapturedArtifacts): void => {\n const capturedAttempt = bound.attempt;\n if (chainDepth > 0 && bound.alive) {\n // Queued behind an in-flight chain: the host sees `uploading` meanwhile.\n bound.capture.setFlowState(\"uploading\");\n }\n chainDepth += 1;\n chain = chain\n .then(() => runFlow(bound, artifacts, capturedAttempt))\n .finally(() => {\n chainDepth -= 1;\n })\n // runFlow never rejects (it maps failures to results); a rejection must\n // still never poison the chain for the captures queued after it.\n .catch(() => undefined);\n };\n\n const liveness = (captureOptions: LivenessCaptureOptions): LivenessCaptureHandle => {\n // Camera teardown of the previous handle (its chain, if any, survives).\n active?.capture.handle.destroy();\n if (active !== null) active.alive = false;\n const capture = createLivenessCaptureInternal(captureOptions, internals.capture);\n const bound: BoundCapture = { capture, alive: true, attempt: 0 };\n active = bound;\n capture.handle.on(\"state\", (state) => {\n // A fresh engine attempt: in-flight flows for older artifacts complete,\n // but no longer push states into (or re-arm) this handle.\n if (state === \"starting\") bound.attempt += 1;\n });\n capture.handle.on(\"captured\", (artifacts) => {\n // Partners' own `captured` handlers run first (the event fires BEFORE\n // any upload); the flow starts on the next microtask, after any\n // in-flight chain.\n void Promise.resolve().then(() => enqueueFlow(bound, artifacts));\n });\n const inner = capture.handle;\n return {\n get state() {\n return inner.state;\n },\n on: (event, handler) => inner.on(event, handler),\n start: () => inner.start(),\n retry: () => inner.retry(),\n switchCamera: () => inner.switchCamera(),\n destroy: () => {\n bound.alive = false;\n if (active === bound) active = null;\n inner.destroy();\n },\n };\n };\n\n return {\n consent: () => ensureConsent(),\n startRegistry,\n liveness,\n on: (event, handler) => emitter.on(event, handler),\n destroy: () => {\n destroyed = true;\n lifetime.abort();\n if (active !== null) {\n active.alive = false;\n active.capture.handle.destroy();\n active = null;\n }\n emitter.clear();\n },\n };\n}\n"],"mappings":"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","names":["i","y","i","a","p","A","B","t","i","E","e","o","n","a","s","I","g","c","r","h","C","Q","l","y","D","d","w","f","m","N","p","F","J","M","u","R","G","k","S","t","y","i","i","o","a","h","t","p","t","w","i","e","s","t","w","h","a","p","extractEyes","a","p","clamp01","_","describeError","best","i","h","err","c","i","sleep","c","i"]}