@camstack/addon-vision 0.1.7 → 0.1.10
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/addons/animal-classifier/index.d.mts +30 -0
- package/dist/addons/animal-classifier/index.d.ts +30 -0
- package/dist/addons/animal-classifier/index.js +822 -999
- package/dist/addons/animal-classifier/index.js.map +1 -1
- package/dist/addons/animal-classifier/index.mjs +7 -242
- package/dist/addons/animal-classifier/index.mjs.map +1 -1
- package/dist/addons/audio-classification/index.d.mts +36 -0
- package/dist/addons/audio-classification/index.d.ts +36 -0
- package/dist/addons/audio-classification/index.js +378 -501
- package/dist/addons/audio-classification/index.js.map +1 -1
- package/dist/addons/audio-classification/index.mjs +4 -224
- package/dist/addons/audio-classification/index.mjs.map +1 -1
- package/dist/addons/bird-global-classifier/index.d.mts +31 -0
- package/dist/addons/bird-global-classifier/index.d.ts +31 -0
- package/dist/addons/bird-global-classifier/index.js +825 -1002
- package/dist/addons/bird-global-classifier/index.js.map +1 -1
- package/dist/addons/bird-global-classifier/index.mjs +7 -248
- package/dist/addons/bird-global-classifier/index.mjs.map +1 -1
- package/dist/addons/bird-nabirds-classifier/index.d.mts +33 -0
- package/dist/addons/bird-nabirds-classifier/index.d.ts +33 -0
- package/dist/addons/bird-nabirds-classifier/index.js +825 -1002
- package/dist/addons/bird-nabirds-classifier/index.js.map +1 -1
- package/dist/addons/bird-nabirds-classifier/index.mjs +7 -289
- package/dist/addons/bird-nabirds-classifier/index.mjs.map +1 -1
- package/dist/addons/face-detection/index.d.mts +29 -0
- package/dist/addons/face-detection/index.d.ts +29 -0
- package/dist/addons/face-detection/index.js +934 -1196
- package/dist/addons/face-detection/index.js.map +1 -1
- package/dist/addons/face-detection/index.mjs +7 -227
- package/dist/addons/face-detection/index.mjs.map +1 -1
- package/dist/addons/face-recognition/index.d.mts +29 -0
- package/dist/addons/face-recognition/index.d.ts +29 -0
- package/dist/addons/face-recognition/index.js +807 -1003
- package/dist/addons/face-recognition/index.js.map +1 -1
- package/dist/addons/face-recognition/index.mjs +6 -197
- package/dist/addons/face-recognition/index.mjs.map +1 -1
- package/dist/addons/motion-detection/index.d.mts +28 -0
- package/dist/addons/motion-detection/index.d.ts +28 -0
- package/dist/addons/motion-detection/index.js +111 -214
- package/dist/addons/motion-detection/index.js.map +1 -1
- package/dist/addons/motion-detection/index.mjs +9 -12
- package/dist/addons/motion-detection/index.mjs.map +1 -1
- package/dist/addons/object-detection/index.d.mts +31 -0
- package/dist/addons/object-detection/index.d.ts +31 -0
- package/dist/addons/object-detection/index.js +1082 -1287
- package/dist/addons/object-detection/index.js.map +1 -1
- package/dist/addons/object-detection/index.mjs +7 -373
- package/dist/addons/object-detection/index.mjs.map +1 -1
- package/dist/addons/plate-detection/index.d.mts +30 -0
- package/dist/addons/plate-detection/index.d.ts +30 -0
- package/dist/addons/plate-detection/index.js +868 -1075
- package/dist/addons/plate-detection/index.js.map +1 -1
- package/dist/addons/plate-detection/index.mjs +7 -230
- package/dist/addons/plate-detection/index.mjs.map +1 -1
- package/dist/addons/plate-recognition/index.d.mts +31 -0
- package/dist/addons/plate-recognition/index.d.ts +31 -0
- package/dist/addons/plate-recognition/index.js +505 -684
- package/dist/addons/plate-recognition/index.js.map +1 -1
- package/dist/addons/plate-recognition/index.mjs +5 -244
- package/dist/addons/plate-recognition/index.mjs.map +1 -1
- package/dist/addons/segmentation-refiner/index.d.mts +30 -0
- package/dist/addons/segmentation-refiner/index.d.ts +30 -0
- package/dist/addons/segmentation-refiner/index.js +790 -967
- package/dist/addons/segmentation-refiner/index.js.map +1 -1
- package/dist/addons/segmentation-refiner/index.mjs +17 -21
- package/dist/addons/segmentation-refiner/index.mjs.map +1 -1
- package/dist/addons/vehicle-classifier/index.d.mts +31 -0
- package/dist/addons/vehicle-classifier/index.d.ts +31 -0
- package/dist/addons/vehicle-classifier/index.js +410 -581
- package/dist/addons/vehicle-classifier/index.js.map +1 -1
- package/dist/addons/vehicle-classifier/index.mjs +16 -20
- package/dist/addons/vehicle-classifier/index.mjs.map +1 -1
- package/dist/chunk-22BHCDT5.mjs +101 -0
- package/dist/{chunk-WG66JYYW.mjs.map → chunk-22BHCDT5.mjs.map} +1 -1
- package/dist/chunk-2IOKI4ES.mjs +335 -0
- package/dist/{chunk-PIFS7AIT.mjs.map → chunk-2IOKI4ES.mjs.map} +1 -1
- package/dist/chunk-7DYHXUPZ.mjs +36 -0
- package/dist/{chunk-BS4DKYGN.mjs.map → chunk-7DYHXUPZ.mjs.map} +1 -1
- package/dist/chunk-BJTO5JO5.mjs +11 -0
- package/dist/chunk-BP7H4NFS.mjs +412 -0
- package/dist/{chunk-MGT6RUVX.mjs.map → chunk-BP7H4NFS.mjs.map} +1 -1
- package/dist/chunk-BR2FPGOX.mjs +98 -0
- package/dist/{chunk-YYDM6V2F.mjs.map → chunk-BR2FPGOX.mjs.map} +1 -1
- package/dist/chunk-D6WEHN33.mjs +276 -0
- package/dist/chunk-D6WEHN33.mjs.map +1 -0
- package/dist/chunk-DRYFGARD.mjs +289 -0
- package/dist/chunk-DRYFGARD.mjs.map +1 -0
- package/dist/chunk-DUN6XU3N.mjs +72 -0
- package/dist/{chunk-XD7WGXHZ.mjs.map → chunk-DUN6XU3N.mjs.map} +1 -1
- package/dist/chunk-ESLHNWWE.mjs +387 -0
- package/dist/chunk-ESLHNWWE.mjs.map +1 -0
- package/dist/chunk-JUQEW6ON.mjs +256 -0
- package/dist/chunk-JUQEW6ON.mjs.map +1 -0
- package/dist/chunk-KUO2BVFY.mjs +90 -0
- package/dist/{chunk-DE7I3VHO.mjs.map → chunk-KUO2BVFY.mjs.map} +1 -1
- package/dist/chunk-R5J3WAUI.mjs +645 -0
- package/dist/chunk-R5J3WAUI.mjs.map +1 -0
- package/dist/chunk-XZ6ZMXXU.mjs +39 -0
- package/dist/{chunk-K36R6HWY.mjs.map → chunk-XZ6ZMXXU.mjs.map} +1 -1
- package/dist/chunk-YPU4WTXZ.mjs +269 -0
- package/dist/chunk-YPU4WTXZ.mjs.map +1 -0
- package/dist/chunk-YUCD2TFH.mjs +242 -0
- package/dist/chunk-YUCD2TFH.mjs.map +1 -0
- package/dist/chunk-ZTJENCFC.mjs +379 -0
- package/dist/chunk-ZTJENCFC.mjs.map +1 -0
- package/dist/chunk-ZWYXXCXP.mjs +248 -0
- package/dist/chunk-ZWYXXCXP.mjs.map +1 -0
- package/dist/index.d.mts +183 -0
- package/dist/index.d.ts +183 -0
- package/dist/index.js +3930 -4449
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +250 -2698
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
- package/dist/chunk-2YMA6QOV.mjs +0 -193
- package/dist/chunk-2YMA6QOV.mjs.map +0 -1
- package/dist/chunk-3IIFBJCD.mjs +0 -45
- package/dist/chunk-BS4DKYGN.mjs +0 -48
- package/dist/chunk-DE7I3VHO.mjs +0 -106
- package/dist/chunk-F6D2OZ36.mjs +0 -89
- package/dist/chunk-F6D2OZ36.mjs.map +0 -1
- package/dist/chunk-GAOIFQDX.mjs +0 -59
- package/dist/chunk-GAOIFQDX.mjs.map +0 -1
- package/dist/chunk-HUIX2XVR.mjs +0 -159
- package/dist/chunk-HUIX2XVR.mjs.map +0 -1
- package/dist/chunk-K36R6HWY.mjs +0 -51
- package/dist/chunk-MBTAI3WE.mjs +0 -78
- package/dist/chunk-MBTAI3WE.mjs.map +0 -1
- package/dist/chunk-MGT6RUVX.mjs +0 -423
- package/dist/chunk-PIFS7AIT.mjs +0 -446
- package/dist/chunk-WG66JYYW.mjs +0 -116
- package/dist/chunk-XD7WGXHZ.mjs +0 -82
- package/dist/chunk-YYDM6V2F.mjs +0 -113
- package/dist/chunk-ZK7P3TZN.mjs +0 -286
- package/dist/chunk-ZK7P3TZN.mjs.map +0 -1
- /package/dist/{chunk-3IIFBJCD.mjs.map → chunk-BJTO5JO5.mjs.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/catalogs/object-detection-models.ts","../../../src/catalogs/segmentation-models.ts","../../../src/shared/image-utils.ts","../../../src/shared/postprocess/yolo.ts","../../../src/shared/postprocess/yolo-seg.ts","../../../src/shared/node-engine.ts","../../../src/shared/python-engine.ts","../../../src/shared/engine-resolver.ts","../../../src/addons/object-detection/index.ts"],"sourcesContent":["import type { ModelCatalogEntry } from '@camstack/types'\nimport { hfModelUrl, COCO_80_LABELS } from '@camstack/types'\n\nconst HF_REPO = 'camstack/camstack-models'\n\n/** Standard files inside every .mlpackage directory bundle */\nexport const MLPACKAGE_FILES = [\n 'Manifest.json',\n 'Data/com.apple.CoreML/model.mlmodel',\n 'Data/com.apple.CoreML/weights/weight.bin',\n] as const\n\nexport const OBJECT_DETECTION_MODELS: readonly ModelCatalogEntry[] = [\n // ── YOLOv8 ──────────────────────────────────────────────────────\n {\n id: 'yolov8n',\n name: 'YOLOv8 Nano',\n description: 'YOLOv8 Nano — fastest, smallest object detection model',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/onnx/camstack-yolov8n.onnx'),\n sizeMB: 12,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/coreml/camstack-yolov8n.mlpackage'),\n sizeMB: 6,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/openvino/camstack-yolov8n.xml'),\n sizeMB: 7,\n runtimes: ['python'],\n },\n tflite: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/tflite/camstack-yolov8n_float32.tflite'),\n sizeMB: 12,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'yolov8s',\n name: 'YOLOv8 Small',\n description: 'YOLOv8 Small — balanced speed and accuracy',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/onnx/camstack-yolov8s.onnx'),\n sizeMB: 43,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/coreml/camstack-yolov8s.mlpackage'),\n sizeMB: 21,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/openvino/camstack-yolov8s.xml'),\n sizeMB: 22,\n runtimes: ['python'],\n },\n tflite: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/tflite/camstack-yolov8s_float32.tflite'),\n sizeMB: 43,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'yolov8s-relu',\n name: 'YOLOv8 Small ReLU',\n description: 'YOLOv8 Small with ReLU activation — better hardware compatibility',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/onnx/camstack-yolov8s-relu.onnx'),\n sizeMB: 43,\n },\n },\n },\n {\n id: 'yolov8m',\n name: 'YOLOv8 Medium',\n description: 'YOLOv8 Medium — higher accuracy, moderate size',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/onnx/camstack-yolov8m.onnx'),\n sizeMB: 99,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/coreml/camstack-yolov8m.mlpackage'),\n sizeMB: 49,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/openvino/camstack-yolov8m.xml'),\n sizeMB: 50,\n runtimes: ['python'],\n },\n tflite: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/tflite/camstack-yolov8m_float32.tflite'),\n sizeMB: 99,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'yolov8l',\n name: 'YOLOv8 Large',\n description: 'YOLOv8 Large — high-accuracy large model',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/onnx/camstack-yolov8l.onnx'),\n sizeMB: 167,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/coreml/camstack-yolov8l.mlpackage'),\n sizeMB: 83,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/openvino/camstack-yolov8l.xml'),\n sizeMB: 84,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'yolov8x',\n name: 'YOLOv8 Extra-Large',\n description: 'YOLOv8 Extra-Large — maximum accuracy',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/onnx/camstack-yolov8x.onnx'),\n sizeMB: 260,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/coreml/camstack-yolov8x.mlpackage'),\n sizeMB: 130,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/openvino/camstack-yolov8x.xml'),\n sizeMB: 131,\n runtimes: ['python'],\n },\n },\n },\n\n // ── YOLOv9 ──────────────────────────────────────────────────────\n {\n id: 'yolov9t',\n name: 'YOLOv9 Tiny',\n description: 'YOLOv9 Tiny — ultra-lightweight next-gen detector',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov9/onnx/camstack-yolov9t.onnx'),\n sizeMB: 8,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov9/coreml/camstack-yolov9t.mlpackage'),\n sizeMB: 4,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov9/openvino/camstack-yolov9t.xml'),\n sizeMB: 6,\n runtimes: ['python'],\n },\n tflite: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov9/tflite/camstack-yolov9t_float32.tflite'),\n sizeMB: 8,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'yolov9s',\n name: 'YOLOv9 Small',\n description: 'YOLOv9 Small — improved efficiency over YOLOv8s',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov9/onnx/camstack-yolov9s.onnx'),\n sizeMB: 28,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov9/coreml/camstack-yolov9s.mlpackage'),\n sizeMB: 14,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov9/openvino/camstack-yolov9s.xml'),\n sizeMB: 16,\n runtimes: ['python'],\n },\n tflite: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov9/tflite/camstack-yolov9s_float32.tflite'),\n sizeMB: 28,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'yolov9c',\n name: 'YOLOv9 C',\n description: 'YOLOv9 C — high-accuracy compact model',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov9/onnx/camstack-yolov9c.onnx'),\n sizeMB: 97,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov9/coreml/camstack-yolov9c.mlpackage'),\n sizeMB: 48,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov9/openvino/camstack-yolov9c.xml'),\n sizeMB: 49,\n runtimes: ['python'],\n },\n tflite: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov9/tflite/camstack-yolov9c_float32.tflite'),\n sizeMB: 97,\n runtimes: ['python'],\n },\n },\n },\n\n // ── YOLO11 ────────────────────────────────────────────────────\n {\n id: 'yolo11n',\n name: 'YOLO11 Nano',\n description: 'YOLO11 Nano — fastest, smallest YOLO11 detection model (mAP 39.5)',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/onnx/camstack-yolo11n.onnx'),\n sizeMB: 10,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/coreml/camstack-yolo11n.mlpackage'),\n sizeMB: 5,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/openvino/camstack-yolo11n.xml'),\n sizeMB: 5,\n runtimes: ['python'],\n },\n tflite: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/tflite/camstack-yolo11n_float32.tflite'),\n sizeMB: 10,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'yolo11s',\n name: 'YOLO11 Small',\n description: 'YOLO11 Small — balanced speed and accuracy (mAP 47.0)',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/onnx/camstack-yolo11s.onnx'),\n sizeMB: 36,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/coreml/camstack-yolo11s.mlpackage'),\n sizeMB: 18,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/openvino/camstack-yolo11s.xml'),\n sizeMB: 18,\n runtimes: ['python'],\n },\n tflite: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/tflite/camstack-yolo11s_float32.tflite'),\n sizeMB: 36,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'yolo11m',\n name: 'YOLO11 Medium',\n description: 'YOLO11 Medium — higher accuracy, moderate size (mAP 51.5)',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/onnx/camstack-yolo11m.onnx'),\n sizeMB: 77,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/coreml/camstack-yolo11m.mlpackage'),\n sizeMB: 39,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/openvino/camstack-yolo11m.xml'),\n sizeMB: 39,\n runtimes: ['python'],\n },\n tflite: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/tflite/camstack-yolo11m_float32.tflite'),\n sizeMB: 77,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'yolo11l',\n name: 'YOLO11 Large',\n description: 'YOLO11 Large — high-accuracy large model (mAP 53.4)',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/onnx/camstack-yolo11l.onnx'),\n sizeMB: 97,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/coreml/camstack-yolo11l.mlpackage'),\n sizeMB: 49,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/openvino/camstack-yolo11l.xml'),\n sizeMB: 49,\n runtimes: ['python'],\n },\n tflite: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/tflite/camstack-yolo11l_float32.tflite'),\n sizeMB: 97,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'yolo11x',\n name: 'YOLO11 Extra-Large',\n description: 'YOLO11 Extra-Large — maximum accuracy (mAP 54.7)',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/onnx/camstack-yolo11x.onnx'),\n sizeMB: 218,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/coreml/camstack-yolo11x.mlpackage'),\n sizeMB: 109,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/openvino/camstack-yolo11x.xml'),\n sizeMB: 109,\n runtimes: ['python'],\n },\n tflite: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/tflite/camstack-yolo11x_float32.tflite'),\n sizeMB: 218,\n runtimes: ['python'],\n },\n },\n },\n] as const\n","import type { ModelCatalogEntry } from '@camstack/types'\nimport { hfModelUrl, COCO_80_LABELS } from '@camstack/types'\nimport { MLPACKAGE_FILES } from './object-detection-models.js'\n\nconst HF_REPO = 'camstack/camstack-models'\n\nexport const SEGMENTATION_MODELS: readonly ModelCatalogEntry[] = [\n // ── YOLO11-seg ───────────────────────────────────────────────\n {\n id: 'yolo11n-seg',\n name: 'YOLO11 Nano Segmentation',\n description: 'YOLO11 Nano — fastest, smallest YOLO11 instance segmentation model',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolo11-seg/onnx/camstack-yolo11n-seg.onnx'),\n sizeMB: 11,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolo11-seg/coreml/camstack-yolo11n-seg.mlpackage'),\n sizeMB: 6,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolo11-seg/openvino/camstack-yolo11n-seg.xml'),\n sizeMB: 6,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'yolo11s-seg',\n name: 'YOLO11 Small Segmentation',\n description: 'YOLO11 Small — balanced speed and accuracy for instance segmentation',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolo11-seg/onnx/camstack-yolo11s-seg.onnx'),\n sizeMB: 39,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolo11-seg/coreml/camstack-yolo11s-seg.mlpackage'),\n sizeMB: 20,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolo11-seg/openvino/camstack-yolo11s-seg.xml'),\n sizeMB: 20,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'yolo11m-seg',\n name: 'YOLO11 Medium Segmentation',\n description: 'YOLO11 Medium — higher accuracy instance segmentation',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolo11-seg/onnx/camstack-yolo11m-seg.onnx'),\n sizeMB: 86,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolo11-seg/coreml/camstack-yolo11m-seg.mlpackage'),\n sizeMB: 43,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolo11-seg/openvino/camstack-yolo11m-seg.xml'),\n sizeMB: 43,\n runtimes: ['python'],\n },\n },\n },\n\n // ── YOLOv8-seg — CoreML supported ─────────────────────────────\n {\n id: 'yolov8n-seg',\n name: 'YOLOv8 Nano Segmentation',\n description: 'YOLOv8 Nano — fastest, smallest YOLOv8 instance segmentation model',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolov8-seg/onnx/camstack-yolov8n-seg.onnx'),\n sizeMB: 13,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolov8-seg/coreml/camstack-yolov8n-seg.mlpackage'),\n sizeMB: 7,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolov8-seg/openvino/camstack-yolov8n-seg.xml'),\n sizeMB: 7,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'yolov8s-seg',\n name: 'YOLOv8 Small Segmentation',\n description: 'YOLOv8 Small — balanced speed and accuracy for instance segmentation',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolov8-seg/onnx/camstack-yolov8s-seg.onnx'),\n sizeMB: 45,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolov8-seg/coreml/camstack-yolov8s-seg.mlpackage'),\n sizeMB: 23,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolov8-seg/openvino/camstack-yolov8s-seg.xml'),\n sizeMB: 23,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'yolov8m-seg',\n name: 'YOLOv8 Medium Segmentation',\n description: 'YOLOv8 Medium — higher accuracy instance segmentation',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolov8-seg/onnx/camstack-yolov8m-seg.onnx'),\n sizeMB: 104,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolov8-seg/coreml/camstack-yolov8m-seg.mlpackage'),\n sizeMB: 52,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolov8-seg/openvino/camstack-yolov8m-seg.xml'),\n sizeMB: 53,\n runtimes: ['python'],\n },\n },\n },\n] as const\n","import sharp from 'sharp'\nimport type { BoundingBox } from '@camstack/types'\n\n/** Decode JPEG to raw RGB pixels */\nexport async function jpegToRgb(\n jpeg: Buffer,\n): Promise<{ data: Buffer; width: number; height: number }> {\n const { data, info } = await sharp(jpeg)\n .removeAlpha()\n .raw()\n .toBuffer({ resolveWithObject: true })\n return { data, width: info.width, height: info.height }\n}\n\n/** Crop a region from a JPEG buffer */\nexport async function cropRegion(jpeg: Buffer, roi: BoundingBox): Promise<Buffer> {\n return sharp(jpeg)\n .extract({\n left: Math.round(roi.x),\n top: Math.round(roi.y),\n width: Math.round(roi.w),\n height: Math.round(roi.h),\n })\n .jpeg()\n .toBuffer()\n}\n\n/** Letterbox resize for YOLO: resize preserving aspect ratio, pad to square */\nexport async function letterbox(\n jpeg: Buffer,\n targetSize: number,\n): Promise<{\n data: Float32Array\n scale: number\n padX: number\n padY: number\n originalWidth: number\n originalHeight: number\n}> {\n const meta = await sharp(jpeg).metadata()\n const originalWidth = meta.width ?? 0\n const originalHeight = meta.height ?? 0\n\n const scale = Math.min(targetSize / originalWidth, targetSize / originalHeight)\n const scaledWidth = Math.round(originalWidth * scale)\n const scaledHeight = Math.round(originalHeight * scale)\n\n const padX = Math.floor((targetSize - scaledWidth) / 2)\n const padY = Math.floor((targetSize - scaledHeight) / 2)\n\n const { data } = await sharp(jpeg)\n .resize(scaledWidth, scaledHeight)\n .extend({\n top: padY,\n bottom: targetSize - scaledHeight - padY,\n left: padX,\n right: targetSize - scaledWidth - padX,\n background: { r: 114, g: 114, b: 114 },\n })\n .removeAlpha()\n .raw()\n .toBuffer({ resolveWithObject: true })\n\n // Convert HWC uint8 to CHW float [0,1]\n const numPixels = targetSize * targetSize\n const float32 = new Float32Array(3 * numPixels)\n for (let i = 0; i < numPixels; i++) {\n const srcBase = i * 3\n float32[0 * numPixels + i] = (data[srcBase]! / 255)\n float32[1 * numPixels + i] = (data[srcBase + 1]! / 255)\n float32[2 * numPixels + i] = (data[srcBase + 2]! / 255)\n }\n\n return { data: float32, scale, padX, padY, originalWidth, originalHeight }\n}\n\n/** Resize and normalize to Float32Array */\nexport async function resizeAndNormalize(\n jpeg: Buffer,\n targetWidth: number,\n targetHeight: number,\n normalization: 'zero-one' | 'imagenet' | 'none',\n layout: 'nchw' | 'nhwc',\n): Promise<Float32Array> {\n const { data } = await sharp(jpeg)\n .resize(targetWidth, targetHeight, { fit: 'fill' })\n .removeAlpha()\n .raw()\n .toBuffer({ resolveWithObject: true })\n\n const numPixels = targetWidth * targetHeight\n const float32 = new Float32Array(3 * numPixels)\n\n // ImageNet mean and std per channel\n const mean = [0.485, 0.456, 0.406]\n const std = [0.229, 0.224, 0.225]\n\n if (layout === 'nchw') {\n for (let i = 0; i < numPixels; i++) {\n const srcBase = i * 3\n for (let c = 0; c < 3; c++) {\n const raw = data[srcBase + c]! / 255\n let val: number\n if (normalization === 'zero-one') {\n val = raw\n } else if (normalization === 'imagenet') {\n val = (raw - mean[c]!) / std[c]!\n } else {\n val = data[srcBase + c]!\n }\n float32[c * numPixels + i] = val\n }\n }\n } else {\n // nhwc\n for (let i = 0; i < numPixels; i++) {\n const srcBase = i * 3\n for (let c = 0; c < 3; c++) {\n const raw = data[srcBase + c]! / 255\n let val: number\n if (normalization === 'zero-one') {\n val = raw\n } else if (normalization === 'imagenet') {\n val = (raw - mean[c]!) / std[c]!\n } else {\n val = data[srcBase + c]!\n }\n float32[i * 3 + c] = val\n }\n }\n }\n\n return float32\n}\n\n/** Convert raw RGB to grayscale Uint8Array */\nexport function rgbToGrayscale(rgb: Buffer, width: number, height: number): Uint8Array {\n const numPixels = width * height\n const gray = new Uint8Array(numPixels)\n for (let i = 0; i < numPixels; i++) {\n const r = rgb[i * 3]!\n const g = rgb[i * 3 + 1]!\n const b = rgb[i * 3 + 2]!\n // BT.601 luma\n gray[i] = Math.round(0.299 * r + 0.587 * g + 0.114 * b)\n }\n return gray\n}\n","import type { SpatialDetection, BoundingBox } from '@camstack/types'\n\nexport interface YoloPostprocessOptions {\n readonly confidence: number\n readonly iouThreshold: number\n readonly labels: readonly string[]\n readonly scale: number\n readonly padX: number\n readonly padY: number\n readonly originalWidth: number\n readonly originalHeight: number\n}\n\n/** Calculate IoU between two bounding boxes */\nexport function iou(a: BoundingBox, b: BoundingBox): number {\n const ax1 = a.x\n const ay1 = a.y\n const ax2 = a.x + a.w\n const ay2 = a.y + a.h\n\n const bx1 = b.x\n const by1 = b.y\n const bx2 = b.x + b.w\n const by2 = b.y + b.h\n\n const interX1 = Math.max(ax1, bx1)\n const interY1 = Math.max(ay1, by1)\n const interX2 = Math.min(ax2, bx2)\n const interY2 = Math.min(ay2, by2)\n\n const interW = Math.max(0, interX2 - interX1)\n const interH = Math.max(0, interY2 - interY1)\n const interArea = interW * interH\n\n if (interArea === 0) return 0\n\n const areaA = a.w * a.h\n const areaB = b.w * b.h\n const unionArea = areaA + areaB - interArea\n\n return unionArea === 0 ? 0 : interArea / unionArea\n}\n\n/** Non-maximum suppression — returns indices of kept boxes (sorted by score desc) */\nexport function nms(\n boxes: ReadonlyArray<{ readonly bbox: BoundingBox; readonly score: number }>,\n iouThreshold: number,\n): number[] {\n const indices = boxes\n .map((_, i) => i)\n .sort((a, b) => (boxes[b]!.score) - (boxes[a]!.score))\n\n const kept: number[] = []\n const suppressed = new Set<number>()\n\n for (const idx of indices) {\n if (suppressed.has(idx)) continue\n kept.push(idx)\n for (const other of indices) {\n if (other === idx || suppressed.has(other)) continue\n if (iou(boxes[idx]!.bbox, boxes[other]!.bbox) > iouThreshold) {\n suppressed.add(other)\n }\n }\n }\n\n return kept\n}\n\n/** Full YOLO v8/v9 postprocessing: filter → NMS → scale back to original coords */\nexport function yoloPostprocess(\n output: Float32Array,\n numClasses: number,\n numBoxes: number,\n options: YoloPostprocessOptions,\n): SpatialDetection[] {\n const { confidence, iouThreshold, labels, scale, padX, padY, originalWidth, originalHeight } = options\n\n interface Candidate {\n readonly bbox: BoundingBox\n readonly score: number\n readonly classIdx: number\n }\n\n const candidates: Candidate[] = []\n\n for (let i = 0; i < numBoxes; i++) {\n // YOLO v8/v9 output layout: [1, 4+numClasses, numBoxes] stored row-major\n const cx = output[0 * numBoxes + i]!\n const cy = output[1 * numBoxes + i]!\n const w = output[2 * numBoxes + i]!\n const h = output[3 * numBoxes + i]!\n\n let bestScore = -Infinity\n let bestClass = 0\n\n for (let j = 0; j < numClasses; j++) {\n const score = output[(4 + j) * numBoxes + i]!\n if (score > bestScore) {\n bestScore = score\n bestClass = j\n }\n }\n\n if (bestScore < confidence) continue\n\n // Convert cx,cy,w,h to x,y,w,h (top-left origin)\n const bbox: BoundingBox = {\n x: cx - w / 2,\n y: cy - h / 2,\n w,\n h,\n }\n\n candidates.push({ bbox, score: bestScore, classIdx: bestClass })\n }\n\n if (candidates.length === 0) return []\n\n const keptIndices = nms(candidates, iouThreshold)\n\n return keptIndices.map((idx) => {\n const { bbox, score, classIdx } = candidates[idx]!\n const label = labels[classIdx] ?? String(classIdx)\n\n // Transform from letterbox coords back to original image coords\n const x = Math.max(0, Math.min(originalWidth, (bbox.x - padX) / scale))\n const y = Math.max(0, Math.min(originalHeight, (bbox.y - padY) / scale))\n const x2 = Math.max(0, Math.min(originalWidth, (bbox.x + bbox.w - padX) / scale))\n const y2 = Math.max(0, Math.min(originalHeight, (bbox.y + bbox.h - padY) / scale))\n\n const finalBbox: BoundingBox = { x, y, w: x2 - x, h: y2 - y }\n\n return {\n class: label,\n originalClass: label,\n score,\n bbox: finalBbox,\n } satisfies SpatialDetection\n })\n}\n","import type { SpatialDetection, BoundingBox } from '@camstack/types'\nimport { nms, iou as _iou } from './yolo.js'\nimport type { YoloPostprocessOptions } from './yolo.js'\n\nexport interface YoloSegOutput {\n /** Detection output: [1, 4 + numClasses + numMaskCoeffs, numBoxes] (row-major, batch dim stripped) */\n readonly detectionOutput: Float32Array\n /** Prototype masks: [1, numMaskCoeffs, maskH, maskW] (batch dim stripped) */\n readonly protoOutput: Float32Array\n readonly numClasses: number\n readonly numBoxes: number\n /** Number of mask prototype coefficients per detection (typically 32) */\n readonly numMaskCoeffs: number\n /** Height of prototype mask grid (typically 160) */\n readonly maskHeight: number\n /** Width of prototype mask grid (typically 160) */\n readonly maskWidth: number\n}\n\nexport interface YoloSegPostprocessOptions extends YoloPostprocessOptions {\n /** Binary mask threshold — pixels above this value become 255, others 0 (default: 0.5) */\n readonly maskThreshold?: number\n}\n\n/** Sigmoid activation: σ(x) = 1 / (1 + e^-x) */\nexport function sigmoid(x: number): number {\n return 1 / (1 + Math.exp(-x))\n}\n\n/**\n * Compute instance segmentation mask for a single detection.\n *\n * @param coeffs [numMaskCoeffs] mask coefficients for this detection\n * @param protos [numMaskCoeffs × maskH × maskW] prototype masks (flat, row-major)\n * @param numMaskCoeffs number of prototype channels (e.g. 32)\n * @param maskH prototype grid height (e.g. 160)\n * @param maskW prototype grid width (e.g. 160)\n * @returns [maskH × maskW] sigmoid-activated raw mask values in [0, 1]\n */\nexport function computeRawMask(\n coeffs: Float32Array,\n protos: Float32Array,\n numMaskCoeffs: number,\n maskH: number,\n maskW: number,\n): Float32Array {\n const maskSize = maskH * maskW\n const rawMask = new Float32Array(maskSize)\n\n // mask_raw[y * maskW + x] = sum_k( coeffs[k] * protos[k * maskSize + y * maskW + x] )\n // Then apply sigmoid element-wise.\n for (let px = 0; px < maskSize; px++) {\n let val = 0\n for (let k = 0; k < numMaskCoeffs; k++) {\n val += (coeffs[k] ?? 0) * (protos[k * maskSize + px] ?? 0)\n }\n rawMask[px] = sigmoid(val)\n }\n\n return rawMask\n}\n\n/**\n * Crop a flat [maskH × maskW] mask to a bounding box region (in mask coordinate space),\n * threshold to binary, and return the cropped Uint8Array along with its dimensions.\n *\n * @param rawMask [maskH × maskW] sigmoid-activated values in [0, 1]\n * @param maskH full mask grid height\n * @param maskW full mask grid width\n * @param bbox detection bounding box in the inference input space (e.g. 640×640 letterboxed)\n * @param maskThreshold threshold above which a pixel is considered foreground (default 0.5)\n * @param maskScale ratio of mask resolution to inference resolution (e.g. 160/640 = 0.25)\n * @returns { data: Uint8Array, width, height } of the cropped binary mask\n */\nexport function cropAndThresholdMask(\n rawMask: Float32Array,\n maskH: number,\n maskW: number,\n bbox: BoundingBox,\n maskThreshold: number,\n maskScale: number,\n): { readonly data: Uint8Array; readonly width: number; readonly height: number } {\n const cropX1 = Math.max(0, Math.floor(bbox.x * maskScale))\n const cropY1 = Math.max(0, Math.floor(bbox.y * maskScale))\n const cropX2 = Math.min(maskW, Math.ceil((bbox.x + bbox.w) * maskScale))\n const cropY2 = Math.min(maskH, Math.ceil((bbox.y + bbox.h) * maskScale))\n\n const cropW = Math.max(1, cropX2 - cropX1)\n const cropH = Math.max(1, cropY2 - cropY1)\n\n const data = new Uint8Array(cropW * cropH)\n\n for (let row = 0; row < cropH; row++) {\n const srcRow = cropY1 + row\n for (let col = 0; col < cropW; col++) {\n const srcCol = cropX1 + col\n const srcIdx = srcRow * maskW + srcCol\n data[row * cropW + col] = (rawMask[srcIdx] ?? 0) > maskThreshold ? 255 : 0\n }\n }\n\n return { data, width: cropW, height: cropH }\n}\n\n/**\n * YOLO-seg postprocessing: run detection filtering + NMS, then decode instance masks.\n *\n * The seg detection tensor has layout [1, 4 + numClasses + numMaskCoeffs, numBoxes]:\n * rows 0–3 : cx, cy, w, h\n * rows 4 to 4+C-1 : class scores\n * rows 4+C to end : mask coefficients (32)\n *\n * Steps:\n * 1. Filter boxes by confidence threshold, collecting mask coefficients per candidate.\n * 2. Run NMS across all candidates.\n * 3. For each surviving detection, compute the instance mask and attach it.\n */\nexport function yoloSegPostprocess(\n segOutput: YoloSegOutput,\n options: YoloSegPostprocessOptions,\n): SpatialDetection[] {\n const {\n detectionOutput,\n protoOutput,\n numClasses,\n numBoxes,\n numMaskCoeffs,\n maskHeight,\n maskWidth,\n } = segOutput\n\n const {\n confidence,\n iouThreshold,\n labels,\n scale,\n padX,\n padY,\n originalWidth,\n originalHeight,\n maskThreshold = 0.5,\n } = options\n\n // The mask resolution to inference resolution scale factor (e.g. 160/640 = 0.25)\n // We derive the inference size from scale/pad context: the letterboxed input is typically 640×640\n // but we receive coordinates in that space already, so we use maskHeight / inferH.\n // Since all YOLO-seg models use 640×640 input and 160×160 proto, the ratio is always 160/640.\n // We compute it generically from the known prototype dims + fixed YOLO input of 640.\n const yoloInputSize = 640\n const maskScale = maskHeight / yoloInputSize\n\n interface Candidate {\n readonly bbox: BoundingBox\n readonly score: number\n readonly classIdx: number\n readonly coeffs: Float32Array\n }\n\n const candidates: Candidate[] = []\n\n for (let i = 0; i < numBoxes; i++) {\n const cx = detectionOutput[0 * numBoxes + i] ?? 0\n const cy = detectionOutput[1 * numBoxes + i] ?? 0\n const w = detectionOutput[2 * numBoxes + i] ?? 0\n const h = detectionOutput[3 * numBoxes + i] ?? 0\n\n let bestScore = -Infinity\n let bestClass = 0\n\n for (let j = 0; j < numClasses; j++) {\n const score = detectionOutput[(4 + j) * numBoxes + i] ?? 0\n if (score > bestScore) {\n bestScore = score\n bestClass = j\n }\n }\n\n if (bestScore < confidence) continue\n\n const bbox: BoundingBox = {\n x: cx - w / 2,\n y: cy - h / 2,\n w,\n h,\n }\n\n // Extract mask coefficients for this box\n const coeffs = new Float32Array(numMaskCoeffs)\n for (let k = 0; k < numMaskCoeffs; k++) {\n coeffs[k] = detectionOutput[(4 + numClasses + k) * numBoxes + i] ?? 0\n }\n\n candidates.push({ bbox, score: bestScore, classIdx: bestClass, coeffs })\n }\n\n if (candidates.length === 0) return []\n\n const keptIndices = nms(candidates, iouThreshold)\n\n return keptIndices.map((idx) => {\n const { bbox, score, classIdx, coeffs } = candidates[idx]!\n const label = labels[classIdx] ?? String(classIdx)\n\n // Scale bbox back from letterbox space to original image coords\n const x = Math.max(0, Math.min(originalWidth, (bbox.x - padX) / scale))\n const y = Math.max(0, Math.min(originalHeight, (bbox.y - padY) / scale))\n const x2 = Math.max(0, Math.min(originalWidth, (bbox.x + bbox.w - padX) / scale))\n const y2 = Math.max(0, Math.min(originalHeight, (bbox.y + bbox.h - padY) / scale))\n const finalBbox: BoundingBox = { x, y, w: x2 - x, h: y2 - y }\n\n // Decode instance mask using the letterbox-space bbox (before coord scaling)\n const rawMask = computeRawMask(coeffs, protoOutput, numMaskCoeffs, maskHeight, maskWidth)\n const { data: maskData, width: mW, height: mH } = cropAndThresholdMask(\n rawMask,\n maskHeight,\n maskWidth,\n bbox,\n maskThreshold,\n maskScale,\n )\n\n return {\n class: label,\n originalClass: label,\n score,\n bbox: finalBbox,\n mask: maskData,\n maskWidth: mW,\n maskHeight: mH,\n } satisfies SpatialDetection\n })\n}\n","import type { IInferenceEngine, DetectionRuntime, DetectionDevice } from '@camstack/types'\nimport * as path from 'node:path'\n\nconst BACKEND_TO_PROVIDER: Readonly<Record<string, string>> = {\n cpu: 'cpu',\n coreml: 'coreml',\n cuda: 'cuda',\n tensorrt: 'tensorrt',\n dml: 'dml',\n} as const\n\nconst BACKEND_TO_DEVICE: Readonly<Record<string, DetectionDevice>> = {\n cpu: 'cpu',\n coreml: 'gpu-mps',\n cuda: 'gpu-cuda',\n tensorrt: 'tensorrt',\n} as const\n\nexport class NodeInferenceEngine implements IInferenceEngine {\n readonly runtime: DetectionRuntime = 'onnx'\n readonly device: DetectionDevice\n private session: unknown = null\n\n constructor(\n private readonly modelPath: string,\n private readonly backend: string,\n ) {\n this.device = (BACKEND_TO_DEVICE[backend] ?? 'cpu') as DetectionDevice\n }\n\n async initialize(): Promise<void> {\n const ort = await import('onnxruntime-node')\n const provider = BACKEND_TO_PROVIDER[this.backend] ?? 'cpu'\n\n // Resolve absolute path\n const absModelPath = path.isAbsolute(this.modelPath)\n ? this.modelPath\n : path.resolve(process.cwd(), this.modelPath)\n\n const sessionOptions: Record<string, unknown> = {\n executionProviders: [provider],\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.session = await (ort as any).InferenceSession.create(absModelPath, sessionOptions)\n }\n\n async run(input: Float32Array, inputShape: readonly number[]): Promise<Float32Array> {\n if (!this.session) {\n throw new Error('NodeInferenceEngine: not initialized — call initialize() first')\n }\n\n const ort = await import('onnxruntime-node')\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const sess = this.session as any\n\n // Get the first input name\n const inputName: string = sess.inputNames[0]\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const tensor = new (ort as any).Tensor('float32', input, [...inputShape])\n const feeds: Record<string, unknown> = { [inputName]: tensor }\n\n const results = await sess.run(feeds)\n const outputName: string = sess.outputNames[0]\n const outputTensor = results[outputName]\n\n return outputTensor.data as Float32Array\n }\n\n async runMultiOutput(\n input: Float32Array,\n inputShape: readonly number[],\n ): Promise<Record<string, Float32Array>> {\n if (!this.session) {\n throw new Error('NodeInferenceEngine: not initialized — call initialize() first')\n }\n\n const ort = await import('onnxruntime-node')\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const sess = this.session as any\n\n const inputName: string = sess.inputNames[0]\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const tensor = new (ort as any).Tensor('float32', input, [...inputShape])\n const feeds: Record<string, unknown> = { [inputName]: tensor }\n\n const results = await sess.run(feeds)\n\n const out: Record<string, Float32Array> = {}\n for (const name of sess.outputNames as string[]) {\n out[name] = results[name].data as Float32Array\n }\n return out\n }\n\n async dispose(): Promise<void> {\n // onnxruntime-node sessions don't have explicit close in all versions\n // but we clear the reference\n this.session = null\n }\n}\n","import type { IInferenceEngine, DetectionRuntime, DetectionDevice, IAddonDepsManager } from '@camstack/types'\nimport { spawn, type ChildProcess } from 'node:child_process'\n\nexport class PythonInferenceEngine implements IInferenceEngine {\n readonly runtime: DetectionRuntime\n readonly device: DetectionDevice\n private process: ChildProcess | null = null\n private receiveBuffer: Buffer = Buffer.alloc(0)\n private pendingResolve: ((value: Record<string, unknown>) => void) | null = null\n private pendingReject: ((reason: Error) => void) | null = null\n\n constructor(\n private readonly pythonPath: string,\n private readonly scriptPath: string,\n runtime: DetectionRuntime,\n private readonly modelPath: string,\n private readonly extraArgs: readonly string[] = [],\n ) {\n this.runtime = runtime\n // Determine device from runtime\n const runtimeDeviceMap: Readonly<Record<DetectionRuntime, DetectionDevice>> = {\n onnx: 'cpu',\n coreml: 'gpu-mps',\n pytorch: 'cpu',\n openvino: 'cpu',\n tflite: 'cpu',\n }\n this.device = runtimeDeviceMap[runtime]\n }\n\n async initialize(): Promise<void> {\n const args = [this.scriptPath, this.modelPath, ...this.extraArgs]\n this.process = spawn(this.pythonPath, args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n })\n\n if (!this.process.stdout || !this.process.stdin) {\n throw new Error('PythonInferenceEngine: failed to create process pipes')\n }\n\n this.process.stderr?.on('data', (chunk: Buffer) => {\n // Log stderr from python process for debugging\n process.stderr.write(`[python-engine] ${chunk.toString()}`)\n })\n\n this.process.on('error', (err) => {\n this.pendingReject?.(err)\n this.pendingReject = null\n this.pendingResolve = null\n })\n\n this.process.on('exit', (code) => {\n if (code !== 0) {\n const err = new Error(`PythonInferenceEngine: process exited with code ${code}`)\n this.pendingReject?.(err)\n this.pendingReject = null\n this.pendingResolve = null\n }\n })\n\n this.process.stdout.on('data', (chunk: Buffer) => {\n this.receiveBuffer = Buffer.concat([this.receiveBuffer, chunk])\n this._tryReceive()\n })\n\n // Give the process a moment to start up and load the model\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => resolve(), 2000)\n this.process?.on('error', (err) => {\n clearTimeout(timeout)\n reject(err)\n })\n this.process?.on('exit', (code) => {\n clearTimeout(timeout)\n if (code !== 0) {\n reject(new Error(`PythonInferenceEngine: process exited early with code ${code}`))\n }\n })\n })\n }\n\n private _tryReceive(): void {\n // Binary IPC: [4 bytes LE uint32 length][JSON bytes]\n if (this.receiveBuffer.length < 4) return\n\n const length = this.receiveBuffer.readUInt32LE(0)\n if (this.receiveBuffer.length < 4 + length) return\n\n const jsonBytes = this.receiveBuffer.subarray(4, 4 + length)\n this.receiveBuffer = this.receiveBuffer.subarray(4 + length)\n\n const resolve = this.pendingResolve\n const reject = this.pendingReject\n this.pendingResolve = null\n this.pendingReject = null\n\n if (!resolve) return\n\n try {\n const parsed = JSON.parse(jsonBytes.toString('utf8')) as Record<string, unknown>\n resolve(parsed)\n } catch (err) {\n reject?.(err instanceof Error ? err : new Error(String(err)))\n }\n }\n\n /** Send JPEG buffer, receive JSON detection results */\n async runJpeg(jpeg: Buffer): Promise<Record<string, unknown>> {\n if (!this.process?.stdin) {\n throw new Error('PythonInferenceEngine: process not initialized')\n }\n\n return new Promise<Record<string, unknown>>((resolve, reject) => {\n this.pendingResolve = resolve\n this.pendingReject = reject\n\n // Binary IPC: [4 bytes LE uint32 length][JPEG bytes]\n const lengthBuf = Buffer.allocUnsafe(4)\n lengthBuf.writeUInt32LE(jpeg.length, 0)\n this.process!.stdin!.write(Buffer.concat([lengthBuf, jpeg]))\n })\n }\n\n /** IInferenceEngine.run — wraps runJpeg for compatibility */\n async run(_input: Float32Array, _inputShape: readonly number[]): Promise<Float32Array> {\n throw new Error(\n 'PythonInferenceEngine: use runJpeg() directly — this engine operates on JPEG input',\n )\n }\n\n /** IInferenceEngine.runMultiOutput — not supported by Python engine (operates on JPEG input) */\n async runMultiOutput(\n _input: Float32Array,\n _inputShape: readonly number[],\n ): Promise<Record<string, Float32Array>> {\n throw new Error(\n 'PythonInferenceEngine: runMultiOutput() is not supported — this engine operates on JPEG input',\n )\n }\n\n async dispose(): Promise<void> {\n if (this.process) {\n this.process.stdin?.end()\n this.process.kill('SIGTERM')\n this.process = null\n }\n }\n}\n\n/**\n * Resolve Python binary for ML inference. Priority:\n * 1. Explicit config pythonPath\n * 2. Embedded (data/deps/python/bin/python3)\n * 3. System PATH (python3, python)\n * 4. Download standalone Python\n *\n * Returns null if Python is not available.\n */\nexport async function resolvePythonBinary(\n configPath: string | undefined,\n deps: IAddonDepsManager,\n): Promise<string | null> {\n if (configPath) return configPath\n return deps.ensurePython()\n}\n","// TODO: Wire PythonInferenceEngine for PyTorch/OpenVINO/TFLite runtimes\n// Currently falls back to ONNX CPU when non-ONNX runtime is requested.\n// See: packages/addon-vision/python/ for stub implementations.\n//\n// WHY THIS FILE USES RAW FILESYSTEM PATHS (modelsDir: string):\n//\n// Model files must be loaded via absolute filesystem paths because inference\n// engines (ONNX Runtime, CoreML, etc.) require direct file access -- they do\n// not accept Buffer or stream inputs. This is fundamentally different from\n// user data (recordings, media) where IAddonFileStorage abstraction makes\n// sense. Models are closer to binaries or compiled artifacts that must live\n// on the local filesystem at runtime.\n//\n// IAddonFileStorage.readFile() returns a Buffer, but onnxruntime-node's\n// InferenceSession.create() only accepts a file path string or a Uint8Array\n// loaded into memory. For large models (hundreds of MB), loading into a\n// Uint8Array is impractical. Therefore, modelsDir stays as a raw string path\n// and is intentionally NOT replaced with IAddonFileStorage here.\n\nimport type {\n IInferenceEngine,\n DetectionRuntime,\n ModelCatalogEntry,\n ModelFormat,\n IAddonModelManager,\n} from '@camstack/types'\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport { NodeInferenceEngine } from './node-engine.js'\nimport { PythonInferenceEngine } from './python-engine.js'\n\nexport interface EngineResolverOptions {\n readonly runtime: DetectionRuntime | 'auto'\n readonly backend: string\n readonly modelEntry: ModelCatalogEntry\n readonly modelsDir: string\n readonly pythonPath?: string\n /** Model service for downloading models. When provided, used instead of raw filesystem probing. */\n readonly models?: IAddonModelManager\n}\n\nexport interface ResolvedEngine {\n readonly engine: IInferenceEngine\n readonly format: ModelFormat\n readonly modelPath: string\n}\n\n/** Priority order for auto-selection of ONNX backends */\nconst AUTO_BACKEND_PRIORITY = ['coreml', 'cuda', 'tensorrt', 'cpu'] as const\n\n/** Map backend names to the model format they require.\n * CoreML backend uses ONNX format -- onnxruntime-node loads the .onnx file\n * and accelerates it via the CoreML execution provider internally.\n * Native .mlpackage is only for PythonInferenceEngine. */\nconst BACKEND_TO_FORMAT: Readonly<Record<string, ModelFormat>> = {\n cpu: 'onnx',\n coreml: 'onnx',\n cuda: 'onnx',\n tensorrt: 'onnx',\n} as const\n\n/** Map DetectionRuntime to ModelFormat */\nconst RUNTIME_TO_FORMAT: Readonly<Partial<Record<DetectionRuntime, ModelFormat>>> = {\n onnx: 'onnx',\n coreml: 'coreml',\n openvino: 'openvino',\n tflite: 'tflite',\n pytorch: 'pt',\n} as const\n\nfunction modelFilePath(modelsDir: string, modelEntry: ModelCatalogEntry, format: ModelFormat): string {\n const formatEntry = modelEntry.formats[format]\n if (!formatEntry) {\n throw new Error(`Model ${modelEntry.id} has no ${format} format`)\n }\n // Derive filename from URL\n const urlParts = formatEntry.url.split('/')\n const filename = urlParts[urlParts.length - 1] ?? `${modelEntry.id}.${format}`\n return path.join(modelsDir, filename)\n}\n\nfunction modelExists(filePath: string): boolean {\n try {\n return fs.existsSync(filePath)\n } catch {\n return false\n }\n}\n\nexport async function resolveEngine(options: EngineResolverOptions): Promise<ResolvedEngine> {\n const { runtime, backend, modelEntry, modelsDir, models } = options\n\n let selectedFormat: ModelFormat\n let selectedBackend: string\n\n if (runtime === 'auto') {\n // Probe available ONNX backends and pick best\n const available = await probeOnnxBackends()\n\n // Pick first priority backend that has a corresponding model format available\n let chosen: { backend: string; format: ModelFormat } | null = null\n\n for (const b of AUTO_BACKEND_PRIORITY) {\n if (!available.includes(b)) continue\n const fmt = BACKEND_TO_FORMAT[b]\n if (!fmt) continue\n if (!modelEntry.formats[fmt]) continue\n chosen = { backend: b, format: fmt }\n break\n }\n\n if (!chosen) {\n throw new Error(\n `resolveEngine: no compatible backend found for model ${modelEntry.id}. Available backends: ${available.join(', ')}`,\n )\n }\n\n selectedFormat = chosen.format\n selectedBackend = chosen.backend\n } else {\n // Explicit runtime requested\n const fmt = RUNTIME_TO_FORMAT[runtime]\n if (!fmt) {\n throw new Error(`resolveEngine: unsupported runtime \"${runtime}\"`)\n }\n if (!modelEntry.formats[fmt]) {\n throw new Error(\n `resolveEngine: model ${modelEntry.id} has no ${fmt} format for runtime ${runtime}`,\n )\n }\n selectedFormat = fmt\n // For onnx runtime, use the provided backend; otherwise use the runtime name\n selectedBackend = runtime === 'onnx' ? (backend || 'cpu') : runtime\n }\n\n // Download model and extra files via the unified service\n let modelPath: string\n\n if (models) {\n // Use the unified ModelDownloadService\n modelPath = await models.ensure(modelEntry.id, selectedFormat)\n } else {\n // Fallback: direct filesystem check (no download capability)\n modelPath = modelFilePath(modelsDir, modelEntry, selectedFormat)\n if (!modelExists(modelPath)) {\n throw new Error(\n `resolveEngine: model file not found at ${modelPath} and no model service provided`,\n )\n }\n }\n\n // NodeInferenceEngine handles ONNX format only (with any ONNX backend including CoreML provider).\n // Native .mlpackage/.mlmodel files go to PythonInferenceEngine below.\n if (selectedFormat === 'onnx') {\n const engine = new NodeInferenceEngine(modelPath, selectedBackend)\n await engine.initialize()\n return { engine, format: selectedFormat, modelPath }\n }\n\n // For non-ONNX/CoreML formats, try PythonInferenceEngine when a python binary is available\n const { pythonPath } = options\n const PYTHON_SCRIPT_MAP: Readonly<Record<string, string>> = {\n coreml: 'coreml_inference.py',\n pytorch: 'pytorch_inference.py',\n openvino: 'openvino_inference.py',\n } as const\n\n const effectiveRuntime = runtime === 'auto' ? selectedBackend : runtime\n const scriptName = PYTHON_SCRIPT_MAP[effectiveRuntime]\n\n if (scriptName && pythonPath) {\n // Resolve python script path -- search multiple locations:\n // - src/shared/ -> ../../python/ (source development)\n // - dist/shared/ -> ../../python/ (installed addon with python/ at package root)\n // - dist/ -> ../python/ (flat dist)\n const candidates = [\n path.join(__dirname, '../../python', scriptName),\n path.join(__dirname, '../python', scriptName),\n path.join(__dirname, '../../../python', scriptName),\n ]\n const scriptPath = candidates.find(p => fs.existsSync(p))\n if (!scriptPath) {\n throw new Error(\n `resolveEngine: Python script \"${scriptName}\" not found. Searched:\\n${candidates.join('\\n')}`,\n )\n }\n const inputSize = Math.max(modelEntry.inputSize.width, modelEntry.inputSize.height)\n const engine = new PythonInferenceEngine(pythonPath, scriptPath, effectiveRuntime as DetectionRuntime, modelPath, [\n `--input-size=${inputSize}`,\n `--confidence=0.25`,\n ])\n await engine.initialize()\n return { engine, format: selectedFormat, modelPath }\n }\n\n // Final fallback: use ONNX CPU if available\n const fallbackPath = modelFilePath(modelsDir, modelEntry, 'onnx')\n if (modelEntry.formats['onnx'] && modelExists(fallbackPath)) {\n const engine = new NodeInferenceEngine(fallbackPath, 'cpu')\n await engine.initialize()\n return { engine, format: 'onnx', modelPath: fallbackPath }\n }\n\n throw new Error(\n `resolveEngine: format ${selectedFormat} is not yet supported by NodeInferenceEngine, ` +\n `no Python runtime is available, and no ONNX fallback exists`,\n )\n}\n\n/** Probe which ONNX execution providers are available on this system */\nexport async function probeOnnxBackends(): Promise<string[]> {\n const available: string[] = ['cpu'] // CPU is always available\n\n try {\n const ort = await import('onnxruntime-node')\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const providers: string[] = (ort as any).env?.webgl?.disabled !== undefined\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ? ((ort as any).InferenceSession?.getAvailableProviders?.() ?? [])\n : []\n\n for (const p of providers) {\n const normalized = p.toLowerCase().replace('executionprovider', '')\n if (normalized === 'coreml') available.push('coreml')\n else if (normalized === 'cuda') available.push('cuda')\n else if (normalized === 'tensorrt') available.push('tensorrt')\n }\n } catch {\n // onnxruntime-node may not be installed; CPU only\n }\n\n // Platform-specific hints when getAvailableProviders isn't exposed\n if (process.platform === 'darwin' && !available.includes('coreml')) {\n available.push('coreml')\n }\n\n return [...new Set(available)]\n}\n","import type {\n IDetectorProvider,\n IDetectionAddon,\n AddonManifest,\n AddonContext,\n FrameInput,\n DetectorOutput,\n SpatialDetection,\n ConfigUISchema,\n ClassMapDefinition,\n ProbeResult,\n ModelCatalogEntry,\n DetectionModel,\n LabelDefinition,\n IInferenceEngine,\n ModelRequirement,\n ResolvedInferenceConfig,\n} from '@camstack/types'\nimport { OBJECT_DETECTION_MODELS } from '../../catalogs/object-detection-models.js'\nimport { SEGMENTATION_MODELS } from '../../catalogs/segmentation-models.js'\nimport { COCO_TO_MACRO, MACRO_LABELS, COCO_80_LABELS } from '@camstack/types'\nimport { letterbox } from '../../shared/image-utils.js'\nimport { yoloPostprocess } from '../../shared/postprocess/yolo.js'\nimport { yoloSegPostprocess } from '../../shared/postprocess/yolo-seg.js'\nimport { resolveEngine } from '../../shared/engine-resolver.js'\n\n/** Returns true when the model id identifies a YOLO segmentation model (e.g. yolov8n-seg, yolo11m-seg) */\nfunction isSegModel(modelId: string): boolean {\n return modelId.includes('-seg')\n}\n\n/** Combined catalog: regular detection models + segmentation models */\nconst ALL_DETECTION_MODELS: readonly ModelCatalogEntry[] = [\n ...OBJECT_DETECTION_MODELS,\n ...SEGMENTATION_MODELS,\n]\n\n/**\n * classMapMode controls how raw COCO labels are mapped after inference:\n *\n * - 'macro' (default): apply COCO_TO_MACRO — only person / vehicle / animal\n * survive, all other classes are dropped.\n * - 'all': keep every raw COCO label (80 classes). originalClass === class.\n */\ntype ClassMapMode = 'macro' | 'all'\n\n/** Map COCO-class detections to macro categories (person/vehicle/animal) */\nfunction applyClassMap(\n detections: SpatialDetection[],\n classMap: ClassMapDefinition,\n): SpatialDetection[] {\n return detections\n .filter((d) => classMap.mapping[d.class] !== undefined)\n .map((d) => ({\n ...d,\n originalClass: d.class,\n class: classMap.mapping[d.class]!,\n }))\n}\n\n/** RAM estimates per model (MB) */\nconst RAM_ESTIMATES: Record<string, number> = {\n 'yolov8n': 80, 'yolov8s': 150, 'yolov8s-relu': 150, 'yolov8m': 300, 'yolov8l': 500, 'yolov8x': 800,\n 'yolov9t': 60, 'yolov9s': 120, 'yolov9c': 300,\n 'yolo11n': 70, 'yolo11s': 130, 'yolo11m': 280, 'yolo11l': 450, 'yolo11x': 750,\n 'yolo11n-seg': 84, 'yolo11s-seg': 156, 'yolo11m-seg': 336,\n 'yolov8n-seg': 96, 'yolov8s-seg': 180, 'yolov8m-seg': 360,\n}\n\n/**\n * Accuracy scores per model (0-100).\n * YOLO11 scores are higher than YOLOv8 equivalents to reflect the\n * ~2 mAP improvement at same parameter count (e.g. YOLO11n 39.5 vs YOLOv8n 37.3).\n * This ensures the resolver prefers YOLO11 when both families are available.\n */\nconst ACCURACY_SCORES: Record<string, number> = {\n 'yolov8n': 55, 'yolov8s': 70, 'yolov8s-relu': 68, 'yolov8m': 82, 'yolov8l': 88, 'yolov8x': 92,\n 'yolov9t': 58, 'yolov9s': 73, 'yolov9c': 86,\n 'yolo11n': 62, 'yolo11s': 78, 'yolo11m': 88, 'yolo11l': 93, 'yolo11x': 97,\n 'yolo11n-seg': 62, 'yolo11s-seg': 78, 'yolo11m-seg': 88,\n 'yolov8n-seg': 55, 'yolov8s-seg': 70, 'yolov8m-seg': 82,\n}\n\nexport default class ObjectDetectionAddon implements IDetectorProvider, IDetectionAddon {\n readonly id = 'object-detection'\n readonly slot = 'detector' as const\n readonly inputClasses: readonly string[] | null = null\n readonly outputClasses = ['person', 'vehicle', 'animal'] as const\n readonly slotPriority = 0\n readonly manifest: AddonManifest = {\n id: 'object-detection',\n name: 'Object Detection',\n version: '0.1.0',\n\n description: 'YOLO-based object detection — detects persons, vehicles, and animals',\n\n slot: 'detector',\n inputClasses: undefined,\n outputClasses: ['person', 'vehicle', 'animal'],\n supportsCustomModels: true,\n mayRequirePython: false,\n defaultConfig: {\n modelId: 'yolo11n',\n runtime: 'node',\n backend: 'cpu',\n confidence: 0.5,\n iouThreshold: 0.45,\n classMapMode: 'macro',\n },\n }\n\n private engine: IInferenceEngine | null = null\n private modelEntry!: ModelCatalogEntry\n private confidence = 0.5\n private iouThreshold = 0.45\n private classMapMode: ClassMapMode = 'macro'\n private resolvedConfig: ResolvedInferenceConfig | null = null\n private ctx: AddonContext | null = null\n\n getModelRequirements(): ModelRequirement[] {\n return ALL_DETECTION_MODELS.map((m) => ({\n modelId: m.id,\n name: m.name,\n minRAM_MB: RAM_ESTIMATES[m.id] ?? 100,\n accuracyScore: ACCURACY_SCORES[m.id] ?? 60,\n formats: Object.keys(m.formats) as readonly string[],\n }))\n }\n\n configure(config: ResolvedInferenceConfig): void {\n this.resolvedConfig = config\n }\n\n async initialize(ctx: AddonContext): Promise<void> {\n this.ctx = ctx\n const cfg = ctx.addonConfig\n const modelId = (cfg['modelId'] as string | undefined) ?? this.resolvedConfig?.modelId ?? 'yolo11n'\n this.confidence = (cfg['confidence'] as number | undefined) ?? 0.5\n this.iouThreshold = (cfg['iouThreshold'] as number | undefined) ?? 0.45\n this.classMapMode = (cfg['classMapMode'] as ClassMapMode | undefined) ?? 'macro'\n\n const entry = ALL_DETECTION_MODELS.find((m) => m.id === modelId)\n if (!entry) {\n throw new Error(`ObjectDetectionAddon: unknown modelId \"${modelId}\"`)\n }\n this.modelEntry = entry\n }\n\n async detect(frame: FrameInput): Promise<DetectorOutput> {\n if (!this.engine) await this.ensureEngine()\n const start = Date.now()\n\n // Python engine path — send JPEG directly, Python handles preprocess + inference + postprocess\n if ('runJpeg' in this.engine! && typeof (this.engine as any).runJpeg === 'function') {\n const result = await (this.engine as any).runJpeg(frame.data) as Record<string, unknown>\n const rawDets = (result.detections ?? []) as Array<{ className: string; score: number; bbox: number[] }>\n const detections: SpatialDetection[] = rawDets.map((d) => ({\n class: this.classMapMode === 'all' ? d.className : (COCO_TO_MACRO.mapping[d.className] ?? d.className),\n originalClass: d.className,\n score: d.score,\n bbox: {\n x: d.bbox[0]! * frame.width,\n y: d.bbox[1]! * frame.height,\n w: (d.bbox[2]! - d.bbox[0]!) * frame.width,\n h: (d.bbox[3]! - d.bbox[1]!) * frame.height,\n },\n })).filter((d) => this.classMapMode === 'all' || COCO_TO_MACRO.mapping[d.originalClass!] !== undefined)\n\n return {\n detections,\n inferenceMs: (result.inferenceMs as number) ?? (Date.now() - start),\n modelId: this.modelEntry.id,\n }\n }\n\n // Node.js engine path — letterbox + run tensor + postprocess\n const { width: inputW, height: inputH } = this.modelEntry.inputSize\n const targetSize = Math.max(inputW, inputH)\n\n const lb = await letterbox(frame.data, targetSize)\n\n const numClasses = this.modelEntry.labels.length\n const labels = this.modelEntry.labels.map((l) => l.id)\n const postprocessOpts = {\n confidence: this.confidence,\n iouThreshold: this.iouThreshold,\n labels,\n scale: lb.scale,\n padX: lb.padX,\n padY: lb.padY,\n originalWidth: lb.originalWidth,\n originalHeight: lb.originalHeight,\n }\n\n let rawDetections: SpatialDetection[]\n\n if (isSegModel(this.modelEntry.id)) {\n // YOLO-seg models produce two outputs:\n // output0: [1, 4 + numClasses + 32, numBoxes] (detection + mask coefficients)\n // output1: [1, 32, 160, 160] (prototype masks)\n const outputs = await this.engine!.runMultiOutput(lb.data, [1, 3, targetSize, targetSize])\n const outputNames = Object.keys(outputs)\n\n if (outputNames.length < 2) {\n throw new Error(\n `ObjectDetectionAddon: seg model \"${this.modelEntry.id}\" returned ${outputNames.length} output(s); expected 2`,\n )\n }\n\n // ONNX output order is deterministic; first output is the detection tensor, second is protos\n const detectionOutput = outputs[outputNames[0]!]!\n const protoOutput = outputs[outputNames[1]!]!\n\n // Infer dims from tensor sizes\n const numMaskCoeffs = 32\n const numBoxes = detectionOutput.length / (4 + numClasses + numMaskCoeffs)\n const maskHeight = 160\n const maskWidth = 160\n\n rawDetections = yoloSegPostprocess(\n {\n detectionOutput,\n protoOutput,\n numClasses,\n numBoxes,\n numMaskCoeffs,\n maskHeight,\n maskWidth,\n },\n postprocessOpts,\n )\n } else {\n // Standard YOLO output: [1, 4+numClasses, numBoxes]\n const output = await this.engine!.run(lb.data, [1, 3, targetSize, targetSize])\n const numBoxes = output.length / (4 + numClasses)\n rawDetections = yoloPostprocess(output, numClasses, numBoxes, postprocessOpts)\n }\n\n const detections = this.classMapMode === 'all'\n ? rawDetections\n : applyClassMap(rawDetections, COCO_TO_MACRO)\n\n return {\n detections,\n inferenceMs: Date.now() - start,\n modelId: this.modelEntry.id,\n }\n }\n\n private async ensureEngine(): Promise<void> {\n const config = this.resolvedConfig\n const modelId = config?.modelId ?? this.modelEntry.id\n const runtime = config?.runtime === 'python' ? 'coreml' : (config?.runtime === 'node' ? 'onnx' : 'auto')\n const backend = config?.backend ?? 'cpu'\n const format = config?.format ?? 'onnx'\n\n const entry = ALL_DETECTION_MODELS.find((m) => m.id === modelId) ?? this.modelEntry\n this.modelEntry = entry\n\n const modelsDir = this.ctx!.models?.getModelsDir() ?? this.ctx!.locationPaths.models\n\n // Download model if needed\n if (this.ctx!.models) {\n await this.ctx!.models.ensure(modelId, format as any)\n }\n\n // Discover Python path for Python-based runtimes\n let pythonPath: string | undefined\n if (config?.runtime === 'python') {\n for (const cmd of ['python3', 'python']) {\n try {\n const { execSync } = await import('node:child_process')\n execSync(`${cmd} --version`, { timeout: 3000, stdio: 'ignore' })\n pythonPath = cmd\n break\n } catch { /* not found */ }\n }\n }\n\n const resolved = await resolveEngine({\n runtime: runtime as 'auto',\n backend,\n modelEntry: entry,\n modelsDir,\n pythonPath,\n models: this.ctx!.models,\n })\n this.engine = resolved.engine\n }\n\n async shutdown(): Promise<void> {\n await this.engine?.dispose()\n }\n\n getConfigSchema(): ConfigUISchema {\n return {\n sections: [\n {\n id: 'model',\n title: 'Model',\n columns: 1,\n fields: [\n {\n key: 'modelId',\n label: 'Model',\n type: 'model-selector',\n catalog: [...ALL_DETECTION_MODELS],\n allowCustom: true,\n allowConversion: true,\n acceptFormats: ['onnx', 'coreml', 'openvino', 'tflite'],\n requiredMetadata: ['inputSize', 'labels', 'outputFormat'],\n outputFormatHint: 'yolo',\n },\n ],\n },\n {\n id: 'runtime',\n title: 'Runtime',\n columns: 2,\n fields: [\n {\n key: 'runtime',\n label: 'Runtime',\n type: 'select',\n options: [\n { value: 'auto', label: 'Auto' },\n { value: 'onnx', label: 'ONNX Runtime' },\n { value: 'coreml', label: 'CoreML (Apple)' },\n { value: 'openvino', label: 'OpenVINO (Intel)' },\n ],\n },\n {\n key: 'backend',\n label: 'Backend',\n type: 'select',\n showWhen: { field: 'runtime', equals: 'onnx' },\n options: [\n { value: 'auto', label: 'Auto' },\n { value: 'cpu', label: 'CPU' },\n { value: 'coreml', label: 'CoreML' },\n { value: 'cuda', label: 'CUDA (NVIDIA)' },\n { value: 'tensorrt', label: 'TensorRT (NVIDIA)' },\n ],\n },\n ],\n },\n {\n id: 'thresholds',\n title: 'Detection Thresholds',\n columns: 2,\n fields: [\n {\n key: 'confidence',\n label: 'Confidence Threshold',\n type: 'slider',\n min: 0.1,\n max: 1.0,\n step: 0.05,\n default: 0.5,\n },\n {\n key: 'iouThreshold',\n label: 'IoU Threshold (NMS)',\n type: 'slider',\n min: 0.1,\n max: 1.0,\n step: 0.05,\n default: 0.45,\n },\n ],\n },\n {\n id: 'classmap',\n title: 'Class Mapping',\n columns: 1,\n fields: [\n {\n key: 'classMapMode',\n label: 'Output classes',\n type: 'select',\n options: [\n { value: 'macro', label: 'Macro (person / vehicle / animal)' },\n { value: 'all', label: 'All COCO classes (80)' },\n ],\n },\n ],\n },\n ],\n }\n }\n\n getClassMap(): ClassMapDefinition {\n return COCO_TO_MACRO\n }\n\n getModelCatalog(): ModelCatalogEntry[] {\n return [...ALL_DETECTION_MODELS]\n }\n\n getAvailableModels(): DetectionModel[] {\n // TODO: check downloaded models in modelsDir\n return []\n }\n\n getActiveLabels(): readonly LabelDefinition[] {\n return this.classMapMode === 'all' ? COCO_80_LABELS : MACRO_LABELS\n }\n\n async probe(): Promise<ProbeResult> {\n return {\n available: true,\n runtime: this.engine?.runtime ?? 'onnx',\n device: this.engine?.device ?? 'cpu',\n capabilities: ['fp32'],\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,QAAA,UAAA,QAAA,iBAAA;AAEA,QAAM,UAAU;AAGH,IAAAA,SAAA,kBAAkB;MAC7B;MACA;MACA;;AAGW,IAAAA,SAAA,0BAAwD;;MAEnE;QACE,IAAI;QACJ,MAAM;QACN,aAAa;QACb,WAAW,EAAE,OAAO,KAAK,QAAQ,IAAG;QACpC,QAAQ,QAAA;QACR,SAAS;UACP,MAAM;YACJ,MAAK,GAAA,QAAA,YAAW,SAAS,mDAAmD;YAC5E,QAAQ;;UAEV,QAAQ;YACN,MAAK,GAAA,QAAA,YAAW,SAAS,0DAA0D;YACnF,QAAQ;YACR,aAAa;YACb,OAAOA,SAAA;YACP,UAAU,CAAC,QAAQ;;UAErB,UAAU;YACR,MAAK,GAAA,QAAA,YAAW,SAAS,sDAAsD;YAC/E,QAAQ;YACR,UAAU,CAAC,QAAQ;;UAErB,QAAQ;YACN,MAAK,GAAA,QAAA,YAAW,SAAS,+DAA+D;YACxF,QAAQ;YACR,UAAU,CAAC,QAAQ;;;;MAIzB;QACE,IAAI;QACJ,MAAM;QACN,aAAa;QACb,WAAW,EAAE,OAAO,KAAK,QAAQ,IAAG;QACpC,QAAQ,QAAA;QACR,SAAS;UACP,MAAM;YACJ,MAAK,GAAA,QAAA,YAAW,SAAS,mDAAmD;YAC5E,QAAQ;;UAEV,QAAQ;YACN,MAAK,GAAA,QAAA,YAAW,SAAS,0DAA0D;YACnF,QAAQ;YACR,aAAa;YACb,OAAOA,SAAA;YACP,UAAU,CAAC,QAAQ;;UAErB,UAAU;YACR,MAAK,GAAA,QAAA,YAAW,SAAS,sDAAsD;YAC/E,QAAQ;YACR,UAAU,CAAC,QAAQ;;UAErB,QAAQ;YACN,MAAK,GAAA,QAAA,YAAW,SAAS,+DAA+D;YACxF,QAAQ;YACR,UAAU,CAAC,QAAQ;;;;MAIzB;QACE,IAAI;QACJ,MAAM;QACN,aAAa;QACb,WAAW,EAAE,OAAO,KAAK,QAAQ,IAAG;QACpC,QAAQ,QAAA;QACR,SAAS;UACP,MAAM;YACJ,MAAK,GAAA,QAAA,YAAW,SAAS,wDAAwD;YACjF,QAAQ;;;;MAId;QACE,IAAI;QACJ,MAAM;QACN,aAAa;QACb,WAAW,EAAE,OAAO,KAAK,QAAQ,IAAG;QACpC,QAAQ,QAAA;QACR,SAAS;UACP,MAAM;YACJ,MAAK,GAAA,QAAA,YAAW,SAAS,mDAAmD;YAC5E,QAAQ;;UAEV,QAAQ;YACN,MAAK,GAAA,QAAA,YAAW,SAAS,0DAA0D;YACnF,QAAQ;YACR,aAAa;YACb,OAAOA,SAAA;YACP,UAAU,CAAC,QAAQ;;UAErB,UAAU;YACR,MAAK,GAAA,QAAA,YAAW,SAAS,sDAAsD;YAC/E,QAAQ;YACR,UAAU,CAAC,QAAQ;;UAErB,QAAQ;YACN,MAAK,GAAA,QAAA,YAAW,SAAS,+DAA+D;YACxF,QAAQ;YACR,UAAU,CAAC,QAAQ;;;;MAIzB;QACE,IAAI;QACJ,MAAM;QACN,aAAa;QACb,WAAW,EAAE,OAAO,KAAK,QAAQ,IAAG;QACpC,QAAQ,QAAA;QACR,SAAS;UACP,MAAM;YACJ,MAAK,GAAA,QAAA,YAAW,SAAS,mDAAmD;YAC5E,QAAQ;;UAEV,QAAQ;YACN,MAAK,GAAA,QAAA,YAAW,SAAS,0DAA0D;YACnF,QAAQ;YACR,aAAa;YACb,OAAOA,SAAA;YACP,UAAU,CAAC,QAAQ;;UAErB,UAAU;YACR,MAAK,GAAA,QAAA,YAAW,SAAS,sDAAsD;YAC/E,QAAQ;YACR,UAAU,CAAC,QAAQ;;;;MAIzB;QACE,IAAI;QACJ,MAAM;QACN,aAAa;QACb,WAAW,EAAE,OAAO,KAAK,QAAQ,IAAG;QACpC,QAAQ,QAAA;QACR,SAAS;UACP,MAAM;YACJ,MAAK,GAAA,QAAA,YAAW,SAAS,mDAAmD;YAC5E,QAAQ;;UAEV,QAAQ;YACN,MAAK,GAAA,QAAA,YAAW,SAAS,0DAA0D;YACnF,QAAQ;YACR,aAAa;YACb,OAAOA,SAAA;YACP,UAAU,CAAC,QAAQ;;UAErB,UAAU;YACR,MAAK,GAAA,QAAA,YAAW,SAAS,sDAAsD;YAC/E,QAAQ;YACR,UAAU,CAAC,QAAQ;;;;;MAMzB;QACE,IAAI;QACJ,MAAM;QACN,aAAa;QACb,WAAW,EAAE,OAAO,KAAK,QAAQ,IAAG;QACpC,QAAQ,QAAA;QACR,SAAS;UACP,MAAM;YACJ,MAAK,GAAA,QAAA,YAAW,SAAS,mDAAmD;YAC5E,QAAQ;;UAEV,QAAQ;YACN,MAAK,GAAA,QAAA,YAAW,SAAS,0DAA0D;YACnF,QAAQ;YACR,aAAa;YACb,OAAOA,SAAA;YACP,UAAU,CAAC,QAAQ;;UAErB,UAAU;YACR,MAAK,GAAA,QAAA,YAAW,SAAS,sDAAsD;YAC/E,QAAQ;YACR,UAAU,CAAC,QAAQ;;UAErB,QAAQ;YACN,MAAK,GAAA,QAAA,YAAW,SAAS,+DAA+D;YACxF,QAAQ;YACR,UAAU,CAAC,QAAQ;;;;MAIzB;QACE,IAAI;QACJ,MAAM;QACN,aAAa;QACb,WAAW,EAAE,OAAO,KAAK,QAAQ,IAAG;QACpC,QAAQ,QAAA;QACR,SAAS;UACP,MAAM;YACJ,MAAK,GAAA,QAAA,YAAW,SAAS,mDAAmD;YAC5E,QAAQ;;UAEV,QAAQ;YACN,MAAK,GAAA,QAAA,YAAW,SAAS,0DAA0D;YACnF,QAAQ;YACR,aAAa;YACb,OAAOA,SAAA;YACP,UAAU,CAAC,QAAQ;;UAErB,UAAU;YACR,MAAK,GAAA,QAAA,YAAW,SAAS,sDAAsD;YAC/E,QAAQ;YACR,UAAU,CAAC,QAAQ;;UAErB,QAAQ;YACN,MAAK,GAAA,QAAA,YAAW,SAAS,+DAA+D;YACxF,QAAQ;YACR,UAAU,CAAC,QAAQ;;;;MAIzB;QACE,IAAI;QACJ,MAAM;QACN,aAAa;QACb,WAAW,EAAE,OAAO,KAAK,QAAQ,IAAG;QACpC,QAAQ,QAAA;QACR,SAAS;UACP,MAAM;YACJ,MAAK,GAAA,QAAA,YAAW,SAAS,mDAAmD;YAC5E,QAAQ;;UAEV,QAAQ;YACN,MAAK,GAAA,QAAA,YAAW,SAAS,0DAA0D;YACnF,QAAQ;YACR,aAAa;YACb,OAAOA,SAAA;YACP,UAAU,CAAC,QAAQ;;UAErB,UAAU;YACR,MAAK,GAAA,QAAA,YAAW,SAAS,sDAAsD;YAC/E,QAAQ;YACR,UAAU,CAAC,QAAQ;;UAErB,QAAQ;YACN,MAAK,GAAA,QAAA,YAAW,SAAS,+DAA+D;YACxF,QAAQ;YACR,UAAU,CAAC,QAAQ;;;;;MAMzB;QACE,IAAI;QACJ,MAAM;QACN,aAAa;QACb,WAAW,EAAE,OAAO,KAAK,QAAQ,IAAG;QACpC,QAAQ,QAAA;QACR,SAAS;UACP,MAAM;YACJ,MAAK,GAAA,QAAA,YAAW,SAAS,mDAAmD;YAC5E,QAAQ;;UAEV,QAAQ;YACN,MAAK,GAAA,QAAA,YAAW,SAAS,0DAA0D;YACnF,QAAQ;YACR,aAAa;YACb,OAAOA,SAAA;YACP,UAAU,CAAC,QAAQ;;UAErB,UAAU;YACR,MAAK,GAAA,QAAA,YAAW,SAAS,sDAAsD;YAC/E,QAAQ;YACR,UAAU,CAAC,QAAQ;;UAErB,QAAQ;YACN,MAAK,GAAA,QAAA,YAAW,SAAS,+DAA+D;YACxF,QAAQ;YACR,UAAU,CAAC,QAAQ;;;;MAIzB;QACE,IAAI;QACJ,MAAM;QACN,aAAa;QACb,WAAW,EAAE,OAAO,KAAK,QAAQ,IAAG;QACpC,QAAQ,QAAA;QACR,SAAS;UACP,MAAM;YACJ,MAAK,GAAA,QAAA,YAAW,SAAS,mDAAmD;YAC5E,QAAQ;;UAEV,QAAQ;YACN,MAAK,GAAA,QAAA,YAAW,SAAS,0DAA0D;YACnF,QAAQ;YACR,aAAa;YACb,OAAOA,SAAA;YACP,UAAU,CAAC,QAAQ;;UAErB,UAAU;YACR,MAAK,GAAA,QAAA,YAAW,SAAS,sDAAsD;YAC/E,QAAQ;YACR,UAAU,CAAC,QAAQ;;UAErB,QAAQ;YACN,MAAK,GAAA,QAAA,YAAW,SAAS,+DAA+D;YACxF,QAAQ;YACR,UAAU,CAAC,QAAQ;;;;MAIzB;QACE,IAAI;QACJ,MAAM;QACN,aAAa;QACb,WAAW,EAAE,OAAO,KAAK,QAAQ,IAAG;QACpC,QAAQ,QAAA;QACR,SAAS;UACP,MAAM;YACJ,MAAK,GAAA,QAAA,YAAW,SAAS,mDAAmD;YAC5E,QAAQ;;UAEV,QAAQ;YACN,MAAK,GAAA,QAAA,YAAW,SAAS,0DAA0D;YACnF,QAAQ;YACR,aAAa;YACb,OAAOA,SAAA;YACP,UAAU,CAAC,QAAQ;;UAErB,UAAU;YACR,MAAK,GAAA,QAAA,YAAW,SAAS,sDAAsD;YAC/E,QAAQ;YACR,UAAU,CAAC,QAAQ;;UAErB,QAAQ;YACN,MAAK,GAAA,QAAA,YAAW,SAAS,+DAA+D;YACxF,QAAQ;YACR,UAAU,CAAC,QAAQ;;;;MAIzB;QACE,IAAI;QACJ,MAAM;QACN,aAAa;QACb,WAAW,EAAE,OAAO,KAAK,QAAQ,IAAG;QACpC,QAAQ,QAAA;QACR,SAAS;UACP,MAAM;YACJ,MAAK,GAAA,QAAA,YAAW,SAAS,mDAAmD;YAC5E,QAAQ;;UAEV,QAAQ;YACN,MAAK,GAAA,QAAA,YAAW,SAAS,0DAA0D;YACnF,QAAQ;YACR,aAAa;YACb,OAAOA,SAAA;YACP,UAAU,CAAC,QAAQ;;UAErB,UAAU;YACR,MAAK,GAAA,QAAA,YAAW,SAAS,sDAAsD;YAC/E,QAAQ;YACR,UAAU,CAAC,QAAQ;;UAErB,QAAQ;YACN,MAAK,GAAA,QAAA,YAAW,SAAS,+DAA+D;YACxF,QAAQ;YACR,UAAU,CAAC,QAAQ;;;;MAIzB;QACE,IAAI;QACJ,MAAM;QACN,aAAa;QACb,WAAW,EAAE,OAAO,KAAK,QAAQ,IAAG;QACpC,QAAQ,QAAA;QACR,SAAS;UACP,MAAM;YACJ,MAAK,GAAA,QAAA,YAAW,SAAS,mDAAmD;YAC5E,QAAQ;;UAEV,QAAQ;YACN,MAAK,GAAA,QAAA,YAAW,SAAS,0DAA0D;YACnF,QAAQ;YACR,aAAa;YACb,OAAOA,SAAA;YACP,UAAU,CAAC,QAAQ;;UAErB,UAAU;YACR,MAAK,GAAA,QAAA,YAAW,SAAS,sDAAsD;YAC/E,QAAQ;YACR,UAAU,CAAC,QAAQ;;UAErB,QAAQ;YACN,MAAK,GAAA,QAAA,YAAW,SAAS,+DAA+D;YACxF,QAAQ;YACR,UAAU,CAAC,QAAQ;;;;;;;;;;;;;;ACtZ3B,QAAA,UAAA,QAAA,iBAAA;AACA,QAAA,+BAAA;AAEA,QAAM,UAAU;AAEH,IAAAC,SAAA,sBAAoD;;MAE/D;QACE,IAAI;QACJ,MAAM;QACN,aAAa;QACb,WAAW,EAAE,OAAO,KAAK,QAAQ,IAAG;QACpC,QAAQ,QAAA;QACR,SAAS;UACP,MAAM;YACJ,MAAK,GAAA,QAAA,YAAW,SAAS,wDAAwD;YACjF,QAAQ;;UAEV,QAAQ;YACN,MAAK,GAAA,QAAA,YAAW,SAAS,+DAA+D;YACxF,QAAQ;YACR,aAAa;YACb,OAAO,6BAAA;YACP,UAAU,CAAC,QAAQ;;UAErB,UAAU;YACR,MAAK,GAAA,QAAA,YAAW,SAAS,2DAA2D;YACpF,QAAQ;YACR,UAAU,CAAC,QAAQ;;;;MAIzB;QACE,IAAI;QACJ,MAAM;QACN,aAAa;QACb,WAAW,EAAE,OAAO,KAAK,QAAQ,IAAG;QACpC,QAAQ,QAAA;QACR,SAAS;UACP,MAAM;YACJ,MAAK,GAAA,QAAA,YAAW,SAAS,wDAAwD;YACjF,QAAQ;;UAEV,QAAQ;YACN,MAAK,GAAA,QAAA,YAAW,SAAS,+DAA+D;YACxF,QAAQ;YACR,aAAa;YACb,OAAO,6BAAA;YACP,UAAU,CAAC,QAAQ;;UAErB,UAAU;YACR,MAAK,GAAA,QAAA,YAAW,SAAS,2DAA2D;YACpF,QAAQ;YACR,UAAU,CAAC,QAAQ;;;;MAIzB;QACE,IAAI;QACJ,MAAM;QACN,aAAa;QACb,WAAW,EAAE,OAAO,KAAK,QAAQ,IAAG;QACpC,QAAQ,QAAA;QACR,SAAS;UACP,MAAM;YACJ,MAAK,GAAA,QAAA,YAAW,SAAS,wDAAwD;YACjF,QAAQ;;UAEV,QAAQ;YACN,MAAK,GAAA,QAAA,YAAW,SAAS,+DAA+D;YACxF,QAAQ;YACR,aAAa;YACb,OAAO,6BAAA;YACP,UAAU,CAAC,QAAQ;;UAErB,UAAU;YACR,MAAK,GAAA,QAAA,YAAW,SAAS,2DAA2D;YACpF,QAAQ;YACR,UAAU,CAAC,QAAQ;;;;;MAMzB;QACE,IAAI;QACJ,MAAM;QACN,aAAa;QACb,WAAW,EAAE,OAAO,KAAK,QAAQ,IAAG;QACpC,QAAQ,QAAA;QACR,SAAS;UACP,MAAM;YACJ,MAAK,GAAA,QAAA,YAAW,SAAS,wDAAwD;YACjF,QAAQ;;UAEV,QAAQ;YACN,MAAK,GAAA,QAAA,YAAW,SAAS,+DAA+D;YACxF,QAAQ;YACR,aAAa;YACb,OAAO,6BAAA;YACP,UAAU,CAAC,QAAQ;;UAErB,UAAU;YACR,MAAK,GAAA,QAAA,YAAW,SAAS,2DAA2D;YACpF,QAAQ;YACR,UAAU,CAAC,QAAQ;;;;MAIzB;QACE,IAAI;QACJ,MAAM;QACN,aAAa;QACb,WAAW,EAAE,OAAO,KAAK,QAAQ,IAAG;QACpC,QAAQ,QAAA;QACR,SAAS;UACP,MAAM;YACJ,MAAK,GAAA,QAAA,YAAW,SAAS,wDAAwD;YACjF,QAAQ;;UAEV,QAAQ;YACN,MAAK,GAAA,QAAA,YAAW,SAAS,+DAA+D;YACxF,QAAQ;YACR,aAAa;YACb,OAAO,6BAAA;YACP,UAAU,CAAC,QAAQ;;UAErB,UAAU;YACR,MAAK,GAAA,QAAA,YAAW,SAAS,2DAA2D;YACpF,QAAQ;YACR,UAAU,CAAC,QAAQ;;;;MAIzB;QACE,IAAI;QACJ,MAAM;QACN,aAAa;QACb,WAAW,EAAE,OAAO,KAAK,QAAQ,IAAG;QACpC,QAAQ,QAAA;QACR,SAAS;UACP,MAAM;YACJ,MAAK,GAAA,QAAA,YAAW,SAAS,wDAAwD;YACjF,QAAQ;;UAEV,QAAQ;YACN,MAAK,GAAA,QAAA,YAAW,SAAS,+DAA+D;YACxF,QAAQ;YACR,aAAa;YACb,OAAO,6BAAA;YACP,UAAU,CAAC,QAAQ;;UAErB,UAAU;YACR,MAAK,GAAA,QAAA,YAAW,SAAS,2DAA2D;YACpF,QAAQ;YACR,UAAU,CAAC,QAAQ;;;;;;;;;;;;;;;;ACxJ3B,IAAAC,SAAA,YAAA;AAWA,IAAAA,SAAA,aAAA;AAaA,IAAAA,SAAA,YAAAC;AAiDA,IAAAD,SAAA,qBAAA;AA2DA,IAAAA,SAAA,iBAAA;AAxIA,QAAA,UAAA,gBAAA,QAAA,OAAA,CAAA;AAIO,mBAAe,UACpB,MAAY;AAEZ,YAAM,EAAE,MAAM,KAAI,IAAK,OAAM,GAAA,QAAA,SAAM,IAAI,EACpC,YAAW,EACX,IAAG,EACH,SAAS,EAAE,mBAAmB,KAAI,CAAE;AACvC,aAAO,EAAE,MAAM,OAAO,KAAK,OAAO,QAAQ,KAAK,OAAM;IACvD;AAGO,mBAAe,WAAW,MAAc,KAAgB;AAC7D,cAAO,GAAA,QAAA,SAAM,IAAI,EACd,QAAQ;QACP,MAAM,KAAK,MAAM,IAAI,CAAC;QACtB,KAAK,KAAK,MAAM,IAAI,CAAC;QACrB,OAAO,KAAK,MAAM,IAAI,CAAC;QACvB,QAAQ,KAAK,MAAM,IAAI,CAAC;OACzB,EACA,KAAI,EACJ,SAAQ;IACb;AAGO,mBAAeC,WACpB,MACA,YAAkB;AASlB,YAAM,OAAO,OAAM,GAAA,QAAA,SAAM,IAAI,EAAE,SAAQ;AACvC,YAAM,gBAAgB,KAAK,SAAS;AACpC,YAAM,iBAAiB,KAAK,UAAU;AAEtC,YAAM,QAAQ,KAAK,IAAI,aAAa,eAAe,aAAa,cAAc;AAC9E,YAAM,cAAc,KAAK,MAAM,gBAAgB,KAAK;AACpD,YAAM,eAAe,KAAK,MAAM,iBAAiB,KAAK;AAEtD,YAAM,OAAO,KAAK,OAAO,aAAa,eAAe,CAAC;AACtD,YAAM,OAAO,KAAK,OAAO,aAAa,gBAAgB,CAAC;AAEvD,YAAM,EAAE,KAAI,IAAK,OAAM,GAAA,QAAA,SAAM,IAAI,EAC9B,OAAO,aAAa,YAAY,EAChC,OAAO;QACN,KAAK;QACL,QAAQ,aAAa,eAAe;QACpC,MAAM;QACN,OAAO,aAAa,cAAc;QAClC,YAAY,EAAE,GAAG,KAAK,GAAG,KAAK,GAAG,IAAG;OACrC,EACA,YAAW,EACX,IAAG,EACH,SAAS,EAAE,mBAAmB,KAAI,CAAE;AAGvC,YAAM,YAAY,aAAa;AAC/B,YAAM,UAAU,IAAI,aAAa,IAAI,SAAS;AAC9C,eAAS,IAAI,GAAG,IAAI,WAAW,KAAK;AAClC,cAAM,UAAU,IAAI;AACpB,gBAAQ,IAAI,YAAY,CAAC,IAAK,KAAK,OAAO,IAAK;AAC/C,gBAAQ,IAAI,YAAY,CAAC,IAAK,KAAK,UAAU,CAAC,IAAK;AACnD,gBAAQ,IAAI,YAAY,CAAC,IAAK,KAAK,UAAU,CAAC,IAAK;MACrD;AAEA,aAAO,EAAE,MAAM,SAAS,OAAO,MAAM,MAAM,eAAe,eAAc;IAC1E;AAGO,mBAAe,mBACpB,MACA,aACA,cACA,eACA,QAAuB;AAEvB,YAAM,EAAE,KAAI,IAAK,OAAM,GAAA,QAAA,SAAM,IAAI,EAC9B,OAAO,aAAa,cAAc,EAAE,KAAK,OAAM,CAAE,EACjD,YAAW,EACX,IAAG,EACH,SAAS,EAAE,mBAAmB,KAAI,CAAE;AAEvC,YAAM,YAAY,cAAc;AAChC,YAAM,UAAU,IAAI,aAAa,IAAI,SAAS;AAG9C,YAAM,OAAO,CAAC,OAAO,OAAO,KAAK;AACjC,YAAM,MAAM,CAAC,OAAO,OAAO,KAAK;AAEhC,UAAI,WAAW,QAAQ;AACrB,iBAAS,IAAI,GAAG,IAAI,WAAW,KAAK;AAClC,gBAAM,UAAU,IAAI;AACpB,mBAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,kBAAM,MAAM,KAAK,UAAU,CAAC,IAAK;AACjC,gBAAI;AACJ,gBAAI,kBAAkB,YAAY;AAChC,oBAAM;YACR,WAAW,kBAAkB,YAAY;AACvC,qBAAO,MAAM,KAAK,CAAC,KAAM,IAAI,CAAC;YAChC,OAAO;AACL,oBAAM,KAAK,UAAU,CAAC;YACxB;AACA,oBAAQ,IAAI,YAAY,CAAC,IAAI;UAC/B;QACF;MACF,OAAO;AAEL,iBAAS,IAAI,GAAG,IAAI,WAAW,KAAK;AAClC,gBAAM,UAAU,IAAI;AACpB,mBAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,kBAAM,MAAM,KAAK,UAAU,CAAC,IAAK;AACjC,gBAAI;AACJ,gBAAI,kBAAkB,YAAY;AAChC,oBAAM;YACR,WAAW,kBAAkB,YAAY;AACvC,qBAAO,MAAM,KAAK,CAAC,KAAM,IAAI,CAAC;YAChC,OAAO;AACL,oBAAM,KAAK,UAAU,CAAC;YACxB;AACA,oBAAQ,IAAI,IAAI,CAAC,IAAI;UACvB;QACF;MACF;AAEA,aAAO;IACT;AAGA,aAAgB,eAAe,KAAa,OAAe,QAAc;AACvE,YAAM,YAAY,QAAQ;AAC1B,YAAM,OAAO,IAAI,WAAW,SAAS;AACrC,eAAS,IAAI,GAAG,IAAI,WAAW,KAAK;AAClC,cAAM,IAAI,IAAI,IAAI,CAAC;AACnB,cAAM,IAAI,IAAI,IAAI,IAAI,CAAC;AACvB,cAAM,IAAI,IAAI,IAAI,IAAI,CAAC;AAEvB,aAAK,CAAC,IAAI,KAAK,MAAM,QAAQ,IAAI,QAAQ,IAAI,QAAQ,CAAC;MACxD;AACA,aAAO;IACT;;;;;;;;;ACrIA,IAAAC,SAAA,MAAA;AA8BA,IAAAA,SAAA,MAAA;AA0BA,IAAAA,SAAA,kBAAAC;AAxDA,aAAgB,IAAI,GAAgB,GAAc;AAChD,YAAM,MAAM,EAAE;AACd,YAAM,MAAM,EAAE;AACd,YAAM,MAAM,EAAE,IAAI,EAAE;AACpB,YAAM,MAAM,EAAE,IAAI,EAAE;AAEpB,YAAM,MAAM,EAAE;AACd,YAAM,MAAM,EAAE;AACd,YAAM,MAAM,EAAE,IAAI,EAAE;AACpB,YAAM,MAAM,EAAE,IAAI,EAAE;AAEpB,YAAM,UAAU,KAAK,IAAI,KAAK,GAAG;AACjC,YAAM,UAAU,KAAK,IAAI,KAAK,GAAG;AACjC,YAAM,UAAU,KAAK,IAAI,KAAK,GAAG;AACjC,YAAM,UAAU,KAAK,IAAI,KAAK,GAAG;AAEjC,YAAM,SAAS,KAAK,IAAI,GAAG,UAAU,OAAO;AAC5C,YAAM,SAAS,KAAK,IAAI,GAAG,UAAU,OAAO;AAC5C,YAAM,YAAY,SAAS;AAE3B,UAAI,cAAc;AAAG,eAAO;AAE5B,YAAM,QAAQ,EAAE,IAAI,EAAE;AACtB,YAAM,QAAQ,EAAE,IAAI,EAAE;AACtB,YAAM,YAAY,QAAQ,QAAQ;AAElC,aAAO,cAAc,IAAI,IAAI,YAAY;IAC3C;AAGA,aAAgB,IACd,OACA,cAAoB;AAEpB,YAAM,UAAU,MACb,IAAI,CAAC,GAAG,MAAM,CAAC,EACf,KAAK,CAAC,GAAG,MAAO,MAAM,CAAC,EAAG,QAAU,MAAM,CAAC,EAAG,KAAM;AAEvD,YAAM,OAAiB,CAAA;AACvB,YAAM,aAAa,oBAAI,IAAG;AAE1B,iBAAW,OAAO,SAAS;AACzB,YAAI,WAAW,IAAI,GAAG;AAAG;AACzB,aAAK,KAAK,GAAG;AACb,mBAAW,SAAS,SAAS;AAC3B,cAAI,UAAU,OAAO,WAAW,IAAI,KAAK;AAAG;AAC5C,cAAI,IAAI,MAAM,GAAG,EAAG,MAAM,MAAM,KAAK,EAAG,IAAI,IAAI,cAAc;AAC5D,uBAAW,IAAI,KAAK;UACtB;QACF;MACF;AAEA,aAAO;IACT;AAGA,aAAgBA,iBACd,QACA,YACA,UACA,SAA+B;AAE/B,YAAM,EAAE,YAAY,cAAc,QAAQ,OAAO,MAAM,MAAM,eAAe,eAAc,IAAK;AAQ/F,YAAM,aAA0B,CAAA;AAEhC,eAAS,IAAI,GAAG,IAAI,UAAU,KAAK;AAEjC,cAAM,KAAK,OAAO,IAAI,WAAW,CAAC;AAClC,cAAM,KAAK,OAAO,IAAI,WAAW,CAAC;AAClC,cAAM,IAAI,OAAO,IAAI,WAAW,CAAC;AACjC,cAAM,IAAI,OAAO,IAAI,WAAW,CAAC;AAEjC,YAAI,YAAY;AAChB,YAAI,YAAY;AAEhB,iBAAS,IAAI,GAAG,IAAI,YAAY,KAAK;AACnC,gBAAM,QAAQ,QAAQ,IAAI,KAAK,WAAW,CAAC;AAC3C,cAAI,QAAQ,WAAW;AACrB,wBAAY;AACZ,wBAAY;UACd;QACF;AAEA,YAAI,YAAY;AAAY;AAG5B,cAAM,OAAoB;UACxB,GAAG,KAAK,IAAI;UACZ,GAAG,KAAK,IAAI;UACZ;UACA;;AAGF,mBAAW,KAAK,EAAE,MAAM,OAAO,WAAW,UAAU,UAAS,CAAE;MACjE;AAEA,UAAI,WAAW,WAAW;AAAG,eAAO,CAAA;AAEpC,YAAM,cAAc,IAAI,YAAY,YAAY;AAEhD,aAAO,YAAY,IAAI,CAAC,QAAO;AAC7B,cAAM,EAAE,MAAM,OAAO,SAAQ,IAAK,WAAW,GAAG;AAChD,cAAM,QAAQ,OAAO,QAAQ,KAAK,OAAO,QAAQ;AAGjD,cAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,gBAAgB,KAAK,IAAI,QAAQ,KAAK,CAAC;AACtE,cAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,iBAAiB,KAAK,IAAI,QAAQ,KAAK,CAAC;AACvE,cAAM,KAAK,KAAK,IAAI,GAAG,KAAK,IAAI,gBAAgB,KAAK,IAAI,KAAK,IAAI,QAAQ,KAAK,CAAC;AAChF,cAAM,KAAK,KAAK,IAAI,GAAG,KAAK,IAAI,iBAAiB,KAAK,IAAI,KAAK,IAAI,QAAQ,KAAK,CAAC;AAEjF,cAAM,YAAyB,EAAE,GAAG,GAAG,GAAG,KAAK,GAAG,GAAG,KAAK,EAAC;AAE3D,eAAO;UACL,OAAO;UACP,eAAe;UACf;UACA,MAAM;;MAEV,CAAC;IACH;;;;;;;;;ACnHA,IAAAC,SAAA,UAAA;AAcA,IAAAA,SAAA,iBAAA;AAmCA,IAAAA,SAAA,uBAAA;AA2CA,IAAAA,SAAA,qBAAAC;AApHA,QAAA,YAAA;AAwBA,aAAgB,QAAQ,GAAS;AAC/B,aAAO,KAAK,IAAI,KAAK,IAAI,CAAC,CAAC;IAC7B;AAYA,aAAgB,eACd,QACA,QACA,eACA,OACA,OAAa;AAEb,YAAM,WAAW,QAAQ;AACzB,YAAM,UAAU,IAAI,aAAa,QAAQ;AAIzC,eAAS,KAAK,GAAG,KAAK,UAAU,MAAM;AACpC,YAAI,MAAM;AACV,iBAAS,IAAI,GAAG,IAAI,eAAe,KAAK;AACtC,kBAAQ,OAAO,CAAC,KAAK,MAAM,OAAO,IAAI,WAAW,EAAE,KAAK;QAC1D;AACA,gBAAQ,EAAE,IAAI,QAAQ,GAAG;MAC3B;AAEA,aAAO;IACT;AAcA,aAAgB,qBACd,SACA,OACA,OACA,MACA,eACA,WAAiB;AAEjB,YAAM,SAAS,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,IAAI,SAAS,CAAC;AACzD,YAAM,SAAS,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,IAAI,SAAS,CAAC;AACzD,YAAM,SAAS,KAAK,IAAI,OAAO,KAAK,MAAM,KAAK,IAAI,KAAK,KAAK,SAAS,CAAC;AACvE,YAAM,SAAS,KAAK,IAAI,OAAO,KAAK,MAAM,KAAK,IAAI,KAAK,KAAK,SAAS,CAAC;AAEvE,YAAM,QAAQ,KAAK,IAAI,GAAG,SAAS,MAAM;AACzC,YAAM,QAAQ,KAAK,IAAI,GAAG,SAAS,MAAM;AAEzC,YAAM,OAAO,IAAI,WAAW,QAAQ,KAAK;AAEzC,eAAS,MAAM,GAAG,MAAM,OAAO,OAAO;AACpC,cAAM,SAAS,SAAS;AACxB,iBAAS,MAAM,GAAG,MAAM,OAAO,OAAO;AACpC,gBAAM,SAAS,SAAS;AACxB,gBAAM,SAAS,SAAS,QAAQ;AAChC,eAAK,MAAM,QAAQ,GAAG,KAAK,QAAQ,MAAM,KAAK,KAAK,gBAAgB,MAAM;QAC3E;MACF;AAEA,aAAO,EAAE,MAAM,OAAO,OAAO,QAAQ,MAAK;IAC5C;AAeA,aAAgBA,oBACd,WACA,SAAkC;AAElC,YAAM,EACJ,iBACA,aACA,YACA,UACA,eACA,YACA,UAAS,IACP;AAEJ,YAAM,EACJ,YACA,cACA,QACA,OACA,MACA,MACA,eACA,gBACA,gBAAgB,IAAG,IACjB;AAOJ,YAAM,gBAAgB;AACtB,YAAM,YAAY,aAAa;AAS/B,YAAM,aAA0B,CAAA;AAEhC,eAAS,IAAI,GAAG,IAAI,UAAU,KAAK;AACjC,cAAM,KAAK,gBAAgB,IAAI,WAAW,CAAC,KAAK;AAChD,cAAM,KAAK,gBAAgB,IAAI,WAAW,CAAC,KAAK;AAChD,cAAM,IAAI,gBAAgB,IAAI,WAAW,CAAC,KAAK;AAC/C,cAAM,IAAI,gBAAgB,IAAI,WAAW,CAAC,KAAK;AAE/C,YAAI,YAAY;AAChB,YAAI,YAAY;AAEhB,iBAAS,IAAI,GAAG,IAAI,YAAY,KAAK;AACnC,gBAAM,QAAQ,iBAAiB,IAAI,KAAK,WAAW,CAAC,KAAK;AACzD,cAAI,QAAQ,WAAW;AACrB,wBAAY;AACZ,wBAAY;UACd;QACF;AAEA,YAAI,YAAY;AAAY;AAE5B,cAAM,OAAoB;UACxB,GAAG,KAAK,IAAI;UACZ,GAAG,KAAK,IAAI;UACZ;UACA;;AAIF,cAAM,SAAS,IAAI,aAAa,aAAa;AAC7C,iBAAS,IAAI,GAAG,IAAI,eAAe,KAAK;AACtC,iBAAO,CAAC,IAAI,iBAAiB,IAAI,aAAa,KAAK,WAAW,CAAC,KAAK;QACtE;AAEA,mBAAW,KAAK,EAAE,MAAM,OAAO,WAAW,UAAU,WAAW,OAAM,CAAE;MACzE;AAEA,UAAI,WAAW,WAAW;AAAG,eAAO,CAAA;AAEpC,YAAM,eAAc,GAAA,UAAA,KAAI,YAAY,YAAY;AAEhD,aAAO,YAAY,IAAI,CAAC,QAAO;AAC7B,cAAM,EAAE,MAAM,OAAO,UAAU,OAAM,IAAK,WAAW,GAAG;AACxD,cAAM,QAAQ,OAAO,QAAQ,KAAK,OAAO,QAAQ;AAGjD,cAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,gBAAgB,KAAK,IAAI,QAAQ,KAAK,CAAC;AACtE,cAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,iBAAiB,KAAK,IAAI,QAAQ,KAAK,CAAC;AACvE,cAAM,KAAK,KAAK,IAAI,GAAG,KAAK,IAAI,gBAAgB,KAAK,IAAI,KAAK,IAAI,QAAQ,KAAK,CAAC;AAChF,cAAM,KAAK,KAAK,IAAI,GAAG,KAAK,IAAI,iBAAiB,KAAK,IAAI,KAAK,IAAI,QAAQ,KAAK,CAAC;AACjF,cAAM,YAAyB,EAAE,GAAG,GAAG,GAAG,KAAK,GAAG,GAAG,KAAK,EAAC;AAG3D,cAAM,UAAU,eAAe,QAAQ,aAAa,eAAe,YAAY,SAAS;AACxF,cAAM,EAAE,MAAM,UAAU,OAAO,IAAI,QAAQ,GAAE,IAAK,qBAChD,SACA,YACA,WACA,MACA,eACA,SAAS;AAGX,eAAO;UACL,OAAO;UACP,eAAe;UACf;UACA,MAAM;UACN,MAAM;UACN,WAAW;UACX,YAAY;;MAEhB,CAAC;IACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACtOA,QAAA,OAAA,aAAA,QAAA,MAAA,CAAA;AAEA,QAAM,sBAAwD;MAC5D,KAAK;MACL,QAAQ;MACR,MAAM;MACN,UAAU;MACV,KAAK;;AAGP,QAAM,oBAA+D;MACnE,KAAK;MACL,QAAQ;MACR,MAAM;MACN,UAAU;;AAGZ,QAAa,sBAAb,MAAgC;MAMX;MACA;MANV,UAA4B;MAC5B;MACD,UAAmB;MAE3B,YACmB,WACA,SAAe;AADf,aAAA,YAAA;AACA,aAAA,UAAA;AAEjB,aAAK,SAAU,kBAAkB,OAAO,KAAK;MAC/C;MAEA,MAAM,aAAU;AACd,cAAM,MAAM,MAAA,QAAA,QAAA,EAAA,KAAA,MAAA,aAAA,QAAa,kBAAkB,CAAA,CAAA;AAC3C,cAAM,WAAW,oBAAoB,KAAK,OAAO,KAAK;AAGtD,cAAM,eAAe,KAAK,WAAW,KAAK,SAAS,IAC/C,KAAK,YACL,KAAK,QAAQ,QAAQ,IAAG,GAAI,KAAK,SAAS;AAE9C,cAAM,iBAA0C;UAC9C,oBAAoB,CAAC,QAAQ;;AAI/B,aAAK,UAAU,MAAO,IAAY,iBAAiB,OAAO,cAAc,cAAc;MACxF;MAEA,MAAM,IAAI,OAAqB,YAA6B;AAC1D,YAAI,CAAC,KAAK,SAAS;AACjB,gBAAM,IAAI,MAAM,qEAAgE;QAClF;AAEA,cAAM,MAAM,MAAA,QAAA,QAAA,EAAA,KAAA,MAAA,aAAA,QAAa,kBAAkB,CAAA,CAAA;AAE3C,cAAM,OAAO,KAAK;AAGlB,cAAM,YAAoB,KAAK,WAAW,CAAC;AAE3C,cAAM,SAAS,IAAK,IAAY,OAAO,WAAW,OAAO,CAAC,GAAG,UAAU,CAAC;AACxE,cAAM,QAAiC,EAAE,CAAC,SAAS,GAAG,OAAM;AAE5D,cAAM,UAAU,MAAM,KAAK,IAAI,KAAK;AACpC,cAAM,aAAqB,KAAK,YAAY,CAAC;AAC7C,cAAM,eAAe,QAAQ,UAAU;AAEvC,eAAO,aAAa;MACtB;MAEA,MAAM,eACJ,OACA,YAA6B;AAE7B,YAAI,CAAC,KAAK,SAAS;AACjB,gBAAM,IAAI,MAAM,qEAAgE;QAClF;AAEA,cAAM,MAAM,MAAA,QAAA,QAAA,EAAA,KAAA,MAAA,aAAA,QAAa,kBAAkB,CAAA,CAAA;AAE3C,cAAM,OAAO,KAAK;AAElB,cAAM,YAAoB,KAAK,WAAW,CAAC;AAE3C,cAAM,SAAS,IAAK,IAAY,OAAO,WAAW,OAAO,CAAC,GAAG,UAAU,CAAC;AACxE,cAAM,QAAiC,EAAE,CAAC,SAAS,GAAG,OAAM;AAE5D,cAAM,UAAU,MAAM,KAAK,IAAI,KAAK;AAEpC,cAAM,MAAoC,CAAA;AAC1C,mBAAW,QAAQ,KAAK,aAAyB;AAC/C,cAAI,IAAI,IAAI,QAAQ,IAAI,EAAE;QAC5B;AACA,eAAO;MACT;MAEA,MAAM,UAAO;AAGX,aAAK,UAAU;MACjB;;AAjFF,IAAAC,SAAA,sBAAA;;;;;;;;;;AC4IA,IAAAC,SAAA,sBAAA;AA7JA,QAAA,uBAAA,QAAA,eAAA;AAEA,QAAa,wBAAb,MAAkC;MASb;MACA;MAEA;MACA;MAZV;MACA;MACD,UAA+B;MAC/B,gBAAwB,OAAO,MAAM,CAAC;MACtC,iBAAoE;MACpE,gBAAkD;MAE1D,YACmB,YACA,YACjB,SACiB,WACA,YAA+B,CAAA,GAAE;AAJjC,aAAA,aAAA;AACA,aAAA,aAAA;AAEA,aAAA,YAAA;AACA,aAAA,YAAA;AAEjB,aAAK,UAAU;AAEf,cAAM,mBAAwE;UAC5E,MAAM;UACN,QAAQ;UACR,SAAS;UACT,UAAU;UACV,QAAQ;;AAEV,aAAK,SAAS,iBAAiB,OAAO;MACxC;MAEA,MAAM,aAAU;AACd,cAAM,OAAO,CAAC,KAAK,YAAY,KAAK,WAAW,GAAG,KAAK,SAAS;AAChE,aAAK,WAAU,GAAA,qBAAA,OAAM,KAAK,YAAY,MAAM;UAC1C,OAAO,CAAC,QAAQ,QAAQ,MAAM;SAC/B;AAED,YAAI,CAAC,KAAK,QAAQ,UAAU,CAAC,KAAK,QAAQ,OAAO;AAC/C,gBAAM,IAAI,MAAM,uDAAuD;QACzE;AAEA,aAAK,QAAQ,QAAQ,GAAG,QAAQ,CAAC,UAAiB;AAEhD,kBAAQ,OAAO,MAAM,mBAAmB,MAAM,SAAQ,CAAE,EAAE;QAC5D,CAAC;AAED,aAAK,QAAQ,GAAG,SAAS,CAAC,QAAO;AAC/B,eAAK,gBAAgB,GAAG;AACxB,eAAK,gBAAgB;AACrB,eAAK,iBAAiB;QACxB,CAAC;AAED,aAAK,QAAQ,GAAG,QAAQ,CAAC,SAAQ;AAC/B,cAAI,SAAS,GAAG;AACd,kBAAM,MAAM,IAAI,MAAM,mDAAmD,IAAI,EAAE;AAC/E,iBAAK,gBAAgB,GAAG;AACxB,iBAAK,gBAAgB;AACrB,iBAAK,iBAAiB;UACxB;QACF,CAAC;AAED,aAAK,QAAQ,OAAO,GAAG,QAAQ,CAAC,UAAiB;AAC/C,eAAK,gBAAgB,OAAO,OAAO,CAAC,KAAK,eAAe,KAAK,CAAC;AAC9D,eAAK,YAAW;QAClB,CAAC;AAGD,cAAM,IAAI,QAAc,CAAC,SAAS,WAAU;AAC1C,gBAAM,UAAU,WAAW,MAAM,QAAO,GAAI,GAAI;AAChD,eAAK,SAAS,GAAG,SAAS,CAAC,QAAO;AAChC,yBAAa,OAAO;AACpB,mBAAO,GAAG;UACZ,CAAC;AACD,eAAK,SAAS,GAAG,QAAQ,CAAC,SAAQ;AAChC,yBAAa,OAAO;AACpB,gBAAI,SAAS,GAAG;AACd,qBAAO,IAAI,MAAM,yDAAyD,IAAI,EAAE,CAAC;YACnF;UACF,CAAC;QACH,CAAC;MACH;MAEQ,cAAW;AAEjB,YAAI,KAAK,cAAc,SAAS;AAAG;AAEnC,cAAM,SAAS,KAAK,cAAc,aAAa,CAAC;AAChD,YAAI,KAAK,cAAc,SAAS,IAAI;AAAQ;AAE5C,cAAM,YAAY,KAAK,cAAc,SAAS,GAAG,IAAI,MAAM;AAC3D,aAAK,gBAAgB,KAAK,cAAc,SAAS,IAAI,MAAM;AAE3D,cAAM,UAAU,KAAK;AACrB,cAAM,SAAS,KAAK;AACpB,aAAK,iBAAiB;AACtB,aAAK,gBAAgB;AAErB,YAAI,CAAC;AAAS;AAEd,YAAI;AACF,gBAAM,SAAS,KAAK,MAAM,UAAU,SAAS,MAAM,CAAC;AACpD,kBAAQ,MAAM;QAChB,SAAS,KAAK;AACZ,mBAAS,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC,CAAC;QAC9D;MACF;;MAGA,MAAM,QAAQ,MAAY;AACxB,YAAI,CAAC,KAAK,SAAS,OAAO;AACxB,gBAAM,IAAI,MAAM,gDAAgD;QAClE;AAEA,eAAO,IAAI,QAAiC,CAAC,SAAS,WAAU;AAC9D,eAAK,iBAAiB;AACtB,eAAK,gBAAgB;AAGrB,gBAAM,YAAY,OAAO,YAAY,CAAC;AACtC,oBAAU,cAAc,KAAK,QAAQ,CAAC;AACtC,eAAK,QAAS,MAAO,MAAM,OAAO,OAAO,CAAC,WAAW,IAAI,CAAC,CAAC;QAC7D,CAAC;MACH;;MAGA,MAAM,IAAI,QAAsB,aAA8B;AAC5D,cAAM,IAAI,MACR,yFAAoF;MAExF;;MAGA,MAAM,eACJ,QACA,aAA8B;AAE9B,cAAM,IAAI,MACR,oGAA+F;MAEnG;MAEA,MAAM,UAAO;AACX,YAAI,KAAK,SAAS;AAChB,eAAK,QAAQ,OAAO,IAAG;AACvB,eAAK,QAAQ,KAAK,SAAS;AAC3B,eAAK,UAAU;QACjB;MACF;;AA/IF,IAAAA,SAAA,wBAAA;AA2JO,mBAAe,oBACpB,YACA,MAAuB;AAEvB,UAAI;AAAY,eAAO;AACvB,aAAO,KAAK,aAAY;IAC1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC3EA,IAAAC,SAAA,gBAAAC;AAyHA,IAAAD,SAAA,oBAAA;AAxLA,QAAA,KAAA,aAAA,QAAA,IAAA,CAAA;AACA,QAAA,OAAA,aAAA,QAAA,MAAA,CAAA;AACA,QAAA,mBAAA;AACA,QAAA,qBAAA;AAmBA,QAAM,wBAAwB,CAAC,UAAU,QAAQ,YAAY,KAAK;AAMlE,QAAM,oBAA2D;MAC/D,KAAK;MACL,QAAQ;MACR,MAAM;MACN,UAAU;;AAIZ,QAAM,oBAA8E;MAClF,MAAM;MACN,QAAQ;MACR,UAAU;MACV,QAAQ;MACR,SAAS;;AAGX,aAAS,cAAc,WAAmB,YAA+B,QAAmB;AAC1F,YAAM,cAAc,WAAW,QAAQ,MAAM;AAC7C,UAAI,CAAC,aAAa;AAChB,cAAM,IAAI,MAAM,SAAS,WAAW,EAAE,WAAW,MAAM,SAAS;MAClE;AAEA,YAAM,WAAW,YAAY,IAAI,MAAM,GAAG;AAC1C,YAAM,WAAW,SAAS,SAAS,SAAS,CAAC,KAAK,GAAG,WAAW,EAAE,IAAI,MAAM;AAC5E,aAAO,KAAK,KAAK,WAAW,QAAQ;IACtC;AAEA,aAAS,YAAY,UAAgB;AACnC,UAAI;AACF,eAAO,GAAG,WAAW,QAAQ;MAC/B,QAAQ;AACN,eAAO;MACT;IACF;AAEO,mBAAeC,eAAc,SAA8B;AAChE,YAAM,EAAE,SAAS,SAAS,YAAY,WAAW,OAAM,IAAK;AAE5D,UAAI;AACJ,UAAI;AAEJ,UAAI,YAAY,QAAQ;AAEtB,cAAM,YAAY,MAAM,kBAAiB;AAGzC,YAAI,SAA0D;AAE9D,mBAAW,KAAK,uBAAuB;AACrC,cAAI,CAAC,UAAU,SAAS,CAAC;AAAG;AAC5B,gBAAM,MAAM,kBAAkB,CAAC;AAC/B,cAAI,CAAC;AAAK;AACV,cAAI,CAAC,WAAW,QAAQ,GAAG;AAAG;AAC9B,mBAAS,EAAE,SAAS,GAAG,QAAQ,IAAG;AAClC;QACF;AAEA,YAAI,CAAC,QAAQ;AACX,gBAAM,IAAI,MACR,wDAAwD,WAAW,EAAE,yBAAyB,UAAU,KAAK,IAAI,CAAC,EAAE;QAExH;AAEA,yBAAiB,OAAO;AACxB,0BAAkB,OAAO;MAC3B,OAAO;AAEL,cAAM,MAAM,kBAAkB,OAAO;AACrC,YAAI,CAAC,KAAK;AACR,gBAAM,IAAI,MAAM,uCAAuC,OAAO,GAAG;QACnE;AACA,YAAI,CAAC,WAAW,QAAQ,GAAG,GAAG;AAC5B,gBAAM,IAAI,MACR,wBAAwB,WAAW,EAAE,WAAW,GAAG,uBAAuB,OAAO,EAAE;QAEvF;AACA,yBAAiB;AAEjB,0BAAkB,YAAY,SAAU,WAAW,QAAS;MAC9D;AAGA,UAAI;AAEJ,UAAI,QAAQ;AAEV,oBAAY,MAAM,OAAO,OAAO,WAAW,IAAI,cAAc;MAC/D,OAAO;AAEL,oBAAY,cAAc,WAAW,YAAY,cAAc;AAC/D,YAAI,CAAC,YAAY,SAAS,GAAG;AAC3B,gBAAM,IAAI,MACR,0CAA0C,SAAS,gCAAgC;QAEvF;MACF;AAIA,UAAI,mBAAmB,QAAQ;AAC7B,cAAM,SAAS,IAAI,iBAAA,oBAAoB,WAAW,eAAe;AACjE,cAAM,OAAO,WAAU;AACvB,eAAO,EAAE,QAAQ,QAAQ,gBAAgB,UAAS;MACpD;AAGA,YAAM,EAAE,WAAU,IAAK;AACvB,YAAM,oBAAsD;QAC1D,QAAQ;QACR,SAAS;QACT,UAAU;;AAGZ,YAAM,mBAAmB,YAAY,SAAS,kBAAkB;AAChE,YAAM,aAAa,kBAAkB,gBAAgB;AAErD,UAAI,cAAc,YAAY;AAK5B,cAAM,aAAa;UACjB,KAAK,KAAK,WAAW,gBAAgB,UAAU;UAC/C,KAAK,KAAK,WAAW,aAAa,UAAU;UAC5C,KAAK,KAAK,WAAW,mBAAmB,UAAU;;AAEpD,cAAM,aAAa,WAAW,KAAK,OAAK,GAAG,WAAW,CAAC,CAAC;AACxD,YAAI,CAAC,YAAY;AACf,gBAAM,IAAI,MACR,iCAAiC,UAAU;EAA2B,WAAW,KAAK,IAAI,CAAC,EAAE;QAEjG;AACA,cAAM,YAAY,KAAK,IAAI,WAAW,UAAU,OAAO,WAAW,UAAU,MAAM;AAClF,cAAM,SAAS,IAAI,mBAAA,sBAAsB,YAAY,YAAY,kBAAsC,WAAW;UAChH,gBAAgB,SAAS;UACzB;SACD;AACD,cAAM,OAAO,WAAU;AACvB,eAAO,EAAE,QAAQ,QAAQ,gBAAgB,UAAS;MACpD;AAGA,YAAM,eAAe,cAAc,WAAW,YAAY,MAAM;AAChE,UAAI,WAAW,QAAQ,MAAM,KAAK,YAAY,YAAY,GAAG;AAC3D,cAAM,SAAS,IAAI,iBAAA,oBAAoB,cAAc,KAAK;AAC1D,cAAM,OAAO,WAAU;AACvB,eAAO,EAAE,QAAQ,QAAQ,QAAQ,WAAW,aAAY;MAC1D;AAEA,YAAM,IAAI,MACR,yBAAyB,cAAc,2GACsB;IAEjE;AAGO,mBAAe,oBAAiB;AACrC,YAAM,YAAsB,CAAC,KAAK;AAElC,UAAI;AACF,cAAM,MAAM,MAAA,QAAA,QAAA,EAAA,KAAA,MAAA,aAAA,QAAa,kBAAkB,CAAA,CAAA;AAE3C,cAAM,YAAuB,IAAY,KAAK,OAAO,aAAa,SAE5D,IAAY,kBAAkB,wBAAuB,KAAM,CAAA,IAC7D,CAAA;AAEJ,mBAAW,KAAK,WAAW;AACzB,gBAAM,aAAa,EAAE,YAAW,EAAG,QAAQ,qBAAqB,EAAE;AAClE,cAAI,eAAe;AAAU,sBAAU,KAAK,QAAQ;mBAC3C,eAAe;AAAQ,sBAAU,KAAK,MAAM;mBAC5C,eAAe;AAAY,sBAAU,KAAK,UAAU;QAC/D;MACF,QAAQ;MAER;AAGA,UAAI,QAAQ,aAAa,YAAY,CAAC,UAAU,SAAS,QAAQ,GAAG;AAClE,kBAAU,KAAK,QAAQ;MACzB;AAEA,aAAO,CAAC,GAAG,IAAI,IAAI,SAAS,CAAC;IAC/B;;;;;AC7OA;AAAA;AAAA;AAAA;AAAA;AAkBA,qCAAwC;AACxC,iCAAoC;AACpC,mBAA4D;AAC5D,yBAA0B;AAC1B,kBAAgC;AAChC,sBAAmC;AACnC,6BAA8B;AAG9B,SAAS,WAAW,SAA0B;AAC5C,SAAO,QAAQ,SAAS,MAAM;AAChC;AAGA,IAAM,uBAAqD;AAAA,EACzD,GAAG;AAAA,EACH,GAAG;AACL;AAYA,SAAS,cACP,YACA,UACoB;AACpB,SAAO,WACJ,OAAO,CAAC,MAAM,SAAS,QAAQ,EAAE,KAAK,MAAM,MAAS,EACrD,IAAI,CAAC,OAAO;AAAA,IACX,GAAG;AAAA,IACH,eAAe,EAAE;AAAA,IACjB,OAAO,SAAS,QAAQ,EAAE,KAAK;AAAA,EACjC,EAAE;AACN;AAGA,IAAM,gBAAwC;AAAA,EAC5C,WAAW;AAAA,EAAI,WAAW;AAAA,EAAK,gBAAgB;AAAA,EAAK,WAAW;AAAA,EAAK,WAAW;AAAA,EAAK,WAAW;AAAA,EAC/F,WAAW;AAAA,EAAI,WAAW;AAAA,EAAK,WAAW;AAAA,EAC1C,WAAW;AAAA,EAAI,WAAW;AAAA,EAAK,WAAW;AAAA,EAAK,WAAW;AAAA,EAAK,WAAW;AAAA,EAC1E,eAAe;AAAA,EAAI,eAAe;AAAA,EAAK,eAAe;AAAA,EACtD,eAAe;AAAA,EAAI,eAAe;AAAA,EAAK,eAAe;AACxD;AAQA,IAAM,kBAA0C;AAAA,EAC9C,WAAW;AAAA,EAAI,WAAW;AAAA,EAAI,gBAAgB;AAAA,EAAI,WAAW;AAAA,EAAI,WAAW;AAAA,EAAI,WAAW;AAAA,EAC3F,WAAW;AAAA,EAAI,WAAW;AAAA,EAAI,WAAW;AAAA,EACzC,WAAW;AAAA,EAAI,WAAW;AAAA,EAAI,WAAW;AAAA,EAAI,WAAW;AAAA,EAAI,WAAW;AAAA,EACvE,eAAe;AAAA,EAAI,eAAe;AAAA,EAAI,eAAe;AAAA,EACrD,eAAe;AAAA,EAAI,eAAe;AAAA,EAAI,eAAe;AACvD;AAEA,IAAqB,uBAArB,MAAwF;AAAA,EAC7E,KAAK;AAAA,EACL,OAAO;AAAA,EACP,eAAyC;AAAA,EACzC,gBAAgB,CAAC,UAAU,WAAW,QAAQ;AAAA,EAC9C,eAAe;AAAA,EACf,WAA0B;AAAA,IACjC,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IAET,aAAa;AAAA,IAEb,MAAM;AAAA,IACN,cAAc;AAAA,IACd,eAAe,CAAC,UAAU,WAAW,QAAQ;AAAA,IAC7C,sBAAsB;AAAA,IACtB,kBAAkB;AAAA,IAClB,eAAe;AAAA,MACb,SAAS;AAAA,MACT,SAAS;AAAA,MACT,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,cAAc;AAAA,MACd,cAAc;AAAA,IAChB;AAAA,EACF;AAAA,EAEQ,SAAkC;AAAA,EAClC;AAAA,EACA,aAAa;AAAA,EACb,eAAe;AAAA,EACf,eAA6B;AAAA,EAC7B,iBAAiD;AAAA,EACjD,MAA2B;AAAA,EAEnC,uBAA2C;AACzC,WAAO,qBAAqB,IAAI,CAAC,OAAO;AAAA,MACtC,SAAS,EAAE;AAAA,MACX,MAAM,EAAE;AAAA,MACR,WAAW,cAAc,EAAE,EAAE,KAAK;AAAA,MAClC,eAAe,gBAAgB,EAAE,EAAE,KAAK;AAAA,MACxC,SAAS,OAAO,KAAK,EAAE,OAAO;AAAA,IAChC,EAAE;AAAA,EACJ;AAAA,EAEA,UAAU,QAAuC;AAC/C,SAAK,iBAAiB;AAAA,EACxB;AAAA,EAEA,MAAM,WAAW,KAAkC;AACjD,SAAK,MAAM;AACX,UAAM,MAAM,IAAI;AAChB,UAAM,UAAW,IAAI,SAAS,KAA4B,KAAK,gBAAgB,WAAW;AAC1F,SAAK,aAAc,IAAI,YAAY,KAA4B;AAC/D,SAAK,eAAgB,IAAI,cAAc,KAA4B;AACnE,SAAK,eAAgB,IAAI,cAAc,KAAkC;AAEzE,UAAM,QAAQ,qBAAqB,KAAK,CAAC,MAAM,EAAE,OAAO,OAAO;AAC/D,QAAI,CAAC,OAAO;AACV,YAAM,IAAI,MAAM,0CAA0C,OAAO,GAAG;AAAA,IACtE;AACA,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,MAAM,OAAO,OAA4C;AACvD,QAAI,CAAC,KAAK,OAAQ,OAAM,KAAK,aAAa;AAC1C,UAAM,QAAQ,KAAK,IAAI;AAGvB,QAAI,aAAa,KAAK,UAAW,OAAQ,KAAK,OAAe,YAAY,YAAY;AACnF,YAAM,SAAS,MAAO,KAAK,OAAe,QAAQ,MAAM,IAAI;AAC5D,YAAM,UAAW,OAAO,cAAc,CAAC;AACvC,YAAMC,cAAiC,QAAQ,IAAI,CAAC,OAAO;AAAA,QACzD,OAAO,KAAK,iBAAiB,QAAQ,EAAE,YAAa,2BAAc,QAAQ,EAAE,SAAS,KAAK,EAAE;AAAA,QAC5F,eAAe,EAAE;AAAA,QACjB,OAAO,EAAE;AAAA,QACT,MAAM;AAAA,UACJ,GAAG,EAAE,KAAK,CAAC,IAAK,MAAM;AAAA,UACtB,GAAG,EAAE,KAAK,CAAC,IAAK,MAAM;AAAA,UACtB,IAAI,EAAE,KAAK,CAAC,IAAK,EAAE,KAAK,CAAC,KAAM,MAAM;AAAA,UACrC,IAAI,EAAE,KAAK,CAAC,IAAK,EAAE,KAAK,CAAC,KAAM,MAAM;AAAA,QACvC;AAAA,MACF,EAAE,EAAE,OAAO,CAAC,MAAM,KAAK,iBAAiB,SAAS,2BAAc,QAAQ,EAAE,aAAc,MAAM,MAAS;AAEtG,aAAO;AAAA,QACL,YAAAA;AAAA,QACA,aAAc,OAAO,eAA2B,KAAK,IAAI,IAAI;AAAA,QAC7D,SAAS,KAAK,WAAW;AAAA,MAC3B;AAAA,IACF;AAGA,UAAM,EAAE,OAAO,QAAQ,QAAQ,OAAO,IAAI,KAAK,WAAW;AAC1D,UAAM,aAAa,KAAK,IAAI,QAAQ,MAAM;AAE1C,UAAM,KAAK,UAAM,8BAAU,MAAM,MAAM,UAAU;AAEjD,UAAM,aAAa,KAAK,WAAW,OAAO;AAC1C,UAAM,SAAS,KAAK,WAAW,OAAO,IAAI,CAAC,MAAM,EAAE,EAAE;AACrD,UAAM,kBAAkB;AAAA,MACtB,YAAY,KAAK;AAAA,MACjB,cAAc,KAAK;AAAA,MACnB;AAAA,MACA,OAAO,GAAG;AAAA,MACV,MAAM,GAAG;AAAA,MACT,MAAM,GAAG;AAAA,MACT,eAAe,GAAG;AAAA,MAClB,gBAAgB,GAAG;AAAA,IACrB;AAEA,QAAI;AAEJ,QAAI,WAAW,KAAK,WAAW,EAAE,GAAG;AAIlC,YAAM,UAAU,MAAM,KAAK,OAAQ,eAAe,GAAG,MAAM,CAAC,GAAG,GAAG,YAAY,UAAU,CAAC;AACzF,YAAM,cAAc,OAAO,KAAK,OAAO;AAEvC,UAAI,YAAY,SAAS,GAAG;AAC1B,cAAM,IAAI;AAAA,UACR,oCAAoC,KAAK,WAAW,EAAE,cAAc,YAAY,MAAM;AAAA,QACxF;AAAA,MACF;AAGA,YAAM,kBAAkB,QAAQ,YAAY,CAAC,CAAE;AAC/C,YAAM,cAAc,QAAQ,YAAY,CAAC,CAAE;AAG3C,YAAM,gBAAgB;AACtB,YAAM,WAAW,gBAAgB,UAAU,IAAI,aAAa;AAC5D,YAAM,aAAa;AACnB,YAAM,YAAY;AAElB,0BAAgB;AAAA,QACd;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,MACF;AAAA,IACF,OAAO;AAEL,YAAM,SAAS,MAAM,KAAK,OAAQ,IAAI,GAAG,MAAM,CAAC,GAAG,GAAG,YAAY,UAAU,CAAC;AAC7E,YAAM,WAAW,OAAO,UAAU,IAAI;AACtC,0BAAgB,6BAAgB,QAAQ,YAAY,UAAU,eAAe;AAAA,IAC/E;AAEA,UAAM,aAAa,KAAK,iBAAiB,QACrC,gBACA,cAAc,eAAe,0BAAa;AAE9C,WAAO;AAAA,MACL;AAAA,MACA,aAAa,KAAK,IAAI,IAAI;AAAA,MAC1B,SAAS,KAAK,WAAW;AAAA,IAC3B;AAAA,EACF;AAAA,EAEA,MAAc,eAA8B;AAC1C,UAAM,SAAS,KAAK;AACpB,UAAM,UAAU,QAAQ,WAAW,KAAK,WAAW;AACnD,UAAM,UAAU,QAAQ,YAAY,WAAW,WAAY,QAAQ,YAAY,SAAS,SAAS;AACjG,UAAM,UAAU,QAAQ,WAAW;AACnC,UAAM,SAAS,QAAQ,UAAU;AAEjC,UAAM,QAAQ,qBAAqB,KAAK,CAAC,MAAM,EAAE,OAAO,OAAO,KAAK,KAAK;AACzE,SAAK,aAAa;AAElB,UAAM,YAAY,KAAK,IAAK,QAAQ,aAAa,KAAK,KAAK,IAAK,cAAc;AAG9E,QAAI,KAAK,IAAK,QAAQ;AACpB,YAAM,KAAK,IAAK,OAAO,OAAO,SAAS,MAAa;AAAA,IACtD;AAGA,QAAI;AACJ,QAAI,QAAQ,YAAY,UAAU;AAChC,iBAAW,OAAO,CAAC,WAAW,QAAQ,GAAG;AACvC,YAAI;AACF,gBAAM,EAAE,SAAS,IAAI,MAAM,OAAO,eAAoB;AACtD,mBAAS,GAAG,GAAG,cAAc,EAAE,SAAS,KAAM,OAAO,SAAS,CAAC;AAC/D,uBAAa;AACb;AAAA,QACF,QAAQ;AAAA,QAAkB;AAAA,MAC5B;AAAA,IACF;AAEA,UAAM,WAAW,UAAM,sCAAc;AAAA,MACnC;AAAA,MACA;AAAA,MACA,YAAY;AAAA,MACZ;AAAA,MACA;AAAA,MACA,QAAQ,KAAK,IAAK;AAAA,IACpB,CAAC;AACD,SAAK,SAAS,SAAS;AAAA,EACzB;AAAA,EAEA,MAAM,WAA0B;AAC9B,UAAM,KAAK,QAAQ,QAAQ;AAAA,EAC7B;AAAA,EAEA,kBAAkC;AAChC,WAAO;AAAA,MACL,UAAU;AAAA,QACR;AAAA,UACE,IAAI;AAAA,UACJ,OAAO;AAAA,UACP,SAAS;AAAA,UACT,QAAQ;AAAA,YACN;AAAA,cACE,KAAK;AAAA,cACL,OAAO;AAAA,cACP,MAAM;AAAA,cACN,SAAS,CAAC,GAAG,oBAAoB;AAAA,cACjC,aAAa;AAAA,cACb,iBAAiB;AAAA,cACjB,eAAe,CAAC,QAAQ,UAAU,YAAY,QAAQ;AAAA,cACtD,kBAAkB,CAAC,aAAa,UAAU,cAAc;AAAA,cACxD,kBAAkB;AAAA,YACpB;AAAA,UACF;AAAA,QACF;AAAA,QACA;AAAA,UACE,IAAI;AAAA,UACJ,OAAO;AAAA,UACP,SAAS;AAAA,UACT,QAAQ;AAAA,YACN;AAAA,cACE,KAAK;AAAA,cACL,OAAO;AAAA,cACP,MAAM;AAAA,cACN,SAAS;AAAA,gBACP,EAAE,OAAO,QAAQ,OAAO,OAAO;AAAA,gBAC/B,EAAE,OAAO,QAAQ,OAAO,eAAe;AAAA,gBACvC,EAAE,OAAO,UAAU,OAAO,iBAAiB;AAAA,gBAC3C,EAAE,OAAO,YAAY,OAAO,mBAAmB;AAAA,cACjD;AAAA,YACF;AAAA,YACA;AAAA,cACE,KAAK;AAAA,cACL,OAAO;AAAA,cACP,MAAM;AAAA,cACN,UAAU,EAAE,OAAO,WAAW,QAAQ,OAAO;AAAA,cAC7C,SAAS;AAAA,gBACP,EAAE,OAAO,QAAQ,OAAO,OAAO;AAAA,gBAC/B,EAAE,OAAO,OAAO,OAAO,MAAM;AAAA,gBAC7B,EAAE,OAAO,UAAU,OAAO,SAAS;AAAA,gBACnC,EAAE,OAAO,QAAQ,OAAO,gBAAgB;AAAA,gBACxC,EAAE,OAAO,YAAY,OAAO,oBAAoB;AAAA,cAClD;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QACA;AAAA,UACE,IAAI;AAAA,UACJ,OAAO;AAAA,UACP,SAAS;AAAA,UACT,QAAQ;AAAA,YACN;AAAA,cACE,KAAK;AAAA,cACL,OAAO;AAAA,cACP,MAAM;AAAA,cACN,KAAK;AAAA,cACL,KAAK;AAAA,cACL,MAAM;AAAA,cACN,SAAS;AAAA,YACX;AAAA,YACA;AAAA,cACE,KAAK;AAAA,cACL,OAAO;AAAA,cACP,MAAM;AAAA,cACN,KAAK;AAAA,cACL,KAAK;AAAA,cACL,MAAM;AAAA,cACN,SAAS;AAAA,YACX;AAAA,UACF;AAAA,QACF;AAAA,QACA;AAAA,UACE,IAAI;AAAA,UACJ,OAAO;AAAA,UACP,SAAS;AAAA,UACT,QAAQ;AAAA,YACN;AAAA,cACE,KAAK;AAAA,cACL,OAAO;AAAA,cACP,MAAM;AAAA,cACN,SAAS;AAAA,gBACP,EAAE,OAAO,SAAS,OAAO,oCAAoC;AAAA,gBAC7D,EAAE,OAAO,OAAO,OAAO,wBAAwB;AAAA,cACjD;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,cAAkC;AAChC,WAAO;AAAA,EACT;AAAA,EAEA,kBAAuC;AACrC,WAAO,CAAC,GAAG,oBAAoB;AAAA,EACjC;AAAA,EAEA,qBAAuC;AAErC,WAAO,CAAC;AAAA,EACV;AAAA,EAEA,kBAA8C;AAC5C,WAAO,KAAK,iBAAiB,QAAQ,8BAAiB;AAAA,EACxD;AAAA,EAEA,MAAM,QAA8B;AAClC,WAAO;AAAA,MACL,WAAW;AAAA,MACX,SAAS,KAAK,QAAQ,WAAW;AAAA,MACjC,QAAQ,KAAK,QAAQ,UAAU;AAAA,MAC/B,cAAc,CAAC,MAAM;AAAA,IACvB;AAAA,EACF;AACF;","names":["exports","exports","exports","letterbox","exports","yoloPostprocess","exports","yoloSegPostprocess","exports","exports","exports","resolveEngine","detections"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/addons/object-detection/index.ts","../../../src/catalogs/object-detection-models.ts","../../../src/catalogs/segmentation-models.ts","../../../src/shared/image-utils.ts","../../../src/shared/postprocess/yolo.ts","../../../src/shared/postprocess/yolo-seg.ts","../../../src/shared/engine-resolver.ts","../../../src/shared/node-engine.ts","../../../src/shared/python-engine.ts"],"sourcesContent":["import type {\n IDetectorProvider,\n IDetectionAddon,\n AddonManifest,\n AddonContext,\n FrameInput,\n DetectorOutput,\n SpatialDetection,\n ConfigUISchema,\n ClassMapDefinition,\n ProbeResult,\n ModelCatalogEntry,\n DetectionModel,\n LabelDefinition,\n IInferenceEngine,\n ModelRequirement,\n ResolvedInferenceConfig,\n} from '@camstack/types'\nimport { OBJECT_DETECTION_MODELS } from '../../catalogs/object-detection-models.js'\nimport { SEGMENTATION_MODELS } from '../../catalogs/segmentation-models.js'\nimport { COCO_TO_MACRO, MACRO_LABELS, COCO_80_LABELS } from '@camstack/types'\nimport { letterbox } from '../../shared/image-utils.js'\nimport { yoloPostprocess } from '../../shared/postprocess/yolo.js'\nimport { yoloSegPostprocess } from '../../shared/postprocess/yolo-seg.js'\nimport { resolveEngine } from '../../shared/engine-resolver.js'\n\n/** Returns true when the model id identifies a YOLO segmentation model (e.g. yolov8n-seg, yolo11m-seg) */\nfunction isSegModel(modelId: string): boolean {\n return modelId.includes('-seg')\n}\n\n/** Combined catalog: regular detection models + segmentation models */\nconst ALL_DETECTION_MODELS: readonly ModelCatalogEntry[] = [\n ...OBJECT_DETECTION_MODELS,\n ...SEGMENTATION_MODELS,\n]\n\n/**\n * classMapMode controls how raw COCO labels are mapped after inference:\n *\n * - 'macro' (default): apply COCO_TO_MACRO — only person / vehicle / animal\n * survive, all other classes are dropped.\n * - 'all': keep every raw COCO label (80 classes). originalClass === class.\n */\ntype ClassMapMode = 'macro' | 'all'\n\n/** Map COCO-class detections to macro categories (person/vehicle/animal) */\nfunction applyClassMap(\n detections: SpatialDetection[],\n classMap: ClassMapDefinition,\n): SpatialDetection[] {\n return detections\n .filter((d) => classMap.mapping[d.class] !== undefined)\n .map((d) => ({\n ...d,\n originalClass: d.class,\n class: classMap.mapping[d.class]!,\n }))\n}\n\n/** RAM estimates per model (MB) */\nconst RAM_ESTIMATES: Record<string, number> = {\n 'yolov8n': 80, 'yolov8s': 150, 'yolov8s-relu': 150, 'yolov8m': 300, 'yolov8l': 500, 'yolov8x': 800,\n 'yolov9t': 60, 'yolov9s': 120, 'yolov9c': 300,\n 'yolo11n': 70, 'yolo11s': 130, 'yolo11m': 280, 'yolo11l': 450, 'yolo11x': 750,\n 'yolo11n-seg': 84, 'yolo11s-seg': 156, 'yolo11m-seg': 336,\n 'yolov8n-seg': 96, 'yolov8s-seg': 180, 'yolov8m-seg': 360,\n}\n\n/**\n * Accuracy scores per model (0-100).\n * YOLO11 scores are higher than YOLOv8 equivalents to reflect the\n * ~2 mAP improvement at same parameter count (e.g. YOLO11n 39.5 vs YOLOv8n 37.3).\n * This ensures the resolver prefers YOLO11 when both families are available.\n */\nconst ACCURACY_SCORES: Record<string, number> = {\n 'yolov8n': 55, 'yolov8s': 70, 'yolov8s-relu': 68, 'yolov8m': 82, 'yolov8l': 88, 'yolov8x': 92,\n 'yolov9t': 58, 'yolov9s': 73, 'yolov9c': 86,\n 'yolo11n': 62, 'yolo11s': 78, 'yolo11m': 88, 'yolo11l': 93, 'yolo11x': 97,\n 'yolo11n-seg': 62, 'yolo11s-seg': 78, 'yolo11m-seg': 88,\n 'yolov8n-seg': 55, 'yolov8s-seg': 70, 'yolov8m-seg': 82,\n}\n\nexport default class ObjectDetectionAddon implements IDetectorProvider, IDetectionAddon {\n readonly id = 'object-detection'\n readonly slot = 'detector' as const\n readonly inputClasses: readonly string[] | null = null\n readonly outputClasses = ['person', 'vehicle', 'animal'] as const\n readonly slotPriority = 0\n readonly manifest: AddonManifest = {\n id: 'object-detection',\n name: 'Object Detection',\n version: '0.1.0',\n\n description: 'YOLO-based object detection — detects persons, vehicles, and animals',\n\n slot: 'detector',\n inputClasses: undefined,\n outputClasses: ['person', 'vehicle', 'animal'],\n supportsCustomModels: true,\n mayRequirePython: false,\n defaultConfig: {\n modelId: 'yolo11n',\n runtime: 'node',\n backend: 'cpu',\n confidence: 0.5,\n iouThreshold: 0.45,\n classMapMode: 'macro',\n },\n }\n\n private engine: IInferenceEngine | null = null\n private modelEntry!: ModelCatalogEntry\n private confidence = 0.5\n private iouThreshold = 0.45\n private classMapMode: ClassMapMode = 'macro'\n private resolvedConfig: ResolvedInferenceConfig | null = null\n private ctx: AddonContext | null = null\n\n getModelRequirements(): ModelRequirement[] {\n return ALL_DETECTION_MODELS.map((m) => ({\n modelId: m.id,\n name: m.name,\n minRAM_MB: RAM_ESTIMATES[m.id] ?? 100,\n accuracyScore: ACCURACY_SCORES[m.id] ?? 60,\n formats: Object.keys(m.formats) as readonly string[],\n }))\n }\n\n configure(config: ResolvedInferenceConfig): void {\n this.resolvedConfig = config\n }\n\n async initialize(ctx: AddonContext): Promise<void> {\n this.ctx = ctx\n const cfg = ctx.addonConfig\n const modelId = (cfg['modelId'] as string | undefined) ?? this.resolvedConfig?.modelId ?? 'yolo11n'\n this.confidence = (cfg['confidence'] as number | undefined) ?? 0.5\n this.iouThreshold = (cfg['iouThreshold'] as number | undefined) ?? 0.45\n this.classMapMode = (cfg['classMapMode'] as ClassMapMode | undefined) ?? 'macro'\n\n const entry = ALL_DETECTION_MODELS.find((m) => m.id === modelId)\n if (!entry) {\n throw new Error(`ObjectDetectionAddon: unknown modelId \"${modelId}\"`)\n }\n this.modelEntry = entry\n }\n\n async detect(frame: FrameInput): Promise<DetectorOutput> {\n if (!this.engine) await this.ensureEngine()\n const start = Date.now()\n\n // Python engine path — send JPEG directly, Python handles preprocess + inference + postprocess\n if ('runJpeg' in this.engine! && typeof (this.engine as any).runJpeg === 'function') {\n const result = await (this.engine as any).runJpeg(frame.data) as Record<string, unknown>\n const rawDets = (result.detections ?? []) as Array<{ className: string; score: number; bbox: number[] }>\n const detections: SpatialDetection[] = rawDets.map((d) => ({\n class: this.classMapMode === 'all' ? d.className : (COCO_TO_MACRO.mapping[d.className] ?? d.className),\n originalClass: d.className,\n score: d.score,\n bbox: {\n x: d.bbox[0]! * frame.width,\n y: d.bbox[1]! * frame.height,\n w: (d.bbox[2]! - d.bbox[0]!) * frame.width,\n h: (d.bbox[3]! - d.bbox[1]!) * frame.height,\n },\n })).filter((d) => this.classMapMode === 'all' || COCO_TO_MACRO.mapping[d.originalClass!] !== undefined)\n\n return {\n detections,\n inferenceMs: (result.inferenceMs as number) ?? (Date.now() - start),\n modelId: this.modelEntry.id,\n }\n }\n\n // Node.js engine path — letterbox + run tensor + postprocess\n const { width: inputW, height: inputH } = this.modelEntry.inputSize\n const targetSize = Math.max(inputW, inputH)\n\n const lb = await letterbox(frame.data, targetSize)\n\n const numClasses = this.modelEntry.labels.length\n const labels = this.modelEntry.labels.map((l) => l.id)\n const postprocessOpts = {\n confidence: this.confidence,\n iouThreshold: this.iouThreshold,\n labels,\n scale: lb.scale,\n padX: lb.padX,\n padY: lb.padY,\n originalWidth: lb.originalWidth,\n originalHeight: lb.originalHeight,\n }\n\n let rawDetections: SpatialDetection[]\n\n if (isSegModel(this.modelEntry.id)) {\n // YOLO-seg models produce two outputs:\n // output0: [1, 4 + numClasses + 32, numBoxes] (detection + mask coefficients)\n // output1: [1, 32, 160, 160] (prototype masks)\n const outputs = await this.engine!.runMultiOutput(lb.data, [1, 3, targetSize, targetSize])\n const outputNames = Object.keys(outputs)\n\n if (outputNames.length < 2) {\n throw new Error(\n `ObjectDetectionAddon: seg model \"${this.modelEntry.id}\" returned ${outputNames.length} output(s); expected 2`,\n )\n }\n\n // ONNX output order is deterministic; first output is the detection tensor, second is protos\n const detectionOutput = outputs[outputNames[0]!]!\n const protoOutput = outputs[outputNames[1]!]!\n\n // Infer dims from tensor sizes\n const numMaskCoeffs = 32\n const numBoxes = detectionOutput.length / (4 + numClasses + numMaskCoeffs)\n const maskHeight = 160\n const maskWidth = 160\n\n rawDetections = yoloSegPostprocess(\n {\n detectionOutput,\n protoOutput,\n numClasses,\n numBoxes,\n numMaskCoeffs,\n maskHeight,\n maskWidth,\n },\n postprocessOpts,\n )\n } else {\n // Standard YOLO output: [1, 4+numClasses, numBoxes]\n const output = await this.engine!.run(lb.data, [1, 3, targetSize, targetSize])\n const numBoxes = output.length / (4 + numClasses)\n rawDetections = yoloPostprocess(output, numClasses, numBoxes, postprocessOpts)\n }\n\n const detections = this.classMapMode === 'all'\n ? rawDetections\n : applyClassMap(rawDetections, COCO_TO_MACRO)\n\n return {\n detections,\n inferenceMs: Date.now() - start,\n modelId: this.modelEntry.id,\n }\n }\n\n private async ensureEngine(): Promise<void> {\n const config = this.resolvedConfig\n const modelId = config?.modelId ?? this.modelEntry.id\n const runtime = config?.runtime === 'python' ? 'coreml' : (config?.runtime === 'node' ? 'onnx' : 'auto')\n const backend = config?.backend ?? 'cpu'\n const format = config?.format ?? 'onnx'\n\n const entry = ALL_DETECTION_MODELS.find((m) => m.id === modelId) ?? this.modelEntry\n this.modelEntry = entry\n\n const modelsDir = this.ctx!.models?.getModelsDir() ?? this.ctx!.locationPaths.models\n\n // Download model if needed\n if (this.ctx!.models) {\n await this.ctx!.models.ensure(modelId, format as any)\n }\n\n // Discover Python path for Python-based runtimes\n let pythonPath: string | undefined\n if (config?.runtime === 'python') {\n for (const cmd of ['python3', 'python']) {\n try {\n const { execSync } = await import('node:child_process')\n execSync(`${cmd} --version`, { timeout: 3000, stdio: 'ignore' })\n pythonPath = cmd\n break\n } catch { /* not found */ }\n }\n }\n\n const resolved = await resolveEngine({\n runtime: runtime as 'auto',\n backend,\n modelEntry: entry,\n modelsDir,\n pythonPath,\n models: this.ctx!.models,\n })\n this.engine = resolved.engine\n }\n\n async shutdown(): Promise<void> {\n await this.engine?.dispose()\n }\n\n getConfigSchema(): ConfigUISchema {\n return {\n sections: [\n {\n id: 'model',\n title: 'Model',\n columns: 1,\n fields: [\n {\n key: 'modelId',\n label: 'Model',\n type: 'model-selector',\n catalog: [...ALL_DETECTION_MODELS],\n allowCustom: true,\n allowConversion: true,\n acceptFormats: ['onnx', 'coreml', 'openvino', 'tflite'],\n requiredMetadata: ['inputSize', 'labels', 'outputFormat'],\n outputFormatHint: 'yolo',\n },\n ],\n },\n {\n id: 'runtime',\n title: 'Runtime',\n columns: 2,\n fields: [\n {\n key: 'runtime',\n label: 'Runtime',\n type: 'select',\n options: [\n { value: 'auto', label: 'Auto' },\n { value: 'onnx', label: 'ONNX Runtime' },\n { value: 'coreml', label: 'CoreML (Apple)' },\n { value: 'openvino', label: 'OpenVINO (Intel)' },\n ],\n },\n {\n key: 'backend',\n label: 'Backend',\n type: 'select',\n showWhen: { field: 'runtime', equals: 'onnx' },\n options: [\n { value: 'auto', label: 'Auto' },\n { value: 'cpu', label: 'CPU' },\n { value: 'coreml', label: 'CoreML' },\n { value: 'cuda', label: 'CUDA (NVIDIA)' },\n { value: 'tensorrt', label: 'TensorRT (NVIDIA)' },\n ],\n },\n ],\n },\n {\n id: 'thresholds',\n title: 'Detection Thresholds',\n columns: 2,\n fields: [\n {\n key: 'confidence',\n label: 'Confidence Threshold',\n type: 'slider',\n min: 0.1,\n max: 1.0,\n step: 0.05,\n default: 0.5,\n },\n {\n key: 'iouThreshold',\n label: 'IoU Threshold (NMS)',\n type: 'slider',\n min: 0.1,\n max: 1.0,\n step: 0.05,\n default: 0.45,\n },\n ],\n },\n {\n id: 'classmap',\n title: 'Class Mapping',\n columns: 1,\n fields: [\n {\n key: 'classMapMode',\n label: 'Output classes',\n type: 'select',\n options: [\n { value: 'macro', label: 'Macro (person / vehicle / animal)' },\n { value: 'all', label: 'All COCO classes (80)' },\n ],\n },\n ],\n },\n ],\n }\n }\n\n getClassMap(): ClassMapDefinition {\n return COCO_TO_MACRO\n }\n\n getModelCatalog(): ModelCatalogEntry[] {\n return [...ALL_DETECTION_MODELS]\n }\n\n getAvailableModels(): DetectionModel[] {\n // TODO: check downloaded models in modelsDir\n return []\n }\n\n getActiveLabels(): readonly LabelDefinition[] {\n return this.classMapMode === 'all' ? COCO_80_LABELS : MACRO_LABELS\n }\n\n async probe(): Promise<ProbeResult> {\n return {\n available: true,\n runtime: this.engine?.runtime ?? 'onnx',\n device: this.engine?.device ?? 'cpu',\n capabilities: ['fp32'],\n }\n }\n}\n","import type { ModelCatalogEntry } from '@camstack/types'\nimport { hfModelUrl, COCO_80_LABELS } from '@camstack/types'\n\nconst HF_REPO = 'camstack/camstack-models'\n\n/** Standard files inside every .mlpackage directory bundle */\nexport const MLPACKAGE_FILES = [\n 'Manifest.json',\n 'Data/com.apple.CoreML/model.mlmodel',\n 'Data/com.apple.CoreML/weights/weight.bin',\n] as const\n\nexport const OBJECT_DETECTION_MODELS: readonly ModelCatalogEntry[] = [\n // ── YOLOv8 ──────────────────────────────────────────────────────\n {\n id: 'yolov8n',\n name: 'YOLOv8 Nano',\n description: 'YOLOv8 Nano — fastest, smallest object detection model',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/onnx/camstack-yolov8n.onnx'),\n sizeMB: 12,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/coreml/camstack-yolov8n.mlpackage'),\n sizeMB: 6,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/openvino/camstack-yolov8n.xml'),\n sizeMB: 7,\n runtimes: ['python'],\n },\n tflite: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/tflite/camstack-yolov8n_float32.tflite'),\n sizeMB: 12,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'yolov8s',\n name: 'YOLOv8 Small',\n description: 'YOLOv8 Small — balanced speed and accuracy',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/onnx/camstack-yolov8s.onnx'),\n sizeMB: 43,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/coreml/camstack-yolov8s.mlpackage'),\n sizeMB: 21,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/openvino/camstack-yolov8s.xml'),\n sizeMB: 22,\n runtimes: ['python'],\n },\n tflite: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/tflite/camstack-yolov8s_float32.tflite'),\n sizeMB: 43,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'yolov8s-relu',\n name: 'YOLOv8 Small ReLU',\n description: 'YOLOv8 Small with ReLU activation — better hardware compatibility',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/onnx/camstack-yolov8s-relu.onnx'),\n sizeMB: 43,\n },\n },\n },\n {\n id: 'yolov8m',\n name: 'YOLOv8 Medium',\n description: 'YOLOv8 Medium — higher accuracy, moderate size',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/onnx/camstack-yolov8m.onnx'),\n sizeMB: 99,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/coreml/camstack-yolov8m.mlpackage'),\n sizeMB: 49,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/openvino/camstack-yolov8m.xml'),\n sizeMB: 50,\n runtimes: ['python'],\n },\n tflite: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/tflite/camstack-yolov8m_float32.tflite'),\n sizeMB: 99,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'yolov8l',\n name: 'YOLOv8 Large',\n description: 'YOLOv8 Large — high-accuracy large model',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/onnx/camstack-yolov8l.onnx'),\n sizeMB: 167,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/coreml/camstack-yolov8l.mlpackage'),\n sizeMB: 83,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/openvino/camstack-yolov8l.xml'),\n sizeMB: 84,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'yolov8x',\n name: 'YOLOv8 Extra-Large',\n description: 'YOLOv8 Extra-Large — maximum accuracy',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/onnx/camstack-yolov8x.onnx'),\n sizeMB: 260,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/coreml/camstack-yolov8x.mlpackage'),\n sizeMB: 130,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov8/openvino/camstack-yolov8x.xml'),\n sizeMB: 131,\n runtimes: ['python'],\n },\n },\n },\n\n // ── YOLOv9 ──────────────────────────────────────────────────────\n {\n id: 'yolov9t',\n name: 'YOLOv9 Tiny',\n description: 'YOLOv9 Tiny — ultra-lightweight next-gen detector',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov9/onnx/camstack-yolov9t.onnx'),\n sizeMB: 8,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov9/coreml/camstack-yolov9t.mlpackage'),\n sizeMB: 4,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov9/openvino/camstack-yolov9t.xml'),\n sizeMB: 6,\n runtimes: ['python'],\n },\n tflite: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov9/tflite/camstack-yolov9t_float32.tflite'),\n sizeMB: 8,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'yolov9s',\n name: 'YOLOv9 Small',\n description: 'YOLOv9 Small — improved efficiency over YOLOv8s',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov9/onnx/camstack-yolov9s.onnx'),\n sizeMB: 28,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov9/coreml/camstack-yolov9s.mlpackage'),\n sizeMB: 14,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov9/openvino/camstack-yolov9s.xml'),\n sizeMB: 16,\n runtimes: ['python'],\n },\n tflite: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov9/tflite/camstack-yolov9s_float32.tflite'),\n sizeMB: 28,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'yolov9c',\n name: 'YOLOv9 C',\n description: 'YOLOv9 C — high-accuracy compact model',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov9/onnx/camstack-yolov9c.onnx'),\n sizeMB: 97,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov9/coreml/camstack-yolov9c.mlpackage'),\n sizeMB: 48,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov9/openvino/camstack-yolov9c.xml'),\n sizeMB: 49,\n runtimes: ['python'],\n },\n tflite: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolov9/tflite/camstack-yolov9c_float32.tflite'),\n sizeMB: 97,\n runtimes: ['python'],\n },\n },\n },\n\n // ── YOLO11 ────────────────────────────────────────────────────\n {\n id: 'yolo11n',\n name: 'YOLO11 Nano',\n description: 'YOLO11 Nano — fastest, smallest YOLO11 detection model (mAP 39.5)',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/onnx/camstack-yolo11n.onnx'),\n sizeMB: 10,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/coreml/camstack-yolo11n.mlpackage'),\n sizeMB: 5,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/openvino/camstack-yolo11n.xml'),\n sizeMB: 5,\n runtimes: ['python'],\n },\n tflite: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/tflite/camstack-yolo11n_float32.tflite'),\n sizeMB: 10,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'yolo11s',\n name: 'YOLO11 Small',\n description: 'YOLO11 Small — balanced speed and accuracy (mAP 47.0)',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/onnx/camstack-yolo11s.onnx'),\n sizeMB: 36,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/coreml/camstack-yolo11s.mlpackage'),\n sizeMB: 18,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/openvino/camstack-yolo11s.xml'),\n sizeMB: 18,\n runtimes: ['python'],\n },\n tflite: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/tflite/camstack-yolo11s_float32.tflite'),\n sizeMB: 36,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'yolo11m',\n name: 'YOLO11 Medium',\n description: 'YOLO11 Medium — higher accuracy, moderate size (mAP 51.5)',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/onnx/camstack-yolo11m.onnx'),\n sizeMB: 77,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/coreml/camstack-yolo11m.mlpackage'),\n sizeMB: 39,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/openvino/camstack-yolo11m.xml'),\n sizeMB: 39,\n runtimes: ['python'],\n },\n tflite: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/tflite/camstack-yolo11m_float32.tflite'),\n sizeMB: 77,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'yolo11l',\n name: 'YOLO11 Large',\n description: 'YOLO11 Large — high-accuracy large model (mAP 53.4)',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/onnx/camstack-yolo11l.onnx'),\n sizeMB: 97,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/coreml/camstack-yolo11l.mlpackage'),\n sizeMB: 49,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/openvino/camstack-yolo11l.xml'),\n sizeMB: 49,\n runtimes: ['python'],\n },\n tflite: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/tflite/camstack-yolo11l_float32.tflite'),\n sizeMB: 97,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'yolo11x',\n name: 'YOLO11 Extra-Large',\n description: 'YOLO11 Extra-Large — maximum accuracy (mAP 54.7)',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/onnx/camstack-yolo11x.onnx'),\n sizeMB: 218,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/coreml/camstack-yolo11x.mlpackage'),\n sizeMB: 109,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/openvino/camstack-yolo11x.xml'),\n sizeMB: 109,\n runtimes: ['python'],\n },\n tflite: {\n url: hfModelUrl(HF_REPO, 'objectDetection/yolo11/tflite/camstack-yolo11x_float32.tflite'),\n sizeMB: 218,\n runtimes: ['python'],\n },\n },\n },\n] as const\n","import type { ModelCatalogEntry } from '@camstack/types'\nimport { hfModelUrl, COCO_80_LABELS } from '@camstack/types'\nimport { MLPACKAGE_FILES } from './object-detection-models.js'\n\nconst HF_REPO = 'camstack/camstack-models'\n\nexport const SEGMENTATION_MODELS: readonly ModelCatalogEntry[] = [\n // ── YOLO11-seg ───────────────────────────────────────────────\n {\n id: 'yolo11n-seg',\n name: 'YOLO11 Nano Segmentation',\n description: 'YOLO11 Nano — fastest, smallest YOLO11 instance segmentation model',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolo11-seg/onnx/camstack-yolo11n-seg.onnx'),\n sizeMB: 11,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolo11-seg/coreml/camstack-yolo11n-seg.mlpackage'),\n sizeMB: 6,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolo11-seg/openvino/camstack-yolo11n-seg.xml'),\n sizeMB: 6,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'yolo11s-seg',\n name: 'YOLO11 Small Segmentation',\n description: 'YOLO11 Small — balanced speed and accuracy for instance segmentation',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolo11-seg/onnx/camstack-yolo11s-seg.onnx'),\n sizeMB: 39,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolo11-seg/coreml/camstack-yolo11s-seg.mlpackage'),\n sizeMB: 20,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolo11-seg/openvino/camstack-yolo11s-seg.xml'),\n sizeMB: 20,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'yolo11m-seg',\n name: 'YOLO11 Medium Segmentation',\n description: 'YOLO11 Medium — higher accuracy instance segmentation',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolo11-seg/onnx/camstack-yolo11m-seg.onnx'),\n sizeMB: 86,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolo11-seg/coreml/camstack-yolo11m-seg.mlpackage'),\n sizeMB: 43,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolo11-seg/openvino/camstack-yolo11m-seg.xml'),\n sizeMB: 43,\n runtimes: ['python'],\n },\n },\n },\n\n // ── YOLOv8-seg — CoreML supported ─────────────────────────────\n {\n id: 'yolov8n-seg',\n name: 'YOLOv8 Nano Segmentation',\n description: 'YOLOv8 Nano — fastest, smallest YOLOv8 instance segmentation model',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolov8-seg/onnx/camstack-yolov8n-seg.onnx'),\n sizeMB: 13,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolov8-seg/coreml/camstack-yolov8n-seg.mlpackage'),\n sizeMB: 7,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolov8-seg/openvino/camstack-yolov8n-seg.xml'),\n sizeMB: 7,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'yolov8s-seg',\n name: 'YOLOv8 Small Segmentation',\n description: 'YOLOv8 Small — balanced speed and accuracy for instance segmentation',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolov8-seg/onnx/camstack-yolov8s-seg.onnx'),\n sizeMB: 45,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolov8-seg/coreml/camstack-yolov8s-seg.mlpackage'),\n sizeMB: 23,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolov8-seg/openvino/camstack-yolov8s-seg.xml'),\n sizeMB: 23,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'yolov8m-seg',\n name: 'YOLOv8 Medium Segmentation',\n description: 'YOLOv8 Medium — higher accuracy instance segmentation',\n inputSize: { width: 640, height: 640 },\n labels: COCO_80_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolov8-seg/onnx/camstack-yolov8m-seg.onnx'),\n sizeMB: 104,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolov8-seg/coreml/camstack-yolov8m-seg.mlpackage'),\n sizeMB: 52,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'segmentation/yolov8-seg/openvino/camstack-yolov8m-seg.xml'),\n sizeMB: 53,\n runtimes: ['python'],\n },\n },\n },\n] as const\n","import sharp from 'sharp'\nimport type { BoundingBox } from '@camstack/types'\n\n/** Decode JPEG to raw RGB pixels */\nexport async function jpegToRgb(\n jpeg: Buffer,\n): Promise<{ data: Buffer; width: number; height: number }> {\n const { data, info } = await sharp(jpeg)\n .removeAlpha()\n .raw()\n .toBuffer({ resolveWithObject: true })\n return { data, width: info.width, height: info.height }\n}\n\n/** Crop a region from a JPEG buffer */\nexport async function cropRegion(jpeg: Buffer, roi: BoundingBox): Promise<Buffer> {\n return sharp(jpeg)\n .extract({\n left: Math.round(roi.x),\n top: Math.round(roi.y),\n width: Math.round(roi.w),\n height: Math.round(roi.h),\n })\n .jpeg()\n .toBuffer()\n}\n\n/** Letterbox resize for YOLO: resize preserving aspect ratio, pad to square */\nexport async function letterbox(\n jpeg: Buffer,\n targetSize: number,\n): Promise<{\n data: Float32Array\n scale: number\n padX: number\n padY: number\n originalWidth: number\n originalHeight: number\n}> {\n const meta = await sharp(jpeg).metadata()\n const originalWidth = meta.width ?? 0\n const originalHeight = meta.height ?? 0\n\n const scale = Math.min(targetSize / originalWidth, targetSize / originalHeight)\n const scaledWidth = Math.round(originalWidth * scale)\n const scaledHeight = Math.round(originalHeight * scale)\n\n const padX = Math.floor((targetSize - scaledWidth) / 2)\n const padY = Math.floor((targetSize - scaledHeight) / 2)\n\n const { data } = await sharp(jpeg)\n .resize(scaledWidth, scaledHeight)\n .extend({\n top: padY,\n bottom: targetSize - scaledHeight - padY,\n left: padX,\n right: targetSize - scaledWidth - padX,\n background: { r: 114, g: 114, b: 114 },\n })\n .removeAlpha()\n .raw()\n .toBuffer({ resolveWithObject: true })\n\n // Convert HWC uint8 to CHW float [0,1]\n const numPixels = targetSize * targetSize\n const float32 = new Float32Array(3 * numPixels)\n for (let i = 0; i < numPixels; i++) {\n const srcBase = i * 3\n float32[0 * numPixels + i] = (data[srcBase]! / 255)\n float32[1 * numPixels + i] = (data[srcBase + 1]! / 255)\n float32[2 * numPixels + i] = (data[srcBase + 2]! / 255)\n }\n\n return { data: float32, scale, padX, padY, originalWidth, originalHeight }\n}\n\n/** Resize and normalize to Float32Array */\nexport async function resizeAndNormalize(\n jpeg: Buffer,\n targetWidth: number,\n targetHeight: number,\n normalization: 'zero-one' | 'imagenet' | 'none',\n layout: 'nchw' | 'nhwc',\n): Promise<Float32Array> {\n const { data } = await sharp(jpeg)\n .resize(targetWidth, targetHeight, { fit: 'fill' })\n .removeAlpha()\n .raw()\n .toBuffer({ resolveWithObject: true })\n\n const numPixels = targetWidth * targetHeight\n const float32 = new Float32Array(3 * numPixels)\n\n // ImageNet mean and std per channel\n const mean = [0.485, 0.456, 0.406]\n const std = [0.229, 0.224, 0.225]\n\n if (layout === 'nchw') {\n for (let i = 0; i < numPixels; i++) {\n const srcBase = i * 3\n for (let c = 0; c < 3; c++) {\n const raw = data[srcBase + c]! / 255\n let val: number\n if (normalization === 'zero-one') {\n val = raw\n } else if (normalization === 'imagenet') {\n val = (raw - mean[c]!) / std[c]!\n } else {\n val = data[srcBase + c]!\n }\n float32[c * numPixels + i] = val\n }\n }\n } else {\n // nhwc\n for (let i = 0; i < numPixels; i++) {\n const srcBase = i * 3\n for (let c = 0; c < 3; c++) {\n const raw = data[srcBase + c]! / 255\n let val: number\n if (normalization === 'zero-one') {\n val = raw\n } else if (normalization === 'imagenet') {\n val = (raw - mean[c]!) / std[c]!\n } else {\n val = data[srcBase + c]!\n }\n float32[i * 3 + c] = val\n }\n }\n }\n\n return float32\n}\n\n/** Convert raw RGB to grayscale Uint8Array */\nexport function rgbToGrayscale(rgb: Buffer, width: number, height: number): Uint8Array {\n const numPixels = width * height\n const gray = new Uint8Array(numPixels)\n for (let i = 0; i < numPixels; i++) {\n const r = rgb[i * 3]!\n const g = rgb[i * 3 + 1]!\n const b = rgb[i * 3 + 2]!\n // BT.601 luma\n gray[i] = Math.round(0.299 * r + 0.587 * g + 0.114 * b)\n }\n return gray\n}\n","import type { SpatialDetection, BoundingBox } from '@camstack/types'\n\nexport interface YoloPostprocessOptions {\n readonly confidence: number\n readonly iouThreshold: number\n readonly labels: readonly string[]\n readonly scale: number\n readonly padX: number\n readonly padY: number\n readonly originalWidth: number\n readonly originalHeight: number\n}\n\n/** Calculate IoU between two bounding boxes */\nexport function iou(a: BoundingBox, b: BoundingBox): number {\n const ax1 = a.x\n const ay1 = a.y\n const ax2 = a.x + a.w\n const ay2 = a.y + a.h\n\n const bx1 = b.x\n const by1 = b.y\n const bx2 = b.x + b.w\n const by2 = b.y + b.h\n\n const interX1 = Math.max(ax1, bx1)\n const interY1 = Math.max(ay1, by1)\n const interX2 = Math.min(ax2, bx2)\n const interY2 = Math.min(ay2, by2)\n\n const interW = Math.max(0, interX2 - interX1)\n const interH = Math.max(0, interY2 - interY1)\n const interArea = interW * interH\n\n if (interArea === 0) return 0\n\n const areaA = a.w * a.h\n const areaB = b.w * b.h\n const unionArea = areaA + areaB - interArea\n\n return unionArea === 0 ? 0 : interArea / unionArea\n}\n\n/** Non-maximum suppression — returns indices of kept boxes (sorted by score desc) */\nexport function nms(\n boxes: ReadonlyArray<{ readonly bbox: BoundingBox; readonly score: number }>,\n iouThreshold: number,\n): number[] {\n const indices = boxes\n .map((_, i) => i)\n .sort((a, b) => (boxes[b]!.score) - (boxes[a]!.score))\n\n const kept: number[] = []\n const suppressed = new Set<number>()\n\n for (const idx of indices) {\n if (suppressed.has(idx)) continue\n kept.push(idx)\n for (const other of indices) {\n if (other === idx || suppressed.has(other)) continue\n if (iou(boxes[idx]!.bbox, boxes[other]!.bbox) > iouThreshold) {\n suppressed.add(other)\n }\n }\n }\n\n return kept\n}\n\n/** Full YOLO v8/v9 postprocessing: filter → NMS → scale back to original coords */\nexport function yoloPostprocess(\n output: Float32Array,\n numClasses: number,\n numBoxes: number,\n options: YoloPostprocessOptions,\n): SpatialDetection[] {\n const { confidence, iouThreshold, labels, scale, padX, padY, originalWidth, originalHeight } = options\n\n interface Candidate {\n readonly bbox: BoundingBox\n readonly score: number\n readonly classIdx: number\n }\n\n const candidates: Candidate[] = []\n\n for (let i = 0; i < numBoxes; i++) {\n // YOLO v8/v9 output layout: [1, 4+numClasses, numBoxes] stored row-major\n const cx = output[0 * numBoxes + i]!\n const cy = output[1 * numBoxes + i]!\n const w = output[2 * numBoxes + i]!\n const h = output[3 * numBoxes + i]!\n\n let bestScore = -Infinity\n let bestClass = 0\n\n for (let j = 0; j < numClasses; j++) {\n const score = output[(4 + j) * numBoxes + i]!\n if (score > bestScore) {\n bestScore = score\n bestClass = j\n }\n }\n\n if (bestScore < confidence) continue\n\n // Convert cx,cy,w,h to x,y,w,h (top-left origin)\n const bbox: BoundingBox = {\n x: cx - w / 2,\n y: cy - h / 2,\n w,\n h,\n }\n\n candidates.push({ bbox, score: bestScore, classIdx: bestClass })\n }\n\n if (candidates.length === 0) return []\n\n const keptIndices = nms(candidates, iouThreshold)\n\n return keptIndices.map((idx) => {\n const { bbox, score, classIdx } = candidates[idx]!\n const label = labels[classIdx] ?? String(classIdx)\n\n // Transform from letterbox coords back to original image coords\n const x = Math.max(0, Math.min(originalWidth, (bbox.x - padX) / scale))\n const y = Math.max(0, Math.min(originalHeight, (bbox.y - padY) / scale))\n const x2 = Math.max(0, Math.min(originalWidth, (bbox.x + bbox.w - padX) / scale))\n const y2 = Math.max(0, Math.min(originalHeight, (bbox.y + bbox.h - padY) / scale))\n\n const finalBbox: BoundingBox = { x, y, w: x2 - x, h: y2 - y }\n\n return {\n class: label,\n originalClass: label,\n score,\n bbox: finalBbox,\n } satisfies SpatialDetection\n })\n}\n","import type { SpatialDetection, BoundingBox } from '@camstack/types'\nimport { nms, iou as _iou } from './yolo.js'\nimport type { YoloPostprocessOptions } from './yolo.js'\n\nexport interface YoloSegOutput {\n /** Detection output: [1, 4 + numClasses + numMaskCoeffs, numBoxes] (row-major, batch dim stripped) */\n readonly detectionOutput: Float32Array\n /** Prototype masks: [1, numMaskCoeffs, maskH, maskW] (batch dim stripped) */\n readonly protoOutput: Float32Array\n readonly numClasses: number\n readonly numBoxes: number\n /** Number of mask prototype coefficients per detection (typically 32) */\n readonly numMaskCoeffs: number\n /** Height of prototype mask grid (typically 160) */\n readonly maskHeight: number\n /** Width of prototype mask grid (typically 160) */\n readonly maskWidth: number\n}\n\nexport interface YoloSegPostprocessOptions extends YoloPostprocessOptions {\n /** Binary mask threshold — pixels above this value become 255, others 0 (default: 0.5) */\n readonly maskThreshold?: number\n}\n\n/** Sigmoid activation: σ(x) = 1 / (1 + e^-x) */\nexport function sigmoid(x: number): number {\n return 1 / (1 + Math.exp(-x))\n}\n\n/**\n * Compute instance segmentation mask for a single detection.\n *\n * @param coeffs [numMaskCoeffs] mask coefficients for this detection\n * @param protos [numMaskCoeffs × maskH × maskW] prototype masks (flat, row-major)\n * @param numMaskCoeffs number of prototype channels (e.g. 32)\n * @param maskH prototype grid height (e.g. 160)\n * @param maskW prototype grid width (e.g. 160)\n * @returns [maskH × maskW] sigmoid-activated raw mask values in [0, 1]\n */\nexport function computeRawMask(\n coeffs: Float32Array,\n protos: Float32Array,\n numMaskCoeffs: number,\n maskH: number,\n maskW: number,\n): Float32Array {\n const maskSize = maskH * maskW\n const rawMask = new Float32Array(maskSize)\n\n // mask_raw[y * maskW + x] = sum_k( coeffs[k] * protos[k * maskSize + y * maskW + x] )\n // Then apply sigmoid element-wise.\n for (let px = 0; px < maskSize; px++) {\n let val = 0\n for (let k = 0; k < numMaskCoeffs; k++) {\n val += (coeffs[k] ?? 0) * (protos[k * maskSize + px] ?? 0)\n }\n rawMask[px] = sigmoid(val)\n }\n\n return rawMask\n}\n\n/**\n * Crop a flat [maskH × maskW] mask to a bounding box region (in mask coordinate space),\n * threshold to binary, and return the cropped Uint8Array along with its dimensions.\n *\n * @param rawMask [maskH × maskW] sigmoid-activated values in [0, 1]\n * @param maskH full mask grid height\n * @param maskW full mask grid width\n * @param bbox detection bounding box in the inference input space (e.g. 640×640 letterboxed)\n * @param maskThreshold threshold above which a pixel is considered foreground (default 0.5)\n * @param maskScale ratio of mask resolution to inference resolution (e.g. 160/640 = 0.25)\n * @returns { data: Uint8Array, width, height } of the cropped binary mask\n */\nexport function cropAndThresholdMask(\n rawMask: Float32Array,\n maskH: number,\n maskW: number,\n bbox: BoundingBox,\n maskThreshold: number,\n maskScale: number,\n): { readonly data: Uint8Array; readonly width: number; readonly height: number } {\n const cropX1 = Math.max(0, Math.floor(bbox.x * maskScale))\n const cropY1 = Math.max(0, Math.floor(bbox.y * maskScale))\n const cropX2 = Math.min(maskW, Math.ceil((bbox.x + bbox.w) * maskScale))\n const cropY2 = Math.min(maskH, Math.ceil((bbox.y + bbox.h) * maskScale))\n\n const cropW = Math.max(1, cropX2 - cropX1)\n const cropH = Math.max(1, cropY2 - cropY1)\n\n const data = new Uint8Array(cropW * cropH)\n\n for (let row = 0; row < cropH; row++) {\n const srcRow = cropY1 + row\n for (let col = 0; col < cropW; col++) {\n const srcCol = cropX1 + col\n const srcIdx = srcRow * maskW + srcCol\n data[row * cropW + col] = (rawMask[srcIdx] ?? 0) > maskThreshold ? 255 : 0\n }\n }\n\n return { data, width: cropW, height: cropH }\n}\n\n/**\n * YOLO-seg postprocessing: run detection filtering + NMS, then decode instance masks.\n *\n * The seg detection tensor has layout [1, 4 + numClasses + numMaskCoeffs, numBoxes]:\n * rows 0–3 : cx, cy, w, h\n * rows 4 to 4+C-1 : class scores\n * rows 4+C to end : mask coefficients (32)\n *\n * Steps:\n * 1. Filter boxes by confidence threshold, collecting mask coefficients per candidate.\n * 2. Run NMS across all candidates.\n * 3. For each surviving detection, compute the instance mask and attach it.\n */\nexport function yoloSegPostprocess(\n segOutput: YoloSegOutput,\n options: YoloSegPostprocessOptions,\n): SpatialDetection[] {\n const {\n detectionOutput,\n protoOutput,\n numClasses,\n numBoxes,\n numMaskCoeffs,\n maskHeight,\n maskWidth,\n } = segOutput\n\n const {\n confidence,\n iouThreshold,\n labels,\n scale,\n padX,\n padY,\n originalWidth,\n originalHeight,\n maskThreshold = 0.5,\n } = options\n\n // The mask resolution to inference resolution scale factor (e.g. 160/640 = 0.25)\n // We derive the inference size from scale/pad context: the letterboxed input is typically 640×640\n // but we receive coordinates in that space already, so we use maskHeight / inferH.\n // Since all YOLO-seg models use 640×640 input and 160×160 proto, the ratio is always 160/640.\n // We compute it generically from the known prototype dims + fixed YOLO input of 640.\n const yoloInputSize = 640\n const maskScale = maskHeight / yoloInputSize\n\n interface Candidate {\n readonly bbox: BoundingBox\n readonly score: number\n readonly classIdx: number\n readonly coeffs: Float32Array\n }\n\n const candidates: Candidate[] = []\n\n for (let i = 0; i < numBoxes; i++) {\n const cx = detectionOutput[0 * numBoxes + i] ?? 0\n const cy = detectionOutput[1 * numBoxes + i] ?? 0\n const w = detectionOutput[2 * numBoxes + i] ?? 0\n const h = detectionOutput[3 * numBoxes + i] ?? 0\n\n let bestScore = -Infinity\n let bestClass = 0\n\n for (let j = 0; j < numClasses; j++) {\n const score = detectionOutput[(4 + j) * numBoxes + i] ?? 0\n if (score > bestScore) {\n bestScore = score\n bestClass = j\n }\n }\n\n if (bestScore < confidence) continue\n\n const bbox: BoundingBox = {\n x: cx - w / 2,\n y: cy - h / 2,\n w,\n h,\n }\n\n // Extract mask coefficients for this box\n const coeffs = new Float32Array(numMaskCoeffs)\n for (let k = 0; k < numMaskCoeffs; k++) {\n coeffs[k] = detectionOutput[(4 + numClasses + k) * numBoxes + i] ?? 0\n }\n\n candidates.push({ bbox, score: bestScore, classIdx: bestClass, coeffs })\n }\n\n if (candidates.length === 0) return []\n\n const keptIndices = nms(candidates, iouThreshold)\n\n return keptIndices.map((idx) => {\n const { bbox, score, classIdx, coeffs } = candidates[idx]!\n const label = labels[classIdx] ?? String(classIdx)\n\n // Scale bbox back from letterbox space to original image coords\n const x = Math.max(0, Math.min(originalWidth, (bbox.x - padX) / scale))\n const y = Math.max(0, Math.min(originalHeight, (bbox.y - padY) / scale))\n const x2 = Math.max(0, Math.min(originalWidth, (bbox.x + bbox.w - padX) / scale))\n const y2 = Math.max(0, Math.min(originalHeight, (bbox.y + bbox.h - padY) / scale))\n const finalBbox: BoundingBox = { x, y, w: x2 - x, h: y2 - y }\n\n // Decode instance mask using the letterbox-space bbox (before coord scaling)\n const rawMask = computeRawMask(coeffs, protoOutput, numMaskCoeffs, maskHeight, maskWidth)\n const { data: maskData, width: mW, height: mH } = cropAndThresholdMask(\n rawMask,\n maskHeight,\n maskWidth,\n bbox,\n maskThreshold,\n maskScale,\n )\n\n return {\n class: label,\n originalClass: label,\n score,\n bbox: finalBbox,\n mask: maskData,\n maskWidth: mW,\n maskHeight: mH,\n } satisfies SpatialDetection\n })\n}\n","// TODO: Wire PythonInferenceEngine for PyTorch/OpenVINO/TFLite runtimes\n// Currently falls back to ONNX CPU when non-ONNX runtime is requested.\n// See: packages/addon-vision/python/ for stub implementations.\n//\n// WHY THIS FILE USES RAW FILESYSTEM PATHS (modelsDir: string):\n//\n// Model files must be loaded via absolute filesystem paths because inference\n// engines (ONNX Runtime, CoreML, etc.) require direct file access -- they do\n// not accept Buffer or stream inputs. This is fundamentally different from\n// user data (recordings, media) where IAddonFileStorage abstraction makes\n// sense. Models are closer to binaries or compiled artifacts that must live\n// on the local filesystem at runtime.\n//\n// IAddonFileStorage.readFile() returns a Buffer, but onnxruntime-node's\n// InferenceSession.create() only accepts a file path string or a Uint8Array\n// loaded into memory. For large models (hundreds of MB), loading into a\n// Uint8Array is impractical. Therefore, modelsDir stays as a raw string path\n// and is intentionally NOT replaced with IAddonFileStorage here.\n\nimport type {\n IInferenceEngine,\n DetectionRuntime,\n ModelCatalogEntry,\n ModelFormat,\n IAddonModelManager,\n} from '@camstack/types'\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport { NodeInferenceEngine } from './node-engine.js'\nimport { PythonInferenceEngine } from './python-engine.js'\n\nexport interface EngineResolverOptions {\n readonly runtime: DetectionRuntime | 'auto'\n readonly backend: string\n readonly modelEntry: ModelCatalogEntry\n readonly modelsDir: string\n readonly pythonPath?: string\n /** Model service for downloading models. When provided, used instead of raw filesystem probing. */\n readonly models?: IAddonModelManager\n}\n\nexport interface ResolvedEngine {\n readonly engine: IInferenceEngine\n readonly format: ModelFormat\n readonly modelPath: string\n}\n\n/** Priority order for auto-selection of ONNX backends */\nconst AUTO_BACKEND_PRIORITY = ['coreml', 'cuda', 'tensorrt', 'cpu'] as const\n\n/** Map backend names to the model format they require.\n * CoreML backend uses ONNX format -- onnxruntime-node loads the .onnx file\n * and accelerates it via the CoreML execution provider internally.\n * Native .mlpackage is only for PythonInferenceEngine. */\nconst BACKEND_TO_FORMAT: Readonly<Record<string, ModelFormat>> = {\n cpu: 'onnx',\n coreml: 'onnx',\n cuda: 'onnx',\n tensorrt: 'onnx',\n} as const\n\n/** Map DetectionRuntime to ModelFormat */\nconst RUNTIME_TO_FORMAT: Readonly<Partial<Record<DetectionRuntime, ModelFormat>>> = {\n onnx: 'onnx',\n coreml: 'coreml',\n openvino: 'openvino',\n tflite: 'tflite',\n pytorch: 'pt',\n} as const\n\nfunction modelFilePath(modelsDir: string, modelEntry: ModelCatalogEntry, format: ModelFormat): string {\n const formatEntry = modelEntry.formats[format]\n if (!formatEntry) {\n throw new Error(`Model ${modelEntry.id} has no ${format} format`)\n }\n // Derive filename from URL\n const urlParts = formatEntry.url.split('/')\n const filename = urlParts[urlParts.length - 1] ?? `${modelEntry.id}.${format}`\n return path.join(modelsDir, filename)\n}\n\nfunction modelExists(filePath: string): boolean {\n try {\n return fs.existsSync(filePath)\n } catch {\n return false\n }\n}\n\nexport async function resolveEngine(options: EngineResolverOptions): Promise<ResolvedEngine> {\n const { runtime, backend, modelEntry, modelsDir, models } = options\n\n let selectedFormat: ModelFormat\n let selectedBackend: string\n\n if (runtime === 'auto') {\n // Probe available ONNX backends and pick best\n const available = await probeOnnxBackends()\n\n // Pick first priority backend that has a corresponding model format available\n let chosen: { backend: string; format: ModelFormat } | null = null\n\n for (const b of AUTO_BACKEND_PRIORITY) {\n if (!available.includes(b)) continue\n const fmt = BACKEND_TO_FORMAT[b]\n if (!fmt) continue\n if (!modelEntry.formats[fmt]) continue\n chosen = { backend: b, format: fmt }\n break\n }\n\n if (!chosen) {\n throw new Error(\n `resolveEngine: no compatible backend found for model ${modelEntry.id}. Available backends: ${available.join(', ')}`,\n )\n }\n\n selectedFormat = chosen.format\n selectedBackend = chosen.backend\n } else {\n // Explicit runtime requested\n const fmt = RUNTIME_TO_FORMAT[runtime]\n if (!fmt) {\n throw new Error(`resolveEngine: unsupported runtime \"${runtime}\"`)\n }\n if (!modelEntry.formats[fmt]) {\n throw new Error(\n `resolveEngine: model ${modelEntry.id} has no ${fmt} format for runtime ${runtime}`,\n )\n }\n selectedFormat = fmt\n // For onnx runtime, use the provided backend; otherwise use the runtime name\n selectedBackend = runtime === 'onnx' ? (backend || 'cpu') : runtime\n }\n\n // Download model and extra files via the unified service\n let modelPath: string\n\n if (models) {\n // Use the unified ModelDownloadService\n modelPath = await models.ensure(modelEntry.id, selectedFormat)\n } else {\n // Fallback: direct filesystem check (no download capability)\n modelPath = modelFilePath(modelsDir, modelEntry, selectedFormat)\n if (!modelExists(modelPath)) {\n throw new Error(\n `resolveEngine: model file not found at ${modelPath} and no model service provided`,\n )\n }\n }\n\n // NodeInferenceEngine handles ONNX format only (with any ONNX backend including CoreML provider).\n // Native .mlpackage/.mlmodel files go to PythonInferenceEngine below.\n if (selectedFormat === 'onnx') {\n const engine = new NodeInferenceEngine(modelPath, selectedBackend)\n await engine.initialize()\n return { engine, format: selectedFormat, modelPath }\n }\n\n // For non-ONNX/CoreML formats, try PythonInferenceEngine when a python binary is available\n const { pythonPath } = options\n const PYTHON_SCRIPT_MAP: Readonly<Record<string, string>> = {\n coreml: 'coreml_inference.py',\n pytorch: 'pytorch_inference.py',\n openvino: 'openvino_inference.py',\n } as const\n\n const effectiveRuntime = runtime === 'auto' ? selectedBackend : runtime\n const scriptName = PYTHON_SCRIPT_MAP[effectiveRuntime]\n\n if (scriptName && pythonPath) {\n // Resolve python script path -- search multiple locations:\n // - src/shared/ -> ../../python/ (source development)\n // - dist/shared/ -> ../../python/ (installed addon with python/ at package root)\n // - dist/ -> ../python/ (flat dist)\n const candidates = [\n path.join(__dirname, '../../python', scriptName),\n path.join(__dirname, '../python', scriptName),\n path.join(__dirname, '../../../python', scriptName),\n ]\n const scriptPath = candidates.find(p => fs.existsSync(p))\n if (!scriptPath) {\n throw new Error(\n `resolveEngine: Python script \"${scriptName}\" not found. Searched:\\n${candidates.join('\\n')}`,\n )\n }\n const inputSize = Math.max(modelEntry.inputSize.width, modelEntry.inputSize.height)\n const engine = new PythonInferenceEngine(pythonPath, scriptPath, effectiveRuntime as DetectionRuntime, modelPath, [\n `--input-size=${inputSize}`,\n `--confidence=0.25`,\n ])\n await engine.initialize()\n return { engine, format: selectedFormat, modelPath }\n }\n\n // Final fallback: use ONNX CPU if available\n const fallbackPath = modelFilePath(modelsDir, modelEntry, 'onnx')\n if (modelEntry.formats['onnx'] && modelExists(fallbackPath)) {\n const engine = new NodeInferenceEngine(fallbackPath, 'cpu')\n await engine.initialize()\n return { engine, format: 'onnx', modelPath: fallbackPath }\n }\n\n throw new Error(\n `resolveEngine: format ${selectedFormat} is not yet supported by NodeInferenceEngine, ` +\n `no Python runtime is available, and no ONNX fallback exists`,\n )\n}\n\n/** Probe which ONNX execution providers are available on this system */\nexport async function probeOnnxBackends(): Promise<string[]> {\n const available: string[] = ['cpu'] // CPU is always available\n\n try {\n const ort = await import('onnxruntime-node')\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const providers: string[] = (ort as any).env?.webgl?.disabled !== undefined\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ? ((ort as any).InferenceSession?.getAvailableProviders?.() ?? [])\n : []\n\n for (const p of providers) {\n const normalized = p.toLowerCase().replace('executionprovider', '')\n if (normalized === 'coreml') available.push('coreml')\n else if (normalized === 'cuda') available.push('cuda')\n else if (normalized === 'tensorrt') available.push('tensorrt')\n }\n } catch {\n // onnxruntime-node may not be installed; CPU only\n }\n\n // Platform-specific hints when getAvailableProviders isn't exposed\n if (process.platform === 'darwin' && !available.includes('coreml')) {\n available.push('coreml')\n }\n\n return [...new Set(available)]\n}\n","import type { IInferenceEngine, DetectionRuntime, DetectionDevice } from '@camstack/types'\nimport * as path from 'node:path'\n\nconst BACKEND_TO_PROVIDER: Readonly<Record<string, string>> = {\n cpu: 'cpu',\n coreml: 'coreml',\n cuda: 'cuda',\n tensorrt: 'tensorrt',\n dml: 'dml',\n} as const\n\nconst BACKEND_TO_DEVICE: Readonly<Record<string, DetectionDevice>> = {\n cpu: 'cpu',\n coreml: 'gpu-mps',\n cuda: 'gpu-cuda',\n tensorrt: 'tensorrt',\n} as const\n\nexport class NodeInferenceEngine implements IInferenceEngine {\n readonly runtime: DetectionRuntime = 'onnx'\n readonly device: DetectionDevice\n private session: unknown = null\n\n constructor(\n private readonly modelPath: string,\n private readonly backend: string,\n ) {\n this.device = (BACKEND_TO_DEVICE[backend] ?? 'cpu') as DetectionDevice\n }\n\n async initialize(): Promise<void> {\n const ort = await import('onnxruntime-node')\n const provider = BACKEND_TO_PROVIDER[this.backend] ?? 'cpu'\n\n // Resolve absolute path\n const absModelPath = path.isAbsolute(this.modelPath)\n ? this.modelPath\n : path.resolve(process.cwd(), this.modelPath)\n\n const sessionOptions: Record<string, unknown> = {\n executionProviders: [provider],\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.session = await (ort as any).InferenceSession.create(absModelPath, sessionOptions)\n }\n\n async run(input: Float32Array, inputShape: readonly number[]): Promise<Float32Array> {\n if (!this.session) {\n throw new Error('NodeInferenceEngine: not initialized — call initialize() first')\n }\n\n const ort = await import('onnxruntime-node')\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const sess = this.session as any\n\n // Get the first input name\n const inputName: string = sess.inputNames[0]\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const tensor = new (ort as any).Tensor('float32', input, [...inputShape])\n const feeds: Record<string, unknown> = { [inputName]: tensor }\n\n const results = await sess.run(feeds)\n const outputName: string = sess.outputNames[0]\n const outputTensor = results[outputName]\n\n return outputTensor.data as Float32Array\n }\n\n async runMultiOutput(\n input: Float32Array,\n inputShape: readonly number[],\n ): Promise<Record<string, Float32Array>> {\n if (!this.session) {\n throw new Error('NodeInferenceEngine: not initialized — call initialize() first')\n }\n\n const ort = await import('onnxruntime-node')\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const sess = this.session as any\n\n const inputName: string = sess.inputNames[0]\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const tensor = new (ort as any).Tensor('float32', input, [...inputShape])\n const feeds: Record<string, unknown> = { [inputName]: tensor }\n\n const results = await sess.run(feeds)\n\n const out: Record<string, Float32Array> = {}\n for (const name of sess.outputNames as string[]) {\n out[name] = results[name].data as Float32Array\n }\n return out\n }\n\n async dispose(): Promise<void> {\n // onnxruntime-node sessions don't have explicit close in all versions\n // but we clear the reference\n this.session = null\n }\n}\n","import type { IInferenceEngine, DetectionRuntime, DetectionDevice, IAddonDepsManager } from '@camstack/types'\nimport { spawn, type ChildProcess } from 'node:child_process'\n\nexport class PythonInferenceEngine implements IInferenceEngine {\n readonly runtime: DetectionRuntime\n readonly device: DetectionDevice\n private process: ChildProcess | null = null\n private receiveBuffer: Buffer = Buffer.alloc(0)\n private pendingResolve: ((value: Record<string, unknown>) => void) | null = null\n private pendingReject: ((reason: Error) => void) | null = null\n\n constructor(\n private readonly pythonPath: string,\n private readonly scriptPath: string,\n runtime: DetectionRuntime,\n private readonly modelPath: string,\n private readonly extraArgs: readonly string[] = [],\n ) {\n this.runtime = runtime\n // Determine device from runtime\n const runtimeDeviceMap: Readonly<Record<DetectionRuntime, DetectionDevice>> = {\n onnx: 'cpu',\n coreml: 'gpu-mps',\n pytorch: 'cpu',\n openvino: 'cpu',\n tflite: 'cpu',\n }\n this.device = runtimeDeviceMap[runtime]\n }\n\n async initialize(): Promise<void> {\n const args = [this.scriptPath, this.modelPath, ...this.extraArgs]\n this.process = spawn(this.pythonPath, args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n })\n\n if (!this.process.stdout || !this.process.stdin) {\n throw new Error('PythonInferenceEngine: failed to create process pipes')\n }\n\n this.process.stderr?.on('data', (chunk: Buffer) => {\n // Log stderr from python process for debugging\n process.stderr.write(`[python-engine] ${chunk.toString()}`)\n })\n\n this.process.on('error', (err) => {\n this.pendingReject?.(err)\n this.pendingReject = null\n this.pendingResolve = null\n })\n\n this.process.on('exit', (code) => {\n if (code !== 0) {\n const err = new Error(`PythonInferenceEngine: process exited with code ${code}`)\n this.pendingReject?.(err)\n this.pendingReject = null\n this.pendingResolve = null\n }\n })\n\n this.process.stdout.on('data', (chunk: Buffer) => {\n this.receiveBuffer = Buffer.concat([this.receiveBuffer, chunk])\n this._tryReceive()\n })\n\n // Give the process a moment to start up and load the model\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => resolve(), 2000)\n this.process?.on('error', (err) => {\n clearTimeout(timeout)\n reject(err)\n })\n this.process?.on('exit', (code) => {\n clearTimeout(timeout)\n if (code !== 0) {\n reject(new Error(`PythonInferenceEngine: process exited early with code ${code}`))\n }\n })\n })\n }\n\n private _tryReceive(): void {\n // Binary IPC: [4 bytes LE uint32 length][JSON bytes]\n if (this.receiveBuffer.length < 4) return\n\n const length = this.receiveBuffer.readUInt32LE(0)\n if (this.receiveBuffer.length < 4 + length) return\n\n const jsonBytes = this.receiveBuffer.subarray(4, 4 + length)\n this.receiveBuffer = this.receiveBuffer.subarray(4 + length)\n\n const resolve = this.pendingResolve\n const reject = this.pendingReject\n this.pendingResolve = null\n this.pendingReject = null\n\n if (!resolve) return\n\n try {\n const parsed = JSON.parse(jsonBytes.toString('utf8')) as Record<string, unknown>\n resolve(parsed)\n } catch (err) {\n reject?.(err instanceof Error ? err : new Error(String(err)))\n }\n }\n\n /** Send JPEG buffer, receive JSON detection results */\n async runJpeg(jpeg: Buffer): Promise<Record<string, unknown>> {\n if (!this.process?.stdin) {\n throw new Error('PythonInferenceEngine: process not initialized')\n }\n\n return new Promise<Record<string, unknown>>((resolve, reject) => {\n this.pendingResolve = resolve\n this.pendingReject = reject\n\n // Binary IPC: [4 bytes LE uint32 length][JPEG bytes]\n const lengthBuf = Buffer.allocUnsafe(4)\n lengthBuf.writeUInt32LE(jpeg.length, 0)\n this.process!.stdin!.write(Buffer.concat([lengthBuf, jpeg]))\n })\n }\n\n /** IInferenceEngine.run — wraps runJpeg for compatibility */\n async run(_input: Float32Array, _inputShape: readonly number[]): Promise<Float32Array> {\n throw new Error(\n 'PythonInferenceEngine: use runJpeg() directly — this engine operates on JPEG input',\n )\n }\n\n /** IInferenceEngine.runMultiOutput — not supported by Python engine (operates on JPEG input) */\n async runMultiOutput(\n _input: Float32Array,\n _inputShape: readonly number[],\n ): Promise<Record<string, Float32Array>> {\n throw new Error(\n 'PythonInferenceEngine: runMultiOutput() is not supported — this engine operates on JPEG input',\n )\n }\n\n async dispose(): Promise<void> {\n if (this.process) {\n this.process.stdin?.end()\n this.process.kill('SIGTERM')\n this.process = null\n }\n }\n}\n\n/**\n * Resolve Python binary for ML inference. Priority:\n * 1. Explicit config pythonPath\n * 2. Embedded (data/deps/python/bin/python3)\n * 3. System PATH (python3, python)\n * 4. Download standalone Python\n *\n * Returns null if Python is not available.\n */\nexport async function resolvePythonBinary(\n configPath: string | undefined,\n deps: IAddonDepsManager,\n): Promise<string | null> {\n if (configPath) return configPath\n return deps.ensurePython()\n}\n"],"mappings":"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","names":["import_types","HF_REPO","import_types","sharp","path","resolve","detections"]}
|