@framefields/vision 2.0.2 → 2.0.3
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.
- package/dist/{index-DwGxgTRf.d.mts → index-CoAN0xxG.d.mts} +84 -4
- package/dist/index-CoAN0xxG.d.mts.map +1 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{src-DbPyIIat.mjs → src-C2sA_wDT.mjs} +167 -4
- package/dist/src-C2sA_wDT.mjs.map +1 -0
- package/dist/web.d.mts +4 -52
- package/dist/web.d.mts.map +1 -1
- package/dist/web.mjs +6 -73
- package/dist/web.mjs.map +1 -1
- package/package.json +4 -4
- package/dist/index-DwGxgTRf.d.mts.map +0 -1
- package/dist/src-DbPyIIat.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"src-DbPyIIat.mjs","names":["masks","clamp","programmaticSignal","coreProgrammaticSignal","resolve"],"sources":["../src/tracking/temporal-object-tracker.ts","../src/analysis/analyze-sequence.ts","../src/decode/preprocess.ts","../src/decode/rtmdet-ins.ts","../src/decode/rtmo.ts","../src/decode/selfie.ts","../src/pose/keypoints.ts","../src/gpu/pose-skeleton-renderer.ts","../src/gpu/segmentation-texture-pool.ts","../src/model/model-store.ts","../src/runner/canonical-baselines.ts","../src/runtime/session-provider.ts","../src/runner/vision-runner.ts","../src/segmentation/subject.ts","../src/spatial/camera-space-transformer.ts","../src/tracking/pose-track-matcher.ts","../src/signals/vision-bundle.ts","../src/spatial/spatial-pin.ts","../src/vision-node.ts","../src/index.ts"],"sourcesContent":["import type {\n\tDetectedObject,\n\tObjectBoundingBox,\n\tTrackedObject,\n} from \"@framefields/core\";\n\nexport interface TemporalTrackerOptions {\n\t/** Minimum Intersection-over-Union to associate a detection with an existing track. Default: 0.25 */\n\treadonly iouThreshold?: number;\n\t/** Number of frames a lost track is coasted via velocity extrapolation before deletion. Default: 15 */\n\treadonly maxMissedFrames?: number;\n\t/** Minimum consecutive hits before a tentative track is confirmed active. Default: 1 */\n\treadonly minHits?: number;\n\t/** Position smoothing weight [0, 1] where 1.0 is instantaneous and 0.0 is fully damped. Default: 0.75 */\n\treadonly positionSmoothing?: number;\n\t/** Whether tracks remain marked active during coasting frames. Default: true */\n\treadonly activeDuringCoast?: boolean;\n}\n\n/** Axis-aligned box in any consistent unit (pixels or normalized). */\nexport type PixelBox = Pick<\n\tObjectBoundingBox,\n\t\"originX\" | \"originY\" | \"width\" | \"height\"\n>;\n\nexport function computeIoU(boxA: PixelBox, boxB: PixelBox): number {\n\tconst xA = Math.max(boxA.originX, boxB.originX);\n\tconst yA = Math.max(boxA.originY, boxB.originY);\n\tconst xB = Math.min(boxA.originX + boxA.width, boxB.originX + boxB.width);\n\tconst yB = Math.min(boxA.originY + boxA.height, boxB.originY + boxB.height);\n\n\tconst interW = Math.max(0, xB - xA);\n\tconst interH = Math.max(0, yB - yA);\n\tconst interArea = interW * interH;\n\n\tif (interArea <= 0) return 0;\n\n\tconst areaA = boxA.width * boxA.height;\n\tconst areaB = boxB.width * boxB.height;\n\tconst unionArea = areaA + areaB - interArea;\n\n\treturn unionArea > 0 ? interArea / unionArea : 0;\n}\n\ninterface InternalTrack {\n\ttrackId: number;\n\tcategory: string;\n\tscore: number;\n\tbox: ObjectBoundingBox;\n\tcenterX: number;\n\tcenterY: number;\n\tvx: number;\n\tvy: number;\n\tage: number;\n\thits: number;\n\ttimeSinceUpdate: number;\n\tactive: boolean;\n\tisCoasting: boolean;\n}\n\nexport class TemporalObjectTracker {\n\tprivate _nextTrackId = 1;\n\tprivate _tracks: InternalTrack[] = [];\n\tprivate _iouThreshold: number;\n\tprivate _maxMissedFrames: number;\n\tprivate _minHits: number;\n\tprivate _positionSmoothing: number;\n\tprivate _activeDuringCoast: boolean;\n\n\tconstructor(options: TemporalTrackerOptions = {}) {\n\t\tthis._iouThreshold = options.iouThreshold ?? 0.25;\n\t\tthis._maxMissedFrames = options.maxMissedFrames ?? 15;\n\t\tthis._minHits = options.minHits ?? 1;\n\t\tthis._positionSmoothing = Math.max(\n\t\t\t0.1,\n\t\t\tMath.min(1.0, options.positionSmoothing ?? 0.75),\n\t\t);\n\t\tthis._activeDuringCoast = options.activeDuringCoast !== false;\n\t}\n\n\t/**\n\t * Updates the multi-object tracker with new detections for the current frame.\n\t *\n\t * @param detections Raw detections found on the current frame\n\t * @param frame Current frame index\n\t * @param fps Video framerate (used for physical velocity estimation)\n\t * @returns Stable, temporal list of TrackedObjects\n\t */\n\tpublic update(\n\t\tdetections: readonly DetectedObject[],\n\t\t_frame: number,\n\t\tfps = 24,\n\t): TrackedObject[] {\n\t\tconst dt = fps > 0 ? 1 / fps : 0.0416;\n\n\t\t// 1. Predict next step for existing tracks using linear velocity\n\t\tfor (const track of this._tracks) {\n\t\t\ttrack.age++;\n\t\t\ttrack.timeSinceUpdate++;\n\n\t\t\tif (track.timeSinceUpdate > 0) {\n\t\t\t\t// Coast forward along velocity vector\n\t\t\t\tconst predCenterX = track.centerX + track.vx * dt;\n\t\t\t\tconst predCenterY = track.centerY + track.vy * dt;\n\t\t\t\ttrack.centerX = predCenterX;\n\t\t\t\ttrack.centerY = predCenterY;\n\n\t\t\t\tconst w = track.box.width;\n\t\t\t\tconst h = track.box.height;\n\t\t\t\tconst normW = track.box.normalizedWidth;\n\t\t\t\tconst normH = track.box.normalizedHeight;\n\n\t\t\t\tconst normCenterX =\n\t\t\t\t\ttrack.box.normalizedX +\n\t\t\t\t\tnormW / 2 +\n\t\t\t\t\t(track.vx * dt) / Math.max(1, track.box.width / normW);\n\t\t\t\tconst normCenterY =\n\t\t\t\t\ttrack.box.normalizedY +\n\t\t\t\t\tnormH / 2 +\n\t\t\t\t\t(track.vy * dt) / Math.max(1, track.box.height / normH);\n\n\t\t\t\ttrack.box = {\n\t\t\t\t\toriginX: predCenterX - w / 2,\n\t\t\t\t\toriginY: predCenterY - h / 2,\n\t\t\t\t\twidth: w,\n\t\t\t\t\theight: h,\n\t\t\t\t\tnormalizedX: normCenterX - normW / 2,\n\t\t\t\t\tnormalizedY: normCenterY - normH / 2,\n\t\t\t\t\tnormalizedWidth: normW,\n\t\t\t\t\tnormalizedHeight: normH,\n\t\t\t\t};\n\n\t\t\t\t// Dampen coasting velocity\n\t\t\t\ttrack.vx *= 0.92;\n\t\t\t\ttrack.vy *= 0.92;\n\t\t\t\ttrack.isCoasting = true;\n\t\t\t}\n\t\t}\n\n\t\t// 2. Association: match detections with existing tracks\n\t\tconst matchedDetections = new Set<number>();\n\t\tconst matchedTracks = new Set<number>();\n\n\t\t// Compute IoU matrix and find greedy best matches\n\t\tconst candidateMatches: {\n\t\t\ttrackIdx: number;\n\t\t\tdetIdx: number;\n\t\t\tiou: number;\n\t\t}[] = [];\n\n\t\tfor (let t = 0; t < this._tracks.length; t++) {\n\t\t\tconst trk = this._tracks[t];\n\t\t\tfor (let d = 0; d < detections.length; d++) {\n\t\t\t\tconst det = detections[d];\n\t\t\t\t// Only match if category matches\n\t\t\t\tif (trk.category !== det.category) continue;\n\n\t\t\t\tconst iou = computeIoU(trk.box, det.boundingBox);\n\t\t\t\tif (iou >= this._iouThreshold) {\n\t\t\t\t\tcandidateMatches.push({ trackIdx: t, detIdx: d, iou });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Sort by IoU descending\n\t\tcandidateMatches.sort((a, b) => b.iou - a.iou);\n\n\t\tfor (const match of candidateMatches) {\n\t\t\tif (\n\t\t\t\tmatchedTracks.has(match.trackIdx) ||\n\t\t\t\tmatchedDetections.has(match.detIdx)\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tmatchedTracks.add(match.trackIdx);\n\t\t\tmatchedDetections.add(match.detIdx);\n\n\t\t\tconst trk = this._tracks[match.trackIdx];\n\t\t\tconst det = detections[match.detIdx];\n\t\t\tconst detBox = det.boundingBox;\n\t\t\tconst detCenterX = detBox.originX + detBox.width / 2;\n\t\t\tconst detCenterY = detBox.originY + detBox.height / 2;\n\n\t\t\t// Instantaneous velocity calculation\n\t\t\tconst instVx = (detCenterX - trk.centerX) / dt;\n\t\t\tconst instVy = (detCenterY - trk.centerY) / dt;\n\n\t\t\t// Smooth velocity\n\t\t\ttrk.vx = trk.vx * 0.4 + instVx * 0.6;\n\t\t\ttrk.vy = trk.vy * 0.4 + instVy * 0.6;\n\n\t\t\t// Smooth position and bounding box\n\t\t\tconst alpha = this._positionSmoothing;\n\t\t\tconst smoothW = trk.box.width * (1 - alpha) + detBox.width * alpha;\n\t\t\tconst smoothH = trk.box.height * (1 - alpha) + detBox.height * alpha;\n\t\t\tconst smoothCenterX = trk.centerX * (1 - alpha) + detCenterX * alpha;\n\t\t\tconst smoothCenterY = trk.centerY * (1 - alpha) + detCenterY * alpha;\n\n\t\t\ttrk.centerX = smoothCenterX;\n\t\t\ttrk.centerY = smoothCenterY;\n\t\t\ttrk.score = det.score;\n\t\t\ttrk.timeSinceUpdate = 0;\n\t\t\ttrk.hits++;\n\t\t\ttrk.isCoasting = false;\n\n\t\t\tif (trk.hits >= this._minHits) {\n\t\t\t\ttrk.active = true;\n\t\t\t}\n\n\t\t\ttrk.box = {\n\t\t\t\toriginX: smoothCenterX - smoothW / 2,\n\t\t\t\toriginY: smoothCenterY - smoothH / 2,\n\t\t\t\twidth: smoothW,\n\t\t\t\theight: smoothH,\n\t\t\t\tnormalizedX: detBox.normalizedX,\n\t\t\t\tnormalizedY: detBox.normalizedY,\n\t\t\t\tnormalizedWidth: detBox.normalizedWidth,\n\t\t\t\tnormalizedHeight: detBox.normalizedHeight,\n\t\t\t};\n\t\t}\n\n\t\t// 3. Initialize new tracks for unmatched detections\n\t\tfor (let d = 0; d < detections.length; d++) {\n\t\t\tif (matchedDetections.has(d)) continue;\n\n\t\t\tconst det = detections[d];\n\t\t\tconst detBox = det.boundingBox;\n\t\t\tconst centerX = detBox.originX + detBox.width / 2;\n\t\t\tconst centerY = detBox.originY + detBox.height / 2;\n\n\t\t\tthis._tracks.push({\n\t\t\t\ttrackId: this._nextTrackId++,\n\t\t\t\tcategory: det.category,\n\t\t\t\tscore: det.score,\n\t\t\t\tbox: detBox,\n\t\t\t\tcenterX,\n\t\t\t\tcenterY,\n\t\t\t\tvx: 0,\n\t\t\t\tvy: 0,\n\t\t\t\tage: 1,\n\t\t\t\thits: 1,\n\t\t\t\ttimeSinceUpdate: 0,\n\t\t\t\tactive: this._minHits <= 1,\n\t\t\t\tisCoasting: false,\n\t\t\t});\n\t\t}\n\n\t\t// 4. Prune expired tracks\n\t\tthis._tracks = this._tracks.filter(\n\t\t\t(t) => t.timeSinceUpdate <= this._maxMissedFrames,\n\t\t);\n\n\t\t// 5. Produce public TrackedObject representations\n\t\treturn this._tracks\n\t\t\t.filter((t) => t.active)\n\t\t\t.map((t) => {\n\t\t\t\tconst normW = t.box.normalizedWidth;\n\t\t\t\tconst normH = t.box.normalizedHeight;\n\t\t\t\tconst normCenterX = t.box.normalizedX + normW / 2;\n\t\t\t\tconst normCenterY = t.box.normalizedY + normH / 2;\n\t\t\t\tconst speed = Math.sqrt(t.vx * t.vx + t.vy * t.vy);\n\n\t\t\t\treturn {\n\t\t\t\t\ttrackId: t.trackId,\n\t\t\t\t\tcategory: t.category,\n\t\t\t\t\tscore: t.score,\n\t\t\t\t\tboundingBox: t.box,\n\t\t\t\t\tcenterX: t.centerX,\n\t\t\t\t\tcenterY: t.centerY,\n\t\t\t\t\tnormalizedCenterX: normCenterX,\n\t\t\t\t\tnormalizedCenterY: normCenterY,\n\t\t\t\t\tvelocity: { vx: t.vx, vy: t.vy },\n\t\t\t\t\tspeed,\n\t\t\t\t\tage: t.age,\n\t\t\t\t\thits: t.hits,\n\t\t\t\t\tactive: this._activeDuringCoast ? true : t.timeSinceUpdate === 0,\n\t\t\t\t\tisCoasting: t.isCoasting,\n\t\t\t\t};\n\t\t\t});\n\t}\n\n\t/**\n\t * Tracks objects across a full sequence of frames with gap interpolation,\n\t * boundary extrapolation (ensuring frame 0 through end are tracked),\n\t * and temporal Gaussian smoothing.\n\t *\n\t * Guarantees zero flicker, zero drift, and frame-accurate stability across the entire video.\n\t */\n\tpublic trackSequence(\n\t\tperFrameDetections: readonly (readonly DetectedObject[])[],\n\t\ttotalFrames: number,\n\t\tfps = 24,\n\t): TrackedObject[][] {\n\t\tthis.reset();\n\t\tconst dt = fps > 0 ? 1 / fps : 0.0416;\n\n\t\t// 1. First pass: run online tracker to associate track IDs and record raw detections per track\n\t\tinterface TrackObservation {\n\t\t\tframe: number;\n\t\t\tbox: ObjectBoundingBox;\n\t\t\tscore: number;\n\t\t}\n\t\tconst trackHistory = new Map<\n\t\t\tnumber,\n\t\t\t{ category: string; observations: TrackObservation[] }\n\t\t>();\n\n\t\tfor (let f = 0; f < totalFrames; f++) {\n\t\t\tconst dets = perFrameDetections[f] ?? [];\n\t\t\tconst stepTracks = this.update(dets, f, fps);\n\t\t\tfor (const trk of stepTracks) {\n\t\t\t\tif (!trackHistory.has(trk.trackId)) {\n\t\t\t\t\ttrackHistory.set(trk.trackId, {\n\t\t\t\t\t\tcategory: trk.category,\n\t\t\t\t\t\tobservations: [],\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\t// Only record if this was a fresh detection or high quality\n\t\t\t\tif (!trk.isCoasting) {\n\t\t\t\t\ttrackHistory.get(trk.trackId)!.observations.push({\n\t\t\t\t\t\tframe: f,\n\t\t\t\t\t\tbox: trk.boundingBox,\n\t\t\t\t\t\tscore: trk.score,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// 2. For each tracked identity, interpolate gaps and extrapolate across the full timeline [0, totalFrames - 1]\n\t\tinterface TrajectoryPoint {\n\t\t\tbox: ObjectBoundingBox;\n\t\t\tscore: number;\n\t\t}\n\t\tconst fullTrajectories = new Map<\n\t\t\tnumber,\n\t\t\t{ category: string; frames: (TrajectoryPoint | null)[] }\n\t\t>();\n\n\t\tfor (const [trackId, info] of trackHistory.entries()) {\n\t\t\tconst obs = info.observations;\n\t\t\tif (obs.length === 0) continue;\n\n\t\t\t// Sort observations by frame\n\t\t\tobs.sort((a, b) => a.frame - b.frame);\n\n\t\t\tconst frameData: (TrajectoryPoint | null)[] = new Array(totalFrames).fill(\n\t\t\t\tnull,\n\t\t\t);\n\n\t\t\t// Populate observed keyframes\n\t\t\tfor (const o of obs) {\n\t\t\t\tframeData[o.frame] = { box: o.box, score: o.score };\n\t\t\t}\n\n\t\t\t// Extrapolate backwards to frame 0 from first observation\n\t\t\tconst firstObs = obs[0];\n\t\t\tfor (let f = 0; f < firstObs.frame; f++) {\n\t\t\t\tframeData[f] = {\n\t\t\t\t\tbox: { ...firstObs.box },\n\t\t\t\t\tscore: firstObs.score * 0.9,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Interpolate gaps between consecutive observations\n\t\t\tfor (let i = 0; i < obs.length - 1; i++) {\n\t\t\t\tconst startObs = obs[i];\n\t\t\t\tconst endObs = obs[i + 1];\n\t\t\t\tconst gap = endObs.frame - startObs.frame;\n\t\t\t\tif (gap <= 1) continue;\n\n\t\t\t\tfor (let f = startObs.frame + 1; f < endObs.frame; f++) {\n\t\t\t\t\tconst t = (f - startObs.frame) / gap;\n\t\t\t\t\t// Smooth hermite/linear blend\n\t\t\t\t\tconst sX =\n\t\t\t\t\t\tstartObs.box.originX +\n\t\t\t\t\t\t(endObs.box.originX - startObs.box.originX) * t;\n\t\t\t\t\tconst sY =\n\t\t\t\t\t\tstartObs.box.originY +\n\t\t\t\t\t\t(endObs.box.originY - startObs.box.originY) * t;\n\t\t\t\t\tconst sW =\n\t\t\t\t\t\tstartObs.box.width + (endObs.box.width - startObs.box.width) * t;\n\t\t\t\t\tconst sH =\n\t\t\t\t\t\tstartObs.box.height + (endObs.box.height - startObs.box.height) * t;\n\t\t\t\t\tconst nX =\n\t\t\t\t\t\tstartObs.box.normalizedX +\n\t\t\t\t\t\t(endObs.box.normalizedX - startObs.box.normalizedX) * t;\n\t\t\t\t\tconst nY =\n\t\t\t\t\t\tstartObs.box.normalizedY +\n\t\t\t\t\t\t(endObs.box.normalizedY - startObs.box.normalizedY) * t;\n\t\t\t\t\tconst nW =\n\t\t\t\t\t\tstartObs.box.normalizedWidth +\n\t\t\t\t\t\t(endObs.box.normalizedWidth - startObs.box.normalizedWidth) * t;\n\t\t\t\t\tconst nH =\n\t\t\t\t\t\tstartObs.box.normalizedHeight +\n\t\t\t\t\t\t(endObs.box.normalizedHeight - startObs.box.normalizedHeight) * t;\n\n\t\t\t\t\tframeData[f] = {\n\t\t\t\t\t\tbox: {\n\t\t\t\t\t\t\toriginX: sX,\n\t\t\t\t\t\t\toriginY: sY,\n\t\t\t\t\t\t\twidth: sW,\n\t\t\t\t\t\t\theight: sH,\n\t\t\t\t\t\t\tnormalizedX: nX,\n\t\t\t\t\t\t\tnormalizedY: nY,\n\t\t\t\t\t\t\tnormalizedWidth: nW,\n\t\t\t\t\t\t\tnormalizedHeight: nH,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tscore: startObs.score * (1 - t) + endObs.score * t,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Extrapolate forwards to totalFrames - 1 from last observation\n\t\t\tconst lastObs = obs[obs.length - 1];\n\t\t\tfor (let f = lastObs.frame + 1; f < totalFrames; f++) {\n\t\t\t\tframeData[f] = { box: { ...lastObs.box }, score: lastObs.score * 0.9 };\n\t\t\t}\n\n\t\t\t// 3. Temporal Gaussian smoothing over a 5-frame moving window\n\t\t\tconst smoothedFrames: TrajectoryPoint[] = [];\n\t\t\tconst radius = 2; // window size 5 (-2, -1, 0, +1, +2)\n\t\t\tconst weights = [0.06136, 0.24477, 0.38774, 0.24477, 0.06136];\n\n\t\t\tfor (let f = 0; f < totalFrames; f++) {\n\t\t\t\tlet sumWeight = 0;\n\t\t\t\tlet sumX = 0;\n\t\t\t\tlet sumY = 0;\n\t\t\t\tlet sumW = 0;\n\t\t\t\tlet sumH = 0;\n\t\t\t\tlet sumNormX = 0;\n\t\t\t\tlet sumNormY = 0;\n\t\t\t\tlet sumNormW = 0;\n\t\t\t\tlet sumNormH = 0;\n\t\t\t\tlet sumScore = 0;\n\n\t\t\t\tfor (let r = -radius; r <= radius; r++) {\n\t\t\t\t\tconst idx = Math.max(0, Math.min(totalFrames - 1, f + r));\n\t\t\t\t\tconst pt = frameData[idx];\n\t\t\t\t\tif (pt) {\n\t\t\t\t\t\tconst w = weights[r + radius];\n\t\t\t\t\t\tsumWeight += w;\n\t\t\t\t\t\tsumX += pt.box.originX * w;\n\t\t\t\t\t\tsumY += pt.box.originY * w;\n\t\t\t\t\t\tsumW += pt.box.width * w;\n\t\t\t\t\t\tsumH += pt.box.height * w;\n\t\t\t\t\t\tsumNormX += pt.box.normalizedX * w;\n\t\t\t\t\t\tsumNormY += pt.box.normalizedY * w;\n\t\t\t\t\t\tsumNormW += pt.box.normalizedWidth * w;\n\t\t\t\t\t\tsumNormH += pt.box.normalizedHeight * w;\n\t\t\t\t\t\tsumScore += pt.score * w;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst invW = sumWeight > 0 ? 1 / sumWeight : 1;\n\t\t\t\tsmoothedFrames.push({\n\t\t\t\t\tbox: {\n\t\t\t\t\t\toriginX: sumX * invW,\n\t\t\t\t\t\toriginY: sumY * invW,\n\t\t\t\t\t\twidth: sumW * invW,\n\t\t\t\t\t\theight: sumH * invW,\n\t\t\t\t\t\tnormalizedX: sumNormX * invW,\n\t\t\t\t\t\tnormalizedY: sumNormY * invW,\n\t\t\t\t\t\tnormalizedWidth: sumNormW * invW,\n\t\t\t\t\t\tnormalizedHeight: sumNormH * invW,\n\t\t\t\t\t},\n\t\t\t\t\tscore: sumScore * invW,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tfullTrajectories.set(trackId, {\n\t\t\t\tcategory: info.category,\n\t\t\t\tframes: smoothedFrames,\n\t\t\t});\n\t\t}\n\n\t\t// 4. Build output per-frame TrackedObject arrays with frame-accurate velocities\n\t\tconst result: TrackedObject[][] = [];\n\t\tfor (let f = 0; f < totalFrames; f++) {\n\t\t\tconst frameObjects: TrackedObject[] = [];\n\n\t\t\tfor (const [trackId, traj] of fullTrajectories.entries()) {\n\t\t\t\tconst current = traj.frames[f];\n\t\t\t\tif (!current) continue;\n\n\t\t\t\tconst prev = traj.frames[Math.max(0, f - 1)] ?? current;\n\t\t\t\tconst next = traj.frames[Math.min(totalFrames - 1, f + 1)] ?? current;\n\n\t\t\t\tconst curCenterX = current.box.originX + current.box.width / 2;\n\t\t\t\tconst curCenterY = current.box.originY + current.box.height / 2;\n\t\t\t\tconst prevCenterX = prev.box.originX + prev.box.width / 2;\n\t\t\t\tconst prevCenterY = prev.box.originY + prev.box.height / 2;\n\t\t\t\tconst nextCenterX = next.box.originX + next.box.width / 2;\n\t\t\t\tconst nextCenterY = next.box.originY + next.box.height / 2;\n\n\t\t\t\tconst timeDelta = f === 0 || f === totalFrames - 1 ? dt : 2 * dt;\n\t\t\t\tconst vx = (nextCenterX - prevCenterX) / timeDelta;\n\t\t\t\tconst vy = (nextCenterY - prevCenterY) / timeDelta;\n\t\t\t\tconst speed = Math.sqrt(vx * vx + vy * vy);\n\n\t\t\t\tconst normW = current.box.normalizedWidth;\n\t\t\t\tconst normH = current.box.normalizedHeight;\n\n\t\t\t\tframeObjects.push({\n\t\t\t\t\ttrackId,\n\t\t\t\t\tcategory: traj.category,\n\t\t\t\t\tscore: current.score,\n\t\t\t\t\tboundingBox: current.box,\n\t\t\t\t\tcenterX: curCenterX,\n\t\t\t\t\tcenterY: curCenterY,\n\t\t\t\t\tnormalizedCenterX: current.box.normalizedX + normW / 2,\n\t\t\t\t\tnormalizedCenterY: current.box.normalizedY + normH / 2,\n\t\t\t\t\tvelocity: { vx, vy },\n\t\t\t\t\tspeed,\n\t\t\t\t\tage: f + 1,\n\t\t\t\t\thits: 10,\n\t\t\t\t\tactive: true,\n\t\t\t\t\tisCoasting: false,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tresult.push(frameObjects);\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Resets all internal track state.\n\t */\n\tpublic reset(): void {\n\t\tthis._tracks = [];\n\t\tthis._nextTrackId = 1;\n\t}\n}\n","import type { DetectedObject } from \"@framefields/core\";\nimport { VISION_MODELS, type VisionTask } from \"../model/registry.js\";\nimport type { VisionRunner } from \"../runner/vision-runner.js\";\nimport { TemporalObjectTracker } from \"../tracking/temporal-object-tracker.js\";\nimport type {\n\tInstanceMask,\n\tVisionAnalysisClassSummary,\n\tVisionAnalysisReport,\n\tVisionAnalysisTrackSummary,\n\tVisionImageInput,\n} from \"../types.js\";\n\n/**\n * One-shot, ffmpeg-free sequence analysis.\n *\n * Pure frame-iterable analyzer: it never decodes media itself, so it stays engine-only and\n * offline-testable. Callers (e.g. the framefields ingestion adapter) supply decoded frames.\n * Model loading remains lazy — the runner downloads each task's model on the first frame\n * that actually runs that task, and only the tasks requested here are ever touched.\n */\n\nexport interface AnalyzeSequenceOptions {\n\treadonly runner: VisionRunner;\n\t/** Label for the report (\"clip.mp4\" or similar). Defaults to \"frames\". */\n\treadonly source?: string;\n\treadonly fps?: number;\n\t/** Tasks to run. Defaults to `[\"detect\"]`. Only these models are ever downloaded. */\n\treadonly tasks?: readonly VisionTask[];\n\t/** Restrict class summaries to these categories (all when omitted). */\n\treadonly categories?: readonly string[];\n\t/** Tracker box-association IoU. Default 0.25. */\n\treadonly iouThreshold?: number;\n\treadonly maxMissedFrames?: number;\n\t/** Sample the per-track center path every N frames. Default: ~50 points across the clip. */\n\treadonly pathStride?: number;\n\t/** Also aggregate instance-mask coverage (requires the `segment` task). Default false. */\n\treadonly includeMasks?: boolean;\n}\n\ninterface TrackAccumulator {\n\tcategory: string;\n\tfirstFrame: number;\n\tlastFrame: number;\n\tspeedSum: number;\n\tspeedCount: number;\n\tcenters: Array<{ frame: number; x: number; y: number }>;\n}\n\ninterface CoverageAccumulator {\n\tsum: number;\n\tcount: number;\n}\n\nconst now = (): number =>\n\ttypeof performance !== \"undefined\" && typeof performance.now === \"function\"\n\t\t? performance.now()\n\t\t: Date.now();\n\nexport async function analyzeSequence(\n\tframes: AsyncIterable<VisionImageInput> | Iterable<VisionImageInput>,\n\toptions: AnalyzeSequenceOptions,\n): Promise<VisionAnalysisReport> {\n\tconst { runner } = options;\n\tconst fps = options.fps ?? 24;\n\tconst tasks =\n\t\toptions.tasks && options.tasks.length > 0\n\t\t\t? options.tasks\n\t\t\t: ([\"detect\"] as const);\n\tconst taskSet = new Set<VisionTask>(tasks);\n\tconst categoryFilter = options.categories\n\t\t? new Set(options.categories.map((c) => c.toLowerCase()))\n\t\t: null;\n\tconst includeMasks = options.includeMasks === true && taskSet.has(\"segment\");\n\t// detect and segment share one RTMDet-Ins pass, so either yields detections.\n\tconst tracksObjects = taskSet.has(\"detect\") || taskSet.has(\"segment\");\n\n\tconst perFrameDetections: Array<readonly DetectedObject[]> = [];\n\tconst modelDownloads: Record<string, { bytes: number; ms: number }> = {};\n\tconst maskCoverage = new Map<string, CoverageAccumulator>();\n\tlet inferenceMs = 0;\n\tlet frameIndex = 0;\n\n\tconst accepts = (category: string): boolean =>\n\t\t!categoryFilter || categoryFilter.has(category.toLowerCase());\n\n\tconst runTask = async <T>(\n\t\ttask: VisionTask,\n\t\tframe: VisionImageInput,\n\t\tfn: () => Promise<T>,\n\t): Promise<T> => {\n\t\tconst key = runner.modelKeyFor(task, frame.width / frame.height);\n\t\tconst wasReady = runner.downloadStatus.get(key) === \"ready\";\n\t\tconst start = now();\n\t\tconst result = await fn();\n\t\tconst elapsed = now() - start;\n\t\tinferenceMs += elapsed;\n\t\tif (!wasReady && !modelDownloads[key]) {\n\t\t\tmodelDownloads[key] = { bytes: VISION_MODELS[key].bytes, ms: elapsed };\n\t\t}\n\t\treturn result;\n\t};\n\n\tconst recordMasks = (masks: readonly InstanceMask[]): void => {\n\t\tfor (const m of masks) {\n\t\t\tif (!accepts(m.category)) continue;\n\t\t\tconst entry = maskCoverage.get(m.category) ?? { sum: 0, count: 0 };\n\t\t\tentry.sum += m.coverage;\n\t\t\tentry.count++;\n\t\t\tmaskCoverage.set(m.category, entry);\n\t\t}\n\t};\n\n\tfor await (const frame of frames) {\n\t\tlet detections: readonly DetectedObject[] = [];\n\n\t\tif (includeMasks) {\n\t\t\tconst seg = await runTask(\"segment\", frame, () => runner.segment(frame));\n\t\t\trecordMasks(seg.masks);\n\t\t\tdetections = seg.detections;\n\t\t} else if (tracksObjects) {\n\t\t\tdetections = await runTask(\"detect\", frame, () => runner.detect(frame));\n\t\t}\n\t\tif (taskSet.has(\"pose\")) {\n\t\t\tawait runTask(\"pose\", frame, () => runner.pose(frame));\n\t\t}\n\t\tif (taskSet.has(\"matte\")) {\n\t\t\tawait runTask(\"matte\", frame, () => runner.matte(frame));\n\t\t}\n\n\t\tperFrameDetections.push(\n\t\t\tcategoryFilter\n\t\t\t\t? detections.filter((d) => accepts(d.category))\n\t\t\t\t: detections,\n\t\t);\n\t\tframeIndex++;\n\t}\n\n\tconst totalFrames = frameIndex;\n\n\t// Temporal association + gap interpolation over the whole sequence.\n\tconst tracker = new TemporalObjectTracker({\n\t\tiouThreshold: options.iouThreshold ?? 0.25,\n\t\tmaxMissedFrames: options.maxMissedFrames ?? 15,\n\t});\n\tconst trackedPerFrame = tracker.trackSequence(\n\t\tperFrameDetections,\n\t\ttotalFrames,\n\t\tfps,\n\t);\n\n\tconst pathStride =\n\t\toptions.pathStride ?? Math.max(1, Math.ceil(totalFrames / 50));\n\n\tconst tracks = new Map<number, TrackAccumulator>();\n\tconst classPresentFrames = new Map<string, Set<number>>();\n\tconst classMaxConfidence = new Map<string, number>();\n\tconst classTrackIds = new Map<string, Set<number>>();\n\n\tconst getOrCreate = <T>(\n\t\tmap: Map<string, T>,\n\t\tkey: string,\n\t\tmake: () => T,\n\t): T => {\n\t\tlet value = map.get(key);\n\t\tif (value === undefined) {\n\t\t\tvalue = make();\n\t\t\tmap.set(key, value);\n\t\t}\n\t\treturn value;\n\t};\n\n\tfor (let f = 0; f < totalFrames; f++) {\n\t\tfor (const obj of trackedPerFrame[f] ?? []) {\n\t\t\tif (!accepts(obj.category)) continue;\n\n\t\t\tlet acc = tracks.get(obj.trackId);\n\t\t\tif (!acc) {\n\t\t\t\tacc = {\n\t\t\t\t\tcategory: obj.category,\n\t\t\t\t\tfirstFrame: f,\n\t\t\t\t\tlastFrame: f,\n\t\t\t\t\tspeedSum: 0,\n\t\t\t\t\tspeedCount: 0,\n\t\t\t\t\tcenters: [],\n\t\t\t\t};\n\t\t\t\ttracks.set(obj.trackId, acc);\n\t\t\t}\n\t\t\tacc.lastFrame = f;\n\t\t\tif (Number.isFinite(obj.speed)) {\n\t\t\t\tacc.speedSum += obj.speed;\n\t\t\t\tacc.speedCount++;\n\t\t\t}\n\t\t\tif ((f - acc.firstFrame) % pathStride === 0) {\n\t\t\t\tacc.centers.push({ frame: f, x: obj.centerX, y: obj.centerY });\n\t\t\t}\n\n\t\t\tgetOrCreate(\n\t\t\t\tclassPresentFrames,\n\t\t\t\tobj.category,\n\t\t\t\t() => new Set<number>(),\n\t\t\t).add(f);\n\t\t\tclassMaxConfidence.set(\n\t\t\t\tobj.category,\n\t\t\t\tMath.max(classMaxConfidence.get(obj.category) ?? 0, obj.score),\n\t\t\t);\n\t\t\tgetOrCreate(classTrackIds, obj.category, () => new Set<number>()).add(\n\t\t\t\tobj.trackId,\n\t\t\t);\n\t\t}\n\t}\n\n\tconst trackSummaries: VisionAnalysisTrackSummary[] = Array.from(\n\t\ttracks.entries(),\n\t)\n\t\t.map(([trackId, acc]) => ({\n\t\t\ttrackId,\n\t\t\tcategory: acc.category,\n\t\t\tframes: [acc.firstFrame, acc.lastFrame] as [number, number],\n\t\t\tspeedMeanPxS: acc.speedCount > 0 ? acc.speedSum / acc.speedCount : 0,\n\t\t\tcenterPath: acc.centers.map((c) => [c.x, c.y] as [number, number]),\n\t\t}))\n\t\t.sort((a, b) => a.trackId - b.trackId);\n\n\tconst classes: Record<string, VisionAnalysisClassSummary> = {};\n\tfor (const [category, frameSet] of classPresentFrames) {\n\t\tclasses[category] = {\n\t\t\tframesPresent: frameSet.size,\n\t\t\ttotalFrames,\n\t\t\tmaxConfidence: classMaxConfidence.get(category) ?? 0,\n\t\t\ttracks: classTrackIds.get(category)?.size ?? 0,\n\t\t};\n\t}\n\n\tconst masks: Record<string, { meanCoverage: number }> = {};\n\tfor (const [category, entry] of maskCoverage) {\n\t\tmasks[category] = {\n\t\t\tmeanCoverage: entry.count > 0 ? entry.sum / entry.count : 0,\n\t\t};\n\t}\n\n\treturn {\n\t\tsource: options.source ?? \"frames\",\n\t\ttotalFrames,\n\t\tfps,\n\t\tdurationSec: fps > 0 ? totalFrames / fps : 0,\n\t\ttasks: Array.from(taskSet),\n\t\tmodelDownloads,\n\t\tinferenceMs,\n\t\ttrackCount: trackSummaries.length,\n\t\tclasses,\n\t\ttracks: trackSummaries,\n\t\tmasks,\n\t};\n}\n","/**\n * Image → NCHW float tensor preprocessing, plus the inverse mapping back to source pixels.\n *\n * Each model family was exported with its own preprocessing contract:\n *\n * | Model | Resize | Pad | Channels | Values |\n * | ----------- | ---------------------------- | ---- | -------- | -------------------------- |\n * | RTMDet-Ins | keep ratio, content top-left | 114 | BGR | (v − mean) / std (ImageNet) |\n * | RTMO | keep ratio, content centered | 114 | BGR | raw 0..255 |\n * | Selfie | stretch to input | — | RGB | v / 255 |\n *\n * Getting any of these wrong does not crash — it silently degrades accuracy — so the specs\n * live here and every runner path goes through `imageToTensor`. Input sizes differ per model\n * (RTMO-t is 416², the rest of RTMO 640²), so they come from the registry, never from here.\n */\n\nexport interface RgbaImage {\n\treadonly data: Uint8ClampedArray | Uint8Array;\n\treadonly width: number;\n\treadonly height: number;\n}\n\nexport interface PreprocessSpec {\n\t/** Model input size in pixels. */\n\treadonly width: number;\n\treadonly height: number;\n\t/** `topLeft` / `center` keep aspect ratio and pad; `stretch` fills the input. */\n\treadonly fit: \"topLeft\" | \"center\" | \"stretch\";\n\treadonly channels: \"rgb\" | \"bgr\";\n\t/** Per-channel mean, in output channel order, on the 0..255 scale. */\n\treadonly mean: readonly [number, number, number];\n\t/** Per-channel std, in output channel order, on the 0..255 scale. */\n\treadonly std: readonly [number, number, number];\n\t/** Padding value on the 0..255 scale (normalized like any other pixel). */\n\treadonly padValue: number;\n}\n\n/** Maps model-input pixels back to source pixels: `src = (input − offset) / scale`. */\nexport interface InputTransform {\n\treadonly scaleX: number;\n\treadonly scaleY: number;\n\treadonly offsetX: number;\n\treadonly offsetY: number;\n\treadonly inputWidth: number;\n\treadonly inputHeight: number;\n}\n\nconst IMAGENET_BGR_MEAN = [103.53, 116.28, 123.675] as const;\nconst IMAGENET_BGR_STD = [57.375, 57.12, 58.395] as const;\n\ntype Normalization = Omit<PreprocessSpec, \"width\" | \"height\">;\n\n/** Per-family normalization; the input size always comes from the model's registry entry. */\nexport const PREPROCESS_BY_FAMILY: Readonly<\n\tRecord<\"rtmdet-ins\" | \"rtmo\" | \"selfie\", Normalization>\n> = {\n\t\"rtmdet-ins\": {\n\t\tfit: \"topLeft\",\n\t\tchannels: \"bgr\",\n\t\tmean: IMAGENET_BGR_MEAN,\n\t\tstd: IMAGENET_BGR_STD,\n\t\tpadValue: 114,\n\t},\n\trtmo: {\n\t\tfit: \"center\",\n\t\tchannels: \"bgr\",\n\t\tmean: [0, 0, 0],\n\t\tstd: [1, 1, 1],\n\t\tpadValue: 114,\n\t},\n\tselfie: {\n\t\tfit: \"stretch\",\n\t\tchannels: \"rgb\",\n\t\tmean: [0, 0, 0],\n\t\tstd: [255, 255, 255],\n\t\tpadValue: 0,\n\t},\n};\n\nexport function preprocessSpec(\n\tfamily: keyof typeof PREPROCESS_BY_FAMILY,\n\tinput: readonly [number, number],\n): PreprocessSpec {\n\treturn { ...PREPROCESS_BY_FAMILY[family], width: input[0], height: input[1] };\n}\n\nexport function computeInputTransform(\n\tsrcW: number,\n\tsrcH: number,\n\tspec: Pick<PreprocessSpec, \"width\" | \"height\" | \"fit\">,\n): InputTransform {\n\tif (spec.fit === \"stretch\") {\n\t\treturn {\n\t\t\tscaleX: spec.width / srcW,\n\t\t\tscaleY: spec.height / srcH,\n\t\t\toffsetX: 0,\n\t\t\toffsetY: 0,\n\t\t\tinputWidth: spec.width,\n\t\t\tinputHeight: spec.height,\n\t\t};\n\t}\n\tconst scale = Math.min(spec.width / srcW, spec.height / srcH);\n\tconst contentW = Math.round(srcW * scale);\n\tconst contentH = Math.round(srcH * scale);\n\tconst center = spec.fit === \"center\";\n\treturn {\n\t\tscaleX: scale,\n\t\tscaleY: scale,\n\t\toffsetX: center ? (spec.width - contentW) / 2 : 0,\n\t\toffsetY: center ? (spec.height - contentH) / 2 : 0,\n\t\tinputWidth: spec.width,\n\t\tinputHeight: spec.height,\n\t};\n}\n\n/** Model-input point → source pixel point. */\nexport function toSourcePoint(\n\tx: number,\n\ty: number,\n\tt: InputTransform,\n): { x: number; y: number } {\n\treturn { x: (x - t.offsetX) / t.scaleX, y: (y - t.offsetY) / t.scaleY };\n}\n\n/**\n * Resizes RGBA → NCHW float32 `[1, 3, height, width]` with bilinear sampling, padding,\n * channel reordering and normalization per `spec`. Reuses `out` when large enough\n * (hot-path frame loop).\n */\nexport function imageToTensor(\n\timage: RgbaImage,\n\tspec: PreprocessSpec,\n\tout?: Float32Array,\n): { tensor: Float32Array; transform: InputTransform } {\n\tconst { width: srcW, height: srcH, data: src } = image;\n\tconst { width: W, height: H } = spec;\n\tconst transform = computeInputTransform(srcW, srcH, spec);\n\tconst { scaleX, scaleY, offsetX, offsetY } = transform;\n\n\tconst plane = W * H;\n\tif (!out || out.length < 3 * plane) {\n\t\tout = new Float32Array(3 * plane);\n\t}\n\n\t// Source channel feeding each output plane (RGBA byte offsets).\n\tconst order = spec.channels === \"bgr\" ? [2, 1, 0] : [0, 1, 2];\n\tconst [m0, m1, m2] = spec.mean;\n\tconst inv0 = 1 / spec.std[0];\n\tconst inv1 = 1 / spec.std[1];\n\tconst inv2 = 1 / spec.std[2];\n\tconst pad0 = (spec.padValue - m0) * inv0;\n\tconst pad1 = (spec.padValue - m1) * inv1;\n\tconst pad2 = (spec.padValue - m2) * inv2;\n\tconst [c0, c1, c2] = order;\n\n\tconst x0 = Math.ceil(offsetX);\n\tconst y0 = Math.ceil(offsetY);\n\tconst x1 = Math.min(W, Math.floor(offsetX + srcW * scaleX)) - 1;\n\tconst y1 = Math.min(H, Math.floor(offsetY + srcH * scaleY)) - 1;\n\n\tfor (let y = 0; y < H; y++) {\n\t\tconst rowBase = y * W;\n\t\tconst paddedRow = y < y0 || y > y1;\n\t\t// Pixel-center sampling keeps stretch/letterbox resizes unbiased.\n\t\tconst sy = Math.max(0, (y + 0.5 - offsetY) / scaleY - 0.5);\n\t\tconst iy0 = Math.min(srcH - 1, Math.floor(sy));\n\t\tconst iy1 = Math.min(srcH - 1, iy0 + 1);\n\t\tconst fy = sy - iy0;\n\t\tfor (let x = 0; x < W; x++) {\n\t\t\tconst o = rowBase + x;\n\t\t\tif (paddedRow || x < x0 || x > x1) {\n\t\t\t\tout[o] = pad0;\n\t\t\t\tout[plane + o] = pad1;\n\t\t\t\tout[2 * plane + o] = pad2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst sx = Math.max(0, (x + 0.5 - offsetX) / scaleX - 0.5);\n\t\t\tconst ix0 = Math.min(srcW - 1, Math.floor(sx));\n\t\t\tconst ix1 = Math.min(srcW - 1, ix0 + 1);\n\t\t\tconst fx = sx - ix0;\n\t\t\tconst i00 = (iy0 * srcW + ix0) * 4;\n\t\t\tconst i10 = (iy0 * srcW + ix1) * 4;\n\t\t\tconst i01 = (iy1 * srcW + ix0) * 4;\n\t\t\tconst i11 = (iy1 * srcW + ix1) * 4;\n\t\t\tconst w00 = (1 - fx) * (1 - fy);\n\t\t\tconst w10 = fx * (1 - fy);\n\t\t\tconst w01 = (1 - fx) * fy;\n\t\t\tconst w11 = fx * fy;\n\t\t\tout[o] =\n\t\t\t\t(src[i00 + c0] * w00 +\n\t\t\t\t\tsrc[i10 + c0] * w10 +\n\t\t\t\t\tsrc[i01 + c0] * w01 +\n\t\t\t\t\tsrc[i11 + c0] * w11 -\n\t\t\t\t\tm0) *\n\t\t\t\tinv0;\n\t\t\tout[plane + o] =\n\t\t\t\t(src[i00 + c1] * w00 +\n\t\t\t\t\tsrc[i10 + c1] * w10 +\n\t\t\t\t\tsrc[i01 + c1] * w01 +\n\t\t\t\t\tsrc[i11 + c1] * w11 -\n\t\t\t\t\tm1) *\n\t\t\t\tinv1;\n\t\t\tout[2 * plane + o] =\n\t\t\t\t(src[i00 + c2] * w00 +\n\t\t\t\t\tsrc[i10 + c2] * w10 +\n\t\t\t\t\tsrc[i01 + c2] * w01 +\n\t\t\t\t\tsrc[i11 + c2] * w11 -\n\t\t\t\t\tm2) *\n\t\t\t\tinv2;\n\t\t}\n\t}\n\n\treturn { tensor: out, transform };\n}\n","import type { DetectedObject } from \"@framefields/core\";\nimport type { InstanceMask, SegmentationResult } from \"../types.js\";\nimport { type InputTransform, toSourcePoint } from \"./preprocess.js\";\n\n/**\n * RTMDet-Ins decode (mmdeploy end2end export — NMS and mask assembly are baked into the graph).\n *\n * Outputs:\n * dets [1, N, 5] x0, y0, x1, y1 (input px), score\n * labels [1, N] COCO-80 class index (int64)\n * masks [1, N, Hm, Wm] per-instance probabilities (already sigmoided), input-aligned\n */\nexport interface RtmdetInsOutputs {\n\treadonly dets: ArrayLike<number>;\n\treadonly labels: ArrayLike<number | bigint>;\n\t/** Omit to decode boxes only (detection without masks). */\n\treadonly masks?: ArrayLike<number>;\n\treadonly count: number;\n\treadonly maskWidth: number;\n\treadonly maskHeight: number;\n}\n\nexport interface RtmdetInsDecodeOptions {\n\treadonly confidence: number;\n\t/** Class-name filter, case-insensitive (all classes when omitted). */\n\treadonly classes?: readonly string[];\n\treadonly classNames: readonly string[];\n\treadonly transform: InputTransform;\n\treadonly sourceWidth: number;\n\treadonly sourceHeight: number;\n\t/** Mask probability threshold. Default 0.5. */\n\treadonly maskThreshold?: number;\n\t/** Soft-edge band around the threshold. Default 0.05. */\n\treadonly featherRadius?: number;\n}\n\n/** Source pixels a mask may extend past its box (instance masks are not box-clipped). */\nconst MASK_BOX_PAD_PX = 8;\n\nexport function decodeRtmdetIns(\n\tout: RtmdetInsOutputs,\n\topts: RtmdetInsDecodeOptions,\n): SegmentationResult {\n\tconst { sourceWidth: sw, sourceHeight: sh, transform } = opts;\n\tconst classFilter = opts.classes\n\t\t? new Set(opts.classes.map((c) => c.toLowerCase()))\n\t\t: null;\n\n\tconst kept: Array<{ index: number; detection: DetectedObject }> = [];\n\tfor (let i = 0; i < out.count; i++) {\n\t\tconst score = out.dets[i * 5 + 4];\n\t\tif (!(score >= opts.confidence)) continue;\n\t\tconst classIndex = Number(out.labels[i]);\n\t\tconst category = opts.classNames[classIndex] ?? `class_${classIndex}`;\n\t\tif (classFilter && !classFilter.has(category.toLowerCase())) continue;\n\n\t\tconst p0 = toSourcePoint(out.dets[i * 5], out.dets[i * 5 + 1], transform);\n\t\tconst p1 = toSourcePoint(\n\t\t\tout.dets[i * 5 + 2],\n\t\t\tout.dets[i * 5 + 3],\n\t\t\ttransform,\n\t\t);\n\t\tconst x0 = clamp(p0.x, 0, sw);\n\t\tconst y0 = clamp(p0.y, 0, sh);\n\t\tconst width = clamp(p1.x, 0, sw) - x0;\n\t\tconst height = clamp(p1.y, 0, sh) - y0;\n\t\tif (width <= 0 || height <= 0) continue;\n\n\t\tkept.push({\n\t\t\tindex: i,\n\t\t\tdetection: {\n\t\t\t\tcategory,\n\t\t\t\tscore,\n\t\t\t\tboundingBox: {\n\t\t\t\t\toriginX: x0,\n\t\t\t\t\toriginY: y0,\n\t\t\t\t\twidth,\n\t\t\t\t\theight,\n\t\t\t\t\tnormalizedX: x0 / sw,\n\t\t\t\t\tnormalizedY: y0 / sh,\n\t\t\t\t\tnormalizedWidth: width / sw,\n\t\t\t\t\tnormalizedHeight: height / sh,\n\t\t\t\t},\n\t\t\t},\n\t\t});\n\t}\n\tkept.sort((a, b) => b.detection.score - a.detection.score);\n\n\tconst detections = kept.map((k) => k.detection);\n\tconst masks: InstanceMask[] = [];\n\tif (!out.masks) return { detections, masks };\n\n\tconst alphaOf = probabilityToAlpha(\n\t\topts.maskThreshold ?? 0.5,\n\t\topts.featherRadius ?? 0.05,\n\t);\n\tconst { maskWidth: mw, maskHeight: mh } = out;\n\tconst plane = mw * mh;\n\t// Mask grid px per input px (exports may emit masks below input resolution).\n\tconst gx = mw / transform.inputWidth;\n\tconst gy = mh / transform.inputHeight;\n\n\tfor (let d = 0; d < kept.length; d++) {\n\t\tconst { index, detection } = kept[d];\n\t\tconst box = detection.boundingBox;\n\t\tconst base = index * plane;\n\t\tconst bx0 = Math.max(0, Math.floor(box.originX) - MASK_BOX_PAD_PX);\n\t\tconst by0 = Math.max(0, Math.floor(box.originY) - MASK_BOX_PAD_PX);\n\t\tconst bx1 = Math.min(\n\t\t\tsw - 1,\n\t\t\tMath.ceil(box.originX + box.width) + MASK_BOX_PAD_PX,\n\t\t);\n\t\tconst by1 = Math.min(\n\t\t\tsh - 1,\n\t\t\tMath.ceil(box.originY + box.height) + MASK_BOX_PAD_PX,\n\t\t);\n\n\t\tconst mask = new Uint8Array(sw * sh);\n\t\tlet area = 0;\n\t\tfor (let sy = by0; sy <= by1; sy++) {\n\t\t\t// source pixel center → input px → mask grid (pixel-center aligned)\n\t\t\tconst my = ((sy + 0.5) * transform.scaleY + transform.offsetY) * gy - 0.5;\n\t\t\tconst my0 = clamp(Math.floor(my), 0, mh - 1);\n\t\t\tconst my1 = Math.min(mh - 1, my0 + 1);\n\t\t\tconst fy = clamp(my - my0, 0, 1);\n\t\t\tconst row = sy * sw;\n\t\t\tfor (let sx = bx0; sx <= bx1; sx++) {\n\t\t\t\tconst mx =\n\t\t\t\t\t((sx + 0.5) * transform.scaleX + transform.offsetX) * gx - 0.5;\n\t\t\t\tconst mx0 = clamp(Math.floor(mx), 0, mw - 1);\n\t\t\t\tconst mx1 = Math.min(mw - 1, mx0 + 1);\n\t\t\t\tconst fx = clamp(mx - mx0, 0, 1);\n\t\t\t\tconst p =\n\t\t\t\t\tout.masks[base + my0 * mw + mx0] * (1 - fx) * (1 - fy) +\n\t\t\t\t\tout.masks[base + my0 * mw + mx1] * fx * (1 - fy) +\n\t\t\t\t\tout.masks[base + my1 * mw + mx0] * (1 - fx) * fy +\n\t\t\t\t\tout.masks[base + my1 * mw + mx1] * fx * fy;\n\t\t\t\tconst alpha = alphaOf(p);\n\t\t\t\tif (alpha > 0) {\n\t\t\t\t\tmask[row + sx] = alpha;\n\t\t\t\t\tarea += alpha / 255;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tarea = Math.round(area);\n\t\tif (area === 0) continue;\n\t\tmasks.push({\n\t\t\tcategory: detection.category,\n\t\t\tmask,\n\t\t\twidth: sw,\n\t\t\theight: sh,\n\t\t\tarea,\n\t\t\tcoverage: area / (sw * sh),\n\t\t\tdetectionIndex: d,\n\t\t});\n\t}\n\n\treturn { detections, masks };\n}\n\n/**\n * Probability → 0..255 alpha. A hard threshold when `feather` is 0, otherwise a linear ramp\n * across `[threshold − feather, threshold + feather]` for anti-aliased edges.\n */\nexport function probabilityToAlpha(\n\tthreshold: number,\n\tfeather: number,\n): (p: number) => number {\n\tif (feather <= 0) {\n\t\treturn (p) => (p > threshold ? 255 : 0);\n\t}\n\tconst lo = threshold - feather;\n\tconst inv = 255 / (2 * feather);\n\treturn (p) => (p <= lo ? 0 : p >= threshold + feather ? 255 : (p - lo) * inv);\n}\n\nfunction clamp(v: number, lo: number, hi: number): number {\n\treturn v < lo ? lo : v > hi ? hi : v;\n}\n","import { computeIoU } from \"../tracking/temporal-object-tracker.js\";\nimport type { PoseKeypoint, PosePerson, PoseResult } from \"../types.js\";\nimport { type InputTransform, toSourcePoint } from \"./preprocess.js\";\n\n/**\n * RTMO decode (one-stage multi-person pose; NMS is baked into the export).\n *\n * Outputs:\n * dets [1, N, 5] x0, y0, x1, y1 (input px), person score\n * keypoints [1, N, 17, 3] x, y (input px), keypoint score — COCO-17 order\n */\nexport interface RtmoOutputs {\n\treadonly dets: ArrayLike<number>;\n\treadonly keypoints: ArrayLike<number>;\n\treadonly count: number;\n\t/** Values per keypoint (3 for x, y, score). */\n\treadonly keypointStride: number;\n}\n\nexport interface RtmoDecodeOptions {\n\treadonly confidence: number;\n\treadonly transform: InputTransform;\n\treadonly sourceWidth: number;\n\treadonly sourceHeight: number;\n\t/** Drop people with fewer keypoints at visibility ≥ 0.3. Default 3. */\n\treadonly minVisibleKeypoints?: number;\n\t/** Suppress a person whose box overlaps a higher-scored one above this IoU. Default 0.6. */\n\treadonly iouThreshold?: number;\n}\n\nexport const COCO17_KEYPOINT_COUNT = 17;\n\n/** Keypoint visibility at which a joint counts as seen. */\nconst VISIBLE = 0.3;\n\nexport function decodeRtmo(\n\tout: RtmoOutputs,\n\topts: RtmoDecodeOptions,\n): PoseResult {\n\tconst { sourceWidth: sw, sourceHeight: sh, transform } = opts;\n\tconst stride = out.keypointStride;\n\tconst people: PosePerson[] = [];\n\n\tfor (let i = 0; i < out.count; i++) {\n\t\tconst score = out.dets[i * 5 + 4];\n\t\tif (!(score >= opts.confidence)) continue;\n\n\t\tconst p0 = toSourcePoint(out.dets[i * 5], out.dets[i * 5 + 1], transform);\n\t\tconst p1 = toSourcePoint(\n\t\t\tout.dets[i * 5 + 2],\n\t\t\tout.dets[i * 5 + 3],\n\t\t\ttransform,\n\t\t);\n\t\tconst x0 = clamp(p0.x, 0, sw);\n\t\tconst y0 = clamp(p0.y, 0, sh);\n\t\tconst width = clamp(p1.x, 0, sw) - x0;\n\t\tconst height = clamp(p1.y, 0, sh) - y0;\n\t\tif (width <= 0 || height <= 0) continue;\n\n\t\tconst keypoints: PoseKeypoint[] = [];\n\t\tconst base = i * COCO17_KEYPOINT_COUNT * stride;\n\t\tfor (let k = 0; k < COCO17_KEYPOINT_COUNT; k++) {\n\t\t\tconst o = base + k * stride;\n\t\t\tconst p = toSourcePoint(\n\t\t\t\tout.keypoints[o],\n\t\t\t\tout.keypoints[o + 1],\n\t\t\t\ttransform,\n\t\t\t);\n\t\t\tkeypoints.push({\n\t\t\t\tx: clamp(p.x, 0, sw),\n\t\t\t\ty: clamp(p.y, 0, sh),\n\t\t\t\tvisibility: clamp(out.keypoints[o + 2], 0, 1),\n\t\t\t});\n\t\t}\n\n\t\tlet visible = 0;\n\t\tfor (const k of keypoints) if (k.visibility >= VISIBLE) visible++;\n\t\tif (visible < (opts.minVisibleKeypoints ?? 3)) continue;\n\n\t\tpeople.push({\n\t\t\tscore,\n\t\t\tboundingBox: {\n\t\t\t\toriginX: x0,\n\t\t\t\toriginY: y0,\n\t\t\t\twidth,\n\t\t\t\theight,\n\t\t\t\tnormalizedX: x0 / sw,\n\t\t\t\tnormalizedY: y0 / sh,\n\t\t\t\tnormalizedWidth: width / sw,\n\t\t\t\tnormalizedHeight: height / sh,\n\t\t\t},\n\t\t\tkeypoints,\n\t\t});\n\t}\n\n\t// Highest-confidence person first — the bundle's named signals track it as primary.\n\t// The export's built-in NMS lets near-identical low-score duplicates through; drop them.\n\tpeople.sort((a, b) => b.score - a.score);\n\tconst iou = opts.iouThreshold ?? 0.6;\n\tconst kept: PosePerson[] = [];\n\tfor (const p of people) {\n\t\tif (!kept.some((k) => isDuplicate(k, p, iou))) kept.push(p);\n\t}\n\treturn { people: kept };\n}\n\nfunction clamp(v: number, lo: number, hi: number): number {\n\treturn v < lo ? lo : v > hi ? hi : v;\n}\n\n/**\n * Same person twice: boxes overlap above `iou`, or the joints both detections can see sit\n * within 10% of the stronger detection's box size of each other (boxes may differ when one\n * of them also covers a flowing garment or a shadow).\n */\nfunction isDuplicate(a: PosePerson, b: PosePerson, iou: number): boolean {\n\tif (computeIoU(a.boundingBox, b.boundingBox) > iou) return true;\n\tconst scale = Math.sqrt(a.boundingBox.width * a.boundingBox.height);\n\tlet sum = 0;\n\tlet n = 0;\n\tfor (let k = 0; k < a.keypoints.length; k++) {\n\t\tconst ka = a.keypoints[k];\n\t\tconst kb = b.keypoints[k];\n\t\tif (ka.visibility < VISIBLE || kb.visibility < VISIBLE) continue;\n\t\tsum += Math.hypot(ka.x - kb.x, ka.y - kb.y);\n\t\tn++;\n\t}\n\treturn n >= 3 && sum / n < 0.1 * scale;\n}\n","import type { PersonMatte } from \"../types.js\";\nimport { probabilityToAlpha } from \"./rtmdet-ins.js\";\n\n/**\n * Selfie Segmenter decode: `alphas [1, 1, h, w]` person probability (stretched input) →\n * frame-sized 0..255 alpha, bilinear-upsampled to the source resolution.\n */\nexport interface SelfieDecodeOptions {\n\treadonly sourceWidth: number;\n\treadonly sourceHeight: number;\n\t/** Probability threshold. Default 0.5. */\n\treadonly maskThreshold?: number;\n\t/** Soft-edge band; the low-res matte reads best with a wide one. Default 0.2. */\n\treadonly featherRadius?: number;\n}\n\nexport function decodeSelfie(\n\talphas: ArrayLike<number>,\n\tmatteWidth: number,\n\tmatteHeight: number,\n\topts: SelfieDecodeOptions,\n): PersonMatte {\n\tconst { sourceWidth: sw, sourceHeight: sh } = opts;\n\tconst alphaOf = probabilityToAlpha(\n\t\topts.maskThreshold ?? 0.5,\n\t\topts.featherRadius ?? 0.2,\n\t);\n\tconst mask = new Uint8Array(sw * sh);\n\tconst kx = matteWidth / sw;\n\tconst ky = matteHeight / sh;\n\tlet sum = 0;\n\n\tfor (let y = 0; y < sh; y++) {\n\t\tconst my = Math.max(0, (y + 0.5) * ky - 0.5);\n\t\tconst my0 = Math.min(matteHeight - 1, Math.floor(my));\n\t\tconst my1 = Math.min(matteHeight - 1, my0 + 1);\n\t\tconst fy = my - my0;\n\t\tfor (let x = 0; x < sw; x++) {\n\t\t\tconst mx = Math.max(0, (x + 0.5) * kx - 0.5);\n\t\t\tconst mx0 = Math.min(matteWidth - 1, Math.floor(mx));\n\t\t\tconst mx1 = Math.min(matteWidth - 1, mx0 + 1);\n\t\t\tconst fx = mx - mx0;\n\t\t\tconst p =\n\t\t\t\talphas[my0 * matteWidth + mx0] * (1 - fx) * (1 - fy) +\n\t\t\t\talphas[my0 * matteWidth + mx1] * fx * (1 - fy) +\n\t\t\t\talphas[my1 * matteWidth + mx0] * (1 - fx) * fy +\n\t\t\t\talphas[my1 * matteWidth + mx1] * fx * fy;\n\t\t\tconst a = alphaOf(p);\n\t\t\tmask[y * sw + x] = a;\n\t\t\tsum += a;\n\t\t}\n\t}\n\n\treturn {\n\t\tmask,\n\t\twidth: sw,\n\t\theight: sh,\n\t\tcoverage: sw * sh > 0 ? sum / (255 * sw * sh) : 0,\n\t};\n}\n","/** COCO-17 keypoint indices (RTMO output order). */\nexport const COCO17_KEYPOINTS = {\n\tNOSE: 0,\n\tLEFT_EYE: 1,\n\tRIGHT_EYE: 2,\n\tLEFT_EAR: 3,\n\tRIGHT_EAR: 4,\n\tLEFT_SHOULDER: 5,\n\tRIGHT_SHOULDER: 6,\n\tLEFT_ELBOW: 7,\n\tRIGHT_ELBOW: 8,\n\tLEFT_WRIST: 9,\n\tRIGHT_WRIST: 10,\n\tLEFT_HIP: 11,\n\tRIGHT_HIP: 12,\n\tLEFT_KNEE: 13,\n\tRIGHT_KNEE: 14,\n\tLEFT_ANKLE: 15,\n\tRIGHT_ANKLE: 16,\n} as const;\n\nexport const COCO17_KEYPOINT_NAMES = [\n\t\"nose\",\n\t\"leftEye\",\n\t\"rightEye\",\n\t\"leftEar\",\n\t\"rightEar\",\n\t\"leftShoulder\",\n\t\"rightShoulder\",\n\t\"leftElbow\",\n\t\"rightElbow\",\n\t\"leftWrist\",\n\t\"rightWrist\",\n\t\"leftHip\",\n\t\"rightHip\",\n\t\"leftKnee\",\n\t\"rightKnee\",\n\t\"leftAnkle\",\n\t\"rightAnkle\",\n] as const;\n\n/** COCO-17 skeleton bones for the WebGPU skeleton renderer (indices above). */\nexport const COCO17_BONES = [\n\t{\n\t\tfrom: COCO17_KEYPOINTS.NOSE,\n\t\tto: COCO17_KEYPOINTS.LEFT_SHOULDER,\n\t\tcolor: [0.0, 1.0, 1.0, 1.0] as const,\n\t},\n\t{\n\t\tfrom: COCO17_KEYPOINTS.NOSE,\n\t\tto: COCO17_KEYPOINTS.RIGHT_SHOULDER,\n\t\tcolor: [0.0, 1.0, 1.0, 1.0] as const,\n\t},\n\t{\n\t\tfrom: COCO17_KEYPOINTS.LEFT_SHOULDER,\n\t\tto: COCO17_KEYPOINTS.RIGHT_SHOULDER,\n\t\tcolor: [1.0, 0.0, 0.0, 1.0] as const,\n\t},\n\t{\n\t\tfrom: COCO17_KEYPOINTS.LEFT_SHOULDER,\n\t\tto: COCO17_KEYPOINTS.LEFT_ELBOW,\n\t\tcolor: [1.0, 0.333, 0.0, 1.0] as const,\n\t},\n\t{\n\t\tfrom: COCO17_KEYPOINTS.LEFT_ELBOW,\n\t\tto: COCO17_KEYPOINTS.LEFT_WRIST,\n\t\tcolor: [1.0, 0.667, 0.0, 1.0] as const,\n\t},\n\t{\n\t\tfrom: COCO17_KEYPOINTS.RIGHT_SHOULDER,\n\t\tto: COCO17_KEYPOINTS.RIGHT_ELBOW,\n\t\tcolor: [1.0, 1.0, 0.0, 1.0] as const,\n\t},\n\t{\n\t\tfrom: COCO17_KEYPOINTS.RIGHT_ELBOW,\n\t\tto: COCO17_KEYPOINTS.RIGHT_WRIST,\n\t\tcolor: [0.667, 1.0, 0.0, 1.0] as const,\n\t},\n\t{\n\t\tfrom: COCO17_KEYPOINTS.LEFT_SHOULDER,\n\t\tto: COCO17_KEYPOINTS.LEFT_HIP,\n\t\tcolor: [0.333, 1.0, 0.0, 1.0] as const,\n\t},\n\t{\n\t\tfrom: COCO17_KEYPOINTS.RIGHT_SHOULDER,\n\t\tto: COCO17_KEYPOINTS.RIGHT_HIP,\n\t\tcolor: [0.0, 1.0, 0.0, 1.0] as const,\n\t},\n\t{\n\t\tfrom: COCO17_KEYPOINTS.LEFT_HIP,\n\t\tto: COCO17_KEYPOINTS.RIGHT_HIP,\n\t\tcolor: [0.0, 1.0, 0.333, 1.0] as const,\n\t},\n\t{\n\t\tfrom: COCO17_KEYPOINTS.LEFT_HIP,\n\t\tto: COCO17_KEYPOINTS.LEFT_KNEE,\n\t\tcolor: [0.0, 1.0, 0.667, 1.0] as const,\n\t},\n\t{\n\t\tfrom: COCO17_KEYPOINTS.LEFT_KNEE,\n\t\tto: COCO17_KEYPOINTS.LEFT_ANKLE,\n\t\tcolor: [0.0, 1.0, 1.0, 1.0] as const,\n\t},\n\t{\n\t\tfrom: COCO17_KEYPOINTS.RIGHT_HIP,\n\t\tto: COCO17_KEYPOINTS.RIGHT_KNEE,\n\t\tcolor: [0.0, 0.667, 1.0, 1.0] as const,\n\t},\n\t{\n\t\tfrom: COCO17_KEYPOINTS.RIGHT_KNEE,\n\t\tto: COCO17_KEYPOINTS.RIGHT_ANKLE,\n\t\tcolor: [0.0, 0.333, 1.0, 1.0] as const,\n\t},\n] as const;\n","import type { PoseSkeletonOptions } from \"@framefields/tensor-webgpu\";\nimport { PoseSkeletonComputePipeline } from \"@framefields/tensor-webgpu\";\nimport { COCO17_BONES } from \"../pose/keypoints.js\";\nimport type { PoseKeypoint } from \"../types.js\";\n\nexport type { PoseSkeletonOptions };\nexport type { CanonicalBoneDef as SkeletonBone } from \"@framefields/tensor-webgpu\";\n\n/**\n * WebGPU skeleton renderer for pose results.\n *\n * Rasterizes the primary person's COCO-17 keypoints into an OpenPose-style\n * conditioning texture natively in VRAM, using the COCO-17 bone set.\n */\nexport class PoseSkeletonRenderer {\n\tprivate pipeline: PoseSkeletonComputePipeline;\n\n\tconstructor(device: GPUDevice) {\n\t\tthis.pipeline = new PoseSkeletonComputePipeline(device);\n\t}\n\n\tpublic renderToTexture(\n\t\tkeypoints: readonly PoseKeypoint[],\n\t\toptions: PoseSkeletonOptions,\n\t\tbones = COCO17_BONES,\n\t): GPUTexture {\n\t\treturn this.pipeline.execute(keypoints as never, options, bones);\n\t}\n\n\tpublic destroy(): void {\n\t\tthis.pipeline.destroy();\n\t}\n}\n","export interface SegmentationTextureOptions {\n\treadonly width: number;\n\treadonly height: number;\n\treadonly format?: \"r8unorm\" | \"rgba8unorm\";\n\treadonly label?: string;\n}\n\nexport class SegmentationTexturePool {\n\tprivate device: GPUDevice;\n\tprivate pool = new Map<string, GPUTexture>();\n\n\tconstructor(device: GPUDevice) {\n\t\tthis.device = device;\n\t}\n\n\tpublic getOrCreateTexture(\n\t\tkey: string,\n\t\toptions: SegmentationTextureOptions,\n\t): GPUTexture {\n\t\tconst existing = this.pool.get(key);\n\t\tif (\n\t\t\texisting &&\n\t\t\texisting.width === options.width &&\n\t\t\texisting.height === options.height\n\t\t) {\n\t\t\treturn existing;\n\t\t}\n\n\t\tif (existing) {\n\t\t\texisting.destroy();\n\t\t}\n\n\t\tconst format = options.format ?? \"rgba8unorm\";\n\t\tconst texture = this.device.createTexture({\n\t\t\tlabel: options.label ?? `vision_segmentation_${key}`,\n\t\t\tsize: [options.width, options.height, 1],\n\t\t\tformat,\n\t\t\tusage:\n\t\t\t\tGPUTextureUsage.TEXTURE_BINDING |\n\t\t\t\tGPUTextureUsage.COPY_DST |\n\t\t\t\tGPUTextureUsage.RENDER_ATTACHMENT,\n\t\t});\n\n\t\tthis.pool.set(key, texture);\n\t\treturn texture;\n\t}\n\n\tpublic uploadMask(\n\t\tkey: string,\n\t\tmaskData: Uint8Array | Float32Array,\n\t\twidth: number,\n\t\theight: number,\n\t): GPUTexture {\n\t\tconst isRgba = maskData.length >= width * height * 4;\n\t\tconst format = isRgba ? \"rgba8unorm\" : \"r8unorm\";\n\t\tconst texture = this.getOrCreateTexture(key, { width, height, format });\n\n\t\tlet uploadBytes: Uint8Array;\n\t\tif (maskData instanceof Float32Array) {\n\t\t\tuploadBytes = new Uint8Array(maskData.length);\n\t\t\tfor (let i = 0; i < maskData.length; i++) {\n\t\t\t\tuploadBytes[i] = Math.round(\n\t\t\t\t\tMath.max(0, Math.min(1, maskData[i])) * 255,\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\tuploadBytes = maskData;\n\t\t}\n\n\t\tconst bytesPerPixel = isRgba ? 4 : 1;\n\t\tconst bytesPerRow = width * bytesPerPixel;\n\t\tconst alignedBytesPerRow = Math.ceil(bytesPerRow / 256) * 256;\n\n\t\tlet finalBuffer: Uint8Array;\n\t\tif (alignedBytesPerRow === bytesPerRow) {\n\t\t\tfinalBuffer = uploadBytes;\n\t\t} else {\n\t\t\tfinalBuffer = new Uint8Array(alignedBytesPerRow * height);\n\t\t\tfor (let y = 0; y < height; y++) {\n\t\t\t\tfinalBuffer.set(\n\t\t\t\t\tuploadBytes.subarray(y * bytesPerRow, (y + 1) * bytesPerRow),\n\t\t\t\t\ty * alignedBytesPerRow,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tthis.device.queue.writeTexture(\n\t\t\t{ texture },\n\t\t\tfinalBuffer.buffer,\n\t\t\t{\n\t\t\t\toffset: finalBuffer.byteOffset,\n\t\t\t\tbytesPerRow: alignedBytesPerRow,\n\t\t\t\trowsPerImage: height,\n\t\t\t},\n\t\t\t{ width, height },\n\t\t);\n\n\t\treturn texture;\n\t}\n\n\tpublic destroy(): void {\n\t\tfor (const tex of this.pool.values()) {\n\t\t\ttex.destroy();\n\t\t}\n\t\tthis.pool.clear();\n\t}\n}\n","import { createHash } from \"node:crypto\";\nimport { existsSync, mkdirSync, statSync } from \"node:fs\";\nimport { readFile, rename, unlink, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\nimport {\n\tVISION_MODELS,\n\ttype VisionModelDescriptor,\n\ttype VisionModelKey,\n} from \"./registry.js\";\n\nexport type ModelDownloadStatus = \"pending\" | \"downloading\" | \"ready\" | \"error\";\n\nexport interface VisionModelStoreOptions {\n\treadonly modelsDir?: string;\n\t/**\n\t * Mirror origin: models are fetched from `<baseUrl>/<filename>` instead of their pinned\n\t * Hugging Face URLs. Defaults to `$FRAMEFIELDS_MODELS_BASE_URL` when set.\n\t */\n\treadonly baseUrl?: string;\n\treadonly timeoutMs?: number;\n\t/** Extra attempts after a network error, HTTP 429 or 5xx. Default 2. */\n\treadonly retries?: number;\n\t/** Base backoff between attempts (doubles each retry). Default 1000 ms. */\n\treadonly retryDelayMs?: number;\n\t/**\n\t * Verify byte size + SHA-256 against the registry (default true). Only offline tests\n\t * that serve fake bytes should turn this off.\n\t */\n\treadonly verify?: boolean;\n\t/** Injectable fetch — offline unit tests inject a mock. */\n\treadonly fetchImpl?: typeof fetch;\n\treadonly onProgress?: (\n\t\tkey: VisionModelKey,\n\t\tbytesLoaded: number,\n\t\ttotalBytes: number,\n\t) => void;\n}\n\n/**\n * Resolves the default model cache directory:\n * 1. `FRAMEFIELDS_MODELS_DIR`\n * 2. `~/.cache/framefields/models`\n */\nexport function getDefaultModelsDir(): string {\n\tif (process.env.FRAMEFIELDS_MODELS_DIR) {\n\t\treturn resolve(process.env.FRAMEFIELDS_MODELS_DIR);\n\t}\n\treturn resolve(homedir(), \".cache/framefields/models\");\n}\n\n/**\n * Lazy model store. The constructor performs ZERO I/O; the only entry that can hit the\n * network is `ensure(key)`, called by an inference function the first time it runs.\n * Concurrent callers of the same key share a single in-flight download (promise dedupe),\n * downloads are written atomically (temp + rename), and verified files on disk are reused\n * across processes.\n */\nexport class VisionModelStore {\n\tprivate readonly _modelsDir: string;\n\tprivate readonly _baseUrl?: string;\n\tprivate readonly _timeoutMs?: number;\n\tprivate readonly _retries: number;\n\tprivate readonly _retryDelayMs: number;\n\tprivate readonly _verify: boolean;\n\tprivate readonly _fetch: typeof fetch;\n\tprivate readonly _onProgress?: VisionModelStoreOptions[\"onProgress\"];\n\n\tprivate _inflight = new Map<VisionModelKey, Promise<Uint8Array>>();\n\tprivate _buffers = new Map<VisionModelKey, Uint8Array>();\n\tprivate _status = new Map<VisionModelKey, ModelDownloadStatus>();\n\n\tconstructor(options: VisionModelStoreOptions = {}) {\n\t\tthis._modelsDir = options.modelsDir\n\t\t\t? resolve(options.modelsDir)\n\t\t\t: getDefaultModelsDir();\n\t\tthis._baseUrl =\n\t\t\toptions.baseUrl ?? process.env.FRAMEFIELDS_MODELS_BASE_URL ?? undefined;\n\t\tthis._timeoutMs = options.timeoutMs;\n\t\tthis._retries = Math.max(0, options.retries ?? 2);\n\t\tthis._retryDelayMs = options.retryDelayMs ?? 1000;\n\t\tthis._verify = options.verify !== false;\n\t\tthis._fetch = options.fetchImpl ?? globalThis.fetch;\n\t\tthis._onProgress = options.onProgress;\n\t}\n\n\tpublic get modelsDir(): string {\n\t\treturn this._modelsDir;\n\t}\n\n\tpublic pathFor(key: VisionModelKey): string {\n\t\treturn join(this._modelsDir, VISION_MODELS[key].filename);\n\t}\n\n\tpublic descriptor(key: VisionModelKey): VisionModelDescriptor {\n\t\treturn VISION_MODELS[key];\n\t}\n\n\t/** The URL `ensure(key)` downloads from (mirror when `baseUrl` is set). */\n\tpublic urlFor(key: VisionModelKey): string {\n\t\tconst desc = VISION_MODELS[key];\n\t\tif (!this._baseUrl) return desc.url;\n\t\treturn `${this._baseUrl.replace(/\\/+$/, \"\")}/${desc.filename}`;\n\t}\n\n\t/** True when a complete cached file exists (exact registry size when verifying). */\n\tpublic has(key: VisionModelKey): boolean {\n\t\tconst targetPath = this.pathFor(key);\n\t\tif (!existsSync(targetPath)) {\n\t\t\treturn false;\n\t\t}\n\t\ttry {\n\t\t\tconst size = statSync(targetPath).size;\n\t\t\treturn this._verify ? size === VISION_MODELS[key].bytes : size > 0;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/** Drops a cached model (file + memory) so the next `ensure` re-downloads it. */\n\tpublic async evict(key: VisionModelKey): Promise<void> {\n\t\tthis._buffers.delete(key);\n\t\tthis._status.set(key, \"pending\");\n\t\tawait unlink(this.pathFor(key)).catch(() => undefined);\n\t}\n\n\tpublic status(key: VisionModelKey): ModelDownloadStatus {\n\t\treturn this._status.get(key) ?? \"pending\";\n\t}\n\n\t/** Snapshot of every tracked model's status (empty until anything is fetched). */\n\tpublic statuses(): ReadonlyMap<VisionModelKey, ModelDownloadStatus> {\n\t\treturn new Map(this._status);\n\t}\n\n\t/** True when the model is resident in memory (loaded or downloaded this process). */\n\tpublic isLoaded(key: VisionModelKey): boolean {\n\t\treturn this._buffers.has(key);\n\t}\n\n\t/**\n\t * THE only download entry point. Returns the model bytes from memory (cached),\n\t * loading from disk or fetching from the registry URL as needed.\n\t */\n\tpublic async ensure(key: VisionModelKey): Promise<Uint8Array> {\n\t\tconst inMemory = this._buffers.get(key);\n\t\tif (inMemory) {\n\t\t\treturn inMemory;\n\t\t}\n\t\tconst inflight = this._inflight.get(key);\n\t\tif (inflight) {\n\t\t\treturn inflight;\n\t\t}\n\t\tconst promise = this.load(key).finally(() => this._inflight.delete(key));\n\t\tthis._inflight.set(key, promise);\n\t\treturn promise;\n\t}\n\n\t/** Explicit warm-up — fetch multiple models ahead of use (agents, renderers). */\n\tpublic async preload(keys: readonly VisionModelKey[]): Promise<void> {\n\t\tawait Promise.all([...new Set(keys)].map((key) => this.ensure(key)));\n\t}\n\n\tprivate async load(key: VisionModelKey): Promise<Uint8Array> {\n\t\tconst targetPath = this.pathFor(key);\n\n\t\tif (this.has(key)) {\n\t\t\tthis._status.set(key, \"ready\");\n\t\t\treturn this.readBuffer(key, targetPath);\n\t\t}\n\n\t\tconst downloadUrl = this.urlFor(key);\n\t\tthis._status.set(key, \"downloading\");\n\n\t\tif (!existsSync(dirname(targetPath))) {\n\t\t\tmkdirSync(dirname(targetPath), { recursive: true });\n\t\t}\n\n\t\tconst tempPath = `${targetPath}.tmp.${Date.now()}`;\n\t\ttry {\n\t\t\tconst { buffer, totalBytes } = await this.download(key, downloadUrl);\n\n\t\t\tif (buffer.byteLength === 0) {\n\t\t\t\tthrow new Error(`Downloaded vision model '${key}' is empty (0 bytes).`);\n\t\t\t}\n\t\t\tif (this._verify) {\n\t\t\t\tthis.verifyBytes(key, buffer, downloadUrl);\n\t\t\t}\n\n\t\t\tthis._onProgress?.(\n\t\t\t\tkey,\n\t\t\t\tbuffer.byteLength,\n\t\t\t\ttotalBytes || buffer.byteLength,\n\t\t\t);\n\n\t\t\t// Write-then-rename keeps the cache atomic: a crash never leaves a partial model\n\t\t\t// at the final path.\n\t\t\tawait writeFile(tempPath, buffer);\n\t\t\tawait rename(tempPath, targetPath);\n\n\t\t\tthis._buffers.set(key, buffer);\n\t\t\tthis._status.set(key, \"ready\");\n\t\t\treturn buffer;\n\t\t} catch (error) {\n\t\t\tthis._status.set(key, \"error\");\n\t\t\tif (existsSync(tempPath)) {\n\t\t\t\tawait unlink(tempPath).catch(() => undefined);\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/** Fetches with retries on transient failures (network errors, HTTP 429/5xx). */\n\tprivate async download(\n\t\tkey: VisionModelKey,\n\t\turl: string,\n\t): Promise<{ buffer: Uint8Array; totalBytes: number }> {\n\t\tfor (let attempt = 0; ; attempt++) {\n\t\t\tlet transient: unknown;\n\t\t\ttry {\n\t\t\t\tconst response = await this._fetch(url, {\n\t\t\t\t\tsignal: this._timeoutMs\n\t\t\t\t\t\t? AbortSignal.timeout(this._timeoutMs)\n\t\t\t\t\t\t: undefined,\n\t\t\t\t});\n\t\t\t\tif (response.ok) {\n\t\t\t\t\tconst totalBytes = Number(\n\t\t\t\t\t\tresponse.headers.get(\"content-length\") ?? 0,\n\t\t\t\t\t);\n\t\t\t\t\treturn {\n\t\t\t\t\t\tbuffer: new Uint8Array(await response.arrayBuffer()),\n\t\t\t\t\t\ttotalBytes,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tconst error = new Error(\n\t\t\t\t\t`Failed to download vision model '${key}' from ${url}: HTTP ${response.status} ${response.statusText}`,\n\t\t\t\t);\n\t\t\t\tif (response.status !== 429 && response.status < 500) throw error;\n\t\t\t\ttransient = error;\n\t\t\t} catch (error) {\n\t\t\t\t// fetch() rejects with a TypeError on network failures (reset, DNS, TLS).\n\t\t\t\tif (!(error instanceof TypeError)) throw error;\n\t\t\t\ttransient = error;\n\t\t\t}\n\t\t\tif (attempt >= this._retries) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Failed to download vision model '${key}' from ${url} after ${attempt + 1} attempts: ${String(transient)}`,\n\t\t\t\t\t{ cause: transient },\n\t\t\t\t);\n\t\t\t}\n\t\t\tawait new Promise((r) => setTimeout(r, this._retryDelayMs * 2 ** attempt));\n\t\t}\n\t}\n\n\tprivate verifyBytes(\n\t\tkey: VisionModelKey,\n\t\tbuffer: Uint8Array,\n\t\turl: string,\n\t): void {\n\t\tconst desc = VISION_MODELS[key];\n\t\tif (buffer.byteLength !== desc.bytes) {\n\t\t\tthrow new Error(\n\t\t\t\t`Vision model '${key}' from ${url} is ${buffer.byteLength} bytes, expected ${desc.bytes}.`,\n\t\t\t);\n\t\t}\n\t\tconst digest = createHash(\"sha256\").update(buffer).digest(\"hex\");\n\t\tif (digest !== desc.sha256) {\n\t\t\tthrow new Error(\n\t\t\t\t`Vision model '${key}' from ${url} failed its SHA-256 check (got ${digest}, expected ${desc.sha256}).`,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate async readBuffer(\n\t\tkey: VisionModelKey,\n\t\ttargetPath: string,\n\t): Promise<Uint8Array> {\n\t\tconst fileBuffer = await readFile(targetPath);\n\t\tconst buffer = new Uint8Array(\n\t\t\tfileBuffer.buffer,\n\t\t\tfileBuffer.byteOffset,\n\t\t\tfileBuffer.byteLength,\n\t\t);\n\t\tthis._buffers.set(key, buffer);\n\t\treturn buffer;\n\t}\n\n\t/** Drops in-memory buffers (model stays on disk for the next run). */\n\tpublic clearMemoryCache(): void {\n\t\tthis._buffers.clear();\n\t}\n}\n","import type {\n\tDetectedObject,\n\tLandmark3D,\n\tTrackedObject,\n} from \"@framefields/core\";\nimport type { PoseResult } from \"../types.js\";\n\n/** Neutral fallbacks so signal evaluators always have a well-formed frame to read. */\n\nexport function createNeutralObjectResult(): {\n\treadonly objects: readonly TrackedObject[];\n\treadonly rawDetections: readonly DetectedObject[];\n} {\n\treturn { objects: [], rawDetections: [] };\n}\n\nexport function createNeutralPoseResult(): PoseResult {\n\treturn { people: [] };\n}\n\n/** 17 neutral COCO keypoints at frame center — used by pose signals when nobody is detected. */\nexport function createNeutralLandmarks(): readonly Landmark3D[] {\n\tconst landmarks: Landmark3D[] = [];\n\tfor (let i = 0; i < 17; i++) {\n\t\tlandmarks.push({ x: 0.5, y: 0.5, z: 0, visibility: 0 });\n\t}\n\treturn landmarks;\n}\n","/**\n * Minimal ONNX Runtime surface — isolates the ORT API to exactly two files so the decode\n * and signals layers never touch it. Node path uses onnxruntime-node (CPU EP); the web\n * entry can swap in a WebGPU-backed provider with the same interface.\n */\n\n/** Model output tensor. Integer outputs (e.g. RTMDet-Ins `labels`) arrive as BigInt64Array. */\nexport interface VisionTensor {\n\treadonly data: Float32Array | BigInt64Array | Int32Array;\n\treadonly dims: readonly number[];\n}\n\nexport interface VisionTensorInput {\n\treadonly name: string;\n\treadonly data: Float32Array;\n\treadonly dims: readonly number[];\n}\n\nexport type VisionTensorOutputs = Readonly<Record<string, VisionTensor>>;\n\nexport interface VisionSession {\n\trun(input: VisionTensorInput): Promise<VisionTensorOutputs>;\n\trelease(): void;\n}\n\nexport interface SessionProvider {\n\treadonly kind: \"node\" | \"webgpu\";\n\tcreateSession(modelBytes: Uint8Array): Promise<VisionSession>;\n}\n\nlet defaultProvider: (() => SessionProvider) | undefined;\n\n/**\n * Sets the provider runners use when none is passed, for hosts that create\n * runners indirectly (e.g. a browser player rendering vision nodes). `undefined`\n * restores the default, onnxruntime-node.\n */\nexport function setDefaultSessionProvider(\n\tfactory: (() => SessionProvider) | undefined,\n): void {\n\tdefaultProvider = factory;\n}\n\n/** The provider for a runner created without one. */\nexport function createDefaultSessionProvider(): SessionProvider {\n\treturn defaultProvider?.() ?? new NodeSessionProvider();\n}\n\n/** onnxruntime-node provider. The native module is imported lazily on first session. */\nexport class NodeSessionProvider implements SessionProvider {\n\tpublic readonly kind = \"node\" as const;\n\n\tprivate ortPromise?: Promise<typeof import(\"onnxruntime-node\")>;\n\n\tprivate async ort(): Promise<typeof import(\"onnxruntime-node\")> {\n\t\tif (!this.ortPromise) {\n\t\t\tthis.ortPromise = import(\"onnxruntime-node\").catch((err: unknown) => {\n\t\t\t\tthis.ortPromise = undefined;\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`onnxruntime-node failed to load (${String(err)}). ` +\n\t\t\t\t\t\t\"Install it in the environment or provide a custom SessionProvider.\",\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\t\treturn this.ortPromise;\n\t}\n\n\tpublic async createSession(modelBytes: Uint8Array): Promise<VisionSession> {\n\t\tconst ort = await this.ort();\n\t\tconst session = await ort.InferenceSession.create(modelBytes, {\n\t\t\texecutionProviders: [\"cpu\"],\n\t\t\tgraphOptimizationLevel: \"all\",\n\t\t});\n\t\ttype OrtTensor = InstanceType<typeof ort.Tensor>;\n\n\t\treturn {\n\t\t\trun: async (input: VisionTensorInput): Promise<VisionTensorOutputs> => {\n\t\t\t\tconst inputName = session.inputNames.includes(input.name)\n\t\t\t\t\t? input.name\n\t\t\t\t\t: (session.inputNames[0] ?? input.name);\n\t\t\t\tconst feeds: Record<string, OrtTensor> = {\n\t\t\t\t\t[inputName]: new ort.Tensor(\"float32\", input.data, [...input.dims]),\n\t\t\t\t};\n\t\t\t\tconst results = await session.run(feeds);\n\t\t\t\tconst outputs: Record<string, VisionTensor> = {};\n\t\t\t\tfor (const [name, tensor] of Object.entries(results)) {\n\t\t\t\t\toutputs[name] = {\n\t\t\t\t\t\tdata: tensor.data as VisionTensor[\"data\"],\n\t\t\t\t\t\tdims: [...tensor.dims],\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn outputs;\n\t\t\t},\n\t\t\trelease: () => {\n\t\t\t\tvoid session.release();\n\t\t\t},\n\t\t};\n\t}\n}\n","import type { DetectedObject } from \"@framefields/core\";\nimport {\n\ttype InputTransform,\n\timageToTensor,\n\tpreprocessSpec,\n} from \"../decode/preprocess.js\";\nimport { decodeRtmdetIns } from \"../decode/rtmdet-ins.js\";\nimport { decodeRtmo } from \"../decode/rtmo.js\";\nimport { decodeSelfie } from \"../decode/selfie.js\";\nimport {\n\ttype ModelDownloadStatus,\n\tVisionModelStore,\n} from \"../model/model-store.js\";\nimport {\n\tCOCO_CLASSES,\n\tmodelKeyFor,\n\tVISION_MODELS,\n\ttype VisionModelKey,\n\ttype VisionTask,\n\ttype VisionVariant,\n} from \"../model/registry.js\";\nimport {\n\tcreateDefaultSessionProvider,\n\ttype SessionProvider,\n\ttype VisionSession,\n\ttype VisionTensor,\n\ttype VisionTensorOutputs,\n} from \"../runtime/session-provider.js\";\nimport type {\n\tPersonMatte,\n\tPoseResult,\n\tSegmentationResult,\n\tVisionImageInput,\n} from \"../types.js\";\n\nexport interface VisionRunnerOptions {\n\t/** Model size for detect/segment/pose. Default \"s\". */\n\treadonly variant?: VisionVariant;\n\t/** Minimum detection / person score, 0..1. Default 0.3. */\n\treadonly confidence?: number;\n\t/** COCO class-name filter for detect/segment (all classes when omitted). */\n\treadonly classes?: readonly string[];\n\treadonly maskThreshold?: number;\n\treadonly featherRadius?: number;\n\treadonly modelsDir?: string;\n\t/** Mirror origin for model downloads (see VisionModelStore). */\n\treadonly baseUrl?: string;\n\treadonly timeoutMs?: number;\n\t/** Session backend. Default: onnxruntime-node (CPU). Browser: `createWebGPUProvider()`. */\n\treadonly provider?: SessionProvider;\n\t/** Inject a model store (tests, shared caches). Overrides modelsDir/baseUrl/timeoutMs. */\n\treadonly store?: VisionModelStore;\n\treadonly onProgress?: (\n\t\tkey: VisionModelKey,\n\t\tbytesLoaded: number,\n\t\ttotalBytes: number,\n\t) => void;\n}\n\n/**\n * Lazy vision runner.\n *\n * `create()` performs ZERO I/O: no downloads, no sessions. Each inference method downloads\n * its model and warms its session on FIRST USE ONLY, then reuses them for the process\n * lifetime. `detect()` and `segment()` share one RTMDet-Ins forward pass per frame.\n * Call `close()` to release sessions.\n */\nexport class VisionRunner {\n\tpublic readonly variant: VisionVariant;\n\tpublic readonly confidence: number;\n\tpublic readonly classes?: readonly string[];\n\tpublic readonly maskThreshold: number;\n\tpublic readonly featherRadius?: number;\n\n\tprivate readonly _store: VisionModelStore;\n\tprivate readonly _provider: SessionProvider;\n\tprivate readonly _sessions = new Map<\n\t\tVisionModelKey,\n\t\tPromise<VisionSession>\n\t>();\n\tprivate readonly _tensorScratch = new Map<VisionModelKey, Float32Array>();\n\t/** One RTMDet-Ins pass per frame buffer, shared by detect() and segment(). */\n\tprivate _instancePass?: {\n\t\treadonly frame: VisionImageInput[\"data\"];\n\t\treadonly result: Promise<InstancePass>;\n\t};\n\n\tprivate constructor(options: VisionRunnerOptions) {\n\t\tthis.variant = options.variant ?? \"s\";\n\t\tthis.confidence = options.confidence ?? 0.3;\n\t\tthis.classes = options.classes;\n\t\tthis.maskThreshold = options.maskThreshold ?? 0.5;\n\t\tthis.featherRadius = options.featherRadius;\n\t\tthis._store =\n\t\t\toptions.store ??\n\t\t\tnew VisionModelStore({\n\t\t\t\tmodelsDir: options.modelsDir,\n\t\t\t\tbaseUrl: options.baseUrl,\n\t\t\t\ttimeoutMs: options.timeoutMs,\n\t\t\t\tonProgress: options.onProgress,\n\t\t\t});\n\t\tthis._provider = options.provider ?? createDefaultSessionProvider();\n\t}\n\n\t/** Cheap: no downloads, no sessions, no side effects. */\n\tpublic static create(options: VisionRunnerOptions = {}): VisionRunner {\n\t\treturn new VisionRunner(options);\n\t}\n\n\tpublic get modelsDir(): string {\n\t\treturn this._store.modelsDir;\n\t}\n\n\t/** Every registry model keyed to its current download state (downloaded → \"ready\"). */\n\tpublic get downloadStatus(): ReadonlyMap<\n\t\tVisionModelKey,\n\t\tModelDownloadStatus\n\t> {\n\t\tconst statuses = new Map<VisionModelKey, ModelDownloadStatus>();\n\t\tfor (const key of Object.keys(VISION_MODELS) as VisionModelKey[]) {\n\t\t\tstatuses.set(key, \"pending\");\n\t\t}\n\t\tfor (const [key, status] of this._store.statuses()) {\n\t\t\tstatuses.set(key, status);\n\t\t}\n\t\treturn statuses;\n\t}\n\n\t/** The model serving `task` (matte depends on frame aspect; defaults to square). */\n\tpublic modelKeyFor(task: VisionTask, aspect = 1): VisionModelKey {\n\t\treturn modelKeyFor(task, this.variant, aspect);\n\t}\n\n\t/**\n\t * Explicit warm-up: downloads + sessions for the given tasks, ahead of first use.\n\t * `matte` warms both aspect variants (the frame aspect is unknown until inference).\n\t */\n\tpublic async preload(\n\t\ttasks: readonly VisionTask[] = [\"detect\"],\n\t): Promise<void> {\n\t\tconst keys = new Set<VisionModelKey>();\n\t\tfor (const task of tasks) {\n\t\t\tif (task === \"matte\") {\n\t\t\t\tkeys.add(\"selfie-square\");\n\t\t\t\tkeys.add(\"selfie-landscape\");\n\t\t\t} else {\n\t\t\t\tkeys.add(this.modelKeyFor(task));\n\t\t\t}\n\t\t}\n\t\tawait this._store.preload([...keys]);\n\t\tawait Promise.all([...keys].map((key) => this.session(key)));\n\t}\n\n\t/** COCO-80 boxes (sorted by score, source pixels). Masks are not decoded. */\n\tpublic async detect(\n\t\timage: VisionImageInput,\n\t): Promise<readonly DetectedObject[]> {\n\t\tconst pass = await this.instancePass(image);\n\t\treturn decodeRtmdetIns(\n\t\t\t{ ...pass.outputs, masks: undefined },\n\t\t\tthis.instanceDecodeOptions(image, pass.transform),\n\t\t).detections;\n\t}\n\n\t/** COCO-80 boxes plus a frame-aligned soft mask per instance. */\n\tpublic async segment(image: VisionImageInput): Promise<SegmentationResult> {\n\t\tconst pass = await this.instancePass(image);\n\t\treturn decodeRtmdetIns(\n\t\t\tpass.outputs,\n\t\t\tthis.instanceDecodeOptions(image, pass.transform),\n\t\t);\n\t}\n\n\t/** COCO-17 keypoints per person (source pixels), highest score first. */\n\tpublic async pose(image: VisionImageInput): Promise<PoseResult> {\n\t\tconst key = this.modelKeyFor(\"pose\");\n\t\tconst { outputs, transform } = await this.infer(key, image);\n\t\tconst dets = output(outputs, \"dets\", key);\n\t\tconst keypoints = output(outputs, \"keypoints\", key);\n\t\treturn decodeRtmo(\n\t\t\t{\n\t\t\t\tdets: dets.data as Float32Array,\n\t\t\t\tkeypoints: keypoints.data as Float32Array,\n\t\t\t\tcount: dets.dims[1] ?? 0,\n\t\t\t\tkeypointStride: keypoints.dims[3] ?? 3,\n\t\t\t},\n\t\t\t{\n\t\t\t\tconfidence: this.confidence,\n\t\t\t\ttransform,\n\t\t\t\tsourceWidth: image.width,\n\t\t\t\tsourceHeight: image.height,\n\t\t\t},\n\t\t);\n\t}\n\n\t/** Person-vs-background alpha for the whole frame (Selfie Segmenter). */\n\tpublic async matte(image: VisionImageInput): Promise<PersonMatte> {\n\t\tconst key = this.modelKeyFor(\"matte\", image.width / image.height);\n\t\tconst [w, h] = VISION_MODELS[key].input;\n\t\tconst { outputs } = await this.infer(key, image);\n\t\tconst alphas = output(outputs, \"alphas\", key);\n\t\treturn decodeSelfie(alphas.data as Float32Array, w, h, {\n\t\t\tsourceWidth: image.width,\n\t\t\tsourceHeight: image.height,\n\t\t\tmaskThreshold: this.maskThreshold,\n\t\t\t...(this.featherRadius !== undefined\n\t\t\t\t? { featherRadius: this.featherRadius }\n\t\t\t\t: {}),\n\t\t});\n\t}\n\n\tpublic close(): void {\n\t\tfor (const promise of this._sessions.values()) {\n\t\t\tvoid promise.then((session) => session.release()).catch(() => undefined);\n\t\t}\n\t\tthis._sessions.clear();\n\t\tthis._instancePass = undefined;\n\t\tthis._store.clearMemoryCache();\n\t}\n\n\t// ── internals ──────────────────────────────────────────────────────────\n\n\tprivate instancePass(image: VisionImageInput): Promise<InstancePass> {\n\t\tif (this._instancePass?.frame === image.data) {\n\t\t\treturn this._instancePass.result;\n\t\t}\n\t\tconst key = this.modelKeyFor(\"segment\");\n\t\tconst result = this.infer(key, image).then(\n\t\t\t({ outputs, transform }) => {\n\t\t\t\tconst dets = output(outputs, \"dets\", key);\n\t\t\t\tconst masks = output(outputs, \"masks\", key);\n\t\t\t\treturn {\n\t\t\t\t\ttransform,\n\t\t\t\t\toutputs: {\n\t\t\t\t\t\tdets: dets.data as Float32Array,\n\t\t\t\t\t\tlabels: output(outputs, \"labels\", key).data,\n\t\t\t\t\t\tmasks: masks.data as Float32Array,\n\t\t\t\t\t\tcount: dets.dims[1] ?? 0,\n\t\t\t\t\t\tmaskHeight: masks.dims[masks.dims.length - 2] ?? 0,\n\t\t\t\t\t\tmaskWidth: masks.dims[masks.dims.length - 1] ?? 0,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t},\n\t\t);\n\t\tthis._instancePass = { frame: image.data, result };\n\t\tresult.catch(() => {\n\t\t\tif (this._instancePass?.result === result) this._instancePass = undefined;\n\t\t});\n\t\treturn result;\n\t}\n\n\tprivate instanceDecodeOptions(\n\t\timage: VisionImageInput,\n\t\ttransform: InputTransform,\n\t) {\n\t\treturn {\n\t\t\tconfidence: this.confidence,\n\t\t\tclasses: this.classes,\n\t\t\tclassNames: COCO_CLASSES,\n\t\t\ttransform,\n\t\t\tsourceWidth: image.width,\n\t\t\tsourceHeight: image.height,\n\t\t\tmaskThreshold: this.maskThreshold,\n\t\t\t...(this.featherRadius !== undefined\n\t\t\t\t? { featherRadius: this.featherRadius }\n\t\t\t\t: {}),\n\t\t};\n\t}\n\n\tprivate async infer(\n\t\tkey: VisionModelKey,\n\t\timage: VisionImageInput,\n\t): Promise<{ outputs: VisionTensorOutputs; transform: InputTransform }> {\n\t\tconst session = await this.session(key);\n\t\tconst desc = VISION_MODELS[key];\n\t\tconst spec = preprocessSpec(desc.family, desc.input);\n\t\tconst size = 3 * spec.width * spec.height;\n\t\tlet scratch = this._tensorScratch.get(key);\n\t\tif (!scratch || scratch.length < size) {\n\t\t\tscratch = new Float32Array(size);\n\t\t\tthis._tensorScratch.set(key, scratch);\n\t\t}\n\t\tconst { tensor, transform } = imageToTensor(image, spec, scratch);\n\t\tconst outputs = await session.run({\n\t\t\tname: \"input\",\n\t\t\tdata: tensor,\n\t\t\tdims: [1, 3, spec.height, spec.width],\n\t\t});\n\t\treturn { outputs, transform };\n\t}\n\n\tprivate session(key: VisionModelKey): Promise<VisionSession> {\n\t\tlet promise = this._sessions.get(key);\n\t\tif (!promise) {\n\t\t\tpromise = this._store\n\t\t\t\t.ensure(key)\n\t\t\t\t.then((bytes) => this._provider.createSession(bytes))\n\t\t\t\t.catch((err: unknown) => {\n\t\t\t\t\t// Drop both the session cache entry AND the cached file: a parse\n\t\t\t\t\t// failure means the on-disk bytes are corrupt — the next call must\n\t\t\t\t\t// re-download instead of replaying the same bad file.\n\t\t\t\t\tthis._sessions.delete(key);\n\t\t\t\t\tvoid this._store.evict(key);\n\t\t\t\t\tthrow err;\n\t\t\t\t});\n\t\t\tthis._sessions.set(key, promise);\n\t\t}\n\t\treturn promise;\n\t}\n}\n\ninterface InstancePass {\n\treadonly transform: InputTransform;\n\treadonly outputs: {\n\t\treadonly dets: Float32Array;\n\t\treadonly labels: VisionTensor[\"data\"];\n\t\treadonly masks: Float32Array;\n\t\treadonly count: number;\n\t\treadonly maskWidth: number;\n\t\treadonly maskHeight: number;\n\t};\n}\n\nfunction output(\n\toutputs: VisionTensorOutputs,\n\tname: string,\n\tkey: VisionModelKey,\n): VisionTensor {\n\tconst tensor = outputs[name];\n\tif (!tensor) {\n\t\tthrow new Error(\n\t\t\t`Vision model '${key}' returned no '${name}' output (got: ${Object.keys(outputs).join(\", \") || \"none\"}). ` +\n\t\t\t\t`Expected the ${VISION_MODELS[key].source}.`,\n\t\t);\n\t}\n\treturn tensor;\n}\n","import type { InstanceMask } from \"../types.js\";\n\n/**\n * The frame's primary instance: the largest person when present, else the most confident\n * instance (lowest `detectionIndex` — detections are score-sorted). Size alone is a poor\n * signal without a person: the largest instance is usually a backdrop (\"dining table\").\n */\nexport function selectSubjectMask(\n\tmasks: readonly InstanceMask[],\n): InstanceMask | undefined {\n\tlet best: InstanceMask | undefined;\n\tfor (const m of masks) {\n\t\tif (!best) {\n\t\t\tbest = m;\n\t\t\tcontinue;\n\t\t}\n\t\tconst mIsPerson = isPerson(m);\n\t\tconst bestIsPerson = isPerson(best);\n\t\tif (mIsPerson !== bestIsPerson) {\n\t\t\tif (mIsPerson) best = m;\n\t\t} else if (\n\t\t\tmIsPerson ? m.area > best.area : m.detectionIndex < best.detectionIndex\n\t\t) {\n\t\t\tbest = m;\n\t\t}\n\t}\n\treturn best;\n}\n\nfunction isPerson(mask: InstanceMask): boolean {\n\treturn mask.category.toLowerCase() === \"person\";\n}\n\nexport interface MaskBounds {\n\treadonly x0: number;\n\treadonly y0: number;\n\treadonly x1: number;\n\treadonly y1: number;\n}\n\n/** Tight pixel bounds of a mask's non-zero alpha, or null when empty. */\nexport function maskBounds(mask: InstanceMask): MaskBounds | null {\n\tconst { mask: data, width, height } = mask;\n\tlet x0 = width;\n\tlet y0 = height;\n\tlet x1 = -1;\n\tlet y1 = -1;\n\tfor (let y = 0; y < height; y++) {\n\t\tconst row = y * width;\n\t\tfor (let x = 0; x < width; x++) {\n\t\t\tif (data[row + x] === 0) continue;\n\t\t\tif (x < x0) x0 = x;\n\t\t\tif (x > x1) x1 = x;\n\t\t\tif (y < y0) y0 = y;\n\t\t\tif (y > y1) y1 = y;\n\t\t}\n\t}\n\treturn x1 < 0 ? null : { x0, y0, x1, y1 };\n}\n\n/**\n * Builds the full subject silhouette: the primary instance plus every comparably sized\n * instance whose bounds sit mostly inside or across it (`overlap` = intersection / smaller\n * box area; `maxGrowth` caps a part's box area relative to the subject's).\n *\n * COCO has no \"clothing\" class, so a flowing dress, a held guitar or a ridden bike comes back\n * as its own instance (often mislabeled) — merging them keeps the whole figure in the cutout.\n * The size cap keeps containers out: a small figure inside a tunnel or window detected as a\n * huge \"clock\" must not drag the whole frame into the subject.\n */\nexport function mergeSubjectMask(\n\tmasks: readonly InstanceMask[],\n\toverlap = 0.5,\n\tmaxGrowth = 2,\n): InstanceMask | undefined {\n\tconst subject = selectSubjectMask(masks);\n\tif (!subject) return undefined;\n\tconst sb = maskBounds(subject);\n\tif (!sb) return subject;\n\n\tconst subjectArea = boundsArea(sb);\n\tconst parts = masks.filter((m) => {\n\t\tif (m === subject) return false;\n\t\tconst b = maskBounds(m);\n\t\treturn (\n\t\t\tb !== null &&\n\t\t\tboundsArea(b) <= subjectArea * maxGrowth &&\n\t\t\tboundsOverlap(sb, b) >= overlap\n\t\t);\n\t});\n\tif (parts.length === 0) return subject;\n\n\tconst merged = subject.mask.slice();\n\tfor (const part of parts) {\n\t\tconst data = part.mask;\n\t\tfor (let i = 0; i < merged.length; i++) {\n\t\t\tif (data[i] > merged[i]) merged[i] = data[i];\n\t\t}\n\t}\n\tlet area = 0;\n\tfor (let i = 0; i < merged.length; i++) area += merged[i];\n\tarea = Math.round(area / 255);\n\treturn {\n\t\t...subject,\n\t\tmask: merged,\n\t\tarea,\n\t\tcoverage: area / (subject.width * subject.height),\n\t};\n}\n\nfunction boundsArea(b: MaskBounds): number {\n\treturn (b.x1 - b.x0 + 1) * (b.y1 - b.y0 + 1);\n}\n\nfunction boundsOverlap(a: MaskBounds, b: MaskBounds): number {\n\tconst iw = Math.min(a.x1, b.x1) - Math.max(a.x0, b.x0) + 1;\n\tconst ih = Math.min(a.y1, b.y1) - Math.max(a.y0, b.y0) + 1;\n\tif (iw <= 0 || ih <= 0) return 0;\n\treturn (iw * ih) / Math.min(boundsArea(a), boundsArea(b));\n}\n","import type { Landmark3D } from \"@framefields/core\";\n\nexport interface Camera3DSpec {\n\treadonly width: number;\n\treadonly height: number;\n\treadonly fov?: number; // In degrees, default 60\n\treadonly cameraDistance?: number;\n}\n\nexport interface ProjectedScreenCoordinate {\n\treadonly x: number; // In canvas pixels [0, width]\n\treadonly y: number; // In canvas pixels [0, height]\n\treadonly z: number; // Depth in canvas units\n\treadonly scale: number; // Perspective foreshortening scale\n}\n\nexport class SpatialLandmarkTransformer {\n\tprivate width: number;\n\tprivate height: number;\n\tprivate fovRad: number;\n\tprivate focalDistance: number;\n\n\tconstructor(camera: Camera3DSpec) {\n\t\tthis.width = camera.width;\n\t\tthis.height = camera.height;\n\t\tconst fovDeg = camera.fov ?? 60;\n\t\tthis.fovRad = (fovDeg * Math.PI) / 180;\n\t\tthis.focalDistance =\n\t\t\tcamera.cameraDistance ?? this.height / 2 / Math.tan(this.fovRad / 2);\n\t}\n\n\t/**\n\t * Projects a normalized landmark [0, 1] into 2D/3D canvas coordinates.\n\t */\n\tpublic projectNormalizedLandmark(\n\t\tlandmark: Landmark3D,\n\t\toffsetZ = 0,\n\t): ProjectedScreenCoordinate {\n\t\tconst screenX = landmark.x * this.width;\n\t\tconst screenY = landmark.y * this.height;\n\t\t// Normalized landmark z is roughly scaled relative to width\n\t\tconst rawZ = landmark.z * this.width + offsetZ;\n\n\t\t// Perspective foreshortening: S = d / (d - z)\n\t\tconst effectiveZ = Math.min(rawZ, this.focalDistance - 10);\n\t\tconst scale = this.focalDistance / (this.focalDistance - effectiveZ);\n\n\t\treturn {\n\t\t\tx: screenX,\n\t\t\ty: screenY,\n\t\t\tz: rawZ,\n\t\t\tscale: Math.max(0.1, scale),\n\t\t};\n\t}\n\n\t/**\n\t * Projects a metric world landmark [X_w, Y_w, Z_w] in meters into canvas space.\n\t */\n\tpublic projectWorldLandmark(\n\t\tworldLandmark: Landmark3D,\n\t\tsubjectDistanceMeters = 2.0,\n\t\tscaleMetersToPixels = 800,\n\t): ProjectedScreenCoordinate {\n\t\t// Subject centered at canvas center (width/2, height/2)\n\t\tconst centerX = this.width / 2;\n\t\tconst centerY = this.height / 2;\n\n\t\tconst worldX = worldLandmark.x * scaleMetersToPixels;\n\t\tconst worldY = worldLandmark.y * scaleMetersToPixels;\n\t\tconst worldZ =\n\t\t\t(worldLandmark.z + subjectDistanceMeters) * scaleMetersToPixels;\n\n\t\tconst effectiveZ = Math.min(worldZ, this.focalDistance - 10);\n\t\tconst scale = this.focalDistance / (this.focalDistance - effectiveZ);\n\n\t\treturn {\n\t\t\tx: centerX + worldX * scale,\n\t\t\ty: centerY + worldY * scale,\n\t\t\tz: worldZ,\n\t\t\tscale: Math.max(0.1, scale),\n\t\t};\n\t}\n}\n","import type { TrackedObject } from \"@framefields/core\";\nimport type { PosePerson } from \"../types.js\";\nimport { computeIoU, type PixelBox } from \"./temporal-object-tracker.js\";\n\nexport function getPersonBoundingBox(person: PosePerson): PixelBox {\n\tif (\n\t\tperson.boundingBox &&\n\t\tperson.boundingBox.width > 0 &&\n\t\tperson.boundingBox.height > 0\n\t) {\n\t\treturn {\n\t\t\toriginX: person.boundingBox.originX,\n\t\t\toriginY: person.boundingBox.originY,\n\t\t\twidth: person.boundingBox.width,\n\t\t\theight: person.boundingBox.height,\n\t\t};\n\t}\n\n\tlet minX = Infinity;\n\tlet minY = Infinity;\n\tlet maxX = -Infinity;\n\tlet maxY = -Infinity;\n\tlet validCount = 0;\n\n\tfor (const kp of person.keypoints) {\n\t\tif (kp.visibility > 0.1) {\n\t\t\tvalidCount++;\n\t\t\tif (kp.x < minX) minX = kp.x;\n\t\t\tif (kp.y < minY) minY = kp.y;\n\t\t\tif (kp.x > maxX) maxX = kp.x;\n\t\t\tif (kp.y > maxY) maxY = kp.y;\n\t\t}\n\t}\n\n\tif (validCount === 0 || minX >= maxX || minY >= maxY) {\n\t\treturn {\n\t\t\toriginX: person.boundingBox?.originX ?? 0,\n\t\t\toriginY: person.boundingBox?.originY ?? 0,\n\t\t\twidth: person.boundingBox?.width ?? 0,\n\t\t\theight: person.boundingBox?.height ?? 0,\n\t\t};\n\t}\n\n\treturn {\n\t\toriginX: minX,\n\t\toriginY: minY,\n\t\twidth: maxX - minX,\n\t\theight: maxY - minY,\n\t};\n}\n\n/**\n * Matches detected pose people with active person tracks using greedy bipartite IoU.\n *\n * Annotates each person with the matched trackId.\n */\nexport function matchPoseToTracks(\n\tpeople: readonly PosePerson[],\n\ttrackedObjects: readonly TrackedObject[],\n\tminIoU = 0.15,\n): PosePerson[] {\n\tif (people.length === 0) return [];\n\n\tconst personTracks = trackedObjects.filter(\n\t\t(o) => o.category.toLowerCase() === \"person\" && o.active,\n\t);\n\n\tif (personTracks.length === 0) {\n\t\treturn [...people];\n\t}\n\n\t// Calculate candidate pairings by IoU\n\tconst candidateMatches: {\n\t\tpersonIdx: number;\n\t\ttrackId: number;\n\t\tiou: number;\n\t}[] = [];\n\n\tfor (let p = 0; p < people.length; p++) {\n\t\tconst person = people[p];\n\t\tif (person.trackId !== undefined) continue;\n\n\t\tconst pBox = getPersonBoundingBox(person);\n\t\tconst isNormalized = pBox.width <= 1.05 && pBox.height <= 1.05;\n\t\tfor (const trk of personTracks) {\n\t\t\tconst targetBox: PixelBox =\n\t\t\t\tisNormalized && trk.boundingBox.normalizedWidth > 0\n\t\t\t\t\t? {\n\t\t\t\t\t\t\toriginX: trk.boundingBox.normalizedX,\n\t\t\t\t\t\t\toriginY: trk.boundingBox.normalizedY,\n\t\t\t\t\t\t\twidth: trk.boundingBox.normalizedWidth,\n\t\t\t\t\t\t\theight: trk.boundingBox.normalizedHeight,\n\t\t\t\t\t\t}\n\t\t\t\t\t: trk.boundingBox;\n\t\t\tconst iou = computeIoU(pBox, targetBox);\n\t\t\tif (iou >= minIoU) {\n\t\t\t\tcandidateMatches.push({ personIdx: p, trackId: trk.trackId, iou });\n\t\t\t}\n\t\t}\n\t}\n\n\t// Sort by IoU descending\n\tcandidateMatches.sort((a, b) => b.iou - a.iou);\n\n\tconst assignedPeople = new Set<number>();\n\tconst assignedTracks = new Set<number>();\n\tconst personTrackMap = new Map<number, number>();\n\n\tfor (const match of candidateMatches) {\n\t\tif (\n\t\t\tassignedPeople.has(match.personIdx) ||\n\t\t\tassignedTracks.has(match.trackId)\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\t\tassignedPeople.add(match.personIdx);\n\t\tassignedTracks.add(match.trackId);\n\t\tpersonTrackMap.set(match.personIdx, match.trackId);\n\t}\n\n\t// Single person & single track fallback\n\tif (\n\t\tpeople.length === 1 &&\n\t\tpersonTracks.length === 1 &&\n\t\t!personTrackMap.has(0) &&\n\t\tpeople[0].trackId === undefined\n\t) {\n\t\tpersonTrackMap.set(0, personTracks[0].trackId);\n\t}\n\n\treturn people.map((person, idx) => {\n\t\tif (person.trackId !== undefined) return person;\n\t\tconst trackId = personTrackMap.get(idx);\n\t\treturn trackId !== undefined ? { ...person, trackId } : person;\n\t});\n}\n","/// <reference types=\"webgpu\" />\nimport {\n\tprogrammaticSignal as coreProgrammaticSignal,\n\ttype DetectedObject,\n\ttype FrameContext,\n\tframeSignal,\n\ttype Landmark3D,\n\ttype ProgrammaticSignal,\n\ttype TensorData,\n\ttype TrackedObject,\n} from \"@framefields/core\";\nimport { COCO_CLASSES } from \"../model/registry.js\";\nimport { COCO17_KEYPOINT_NAMES, COCO17_KEYPOINTS } from \"../pose/keypoints.js\";\nimport {\n\tcreateNeutralLandmarks,\n\tcreateNeutralObjectResult,\n\tcreateNeutralPoseResult,\n} from \"../runner/canonical-baselines.js\";\nimport { selectSubjectMask } from \"../segmentation/subject.js\";\nimport { SpatialLandmarkTransformer } from \"../spatial/camera-space-transformer.js\";\nimport { getPersonBoundingBox } from \"../tracking/pose-track-matcher.js\";\nimport { computeIoU } from \"../tracking/temporal-object-tracker.js\";\nimport type {\n\tInstanceMask,\n\tLandmarkCoordinateSignals,\n\tPersonMatte,\n\tPosePerson,\n\tPoseResult,\n\tVisionConfig,\n\tVisionSummary,\n} from \"../types.js\";\n\nexport interface VisionBundleOptions {\n\treadonly totalFrames?: number;\n\treadonly fps?: number;\n\treadonly width?: number;\n\treadonly height?: number;\n\treadonly cameraFov?: number;\n\treadonly config?: VisionConfig;\n}\n\n// ── Signal surface types ────────────────────────────────────────────────────\n\n/** Named pose landmarks (COCO-17) plus numeric proxy access to any of the 17 keypoints. */\nexport interface PoseLandmarkSignals {\n\treadonly shoulder: LandmarkCoordinateSignals;\n\treadonly leftShoulder: LandmarkCoordinateSignals;\n\treadonly rightShoulder: LandmarkCoordinateSignals;\n\treadonly leftElbow: LandmarkCoordinateSignals;\n\treadonly rightElbow: LandmarkCoordinateSignals;\n\treadonly leftWrist: LandmarkCoordinateSignals;\n\treadonly rightWrist: LandmarkCoordinateSignals;\n\treadonly leftHip: LandmarkCoordinateSignals;\n\treadonly rightHip: LandmarkCoordinateSignals;\n\treadonly leftKnee: LandmarkCoordinateSignals;\n\treadonly rightKnee: LandmarkCoordinateSignals;\n\treadonly leftAnkle: LandmarkCoordinateSignals;\n\treadonly rightAnkle: LandmarkCoordinateSignals;\n\treadonly nose: LandmarkCoordinateSignals;\n\treadonly leftEye: LandmarkCoordinateSignals;\n\treadonly rightEye: LandmarkCoordinateSignals;\n\treadonly leftEar: LandmarkCoordinateSignals;\n\treadonly rightEar: LandmarkCoordinateSignals;\n\tget(keypointIndex: number): LandmarkCoordinateSignals;\n}\n\nexport interface TrackPoseSignals extends PoseLandmarkSignals {\n\treadonly hasPose: ProgrammaticSignal;\n\treadonly wristSpeed: ProgrammaticSignal;\n\treadonly handRaised: ProgrammaticSignal;\n\treadonly bodyTiltAngle: ProgrammaticSignal;\n}\n\nexport interface ObjectBoundingBoxSignals {\n\treadonly x: ProgrammaticSignal;\n\treadonly y: ProgrammaticSignal;\n\treadonly width: ProgrammaticSignal;\n\treadonly height: ProgrammaticSignal;\n\treadonly screenX: ProgrammaticSignal;\n\treadonly screenY: ProgrammaticSignal;\n\treadonly screenWidth: ProgrammaticSignal;\n\treadonly screenHeight: ProgrammaticSignal;\n\treadonly aspectRatio: ProgrammaticSignal;\n\treadonly area: ProgrammaticSignal;\n}\n\nexport interface ObjectAnchorsSignals {\n\treadonly topLeft: LandmarkCoordinateSignals;\n\treadonly topCenter: LandmarkCoordinateSignals;\n\treadonly topRight: LandmarkCoordinateSignals;\n\treadonly centerLeft: LandmarkCoordinateSignals;\n\treadonly center: LandmarkCoordinateSignals;\n\treadonly centerRight: LandmarkCoordinateSignals;\n\treadonly bottomLeft: LandmarkCoordinateSignals;\n\treadonly bottomCenter: LandmarkCoordinateSignals;\n\treadonly bottomRight: LandmarkCoordinateSignals;\n}\n\nexport interface ObjectKinematicsSignals {\n\treadonly vx: ProgrammaticSignal;\n\treadonly vy: ProgrammaticSignal;\n\treadonly speed: ProgrammaticSignal;\n\treadonly acceleration: ProgrammaticSignal;\n\treadonly headingRad: ProgrammaticSignal;\n\treadonly headingDeg: ProgrammaticSignal;\n}\n\nexport interface ObjectTrackSignals {\n\treadonly trackId: number;\n\treadonly category: string;\n\treadonly bounds: ObjectBoundingBoxSignals;\n\treadonly anchors: ObjectAnchorsSignals;\n\treadonly kinematics: ObjectKinematicsSignals;\n\treadonly confidence: ProgrammaticSignal;\n\treadonly active: ProgrammaticSignal;\n\treadonly isCoasting: ProgrammaticSignal;\n\treadonly age: ProgrammaticSignal;\n\treadonly pose: TrackPoseSignals;\n\n\t// Anchor shortcuts (pinToObject compatibility)\n\treadonly center: LandmarkCoordinateSignals;\n\treadonly topCenter: LandmarkCoordinateSignals;\n\treadonly bottomCenter: LandmarkCoordinateSignals;\n\treadonly topLeft: LandmarkCoordinateSignals;\n\treadonly bottomLeft: LandmarkCoordinateSignals;\n\n\t// Extensible editing & isolating helpers (decorated by @framefields/framefields)\n\treadonly [key: string]: unknown;\n}\n\nexport interface MaskTrackSignals {\n\treadonly trackId: number;\n\treadonly category: string;\n\treadonly area: ProgrammaticSignal; // px\n\treadonly coverage: ProgrammaticSignal; // area / frame area\n\treadonly solidity: ProgrammaticSignal; // area / bbox area\n\treadonly bboxFill: ProgrammaticSignal; // bbox area / frame area\n\t/** Frame-sized {0,255} mask for the current frame (renderer-populated). */\n\tdata?: Uint8Array;\n\t/** GPU-resident silhouette texture (renderer-populated via SegmentationTexturePool). */\n\ttexture?: GPUTexture;\n}\n\nexport interface MaskCollectionSignals {\n\tget(trackId: number): MaskTrackSignals;\n\t/** Largest instance of the current frame (person preferred when present). */\n\treadonly subject: MaskTrackSignals;\n\treadonly count: ProgrammaticSignal;\n}\n\nexport interface SegmentationSignals {\n\treadonly humanSilhouette: MaskTrackSignals;\n\treadonly subject: MaskTrackSignals;\n\treadonly instanceMasks: MaskCollectionSignals;\n\t/** Person-vs-background alpha from the Selfie Segmenter (`enableMatte`). */\n\treadonly matte: PersonMatteSignals;\n\treadonly stencilTexture?: GPUTexture;\n}\n\nexport interface PersonMatteSignals {\n\t/** Mean person alpha over the frame, 0..1 (0 when no matte has run). */\n\treadonly coverage: ProgrammaticSignal;\n\t/** Frame-sized 0..255 alpha for the given frame, if a matte has run. */\n\tat(frame: number): PersonMatte | undefined;\n}\n\nexport interface ClassSignals {\n\treadonly count: ProgrammaticSignal;\n\treadonly maxConfidence: ProgrammaticSignal;\n\treadonly present: ProgrammaticSignal;\n\treadonly primary: ObjectTrackSignals;\n}\n\nexport interface ClassCollectionSignals {\n\t/** Cached per-class signals (stable identity). */\n\tget(name: string): ClassSignals;\n\t/** Sorted active category names for the current frame. */\n\treadonly names: readonly string[];\n\treadonly histogram: {\n\t\tget(ctx?: FrameContext): TensorData;\n\t\treadonly value: TensorData;\n\t};\n}\n\nexport interface ObjectCollectionSignals {\n\tget(trackId: number): ObjectTrackSignals;\n\tbyCategory(category: string, rank?: number): ObjectTrackSignals;\n\treadonly primary: ObjectTrackSignals;\n\treadonly count: ProgrammaticSignal;\n\thasCategory(category: string): ProgrammaticSignal;\n\tgetActiveTracks(frame: number): readonly TrackedObject[];\n\treadonly detectedCategories: readonly string[];\n}\n\n// ── The bundle ──────────────────────────────────────────────────────────────\n\nexport class VisionBundle {\n\tpublic readonly objects: ObjectCollectionSignals;\n\tpublic readonly poseLandmarks: PoseLandmarkSignals;\n\tpublic readonly masks: MaskCollectionSignals;\n\tpublic readonly segmentation: SegmentationSignals;\n\tpublic readonly classes: ClassCollectionSignals;\n\n\tpublic readonly poseLandmarksTensor: {\n\t\tget(ctx?: FrameContext): TensorData;\n\t\treadonly value: TensorData;\n\t};\n\tpublic readonly objectsTensor: {\n\t\tget(ctx?: FrameContext): TensorData;\n\t\treadonly value: TensorData;\n\t};\n\tpublic readonly masksTensor: {\n\t\tget(ctx?: FrameContext): TensorData;\n\t\treadonly value: TensorData;\n\t};\n\t/** Per-class detection histogram [nc] — top-level convenience mirror of `classes.histogram`. */\n\tpublic readonly histogramTensor: {\n\t\tget(ctx?: FrameContext): TensorData;\n\t\treadonly value: TensorData;\n\t};\n\n\tprivate _totalFrames: number;\n\tprivate _fps: number;\n\tprivate _width: number;\n\tprivate _height: number;\n\tprivate _transformer: SpatialLandmarkTransformer;\n\tprivate _stencilTexture?: GPUTexture;\n\n\tprivate _poseCache = new Map<number, PoseResult>();\n\tprivate _objectCache = new Map<\n\t\tnumber,\n\t\t{\n\t\t\tobjects: readonly TrackedObject[];\n\t\t\trawDetections: readonly DetectedObject[];\n\t\t}\n\t>();\n\tprivate _maskCache = new Map<number, readonly InstanceMask[]>();\n\tprivate _matteCache = new Map<number, PersonMatte>();\n\n\tprivate _poseLmCache = new Map<number, LandmarkCoordinateSignals>();\n\tprivate _trackCache = new Map<number, ObjectTrackSignals>();\n\tprivate _categoryCache = new Map<string, ObjectTrackSignals>();\n\tprivate _classCache = new Map<string, ClassSignals>();\n\tprivate _maskTrackCache = new Map<number, MaskTrackSignals>();\n\tprivate _registeredSignals = new Set<ProgrammaticSignal>();\n\n\tconstructor(options: VisionBundleOptions = {}) {\n\t\tthis._totalFrames = options.totalFrames ?? 120;\n\t\tthis._fps = options.fps ?? 24;\n\t\tthis._width = options.width ?? 1920;\n\t\tthis._height = options.height ?? 1080;\n\t\tthis._transformer = new SpatialLandmarkTransformer({\n\t\t\twidth: this._width,\n\t\t\theight: this._height,\n\t\t\tfov: options.cameraFov ?? 60,\n\t\t});\n\n\t\t// `self` avoids `this` contextual-typing issues inside object literals below.\n\t\tconst self: VisionBundle = this;\n\n\t\tconst programmaticSignal = (\n\t\t\tevaluator: (ctx: FrameContext) => number,\n\t\t\tsigOptions?: Parameters<typeof coreProgrammaticSignal>[1],\n\t\t): ProgrammaticSignal => {\n\t\t\tconst sig = coreProgrammaticSignal(evaluator, sigOptions);\n\t\t\tthis._registeredSignals.add(sig);\n\t\t\treturn sig;\n\t\t};\n\n\t\t// ── Pose landmark signals (COCO-17, primary person) ──────────────\n\t\tconst getPrimaryLandmarks = (frame: number): readonly Landmark3D[] => {\n\t\t\tconst person = this.getPoseResult(frame).people[0];\n\t\t\treturn (\n\t\t\t\t(person?.keypoints as unknown as Landmark3D[]) ??\n\t\t\t\tcreateNeutralLandmarks()\n\t\t\t);\n\t\t};\n\n\t\tconst createPoseCoord = (\n\t\t\tindex: number,\n\t\t\tlabel: string,\n\t\t): LandmarkCoordinateSignals => {\n\t\t\tconst getLm = (frame: number): Landmark3D =>\n\t\t\t\tgetPrimaryLandmarks(frame)[index] ?? { x: 0.5, y: 0.5, z: 0 };\n\t\t\tconst x = programmaticSignal((ctx) => getLm(ctx.frame).x, {\n\t\t\t\tfps: this._fps,\n\t\t\t\tlabel: `${label}_x`,\n\t\t\t});\n\t\t\tconst y = programmaticSignal((ctx) => getLm(ctx.frame).y, {\n\t\t\t\tfps: this._fps,\n\t\t\t\tlabel: `${label}_y`,\n\t\t\t});\n\t\t\tconst z = programmaticSignal((ctx) => getLm(ctx.frame).z ?? 0, {\n\t\t\t\tfps: this._fps,\n\t\t\t\tlabel: `${label}_z`,\n\t\t\t});\n\t\t\tconst screenX = programmaticSignal(\n\t\t\t\t(ctx) =>\n\t\t\t\t\tthis._transformer.projectNormalizedLandmark(getLm(ctx.frame)).x,\n\t\t\t\t{ fps: this._fps, label: `${label}_screenX` },\n\t\t\t);\n\t\t\tconst screenY = programmaticSignal(\n\t\t\t\t(ctx) =>\n\t\t\t\t\tthis._transformer.projectNormalizedLandmark(getLm(ctx.frame)).y,\n\t\t\t\t{ fps: this._fps, label: `${label}_screenY` },\n\t\t\t);\n\t\t\treturn { x, y, z, screenX, screenY };\n\t\t};\n\n\t\tconst getOrCreatePoseLm = (index: number): LandmarkCoordinateSignals => {\n\t\t\tlet sig = this._poseLmCache.get(index);\n\t\t\tif (!sig) {\n\t\t\t\tsig = createPoseCoord(\n\t\t\t\t\tindex,\n\t\t\t\t\tCOCO17_KEYPOINT_NAMES[index] ?? `kpt_${index}`,\n\t\t\t\t);\n\t\t\t\tthis._poseLmCache.set(index, sig);\n\t\t\t}\n\t\t\treturn sig;\n\t\t};\n\n\t\tconst poseNamed: PoseLandmarkSignals = {\n\t\t\tnose: getOrCreatePoseLm(COCO17_KEYPOINTS.NOSE),\n\t\t\tleftEye: getOrCreatePoseLm(COCO17_KEYPOINTS.LEFT_EYE),\n\t\t\trightEye: getOrCreatePoseLm(COCO17_KEYPOINTS.RIGHT_EYE),\n\t\t\tleftEar: getOrCreatePoseLm(COCO17_KEYPOINTS.LEFT_EAR),\n\t\t\trightEar: getOrCreatePoseLm(COCO17_KEYPOINTS.RIGHT_EAR),\n\t\t\tshoulder: getOrCreatePoseLm(COCO17_KEYPOINTS.LEFT_SHOULDER),\n\t\t\tleftShoulder: getOrCreatePoseLm(COCO17_KEYPOINTS.LEFT_SHOULDER),\n\t\t\trightShoulder: getOrCreatePoseLm(COCO17_KEYPOINTS.RIGHT_SHOULDER),\n\t\t\tleftElbow: getOrCreatePoseLm(COCO17_KEYPOINTS.LEFT_ELBOW),\n\t\t\trightElbow: getOrCreatePoseLm(COCO17_KEYPOINTS.RIGHT_ELBOW),\n\t\t\tleftWrist: getOrCreatePoseLm(COCO17_KEYPOINTS.LEFT_WRIST),\n\t\t\trightWrist: getOrCreatePoseLm(COCO17_KEYPOINTS.RIGHT_WRIST),\n\t\t\tleftHip: getOrCreatePoseLm(COCO17_KEYPOINTS.LEFT_HIP),\n\t\t\trightHip: getOrCreatePoseLm(COCO17_KEYPOINTS.RIGHT_HIP),\n\t\t\tleftKnee: getOrCreatePoseLm(COCO17_KEYPOINTS.LEFT_KNEE),\n\t\t\trightKnee: getOrCreatePoseLm(COCO17_KEYPOINTS.RIGHT_KNEE),\n\t\t\tleftAnkle: getOrCreatePoseLm(COCO17_KEYPOINTS.LEFT_ANKLE),\n\t\t\trightAnkle: getOrCreatePoseLm(COCO17_KEYPOINTS.RIGHT_ANKLE),\n\t\t\tget: getOrCreatePoseLm,\n\t\t};\n\t\tthis.poseLandmarks = new Proxy(poseNamed, {\n\t\t\tget(target, prop, receiver) {\n\t\t\t\tif (typeof prop === \"string\" && /^\\d+$/.test(prop)) {\n\t\t\t\t\treturn target.get(Number(prop));\n\t\t\t\t}\n\t\t\t\tif (typeof prop === \"number\") {\n\t\t\t\t\treturn target.get(prop);\n\t\t\t\t}\n\t\t\t\treturn Reflect.get(target, prop, receiver);\n\t\t\t},\n\t\t}) as PoseLandmarkSignals;\n\n\t\t// ── Object track signals ──\n\t\tconst neutralTrack = (\n\t\t\ttrackId: number,\n\t\t\tcategory = \"unknown\",\n\t\t): TrackedObject => ({\n\t\t\ttrackId,\n\t\t\tcategory,\n\t\t\tscore: 0,\n\t\t\tboundingBox: {\n\t\t\t\toriginX: this._width / 2,\n\t\t\t\toriginY: this._height / 2,\n\t\t\t\twidth: 0,\n\t\t\t\theight: 0,\n\t\t\t\tnormalizedX: 0.5,\n\t\t\t\tnormalizedY: 0.5,\n\t\t\t\tnormalizedWidth: 0,\n\t\t\t\tnormalizedHeight: 0,\n\t\t\t},\n\t\t\tcenterX: this._width / 2,\n\t\t\tcenterY: this._height / 2,\n\t\t\tnormalizedCenterX: 0.5,\n\t\t\tnormalizedCenterY: 0.5,\n\t\t\tvelocity: { vx: 0, vy: 0 },\n\t\t\tspeed: 0,\n\t\t\tage: 0,\n\t\t\thits: 0,\n\t\t\tactive: false,\n\t\t\tisCoasting: false,\n\t\t});\n\n\t\tconst createAnchor = (\n\t\t\tgetPos: (f: number) => { sx: number; sy: number },\n\t\t\tlabel: string,\n\t\t): LandmarkCoordinateSignals => {\n\t\t\tconst screenX = programmaticSignal((ctx) => getPos(ctx.frame).sx, {\n\t\t\t\tfps: this._fps,\n\t\t\t\tlabel: `${label}_screenX`,\n\t\t\t});\n\t\t\tconst screenY = programmaticSignal((ctx) => getPos(ctx.frame).sy, {\n\t\t\t\tfps: this._fps,\n\t\t\t\tlabel: `${label}_screenY`,\n\t\t\t});\n\t\t\tconst x = programmaticSignal(\n\t\t\t\t(ctx) => (this._width > 0 ? getPos(ctx.frame).sx / this._width : 0),\n\t\t\t\t{ fps: this._fps, label: `${label}_x` },\n\t\t\t);\n\t\t\tconst y = programmaticSignal(\n\t\t\t\t(ctx) => (this._height > 0 ? getPos(ctx.frame).sy / this._height : 0),\n\t\t\t\t{ fps: this._fps, label: `${label}_y` },\n\t\t\t);\n\t\t\tconst z = programmaticSignal(() => 0, {\n\t\t\t\tfps: this._fps,\n\t\t\t\tlabel: `${label}_z`,\n\t\t\t});\n\t\t\treturn { x, y, z, screenX, screenY };\n\t\t};\n\n\t\tconst buildTrackPoseSignals = (\n\t\t\tresolveTrack: (frame: number) => TrackedObject,\n\t\t\tlabel: string,\n\t\t\tfixedId?: number,\n\t\t): TrackPoseSignals => {\n\t\t\tconst resolvePerson = (frame: number): PosePerson | undefined => {\n\t\t\t\tconst poseRes = self.getPoseResult(frame);\n\t\t\t\tif (poseRes.people.length === 0) return undefined;\n\n\t\t\t\tconst trk = resolveTrack(frame);\n\t\t\t\tconst targetId = fixedId ?? trk.trackId;\n\n\t\t\t\t// 1. Direct match by trackId\n\t\t\t\tconst byId = poseRes.people.find((p) => p.trackId === targetId);\n\t\t\t\tif (byId) return byId;\n\n\t\t\t\t// 2. Spatial IoU fallback against track's bounding box\n\t\t\t\tif (!trk.active && poseRes.people.length > 1) return undefined;\n\n\t\t\t\tif (poseRes.people.length === 1) {\n\t\t\t\t\treturn poseRes.people[0];\n\t\t\t\t}\n\n\t\t\t\tlet bestPerson: PosePerson | undefined;\n\t\t\t\tlet bestIoU = 0.1;\n\t\t\t\tfor (const p of poseRes.people) {\n\t\t\t\t\tconst pBox = getPersonBoundingBox(p);\n\t\t\t\t\tconst isNormalized = pBox.width <= 1.05 && pBox.height <= 1.05;\n\t\t\t\t\tconst targetBox =\n\t\t\t\t\t\tisNormalized && trk.boundingBox.normalizedWidth > 0\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\toriginX: trk.boundingBox.normalizedX,\n\t\t\t\t\t\t\t\t\toriginY: trk.boundingBox.normalizedY,\n\t\t\t\t\t\t\t\t\twidth: trk.boundingBox.normalizedWidth,\n\t\t\t\t\t\t\t\t\theight: trk.boundingBox.normalizedHeight,\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t: trk.boundingBox;\n\t\t\t\t\tconst iou = computeIoU(pBox, targetBox);\n\t\t\t\t\tif (iou > bestIoU) {\n\t\t\t\t\t\tbestIoU = iou;\n\t\t\t\t\t\tbestPerson = p;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn bestPerson;\n\t\t\t};\n\n\t\t\tconst hasPose = programmaticSignal(\n\t\t\t\t(ctx) => (resolvePerson(ctx.frame) ? 1.0 : 0.0),\n\t\t\t\t{ fps: this._fps, label: `${label}_hasPose` },\n\t\t\t);\n\n\t\t\tconst createCoord = (\n\t\t\t\tindex: number,\n\t\t\t\tkptName: string,\n\t\t\t): LandmarkCoordinateSignals => {\n\t\t\t\tconst getLm = (frame: number): Landmark3D => {\n\t\t\t\t\tconst person = resolvePerson(frame);\n\t\t\t\t\tconst kp = person?.keypoints[index];\n\t\t\t\t\tif (kp && kp.visibility > 0.05) {\n\t\t\t\t\t\treturn { x: kp.x, y: kp.y, z: 0 };\n\t\t\t\t\t}\n\t\t\t\t\tconst trk = resolveTrack(frame);\n\t\t\t\t\treturn {\n\t\t\t\t\t\tx: trk.normalizedCenterX,\n\t\t\t\t\t\ty: trk.normalizedCenterY,\n\t\t\t\t\t\tz: 0,\n\t\t\t\t\t};\n\t\t\t\t};\n\n\t\t\t\tconst x = programmaticSignal((ctx) => getLm(ctx.frame).x, {\n\t\t\t\t\tfps: this._fps,\n\t\t\t\t\tlabel: `${label}_${kptName}_x`,\n\t\t\t\t});\n\t\t\t\tconst y = programmaticSignal((ctx) => getLm(ctx.frame).y, {\n\t\t\t\t\tfps: this._fps,\n\t\t\t\t\tlabel: `${label}_${kptName}_y`,\n\t\t\t\t});\n\t\t\t\tconst z = programmaticSignal((ctx) => getLm(ctx.frame).z ?? 0, {\n\t\t\t\t\tfps: this._fps,\n\t\t\t\t\tlabel: `${label}_${kptName}_z`,\n\t\t\t\t});\n\t\t\t\tconst screenX = programmaticSignal(\n\t\t\t\t\t(ctx) =>\n\t\t\t\t\t\tself._transformer.projectNormalizedLandmark(getLm(ctx.frame)).x,\n\t\t\t\t\t{ fps: this._fps, label: `${label}_${kptName}_screenX` },\n\t\t\t\t);\n\t\t\t\tconst screenY = programmaticSignal(\n\t\t\t\t\t(ctx) =>\n\t\t\t\t\t\tself._transformer.projectNormalizedLandmark(getLm(ctx.frame)).y,\n\t\t\t\t\t{ fps: this._fps, label: `${label}_${kptName}_screenY` },\n\t\t\t\t);\n\t\t\t\treturn { x, y, z, screenX, screenY };\n\t\t\t};\n\n\t\t\tconst coordsCache = new Map<number, LandmarkCoordinateSignals>();\n\t\t\tconst getOrCreateCoord = (idx: number): LandmarkCoordinateSignals => {\n\t\t\t\tlet c = coordsCache.get(idx);\n\t\t\t\tif (!c) {\n\t\t\t\t\tc = createCoord(idx, COCO17_KEYPOINT_NAMES[idx] ?? `kpt_${idx}`);\n\t\t\t\t\tcoordsCache.set(idx, c);\n\t\t\t\t}\n\t\t\t\treturn c;\n\t\t\t};\n\n\t\t\tconst wristSpeed = programmaticSignal(\n\t\t\t\t(ctx) => {\n\t\t\t\t\tconst f = ctx.frame;\n\t\t\t\t\tconst curr = resolvePerson(f);\n\t\t\t\t\tif (!curr) return 0;\n\t\t\t\t\tconst prev = resolvePerson(Math.max(0, f - 1));\n\t\t\t\t\tconst currKp = curr.keypoints;\n\t\t\t\t\tconst prevKp = prev?.keypoints;\n\n\t\t\t\t\tconst rwCurr = currKp[COCO17_KEYPOINTS.RIGHT_WRIST];\n\t\t\t\t\tconst rwPrev = prevKp?.[COCO17_KEYPOINTS.RIGHT_WRIST];\n\t\t\t\t\tlet rwSpeed = 0;\n\t\t\t\t\tif (\n\t\t\t\t\t\trwCurr &&\n\t\t\t\t\t\trwPrev &&\n\t\t\t\t\t\trwCurr.visibility > 0.1 &&\n\t\t\t\t\t\trwPrev.visibility > 0.1\n\t\t\t\t\t) {\n\t\t\t\t\t\tconst dx = (rwCurr.x - rwPrev.x) * this._width;\n\t\t\t\t\t\tconst dy = (rwCurr.y - rwPrev.y) * this._height;\n\t\t\t\t\t\trwSpeed = Math.sqrt(dx * dx + dy * dy) * this._fps;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst lwCurr = currKp[COCO17_KEYPOINTS.LEFT_WRIST];\n\t\t\t\t\tconst lwPrev = prevKp?.[COCO17_KEYPOINTS.LEFT_WRIST];\n\t\t\t\t\tlet lwSpeed = 0;\n\t\t\t\t\tif (\n\t\t\t\t\t\tlwCurr &&\n\t\t\t\t\t\tlwPrev &&\n\t\t\t\t\t\tlwCurr.visibility > 0.1 &&\n\t\t\t\t\t\tlwPrev.visibility > 0.1\n\t\t\t\t\t) {\n\t\t\t\t\t\tconst dx = (lwCurr.x - lwPrev.x) * this._width;\n\t\t\t\t\t\tconst dy = (lwCurr.y - lwPrev.y) * this._height;\n\t\t\t\t\t\tlwSpeed = Math.sqrt(dx * dx + dy * dy) * this._fps;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn Math.max(rwSpeed, lwSpeed);\n\t\t\t\t},\n\t\t\t\t{ fps: this._fps, label: `${label}_wristSpeed` },\n\t\t\t);\n\n\t\t\tconst handRaised = programmaticSignal(\n\t\t\t\t(ctx) => {\n\t\t\t\t\tconst p = resolvePerson(ctx.frame);\n\t\t\t\t\tif (!p) return 0.0;\n\t\t\t\t\tconst k = p.keypoints;\n\t\t\t\t\tconst lw = k[COCO17_KEYPOINTS.LEFT_WRIST];\n\t\t\t\t\tconst ls = k[COCO17_KEYPOINTS.LEFT_SHOULDER];\n\t\t\t\t\tconst rw = k[COCO17_KEYPOINTS.RIGHT_WRIST];\n\t\t\t\t\tconst rs = k[COCO17_KEYPOINTS.RIGHT_SHOULDER];\n\n\t\t\t\t\tconst lRaised =\n\t\t\t\t\t\tlw &&\n\t\t\t\t\t\tls &&\n\t\t\t\t\t\tlw.visibility > 0.1 &&\n\t\t\t\t\t\tls.visibility > 0.1 &&\n\t\t\t\t\t\tlw.y < ls.y;\n\t\t\t\t\tconst rRaised =\n\t\t\t\t\t\trw &&\n\t\t\t\t\t\trs &&\n\t\t\t\t\t\trw.visibility > 0.1 &&\n\t\t\t\t\t\trs.visibility > 0.1 &&\n\t\t\t\t\t\trw.y < rs.y;\n\t\t\t\t\treturn lRaised || rRaised ? 1.0 : 0.0;\n\t\t\t\t},\n\t\t\t\t{ fps: this._fps, label: `${label}_handRaised` },\n\t\t\t);\n\n\t\t\tconst bodyTiltAngle = programmaticSignal(\n\t\t\t\t(ctx) => {\n\t\t\t\t\tconst p = resolvePerson(ctx.frame);\n\t\t\t\t\tif (!p) return 0.0;\n\t\t\t\t\tconst k = p.keypoints;\n\t\t\t\t\tconst ls = k[COCO17_KEYPOINTS.LEFT_SHOULDER];\n\t\t\t\t\tconst rs = k[COCO17_KEYPOINTS.RIGHT_SHOULDER];\n\t\t\t\t\tconst lh = k[COCO17_KEYPOINTS.LEFT_HIP];\n\t\t\t\t\tconst rh = k[COCO17_KEYPOINTS.RIGHT_HIP];\n\t\t\t\t\tif (!ls || !rs || !lh || !rh) return 0.0;\n\n\t\t\t\t\tconst sx = ((ls.x + rs.x) / 2) * this._width;\n\t\t\t\t\tconst sy = ((ls.y + rs.y) / 2) * this._height;\n\t\t\t\t\tconst hx = ((lh.x + rh.x) / 2) * this._width;\n\t\t\t\t\tconst hy = ((lh.y + rh.y) / 2) * this._height;\n\n\t\t\t\t\tconst dx = sx - hx;\n\t\t\t\t\tconst dy = sy - hy;\n\t\t\t\t\tif (dx === 0 && dy === 0) return 0.0;\n\t\t\t\t\treturn Math.atan2(dx, -dy);\n\t\t\t\t},\n\t\t\t\t{ fps: this._fps, label: `${label}_bodyTiltAngle` },\n\t\t\t);\n\n\t\t\tconst namedPose: TrackPoseSignals = {\n\t\t\t\thasPose,\n\t\t\t\twristSpeed,\n\t\t\t\thandRaised,\n\t\t\t\tbodyTiltAngle,\n\t\t\t\tnose: getOrCreateCoord(COCO17_KEYPOINTS.NOSE),\n\t\t\t\tleftEye: getOrCreateCoord(COCO17_KEYPOINTS.LEFT_EYE),\n\t\t\t\trightEye: getOrCreateCoord(COCO17_KEYPOINTS.RIGHT_EYE),\n\t\t\t\tleftEar: getOrCreateCoord(COCO17_KEYPOINTS.LEFT_EAR),\n\t\t\t\trightEar: getOrCreateCoord(COCO17_KEYPOINTS.RIGHT_EAR),\n\t\t\t\tshoulder: getOrCreateCoord(COCO17_KEYPOINTS.LEFT_SHOULDER),\n\t\t\t\tleftShoulder: getOrCreateCoord(COCO17_KEYPOINTS.LEFT_SHOULDER),\n\t\t\t\trightShoulder: getOrCreateCoord(COCO17_KEYPOINTS.RIGHT_SHOULDER),\n\t\t\t\tleftElbow: getOrCreateCoord(COCO17_KEYPOINTS.LEFT_ELBOW),\n\t\t\t\trightElbow: getOrCreateCoord(COCO17_KEYPOINTS.RIGHT_ELBOW),\n\t\t\t\tleftWrist: getOrCreateCoord(COCO17_KEYPOINTS.LEFT_WRIST),\n\t\t\t\trightWrist: getOrCreateCoord(COCO17_KEYPOINTS.RIGHT_WRIST),\n\t\t\t\tleftHip: getOrCreateCoord(COCO17_KEYPOINTS.LEFT_HIP),\n\t\t\t\trightHip: getOrCreateCoord(COCO17_KEYPOINTS.RIGHT_HIP),\n\t\t\t\tleftKnee: getOrCreateCoord(COCO17_KEYPOINTS.LEFT_KNEE),\n\t\t\t\trightKnee: getOrCreateCoord(COCO17_KEYPOINTS.RIGHT_KNEE),\n\t\t\t\tleftAnkle: getOrCreateCoord(COCO17_KEYPOINTS.LEFT_ANKLE),\n\t\t\t\trightAnkle: getOrCreateCoord(COCO17_KEYPOINTS.RIGHT_ANKLE),\n\t\t\t\tget: getOrCreateCoord,\n\t\t\t};\n\n\t\t\treturn new Proxy(namedPose, {\n\t\t\t\tget(target, prop, receiver) {\n\t\t\t\t\tif (typeof prop === \"string\" && /^\\d+$/.test(prop)) {\n\t\t\t\t\t\treturn target.get(Number(prop));\n\t\t\t\t\t}\n\t\t\t\t\tif (typeof prop === \"number\") {\n\t\t\t\t\t\treturn target.get(prop);\n\t\t\t\t\t}\n\t\t\t\t\treturn Reflect.get(target, prop, receiver);\n\t\t\t\t},\n\t\t\t});\n\t\t};\n\n\t\tconst buildTrackSignals = (\n\t\t\tresolve: (frame: number) => TrackedObject,\n\t\t\tlabel: string,\n\t\t\tfixedCategory?: string,\n\t\t\tfixedId?: number,\n\t\t): ObjectTrackSignals => {\n\t\t\tconst getBox = (f: number) => resolve(f).boundingBox;\n\t\t\tconst pose = buildTrackPoseSignals(resolve, `${label}_pose`, fixedId);\n\t\t\tconst anchor = (\n\t\t\t\tname: string,\n\t\t\t\tsx: (b: TrackedObject[\"boundingBox\"]) => number,\n\t\t\t\tsy: (b: TrackedObject[\"boundingBox\"]) => number,\n\t\t\t) =>\n\t\t\t\tcreateAnchor(\n\t\t\t\t\t(f) => ({ sx: sx(getBox(f)), sy: sy(getBox(f)) }),\n\t\t\t\t\t`${label}_${name}`,\n\t\t\t\t);\n\n\t\t\tconst center = anchor(\n\t\t\t\t\"center\",\n\t\t\t\t(b) => b.originX + b.width / 2,\n\t\t\t\t(b) => b.originY + b.height / 2,\n\t\t\t);\n\t\t\tconst speed = programmaticSignal((ctx) => resolve(ctx.frame).speed, {\n\t\t\t\tfps: this._fps,\n\t\t\t\tlabel: `${label}_speed`,\n\t\t\t});\n\n\t\t\treturn {\n\t\t\t\tget trackId() {\n\t\t\t\t\treturn fixedId ?? resolve(0).trackId;\n\t\t\t\t},\n\t\t\t\tget category() {\n\t\t\t\t\treturn fixedCategory ?? resolve(0).category;\n\t\t\t\t},\n\t\t\t\tbounds: {\n\t\t\t\t\tx: programmaticSignal((ctx) => getBox(ctx.frame).normalizedX, {\n\t\t\t\t\t\tfps: this._fps,\n\t\t\t\t\t\tlabel: `${label}_normX`,\n\t\t\t\t\t}),\n\t\t\t\t\ty: programmaticSignal((ctx) => getBox(ctx.frame).normalizedY, {\n\t\t\t\t\t\tfps: this._fps,\n\t\t\t\t\t\tlabel: `${label}_normY`,\n\t\t\t\t\t}),\n\t\t\t\t\twidth: programmaticSignal(\n\t\t\t\t\t\t(ctx) => getBox(ctx.frame).normalizedWidth,\n\t\t\t\t\t\t{ fps: this._fps, label: `${label}_normWidth` },\n\t\t\t\t\t),\n\t\t\t\t\theight: programmaticSignal(\n\t\t\t\t\t\t(ctx) => getBox(ctx.frame).normalizedHeight,\n\t\t\t\t\t\t{ fps: this._fps, label: `${label}_normHeight` },\n\t\t\t\t\t),\n\t\t\t\t\tscreenX: programmaticSignal((ctx) => getBox(ctx.frame).originX, {\n\t\t\t\t\t\tfps: this._fps,\n\t\t\t\t\t\tlabel: `${label}_screenX`,\n\t\t\t\t\t}),\n\t\t\t\t\tscreenY: programmaticSignal((ctx) => getBox(ctx.frame).originY, {\n\t\t\t\t\t\tfps: this._fps,\n\t\t\t\t\t\tlabel: `${label}_screenY`,\n\t\t\t\t\t}),\n\t\t\t\t\tscreenWidth: programmaticSignal((ctx) => getBox(ctx.frame).width, {\n\t\t\t\t\t\tfps: this._fps,\n\t\t\t\t\t\tlabel: `${label}_screenWidth`,\n\t\t\t\t\t}),\n\t\t\t\t\tscreenHeight: programmaticSignal((ctx) => getBox(ctx.frame).height, {\n\t\t\t\t\t\tfps: this._fps,\n\t\t\t\t\t\tlabel: `${label}_screenHeight`,\n\t\t\t\t\t}),\n\t\t\t\t\taspectRatio: programmaticSignal(\n\t\t\t\t\t\t(ctx) => {\n\t\t\t\t\t\t\tconst b = getBox(ctx.frame);\n\t\t\t\t\t\t\treturn b.height > 0 ? b.width / b.height : 1.0;\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ fps: this._fps, label: `${label}_aspectRatio` },\n\t\t\t\t\t),\n\t\t\t\t\tarea: programmaticSignal(\n\t\t\t\t\t\t(ctx) => {\n\t\t\t\t\t\t\tconst b = getBox(ctx.frame);\n\t\t\t\t\t\t\treturn b.width * b.height;\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ fps: this._fps, label: `${label}_area` },\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t\tanchors: {\n\t\t\t\t\ttopLeft: anchor(\n\t\t\t\t\t\t\"topLeft\",\n\t\t\t\t\t\t(b) => b.originX,\n\t\t\t\t\t\t(b) => b.originY,\n\t\t\t\t\t),\n\t\t\t\t\ttopCenter: anchor(\n\t\t\t\t\t\t\"topCenter\",\n\t\t\t\t\t\t(b) => b.originX + b.width / 2,\n\t\t\t\t\t\t(b) => b.originY,\n\t\t\t\t\t),\n\t\t\t\t\ttopRight: anchor(\n\t\t\t\t\t\t\"topRight\",\n\t\t\t\t\t\t(b) => b.originX + b.width,\n\t\t\t\t\t\t(b) => b.originY,\n\t\t\t\t\t),\n\t\t\t\t\tcenterLeft: anchor(\n\t\t\t\t\t\t\"centerLeft\",\n\t\t\t\t\t\t(b) => b.originX,\n\t\t\t\t\t\t(b) => b.originY + b.height / 2,\n\t\t\t\t\t),\n\t\t\t\t\tcenter,\n\t\t\t\t\tcenterRight: anchor(\n\t\t\t\t\t\t\"centerRight\",\n\t\t\t\t\t\t(b) => b.originX + b.width,\n\t\t\t\t\t\t(b) => b.originY + b.height / 2,\n\t\t\t\t\t),\n\t\t\t\t\tbottomLeft: anchor(\n\t\t\t\t\t\t\"bottomLeft\",\n\t\t\t\t\t\t(b) => b.originX,\n\t\t\t\t\t\t(b) => b.originY + b.height,\n\t\t\t\t\t),\n\t\t\t\t\tbottomCenter: anchor(\n\t\t\t\t\t\t\"bottomCenter\",\n\t\t\t\t\t\t(b) => b.originX + b.width / 2,\n\t\t\t\t\t\t(b) => b.originY + b.height,\n\t\t\t\t\t),\n\t\t\t\t\tbottomRight: anchor(\n\t\t\t\t\t\t\"bottomRight\",\n\t\t\t\t\t\t(b) => b.originX + b.width,\n\t\t\t\t\t\t(b) => b.originY + b.height,\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t\tkinematics: {\n\t\t\t\t\tvx: programmaticSignal((ctx) => resolve(ctx.frame).velocity.vx, {\n\t\t\t\t\t\tfps: this._fps,\n\t\t\t\t\t\tlabel: `${label}_vx`,\n\t\t\t\t\t}),\n\t\t\t\t\tvy: programmaticSignal((ctx) => resolve(ctx.frame).velocity.vy, {\n\t\t\t\t\t\tfps: this._fps,\n\t\t\t\t\t\tlabel: `${label}_vy`,\n\t\t\t\t\t}),\n\t\t\t\t\tspeed,\n\t\t\t\t\tacceleration: speed.velocity(1),\n\t\t\t\t\theadingRad: programmaticSignal(\n\t\t\t\t\t\t(ctx) => {\n\t\t\t\t\t\t\tconst v = resolve(ctx.frame).velocity;\n\t\t\t\t\t\t\treturn Math.atan2(v.vy, v.vx);\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ fps: this._fps, label: `${label}_headingRad` },\n\t\t\t\t\t),\n\t\t\t\t\theadingDeg: programmaticSignal(\n\t\t\t\t\t\t(ctx) => {\n\t\t\t\t\t\t\tconst v = resolve(ctx.frame).velocity;\n\t\t\t\t\t\t\treturn (Math.atan2(v.vy, v.vx) * 180) / Math.PI;\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ fps: this._fps, label: `${label}_headingDeg` },\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t\tconfidence: programmaticSignal((ctx) => resolve(ctx.frame).score, {\n\t\t\t\t\tfps: this._fps,\n\t\t\t\t\tlabel: `${label}_score`,\n\t\t\t\t}),\n\t\t\t\tactive: programmaticSignal(\n\t\t\t\t\t(ctx) => (resolve(ctx.frame).active ? 1.0 : 0.0),\n\t\t\t\t\t{ fps: this._fps, label: `${label}_active` },\n\t\t\t\t),\n\t\t\t\tisCoasting: programmaticSignal(\n\t\t\t\t\t(ctx) => (resolve(ctx.frame).isCoasting ? 1.0 : 0.0),\n\t\t\t\t\t{ fps: this._fps, label: `${label}_isCoasting` },\n\t\t\t\t),\n\t\t\t\tage: programmaticSignal((ctx) => resolve(ctx.frame).age, {\n\t\t\t\t\tfps: this._fps,\n\t\t\t\t\tlabel: `${label}_age`,\n\t\t\t\t}),\n\t\t\t\tpose,\n\t\t\t\tcenter,\n\t\t\t\ttopCenter: (this as unknown as Record<string, unknown>)[\n\t\t\t\t\t`__pending`\n\t\t\t\t] as never,\n\t\t\t\tbottomCenter: center,\n\t\t\t\ttopLeft: center,\n\t\t\t\tbottomLeft: center,\n\t\t\t} as ObjectTrackSignals;\n\t\t};\n\n\t\t// NOTE: shortcuts are patched below from the anchors map (kept readable)\n\t\tconst buildTrack = (\n\t\t\tresolve: (frame: number) => TrackedObject,\n\t\t\tlabel: string,\n\t\t\tfixedCategory?: string,\n\t\t\tfixedId?: number,\n\t\t): ObjectTrackSignals => {\n\t\t\tconst sig = buildTrackSignals(resolve, label, fixedCategory, fixedId);\n\t\t\tconst anchors = sig.anchors;\n\t\t\tObject.assign(sig, {\n\t\t\t\ttopCenter: anchors.topCenter,\n\t\t\t\tbottomCenter: anchors.bottomCenter,\n\t\t\t\ttopLeft: anchors.topLeft,\n\t\t\t\tbottomLeft: anchors.bottomLeft,\n\t\t\t});\n\t\t\treturn sig;\n\t\t};\n\n\t\tconst getTrackById = (trackId: number): ObjectTrackSignals => {\n\t\t\tlet sig = this._trackCache.get(trackId);\n\t\t\tif (!sig) {\n\t\t\t\tsig = buildTrack(\n\t\t\t\t\t(frame) =>\n\t\t\t\t\t\tthis.getObjectResult(frame).objects.find(\n\t\t\t\t\t\t\t(o) => o.trackId === trackId,\n\t\t\t\t\t\t) ?? neutralTrack(trackId),\n\t\t\t\t\t`track_${trackId}`,\n\t\t\t\t\tundefined,\n\t\t\t\t\ttrackId,\n\t\t\t\t);\n\t\t\t\tthis._trackCache.set(trackId, sig);\n\t\t\t}\n\t\t\treturn sig;\n\t\t};\n\n\t\tconst getTrackByCategory = (\n\t\t\tcategory: string,\n\t\t\trank = 0,\n\t\t): ObjectTrackSignals => {\n\t\t\tconst cacheKey = `${category.toLowerCase()}_${rank}`;\n\t\t\tlet sig = this._categoryCache.get(cacheKey);\n\t\t\tif (!sig) {\n\t\t\t\tsig = buildTrack(\n\t\t\t\t\t(frame) => {\n\t\t\t\t\t\tconst res = this.getObjectResult(frame);\n\t\t\t\t\t\tconst matches = res.objects.filter(\n\t\t\t\t\t\t\t(o) =>\n\t\t\t\t\t\t\t\to.category.toLowerCase() === category.toLowerCase() && o.active,\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn matches[rank] ?? neutralTrack(0, category);\n\t\t\t\t\t},\n\t\t\t\t\t`cat_${category}_${rank}`,\n\t\t\t\t\tcategory,\n\t\t\t\t);\n\t\t\t\tthis._categoryCache.set(cacheKey, sig);\n\t\t\t}\n\t\t\treturn sig;\n\t\t};\n\n\t\tconst primaryTrack = buildTrack((frame) => {\n\t\t\tconst res = this.getObjectResult(frame);\n\t\t\tif (res.objects.length === 0) return neutralTrack(0);\n\t\t\tlet best = res.objects[0];\n\t\t\tfor (let i = 1; i < res.objects.length; i++) {\n\t\t\t\tif (res.objects[i].score > best.score) best = res.objects[i];\n\t\t\t}\n\t\t\treturn best;\n\t\t}, \"primary_object\");\n\n\t\tconst activeCategories = (frame: number): string[] => {\n\t\t\tconst set = new Set<string>();\n\t\t\tfor (const o of this.getObjectResult(frame).objects) {\n\t\t\t\tif (o.active) set.add(o.category);\n\t\t\t}\n\t\t\treturn Array.from(set).sort();\n\t\t};\n\n\t\t// ── Class signals (per COCO class, cached stable identity) ────────\n\t\tconst buildClassSignals = (category: string): ClassSignals => {\n\t\t\tconst lower = category.toLowerCase();\n\t\t\tlet sig = this._classCache.get(lower);\n\t\t\tif (sig) return sig;\n\t\t\tsig = {\n\t\t\t\tcount: programmaticSignal(\n\t\t\t\t\t(ctx) =>\n\t\t\t\t\t\tthis.getObjectResult(ctx.frame).objects.filter(\n\t\t\t\t\t\t\t(o) => o.active && o.category.toLowerCase() === lower,\n\t\t\t\t\t\t).length,\n\t\t\t\t\t{ fps: this._fps, label: `class_${lower}_count` },\n\t\t\t\t),\n\t\t\t\tmaxConfidence: programmaticSignal(\n\t\t\t\t\t(ctx) => {\n\t\t\t\t\t\tlet max = 0;\n\t\t\t\t\t\tfor (const o of this.getObjectResult(ctx.frame).objects) {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\to.active &&\n\t\t\t\t\t\t\t\to.category.toLowerCase() === lower &&\n\t\t\t\t\t\t\t\to.score > max\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tmax = o.score;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn max;\n\t\t\t\t\t},\n\t\t\t\t\t{ fps: this._fps, label: `class_${lower}_maxConf` },\n\t\t\t\t),\n\t\t\t\tpresent: programmaticSignal(\n\t\t\t\t\t(ctx) =>\n\t\t\t\t\t\tthis.getObjectResult(ctx.frame).objects.some(\n\t\t\t\t\t\t\t(o) => o.active && o.category.toLowerCase() === lower,\n\t\t\t\t\t\t)\n\t\t\t\t\t\t\t? 1.0\n\t\t\t\t\t\t\t: 0.0,\n\t\t\t\t\t{ fps: this._fps, label: `class_${lower}_present` },\n\t\t\t\t),\n\t\t\t\tprimary: getTrackByCategory(category),\n\t\t\t};\n\t\t\tthis._classCache.set(lower, sig);\n\t\t\treturn sig;\n\t\t};\n\n\t\tthis.classes = {\n\t\t\tget: buildClassSignals,\n\t\t\tget names() {\n\t\t\t\treturn activeCategories(frameSignal.value);\n\t\t\t},\n\t\t\thistogram: {\n\t\t\t\tget: (ctx?: FrameContext) =>\n\t\t\t\t\tself.getClassHistogramTensor(ctx?.frame ?? frameSignal.value),\n\t\t\t\tget value() {\n\t\t\t\t\treturn self.getClassHistogramTensor(frameSignal.value);\n\t\t\t\t},\n\t\t\t},\n\t\t};\n\n\t\tthis.objects = {\n\t\t\tget: getTrackById,\n\t\t\tbyCategory: getTrackByCategory,\n\t\t\tprimary: primaryTrack,\n\t\t\tcount: programmaticSignal(\n\t\t\t\t(ctx) =>\n\t\t\t\t\tthis.getObjectResult(ctx.frame).objects.filter((o) => o.active)\n\t\t\t\t\t\t.length,\n\t\t\t\t{ fps: this._fps, label: \"tracked_objects_count\" },\n\t\t\t),\n\t\t\thasCategory: (category: string) => buildClassSignals(category).present,\n\t\t\tgetActiveTracks: (frame: number) =>\n\t\t\t\tthis.getObjectResult(frame).objects.filter((o) => o.active),\n\t\t\tget detectedCategories() {\n\t\t\t\treturn activeCategories(frameSignal.value);\n\t\t\t},\n\t\t};\n\n\t\t// ── Mask signals ──────────────────────────────────────────────────\n\t\tconst maskForTrack = (\n\t\t\tframe: number,\n\t\t\ttrackId: number,\n\t\t): InstanceMask | undefined =>\n\t\t\tthis.getMaskResult(frame).find((m) => m.trackId === trackId);\n\n\t\tconst subjectMask = (frame: number): InstanceMask | undefined =>\n\t\t\tselectSubjectMask(this.getMaskResult(frame));\n\n\t\tconst buildMaskTrackSignals = (\n\t\t\tresolve: (frame: number) => InstanceMask | undefined,\n\t\t\tlabel: string,\n\t\t): MaskTrackSignals => {\n\t\t\tconst boxFor = (frame: number) => {\n\t\t\t\tconst mask = resolve(frame);\n\t\t\t\tif (!mask || mask.trackId === undefined) return undefined;\n\t\t\t\treturn this.getObjectResult(frame).objects.find(\n\t\t\t\t\t(o) => o.trackId === mask.trackId,\n\t\t\t\t);\n\t\t\t};\n\t\t\treturn {\n\t\t\t\tget trackId() {\n\t\t\t\t\treturn resolve(frameSignal.value)?.trackId ?? 0;\n\t\t\t\t},\n\t\t\t\tget category() {\n\t\t\t\t\treturn resolve(frameSignal.value)?.category ?? \"unknown\";\n\t\t\t\t},\n\t\t\t\tarea: programmaticSignal((ctx) => resolve(ctx.frame)?.area ?? 0, {\n\t\t\t\t\tfps: this._fps,\n\t\t\t\t\tlabel: `${label}_area`,\n\t\t\t\t}),\n\t\t\t\tcoverage: programmaticSignal(\n\t\t\t\t\t(ctx) => resolve(ctx.frame)?.coverage ?? 0,\n\t\t\t\t\t{\n\t\t\t\t\t\tfps: this._fps,\n\t\t\t\t\t\tlabel: `${label}_coverage`,\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t\tsolidity: programmaticSignal(\n\t\t\t\t\t(ctx) => {\n\t\t\t\t\t\tconst mask = resolve(ctx.frame);\n\t\t\t\t\t\tconst box = boxFor(ctx.frame);\n\t\t\t\t\t\tif (!mask || !box) return 0;\n\t\t\t\t\t\tconst bboxArea = box.boundingBox.width * box.boundingBox.height;\n\t\t\t\t\t\treturn bboxArea > 0 ? mask.area / bboxArea : 0;\n\t\t\t\t\t},\n\t\t\t\t\t{ fps: this._fps, label: `${label}_solidity` },\n\t\t\t\t),\n\t\t\t\tbboxFill: programmaticSignal(\n\t\t\t\t\t(ctx) => {\n\t\t\t\t\t\tconst mask = resolve(ctx.frame);\n\t\t\t\t\t\tif (!mask || mask.width * mask.height === 0) return 0;\n\t\t\t\t\t\tconst box = boxFor(ctx.frame);\n\t\t\t\t\t\tif (!box) return 0;\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t(box.boundingBox.width * box.boundingBox.height) /\n\t\t\t\t\t\t\t(mask.width * mask.height)\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t\t{ fps: this._fps, label: `${label}_bboxFill` },\n\t\t\t\t),\n\t\t\t};\n\t\t};\n\n\t\tthis.masks = {\n\t\t\tget: (trackId: number) => {\n\t\t\t\tlet sig = this._maskTrackCache.get(trackId);\n\t\t\t\tif (!sig) {\n\t\t\t\t\tsig = buildMaskTrackSignals(\n\t\t\t\t\t\t(frame) => maskForTrack(frame, trackId),\n\t\t\t\t\t\t`mask_${trackId}`,\n\t\t\t\t\t);\n\t\t\t\t\tthis._maskTrackCache.set(trackId, sig);\n\t\t\t\t}\n\t\t\t\treturn sig;\n\t\t\t},\n\t\t\tsubject: buildMaskTrackSignals(subjectMask, \"subject\"),\n\t\t\tcount: programmaticSignal(\n\t\t\t\t(ctx) =>\n\t\t\t\t\tnew Set(this.getMaskResult(ctx.frame).map((m) => m.trackId ?? -1))\n\t\t\t\t\t\t.size,\n\t\t\t\t{ fps: this._fps, label: \"mask_count\" },\n\t\t\t),\n\t\t};\n\n\t\tthis.segmentation = {\n\t\t\thumanSilhouette: this.masks.subject,\n\t\t\tsubject: this.masks.subject,\n\t\t\tinstanceMasks: this.masks,\n\t\t\tmatte: {\n\t\t\t\tcoverage: programmaticSignal(\n\t\t\t\t\t(ctx) => self.getMatteResult(ctx.frame)?.coverage ?? 0,\n\t\t\t\t\t{ fps: this._fps, label: \"matte_coverage\" },\n\t\t\t\t),\n\t\t\t\tat: (frame: number) => self.getMatteResult(frame),\n\t\t\t},\n\t\t\tget stencilTexture() {\n\t\t\t\treturn self._stencilTexture;\n\t\t\t},\n\t\t};\n\n\t\t// ── Tensor views ──────────────────────────────────────────────────\n\t\tthis.poseLandmarksTensor = {\n\t\t\tget: (ctx?: FrameContext) =>\n\t\t\t\tself.getPoseLandmarksTensor(ctx?.frame ?? frameSignal.value),\n\t\t\tget value() {\n\t\t\t\treturn self.getPoseLandmarksTensor(frameSignal.value);\n\t\t\t},\n\t\t};\n\t\tthis.objectsTensor = {\n\t\t\tget: (ctx?: FrameContext) =>\n\t\t\t\tself.getObjectsTensor(ctx?.frame ?? frameSignal.value),\n\t\t\tget value() {\n\t\t\t\treturn self.getObjectsTensor(frameSignal.value);\n\t\t\t},\n\t\t};\n\t\tthis.masksTensor = {\n\t\t\tget: (ctx?: FrameContext) =>\n\t\t\t\tself.getMasksTensor(ctx?.frame ?? frameSignal.value),\n\t\t\tget value() {\n\t\t\t\treturn self.getMasksTensor(frameSignal.value);\n\t\t\t},\n\t\t};\n\t\tthis.histogramTensor = {\n\t\t\tget: (ctx?: FrameContext) =>\n\t\t\t\tself.getClassHistogramTensor(ctx?.frame ?? frameSignal.value),\n\t\t\tget value() {\n\t\t\t\treturn self.getClassHistogramTensor(frameSignal.value);\n\t\t\t},\n\t\t};\n\t}\n\n\tpublic setStencilTexture(texture: GPUTexture): void {\n\t\tthis._stencilTexture = texture;\n\t}\n\n\tpublic get stencilTexture(): GPUTexture | undefined {\n\t\treturn this._stencilTexture;\n\t}\n\n\t// ── Per-frame result caches (async writes → sync signal reads) ───────\n\n\t/**\n\t * Reads the most recent result at or before `frame`. Vision results are written one\n\t * frame behind the plate (the node renderer reads back the previous frame to infer),\n\t * and pinned-signal layout runs before the current frame's inference, so a strict\n\t * per-frame lookup would always miss. Walking back a few frames keeps signals live at\n\t * a stable one-frame lag instead of snapping to neutral defaults.\n\t */\n\tprivate latestAtOrBefore<T>(\n\t\tcache: Map<number, T>,\n\t\tframe: number,\n\t\tmaxBack = 8,\n\t): T | undefined {\n\t\tconst start = this.clamp(frame);\n\t\tconst floor = Math.max(0, start - maxBack);\n\t\tfor (let f = start; f >= floor; f--) {\n\t\t\tconst value = cache.get(f);\n\t\t\tif (value !== undefined) return value;\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tpublic invalidateSignals(): void {\n\t\tfor (const sig of this._registeredSignals) {\n\t\t\tsig.invalidate();\n\t\t}\n\t}\n\n\tpublic setPoseResult(frame: number, result: PoseResult): void {\n\t\tthis._poseCache.set(this.clamp(frame), result);\n\t\tthis.invalidateSignals();\n\t}\n\n\tpublic getPoseResult(frame: number): PoseResult {\n\t\treturn (\n\t\t\tthis.latestAtOrBefore(this._poseCache, frame) ?? createNeutralPoseResult()\n\t\t);\n\t}\n\n\tpublic setObjectResult(\n\t\tframe: number,\n\t\tresult:\n\t\t\t| {\n\t\t\t\t\tobjects: readonly TrackedObject[];\n\t\t\t\t\trawDetections?: readonly DetectedObject[];\n\t\t\t }\n\t\t\t| readonly TrackedObject[],\n\t): void {\n\t\t// `in`-narrowing instead of Array.isArray: the guard can't discriminate\n\t\t// readonly tuple-ish arrays, which keeps the union open.\n\t\tconst normalized =\n\t\t\t\"objects\" in result ? result : { objects: result, rawDetections: [] };\n\t\tthis._objectCache.set(this.clamp(frame), {\n\t\t\tobjects: normalized.objects,\n\t\t\trawDetections: normalized.rawDetections ?? [],\n\t\t});\n\t\tthis.invalidateSignals();\n\t}\n\n\tpublic getObjectResult(frame: number): {\n\t\tobjects: readonly TrackedObject[];\n\t\trawDetections: readonly DetectedObject[];\n\t} {\n\t\treturn (\n\t\t\tthis.latestAtOrBefore(this._objectCache, frame) ??\n\t\t\tcreateNeutralObjectResult()\n\t\t);\n\t}\n\n\tpublic setMaskResult(frame: number, masks: readonly InstanceMask[]): void {\n\t\tthis._maskCache.set(this.clamp(frame), masks);\n\t\tthis.invalidateSignals();\n\t}\n\n\tpublic getMaskResult(frame: number): readonly InstanceMask[] {\n\t\treturn this.latestAtOrBefore(this._maskCache, frame) ?? [];\n\t}\n\n\tpublic setMatteResult(frame: number, matte: PersonMatte): void {\n\t\tthis._matteCache.set(this.clamp(frame), matte);\n\t\tthis.invalidateSignals();\n\t}\n\n\tpublic getMatteResult(frame: number): PersonMatte | undefined {\n\t\treturn this.latestAtOrBefore(this._matteCache, frame);\n\t}\n\n\t// ── Agent DX snapshot ─────────────────────────────────────────────────\n\n\t/**\n\t * Serializable snapshot of one frame's object / class / mask signals.\n\t * Synchronous — reads only the per-frame caches, never triggers inference.\n\t */\n\tpublic summary(frame: number = frameSignal.value): VisionSummary {\n\t\tconst f = this.clamp(frame);\n\t\tconst res = this.getObjectResult(f);\n\n\t\tconst objects = res.objects.map((o) => ({\n\t\t\ttrackId: o.trackId,\n\t\t\tcategory: o.category,\n\t\t\tscore: o.score,\n\t\t\tcenter: [o.centerX, o.centerY] as [number, number],\n\t\t\tspeed: o.speed,\n\t\t\tactive: o.active,\n\t\t}));\n\n\t\tconst classSet = new Set<string>();\n\t\tfor (const o of res.objects) {\n\t\t\tif (o.active) classSet.add(o.category);\n\t\t}\n\n\t\tconst masks: Record<string, number> = {};\n\t\tfor (const m of this.getMaskResult(f)) {\n\t\t\tmasks[m.category] = (masks[m.category] ?? 0) + 1;\n\t\t}\n\n\t\treturn { frame: f, objects, classes: Array.from(classSet).sort(), masks };\n\t}\n\n\t// ── Tensor builders ───────────────────────────────────────────────────\n\n\t/** Primary person's 17 keypoints as a [17, 3] float32 tensor. */\n\tpublic getPoseLandmarksTensor(frame: number): TensorData {\n\t\tconst person = this.getPoseResult(frame).people[0];\n\t\tconst kpts = person?.keypoints ?? [];\n\t\tconst data = new Float32Array(17 * 3);\n\t\tfor (let i = 0; i < 17; i++) {\n\t\t\tdata[i * 3] = kpts[i]?.x ?? 0.5;\n\t\t\tdata[i * 3 + 1] = kpts[i]?.y ?? 0.5;\n\t\t\tdata[i * 3 + 2] = kpts[i]?.visibility ?? 0;\n\t\t}\n\t\treturn { data, shape: [17, 3], dtype: \"float32\" };\n\t}\n\n\t/** Up to 16 active tracks as [16, 8]: [active, categoryHash, x, y, w, h, vx, vy]. */\n\tpublic getObjectsTensor(frame: number, maxObjects = 16): TensorData {\n\t\tconst res = this.getObjectResult(frame);\n\t\tconst data = new Float32Array(maxObjects * 8);\n\t\tconst count = Math.min(maxObjects, res.objects.length);\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tconst obj = res.objects[i];\n\t\t\tconst off = i * 8;\n\t\t\tlet catHash = 0;\n\t\t\tfor (let c = 0; c < obj.category.length; c++) {\n\t\t\t\tcatHash = (catHash * 31 + obj.category.charCodeAt(c)) & 0xffff;\n\t\t\t}\n\t\t\tdata[off] = obj.active ? 1.0 : 0.0;\n\t\t\tdata[off + 1] = catHash;\n\t\t\tdata[off + 2] = obj.centerX;\n\t\t\tdata[off + 3] = obj.centerY;\n\t\t\tdata[off + 4] = obj.boundingBox.width;\n\t\t\tdata[off + 5] = obj.boundingBox.height;\n\t\t\tdata[off + 6] = obj.velocity.vx;\n\t\t\tdata[off + 7] = obj.velocity.vy;\n\t\t}\n\t\treturn { data, shape: [maxObjects, 8], dtype: \"float32\" };\n\t}\n\n\t/** Per-mask coverage + solidity as [16, 2]. */\n\tpublic getMasksTensor(frame: number, maxMasks = 16): TensorData {\n\t\tconst masks = this.getMaskResult(frame);\n\t\tconst data = new Float32Array(maxMasks * 2);\n\t\tconst count = Math.min(maxMasks, masks.length);\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tconst m = masks[i];\n\t\t\tdata[i * 2] = m.coverage;\n\t\t\tconst box = this.getObjectResult(frame).objects.find(\n\t\t\t\t(o) => o.trackId === m.trackId,\n\t\t\t);\n\t\t\tconst bboxArea = box ? box.boundingBox.width * box.boundingBox.height : 0;\n\t\t\tdata[i * 2 + 1] = bboxArea > 0 ? m.area / bboxArea : 0;\n\t\t}\n\t\treturn { data, shape: [maxMasks, 2], dtype: \"float32\" };\n\t}\n\n\t/** Per-class detection histogram for the frame as [nc] float32 (COCO 80 by default). */\n\tpublic getClassHistogramTensor(frame: number, nc = 80): TensorData {\n\t\tconst data = new Float32Array(nc);\n\t\tfor (const o of this.getObjectResult(frame).objects) {\n\t\t\tif (o.active) {\n\t\t\t\tconst idx = COCO_CLASS_INDEX_BY_NAME.get(o.category.toLowerCase());\n\t\t\t\tif (idx !== undefined) data[idx] += 1;\n\t\t\t}\n\t\t}\n\t\treturn { data, shape: [nc], dtype: \"float32\" };\n\t}\n\n\tprivate clamp(frame: number): number {\n\t\treturn Math.max(0, Math.min(this._totalFrames - 1, Math.round(frame)));\n\t}\n}\n\nexport function createVisionBundle(\n\toptions?: VisionBundleOptions,\n): VisionBundle {\n\treturn new VisionBundle(options);\n}\n\n// ── Module-local constants ──────────────────────────────────────────────────\n\nconst COCO_CLASS_INDEX_BY_NAME = new Map<string, number>(\n\tCOCO_CLASSES.map((name, index) => [name, index]),\n);\n","import type { ObjectTrackSignals } from \"../signals/vision-bundle.js\";\nimport type {\n\tLandmarkCoordinateSignals,\n\tPinToLandmarkOptions,\n\tPinToObjectOptions,\n} from \"../types.js\";\n\nexport function pinNodeToLandmark<\n\tT extends { x?: unknown; y?: unknown; z?: unknown; [key: string]: unknown },\n>(\n\tnode: T,\n\ttarget:\n\t\t| LandmarkCoordinateSignals\n\t\t| { x: number; y: number; z?: number; screenX?: number; screenY?: number },\n\toptions: PinToLandmarkOptions = {},\n): T {\n\tconst offX = options.offsetX ?? 0;\n\tconst offY = options.offsetY ?? 0;\n\tconst offZ = options.offsetZ ?? 0;\n\n\tif (!target || typeof target !== \"object\") {\n\t\treturn node;\n\t}\n\n\t// Check if target provides programmatic signals\n\tif (\n\t\t\"screenX\" in target &&\n\t\ttarget.screenX &&\n\t\ttypeof target.screenX === \"object\"\n\t) {\n\t\tconst signals = target as LandmarkCoordinateSignals;\n\t\tnode.x = offX !== 0 ? signals.screenX.add(offX) : signals.screenX;\n\t\tnode.y = offY !== 0 ? signals.screenY.add(offY) : signals.screenY;\n\t\tnode.z = offZ !== 0 ? signals.z.add(offZ) : signals.z;\n\t} else if (\n\t\t\"x\" in target &&\n\t\ttypeof target.x === \"object\" &&\n\t\ttarget.x !== null\n\t) {\n\t\tconst signals = target as LandmarkCoordinateSignals;\n\t\tnode.x = offX !== 0 ? signals.x.add(offX) : signals.x;\n\t\tnode.y = offY !== 0 ? signals.y.add(offY) : signals.y;\n\t\tnode.z = offZ !== 0 ? signals.z.add(offZ) : signals.z;\n\t} else {\n\t\tconst staticCoord = target as {\n\t\t\tx: number;\n\t\t\ty: number;\n\t\t\tz?: number;\n\t\t\tscreenX?: number;\n\t\t\tscreenY?: number;\n\t\t};\n\t\tnode.x = (staticCoord.screenX ?? staticCoord.x) + offX;\n\t\tnode.y = (staticCoord.screenY ?? staticCoord.y) + offY;\n\t\tnode.z = (staticCoord.z ?? 0) + offZ;\n\t}\n\n\treturn node;\n}\n\nexport function pinNodeToObject<\n\tT extends {\n\t\tx?: unknown;\n\t\ty?: unknown;\n\t\tz?: unknown;\n\t\twidth?: unknown;\n\t\theight?: unknown;\n\t\topacity?: unknown;\n\t\t[key: string]: unknown;\n\t},\n>(\n\tnode: T,\n\ttarget:\n\t\t| ObjectTrackSignals\n\t\t| LandmarkCoordinateSignals\n\t\t| { x: number; y: number; z?: number; screenX?: number; screenY?: number },\n\toptions: PinToObjectOptions = {},\n): T {\n\tif (!target || typeof target !== \"object\") {\n\t\treturn node;\n\t}\n\n\tif (\"anchors\" in target && target.anchors) {\n\t\tconst track = target as ObjectTrackSignals;\n\t\tconst anchorName =\n\t\t\toptions.anchor ??\n\t\t\t(options.matchWidth || options.matchHeight ? \"topLeft\" : \"center\");\n\t\tconst rawAnchor = track.anchors[anchorName] ?? track.center;\n\n\t\tlet resolvedAnchor = rawAnchor;\n\t\tif (options.smoothFrames && options.smoothFrames > 1) {\n\t\t\tresolvedAnchor = {\n\t\t\t\tx: rawAnchor.x.smooth(options.smoothFrames),\n\t\t\t\ty: rawAnchor.y.smooth(options.smoothFrames),\n\t\t\t\tz: rawAnchor.z,\n\t\t\t\tscreenX: rawAnchor.screenX.smooth(options.smoothFrames),\n\t\t\t\tscreenY: rawAnchor.screenY.smooth(options.smoothFrames),\n\t\t\t};\n\t\t}\n\n\t\tif (options.matchWidth) {\n\t\t\tnode.width =\n\t\t\t\toptions.smoothFrames && options.smoothFrames > 1\n\t\t\t\t\t? track.bounds.screenWidth.smooth(options.smoothFrames)\n\t\t\t\t\t: track.bounds.screenWidth;\n\t\t}\n\n\t\tif (options.matchHeight) {\n\t\t\tnode.height =\n\t\t\t\toptions.smoothFrames && options.smoothFrames > 1\n\t\t\t\t\t? track.bounds.screenHeight.smooth(options.smoothFrames)\n\t\t\t\t\t: track.bounds.screenHeight;\n\t\t}\n\n\t\tif (options.hideWhenLost) {\n\t\t\tnode.opacity = track.active;\n\t\t}\n\n\t\treturn pinNodeToLandmark(node, resolvedAnchor, options);\n\t}\n\n\treturn pinNodeToLandmark(\n\t\tnode,\n\t\ttarget as\n\t\t\t| LandmarkCoordinateSignals\n\t\t\t| {\n\t\t\t\t\tx: number;\n\t\t\t\t\ty: number;\n\t\t\t\t\tz?: number;\n\t\t\t\t\tscreenX?: number;\n\t\t\t\t\tscreenY?: number;\n\t\t\t },\n\t\toptions,\n\t);\n}\n","import type { VisionConfig, VisionNodeSpec } from \"@framefields/core\";\nimport type { VisionTask } from \"./model/registry.js\";\nimport {\n\tVisionRunner,\n\ttype VisionRunnerOptions,\n} from \"./runner/vision-runner.js\";\nimport {\n\tVisionBundle,\n\ttype VisionBundleOptions,\n} from \"./signals/vision-bundle.js\";\nimport type { VisionInputSource } from \"./types.js\";\n\n/**\n * Bundle returned by `VisionNode.attach()`: the reactive signals surface plus the lazy lifecycle\n * helpers (all zero-I/O until `runner()` really needs a model).\n */\nexport interface VisionAttachedBundle extends VisionBundle {\n\treadonly node: VisionNodeSpec;\n\t/** Warm the enabled tasks' models/sessions ahead of first use. */\n\tready(): Promise<VisionRunner>;\n\t/** Lazily-created runner (downloads happen on first real inference). */\n\trunner(): VisionRunner;\n\t/** Release this node's runner/sessions. */\n\tclose(): void;\n}\n\n/** Tasks a config turns on; detection is the default when nothing is enabled explicitly. */\nexport function enabledTasks(config: VisionConfig): VisionTask[] {\n\tconst tasks: VisionTask[] = [];\n\tif (config.enableDetection === true) tasks.push(\"detect\");\n\tif (config.enableSegmentation === true) tasks.push(\"segment\");\n\tif (config.enablePose === true) tasks.push(\"pose\");\n\tif (config.enableMatte === true) tasks.push(\"matte\");\n\treturn tasks.length > 0 ? tasks : [\"detect\"];\n}\n\n/**\n * Vision node.\n *\n * LAZY BY CONSTRUCTION: creating a VisionNode performs ZERO I/O — no model downloads, no\n * sessions, no file probes. The first inference call (or an explicit `await vision.ready()`)\n * downloads the required models.\n */\nexport class VisionNode {\n\tpublic readonly id: string;\n\tpublic readonly kind = \"vision\" as const;\n\tpublic readonly source: VisionInputSource;\n\tpublic readonly config: VisionConfig;\n\tpublic readonly vision: VisionBundle;\n\n\tprivate _runner?: VisionRunner;\n\n\t/** Runner construction options (modelsDir, provider, store, …) — injectable for tests/agents. */\n\tprivate readonly _runnerOptions: VisionRunnerOptions;\n\n\tconstructor(\n\t\tsource: VisionInputSource,\n\t\tconfig: VisionConfig = {},\n\t\tbundleOptions: VisionBundleOptions = {},\n\t\trunnerOptions: VisionRunnerOptions = {},\n\t) {\n\t\tthis.id = `vision-${Math.random().toString(36).slice(2, 9)}`;\n\t\tthis.source = source;\n\t\tthis.config = config;\n\t\tthis._runnerOptions = runnerOptions;\n\t\tthis.vision = new VisionBundle({\n\t\t\t...bundleOptions,\n\t\t\tconfig,\n\t\t});\n\t}\n\n\t/** Lazily-created runner; downloads happen on its first inference. */\n\tpublic runner(): VisionRunner {\n\t\tif (!this._runner) {\n\t\t\tconst {\n\t\t\t\tvariant,\n\t\t\t\tconfidence,\n\t\t\t\tclasses,\n\t\t\t\tmodelsDir,\n\t\t\t\tbaseUrl,\n\t\t\t\tmaskThreshold,\n\t\t\t\tfeatherRadius,\n\t\t\t} = this.config;\n\t\t\t// Config values win over injected runner options, but only when set —\n\t\t\t// an explicit undefined must not clobber an injected modelsDir/provider.\n\t\t\tthis._runner = VisionRunner.create({\n\t\t\t\t...this._runnerOptions,\n\t\t\t\t...(variant !== undefined ? { variant } : {}),\n\t\t\t\t...(confidence !== undefined ? { confidence } : {}),\n\t\t\t\t...(classes !== undefined ? { classes } : {}),\n\t\t\t\t...(modelsDir !== undefined ? { modelsDir } : {}),\n\t\t\t\t...(baseUrl !== undefined ? { baseUrl } : {}),\n\t\t\t\t...(maskThreshold !== undefined ? { maskThreshold } : {}),\n\t\t\t\t...(featherRadius !== undefined ? { featherRadius } : {}),\n\t\t\t});\n\t\t}\n\t\treturn this._runner;\n\t}\n\n\t/** Explicit warm-up — downloads the models for the enabled tasks, ahead of first inference. */\n\tpublic async ready(): Promise<VisionRunner> {\n\t\tconst runner = this.runner();\n\t\tawait runner.preload(enabledTasks(this.config));\n\t\treturn runner;\n\t}\n\n\tpublic close(): void {\n\t\tthis._runner?.close();\n\t\tthis._runner = undefined;\n\t}\n\n\tpublic static attach(\n\t\tsource: VisionInputSource,\n\t\tconfig: VisionConfig = {},\n\t\tbundleOptions: VisionBundleOptions = {},\n\t): VisionAttachedBundle {\n\t\tconst node = new VisionNode(source, config, bundleOptions);\n\t\tconst vision = node.vision;\n\n\t\t// AST node for composition graph inclusion, plus the lazy lifecycle helpers.\n\t\tObject.defineProperties(vision, {\n\t\t\tnode: { value: node.toNode(), enumerable: true },\n\t\t\tready: { value: () => node.ready() },\n\t\t\trunner: { value: () => node.runner() },\n\t\t\tclose: { value: () => node.close() },\n\t\t});\n\n\t\treturn vision as VisionAttachedBundle;\n\t}\n\n\tpublic toNode(): VisionNodeSpec {\n\t\treturn {\n\t\t\tid: this.id,\n\t\t\tkind: \"vision\",\n\t\t\tsource: this.source,\n\t\t\tconfig: this.config,\n\t\t};\n\t}\n}\n","export * from \"./analysis/analyze-sequence.js\";\nexport * from \"./decode/preprocess.js\";\nexport * from \"./decode/rtmdet-ins.js\";\nexport * from \"./decode/rtmo.js\";\nexport * from \"./decode/selfie.js\";\nexport * from \"./gpu/pose-skeleton-renderer.js\";\nexport * from \"./gpu/segmentation-texture-pool.js\";\nexport * from \"./model/model-store.js\";\nexport * from \"./model/registry.js\";\nexport * from \"./pose/keypoints.js\";\nexport * from \"./runner/canonical-baselines.js\";\nexport * from \"./runner/vision-runner.js\";\nexport * from \"./runtime/session-provider.js\";\nexport * from \"./segmentation/subject.js\";\nexport * from \"./signals/vision-bundle.js\";\nexport * from \"./spatial/camera-space-transformer.js\";\nexport * from \"./spatial/spatial-pin.js\";\nexport * from \"./tracking/pose-track-matcher.js\";\nexport * from \"./tracking/temporal-object-tracker.js\";\nexport * from \"./types.js\";\nexport { type VisionAttachedBundle, VisionNode } from \"./vision-node.js\";\n"],"mappings":"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"}
|