@camstack/addon-model-studio 1.1.293 → 1.1.295

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (20) hide show
  1. package/THIRD_PARTY_MODELS.md +2 -2
  2. package/dist/{MotionZonesSettings-DrHyXG0G.mjs → MotionZonesSettings-DOhuE4t6.mjs} +2 -2
  3. package/dist/{PrivacyMaskSettings-CuqGSOYk.mjs → PrivacyMaskSettings-BtQIysUm.mjs} +4 -4
  4. package/dist/{SceneMonitorEditor-_wt-7NOB.mjs → SceneMonitorEditor-B4cEP3UH.mjs} +3 -3
  5. package/dist/_stub.js +155 -155
  6. package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-D1kg1qk9.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-DNRDIeO2.mjs} +4 -4
  7. package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CDZyIXC0.mjs +26 -0
  8. package/dist/{hostInit-CqUjCpJe.mjs → hostInit-DLBoEjee.mjs} +3 -3
  9. package/dist/model-studio.addon.js +2257 -261
  10. package/dist/model-studio.addon.mjs +2256 -260
  11. package/dist/{player-overlays-IswZiT1v.mjs → player-overlays-BVHDRE8f.mjs} +1 -1
  12. package/dist/remoteEntry.js +1 -1
  13. package/dist/{responsive-BRDOoNTu.mjs → responsive-CI-NtcQi.mjs} +1 -1
  14. package/dist/{scene-monitor-copy-BLrlOdpo.mjs → scene-monitor-copy-CvzuJJ8Z.mjs} +1 -1
  15. package/dist/{square-CqxajgGh.mjs → square-CsljmL2M.mjs} +1 -1
  16. package/dist/{trash-2-B67pP3l-.mjs → trash-2-DwX9K1LA.mjs} +1 -1
  17. package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-DeT4IssS.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-Bu2vRo0B.mjs} +1 -1
  18. package/package.json +1 -1
  19. package/python/__tests__/test_calibration.py +3 -3
  20. package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BPZnyWUq.mjs +0 -26
@@ -11,12 +11,12 @@ import { cp, mkdir, open, rename, rm, writeFile } from "node:fs/promises";
11
11
  //#region \0rolldown/runtime.js
12
12
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
13
13
  //#endregion
14
- //#region src/scrypted/scrypted-yolo-manifest-data.json
15
- var scrypted_yolo_manifest_data_default = /*#__PURE__*/ JSON.parse("[{\"id\":\"scrypted-yolov9t-relu-coreml\",\"label\":\"Scrypted YOLOv9T ReLU CoreML\",\"family\":\"yolov9t\",\"variant\":\"relu\",\"format\":\"coreml\",\"precision\":\"fp16\",\"files\":[{\"relativePath\":\"coreml/scrypted_yolov9t_relu/scrypted_yolov9t_relu.mlpackage/Manifest.json\",\"size\":617,\"sha256\":\"0a8733949d77e3204dba6418e81a11a8cc177015711457ce2c171266f23382d6\"},{\"relativePath\":\"coreml/scrypted_yolov9t_relu/scrypted_yolov9t_relu.mlpackage/Data/com.apple.CoreML/model.mlmodel\",\"size\":322229,\"sha256\":\"f5a62f196f1e72a84efa1637119dffb6501621af9cf6f867bc76b4b59c9242a0\"},{\"relativePath\":\"coreml/scrypted_yolov9t_relu/scrypted_yolov9t_relu.mlpackage/Data/com.apple.CoreML/weights/weight.bin\",\"size\":3797160,\"sha256\":\"b994419b8b68cfd6b89c3c6f3fe6b37458c86cc1d87fcca3df5034476a99dd38\"}],\"sizeMB\":4.12},{\"id\":\"scrypted-yolov9t-relu-onnx\",\"label\":\"Scrypted YOLOv9T ReLU ONNX\",\"family\":\"yolov9t\",\"variant\":\"relu\",\"format\":\"onnx\",\"precision\":\"fp32\",\"files\":[{\"relativePath\":\"onnx/scrypted_yolov9t_relu/scrypted_yolov9t_relu.onnx\",\"size\":8499266,\"sha256\":\"3f11ea2071b27c285b58c16636a44d6a0a27bdd1ca8b64112dfadabd39cfea47\"}],\"sizeMB\":8.5},{\"id\":\"scrypted-yolov9t-relu-test-coreml\",\"label\":\"Scrypted YOLOv9T ReLU test CoreML\",\"family\":\"yolov9t\",\"variant\":\"relu_test\",\"format\":\"coreml\",\"precision\":\"fp16\",\"files\":[{\"relativePath\":\"coreml/scrypted_yolov9t_relu_test/scrypted_yolov9t_relu_test.mlpackage/Manifest.json\",\"size\":617,\"sha256\":\"a5e0128b643f1a66f3e07d4b332f9ccbca97ccab75651c794f0b9f1fb41c8491\"},{\"relativePath\":\"coreml/scrypted_yolov9t_relu_test/scrypted_yolov9t_relu_test.mlpackage/Data/com.apple.CoreML/model.mlmodel\",\"size\":322229,\"sha256\":\"79f4f647f2a0c79db3b560c84251b48c7ba7cbe9c1fecc9674d1a603a389dfa3\"},{\"relativePath\":\"coreml/scrypted_yolov9t_relu_test/scrypted_yolov9t_relu_test.mlpackage/Data/com.apple.CoreML/weights/weight.bin\",\"size\":3797160,\"sha256\":\"72efc9dc6af9241b5e5ee7de24a4f55741f6425d0e279d797f0f223e3d355f84\"}],\"sizeMB\":4.12},{\"id\":\"scrypted-yolov9t-relu-test-onnx\",\"label\":\"Scrypted YOLOv9T ReLU test ONNX\",\"family\":\"yolov9t\",\"variant\":\"relu_test\",\"format\":\"onnx\",\"precision\":\"fp32\",\"files\":[{\"relativePath\":\"onnx/scrypted_yolov9t_relu_test/scrypted_yolov9t_relu_test.onnx\",\"size\":8499266,\"sha256\":\"d20aa0e6923a3af7f5e84e3a6d28fb00e8ecd592e3225f986f93bd34b634e2f8\"}],\"sizeMB\":8.5},{\"id\":\"scrypted-yolov9s-relu-coreml\",\"label\":\"Scrypted YOLOv9S ReLU CoreML\",\"family\":\"yolov9s\",\"variant\":\"relu\",\"format\":\"coreml\",\"precision\":\"fp16\",\"files\":[{\"relativePath\":\"coreml/scrypted_yolov9s_relu/scrypted_yolov9s_relu.mlpackage/Manifest.json\",\"size\":617,\"sha256\":\"3bcdb820b82f1e89266f2d11bae1604d3ee4ca6d11dc5bd5c57055ff4157e9f3\"},{\"relativePath\":\"coreml/scrypted_yolov9s_relu/scrypted_yolov9s_relu.mlpackage/Data/com.apple.CoreML/model.mlmodel\",\"size\":322664,\"sha256\":\"9a9c3c9cbca406ec2f0418ec867ed6b878ec6d02c16636d30e0bbd83d2ff7c40\"},{\"relativePath\":\"coreml/scrypted_yolov9s_relu/scrypted_yolov9s_relu.mlpackage/Data/com.apple.CoreML/weights/weight.bin\",\"size\":14190120,\"sha256\":\"fd51eda58a993997268f6a2e424b536ba173207ad7974ab8bee2a8ff76d52dab\"}],\"sizeMB\":14.51},{\"id\":\"scrypted-yolov9s-relu-onnx\",\"label\":\"Scrypted YOLOv9S ReLU ONNX\",\"family\":\"yolov9s\",\"variant\":\"relu\",\"format\":\"onnx\",\"precision\":\"fp32\",\"files\":[{\"relativePath\":\"onnx/scrypted_yolov9s_relu/scrypted_yolov9s_relu.onnx\",\"size\":29287339,\"sha256\":\"ca0b5bd98d5f59eb2029c6cb5129d53af59873f62a317a028beda463bbb96399\"}],\"sizeMB\":29.29},{\"id\":\"scrypted-yolov9s-relu-test-coreml\",\"label\":\"Scrypted YOLOv9S ReLU test CoreML\",\"family\":\"yolov9s\",\"variant\":\"relu_test\",\"format\":\"coreml\",\"precision\":\"fp16\",\"files\":[{\"relativePath\":\"coreml/scrypted_yolov9s_relu_test/scrypted_yolov9s_relu_test.mlpackage/Manifest.json\",\"size\":617,\"sha256\":\"e2d24de0ce7e8573f19572029765e55abc714f36a85175ad7fcb95c001a76653\"},{\"relativePath\":\"coreml/scrypted_yolov9s_relu_test/scrypted_yolov9s_relu_test.mlpackage/Data/com.apple.CoreML/model.mlmodel\",\"size\":322664,\"sha256\":\"186b147cdfd15c5ed7a381ec3a426a22cee0b5c52d56f14efd26da06357f5cb0\"},{\"relativePath\":\"coreml/scrypted_yolov9s_relu_test/scrypted_yolov9s_relu_test.mlpackage/Data/com.apple.CoreML/weights/weight.bin\",\"size\":14190120,\"sha256\":\"e50651924c2cbffd56008a8953569e66c3de69f21807fcf7d825390ce30f21f8\"}],\"sizeMB\":14.51},{\"id\":\"scrypted-yolov9s-relu-test-onnx\",\"label\":\"Scrypted YOLOv9S ReLU test ONNX\",\"family\":\"yolov9s\",\"variant\":\"relu_test\",\"format\":\"onnx\",\"precision\":\"fp32\",\"files\":[{\"relativePath\":\"onnx/scrypted_yolov9s_relu_test/scrypted_yolov9s_relu_test.onnx\",\"size\":29287339,\"sha256\":\"115ddb83333762a0f2599421335678696454a5c3571ade5df9bac8e9cb5fb4cf\"}],\"sizeMB\":29.29},{\"id\":\"scrypted-yolov9m-relu-coreml\",\"label\":\"Scrypted YOLOv9M ReLU CoreML\",\"family\":\"yolov9m\",\"variant\":\"relu\",\"format\":\"coreml\",\"precision\":\"fp16\",\"files\":[{\"relativePath\":\"coreml/scrypted_yolov9m_relu/scrypted_yolov9m_relu.mlpackage/Manifest.json\",\"size\":617,\"sha256\":\"c548c6e1ff768b2b01bd71e230aa712a1635ae2baa30e0369557a42fc531ecbf\"},{\"relativePath\":\"coreml/scrypted_yolov9m_relu/scrypted_yolov9m_relu.mlpackage/Data/com.apple.CoreML/model.mlmodel\",\"size\":247061,\"sha256\":\"1c40e02fc2a2559cb906ea6cd9da9c730d4a78f5019290cbb38d2fcaae379fe7\"},{\"relativePath\":\"coreml/scrypted_yolov9m_relu/scrypted_yolov9m_relu.mlpackage/Data/com.apple.CoreML/weights/weight.bin\",\"size\":39880616,\"sha256\":\"4cf938e5bfcc3ee1644813e4eb4702a7de450cc0581df94c719cf43d0ed2e408\"}],\"sizeMB\":40.13},{\"id\":\"scrypted-yolov9m-relu-onnx\",\"label\":\"Scrypted YOLOv9M ReLU ONNX\",\"family\":\"yolov9m\",\"variant\":\"relu\",\"format\":\"onnx\",\"precision\":\"fp32\",\"files\":[{\"relativePath\":\"onnx/scrypted_yolov9m_relu/scrypted_yolov9m_relu.onnx\",\"size\":80380404,\"sha256\":\"e7a81fb33224a0105d2a0a594c3fa43c398c361de623f1d14156ae826e7312d5\"}],\"sizeMB\":80.38},{\"id\":\"scrypted-yolov9m-relu-test-coreml\",\"label\":\"Scrypted YOLOv9M ReLU test CoreML\",\"family\":\"yolov9m\",\"variant\":\"relu_test\",\"format\":\"coreml\",\"precision\":\"fp16\",\"files\":[{\"relativePath\":\"coreml/scrypted_yolov9m_relu_test/scrypted_yolov9m_relu_test.mlpackage/Manifest.json\",\"size\":617,\"sha256\":\"8e2684b286d02b4bdf9db1027c84cb89bf8e4830cfb58269f3ec457c5a010650\"},{\"relativePath\":\"coreml/scrypted_yolov9m_relu_test/scrypted_yolov9m_relu_test.mlpackage/Data/com.apple.CoreML/model.mlmodel\",\"size\":247061,\"sha256\":\"53d5946e74b13b15c5f8616081c9f15e8a95a5df3d5b45b830fc5a7f49561c16\"},{\"relativePath\":\"coreml/scrypted_yolov9m_relu_test/scrypted_yolov9m_relu_test.mlpackage/Data/com.apple.CoreML/weights/weight.bin\",\"size\":39880616,\"sha256\":\"69774bf0032c37707601b8cdc1e1820dbd9f8288eb5d6f3879618a5d34ff5199\"}],\"sizeMB\":40.13},{\"id\":\"scrypted-yolov9m-relu-test-onnx\",\"label\":\"Scrypted YOLOv9M ReLU test ONNX\",\"family\":\"yolov9m\",\"variant\":\"relu_test\",\"format\":\"onnx\",\"precision\":\"fp32\",\"files\":[{\"relativePath\":\"onnx/scrypted_yolov9m_relu_test/scrypted_yolov9m_relu_test.onnx\",\"size\":80380404,\"sha256\":\"8bb054f099295909ec518e2a6598d63db24d3f90edc8105a0f016903f2a205a2\"}],\"sizeMB\":80.38},{\"id\":\"scrypted-yolov9c-relu-coreml\",\"label\":\"Scrypted YOLOv9C ReLU CoreML\",\"family\":\"yolov9c\",\"variant\":\"relu\",\"format\":\"coreml\",\"precision\":\"fp16\",\"files\":[{\"relativePath\":\"coreml/scrypted_yolov9c_relu/scrypted_yolov9c_relu.mlpackage/Manifest.json\",\"size\":617,\"sha256\":\"813a306ebd69cabfd31f00434f5a961feeca7d237833f3e11805dcf4ad120ba9\"},{\"relativePath\":\"coreml/scrypted_yolov9c_relu/scrypted_yolov9c_relu.mlpackage/Data/com.apple.CoreML/model.mlmodel\",\"size\":263210,\"sha256\":\"862f082619075e470738306b0ff0a37ae70a7d08e684ca6a6dfa1971d404e0c3\"},{\"relativePath\":\"coreml/scrypted_yolov9c_relu/scrypted_yolov9c_relu.mlpackage/Data/com.apple.CoreML/weights/weight.bin\",\"size\":50489960,\"sha256\":\"ed89747e58943758e2a87221d1d404f6a4466cbc039c3c6f96e327cadc403d27\"}],\"sizeMB\":50.75},{\"id\":\"scrypted-yolov9c-relu-onnx\",\"label\":\"Scrypted YOLOv9C ReLU ONNX\",\"family\":\"yolov9c\",\"variant\":\"relu\",\"format\":\"onnx\",\"precision\":\"fp32\",\"files\":[{\"relativePath\":\"onnx/scrypted_yolov9c_relu/scrypted_yolov9c_relu.onnx\",\"size\":101631962,\"sha256\":\"b9372c4428daf4cd944c114b1e80d1a9ff0487d743e53a77216a051cfbef7116\"}],\"sizeMB\":101.63},{\"id\":\"scrypted-yolov9c-relu-test-coreml\",\"label\":\"Scrypted YOLOv9C ReLU test CoreML\",\"family\":\"yolov9c\",\"variant\":\"relu_test\",\"format\":\"coreml\",\"precision\":\"fp16\",\"files\":[{\"relativePath\":\"coreml/scrypted_yolov9c_relu_test/scrypted_yolov9c_relu_test.mlpackage/Manifest.json\",\"size\":617,\"sha256\":\"966ef82a93cb0ccf1036a8c9729c065fd372fa9590a97d0945e581cc674f7ad2\"},{\"relativePath\":\"coreml/scrypted_yolov9c_relu_test/scrypted_yolov9c_relu_test.mlpackage/Data/com.apple.CoreML/model.mlmodel\",\"size\":263210,\"sha256\":\"08718ecd3e9552d21a702bd8df60911cad0eec7b2ae382466809550f14634711\"},{\"relativePath\":\"coreml/scrypted_yolov9c_relu_test/scrypted_yolov9c_relu_test.mlpackage/Data/com.apple.CoreML/weights/weight.bin\",\"size\":50489960,\"sha256\":\"fe5936b9430ab4c87f30b148220131d6ec998b2377223d033e2fa2a00e60aada\"}],\"sizeMB\":50.75},{\"id\":\"scrypted-yolov9c-relu-test-onnx\",\"label\":\"Scrypted YOLOv9C ReLU test ONNX\",\"family\":\"yolov9c\",\"variant\":\"relu_test\",\"format\":\"onnx\",\"precision\":\"fp32\",\"files\":[{\"relativePath\":\"onnx/scrypted_yolov9c_relu_test/scrypted_yolov9c_relu_test.onnx\",\"size\":101631962,\"sha256\":\"2f4e2031e8efb4cbc871594338b2e875d78ab4af3ee0258d253273b1aac84742\"}],\"sizeMB\":101.63},{\"id\":\"scrypted-yolov9t-relu-openvino-fp32\",\"label\":\"Scrypted YOLOv9T ReLU OpenVINO FP32\",\"family\":\"yolov9t\",\"variant\":\"relu\",\"format\":\"openvino\",\"precision\":\"fp32\",\"files\":[{\"relativePath\":\"openvino/scrypted_yolov9t_relu/best-converted.xml\",\"size\":628222,\"sha256\":\"01b5a9d02a0f281e1aaf4860e1b0ed3a7f16b9d78975be8ff985ae0ee283d877\"},{\"relativePath\":\"openvino/scrypted_yolov9t_relu/best-converted.bin\",\"size\":7542204,\"sha256\":\"4fe9ce8dbdf94514fdd450cbfc907f257153e4898a0c1489a44e4912d8e32cc7\"}],\"sizeMB\":8.17},{\"id\":\"scrypted-yolov9s-relu-openvino-fp32\",\"label\":\"Scrypted YOLOv9S ReLU OpenVINO FP32\",\"family\":\"yolov9s\",\"variant\":\"relu\",\"format\":\"openvino\",\"precision\":\"fp32\",\"files\":[{\"relativePath\":\"openvino/scrypted_yolov9s_relu/best-converted.xml\",\"size\":629249,\"sha256\":\"5b4a229bf7229425698b63bd065a403e440a6151a6ddff0034867659cc4a480d\"},{\"relativePath\":\"openvino/scrypted_yolov9s_relu/best-converted.bin\",\"size\":28329724,\"sha256\":\"c030bd219208ea94082578c81f383d4ef9ec45d7150eec1c2c2ff2569cf49b35\"}],\"sizeMB\":28.96},{\"id\":\"scrypted-yolov9m-relu-openvino-fp32\",\"label\":\"Scrypted YOLOv9M ReLU OpenVINO FP32\",\"family\":\"yolov9m\",\"variant\":\"relu\",\"format\":\"openvino\",\"precision\":\"fp32\",\"files\":[{\"relativePath\":\"openvino/scrypted_yolov9m_relu/best-converted.xml\",\"size\":485439,\"sha256\":\"c66f9f1965bf70fd3635d4dfc3cb94c72c06b344c256713237d77706725b9a0c\"},{\"relativePath\":\"openvino/scrypted_yolov9m_relu/best-converted.bin\",\"size\":79717372,\"sha256\":\"dfc2d8952bbca9ad0e116168e3fd5c754e601c327d78c4f4d0d4cae12f0e1d2a\"}],\"sizeMB\":80.2},{\"id\":\"scrypted-yolov9c-relu-openvino-fp32\",\"label\":\"Scrypted YOLOv9C ReLU OpenVINO FP32\",\"family\":\"yolov9c\",\"variant\":\"relu\",\"format\":\"openvino\",\"precision\":\"fp32\",\"files\":[{\"relativePath\":\"openvino/scrypted_yolov9c_relu/best-converted.xml\",\"size\":535047,\"sha256\":\"836c1e998ebf76108ff64d554fdfa07aa72c42624f1a5448701bb409f27b8d68\"},{\"relativePath\":\"openvino/scrypted_yolov9c_relu/best-converted.bin\",\"size\":100942972,\"sha256\":\"11a1b330ac9843b349927977b3c7c7f17bb42af73a7ff102969132f27ab81814\"}],\"sizeMB\":101.48},{\"id\":\"scrypted-yolov9t-relu-openvino-int8\",\"label\":\"Scrypted YOLOv9T ReLU OpenVINO INT8\",\"family\":\"yolov9t\",\"variant\":\"relu\",\"format\":\"openvino\",\"precision\":\"int8\",\"files\":[{\"relativePath\":\"openvino/scrypted_yolov9t_relu_int8/best-converted.xml\",\"size\":1380379,\"sha256\":\"e5a76bf88ac69fc0ebc50c04b61ff91550dd9c2349af1f6d7e4cac949c640cec\"},{\"relativePath\":\"openvino/scrypted_yolov9t_relu_int8/best-converted.bin\",\"size\":1954956,\"sha256\":\"98fb5b6826d7c6697a585f69ba96754873772d9d61fbed8335aab761e8248659\"}],\"sizeMB\":3.34},{\"id\":\"scrypted-yolov9t-relu-test-openvino-int8\",\"label\":\"Scrypted YOLOv9T ReLU test OpenVINO INT8\",\"family\":\"yolov9t\",\"variant\":\"relu_test\",\"format\":\"openvino\",\"precision\":\"int8\",\"files\":[{\"relativePath\":\"openvino/scrypted_yolov9t_relu_test_int8/best-converted.xml\",\"size\":1380383,\"sha256\":\"9e4119284e923e08c9929e78fd31e2552e602a552ac538ae99bf34a50dd4d172\"},{\"relativePath\":\"openvino/scrypted_yolov9t_relu_test_int8/best-converted.bin\",\"size\":1954960,\"sha256\":\"efe5b0a2fd2f5ddef5923eeb9e592a7ef14719061bb7605c86e05b35c2c58ea9\"}],\"sizeMB\":3.34},{\"id\":\"scrypted-yolov9s-relu-openvino-int8\",\"label\":\"Scrypted YOLOv9S ReLU OpenVINO INT8\",\"family\":\"yolov9s\",\"variant\":\"relu\",\"format\":\"openvino\",\"precision\":\"int8\",\"files\":[{\"relativePath\":\"openvino/scrypted_yolov9s_relu_int8/best-converted.xml\",\"size\":1382088,\"sha256\":\"4e6c24cf24afbab21462f7e1a15bd05b1cbbe5915046000e03c2435d8110bbbf\"},{\"relativePath\":\"openvino/scrypted_yolov9s_relu_int8/best-converted.bin\",\"size\":7197308,\"sha256\":\"23fd3d666a938c41db232d9c6239baec1134716cfb4ed4ddd3d602dd20eb8ac0\"}],\"sizeMB\":8.58},{\"id\":\"scrypted-yolov9s-relu-test-openvino-int8\",\"label\":\"Scrypted YOLOv9S ReLU test OpenVINO INT8\",\"family\":\"yolov9s\",\"variant\":\"relu_test\",\"format\":\"openvino\",\"precision\":\"int8\",\"files\":[{\"relativePath\":\"openvino/scrypted_yolov9s_relu_test_int8/best-converted.xml\",\"size\":1382092,\"sha256\":\"49865bfeafe7576afce089ba6f5c3e25a9192c8b514eb96265c90fe877795641\"},{\"relativePath\":\"openvino/scrypted_yolov9s_relu_test_int8/best-converted.bin\",\"size\":7197312,\"sha256\":\"78e9d36e6b74754db2b624ea3ec0b3ff57ed6dfed59a4f2225e1a271054597de\"}],\"sizeMB\":8.58},{\"id\":\"scrypted-yolov9m-relu-openvino-int8\",\"label\":\"Scrypted YOLOv9M ReLU OpenVINO INT8\",\"family\":\"yolov9m\",\"variant\":\"relu\",\"format\":\"openvino\",\"precision\":\"int8\",\"files\":[{\"relativePath\":\"openvino/scrypted_yolov9m_relu_int8/best-converted.xml\",\"size\":1024595,\"sha256\":\"1242ab8d8c73b2e80c5dd541177ade6e102a2684114b059136acb4cad6efb034\"},{\"relativePath\":\"openvino/scrypted_yolov9m_relu_int8/best-converted.bin\",\"size\":20090516,\"sha256\":\"da8e44af8bee66478e6f359e9504bfb13ab4b76f4bd8a2f1b10cfbc22febcf6e\"}],\"sizeMB\":21.12},{\"id\":\"scrypted-yolov9m-relu-test-openvino-int8\",\"label\":\"Scrypted YOLOv9M ReLU test OpenVINO INT8\",\"family\":\"yolov9m\",\"variant\":\"relu_test\",\"format\":\"openvino\",\"precision\":\"int8\",\"files\":[{\"relativePath\":\"openvino/scrypted_yolov9m_relu_test_int8/best-converted.xml\",\"size\":1024601,\"sha256\":\"24395ae5fdbb321304c865372cd2b905cdc55abb7610520f3963702e2371decb\"},{\"relativePath\":\"openvino/scrypted_yolov9m_relu_test_int8/best-converted.bin\",\"size\":20090520,\"sha256\":\"4360fe0312067f92c49f180c7b8a10271f14d58b8909aa9b96b13af4ab9289aa\"}],\"sizeMB\":21.12},{\"id\":\"scrypted-yolov9c-relu-openvino-int8\",\"label\":\"Scrypted YOLOv9C ReLU OpenVINO INT8\",\"family\":\"yolov9c\",\"variant\":\"relu\",\"format\":\"openvino\",\"precision\":\"int8\",\"files\":[{\"relativePath\":\"openvino/scrypted_yolov9c_relu_int8/best-converted.xml\",\"size\":1092695,\"sha256\":\"a45c62940120c4301d8fff9fb3b275c29e3618f403ea68a785f2f3220cefec7a\"},{\"relativePath\":\"openvino/scrypted_yolov9c_relu_int8/best-converted.bin\",\"size\":25428280,\"sha256\":\"0643403a56178c3ed1e066c7884458d8ea6780115d662bdc38d10754d7a11c79\"}],\"sizeMB\":26.52},{\"id\":\"scrypted-yolov9c-relu-test-openvino-int8\",\"label\":\"Scrypted YOLOv9C ReLU test OpenVINO INT8\",\"family\":\"yolov9c\",\"variant\":\"relu_test\",\"format\":\"openvino\",\"precision\":\"int8\",\"files\":[{\"relativePath\":\"openvino/scrypted_yolov9c_relu_test_int8/best-converted.xml\",\"size\":1092695,\"sha256\":\"a8a1899848ebd060af2326d3c8d3c09ea83354f0bedff6cce6fa08b284ea5519\"},{\"relativePath\":\"openvino/scrypted_yolov9c_relu_test_int8/best-converted.bin\",\"size\":25428280,\"sha256\":\"2eb6bb3d0a03a9b239b6f623f9e7bced62eea61fbe4d8ff89c1b3e2e2b7978a2\"}],\"sizeMB\":26.52},{\"id\":\"scrypted-yolov9s-relu-sep-320-tflite-float16\",\"label\":\"Scrypted YOLOv9s ReLU sep 320 TFLite float16\",\"family\":\"yolov9s\",\"variant\":\"relu\",\"format\":\"tflite\",\"precision\":\"float16\",\"files\":[{\"relativePath\":\"tflite/scrypted_yolov9s_relu_sep_320/best_float16.tflite\",\"size\":14482836,\"sha256\":\"04889db3b81af361c361e41ffa99327330d37b71d680a2f889e6cdf1e94c0d8c\"}],\"sizeMB\":14.48},{\"id\":\"scrypted-yolov9s-relu-sep-320-tflite-float32\",\"label\":\"Scrypted YOLOv9s ReLU sep 320 TFLite float32\",\"family\":\"yolov9s\",\"variant\":\"relu\",\"format\":\"tflite\",\"precision\":\"float32\",\"files\":[{\"relativePath\":\"tflite/scrypted_yolov9s_relu_sep_320/best_float32.tflite\",\"size\":28777068,\"sha256\":\"f5d7d08fc1d8f2262633d2df4391638e0481740331aaa1837880a47c33001a96\"}],\"sizeMB\":28.78},{\"id\":\"scrypted-yolov9s-relu-sep-320-tflite-int8\",\"label\":\"Scrypted YOLOv9s ReLU sep 320 TFLite int8\",\"family\":\"yolov9s\",\"variant\":\"relu\",\"format\":\"tflite\",\"precision\":\"int8\",\"files\":[{\"relativePath\":\"tflite/scrypted_yolov9s_relu_sep_320/best_int8.tflite\",\"size\":7325616,\"sha256\":\"1e9866b16fe80931383bf3c94dc629fe93a37ba3dc1465ea019eb0a50bd428df\"}],\"sizeMB\":7.33},{\"id\":\"scrypted-yolov9s-relu-sep-320-tflite-integer_quant\",\"label\":\"Scrypted YOLOv9s ReLU sep 320 TFLite integer_quant\",\"family\":\"yolov9s\",\"variant\":\"relu\",\"format\":\"tflite\",\"precision\":\"integer_quant\",\"files\":[{\"relativePath\":\"tflite/scrypted_yolov9s_relu_sep_320/best_integer_quant.tflite\",\"size\":7342552,\"sha256\":\"bc1c902e9a9865637ee2403f70c6bf5c29c695d9163e58ad658feb29bb097ebc\"}],\"sizeMB\":7.34},{\"id\":\"scrypted-yolov9s-relu-sep-320-tflite-full_integer_quant\",\"label\":\"Scrypted YOLOv9s ReLU sep 320 TFLite full_integer_quant\",\"family\":\"yolov9s\",\"variant\":\"relu\",\"format\":\"tflite\",\"precision\":\"full_integer_quant\",\"files\":[{\"relativePath\":\"tflite/scrypted_yolov9s_relu_sep_320/best_full_integer_quant.tflite\",\"size\":7341704,\"sha256\":\"483ce38dbe33ee5a35f40a82f56c77629a44fa5d95efd8ade9fa97e4d2a261fd\"}],\"sizeMB\":7.34},{\"id\":\"scrypted-yolov9s-relu-sep-320-tflite-edgetpu\",\"label\":\"Scrypted YOLOv9s ReLU sep 320 TFLite edgetpu\",\"family\":\"yolov9s\",\"variant\":\"relu\",\"format\":\"tflite\",\"precision\":\"edgetpu\",\"files\":[{\"relativePath\":\"tflite/scrypted_yolov9s_relu_sep_320/best_full_integer_quant_edgetpu.tflite\",\"size\":8164480,\"sha256\":\"e1e6b074a3b9fdf19a171baf615553ad375a046aa7de2a3fef9a1950175fab22\"}],\"sizeMB\":8.16}]");
14
+ //#region src/plugin-catalog/plugin-catalog-yolo-manifest-data.json
15
+ var plugin_catalog_yolo_manifest_data_default = /*#__PURE__*/ JSON.parse("[{\"id\":\"scrypted-yolov9t-relu-coreml\",\"label\":\"plugin catalog YOLOv9T ReLU CoreML\",\"family\":\"yolov9t\",\"variant\":\"relu\",\"format\":\"coreml\",\"precision\":\"fp16\",\"files\":[{\"relativePath\":\"coreml/scrypted_yolov9t_relu/scrypted_yolov9t_relu.mlpackage/Manifest.json\",\"size\":617,\"sha256\":\"0a8733949d77e3204dba6418e81a11a8cc177015711457ce2c171266f23382d6\"},{\"relativePath\":\"coreml/scrypted_yolov9t_relu/scrypted_yolov9t_relu.mlpackage/Data/com.apple.CoreML/model.mlmodel\",\"size\":322229,\"sha256\":\"f5a62f196f1e72a84efa1637119dffb6501621af9cf6f867bc76b4b59c9242a0\"},{\"relativePath\":\"coreml/scrypted_yolov9t_relu/scrypted_yolov9t_relu.mlpackage/Data/com.apple.CoreML/weights/weight.bin\",\"size\":3797160,\"sha256\":\"b994419b8b68cfd6b89c3c6f3fe6b37458c86cc1d87fcca3df5034476a99dd38\"}],\"sizeMB\":4.12},{\"id\":\"scrypted-yolov9t-relu-onnx\",\"label\":\"plugin catalog YOLOv9T ReLU ONNX\",\"family\":\"yolov9t\",\"variant\":\"relu\",\"format\":\"onnx\",\"precision\":\"fp32\",\"files\":[{\"relativePath\":\"onnx/scrypted_yolov9t_relu/scrypted_yolov9t_relu.onnx\",\"size\":8499266,\"sha256\":\"3f11ea2071b27c285b58c16636a44d6a0a27bdd1ca8b64112dfadabd39cfea47\"}],\"sizeMB\":8.5},{\"id\":\"scrypted-yolov9t-relu-test-coreml\",\"label\":\"plugin catalog YOLOv9T ReLU test CoreML\",\"family\":\"yolov9t\",\"variant\":\"relu_test\",\"format\":\"coreml\",\"precision\":\"fp16\",\"files\":[{\"relativePath\":\"coreml/scrypted_yolov9t_relu_test/scrypted_yolov9t_relu_test.mlpackage/Manifest.json\",\"size\":617,\"sha256\":\"a5e0128b643f1a66f3e07d4b332f9ccbca97ccab75651c794f0b9f1fb41c8491\"},{\"relativePath\":\"coreml/scrypted_yolov9t_relu_test/scrypted_yolov9t_relu_test.mlpackage/Data/com.apple.CoreML/model.mlmodel\",\"size\":322229,\"sha256\":\"79f4f647f2a0c79db3b560c84251b48c7ba7cbe9c1fecc9674d1a603a389dfa3\"},{\"relativePath\":\"coreml/scrypted_yolov9t_relu_test/scrypted_yolov9t_relu_test.mlpackage/Data/com.apple.CoreML/weights/weight.bin\",\"size\":3797160,\"sha256\":\"72efc9dc6af9241b5e5ee7de24a4f55741f6425d0e279d797f0f223e3d355f84\"}],\"sizeMB\":4.12},{\"id\":\"scrypted-yolov9t-relu-test-onnx\",\"label\":\"plugin catalog YOLOv9T ReLU test ONNX\",\"family\":\"yolov9t\",\"variant\":\"relu_test\",\"format\":\"onnx\",\"precision\":\"fp32\",\"files\":[{\"relativePath\":\"onnx/scrypted_yolov9t_relu_test/scrypted_yolov9t_relu_test.onnx\",\"size\":8499266,\"sha256\":\"d20aa0e6923a3af7f5e84e3a6d28fb00e8ecd592e3225f986f93bd34b634e2f8\"}],\"sizeMB\":8.5},{\"id\":\"scrypted-yolov9s-relu-coreml\",\"label\":\"plugin catalog YOLOv9S ReLU CoreML\",\"family\":\"yolov9s\",\"variant\":\"relu\",\"format\":\"coreml\",\"precision\":\"fp16\",\"files\":[{\"relativePath\":\"coreml/scrypted_yolov9s_relu/scrypted_yolov9s_relu.mlpackage/Manifest.json\",\"size\":617,\"sha256\":\"3bcdb820b82f1e89266f2d11bae1604d3ee4ca6d11dc5bd5c57055ff4157e9f3\"},{\"relativePath\":\"coreml/scrypted_yolov9s_relu/scrypted_yolov9s_relu.mlpackage/Data/com.apple.CoreML/model.mlmodel\",\"size\":322664,\"sha256\":\"9a9c3c9cbca406ec2f0418ec867ed6b878ec6d02c16636d30e0bbd83d2ff7c40\"},{\"relativePath\":\"coreml/scrypted_yolov9s_relu/scrypted_yolov9s_relu.mlpackage/Data/com.apple.CoreML/weights/weight.bin\",\"size\":14190120,\"sha256\":\"fd51eda58a993997268f6a2e424b536ba173207ad7974ab8bee2a8ff76d52dab\"}],\"sizeMB\":14.51},{\"id\":\"scrypted-yolov9s-relu-onnx\",\"label\":\"plugin catalog YOLOv9S ReLU ONNX\",\"family\":\"yolov9s\",\"variant\":\"relu\",\"format\":\"onnx\",\"precision\":\"fp32\",\"files\":[{\"relativePath\":\"onnx/scrypted_yolov9s_relu/scrypted_yolov9s_relu.onnx\",\"size\":29287339,\"sha256\":\"ca0b5bd98d5f59eb2029c6cb5129d53af59873f62a317a028beda463bbb96399\"}],\"sizeMB\":29.29},{\"id\":\"scrypted-yolov9s-relu-test-coreml\",\"label\":\"plugin catalog YOLOv9S ReLU test CoreML\",\"family\":\"yolov9s\",\"variant\":\"relu_test\",\"format\":\"coreml\",\"precision\":\"fp16\",\"files\":[{\"relativePath\":\"coreml/scrypted_yolov9s_relu_test/scrypted_yolov9s_relu_test.mlpackage/Manifest.json\",\"size\":617,\"sha256\":\"e2d24de0ce7e8573f19572029765e55abc714f36a85175ad7fcb95c001a76653\"},{\"relativePath\":\"coreml/scrypted_yolov9s_relu_test/scrypted_yolov9s_relu_test.mlpackage/Data/com.apple.CoreML/model.mlmodel\",\"size\":322664,\"sha256\":\"186b147cdfd15c5ed7a381ec3a426a22cee0b5c52d56f14efd26da06357f5cb0\"},{\"relativePath\":\"coreml/scrypted_yolov9s_relu_test/scrypted_yolov9s_relu_test.mlpackage/Data/com.apple.CoreML/weights/weight.bin\",\"size\":14190120,\"sha256\":\"e50651924c2cbffd56008a8953569e66c3de69f21807fcf7d825390ce30f21f8\"}],\"sizeMB\":14.51},{\"id\":\"scrypted-yolov9s-relu-test-onnx\",\"label\":\"plugin catalog YOLOv9S ReLU test ONNX\",\"family\":\"yolov9s\",\"variant\":\"relu_test\",\"format\":\"onnx\",\"precision\":\"fp32\",\"files\":[{\"relativePath\":\"onnx/scrypted_yolov9s_relu_test/scrypted_yolov9s_relu_test.onnx\",\"size\":29287339,\"sha256\":\"115ddb83333762a0f2599421335678696454a5c3571ade5df9bac8e9cb5fb4cf\"}],\"sizeMB\":29.29},{\"id\":\"scrypted-yolov9m-relu-coreml\",\"label\":\"plugin catalog YOLOv9M ReLU CoreML\",\"family\":\"yolov9m\",\"variant\":\"relu\",\"format\":\"coreml\",\"precision\":\"fp16\",\"files\":[{\"relativePath\":\"coreml/scrypted_yolov9m_relu/scrypted_yolov9m_relu.mlpackage/Manifest.json\",\"size\":617,\"sha256\":\"c548c6e1ff768b2b01bd71e230aa712a1635ae2baa30e0369557a42fc531ecbf\"},{\"relativePath\":\"coreml/scrypted_yolov9m_relu/scrypted_yolov9m_relu.mlpackage/Data/com.apple.CoreML/model.mlmodel\",\"size\":247061,\"sha256\":\"1c40e02fc2a2559cb906ea6cd9da9c730d4a78f5019290cbb38d2fcaae379fe7\"},{\"relativePath\":\"coreml/scrypted_yolov9m_relu/scrypted_yolov9m_relu.mlpackage/Data/com.apple.CoreML/weights/weight.bin\",\"size\":39880616,\"sha256\":\"4cf938e5bfcc3ee1644813e4eb4702a7de450cc0581df94c719cf43d0ed2e408\"}],\"sizeMB\":40.13},{\"id\":\"scrypted-yolov9m-relu-onnx\",\"label\":\"plugin catalog YOLOv9M ReLU ONNX\",\"family\":\"yolov9m\",\"variant\":\"relu\",\"format\":\"onnx\",\"precision\":\"fp32\",\"files\":[{\"relativePath\":\"onnx/scrypted_yolov9m_relu/scrypted_yolov9m_relu.onnx\",\"size\":80380404,\"sha256\":\"e7a81fb33224a0105d2a0a594c3fa43c398c361de623f1d14156ae826e7312d5\"}],\"sizeMB\":80.38},{\"id\":\"scrypted-yolov9m-relu-test-coreml\",\"label\":\"plugin catalog YOLOv9M ReLU test CoreML\",\"family\":\"yolov9m\",\"variant\":\"relu_test\",\"format\":\"coreml\",\"precision\":\"fp16\",\"files\":[{\"relativePath\":\"coreml/scrypted_yolov9m_relu_test/scrypted_yolov9m_relu_test.mlpackage/Manifest.json\",\"size\":617,\"sha256\":\"8e2684b286d02b4bdf9db1027c84cb89bf8e4830cfb58269f3ec457c5a010650\"},{\"relativePath\":\"coreml/scrypted_yolov9m_relu_test/scrypted_yolov9m_relu_test.mlpackage/Data/com.apple.CoreML/model.mlmodel\",\"size\":247061,\"sha256\":\"53d5946e74b13b15c5f8616081c9f15e8a95a5df3d5b45b830fc5a7f49561c16\"},{\"relativePath\":\"coreml/scrypted_yolov9m_relu_test/scrypted_yolov9m_relu_test.mlpackage/Data/com.apple.CoreML/weights/weight.bin\",\"size\":39880616,\"sha256\":\"69774bf0032c37707601b8cdc1e1820dbd9f8288eb5d6f3879618a5d34ff5199\"}],\"sizeMB\":40.13},{\"id\":\"scrypted-yolov9m-relu-test-onnx\",\"label\":\"plugin catalog YOLOv9M ReLU test ONNX\",\"family\":\"yolov9m\",\"variant\":\"relu_test\",\"format\":\"onnx\",\"precision\":\"fp32\",\"files\":[{\"relativePath\":\"onnx/scrypted_yolov9m_relu_test/scrypted_yolov9m_relu_test.onnx\",\"size\":80380404,\"sha256\":\"8bb054f099295909ec518e2a6598d63db24d3f90edc8105a0f016903f2a205a2\"}],\"sizeMB\":80.38},{\"id\":\"scrypted-yolov9c-relu-coreml\",\"label\":\"plugin catalog YOLOv9C ReLU CoreML\",\"family\":\"yolov9c\",\"variant\":\"relu\",\"format\":\"coreml\",\"precision\":\"fp16\",\"files\":[{\"relativePath\":\"coreml/scrypted_yolov9c_relu/scrypted_yolov9c_relu.mlpackage/Manifest.json\",\"size\":617,\"sha256\":\"813a306ebd69cabfd31f00434f5a961feeca7d237833f3e11805dcf4ad120ba9\"},{\"relativePath\":\"coreml/scrypted_yolov9c_relu/scrypted_yolov9c_relu.mlpackage/Data/com.apple.CoreML/model.mlmodel\",\"size\":263210,\"sha256\":\"862f082619075e470738306b0ff0a37ae70a7d08e684ca6a6dfa1971d404e0c3\"},{\"relativePath\":\"coreml/scrypted_yolov9c_relu/scrypted_yolov9c_relu.mlpackage/Data/com.apple.CoreML/weights/weight.bin\",\"size\":50489960,\"sha256\":\"ed89747e58943758e2a87221d1d404f6a4466cbc039c3c6f96e327cadc403d27\"}],\"sizeMB\":50.75},{\"id\":\"scrypted-yolov9c-relu-onnx\",\"label\":\"plugin catalog YOLOv9C ReLU ONNX\",\"family\":\"yolov9c\",\"variant\":\"relu\",\"format\":\"onnx\",\"precision\":\"fp32\",\"files\":[{\"relativePath\":\"onnx/scrypted_yolov9c_relu/scrypted_yolov9c_relu.onnx\",\"size\":101631962,\"sha256\":\"b9372c4428daf4cd944c114b1e80d1a9ff0487d743e53a77216a051cfbef7116\"}],\"sizeMB\":101.63},{\"id\":\"scrypted-yolov9c-relu-test-coreml\",\"label\":\"plugin catalog YOLOv9C ReLU test CoreML\",\"family\":\"yolov9c\",\"variant\":\"relu_test\",\"format\":\"coreml\",\"precision\":\"fp16\",\"files\":[{\"relativePath\":\"coreml/scrypted_yolov9c_relu_test/scrypted_yolov9c_relu_test.mlpackage/Manifest.json\",\"size\":617,\"sha256\":\"966ef82a93cb0ccf1036a8c9729c065fd372fa9590a97d0945e581cc674f7ad2\"},{\"relativePath\":\"coreml/scrypted_yolov9c_relu_test/scrypted_yolov9c_relu_test.mlpackage/Data/com.apple.CoreML/model.mlmodel\",\"size\":263210,\"sha256\":\"08718ecd3e9552d21a702bd8df60911cad0eec7b2ae382466809550f14634711\"},{\"relativePath\":\"coreml/scrypted_yolov9c_relu_test/scrypted_yolov9c_relu_test.mlpackage/Data/com.apple.CoreML/weights/weight.bin\",\"size\":50489960,\"sha256\":\"fe5936b9430ab4c87f30b148220131d6ec998b2377223d033e2fa2a00e60aada\"}],\"sizeMB\":50.75},{\"id\":\"scrypted-yolov9c-relu-test-onnx\",\"label\":\"plugin catalog YOLOv9C ReLU test ONNX\",\"family\":\"yolov9c\",\"variant\":\"relu_test\",\"format\":\"onnx\",\"precision\":\"fp32\",\"files\":[{\"relativePath\":\"onnx/scrypted_yolov9c_relu_test/scrypted_yolov9c_relu_test.onnx\",\"size\":101631962,\"sha256\":\"2f4e2031e8efb4cbc871594338b2e875d78ab4af3ee0258d253273b1aac84742\"}],\"sizeMB\":101.63},{\"id\":\"scrypted-yolov9t-relu-openvino-fp32\",\"label\":\"plugin catalog YOLOv9T ReLU OpenVINO FP32\",\"family\":\"yolov9t\",\"variant\":\"relu\",\"format\":\"openvino\",\"precision\":\"fp32\",\"files\":[{\"relativePath\":\"openvino/scrypted_yolov9t_relu/best-converted.xml\",\"size\":628222,\"sha256\":\"01b5a9d02a0f281e1aaf4860e1b0ed3a7f16b9d78975be8ff985ae0ee283d877\"},{\"relativePath\":\"openvino/scrypted_yolov9t_relu/best-converted.bin\",\"size\":7542204,\"sha256\":\"4fe9ce8dbdf94514fdd450cbfc907f257153e4898a0c1489a44e4912d8e32cc7\"}],\"sizeMB\":8.17},{\"id\":\"scrypted-yolov9s-relu-openvino-fp32\",\"label\":\"plugin catalog YOLOv9S ReLU OpenVINO FP32\",\"family\":\"yolov9s\",\"variant\":\"relu\",\"format\":\"openvino\",\"precision\":\"fp32\",\"files\":[{\"relativePath\":\"openvino/scrypted_yolov9s_relu/best-converted.xml\",\"size\":629249,\"sha256\":\"5b4a229bf7229425698b63bd065a403e440a6151a6ddff0034867659cc4a480d\"},{\"relativePath\":\"openvino/scrypted_yolov9s_relu/best-converted.bin\",\"size\":28329724,\"sha256\":\"c030bd219208ea94082578c81f383d4ef9ec45d7150eec1c2c2ff2569cf49b35\"}],\"sizeMB\":28.96},{\"id\":\"scrypted-yolov9m-relu-openvino-fp32\",\"label\":\"plugin catalog YOLOv9M ReLU OpenVINO FP32\",\"family\":\"yolov9m\",\"variant\":\"relu\",\"format\":\"openvino\",\"precision\":\"fp32\",\"files\":[{\"relativePath\":\"openvino/scrypted_yolov9m_relu/best-converted.xml\",\"size\":485439,\"sha256\":\"c66f9f1965bf70fd3635d4dfc3cb94c72c06b344c256713237d77706725b9a0c\"},{\"relativePath\":\"openvino/scrypted_yolov9m_relu/best-converted.bin\",\"size\":79717372,\"sha256\":\"dfc2d8952bbca9ad0e116168e3fd5c754e601c327d78c4f4d0d4cae12f0e1d2a\"}],\"sizeMB\":80.2},{\"id\":\"scrypted-yolov9c-relu-openvino-fp32\",\"label\":\"plugin catalog YOLOv9C ReLU OpenVINO FP32\",\"family\":\"yolov9c\",\"variant\":\"relu\",\"format\":\"openvino\",\"precision\":\"fp32\",\"files\":[{\"relativePath\":\"openvino/scrypted_yolov9c_relu/best-converted.xml\",\"size\":535047,\"sha256\":\"836c1e998ebf76108ff64d554fdfa07aa72c42624f1a5448701bb409f27b8d68\"},{\"relativePath\":\"openvino/scrypted_yolov9c_relu/best-converted.bin\",\"size\":100942972,\"sha256\":\"11a1b330ac9843b349927977b3c7c7f17bb42af73a7ff102969132f27ab81814\"}],\"sizeMB\":101.48},{\"id\":\"scrypted-yolov9t-relu-openvino-int8\",\"label\":\"plugin catalog YOLOv9T ReLU OpenVINO INT8\",\"family\":\"yolov9t\",\"variant\":\"relu\",\"format\":\"openvino\",\"precision\":\"int8\",\"files\":[{\"relativePath\":\"openvino/scrypted_yolov9t_relu_int8/best-converted.xml\",\"size\":1380379,\"sha256\":\"e5a76bf88ac69fc0ebc50c04b61ff91550dd9c2349af1f6d7e4cac949c640cec\"},{\"relativePath\":\"openvino/scrypted_yolov9t_relu_int8/best-converted.bin\",\"size\":1954956,\"sha256\":\"98fb5b6826d7c6697a585f69ba96754873772d9d61fbed8335aab761e8248659\"}],\"sizeMB\":3.34},{\"id\":\"scrypted-yolov9t-relu-test-openvino-int8\",\"label\":\"plugin catalog YOLOv9T ReLU test OpenVINO INT8\",\"family\":\"yolov9t\",\"variant\":\"relu_test\",\"format\":\"openvino\",\"precision\":\"int8\",\"files\":[{\"relativePath\":\"openvino/scrypted_yolov9t_relu_test_int8/best-converted.xml\",\"size\":1380383,\"sha256\":\"9e4119284e923e08c9929e78fd31e2552e602a552ac538ae99bf34a50dd4d172\"},{\"relativePath\":\"openvino/scrypted_yolov9t_relu_test_int8/best-converted.bin\",\"size\":1954960,\"sha256\":\"efe5b0a2fd2f5ddef5923eeb9e592a7ef14719061bb7605c86e05b35c2c58ea9\"}],\"sizeMB\":3.34},{\"id\":\"scrypted-yolov9s-relu-openvino-int8\",\"label\":\"plugin catalog YOLOv9S ReLU OpenVINO INT8\",\"family\":\"yolov9s\",\"variant\":\"relu\",\"format\":\"openvino\",\"precision\":\"int8\",\"files\":[{\"relativePath\":\"openvino/scrypted_yolov9s_relu_int8/best-converted.xml\",\"size\":1382088,\"sha256\":\"4e6c24cf24afbab21462f7e1a15bd05b1cbbe5915046000e03c2435d8110bbbf\"},{\"relativePath\":\"openvino/scrypted_yolov9s_relu_int8/best-converted.bin\",\"size\":7197308,\"sha256\":\"23fd3d666a938c41db232d9c6239baec1134716cfb4ed4ddd3d602dd20eb8ac0\"}],\"sizeMB\":8.58},{\"id\":\"scrypted-yolov9s-relu-test-openvino-int8\",\"label\":\"plugin catalog YOLOv9S ReLU test OpenVINO INT8\",\"family\":\"yolov9s\",\"variant\":\"relu_test\",\"format\":\"openvino\",\"precision\":\"int8\",\"files\":[{\"relativePath\":\"openvino/scrypted_yolov9s_relu_test_int8/best-converted.xml\",\"size\":1382092,\"sha256\":\"49865bfeafe7576afce089ba6f5c3e25a9192c8b514eb96265c90fe877795641\"},{\"relativePath\":\"openvino/scrypted_yolov9s_relu_test_int8/best-converted.bin\",\"size\":7197312,\"sha256\":\"78e9d36e6b74754db2b624ea3ec0b3ff57ed6dfed59a4f2225e1a271054597de\"}],\"sizeMB\":8.58},{\"id\":\"scrypted-yolov9m-relu-openvino-int8\",\"label\":\"plugin catalog YOLOv9M ReLU OpenVINO INT8\",\"family\":\"yolov9m\",\"variant\":\"relu\",\"format\":\"openvino\",\"precision\":\"int8\",\"files\":[{\"relativePath\":\"openvino/scrypted_yolov9m_relu_int8/best-converted.xml\",\"size\":1024595,\"sha256\":\"1242ab8d8c73b2e80c5dd541177ade6e102a2684114b059136acb4cad6efb034\"},{\"relativePath\":\"openvino/scrypted_yolov9m_relu_int8/best-converted.bin\",\"size\":20090516,\"sha256\":\"da8e44af8bee66478e6f359e9504bfb13ab4b76f4bd8a2f1b10cfbc22febcf6e\"}],\"sizeMB\":21.12},{\"id\":\"scrypted-yolov9m-relu-test-openvino-int8\",\"label\":\"plugin catalog YOLOv9M ReLU test OpenVINO INT8\",\"family\":\"yolov9m\",\"variant\":\"relu_test\",\"format\":\"openvino\",\"precision\":\"int8\",\"files\":[{\"relativePath\":\"openvino/scrypted_yolov9m_relu_test_int8/best-converted.xml\",\"size\":1024601,\"sha256\":\"24395ae5fdbb321304c865372cd2b905cdc55abb7610520f3963702e2371decb\"},{\"relativePath\":\"openvino/scrypted_yolov9m_relu_test_int8/best-converted.bin\",\"size\":20090520,\"sha256\":\"4360fe0312067f92c49f180c7b8a10271f14d58b8909aa9b96b13af4ab9289aa\"}],\"sizeMB\":21.12},{\"id\":\"scrypted-yolov9c-relu-openvino-int8\",\"label\":\"plugin catalog YOLOv9C ReLU OpenVINO INT8\",\"family\":\"yolov9c\",\"variant\":\"relu\",\"format\":\"openvino\",\"precision\":\"int8\",\"files\":[{\"relativePath\":\"openvino/scrypted_yolov9c_relu_int8/best-converted.xml\",\"size\":1092695,\"sha256\":\"a45c62940120c4301d8fff9fb3b275c29e3618f403ea68a785f2f3220cefec7a\"},{\"relativePath\":\"openvino/scrypted_yolov9c_relu_int8/best-converted.bin\",\"size\":25428280,\"sha256\":\"0643403a56178c3ed1e066c7884458d8ea6780115d662bdc38d10754d7a11c79\"}],\"sizeMB\":26.52},{\"id\":\"scrypted-yolov9c-relu-test-openvino-int8\",\"label\":\"plugin catalog YOLOv9C ReLU test OpenVINO INT8\",\"family\":\"yolov9c\",\"variant\":\"relu_test\",\"format\":\"openvino\",\"precision\":\"int8\",\"files\":[{\"relativePath\":\"openvino/scrypted_yolov9c_relu_test_int8/best-converted.xml\",\"size\":1092695,\"sha256\":\"a8a1899848ebd060af2326d3c8d3c09ea83354f0bedff6cce6fa08b284ea5519\"},{\"relativePath\":\"openvino/scrypted_yolov9c_relu_test_int8/best-converted.bin\",\"size\":25428280,\"sha256\":\"2eb6bb3d0a03a9b239b6f623f9e7bced62eea61fbe4d8ff89c1b3e2e2b7978a2\"}],\"sizeMB\":26.52},{\"id\":\"scrypted-yolov9s-relu-sep-320-tflite-float16\",\"label\":\"plugin catalog YOLOv9s ReLU sep 320 TFLite float16\",\"family\":\"yolov9s\",\"variant\":\"relu\",\"format\":\"tflite\",\"precision\":\"float16\",\"files\":[{\"relativePath\":\"tflite/scrypted_yolov9s_relu_sep_320/best_float16.tflite\",\"size\":14482836,\"sha256\":\"04889db3b81af361c361e41ffa99327330d37b71d680a2f889e6cdf1e94c0d8c\"}],\"sizeMB\":14.48},{\"id\":\"scrypted-yolov9s-relu-sep-320-tflite-float32\",\"label\":\"plugin catalog YOLOv9s ReLU sep 320 TFLite float32\",\"family\":\"yolov9s\",\"variant\":\"relu\",\"format\":\"tflite\",\"precision\":\"float32\",\"files\":[{\"relativePath\":\"tflite/scrypted_yolov9s_relu_sep_320/best_float32.tflite\",\"size\":28777068,\"sha256\":\"f5d7d08fc1d8f2262633d2df4391638e0481740331aaa1837880a47c33001a96\"}],\"sizeMB\":28.78},{\"id\":\"scrypted-yolov9s-relu-sep-320-tflite-int8\",\"label\":\"plugin catalog YOLOv9s ReLU sep 320 TFLite int8\",\"family\":\"yolov9s\",\"variant\":\"relu\",\"format\":\"tflite\",\"precision\":\"int8\",\"files\":[{\"relativePath\":\"tflite/scrypted_yolov9s_relu_sep_320/best_int8.tflite\",\"size\":7325616,\"sha256\":\"1e9866b16fe80931383bf3c94dc629fe93a37ba3dc1465ea019eb0a50bd428df\"}],\"sizeMB\":7.33},{\"id\":\"scrypted-yolov9s-relu-sep-320-tflite-integer_quant\",\"label\":\"plugin catalog YOLOv9s ReLU sep 320 TFLite integer_quant\",\"family\":\"yolov9s\",\"variant\":\"relu\",\"format\":\"tflite\",\"precision\":\"integer_quant\",\"files\":[{\"relativePath\":\"tflite/scrypted_yolov9s_relu_sep_320/best_integer_quant.tflite\",\"size\":7342552,\"sha256\":\"bc1c902e9a9865637ee2403f70c6bf5c29c695d9163e58ad658feb29bb097ebc\"}],\"sizeMB\":7.34},{\"id\":\"scrypted-yolov9s-relu-sep-320-tflite-full_integer_quant\",\"label\":\"plugin catalog YOLOv9s ReLU sep 320 TFLite full_integer_quant\",\"family\":\"yolov9s\",\"variant\":\"relu\",\"format\":\"tflite\",\"precision\":\"full_integer_quant\",\"files\":[{\"relativePath\":\"tflite/scrypted_yolov9s_relu_sep_320/best_full_integer_quant.tflite\",\"size\":7341704,\"sha256\":\"483ce38dbe33ee5a35f40a82f56c77629a44fa5d95efd8ade9fa97e4d2a261fd\"}],\"sizeMB\":7.34},{\"id\":\"scrypted-yolov9s-relu-sep-320-tflite-edgetpu\",\"label\":\"plugin catalog YOLOv9s ReLU sep 320 TFLite edgetpu\",\"family\":\"yolov9s\",\"variant\":\"relu\",\"format\":\"tflite\",\"precision\":\"edgetpu\",\"files\":[{\"relativePath\":\"tflite/scrypted_yolov9s_relu_sep_320/best_full_integer_quant_edgetpu.tflite\",\"size\":8164480,\"sha256\":\"e1e6b074a3b9fdf19a171baf615553ad375a046aa7de2a3fef9a1950175fab22\"}],\"sizeMB\":8.16}]");
16
16
  //#endregion
17
17
  //#region src/model-licenses.ts
18
18
  /**
19
- * Scrypted's YOLOv9 ReLU detectors. Checked 2026-09-27 on
19
+ * plugin catalog's YOLOv9 ReLU detectors. Checked 2026-09-27 on
20
20
  * `onnx/scrypted_yolov9t_relu/scrypted_yolov9t_relu.onnx` at the pinned
21
21
  * revision: no licence in the ONNX metadata, and the export's node traces name
22
22
  * `models.yolo.DetectionModel` / `models.common.Conv` from a `yolov9/` checkout
@@ -24,23 +24,23 @@ var scrypted_yolo_manifest_data_default = /*#__PURE__*/ JSON.parse("[{\"id\":\"s
24
24
  * card says `license: mit` at repository level; nothing states terms per model
25
25
  * or names the training data. So: code GPL-3.0, weights UNKNOWN.
26
26
  */
27
- var SCRYPTED_YOLOV9_UNKNOWN = {
27
+ var PLUGIN_CATALOG_YOLOV9_UNKNOWN = {
28
28
  weights: "UNKNOWN",
29
29
  code: "GPL-3.0",
30
30
  data: {
31
- name: "not stated by Scrypted",
31
+ name: "not stated by plugin catalog",
32
32
  terms: "UNKNOWN"
33
33
  },
34
34
  upstream: {
35
- name: "Scrypted plugin-models (repository tagged MIT, no per-model terms)",
35
+ name: "plugin catalog plugin-models (repository tagged MIT, no per-model terms)",
36
36
  url: "https://huggingface.co/scrypted/plugin-models"
37
37
  },
38
38
  url: "https://huggingface.co/scrypted/plugin-models",
39
- attribution: "Scrypted YOLOv9 ReLU detectors, Koushik Dutta (scrypted/plugin-models, repository tagged MIT); trained with the YOLOv9 code of Chien-Yao Wang, I-Hau Yeh, Hong-Yuan Mark Liao, GPL-3.0 (https://github.com/WongKinYiu/yolov9).",
39
+ attribution: "plugin catalog YOLOv9 ReLU detectors, Koushik Dutta (scrypted/plugin-models, repository tagged MIT); trained with the YOLOv9 code of Chien-Yao Wang, I-Hau Yeh, Hong-Yuan Mark Liao, GPL-3.0 (https://github.com/WongKinYiu/yolov9).",
40
40
  modifications: "none: downloaded as published, at a pinned revision",
41
41
  hosting: "third-party"
42
42
  };
43
- /** Frigate's default Coral model: Google's SSDLite MobileDet, Apache-2.0. */
43
+ /** plus catalog's default Coral model: Google's SSDLite MobileDet, Apache-2.0. */
44
44
  var CORAL_MOBILEDET_APACHE = {
45
45
  weights: "Apache-2.0",
46
46
  code: "Apache-2.0",
@@ -58,17 +58,17 @@ var CORAL_MOBILEDET_APACHE = {
58
58
  hosting: "third-party"
59
59
  };
60
60
  //#endregion
61
- //#region src/scrypted/scrypted-yolo-manifest.ts
62
- var SCRYPTED_SHA256_RE = /^[0-9a-f]{64}$/;
63
- var SCRYPTED_HF_HOST = "https://huggingface.co";
64
- var SCRYPTED_HF_REPO = "scrypted/plugin-models";
65
- var SCRYPTED_HF_REVISION = "187402b20a3be0a7fab9bceee21d857ed6ae0064";
66
- var SCRYPTED_YOLO_LABELS = [
61
+ //#region src/plugin-catalog/plugin-catalog-yolo-manifest.ts
62
+ var PLUGIN_CATALOG_SHA256_RE = /^[0-9a-f]{64}$/;
63
+ var PLUGIN_CATALOG_HF_HOST = "https://huggingface.co";
64
+ var PLUGIN_CATALOG_HF_REPO = "scrypted/plugin-models";
65
+ var PLUGIN_CATALOG_HF_REVISION = "187402b20a3be0a7fab9bceee21d857ed6ae0064";
66
+ var PLUGIN_CATALOG_YOLO_LABELS = [
67
67
  "person",
68
68
  "vehicle",
69
69
  "animal"
70
70
  ];
71
- var SCRYPTED_IDENTITY_CLASS_MAP = {
71
+ var PLUGIN_CATALOG_IDENTITY_CLASS_MAP = {
72
72
  mapping: {
73
73
  person: "person",
74
74
  vehicle: "vehicle",
@@ -76,7 +76,7 @@ var SCRYPTED_IDENTITY_CLASS_MAP = {
76
76
  },
77
77
  preserveOriginal: false
78
78
  };
79
- var SCRYPTED_LABEL_DEFS = SCRYPTED_YOLO_LABELS.map((id) => ({
79
+ var PLUGIN_CATALOG_LABEL_DEFS = PLUGIN_CATALOG_YOLO_LABELS.map((id) => ({
80
80
  id,
81
81
  name: id
82
82
  }));
@@ -89,22 +89,22 @@ var INPUT_SIZE = {
89
89
  width: 320,
90
90
  height: 320
91
91
  };
92
- function assertScryptedFileSha256(value, relativePath) {
93
- if (value === void 0 || !SCRYPTED_SHA256_RE.test(value)) throw new Error(`Invalid sha256 for ${relativePath}: expected 64 lowercase hex`);
92
+ function assertPluginCatalogFileSha256(value, relativePath) {
93
+ if (value === void 0 || !PLUGIN_CATALOG_SHA256_RE.test(value)) throw new Error(`Invalid sha256 for ${relativePath}: expected 64 lowercase hex`);
94
94
  return value;
95
95
  }
96
- function assertScryptedRelativePath(value) {
97
- if (value.length === 0 || value.startsWith("/") || value.includes("\\") || value.includes("\0")) throw new Error(`Unsafe Scrypted relative path: ${value}`);
98
- if (value.split("/").some((segment) => segment.length === 0 || segment === "." || segment === "..")) throw new Error(`Unsafe Scrypted relative path: ${value}`);
96
+ function assertPluginCatalogRelativePath(value) {
97
+ if (value.length === 0 || value.startsWith("/") || value.includes("\\") || value.includes("\0")) throw new Error(`Unsafe plugin catalog relative path: ${value}`);
98
+ if (value.split("/").some((segment) => segment.length === 0 || segment === "." || segment === "..")) throw new Error(`Unsafe plugin catalog relative path: ${value}`);
99
99
  return value;
100
100
  }
101
- function buildScryptedResolveUrl(relativePath) {
102
- return `${SCRYPTED_HF_HOST}/${SCRYPTED_HF_REPO}/resolve/${SCRYPTED_HF_REVISION}/${assertScryptedRelativePath(relativePath).split("/").map((segment) => encodeURIComponent(segment)).join("/")}`;
101
+ function buildPluginCatalogResolveUrl(relativePath) {
102
+ return `${PLUGIN_CATALOG_HF_HOST}/${PLUGIN_CATALOG_HF_REPO}/resolve/${PLUGIN_CATALOG_HF_REVISION}/${assertPluginCatalogRelativePath(relativePath).split("/").map((segment) => encodeURIComponent(segment)).join("/")}`;
103
103
  }
104
104
  function packageDirectory(files) {
105
105
  const manifest = files.find((file) => file.relativePath.endsWith("/Manifest.json"));
106
106
  if (!manifest) throw new Error("CoreML entry is missing Manifest.json");
107
- return assertScryptedRelativePath(manifest.relativePath.replace(/\/Manifest\.json$/, ""));
107
+ return assertPluginCatalogRelativePath(manifest.relativePath.replace(/\/Manifest\.json$/, ""));
108
108
  }
109
109
  function buildModel(spec) {
110
110
  const tier = spec.family.slice(-1);
@@ -127,25 +127,25 @@ function buildModel(spec) {
127
127
  if (spec.variant === "relu_test") nameParts.push("(Test)");
128
128
  if (int8) nameParts.push("INT8");
129
129
  const name = nameParts.join(" ");
130
- const description = `${name} — imported from the local Scrypted YOLO catalog.`;
130
+ const description = `${name} — imported from the local plugin catalog YOLO catalog.`;
131
131
  if (spec.format === "coreml") return {
132
132
  id: canonicalId,
133
133
  name,
134
134
  description,
135
135
  formats: { coreml: {
136
- url: buildScryptedResolveUrl(packageDirectory(spec.files)),
136
+ url: buildPluginCatalogResolveUrl(packageDirectory(spec.files)),
137
137
  sizeMB: spec.sizeMB,
138
138
  isDirectory: true,
139
139
  files: [...MLPACKAGE_INNER_FILES],
140
140
  runtimes: ["python"]
141
141
  } },
142
142
  inputSize: INPUT_SIZE,
143
- labels: SCRYPTED_LABEL_DEFS,
143
+ labels: PLUGIN_CATALOG_LABEL_DEFS,
144
144
  preprocessMode: "resize",
145
- classMap: SCRYPTED_IDENTITY_CLASS_MAP,
145
+ classMap: PLUGIN_CATALOG_IDENTITY_CLASS_MAP,
146
146
  group,
147
147
  provider: "scrypted",
148
- license: SCRYPTED_YOLOV9_UNKNOWN
148
+ license: PLUGIN_CATALOG_YOLOV9_UNKNOWN
149
149
  };
150
150
  if (spec.format === "openvino") {
151
151
  const xml = spec.files.find((file) => file.relativePath.endsWith(".xml"));
@@ -157,18 +157,18 @@ function buildModel(spec) {
157
157
  name,
158
158
  description,
159
159
  formats: { openvino: {
160
- url: buildScryptedResolveUrl(xml.relativePath),
160
+ url: buildPluginCatalogResolveUrl(xml.relativePath),
161
161
  sizeMB: spec.sizeMB,
162
162
  files: [binName],
163
163
  runtimes: ["python"]
164
164
  } },
165
165
  inputSize: INPUT_SIZE,
166
- labels: SCRYPTED_LABEL_DEFS,
166
+ labels: PLUGIN_CATALOG_LABEL_DEFS,
167
167
  preprocessMode: "resize",
168
- classMap: SCRYPTED_IDENTITY_CLASS_MAP,
168
+ classMap: PLUGIN_CATALOG_IDENTITY_CLASS_MAP,
169
169
  group,
170
170
  provider: "scrypted",
171
- license: SCRYPTED_YOLOV9_UNKNOWN
171
+ license: PLUGIN_CATALOG_YOLOV9_UNKNOWN
172
172
  };
173
173
  }
174
174
  const main = spec.files[0];
@@ -178,25 +178,25 @@ function buildModel(spec) {
178
178
  name,
179
179
  description,
180
180
  formats: { [spec.format]: {
181
- url: buildScryptedResolveUrl(main.relativePath),
181
+ url: buildPluginCatalogResolveUrl(main.relativePath),
182
182
  sizeMB: spec.sizeMB,
183
183
  runtimes: spec.format === "tflite" ? ["python"] : void 0
184
184
  } },
185
185
  inputSize: INPUT_SIZE,
186
- labels: SCRYPTED_LABEL_DEFS,
186
+ labels: PLUGIN_CATALOG_LABEL_DEFS,
187
187
  preprocessMode: "resize",
188
- classMap: SCRYPTED_IDENTITY_CLASS_MAP,
188
+ classMap: PLUGIN_CATALOG_IDENTITY_CLASS_MAP,
189
189
  group,
190
190
  provider: "scrypted",
191
- license: SCRYPTED_YOLOV9_UNKNOWN,
191
+ license: PLUGIN_CATALOG_YOLOV9_UNKNOWN,
192
192
  ...spec.format === "tflite" ? { postprocessor: "yolo-split-dfl" } : {}
193
193
  };
194
194
  }
195
195
  function freezeEntry(spec) {
196
196
  const files = spec.files.map((file) => Object.freeze({
197
- relativePath: assertScryptedRelativePath(file.relativePath),
197
+ relativePath: assertPluginCatalogRelativePath(file.relativePath),
198
198
  size: file.size,
199
- sha256: assertScryptedFileSha256(file.sha256, file.relativePath)
199
+ sha256: assertPluginCatalogFileSha256(file.sha256, file.relativePath)
200
200
  }));
201
201
  return Object.freeze({
202
202
  id: spec.id,
@@ -213,26 +213,26 @@ function freezeEntry(spec) {
213
213
  })
214
214
  });
215
215
  }
216
- var SCRYPTED_YOLO_MANIFEST = Object.freeze(scrypted_yolo_manifest_data_default.map(freezeEntry));
217
- function getScryptedManifestEntry(manifestId) {
218
- return SCRYPTED_YOLO_MANIFEST.find((entry) => entry.id === manifestId);
216
+ var PLUGIN_CATALOG_YOLO_MANIFEST = Object.freeze(plugin_catalog_yolo_manifest_data_default.map(freezeEntry));
217
+ function getPluginCatalogManifestEntry(manifestId) {
218
+ return PLUGIN_CATALOG_YOLO_MANIFEST.find((entry) => entry.id === manifestId);
219
219
  }
220
220
  //#endregion
221
- //#region src/scrypted/scrypted-tree-drift.ts
221
+ //#region src/plugin-catalog/plugin-catalog-tree-drift.ts
222
222
  /**
223
- * Read-only drift check: compare the local Scrypted YOLO manifest to a
223
+ * Read-only drift check: compare the local plugin catalog YOLO manifest to a
224
224
  * Hugging Face tree. Never mutates the manifest and never auto-imports
225
225
  * remote-only files.
226
226
  */
227
- var SCRYPTED_KNOWN_DRIFT_STATUSES = [
227
+ var PLUGIN_CATALOG_KNOWN_DRIFT_STATUSES = [
228
228
  "ok",
229
229
  "missing",
230
230
  "size-changed",
231
231
  "unavailable"
232
232
  ];
233
233
  /** Fail-closed: a future/unknown status is never treated as `ok`. */
234
- function normalizeScryptedDrift(row) {
235
- if (SCRYPTED_KNOWN_DRIFT_STATUSES.includes(row.status)) return {
234
+ function normalizePluginCatalogDrift(row) {
235
+ if (PLUGIN_CATALOG_KNOWN_DRIFT_STATUSES.includes(row.status)) return {
236
236
  manifestId: row.manifestId,
237
237
  status: row.status,
238
238
  ...row.details !== void 0 ? { details: row.details } : {}
@@ -246,7 +246,7 @@ function normalizeScryptedDrift(row) {
246
246
  function remoteSize(file) {
247
247
  return file.lfs?.size ?? file.size;
248
248
  }
249
- function compareScryptedManifestDrift(manifest, tree) {
249
+ function comparePluginCatalogManifestDrift(manifest, tree) {
250
250
  const byPath = new Map(tree.map((file) => [file.path, file]));
251
251
  return manifest.map((entry) => {
252
252
  const missing = [];
@@ -275,25 +275,25 @@ function compareScryptedManifestDrift(manifest, tree) {
275
275
  };
276
276
  });
277
277
  }
278
- var ScryptedTreeLinkError = class extends Error {
278
+ var PluginCatalogTreeLinkError = class extends Error {
279
279
  constructor(message) {
280
280
  super(message);
281
- this.name = "ScryptedTreeLinkError";
281
+ this.name = "PluginCatalogTreeLinkError";
282
282
  }
283
283
  };
284
- function assertScryptedTreePageUrl(url, revision) {
285
- if (url.protocol !== "https:") throw new ScryptedTreeLinkError(`Refusing non-https tree link: ${url.protocol}`);
286
- if (url.username || url.password) throw new ScryptedTreeLinkError("Refusing tree link with userinfo");
287
- if (url.origin !== `https://huggingface.co`) throw new ScryptedTreeLinkError(`Refusing tree link origin ${url.origin}`);
288
- const expectedPath = `/api/models/${SCRYPTED_HF_REPO}/tree/${revision}`;
289
- if (url.pathname !== expectedPath) throw new ScryptedTreeLinkError(`Refusing tree link path/revision ${url.pathname} (expected ${expectedPath})`);
284
+ function assertPluginCatalogTreePageUrl(url, revision) {
285
+ if (url.protocol !== "https:") throw new PluginCatalogTreeLinkError(`Refusing non-https tree link: ${url.protocol}`);
286
+ if (url.username || url.password) throw new PluginCatalogTreeLinkError("Refusing tree link with userinfo");
287
+ if (url.origin !== `https://huggingface.co`) throw new PluginCatalogTreeLinkError(`Refusing tree link origin ${url.origin}`);
288
+ const expectedPath = `/api/models/${PLUGIN_CATALOG_HF_REPO}/tree/${revision}`;
289
+ if (url.pathname !== expectedPath) throw new PluginCatalogTreeLinkError(`Refusing tree link path/revision ${url.pathname} (expected ${expectedPath})`);
290
290
  }
291
291
  /**
292
292
  * Parse `Link: <...>; rel="next"` and accept only an HTTPS huggingface.co
293
293
  * tree URL for the same repo + revision. Relative hrefs resolve against the
294
294
  * current page URL. Never returns a URL that failed validation.
295
295
  */
296
- function resolveScryptedTreeNextLink(header, currentUrl, revision) {
296
+ function resolvePluginCatalogTreeNextLink(header, currentUrl, revision) {
297
297
  if (!header) return void 0;
298
298
  const match = /<([^>]+)>;\s*rel="next"/.exec(header);
299
299
  if (!match?.[1]) return void 0;
@@ -301,34 +301,34 @@ function resolveScryptedTreeNextLink(header, currentUrl, revision) {
301
301
  try {
302
302
  resolved = new URL(match[1], currentUrl);
303
303
  } catch {
304
- throw new ScryptedTreeLinkError(`Refusing unparsable tree next link: ${match[1]}`);
304
+ throw new PluginCatalogTreeLinkError(`Refusing unparsable tree next link: ${match[1]}`);
305
305
  }
306
- assertScryptedTreePageUrl(resolved, revision);
306
+ assertPluginCatalogTreePageUrl(resolved, revision);
307
307
  return resolved.href;
308
308
  }
309
309
  async function sleep(ms) {
310
310
  if (ms <= 0) return;
311
311
  await new Promise((resolve) => setTimeout(resolve, ms));
312
312
  }
313
- async function fetchScryptedRemoteTree(opts) {
313
+ async function fetchPluginCatalogRemoteTree(opts) {
314
314
  const revision = opts.revision ?? "main";
315
315
  const maxRetries = opts.maxRetries ?? 4;
316
316
  const retryDelayMs = opts.retryDelayMs ?? 200;
317
- let lastError = /* @__PURE__ */ new Error("Scrypted Hugging Face tree unavailable");
317
+ let lastError = /* @__PURE__ */ new Error("plugin catalog Hugging Face tree unavailable");
318
318
  for (let attempt = 0; attempt < maxRetries; attempt++) try {
319
319
  const files = [];
320
- let url = `${SCRYPTED_HF_HOST}/api/models/${SCRYPTED_HF_REPO}/tree/${encodeURIComponent(revision)}?recursive=true&expand=true`;
320
+ let url = `${PLUGIN_CATALOG_HF_HOST}/api/models/${PLUGIN_CATALOG_HF_REPO}/tree/${encodeURIComponent(revision)}?recursive=true&expand=true`;
321
321
  let pages = 0;
322
322
  while (url) {
323
323
  pages += 1;
324
- if (pages > 50) throw new Error("Scrypted Hugging Face tree pagination exceeded the bound");
325
- assertScryptedTreePageUrl(new URL(url), revision);
324
+ if (pages > 50) throw new Error("plugin catalog Hugging Face tree pagination exceeded the bound");
325
+ assertPluginCatalogTreePageUrl(new URL(url), revision);
326
326
  const response = await opts.fetchImpl(url, {
327
327
  redirect: "manual",
328
328
  headers: { "User-Agent": "CamStack/1.0" }
329
329
  });
330
- if (response.status === 301 || response.status === 302 || response.status === 303 || response.status === 307 || response.status === 308) throw new ScryptedTreeLinkError(`Refusing tree API redirect ${response.status} (fail-closed, no follow)`);
331
- if (!response.ok) throw new Error(`HTTP ${response.status} fetching Scrypted Hugging Face tree`);
330
+ if (response.status === 301 || response.status === 302 || response.status === 303 || response.status === 307 || response.status === 308) throw new PluginCatalogTreeLinkError(`Refusing tree API redirect ${response.status} (fail-closed, no follow)`);
331
+ if (!response.ok) throw new Error(`HTTP ${response.status} fetching plugin catalog Hugging Face tree`);
332
332
  const payload = await response.json();
333
333
  for (const entry of payload) {
334
334
  if (entry.type !== "file" || !entry.path) continue;
@@ -338,28 +338,28 @@ async function fetchScryptedRemoteTree(opts) {
338
338
  ...entry.lfs !== void 0 ? { lfs: entry.lfs } : {}
339
339
  });
340
340
  }
341
- url = resolveScryptedTreeNextLink(response.headers.get("link") ?? "", url, revision);
341
+ url = resolvePluginCatalogTreeNextLink(response.headers.get("link") ?? "", url, revision);
342
342
  }
343
343
  return files;
344
344
  } catch (err) {
345
- if (err instanceof ScryptedTreeLinkError) throw err;
345
+ if (err instanceof PluginCatalogTreeLinkError) throw err;
346
346
  lastError = err instanceof Error ? err : new Error(String(err));
347
347
  await sleep(Math.min(retryDelayMs * 2 ** attempt, 3e3));
348
348
  }
349
- throw new Error(`Scrypted Hugging Face tree unavailable: ${lastError.message}`);
349
+ throw new Error(`plugin catalog Hugging Face tree unavailable: ${lastError.message}`);
350
350
  }
351
351
  //#endregion
352
- //#region src/scrypted/scrypted-import.ts
352
+ //#region src/plugin-catalog/plugin-catalog-import.ts
353
353
  /**
354
354
  * Library registration descriptor: keeps manifesto remote URLs (HF resolve).
355
355
  * Files land on a node only via Distribute / downloadModel — not hub staging.
356
356
  */
357
- function buildScryptedRegistryDescriptor(entry) {
357
+ function buildPluginCatalogRegistryDescriptor(entry) {
358
358
  return {
359
359
  stepId: "object-detection",
360
360
  entry: {
361
361
  ...entry.model,
362
- classMap: SCRYPTED_IDENTITY_CLASS_MAP,
362
+ classMap: PLUGIN_CATALOG_IDENTITY_CLASS_MAP,
363
363
  formats: { ...entry.model.formats },
364
364
  name: entry.model.name,
365
365
  description: entry.model.description,
@@ -368,7 +368,7 @@ function buildScryptedRegistryDescriptor(entry) {
368
368
  };
369
369
  }
370
370
  //#endregion
371
- //#region ../types/dist/event-category-Ceif8n-v.mjs
371
+ //#region ../types/dist/event-category-DHXxB8t9.mjs
372
372
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
373
373
  EventCategory["SystemBoot"] = "system.boot";
374
374
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -664,7 +664,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
664
664
  * TRANSITION into that state (never per dispatch), and the node is dropped
665
665
  * from the placement candidate set for as long as it holds.
666
666
  *
667
- * This exists because the state was previously invisible: little-unraid
667
+ * This exists because the state was previously invisible: agent-a
668
668
  * absorbed 283k inference errors in a day while still being handed cameras,
669
669
  * and nothing in the system said so.
670
670
  *
@@ -5803,7 +5803,7 @@ var ZodIssueCode = {
5803
5803
  var ZodFirstPartyTypeKind;
5804
5804
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5805
5805
  //#endregion
5806
- //#region ../types/dist/sleep-CYfIZzGv.mjs
5806
+ //#region ../types/dist/sleep-BErAxhul.mjs
5807
5807
  /**
5808
5808
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5809
5809
  * window to float samples (D455).
@@ -8836,6 +8836,1980 @@ method(object({ deviceId: number() }), array(StreamSourceEntrySchema)), method(o
8836
8836
  kind: "mutation",
8837
8837
  auth: "admin"
8838
8838
  }), method(object({ deviceId: number() }), unknown().nullable()), method(object({ deviceId: number() }), RawStateResultSchema.nullable(), { auth: "protected" });
8839
+ Object.freeze({ "doorbell": "lastPressedAt" });
8840
+ /** Every capability name, so addon code can check a name without the schema graph. */
8841
+ var CAP_NAMES = Object.freeze([
8842
+ "accessories",
8843
+ "addon-pages",
8844
+ "addon-pages-source",
8845
+ "addon-routes",
8846
+ "addon-settings",
8847
+ "addon-widgets",
8848
+ "addon-widgets-source",
8849
+ "addons",
8850
+ "admin-ui",
8851
+ "air-quality-sensor",
8852
+ "alarm-panel",
8853
+ "alerts",
8854
+ "ambient-light-sensor",
8855
+ "audio-analysis",
8856
+ "audio-analyzer",
8857
+ "audio-codec",
8858
+ "audio-metrics",
8859
+ "auth-provider",
8860
+ "automation-control",
8861
+ "backup",
8862
+ "battery",
8863
+ "binary",
8864
+ "brightness",
8865
+ "broker",
8866
+ "button",
8867
+ "calendar-source",
8868
+ "calendars",
8869
+ "camera-credentials",
8870
+ "camera-grid-layout",
8871
+ "camera-pipeline-config",
8872
+ "camera-streams",
8873
+ "carbon-monoxide",
8874
+ "climate-control",
8875
+ "color",
8876
+ "composer",
8877
+ "connection-test",
8878
+ "connectivity",
8879
+ "consumables",
8880
+ "contact",
8881
+ "control",
8882
+ "core-blocks",
8883
+ "cover",
8884
+ "custom-model-registry",
8885
+ "data-store-provider",
8886
+ "database-snapshot",
8887
+ "day-night",
8888
+ "decoder",
8889
+ "detection-pipeline",
8890
+ "device-admin-link",
8891
+ "device-adoption",
8892
+ "device-credentials",
8893
+ "device-discovery",
8894
+ "device-export",
8895
+ "device-extension",
8896
+ "device-history",
8897
+ "device-manager",
8898
+ "device-ops",
8899
+ "device-provider",
8900
+ "device-removal-hook",
8901
+ "device-state",
8902
+ "device-status",
8903
+ "dishwasher",
8904
+ "display-palette",
8905
+ "doorbell",
8906
+ "embedding-encoder",
8907
+ "enum-sensor",
8908
+ "event-emitter",
8909
+ "face-gallery",
8910
+ "failure-contribution",
8911
+ "fan-control",
8912
+ "feature-probe",
8913
+ "filesystem-browse",
8914
+ "flood",
8915
+ "gas",
8916
+ "heating-valve",
8917
+ "humidifier",
8918
+ "humidity-sensor",
8919
+ "image",
8920
+ "image-settings",
8921
+ "integrations",
8922
+ "intercom",
8923
+ "keychain",
8924
+ "keychain-admin",
8925
+ "lawn-mower-control",
8926
+ "llm",
8927
+ "llm-runtime",
8928
+ "load-contribution",
8929
+ "local-network",
8930
+ "lock-control",
8931
+ "log-channels",
8932
+ "log-destination",
8933
+ "login-method",
8934
+ "media-player",
8935
+ "mesh-network",
8936
+ "metrics-provider",
8937
+ "model-convert",
8938
+ "model-distributor",
8939
+ "motion",
8940
+ "motion-detection",
8941
+ "motion-trigger",
8942
+ "motion-zones",
8943
+ "mqtt-broker",
8944
+ "native-object-detection",
8945
+ "navigation",
8946
+ "network-access",
8947
+ "network-link",
8948
+ "network-quality",
8949
+ "node-certificates",
8950
+ "nodes",
8951
+ "notification-output",
8952
+ "notification-rules",
8953
+ "notifier",
8954
+ "numeric-sensor",
8955
+ "oauth-integration",
8956
+ "oidc-connections",
8957
+ "osd",
8958
+ "osd-manager",
8959
+ "pet-feeder",
8960
+ "pipeline-analytics",
8961
+ "pipeline-executor",
8962
+ "pipeline-orchestrator",
8963
+ "pipeline-runner",
8964
+ "plate-gallery",
8965
+ "platform-probe",
8966
+ "power-meter",
8967
+ "presence",
8968
+ "pressure-sensor",
8969
+ "privacy-mask",
8970
+ "ptz",
8971
+ "ptz-autotrack",
8972
+ "reboot",
8973
+ "record-entries",
8974
+ "recording",
8975
+ "recording-archive",
8976
+ "recording-export",
8977
+ "recording-onboard",
8978
+ "recording-signal",
8979
+ "records",
8980
+ "running-state",
8981
+ "scene-monitor",
8982
+ "script-runner",
8983
+ "server-management",
8984
+ "settings-store",
8985
+ "smoke",
8986
+ "smtp-provider",
8987
+ "snapshot",
8988
+ "sso-bridge",
8989
+ "storage",
8990
+ "storage-admin",
8991
+ "storage-evictable",
8992
+ "storage-migration",
8993
+ "storage-occupancy",
8994
+ "storage-provider",
8995
+ "stream-broker",
8996
+ "stream-catalog",
8997
+ "stream-params",
8998
+ "stream-signals",
8999
+ "switch",
9000
+ "system",
9001
+ "tamper",
9002
+ "temperature-sensor",
9003
+ "terminal-session",
9004
+ "toast",
9005
+ "training",
9006
+ "training-provider",
9007
+ "turn-provider",
9008
+ "update",
9009
+ "user-management",
9010
+ "user-passkeys",
9011
+ "vacuum-control",
9012
+ "valve",
9013
+ "vector-store",
9014
+ "vibration",
9015
+ "videoclips",
9016
+ "viewer-ui",
9017
+ "water-heater",
9018
+ "weather",
9019
+ "webrtc-session",
9020
+ "zone-analytics",
9021
+ "zone-rules",
9022
+ "zones"
9023
+ ]);
9024
+ Object.freeze({
9025
+ "air-quality-sensor": [
9026
+ {
9027
+ "path": "co2Ppm",
9028
+ "valueType": "number"
9029
+ },
9030
+ {
9031
+ "path": "vocPpb",
9032
+ "valueType": "number"
9033
+ },
9034
+ {
9035
+ "path": "pm25",
9036
+ "valueType": "number"
9037
+ },
9038
+ {
9039
+ "path": "pm10",
9040
+ "valueType": "number"
9041
+ },
9042
+ {
9043
+ "path": "aqi",
9044
+ "valueType": "number"
9045
+ },
9046
+ {
9047
+ "path": "unit",
9048
+ "valueType": "string"
9049
+ },
9050
+ {
9051
+ "path": "precision",
9052
+ "valueType": "number"
9053
+ }
9054
+ ],
9055
+ "alarm-panel": [
9056
+ {
9057
+ "path": "state",
9058
+ "valueType": "enum",
9059
+ "enumValues": [
9060
+ "disarmed",
9061
+ "armed_home",
9062
+ "armed_away",
9063
+ "armed_night",
9064
+ "armed_vacation",
9065
+ "armed_custom_bypass",
9066
+ "arming",
9067
+ "disarming",
9068
+ "pending",
9069
+ "triggered"
9070
+ ]
9071
+ },
9072
+ {
9073
+ "path": "targetMode",
9074
+ "valueType": "enum",
9075
+ "enumValues": [
9076
+ "home",
9077
+ "away",
9078
+ "night",
9079
+ "vacation",
9080
+ "custom_bypass"
9081
+ ]
9082
+ },
9083
+ {
9084
+ "path": "requiresCode",
9085
+ "valueType": "boolean"
9086
+ }
9087
+ ],
9088
+ "ambient-light-sensor": [
9089
+ {
9090
+ "path": "lux",
9091
+ "valueType": "number"
9092
+ },
9093
+ {
9094
+ "path": "unit",
9095
+ "valueType": "string"
9096
+ },
9097
+ {
9098
+ "path": "precision",
9099
+ "valueType": "number"
9100
+ }
9101
+ ],
9102
+ "audio-metrics": [
9103
+ {
9104
+ "path": "ts",
9105
+ "valueType": "number"
9106
+ },
9107
+ {
9108
+ "path": "windowSec",
9109
+ "valueType": "number"
9110
+ },
9111
+ {
9112
+ "path": "level.rms",
9113
+ "valueType": "number"
9114
+ },
9115
+ {
9116
+ "path": "level.dbfs",
9117
+ "valueType": "number"
9118
+ },
9119
+ {
9120
+ "path": "peakDbfs",
9121
+ "valueType": "number"
9122
+ },
9123
+ {
9124
+ "path": "avgDbfs",
9125
+ "valueType": "number"
9126
+ },
9127
+ {
9128
+ "path": "current.className",
9129
+ "valueType": "string"
9130
+ },
9131
+ {
9132
+ "path": "current.score",
9133
+ "valueType": "number"
9134
+ },
9135
+ {
9136
+ "path": "current.timestamp",
9137
+ "valueType": "number"
9138
+ }
9139
+ ],
9140
+ "automation-control": [
9141
+ {
9142
+ "path": "enabled",
9143
+ "valueType": "boolean"
9144
+ },
9145
+ {
9146
+ "path": "isRunning",
9147
+ "valueType": "boolean"
9148
+ },
9149
+ {
9150
+ "path": "lastTriggeredAt",
9151
+ "valueType": "number"
9152
+ },
9153
+ {
9154
+ "path": "lastError",
9155
+ "valueType": "string"
9156
+ }
9157
+ ],
9158
+ "battery": [
9159
+ {
9160
+ "path": "percentage",
9161
+ "valueType": "number"
9162
+ },
9163
+ {
9164
+ "path": "charging",
9165
+ "valueType": "enum",
9166
+ "enumValues": [
9167
+ "dc",
9168
+ "solar",
9169
+ "none",
9170
+ "unknown"
9171
+ ]
9172
+ },
9173
+ {
9174
+ "path": "sleeping",
9175
+ "valueType": "boolean"
9176
+ },
9177
+ {
9178
+ "path": "lastUpdated",
9179
+ "valueType": "number"
9180
+ },
9181
+ {
9182
+ "path": "lastContactAt",
9183
+ "valueType": "number"
9184
+ },
9185
+ {
9186
+ "path": "lastFullRefreshAt",
9187
+ "valueType": "number"
9188
+ },
9189
+ {
9190
+ "path": "binary",
9191
+ "valueType": "boolean"
9192
+ }
9193
+ ],
9194
+ "binary": [{
9195
+ "path": "on",
9196
+ "valueType": "boolean"
9197
+ }],
9198
+ "brightness": [{
9199
+ "path": "percentage",
9200
+ "valueType": "number"
9201
+ }],
9202
+ "broker": [{
9203
+ "path": "brokerCount",
9204
+ "valueType": "number"
9205
+ }, {
9206
+ "path": "connectedCount",
9207
+ "valueType": "number"
9208
+ }],
9209
+ "camera-credentials": [
9210
+ {
9211
+ "path": "host",
9212
+ "valueType": "string"
9213
+ },
9214
+ {
9215
+ "path": "port",
9216
+ "valueType": "number"
9217
+ },
9218
+ {
9219
+ "path": "onvifPort",
9220
+ "valueType": "number"
9221
+ },
9222
+ {
9223
+ "path": "rtspPort",
9224
+ "valueType": "number"
9225
+ },
9226
+ {
9227
+ "path": "https",
9228
+ "valueType": "boolean"
9229
+ },
9230
+ {
9231
+ "path": "hasUsername",
9232
+ "valueType": "boolean"
9233
+ },
9234
+ {
9235
+ "path": "hasPassword",
9236
+ "valueType": "boolean"
9237
+ },
9238
+ {
9239
+ "path": "onvifProfile",
9240
+ "valueType": "string"
9241
+ }
9242
+ ],
9243
+ "camera-streams": [
9244
+ {
9245
+ "path": "online",
9246
+ "valueType": "boolean"
9247
+ },
9248
+ {
9249
+ "path": "slotStatuses.high",
9250
+ "valueType": "enum",
9251
+ "enumValues": [
9252
+ "unassigned",
9253
+ "idle",
9254
+ "connecting",
9255
+ "streaming",
9256
+ "error"
9257
+ ]
9258
+ },
9259
+ {
9260
+ "path": "slotStatuses.mid",
9261
+ "valueType": "enum",
9262
+ "enumValues": [
9263
+ "unassigned",
9264
+ "idle",
9265
+ "connecting",
9266
+ "streaming",
9267
+ "error"
9268
+ ]
9269
+ },
9270
+ {
9271
+ "path": "slotStatuses.low",
9272
+ "valueType": "enum",
9273
+ "enumValues": [
9274
+ "unassigned",
9275
+ "idle",
9276
+ "connecting",
9277
+ "streaming",
9278
+ "error"
9279
+ ]
9280
+ },
9281
+ {
9282
+ "path": "slotErrors.high",
9283
+ "valueType": "string"
9284
+ },
9285
+ {
9286
+ "path": "slotErrors.mid",
9287
+ "valueType": "string"
9288
+ },
9289
+ {
9290
+ "path": "slotErrors.low",
9291
+ "valueType": "string"
9292
+ }
9293
+ ],
9294
+ "carbon-monoxide": [{
9295
+ "path": "detected",
9296
+ "valueType": "boolean"
9297
+ }],
9298
+ "climate-control": [
9299
+ {
9300
+ "path": "mode",
9301
+ "valueType": "enum",
9302
+ "enumValues": [
9303
+ "off",
9304
+ "heat",
9305
+ "cool",
9306
+ "auto",
9307
+ "heat_cool",
9308
+ "fan_only",
9309
+ "dry"
9310
+ ]
9311
+ },
9312
+ {
9313
+ "path": "fanMode",
9314
+ "valueType": "string"
9315
+ },
9316
+ {
9317
+ "path": "preset",
9318
+ "valueType": "string"
9319
+ },
9320
+ {
9321
+ "path": "target",
9322
+ "valueType": "number"
9323
+ },
9324
+ {
9325
+ "path": "targetHigh",
9326
+ "valueType": "number"
9327
+ },
9328
+ {
9329
+ "path": "targetLow",
9330
+ "valueType": "number"
9331
+ },
9332
+ {
9333
+ "path": "targetHumidity",
9334
+ "valueType": "number"
9335
+ },
9336
+ {
9337
+ "path": "currentTemp",
9338
+ "valueType": "number"
9339
+ },
9340
+ {
9341
+ "path": "currentHumidity",
9342
+ "valueType": "number"
9343
+ },
9344
+ {
9345
+ "path": "swingVertical",
9346
+ "valueType": "boolean"
9347
+ },
9348
+ {
9349
+ "path": "swingHorizontal",
9350
+ "valueType": "boolean"
9351
+ },
9352
+ {
9353
+ "path": "minTemp",
9354
+ "valueType": "number"
9355
+ },
9356
+ {
9357
+ "path": "maxTemp",
9358
+ "valueType": "number"
9359
+ },
9360
+ {
9361
+ "path": "tempStep",
9362
+ "valueType": "number"
9363
+ }
9364
+ ],
9365
+ "color": [
9366
+ {
9367
+ "path": "mode",
9368
+ "valueType": "enum",
9369
+ "enumValues": [
9370
+ "rgb",
9371
+ "hsv",
9372
+ "mired"
9373
+ ]
9374
+ },
9375
+ {
9376
+ "path": "rgb.r",
9377
+ "valueType": "number"
9378
+ },
9379
+ {
9380
+ "path": "rgb.g",
9381
+ "valueType": "number"
9382
+ },
9383
+ {
9384
+ "path": "rgb.b",
9385
+ "valueType": "number"
9386
+ },
9387
+ {
9388
+ "path": "hsv.h",
9389
+ "valueType": "number"
9390
+ },
9391
+ {
9392
+ "path": "hsv.s",
9393
+ "valueType": "number"
9394
+ },
9395
+ {
9396
+ "path": "hsv.v",
9397
+ "valueType": "number"
9398
+ },
9399
+ {
9400
+ "path": "mireds",
9401
+ "valueType": "number"
9402
+ }
9403
+ ],
9404
+ "connectivity": [{
9405
+ "path": "connected",
9406
+ "valueType": "boolean"
9407
+ }],
9408
+ "contact": [{
9409
+ "path": "entryOpen",
9410
+ "valueType": "boolean"
9411
+ }],
9412
+ "control": [
9413
+ {
9414
+ "path": "kind",
9415
+ "valueType": "enum",
9416
+ "enumValues": [
9417
+ "numeric",
9418
+ "select",
9419
+ "text",
9420
+ "datetime"
9421
+ ]
9422
+ },
9423
+ {
9424
+ "path": "unit",
9425
+ "valueType": "string"
9426
+ },
9427
+ {
9428
+ "path": "min",
9429
+ "valueType": "number"
9430
+ },
9431
+ {
9432
+ "path": "max",
9433
+ "valueType": "number"
9434
+ },
9435
+ {
9436
+ "path": "step",
9437
+ "valueType": "number"
9438
+ },
9439
+ {
9440
+ "path": "precision",
9441
+ "valueType": "number"
9442
+ },
9443
+ {
9444
+ "path": "format",
9445
+ "valueType": "enum",
9446
+ "enumValues": [
9447
+ "date",
9448
+ "time",
9449
+ "datetime"
9450
+ ]
9451
+ }
9452
+ ],
9453
+ "cover": [
9454
+ {
9455
+ "path": "state",
9456
+ "valueType": "enum",
9457
+ "enumValues": [
9458
+ "open",
9459
+ "opening",
9460
+ "closing",
9461
+ "closed",
9462
+ "stopped"
9463
+ ]
9464
+ },
9465
+ {
9466
+ "path": "position",
9467
+ "valueType": "number"
9468
+ },
9469
+ {
9470
+ "path": "tiltPosition",
9471
+ "valueType": "number"
9472
+ }
9473
+ ],
9474
+ "day-night": [
9475
+ {
9476
+ "path": "mode",
9477
+ "valueType": "enum",
9478
+ "enumValues": [
9479
+ "auto",
9480
+ "day",
9481
+ "night",
9482
+ "schedule"
9483
+ ]
9484
+ },
9485
+ {
9486
+ "path": "sensitivity",
9487
+ "valueType": "number"
9488
+ },
9489
+ {
9490
+ "path": "switchDelaySec",
9491
+ "valueType": "number"
9492
+ }
9493
+ ],
9494
+ "device-adoption": [
9495
+ {
9496
+ "path": "lastDiscoveryAt",
9497
+ "valueType": "number"
9498
+ },
9499
+ {
9500
+ "path": "candidateCount",
9501
+ "valueType": "number"
9502
+ },
9503
+ {
9504
+ "path": "adoptedCount",
9505
+ "valueType": "number"
9506
+ },
9507
+ {
9508
+ "path": "lastError",
9509
+ "valueType": "string"
9510
+ }
9511
+ ],
9512
+ "device-discovery": [{
9513
+ "path": "lastDiscoveryAt",
9514
+ "valueType": "number"
9515
+ }, {
9516
+ "path": "lastError",
9517
+ "valueType": "string"
9518
+ }],
9519
+ "device-export": [
9520
+ {
9521
+ "path": "linkState",
9522
+ "valueType": "enum",
9523
+ "enumValues": [
9524
+ "unlinked",
9525
+ "linked",
9526
+ "error"
9527
+ ]
9528
+ },
9529
+ {
9530
+ "path": "exposedDeviceCount",
9531
+ "valueType": "number"
9532
+ },
9533
+ {
9534
+ "path": "error",
9535
+ "valueType": "string"
9536
+ },
9537
+ {
9538
+ "path": "setup.qr",
9539
+ "valueType": "string"
9540
+ },
9541
+ {
9542
+ "path": "setup.note",
9543
+ "valueType": "string"
9544
+ }
9545
+ ],
9546
+ "device-status": [{
9547
+ "path": "online",
9548
+ "valueType": "boolean"
9549
+ }],
9550
+ "dishwasher": [
9551
+ {
9552
+ "path": "availability",
9553
+ "valueType": "enum",
9554
+ "enumValues": [
9555
+ "available",
9556
+ "offline",
9557
+ "description-missing"
9558
+ ]
9559
+ },
9560
+ {
9561
+ "path": "state",
9562
+ "valueType": "enum",
9563
+ "enumValues": [
9564
+ "idle",
9565
+ "running",
9566
+ "paused",
9567
+ "finished",
9568
+ "error",
9569
+ "unavailable"
9570
+ ]
9571
+ },
9572
+ {
9573
+ "path": "operationState",
9574
+ "valueType": "enum",
9575
+ "enumValues": [
9576
+ "Inactive",
9577
+ "Ready",
9578
+ "DelayedStart",
9579
+ "Run",
9580
+ "Pause",
9581
+ "ActionRequired",
9582
+ "Finished",
9583
+ "Error",
9584
+ "Aborting"
9585
+ ]
9586
+ },
9587
+ {
9588
+ "path": "program",
9589
+ "valueType": "string"
9590
+ },
9591
+ {
9592
+ "path": "selectedProgram",
9593
+ "valueType": "string"
9594
+ },
9595
+ {
9596
+ "path": "remainingSeconds",
9597
+ "valueType": "number"
9598
+ },
9599
+ {
9600
+ "path": "delayedStartSeconds",
9601
+ "valueType": "number"
9602
+ },
9603
+ {
9604
+ "path": "progressPercent",
9605
+ "valueType": "number"
9606
+ },
9607
+ {
9608
+ "path": "doorOpen",
9609
+ "valueType": "boolean"
9610
+ },
9611
+ {
9612
+ "path": "doorLocked",
9613
+ "valueType": "boolean"
9614
+ },
9615
+ {
9616
+ "path": "remoteStartAllowed",
9617
+ "valueType": "boolean"
9618
+ },
9619
+ {
9620
+ "path": "remoteControlActive",
9621
+ "valueType": "boolean"
9622
+ },
9623
+ {
9624
+ "path": "localControlActive",
9625
+ "valueType": "boolean"
9626
+ },
9627
+ {
9628
+ "path": "powerOn",
9629
+ "valueType": "boolean"
9630
+ },
9631
+ {
9632
+ "path": "powerState",
9633
+ "valueType": "string"
9634
+ },
9635
+ {
9636
+ "path": "filterCleaningDue",
9637
+ "valueType": "boolean"
9638
+ },
9639
+ {
9640
+ "path": "machineCareDue",
9641
+ "valueType": "boolean"
9642
+ },
9643
+ {
9644
+ "path": "machineCareRemainingRuns",
9645
+ "valueType": "number"
9646
+ },
9647
+ {
9648
+ "path": "halfLoad",
9649
+ "valueType": "boolean"
9650
+ },
9651
+ {
9652
+ "path": "hygienePlus",
9653
+ "valueType": "boolean"
9654
+ },
9655
+ {
9656
+ "path": "extraDry",
9657
+ "valueType": "boolean"
9658
+ },
9659
+ {
9660
+ "path": "intensiveZone",
9661
+ "valueType": "boolean"
9662
+ },
9663
+ {
9664
+ "path": "varioSpeedPlus",
9665
+ "valueType": "boolean"
9666
+ },
9667
+ {
9668
+ "path": "childLock",
9669
+ "valueType": "boolean"
9670
+ },
9671
+ {
9672
+ "path": "errorCode",
9673
+ "valueType": "number"
9674
+ },
9675
+ {
9676
+ "path": "errorLabel",
9677
+ "valueType": "string"
9678
+ }
9679
+ ],
9680
+ "doorbell": [{
9681
+ "path": "lastPressedAt",
9682
+ "valueType": "number"
9683
+ }, {
9684
+ "path": "pressCountSinceStart",
9685
+ "valueType": "number"
9686
+ }],
9687
+ "enum-sensor": [{
9688
+ "path": "value",
9689
+ "valueType": "string"
9690
+ }, {
9691
+ "path": "format",
9692
+ "valueType": "enum",
9693
+ "enumValues": [
9694
+ "date",
9695
+ "time",
9696
+ "datetime"
9697
+ ]
9698
+ }],
9699
+ "event-emitter": [
9700
+ {
9701
+ "path": "lastEvent.deviceId",
9702
+ "valueType": "number"
9703
+ },
9704
+ {
9705
+ "path": "lastEvent.eventType",
9706
+ "valueType": "string"
9707
+ },
9708
+ {
9709
+ "path": "lastEvent.timestamp",
9710
+ "valueType": "number"
9711
+ },
9712
+ {
9713
+ "path": "lastEvent.seq",
9714
+ "valueType": "number"
9715
+ },
9716
+ {
9717
+ "path": "eventCountSinceStart",
9718
+ "valueType": "number"
9719
+ }
9720
+ ],
9721
+ "fan-control": [
9722
+ {
9723
+ "path": "percentage",
9724
+ "valueType": "number"
9725
+ },
9726
+ {
9727
+ "path": "percentageStep",
9728
+ "valueType": "number"
9729
+ },
9730
+ {
9731
+ "path": "preset",
9732
+ "valueType": "string"
9733
+ },
9734
+ {
9735
+ "path": "direction",
9736
+ "valueType": "enum",
9737
+ "enumValues": ["forward", "reverse"]
9738
+ },
9739
+ {
9740
+ "path": "oscillating",
9741
+ "valueType": "boolean"
9742
+ }
9743
+ ],
9744
+ "feature-probe": [
9745
+ {
9746
+ "path": "deviceType",
9747
+ "valueType": "string"
9748
+ },
9749
+ {
9750
+ "path": "model",
9751
+ "valueType": "string"
9752
+ },
9753
+ {
9754
+ "path": "channelCount",
9755
+ "valueType": "number"
9756
+ },
9757
+ {
9758
+ "path": "lastProbedAt",
9759
+ "valueType": "number"
9760
+ }
9761
+ ],
9762
+ "flood": [{
9763
+ "path": "flooded",
9764
+ "valueType": "boolean"
9765
+ }],
9766
+ "gas": [{
9767
+ "path": "detected",
9768
+ "valueType": "boolean"
9769
+ }],
9770
+ "heating-valve": [{
9771
+ "path": "position",
9772
+ "valueType": "number"
9773
+ }],
9774
+ "humidifier": [
9775
+ {
9776
+ "path": "on",
9777
+ "valueType": "boolean"
9778
+ },
9779
+ {
9780
+ "path": "currentHumidity",
9781
+ "valueType": "number"
9782
+ },
9783
+ {
9784
+ "path": "targetHumidity",
9785
+ "valueType": "number"
9786
+ },
9787
+ {
9788
+ "path": "mode",
9789
+ "valueType": "string"
9790
+ },
9791
+ {
9792
+ "path": "action",
9793
+ "valueType": "string"
9794
+ },
9795
+ {
9796
+ "path": "minHumidity",
9797
+ "valueType": "number"
9798
+ },
9799
+ {
9800
+ "path": "maxHumidity",
9801
+ "valueType": "number"
9802
+ }
9803
+ ],
9804
+ "humidity-sensor": [
9805
+ {
9806
+ "path": "percent",
9807
+ "valueType": "number"
9808
+ },
9809
+ {
9810
+ "path": "unit",
9811
+ "valueType": "string"
9812
+ },
9813
+ {
9814
+ "path": "precision",
9815
+ "valueType": "number"
9816
+ }
9817
+ ],
9818
+ "image": [{
9819
+ "path": "url",
9820
+ "valueType": "string"
9821
+ }, {
9822
+ "path": "lastUpdated",
9823
+ "valueType": "number"
9824
+ }],
9825
+ "image-settings": [
9826
+ {
9827
+ "path": "brightness",
9828
+ "valueType": "number"
9829
+ },
9830
+ {
9831
+ "path": "contrast",
9832
+ "valueType": "number"
9833
+ },
9834
+ {
9835
+ "path": "saturation",
9836
+ "valueType": "number"
9837
+ },
9838
+ {
9839
+ "path": "sharpness",
9840
+ "valueType": "number"
9841
+ },
9842
+ {
9843
+ "path": "mirror",
9844
+ "valueType": "boolean"
9845
+ },
9846
+ {
9847
+ "path": "flip",
9848
+ "valueType": "boolean"
9849
+ },
9850
+ {
9851
+ "path": "rotate",
9852
+ "valueType": "enum",
9853
+ "enumValues": [
9854
+ "0",
9855
+ "90",
9856
+ "180",
9857
+ "270"
9858
+ ]
9859
+ },
9860
+ {
9861
+ "path": "whiteBalance",
9862
+ "valueType": "enum",
9863
+ "enumValues": ["auto", "manual"]
9864
+ },
9865
+ {
9866
+ "path": "warmth",
9867
+ "valueType": "number"
9868
+ },
9869
+ {
9870
+ "path": "exposureMode",
9871
+ "valueType": "enum",
9872
+ "enumValues": ["auto", "manual"]
9873
+ },
9874
+ {
9875
+ "path": "backlightMode",
9876
+ "valueType": "enum",
9877
+ "enumValues": [
9878
+ "off",
9879
+ "blc",
9880
+ "wdr",
9881
+ "hlc"
9882
+ ]
9883
+ }
9884
+ ],
9885
+ "intercom": [
9886
+ {
9887
+ "path": "talking",
9888
+ "valueType": "boolean"
9889
+ },
9890
+ {
9891
+ "path": "lastSessionAt",
9892
+ "valueType": "number"
9893
+ },
9894
+ {
9895
+ "path": "ability.sampleRate",
9896
+ "valueType": "number"
9897
+ },
9898
+ {
9899
+ "path": "ability.duplex",
9900
+ "valueType": "enum",
9901
+ "enumValues": ["half", "full"]
9902
+ },
9903
+ {
9904
+ "path": "ability.maxBacklogMs",
9905
+ "valueType": "number"
9906
+ }
9907
+ ],
9908
+ "lawn-mower-control": [
9909
+ {
9910
+ "path": "activity",
9911
+ "valueType": "enum",
9912
+ "enumValues": [
9913
+ "idle",
9914
+ "mowing",
9915
+ "paused",
9916
+ "docked",
9917
+ "error"
9918
+ ]
9919
+ },
9920
+ {
9921
+ "path": "batteryLevel",
9922
+ "valueType": "number"
9923
+ },
9924
+ {
9925
+ "path": "progressPercent",
9926
+ "valueType": "number"
9927
+ },
9928
+ {
9929
+ "path": "currentCode",
9930
+ "valueType": "number"
9931
+ },
9932
+ {
9933
+ "path": "currentCodeLabel",
9934
+ "valueType": "string"
9935
+ },
9936
+ {
9937
+ "path": "severity",
9938
+ "valueType": "enum",
9939
+ "enumValues": [
9940
+ "info",
9941
+ "warning",
9942
+ "error"
9943
+ ]
9944
+ }
9945
+ ],
9946
+ "lock-control": [{
9947
+ "path": "state",
9948
+ "valueType": "enum",
9949
+ "enumValues": [
9950
+ "locked",
9951
+ "unlocked",
9952
+ "locking",
9953
+ "unlocking",
9954
+ "jammed"
9955
+ ]
9956
+ }],
9957
+ "media-player": [
9958
+ {
9959
+ "path": "state",
9960
+ "valueType": "enum",
9961
+ "enumValues": [
9962
+ "off",
9963
+ "on",
9964
+ "idle",
9965
+ "playing",
9966
+ "paused",
9967
+ "buffering",
9968
+ "standby"
9969
+ ]
9970
+ },
9971
+ {
9972
+ "path": "volumeLevel",
9973
+ "valueType": "number"
9974
+ },
9975
+ {
9976
+ "path": "isMuted",
9977
+ "valueType": "boolean"
9978
+ },
9979
+ {
9980
+ "path": "source",
9981
+ "valueType": "string"
9982
+ },
9983
+ {
9984
+ "path": "currentMedia.type",
9985
+ "valueType": "string"
9986
+ },
9987
+ {
9988
+ "path": "currentMedia.title",
9989
+ "valueType": "string"
9990
+ },
9991
+ {
9992
+ "path": "currentMedia.artist",
9993
+ "valueType": "string"
9994
+ },
9995
+ {
9996
+ "path": "currentMedia.album",
9997
+ "valueType": "string"
9998
+ },
9999
+ {
10000
+ "path": "currentMedia.imageUrl",
10001
+ "valueType": "string"
10002
+ },
10003
+ {
10004
+ "path": "positionMs",
10005
+ "valueType": "number"
10006
+ },
10007
+ {
10008
+ "path": "durationMs",
10009
+ "valueType": "number"
10010
+ },
10011
+ {
10012
+ "path": "shuffle",
10013
+ "valueType": "boolean"
10014
+ },
10015
+ {
10016
+ "path": "repeat",
10017
+ "valueType": "enum",
10018
+ "enumValues": [
10019
+ "off",
10020
+ "all",
10021
+ "one"
10022
+ ]
10023
+ }
10024
+ ],
10025
+ "motion": [
10026
+ {
10027
+ "path": "detected",
10028
+ "valueType": "boolean"
10029
+ },
10030
+ {
10031
+ "path": "lastDetectedAt",
10032
+ "valueType": "number"
10033
+ },
10034
+ {
10035
+ "path": "autoClearAfterMs",
10036
+ "valueType": "number"
10037
+ }
10038
+ ],
10039
+ "motion-trigger": [{
10040
+ "path": "enabled",
10041
+ "valueType": "boolean"
10042
+ }],
10043
+ "motion-zones": [{
10044
+ "path": "enabled",
10045
+ "valueType": "boolean"
10046
+ }, {
10047
+ "path": "sensitivity",
10048
+ "valueType": "number"
10049
+ }],
10050
+ "mqtt-broker": [{
10051
+ "path": "brokerCount",
10052
+ "valueType": "number"
10053
+ }, {
10054
+ "path": "embeddedRunning",
10055
+ "valueType": "boolean"
10056
+ }],
10057
+ "native-object-detection": [{
10058
+ "path": "enabled",
10059
+ "valueType": "boolean"
10060
+ }],
10061
+ "navigation": [
10062
+ {
10063
+ "path": "mode",
10064
+ "valueType": "enum",
10065
+ "enumValues": [
10066
+ "idle",
10067
+ "cleaning",
10068
+ "spot",
10069
+ "following",
10070
+ "goto",
10071
+ "returning",
10072
+ "paused",
10073
+ "unknown"
10074
+ ]
10075
+ },
10076
+ {
10077
+ "path": "following",
10078
+ "valueType": "boolean"
10079
+ },
10080
+ {
10081
+ "path": "flash",
10082
+ "valueType": "boolean"
10083
+ },
10084
+ {
10085
+ "path": "lightMode",
10086
+ "valueType": "enum",
10087
+ "enumValues": ["auto", "manual"]
10088
+ },
10089
+ {
10090
+ "path": "lightLevel",
10091
+ "valueType": "number"
10092
+ }
10093
+ ],
10094
+ "network-link": [
10095
+ {
10096
+ "path": "type",
10097
+ "valueType": "enum",
10098
+ "enumValues": [
10099
+ "wifi",
10100
+ "ethernet",
10101
+ "cellular",
10102
+ "unknown"
10103
+ ]
10104
+ },
10105
+ {
10106
+ "path": "signalPercent",
10107
+ "valueType": "number"
10108
+ },
10109
+ {
10110
+ "path": "rssiDbm",
10111
+ "valueType": "number"
10112
+ },
10113
+ {
10114
+ "path": "ssid",
10115
+ "valueType": "string"
10116
+ },
10117
+ {
10118
+ "path": "lastUpdated",
10119
+ "valueType": "number"
10120
+ }
10121
+ ],
10122
+ "notifier": [
10123
+ {
10124
+ "path": "lastSentAt",
10125
+ "valueType": "number"
10126
+ },
10127
+ {
10128
+ "path": "lastError",
10129
+ "valueType": "string"
10130
+ },
10131
+ {
10132
+ "path": "queueDepth",
10133
+ "valueType": "number"
10134
+ },
10135
+ {
10136
+ "path": "supports.image",
10137
+ "valueType": "boolean"
10138
+ },
10139
+ {
10140
+ "path": "supports.priority",
10141
+ "valueType": "boolean"
10142
+ },
10143
+ {
10144
+ "path": "supports.data",
10145
+ "valueType": "boolean"
10146
+ },
10147
+ {
10148
+ "path": "supports.actions",
10149
+ "valueType": "boolean"
10150
+ },
10151
+ {
10152
+ "path": "supports.recipients",
10153
+ "valueType": "boolean"
10154
+ }
10155
+ ],
10156
+ "numeric-sensor": [
10157
+ {
10158
+ "path": "value",
10159
+ "valueType": "number"
10160
+ },
10161
+ {
10162
+ "path": "unit",
10163
+ "valueType": "string"
10164
+ },
10165
+ {
10166
+ "path": "precision",
10167
+ "valueType": "number"
10168
+ }
10169
+ ],
10170
+ "pet-feeder": [
10171
+ {
10172
+ "path": "foodLevel",
10173
+ "valueType": "number"
10174
+ },
10175
+ {
10176
+ "path": "food1",
10177
+ "valueType": "number"
10178
+ },
10179
+ {
10180
+ "path": "food2",
10181
+ "valueType": "number"
10182
+ },
10183
+ {
10184
+ "path": "lowFood",
10185
+ "valueType": "boolean"
10186
+ },
10187
+ {
10188
+ "path": "batteryPower",
10189
+ "valueType": "number"
10190
+ },
10191
+ {
10192
+ "path": "desiccantLeftDays",
10193
+ "valueType": "number"
10194
+ },
10195
+ {
10196
+ "path": "feeding",
10197
+ "valueType": "boolean"
10198
+ },
10199
+ {
10200
+ "path": "status",
10201
+ "valueType": "enum",
10202
+ "enumValues": [
10203
+ "normal",
10204
+ "offline",
10205
+ "on_batteries"
10206
+ ]
10207
+ },
10208
+ {
10209
+ "path": "error",
10210
+ "valueType": "string"
10211
+ },
10212
+ {
10213
+ "path": "errorCode",
10214
+ "valueType": "number"
10215
+ },
10216
+ {
10217
+ "path": "isDualHopper",
10218
+ "valueType": "boolean"
10219
+ },
10220
+ {
10221
+ "path": "childLock",
10222
+ "valueType": "boolean"
10223
+ },
10224
+ {
10225
+ "path": "indicatorLight",
10226
+ "valueType": "boolean"
10227
+ },
10228
+ {
10229
+ "path": "feedSound",
10230
+ "valueType": "boolean"
10231
+ },
10232
+ {
10233
+ "path": "volume",
10234
+ "valueType": "number"
10235
+ }
10236
+ ],
10237
+ "power-meter": [
10238
+ {
10239
+ "path": "watts",
10240
+ "valueType": "number"
10241
+ },
10242
+ {
10243
+ "path": "kwhTotal",
10244
+ "valueType": "number"
10245
+ },
10246
+ {
10247
+ "path": "volts",
10248
+ "valueType": "number"
10249
+ },
10250
+ {
10251
+ "path": "amps",
10252
+ "valueType": "number"
10253
+ },
10254
+ {
10255
+ "path": "va",
10256
+ "valueType": "number"
10257
+ },
10258
+ {
10259
+ "path": "powerFactor",
10260
+ "valueType": "number"
10261
+ },
10262
+ {
10263
+ "path": "unit",
10264
+ "valueType": "string"
10265
+ },
10266
+ {
10267
+ "path": "precision",
10268
+ "valueType": "number"
10269
+ }
10270
+ ],
10271
+ "presence": [
10272
+ {
10273
+ "path": "state",
10274
+ "valueType": "string"
10275
+ },
10276
+ {
10277
+ "path": "location",
10278
+ "valueType": "string"
10279
+ },
10280
+ {
10281
+ "path": "gps.latitude",
10282
+ "valueType": "number"
10283
+ },
10284
+ {
10285
+ "path": "gps.longitude",
10286
+ "valueType": "number"
10287
+ },
10288
+ {
10289
+ "path": "gps.accuracyMeters",
10290
+ "valueType": "number"
10291
+ },
10292
+ {
10293
+ "path": "batteryPercent",
10294
+ "valueType": "number"
10295
+ }
10296
+ ],
10297
+ "pressure-sensor": [
10298
+ {
10299
+ "path": "hpa",
10300
+ "valueType": "number"
10301
+ },
10302
+ {
10303
+ "path": "unit",
10304
+ "valueType": "string"
10305
+ },
10306
+ {
10307
+ "path": "precision",
10308
+ "valueType": "number"
10309
+ }
10310
+ ],
10311
+ "privacy-mask": [{
10312
+ "path": "enabled",
10313
+ "valueType": "boolean"
10314
+ }, {
10315
+ "path": "audioEnabled",
10316
+ "valueType": "boolean"
10317
+ }],
10318
+ "ptz": [
10319
+ {
10320
+ "path": "pan",
10321
+ "valueType": "number"
10322
+ },
10323
+ {
10324
+ "path": "tilt",
10325
+ "valueType": "number"
10326
+ },
10327
+ {
10328
+ "path": "zoom",
10329
+ "valueType": "number"
10330
+ },
10331
+ {
10332
+ "path": "autofocus",
10333
+ "valueType": "boolean"
10334
+ }
10335
+ ],
10336
+ "ptz-autotrack": [
10337
+ {
10338
+ "path": "enabled",
10339
+ "valueType": "boolean"
10340
+ },
10341
+ {
10342
+ "path": "currentSettings.targetType",
10343
+ "valueType": "string"
10344
+ },
10345
+ {
10346
+ "path": "currentSettings.stopDelaySeconds",
10347
+ "valueType": "number"
10348
+ },
10349
+ {
10350
+ "path": "currentSettings.disappearDelaySeconds",
10351
+ "valueType": "number"
10352
+ }
10353
+ ],
10354
+ "recording-archive": [
10355
+ {
10356
+ "path": "deviceId",
10357
+ "valueType": "number"
10358
+ },
10359
+ {
10360
+ "path": "enabled",
10361
+ "valueType": "boolean"
10362
+ },
10363
+ {
10364
+ "path": "activeMode",
10365
+ "valueType": "enum",
10366
+ "enumValues": [
10367
+ "off",
10368
+ "events",
10369
+ "continuous",
10370
+ "on-device-decision"
10371
+ ]
10372
+ },
10373
+ {
10374
+ "path": "nodeId",
10375
+ "valueType": "string"
10376
+ },
10377
+ {
10378
+ "path": "storageBytes",
10379
+ "valueType": "number"
10380
+ }
10381
+ ],
10382
+ "recording-onboard": [
10383
+ {
10384
+ "path": "primaryTrackId",
10385
+ "valueType": "string"
10386
+ },
10387
+ {
10388
+ "path": "enabled",
10389
+ "valueType": "boolean"
10390
+ },
10391
+ {
10392
+ "path": "overwriteWhenFull",
10393
+ "valueType": "boolean"
10394
+ },
10395
+ {
10396
+ "path": "preRecordSec",
10397
+ "valueType": "number"
10398
+ },
10399
+ {
10400
+ "path": "postRecordSec",
10401
+ "valueType": "number"
10402
+ },
10403
+ {
10404
+ "path": "segmentMinutes",
10405
+ "valueType": "number"
10406
+ },
10407
+ {
10408
+ "path": "unreadableWindows",
10409
+ "valueType": "number"
10410
+ },
10411
+ {
10412
+ "path": "recordingToNowhere",
10413
+ "valueType": "boolean"
10414
+ }
10415
+ ],
10416
+ "recording-signal": [{
10417
+ "path": "active",
10418
+ "valueType": "boolean"
10419
+ }, {
10420
+ "path": "reason",
10421
+ "valueType": "string"
10422
+ }],
10423
+ "running-state": [
10424
+ {
10425
+ "path": "running",
10426
+ "valueType": "boolean"
10427
+ },
10428
+ {
10429
+ "path": "since",
10430
+ "valueType": "number"
10431
+ },
10432
+ {
10433
+ "path": "source",
10434
+ "valueType": "enum",
10435
+ "enumValues": ["native", "assigned"]
10436
+ },
10437
+ {
10438
+ "path": "phase",
10439
+ "valueType": "string"
10440
+ }
10441
+ ],
10442
+ "script-runner": [
10443
+ {
10444
+ "path": "isRunning",
10445
+ "valueType": "boolean"
10446
+ },
10447
+ {
10448
+ "path": "lastRunAt",
10449
+ "valueType": "number"
10450
+ },
10451
+ {
10452
+ "path": "lastRunSuccess",
10453
+ "valueType": "boolean"
10454
+ },
10455
+ {
10456
+ "path": "lastError",
10457
+ "valueType": "string"
10458
+ }
10459
+ ],
10460
+ "smoke": [{
10461
+ "path": "detected",
10462
+ "valueType": "boolean"
10463
+ }],
10464
+ "snapshot": [
10465
+ {
10466
+ "path": "lastCapturedAt",
10467
+ "valueType": "number"
10468
+ },
10469
+ {
10470
+ "path": "cacheAgeMs",
10471
+ "valueType": "number"
10472
+ },
10473
+ {
10474
+ "path": "lastBytes",
10475
+ "valueType": "number"
10476
+ },
10477
+ {
10478
+ "path": "lastStreamId",
10479
+ "valueType": "string"
10480
+ }
10481
+ ],
10482
+ "stream-params": [
10483
+ {
10484
+ "path": "main.width",
10485
+ "valueType": "number"
10486
+ },
10487
+ {
10488
+ "path": "main.height",
10489
+ "valueType": "number"
10490
+ },
10491
+ {
10492
+ "path": "main.codec",
10493
+ "valueType": "enum",
10494
+ "enumValues": ["h264", "h265"]
10495
+ },
10496
+ {
10497
+ "path": "main.framerate",
10498
+ "valueType": "number"
10499
+ },
10500
+ {
10501
+ "path": "main.bitrate",
10502
+ "valueType": "number"
10503
+ },
10504
+ {
10505
+ "path": "main.bitrateMode",
10506
+ "valueType": "enum",
10507
+ "enumValues": ["vbr", "cbr"]
10508
+ },
10509
+ {
10510
+ "path": "main.encoderProfile",
10511
+ "valueType": "enum",
10512
+ "enumValues": [
10513
+ "high",
10514
+ "main",
10515
+ "baseline"
10516
+ ]
10517
+ },
10518
+ {
10519
+ "path": "main.gop",
10520
+ "valueType": "number"
10521
+ },
10522
+ {
10523
+ "path": "main.audio",
10524
+ "valueType": "boolean"
10525
+ },
10526
+ {
10527
+ "path": "sub.width",
10528
+ "valueType": "number"
10529
+ },
10530
+ {
10531
+ "path": "sub.height",
10532
+ "valueType": "number"
10533
+ },
10534
+ {
10535
+ "path": "sub.codec",
10536
+ "valueType": "enum",
10537
+ "enumValues": ["h264", "h265"]
10538
+ },
10539
+ {
10540
+ "path": "sub.framerate",
10541
+ "valueType": "number"
10542
+ },
10543
+ {
10544
+ "path": "sub.bitrate",
10545
+ "valueType": "number"
10546
+ },
10547
+ {
10548
+ "path": "sub.bitrateMode",
10549
+ "valueType": "enum",
10550
+ "enumValues": ["vbr", "cbr"]
10551
+ },
10552
+ {
10553
+ "path": "sub.encoderProfile",
10554
+ "valueType": "enum",
10555
+ "enumValues": [
10556
+ "high",
10557
+ "main",
10558
+ "baseline"
10559
+ ]
10560
+ },
10561
+ {
10562
+ "path": "sub.gop",
10563
+ "valueType": "number"
10564
+ },
10565
+ {
10566
+ "path": "sub.audio",
10567
+ "valueType": "boolean"
10568
+ },
10569
+ {
10570
+ "path": "ext.width",
10571
+ "valueType": "number"
10572
+ },
10573
+ {
10574
+ "path": "ext.height",
10575
+ "valueType": "number"
10576
+ },
10577
+ {
10578
+ "path": "ext.codec",
10579
+ "valueType": "enum",
10580
+ "enumValues": ["h264", "h265"]
10581
+ },
10582
+ {
10583
+ "path": "ext.framerate",
10584
+ "valueType": "number"
10585
+ },
10586
+ {
10587
+ "path": "ext.bitrate",
10588
+ "valueType": "number"
10589
+ },
10590
+ {
10591
+ "path": "ext.bitrateMode",
10592
+ "valueType": "enum",
10593
+ "enumValues": ["vbr", "cbr"]
10594
+ },
10595
+ {
10596
+ "path": "ext.encoderProfile",
10597
+ "valueType": "enum",
10598
+ "enumValues": [
10599
+ "high",
10600
+ "main",
10601
+ "baseline"
10602
+ ]
10603
+ },
10604
+ {
10605
+ "path": "ext.gop",
10606
+ "valueType": "number"
10607
+ },
10608
+ {
10609
+ "path": "ext.audio",
10610
+ "valueType": "boolean"
10611
+ }
10612
+ ],
10613
+ "switch": [{
10614
+ "path": "on",
10615
+ "valueType": "boolean"
10616
+ }],
10617
+ "tamper": [{
10618
+ "path": "tampered",
10619
+ "valueType": "boolean"
10620
+ }],
10621
+ "temperature-sensor": [
10622
+ {
10623
+ "path": "celsius",
10624
+ "valueType": "number"
10625
+ },
10626
+ {
10627
+ "path": "unit",
10628
+ "valueType": "string"
10629
+ },
10630
+ {
10631
+ "path": "precision",
10632
+ "valueType": "number"
10633
+ }
10634
+ ],
10635
+ "update": [
10636
+ {
10637
+ "path": "currentVersion",
10638
+ "valueType": "string"
10639
+ },
10640
+ {
10641
+ "path": "availableVersion",
10642
+ "valueType": "string"
10643
+ },
10644
+ {
10645
+ "path": "updatable",
10646
+ "valueType": "boolean"
10647
+ },
10648
+ {
10649
+ "path": "state",
10650
+ "valueType": "string"
10651
+ },
10652
+ {
10653
+ "path": "inProgress",
10654
+ "valueType": "boolean"
10655
+ }
10656
+ ],
10657
+ "vacuum-control": [
10658
+ {
10659
+ "path": "state",
10660
+ "valueType": "enum",
10661
+ "enumValues": [
10662
+ "idle",
10663
+ "cleaning",
10664
+ "paused",
10665
+ "returning",
10666
+ "docked",
10667
+ "drying",
10668
+ "error"
10669
+ ]
10670
+ },
10671
+ {
10672
+ "path": "batteryLevel",
10673
+ "valueType": "number"
10674
+ },
10675
+ {
10676
+ "path": "fanSpeed",
10677
+ "valueType": "string"
10678
+ },
10679
+ {
10680
+ "path": "progressPercent",
10681
+ "valueType": "number"
10682
+ },
10683
+ {
10684
+ "path": "errorCode",
10685
+ "valueType": "number"
10686
+ },
10687
+ {
10688
+ "path": "errorLabel",
10689
+ "valueType": "string"
10690
+ }
10691
+ ],
10692
+ "valve": [{
10693
+ "path": "state",
10694
+ "valueType": "enum",
10695
+ "enumValues": [
10696
+ "open",
10697
+ "opening",
10698
+ "closing",
10699
+ "closed",
10700
+ "stopped"
10701
+ ]
10702
+ }, {
10703
+ "path": "position",
10704
+ "valueType": "number"
10705
+ }],
10706
+ "vibration": [{
10707
+ "path": "detected",
10708
+ "valueType": "boolean"
10709
+ }],
10710
+ "water-heater": [
10711
+ {
10712
+ "path": "currentTemp",
10713
+ "valueType": "number"
10714
+ },
10715
+ {
10716
+ "path": "targetTemp",
10717
+ "valueType": "number"
10718
+ },
10719
+ {
10720
+ "path": "operationMode",
10721
+ "valueType": "string"
10722
+ },
10723
+ {
10724
+ "path": "away",
10725
+ "valueType": "boolean"
10726
+ },
10727
+ {
10728
+ "path": "minTemp",
10729
+ "valueType": "number"
10730
+ },
10731
+ {
10732
+ "path": "maxTemp",
10733
+ "valueType": "number"
10734
+ }
10735
+ ],
10736
+ "weather": [
10737
+ {
10738
+ "path": "condition",
10739
+ "valueType": "string"
10740
+ },
10741
+ {
10742
+ "path": "temperature",
10743
+ "valueType": "number"
10744
+ },
10745
+ {
10746
+ "path": "temperatureUnit",
10747
+ "valueType": "string"
10748
+ },
10749
+ {
10750
+ "path": "humidity",
10751
+ "valueType": "number"
10752
+ },
10753
+ {
10754
+ "path": "pressure",
10755
+ "valueType": "number"
10756
+ },
10757
+ {
10758
+ "path": "pressureUnit",
10759
+ "valueType": "string"
10760
+ },
10761
+ {
10762
+ "path": "windSpeed",
10763
+ "valueType": "number"
10764
+ },
10765
+ {
10766
+ "path": "windSpeedUnit",
10767
+ "valueType": "string"
10768
+ },
10769
+ {
10770
+ "path": "windBearing",
10771
+ "valueType": "number"
10772
+ }
10773
+ ],
10774
+ "zone-analytics": [
10775
+ {
10776
+ "path": "ts",
10777
+ "valueType": "number"
10778
+ },
10779
+ {
10780
+ "path": "frameWidth",
10781
+ "valueType": "number"
10782
+ },
10783
+ {
10784
+ "path": "frameHeight",
10785
+ "valueType": "number"
10786
+ },
10787
+ {
10788
+ "path": "frame.totalObjects",
10789
+ "valueType": "number"
10790
+ },
10791
+ {
10792
+ "path": "frame.standingObjects",
10793
+ "valueType": "number"
10794
+ },
10795
+ {
10796
+ "path": "frame.transientObjects",
10797
+ "valueType": "number"
10798
+ },
10799
+ {
10800
+ "path": "unzoned.totalObjects",
10801
+ "valueType": "number"
10802
+ },
10803
+ {
10804
+ "path": "unzoned.standingObjects",
10805
+ "valueType": "number"
10806
+ },
10807
+ {
10808
+ "path": "unzoned.transientObjects",
10809
+ "valueType": "number"
10810
+ }
10811
+ ]
10812
+ });
8839
10813
  object({
8840
10814
  code: string().regex(/^[a-z][a-z0-9-]*(\.[a-z0-9-]+)+$/),
8841
10815
  params: record(string(), union([string(), number()])).optional()
@@ -9184,7 +11158,7 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
9184
11158
  return DeviceRole;
9185
11159
  }({});
9186
11160
  //#endregion
9187
- //#region ../types/dist/composition-BJ8iAZb3.mjs
11161
+ //#region ../types/dist/composition-kEl9mevu.mjs
9188
11162
  /**
9189
11163
  * The ffmpeg build every CamStack node downloads, per platform and arch.
9190
11164
  *
@@ -12399,7 +14373,7 @@ var LogChannelDescriptorSchema = object({
12399
14373
  * `true` is a PROMISE with two halves, and both must hold: the gate is
12400
14374
  * consulted with the numeric device id, AND every line the channel admits
12401
14375
  * carries `tags: { deviceId }` with that same numeric id. The second half is
12402
- * what makes `| json | deviceId="617"` work in Loki — `loki-payload.ts`
14376
+ * what makes `| json | deviceId="102"` work in Loki — `loki-payload.ts`
12403
14377
  * keeps `deviceId` out of the stream labels for cardinality, so the tag in
12404
14378
  * the body is the only way to filter.
12405
14379
  *
@@ -12563,7 +14537,7 @@ function effectFor(stepId, label) {
12563
14537
  * - label kind: a label counts for a step only when the classMap sends it to
12564
14538
  * that step's macro AND it names a vocabulary entry. Every root is judged
12565
14539
  * the same way — a COCO model supplies the animal classifier with the six
12566
- * species COCO names, exactly as a Frigate+ model supplies seven.
14540
+ * species COCO names, exactly as a plus catalog model supplies seven.
12567
14541
  * - crop kind: the labelmap carries one of the step's root labels. Those
12568
14542
  * labels are deliberately left out of the classMap, so they never make a
12569
14543
  * track of their own.
@@ -12712,7 +14686,7 @@ var ModelVariantGroupSchema = object({
12712
14686
  precision: _enum(["fp32", "int8"]).optional(),
12713
14687
  /**
12714
14688
  * Training / latency-variant axis. Omit ⇒ the standard build. `test` marks
12715
- * an alternate training of the same family (Scrypted `relu_test`); chip
14689
+ * an alternate training of the same family (plugin catalog `relu_test`); chip
12716
14690
  * label is "Test".
12717
14691
  */
12718
14692
  optimization: _enum(["standard", "test"]).optional(),
@@ -12733,9 +14707,9 @@ var ModelProviderIdSchema = _enum([
12733
14707
  ]);
12734
14708
  /**
12735
14709
  * Resolve a catalog entry's picker provider. An explicit stamp always wins;
12736
- * otherwise Frigate/Scrypted are recognised from id prefix or description.
14710
+ * otherwise plus catalog/plugin catalog are recognised from id prefix or description.
12737
14711
  * Unstamped BYO registry rows fall through to `custom`. Family `yolov9` is
12738
- * NOT a Scrypted signal — CamStack ships that family too.
14712
+ * NOT a plugin catalog signal — CamStack ships that family too.
12739
14713
  */
12740
14714
  function inferModelProvider(entry) {
12741
14715
  if (entry.provider !== void 0) return entry.provider;
@@ -12977,8 +14951,8 @@ var ModelCatalogEntrySchema = object({
12977
14951
  provider: ModelProviderIdSchema.optional(),
12978
14952
  /**
12979
14953
  * Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
12980
- * applies (Frigate / COCO public catalog). Set on a custom model whose raw
12981
- * labels already ARE the CamStack macros (Scrypted identity map).
14954
+ * applies (plus catalog / COCO public catalog). Set on a custom model whose raw
14955
+ * labels already ARE the CamStack macros (plugin catalog identity map).
12982
14956
  */
12983
14957
  classMap: DetectionCatalogClassMapSchema.optional(),
12984
14958
  /**
@@ -15965,7 +17939,7 @@ method(object({
15965
17939
  * `1` is real time and is the ONLY value that allows the copy branch —
15966
17940
  * anything else forces `libx264` over the window. That was priced
15967
17941
  * before it was chosen: a per-event burst measured at 0.23 s and 254 KB
15968
- * on a real 615 720p cut, against 922 KB for the copy it replaces. A
17942
+ * on a real 101 720p cut, against 922 KB for the copy it replaces. A
15969
17943
  * re-encode is capped at 720p (`EVENT_CLIP_ENCODE_MAX_WIDTH`), because
15970
17944
  * once the decode is forced the width stops being free.
15971
17945
  */
@@ -16385,6 +18359,7 @@ var CompositionRunStatusSchema = _enum([
16385
18359
  "starting",
16386
18360
  "running",
16387
18361
  "degraded",
18362
+ "incomplete",
16388
18363
  "failed"
16389
18364
  ]);
16390
18365
  var CompositionFieldStateKindSchema = _enum([
@@ -16598,6 +18573,7 @@ var CoreBlockStatusSchema = _enum([
16598
18573
  "starting",
16599
18574
  "running",
16600
18575
  "degraded",
18576
+ "incomplete",
16601
18577
  "failed"
16602
18578
  ]);
16603
18579
  /** path → TypeScript source for a multi-file block. */
@@ -38549,7 +40525,7 @@ var PRIMARY_CATEGORIES = new Set(ENTRIES.map((e) => e.primaryCategory));
38549
40525
  * `locationKey` is ALWAYS {@link locationIconKey} of the label — never the
38550
40526
  * operator's casing. The registry matches labels trimmed + case-insensitively
38551
40527
  * everywhere (`addLocation`, `removeLocation`, `renameLocation`), and a
38552
- * case-only rename (`cucina` → `Cucina`) is a real edit this repo supports; a
40528
+ * case-only rename (`kitchen` → `Kitchen`) is a real edit this repo supports; a
38553
40529
  * map keyed on the displayed casing would orphan its entry on exactly that
38554
40530
  * edit. Consumers join by keying their own label through `locationIconKey`.
38555
40531
  */
@@ -38574,7 +40550,7 @@ var LocationDescriptionAssignmentSchema = object({
38574
40550
  /**
38575
40551
  * A SITE ZONE — a named part of the property that several locations belong to.
38576
40552
  *
38577
- * "Zona notte" holds every bedroom; "Zona giorno" the living room and the
40553
+ * "Night zone" holds every bedroom; "Zona giorno" the living room and the
38578
40554
  * kitchen. A camera belongs to exactly one location, and a location to at most
38579
40555
  * one zone, so a camera's zone is derived and never stored on the device: the
38580
40556
  * whole point of this entity is that grouping rooms touches no device row.
@@ -38603,7 +40579,7 @@ var LocationDescriptionAssignmentSchema = object({
38603
40579
  * the locations inside it.
38604
40580
  *
38605
40581
  * The LABEL is carried alongside the key because the key is lossy on purpose —
38606
- * a surface must show "Zona notte", not "zona notte". Locations are carried
40582
+ * a surface must show "Night zone", not "night zone". Locations are carried
38607
40583
  * here, rather than left to a second call, because every consumer wants both
38608
40584
  * at once and a viewer that asked twice could render a zone whose membership
38609
40585
  * it has not fetched yet.
@@ -40716,8 +42692,8 @@ var LoadContributionSchema = object({
40716
42692
  "unattributable"
40717
42693
  ]),
40718
42694
  /**
40719
- * What ONE entry is, in the contributor's own words — `615/high`,
40720
- * `617/native`, `cuda:0 shared pool`. Free text because the unit differs per
42695
+ * What ONE entry is, in the contributor's own words — `101/high`,
42696
+ * `102/native`, `cuda:0 shared pool`. Free text because the unit differs per
40721
42697
  * family and inventing a common one would lose the only information that
40722
42698
  * makes two entries for the same camera distinguishable.
40723
42699
  */
@@ -43683,7 +45659,7 @@ var NcConditionsSchema = object({
43683
45659
  * with the list under it is worse than no switch (D62).
43684
45660
  *
43685
45661
  * MEMBERS ARE FACE-GALLERY `Identity.id`s (uuid), not display names. A name is
43686
- * renameable, and a rule authored on "Gianluca" went silently dark the moment
45662
+ * renameable, and a rule authored on "Alice" went silently dark the moment
43687
45663
  * the operator fixed the spelling. The id reaches the record on
43688
45664
  * `LabelAttribution.identityId`; the name is what the editor shows and what
43689
45665
  * `{{label}}` renders.
@@ -44234,7 +46210,7 @@ var NcRulePatchSchema = NcRuleInputSchema.partial().extend({
44234
46210
  * A rule scoped to one camera and one zone silently became a rule that
44235
46211
  * matches EVERY event on EVERY camera, and lost its `media` policy
44236
46212
  * (zoneCrop / gif / clip / frame) and its `priority` at the same time. Seen
44237
- * live on 2026-08-12: a rule scoped to device 617 fired on 590 and 615
46213
+ * live on 2026-08-12: a rule scoped to device 102 fired on 104 and 101
44238
46214
  * within a minute of a two-field patch.
44239
46215
  *
44240
46216
  * So every defaulted field is re-declared here WITHOUT its default. The
@@ -46047,7 +48023,7 @@ var LabelAttributionSchema = object({
46047
48023
  * `Identity.id` or a plate-gallery `Vehicle.id` (both `randomUUID`).
46048
48024
  *
46049
48025
  * The text alone is a DISPLAY NAME, and a display name is renameable: a
46050
- * notification rule authored on "Gianluca" stopped matching the moment the
48026
+ * notification rule authored on "Alice" stopped matching the moment the
46051
48027
  * operator fixed the spelling in the gallery, and nothing said so. The id is
46052
48028
  * the thing that does not move, so it is what a rule matches on
46053
48029
  * (`NcConditions.identities`) and the text is what a human is shown.
@@ -48586,7 +50562,7 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
48586
50562
  /**
48587
50563
  * Root-supplied detections for the tree's ROOT step (D730). Set by
48588
50564
  * `runDetailSubtree` when the camera's root model supplies a crop-kind
48589
- * step (a Frigate+ `license_plate` for `plate-detection`): the step is
50565
+ * step (a plus catalog `license_plate` for `plate-detection`): the step is
48590
50566
  * NOT inferred, these boxes are its output, and its children (the plate
48591
50567
  * reader) run on them through their own crop policy. Boxes are in the
48592
50568
  * PIXELS of the image this call carries. Absent ⇒ the root step runs.
@@ -50219,7 +52195,7 @@ var RunnerCameraConfigSchema = object({
50219
52195
  * detection session that asks for history. What shipped was a last-moment
50220
52196
  * discard — `FrameSlot`'s throttle compares wall clocks, and ~4 s of media
50221
52197
  * arriving inside a few hundred ms of wall clock looks to it like one frame's
50222
- * worth. Device 617, 2026-09-08: a re-run of the SAME model over the stored
52198
+ * worth. Device 102, 2026-09-08: a re-run of the SAME model over the stored
50223
52199
  * recording scored the subject `vehicle 0.5669` — above the 0.50 floor —
50224
52200
  * 1.68 s BEFORE the live track was born, on a frame that was in the pre-roll,
50225
52201
  * was decoded, and was freed.
@@ -52249,7 +54225,7 @@ method(_void(), ProviderInfoSchema, { auth: "admin" }), method(object({ config:
52249
54225
  * The signals a device can emit to WAKE its own stream.
52250
54226
  *
52251
54227
  * A camera whose stream is built on demand sleeps until something asks for it,
52252
- * and "something" cannot be a consumer that is merely attached — a Frigate-style
54228
+ * and "something" cannot be a consumer that is merely attached — a external-catalog
52253
54229
  * puller holds a session open for ever, and treating that as demand would keep
52254
54230
  * a battery camera awake for ever, which is the whole thing the battery is for
52255
54231
  * (D173). So the wake has to come from the CAMERA: an event it noticed by
@@ -52936,7 +54912,7 @@ var ClipSchema = object({
52936
54912
  * {@link MAX_CLIP_EVENT_IDS}. Empty on footage-only clips.
52937
54913
  *
52938
54914
  * Bounded because it is not a payload the surface pages through: one visit on
52939
- * device 615 carried 2 345 ids, and `eventIds` was 99% of a 153 KB
54915
+ * device 101 carried 2 345 ids, and `eventIds` was 99% of a 153 KB
52940
54916
  * camera-day. Read {@link eventCount} for the true total.
52941
54917
  */
52942
54918
  eventIds: array(string()).optional(),
@@ -53081,7 +55057,7 @@ var ClipPlaybackSchema = object({
53081
55057
  * camera has no recordings", which is the defect this whole line of work is
53082
55058
  * about: a battery camera nobody woke (`sleeping`), a camera that could not be
53083
55059
  * reached at all (`unreachable`, also what a provider that THREW reports), a
53084
- * camera whose SD card is not mounted (`no-storage`, measured on 640 —
55060
+ * camera whose SD card is not mounted (`no-storage`, measured on 106 —
53085
55061
  * `HddInfo mount 0`, honestly nothing to list rather than "no clips"), and a
53086
55062
  * camera whose OWN index disagrees with its OWN calendar (`index-empty`,
53087
55063
  * measured on 618: the calendar marks 3–20 September, days 6–20 list zero
@@ -53346,7 +55322,7 @@ DeviceType.Camera, method(object({
53346
55322
  *
53347
55323
  * It was optional, documented as "absent means the device's BOUND
53348
55324
  * provider, which is CamStack on every camera". No code implemented
53349
- * that. Measured on the live hub 2026-09-20 — device 592, bound to
55325
+ * that. Measured on the live hub 2026-09-20 — device 107, bound to
53350
55326
  * `recorder` AND `provider-reolink` — a bare call with `limit: 3`
53351
55327
  * answered SIX rows, three from each source, merged newest-first:
53352
55328
  * `device-collection-dispatch.ts` simply left the fan-out un-narrowed,
@@ -54424,7 +56400,10 @@ object({
54424
56400
  DeviceType.Sensor;
54425
56401
  object({
54426
56402
  /** Current illuminance in lux (lx). */
54427
- lux: number().min(0),
56403
+ lux: number().min(0).meta({
56404
+ unit: "lx",
56405
+ label: "Illuminance"
56406
+ }),
54428
56407
  /** Ms epoch when the slice was last updated. */
54429
56408
  lastFetchedAt: number(),
54430
56409
  /** Live display unit from the upstream source (e.g. HA
@@ -54580,7 +56559,10 @@ var BatteryStatusSchema = object({
54580
56559
  * Consumers must SKIP a null rather than coerce it — `battery-band` already
54581
56560
  * declines to band a non-finite reading, which is the correct shape.
54582
56561
  */
54583
- percentage: number().min(0).max(100).nullable(),
56562
+ percentage: number().min(0).max(100).nullable().meta({
56563
+ unit: "%",
56564
+ label: "Charge"
56565
+ }),
54584
56566
  /**
54585
56567
  * Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
54586
56568
  * Reolink-specific for the Solar Panel 2 accessory (will become
@@ -54599,13 +56581,13 @@ var BatteryStatusSchema = object({
54599
56581
  "solar",
54600
56582
  "none",
54601
56583
  "unknown"
54602
- ]),
56584
+ ]).meta({ label: "Charging source" }),
54603
56585
  /**
54604
56586
  * True when the camera firmware has gone into low-power mode. Battery
54605
56587
  * providers MUST avoid polling during sleep — reading the battery
54606
56588
  * wakes the camera up and drains charge.
54607
56589
  */
54608
- sleeping: boolean(),
56590
+ sleeping: boolean().meta({ label: "Sleeping" }),
54609
56591
  /** Ms epoch of the last observation. Lets consumers reason about freshness. */
54610
56592
  lastUpdated: number(),
54611
56593
  /**
@@ -54645,7 +56627,7 @@ var BatteryStatusSchema = object({
54645
56627
  * sub-threshold = low). UI MUST render "Normal"/"Low" instead of a
54646
56628
  * misleading exact percentage. Absent/false → genuine 0–100 % reading.
54647
56629
  */
54648
- binary: boolean().optional()
56630
+ binary: boolean().optional().meta({ label: "Binary indicator" })
54649
56631
  });
54650
56632
  DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat;
54651
56633
  method(object({
@@ -54660,7 +56642,7 @@ method(object({
54660
56642
  status: BatteryStatusSchema
54661
56643
  });
54662
56644
  object({
54663
- on: boolean(),
56645
+ on: boolean().meta({ label: "On" }),
54664
56646
  /** Ms epoch of the last transition. 0 if never observed. */
54665
56647
  lastChangedAt: number()
54666
56648
  });
@@ -54918,7 +56900,7 @@ var GridLayoutCellSchema = object({
54918
56900
  *
54919
56901
  * A grid's `high` composes its sources' `high` and its `low` their `low`, so a
54920
56902
  * profile is on offer only when EVERY source can serve it. The refusal NAMES
54921
- * the sources, because "this grid has no low" is not a finding — "615 has no
56903
+ * the sources, because "this grid has no low" is not a finding — "101 has no
54922
56904
  * low" is, and it is the one an operator can act on.
54923
56905
  */
54924
56906
  var GridProfileOfferSchema = object({
@@ -56469,7 +58451,10 @@ DeviceType.Humidifier, method(object({
56469
58451
  });
56470
58452
  object({
56471
58453
  /** Current relative humidity, 0..100. */
56472
- percent: number().min(0).max(100),
58454
+ percent: number().min(0).max(100).meta({
58455
+ unit: "%",
58456
+ label: "Humidity"
58457
+ }),
56473
58458
  /** Ms epoch when the slice was last updated. */
56474
58459
  lastFetchedAt: number(),
56475
58460
  /** Live display unit from the upstream source (e.g. HA
@@ -59246,9 +61231,15 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
59246
61231
  });
59247
61232
  object({
59248
61233
  /** Instantaneous power draw in watts. */
59249
- watts: number().optional(),
61234
+ watts: number().optional().meta({
61235
+ unit: "W",
61236
+ label: "Power"
61237
+ }),
59250
61238
  /** Cumulative energy in kilowatt-hours since the meter was reset. */
59251
- kwhTotal: number().optional(),
61239
+ kwhTotal: number().optional().meta({
61240
+ unit: "kWh",
61241
+ label: "Energy"
61242
+ }),
59252
61243
  /** Voltage in volts. */
59253
61244
  volts: number().optional(),
59254
61245
  /** Current in amperes. */
@@ -59567,9 +61558,9 @@ var PtzOptionsSchema = object({
59567
61558
  * Reolink preset 0, Hikvision preset '1', Dahua preset 1 -- and on this fleet
59568
61559
  * not one of the three cameras honours its own:
59569
61560
  *
59570
- * 592 Videocamera camera Daniel (reolink) preset 0 holds "stanza"
59571
- * 1438 Videocamera dispensa (hikvision) preset 1 holds "Credenza"
59572
- * 3836 Videocamera studio (amcrest) preset 1 holds "Preset1"
61561
+ * 107 Camera camera Carol (reolink) preset 0 holds "stanza"
61562
+ * 1438 Camera dispensa (hikvision) preset 1 holds "Credenza"
61563
+ * 3836 Camera studio (amcrest) preset 1 holds "Preset1"
59573
61564
  *
59574
61565
  * So `goHome` meant "go wherever the operator happened to save in slot 0 or 1",
59575
61566
  * and two of the three swallowed the failure in a bare `catch`. For autotrack
@@ -59716,7 +61707,7 @@ object({
59716
61707
  running: boolean().nullable(),
59717
61708
  /** Epoch ms the current boolean began; null while `running` is null. */
59718
61709
  since: number().nullable(),
59719
- source: RunningStateSourceSchema,
61710
+ source: RunningStateSourceSchema.meta({ label: "Source" }),
59720
61711
  phase: string().nullable(),
59721
61712
  /** null until a reading has been published (D393). */
59722
61713
  lastFetchedAt: number().nullable()
@@ -59769,7 +61760,7 @@ var RecordingAvailabilitySchema = object({
59769
61760
  * would look identical. But the answer used to say nothing about that, so a
59770
61761
  * caller asking "what can I export?" read the single preferred profile as
59771
61762
  * the only one that exists — on this deployment every camera records `high`
59772
- * AND `low`, the low tree holding 14 GB for camera 615 alone, and the export
61763
+ * AND `low`, the low tree holding 14 GB for camera 101 alone, and the export
59773
61764
  * UI could not see it.
59774
61765
  *
59775
61766
  * Cheap: it is the same shallow directory read the profile CHOICE already
@@ -59868,7 +61859,7 @@ var RecordingSourceOptionsSchema = object({
59868
61859
  * `sparse` = gaps are the absence of one, and must be drawn as such.
59869
61860
  *
59870
61861
  * Not an onboard-only concession: measured 2026-09-24, OUR bar covers 98.8 %
59871
- * of 592's day and 1.2 % of 1436's. It is a fact about a (source, camera)
61862
+ * of 107's day and 1.2 % of 1436's. It is a fact about a (source, camera)
59872
61863
  * pair, and ours answers it per camera from `deriveRecordingMode`. */
59873
61864
  coverage: _enum(["continuous", "sparse"]),
59874
61865
  /** Where the playhead may be put.
@@ -59944,7 +61935,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(RecordingSourceS
59944
61935
  * merely discouraged (D554 amended).
59945
61936
  *
59946
61937
  * It was learned the expensive way on `videoclips.listClips`: measured
59947
- * on the live hub 2026-09-20, device 592 bound to `recorder` AND
61938
+ * on the live hub 2026-09-20, device 107 bound to `recorder` AND
59948
61939
  * `provider-reolink`, a bare call with `limit: 3` answered SIX rows,
59949
61940
  * three from each source, merged — `device-collection-dispatch.ts`
59950
61941
  * leaves an unpinned fan-out un-narrowed, so absence buys the union the
@@ -60545,7 +62536,7 @@ var ExportSpeedSchema = number().min(.25).max(32);
60545
62536
  * on a 10 h window holding 29,393 s of footage every range landed late by the
60546
62537
  * gap accumulated before it — up to 6,607 s, well past EOF. Nothing matched,
60547
62538
  * the video was a uniform timelapse, and the log line reported the five ranges
60548
- * that had been ASKED for (2026-08-13, export `57d14363`, camera 615).
62539
+ * that had been ASKED for (2026-08-13, export `57d14363`, camera 101).
60549
62540
  *
60550
62541
  * Relative and not absolute epoch, because an absolute epoch would make every
60551
62542
  * call site responsible for the same subtraction.
@@ -61179,7 +63170,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), RecordingSignalStatusS
61179
63170
  * which put a "Scenes" tab on one camera's detail page. That is the wrong shape
61180
63171
  * for the thing: a scene is a standing question about the property ("is the bin
61181
63172
  * still out"), and the operator's question is "which of my scenes have tripped",
61182
- * across every camera at once — not "what does camera 617 think". Buried one
63173
+ * across every camera at once — not "what does camera 102 think". Buried one
61183
63174
  * camera deep it also could not be found. The surface is now a top-level admin
61184
63175
  * page (`/scenes`, `pages/Scenes.tsx`) that lists every scene on every camera and
61185
63176
  * picks the camera inside the create flow, the same shape Events and Faces have.
@@ -61762,7 +63753,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), StreamParamsOptionsSch
61762
63753
  auth: "admin"
61763
63754
  }), method(object({ deviceId: number() }), unknown().nullable());
61764
63755
  object({
61765
- on: boolean(),
63756
+ on: boolean().meta({ label: "On" }),
61766
63757
  /** Ms epoch of the last state change. Useful for UI "X minutes ago". */
61767
63758
  lastChangedAt: number()
61768
63759
  });
@@ -62325,7 +64316,10 @@ object({
62325
64316
  DeviceType.Sensor;
62326
64317
  object({
62327
64318
  /** Current temperature in Celsius. */
62328
- celsius: number(),
64319
+ celsius: number().meta({
64320
+ unit: "°C",
64321
+ label: "Temperature"
64322
+ }),
62329
64323
  /** Ms epoch when the slice was last updated (push or poll). */
62330
64324
  lastFetchedAt: number(),
62331
64325
  /** Live display unit from the upstream source (e.g. HA
@@ -63473,15 +65467,19 @@ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" })
63473
65467
  auth: "admin"
63474
65468
  });
63475
65469
  SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
65470
+ DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher, DeviceType.Camera, DeviceType.Camera, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
65471
+ String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
65472
+ DeviceRole.BinarySensor, DeviceRole.MotionSensor;
65473
+ new Set(CAP_NAMES);
63476
65474
  function isClassMapMacroTarget(value) {
63477
65475
  return CLASS_MAP_MACRO_TARGETS.some((target) => target === value);
63478
65476
  }
63479
65477
  /**
63480
- * Raw Frigate+ label → detection macro. Every label of the documented
63481
- * Frigate+ base set (docs.frigate.video/plus, verified 2026-08-21) is either
63482
- * here or in {@link FRIGATE_PLUS_UNMAPPED_LABELS}, with the reason it is not.
65478
+ * Raw plus catalog label → detection macro. Every label of the documented
65479
+ * plus catalog base set (docs.frigate.video/plus, verified 2026-08-21) is either
65480
+ * here or in {@link PLUS_CATALOG_UNMAPPED_LABELS}, with the reason it is not.
63483
65481
  *
63484
- * Why this exists: a Frigate+ import used to carry NO classMap, so it inherited
65482
+ * Why this exists: a plus catalog import used to carry NO classMap, so it inherited
63485
65483
  * the step's `COCO_TO_MACRO` (`preserveOriginal: false`) and the executor
63486
65484
  * dropped every label COCO does not name — deer, raccoon, fox, squirrel, goat,
63487
65485
  * rabbit, skunk, kangaroo, possum, rodent, school_bus, garbage_truck and even
@@ -63489,7 +65487,7 @@ function isClassMapMacroTarget(value) {
63489
65487
  * label as `originalClass` whenever the map resolves it, so the fine identity
63490
65488
  * survives under the macro.
63491
65489
  */
63492
- var FRIGATE_PLUS_TO_MACRO = {
65490
+ var PLUS_CATALOG_TO_MACRO = {
63493
65491
  person: "person",
63494
65492
  baby: "person",
63495
65493
  car: "vehicle",
@@ -63517,17 +65515,17 @@ var FRIGATE_PLUS_TO_MACRO = {
63517
65515
  package: "package"
63518
65516
  };
63519
65517
  /**
63520
- * The per-model classMap for a Frigate / Frigate+ detector, derived from ITS
63521
- * labelmap: each label resolves through {@link FRIGATE_PLUS_TO_MACRO} first,
63522
- * then `COCO_TO_MACRO` (Frigate's default model ships the COCO-91 labelmap, so
65518
+ * The per-model classMap for a plus catalog / plus catalog detector, derived from ITS
65519
+ * labelmap: each label resolves through {@link PLUS_CATALOG_TO_MACRO} first,
65520
+ * then `COCO_TO_MACRO` (plus catalog's default model ships the COCO-91 labelmap, so
63523
65521
  * a preset import may carry either vocabulary). A label neither knows is left
63524
65522
  * out, and `preserveOriginal: false` drops it in the executor — the same
63525
- * contract as the COCO map, now with the Frigate+ vocabulary in it.
65523
+ * contract as the COCO map, now with the plus catalog vocabulary in it.
63526
65524
  */
63527
- function buildFrigateClassMap(labels) {
65525
+ function buildPlusCatalogClassMap(labels) {
63528
65526
  const mapping = {};
63529
65527
  for (const label of labels) {
63530
- const target = FRIGATE_PLUS_TO_MACRO[label] ?? COCO_TO_MACRO.mapping[label];
65528
+ const target = PLUS_CATALOG_TO_MACRO[label] ?? COCO_TO_MACRO.mapping[label];
63531
65529
  if (target !== void 0 && isClassMapMacroTarget(target)) mapping[label] = target;
63532
65530
  }
63533
65531
  return {
@@ -63536,14 +65534,14 @@ function buildFrigateClassMap(labels) {
63536
65534
  };
63537
65535
  }
63538
65536
  /**
63539
- * Everything a Frigate / Frigate+ entry derives from ITS OWN labelmap: the
65537
+ * Everything a plus catalog / plus catalog entry derives from ITS OWN labelmap: the
63540
65538
  * classMap and the steps it can supply (D730) — label and crop kinds alike.
63541
- * Every Frigate builder spreads this at import, so the two cannot be derived
65539
+ * Every plus catalog builder spreads this at import, so the two cannot be derived
63542
65540
  * from different label lists, and no family is assumed to carry a label it
63543
65541
  * does not list.
63544
65542
  */
63545
- function frigateLabelFields(labels) {
63546
- const classMap = buildFrigateClassMap(labels);
65543
+ function plusCatalogLabelFields(labels) {
65544
+ const classMap = buildPlusCatalogClassMap(labels);
63547
65545
  const supplies = deriveRootSupplies(labels, classMap);
63548
65546
  return supplies.length > 0 ? {
63549
65547
  classMap,
@@ -63551,35 +65549,35 @@ function frigateLabelFields(labels) {
63551
65549
  } : { classMap };
63552
65550
  }
63553
65551
  /**
63554
- * Per-class confidence-floor defaults of an imported stock Frigate detector
65552
+ * Per-class confidence-floor defaults of an imported stock plus catalog detector
63555
65553
  * (D738): its per-detection `min_score` default, 0.5, for every class. Its
63556
65554
  * track-level `threshold` (the median of a track's recent scores) has no
63557
65555
  * counterpart in CamStack's per-detection floors and is not carried.
63558
65556
  */
63559
- var FRIGATE_STOCK_CLASS_FLOORS = Object.freeze({
65557
+ var PLUS_CATALOG_STOCK_CLASS_FLOORS = Object.freeze({
63560
65558
  person: .5,
63561
65559
  vehicle: .5,
63562
65560
  animal: .5
63563
65561
  });
63564
65562
  /**
63565
- * Per-class floor defaults of an imported Frigate+ detector (D738): the
63566
- * documented starting `min_score` values for Frigate+ models, which score
65563
+ * Per-class floor defaults of an imported plus catalog detector (D738): the
65564
+ * documented starting `min_score` values for plus catalog models, which score
63567
65565
  * higher than the stock ones (person 0.65, car 0.65, cat 0.65, dog 0.70). The
63568
65566
  * macro `animal` takes the lower of its classes, so no class is cut above its
63569
65567
  * documented value.
63570
65568
  */
63571
- var FRIGATE_PLUS_CLASS_FLOORS = Object.freeze({
65569
+ var PLUS_CATALOG_CLASS_FLOORS = Object.freeze({
63572
65570
  person: .65,
63573
65571
  vehicle: .65,
63574
65572
  animal: .65
63575
65573
  });
63576
65574
  /**
63577
- * The `defaultClassFloors` an imported Frigate entry carries: the import's
65575
+ * The `defaultClassFloors` an imported plus catalog entry carries: the import's
63578
65576
  * own, when it states them, else the defaults of its kind. A fresh object.
63579
65577
  */
63580
- function frigateDefaultClassFloors(kind, carried) {
65578
+ function plusCatalogDefaultClassFloors(kind, carried) {
63581
65579
  if (carried !== void 0) return { ...carried };
63582
- return { ...kind === "plus" ? FRIGATE_PLUS_CLASS_FLOORS : FRIGATE_STOCK_CLASS_FLOORS };
65580
+ return { ...kind === "plus" ? PLUS_CATALOG_CLASS_FLOORS : PLUS_CATALOG_STOCK_CLASS_FLOORS };
63583
65581
  }
63584
65582
  /**
63585
65583
  * Accessory device helpers — shared across drivers.
@@ -76508,7 +78506,7 @@ var SENSOR_CAP_VOCABULARY = {
76508
78506
  state: [{
76509
78507
  kind: "boolean",
76510
78508
  field: "on",
76511
- label: t("Active", "Attivo"),
78509
+ label: t("On", "Acceso"),
76512
78510
  whenTrue: t("When {device} turns active", "Quando {device} si attiva"),
76513
78511
  whenFalse: t("When {device} turns inactive", "Quando {device} si disattiva"),
76514
78512
  icon: "toggle-right"
@@ -79932,7 +81930,6 @@ Object.freeze({
79932
81930
  "smtp-provider": "email"
79933
81931
  });
79934
81932
  DeviceType.Camera;
79935
- DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher, DeviceType.Camera, DeviceType.Camera, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
79936
81933
  /**
79937
81934
  * A saved Customize assignment (D936). The schema is the type: callers use
79938
81935
  * `z.infer`, they do not restate the shape.
@@ -80021,7 +82018,6 @@ object({
80021
82018
  ]),
80022
82019
  reason: string().nullable()
80023
82020
  });
80024
- String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
80025
82021
  var G711_SCALE_CORRECTION_DB = {
80026
82022
  PCMU: 20 * Math.log10(4),
80027
82023
  PCMA: 20 * Math.log10(8)
@@ -80394,7 +82390,7 @@ var STATE_SUMMARY_SECTION_VARS = [
80394
82390
  {
80395
82391
  name: "summaryStreams",
80396
82392
  label: "Summary: streams offline",
80397
- example: "Ingresso (high) — since 06:40",
82393
+ example: "Front door (high) — since 06:40",
80398
82394
  kinds: ["stream-offline", "stream-online"]
80399
82395
  },
80400
82396
  {
@@ -80412,13 +82408,13 @@ var STATE_SUMMARY_SECTION_VARS = [
80412
82408
  {
80413
82409
  name: "summaryDetection",
80414
82410
  label: "Summary: cameras detecting nothing",
80415
- example: "Ingresso — since 05:10",
82411
+ example: "Front door — since 05:10",
80416
82412
  kinds: ["detection-blind"]
80417
82413
  },
80418
82414
  {
80419
82415
  name: "summaryNodes",
80420
82416
  label: "Summary: nodes",
80421
- example: "little-unraid — offline since 03:00",
82417
+ example: "agent-a — offline since 03:00",
80422
82418
  kinds: [
80423
82419
  "node-offline",
80424
82420
  "node-online",
@@ -81409,7 +83405,7 @@ function upsertAvailability(map, modelId, nodeId, entry) {
81409
83405
  }
81410
83406
  /**
81411
83407
  * Insert or replace a descriptor keyed by `entry.id`. When the id already
81412
- * exists, **formats are merged** (Scrypted multi-format accumulate) — sibling
83408
+ * exists, **formats are merged** (plugin catalog multi-format accumulate) — sibling
81413
83409
  * formats on the prior entry are never dropped. Returns a new array.
81414
83410
  */
81415
83411
  function upsertCustomModel(list, descriptor, nameOrigin = "source") {
@@ -81582,23 +83578,23 @@ function stripModelIdFromInferenceDevices(devices, modelId) {
81582
83578
  };
81583
83579
  }
81584
83580
  //#endregion
81585
- //#region src/frigate/frigate-import.ts
83581
+ //#region src/plus-catalog/plus-catalog-import.ts
81586
83582
  /**
81587
- * Variant-selector axes for an imported Frigate / Frigate+ detector. Family
83583
+ * Variant-selector axes for an imported plus catalog / plus catalog detector. Family
81588
83584
  * follows the generation (`ssdlite-mobiledet` / `yolonas` / `yolov9`); a
81589
83585
  * single-model import uses tier `default` so the stepper still gets a grouped
81590
- * picker under the Frigate provider.
83586
+ * picker under the plus catalog provider.
81591
83587
  */
81592
- function frigateVariantGroup(type, resolution) {
83588
+ function plusCatalogVariantGroup(type, resolution) {
81593
83589
  return {
81594
83590
  family: type === "mobiledet" ? "ssdlite-mobiledet" : type,
81595
83591
  tier: "default",
81596
83592
  resolution
81597
83593
  };
81598
83594
  }
81599
- var FRIGATE_PUBLIC_CATALOG = [{
83595
+ var PLUS_CATALOG_PUBLIC_CATALOG = [{
81600
83596
  id: "frigate-mobiledet-edgetpu",
81601
- label: "Frigate default — SSDLite MobileDet (EdgeTPU)",
83597
+ label: "plus catalog default — SSDLite MobileDet (EdgeTPU)",
81602
83598
  format: "tflite",
81603
83599
  url: "https://github.com/google-coral/test_data/raw/release-frogfish/ssdlite_mobiledet_coco_qat_postprocess_edgetpu.tflite",
81604
83600
  sizeMB: 5.4,
@@ -81698,21 +83694,21 @@ var FRIGATE_PUBLIC_CATALOG = [{
81698
83694
  "hair brush"
81699
83695
  ],
81700
83696
  license: CORAL_MOBILEDET_APACHE,
81701
- notes: "Frigate's default detection model (the one a stock Frigate + Coral install runs). EdgeTPU-compiled full-integer TFLite, 320×320, TFLite_Detection_PostProcess output → ssd decode. Requires a Coral (tflite format) node."
83697
+ notes: "plus catalog's default detection model (the one a stock plus catalog + Coral install runs). EdgeTPU-compiled full-integer TFLite, 320×320, TFLite_Detection_PostProcess output → ssd decode. Requires a Coral (tflite format) node."
81702
83698
  }];
81703
83699
  /**
81704
83700
  * Build the registrable descriptor for a curated catalog entry. The URL is
81705
83701
  * the PUBLIC one — any node downloads it on demand; no Distribute needed.
81706
83702
  */
81707
- function buildFrigateCatalogDescriptor(catalogId, overrides) {
81708
- const cat = FRIGATE_PUBLIC_CATALOG.find((e) => e.id === catalogId);
81709
- if (!cat) throw new Error(`Unknown Frigate catalog id "${catalogId}" — available: ${FRIGATE_PUBLIC_CATALOG.map((e) => e.id).join(", ")}`);
83703
+ function buildPlusCatalogCatalogDescriptor(catalogId, overrides) {
83704
+ const cat = PLUS_CATALOG_PUBLIC_CATALOG.find((e) => e.id === catalogId);
83705
+ if (!cat) throw new Error(`Unknown plus catalog catalog id "${catalogId}" — available: ${PLUS_CATALOG_PUBLIC_CATALOG.map((e) => e.id).join(", ")}`);
81710
83706
  return {
81711
83707
  stepId: "object-detection",
81712
83708
  entry: {
81713
83709
  id: overrides?.modelId?.trim() || cat.id,
81714
83710
  name: overrides?.name?.trim() || cat.label,
81715
- description: `${cat.notes} Imported from the Frigate public catalog via Model Studio.`,
83711
+ description: `${cat.notes} Imported from the plus catalog public catalog via Model Studio.`,
81716
83712
  formats: { [cat.format]: {
81717
83713
  url: cat.url,
81718
83714
  sizeMB: cat.sizeMB,
@@ -81726,18 +83722,18 @@ function buildFrigateCatalogDescriptor(catalogId, overrides) {
81726
83722
  id: name,
81727
83723
  name
81728
83724
  })),
81729
- ...frigateLabelFields(cat.labels),
81730
- defaultClassFloors: frigateDefaultClassFloors("stock"),
83725
+ ...plusCatalogLabelFields(cat.labels),
83726
+ defaultClassFloors: plusCatalogDefaultClassFloors("stock"),
81731
83727
  preprocessMode: "letterbox",
81732
83728
  provider: "frigate",
81733
83729
  license: cat.license,
81734
- group: frigateVariantGroup("mobiledet", cat.inputSize),
83730
+ group: plusCatalogVariantGroup("mobiledet", cat.inputSize),
81735
83731
  ...cat.postprocessor !== void 0 ? { postprocessor: cat.postprocessor } : {}
81736
83732
  }
81737
83733
  };
81738
83734
  }
81739
83735
  //#endregion
81740
- //#region src/frigate/plus-conversion.ts
83736
+ //#region src/plus-catalog/plus-conversion.ts
81741
83737
  /** Converted formats ADD to the imported entry; identity fields (decode,
81742
83738
  * labels, description, preprocess) stay the import's. */
81743
83739
  function mergeConvertedFormats(base, converted) {
@@ -82180,14 +84176,14 @@ async function moveInto(source, target) {
82180
84176
  }
82181
84177
  }
82182
84178
  //#endregion
82183
- //#region src/frigate/plus-decode.ts
84179
+ //#region src/plus-catalog/plus-decode.ts
82184
84180
  var UnsupportedPlusDecodeError = class extends Error {
82185
84181
  type;
82186
84182
  format;
82187
84183
  detectors;
82188
84184
  constructor(type, format, detectors) {
82189
84185
  const detList = detectors.length > 0 ? detectors.join(", ") : "(none)";
82190
- super(`Frigate+ import refused — no decoder for type "${type}", format "${format}", detectors ${detList}`);
84186
+ super(`plus catalog import refused — no decoder for type "${type}", format "${format}", detectors ${detList}`);
82191
84187
  this.name = "UnsupportedPlusDecodeError";
82192
84188
  this.type = type;
82193
84189
  this.format = format;
@@ -82265,12 +84261,12 @@ function resolvePlusDecode(info, formatOverride) {
82265
84261
  return decode;
82266
84262
  }
82267
84263
  //#endregion
82268
- //#region src/frigate/frigate-plus.ts
84264
+ //#region src/plus-catalog/plus-catalog-api.ts
82269
84265
  /**
82270
- * Frigate+ API client — the REAL api.frigate.video contract, verified against
82271
- * frigate/plus.py (dev branch, 2026-08-21):
84266
+ * plus catalog API client — the REAL api.frigate.video contract, verified against
84267
+ * plus-catalog/plus.py (dev branch, 2026-08-21):
82272
84268
  *
82273
- * - key format: `[uuid]:[40 hex]` (Frigate validates
84269
+ * - key format: `[uuid]:[40 hex]` (plus catalog validates
82274
84270
  * `[a-z0-9]{8}-…-[a-z0-9]{12}:[a-z0-9]{40}`)
82275
84271
  * - GET /v1/auth/token with HTTP basic auth (key split on `:`) →
82276
84272
  * `{ accessToken, expires }`
@@ -82294,19 +84290,19 @@ function isRecord(value) {
82294
84290
  }
82295
84291
  /** Exchange the API key for an access token. The key never appears in errors. */
82296
84292
  async function fetchPlusAccessToken(fetchFn, apiKey) {
82297
- if (!isValidPlusApiKey(apiKey)) throw new Error("Frigate+ API key is malformed — expected the \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:40-hex\" shape shown in your Frigate+ account settings");
84293
+ if (!isValidPlusApiKey(apiKey)) throw new Error("plus catalog API key is malformed — expected the \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:40-hex\" shape shown in your plus catalog account settings");
82298
84294
  const [user, pass] = apiKey.split(":");
82299
84295
  const basic = Buffer.from(`${user}:${pass}`).toString("base64");
82300
84296
  const res = await fetchFn(`${PLUS_API_HOST}/v1/auth/token`, { headers: { authorization: `Basic ${basic}` } });
82301
- if (!res.ok) throw new Error(`Frigate+ authentication failed (HTTP ${res.status}) — check the API key in the Model Studio addon settings`);
84297
+ if (!res.ok) throw new Error(`plus catalog authentication failed (HTTP ${res.status}) — check the API key in the Model Studio addon settings`);
82302
84298
  const body = await res.json();
82303
84299
  const token = isRecord(body) && typeof body.accessToken === "string" ? body.accessToken : null;
82304
- if (token === null) throw new Error("Frigate+ auth response carried no accessToken");
84300
+ if (token === null) throw new Error("plus catalog auth response carried no accessToken");
82305
84301
  return token;
82306
84302
  }
82307
84303
  async function plusGet(fetchFn, token, path) {
82308
84304
  const res = await fetchFn(`${PLUS_API_HOST}/v1/${path}`, { headers: { authorization: `Bearer ${token}` } });
82309
- if (!res.ok) throw new Error(`Frigate+ request "${path}" failed (HTTP ${res.status}): ${await res.text()}`);
84305
+ if (!res.ok) throw new Error(`plus catalog request "${path}" failed (HTTP ${res.status}): ${await res.text()}`);
82310
84306
  return res.json();
82311
84307
  }
82312
84308
  /**
@@ -82354,7 +84350,7 @@ async function listPlusModels(fetchFn, apiKey) {
82354
84350
  return toPlusModelSummaries(await plusGet(fetchFn, await fetchPlusAccessToken(fetchFn, apiKey), "model/list"));
82355
84351
  }
82356
84352
  function toModelInfo(raw, modelId) {
82357
- if (!isRecord(raw)) throw new Error("Frigate+ model info: unexpected response shape");
84353
+ if (!isRecord(raw)) throw new Error("plus catalog model info: unexpected response shape");
82358
84354
  const labelMap = {};
82359
84355
  if (isRecord(raw.labelMap)) {
82360
84356
  for (const [k, v] of Object.entries(raw.labelMap)) if (typeof v === "string") labelMap[k] = v;
@@ -82378,7 +84374,7 @@ async function requestPlusModelDownload(fetchFn, apiKey, plusModelId) {
82378
84374
  const info = toModelInfo(await plusGet(fetchFn, token, `model/${plusModelId}`), plusModelId);
82379
84375
  const signed = await plusGet(fetchFn, token, `model/${plusModelId}/signed_url`);
82380
84376
  const url = isRecord(signed) && typeof signed.url === "string" ? signed.url : null;
82381
- if (url === null) throw new Error("Frigate+ signed_url response carried no url");
84377
+ if (url === null) throw new Error("plus catalog signed_url response carried no url");
82382
84378
  return {
82383
84379
  info,
82384
84380
  downloadUrl: url
@@ -82394,7 +84390,7 @@ function orderedLabels(labelMap) {
82394
84390
  return out;
82395
84391
  }
82396
84392
  /**
82397
- * Build the registrable descriptor for a downloaded Frigate+ model. The
84393
+ * Build the registrable descriptor for a downloaded plus catalog model. The
82398
84394
  * artifact is hub-local (landed by the server-side download), so the URL uses
82399
84395
  * the `camstack-local://` convention (D208) — other nodes get it via
82400
84396
  * Distribute.
@@ -82407,7 +84403,7 @@ function plusInfoToDescriptor(info, opts) {
82407
84403
  entry: {
82408
84404
  id: opts.modelId,
82409
84405
  name: opts.name,
82410
- description: `Frigate+ personal model (${info.type}) — imported via Model Studio`,
84406
+ description: `plus catalog personal model (${info.type}) — imported via Model Studio`,
82411
84407
  formats: { [decode.format]: {
82412
84408
  url: `camstack-local://${opts.modelId}/${opts.filename}`,
82413
84409
  sizeMB: opts.sizeMB,
@@ -82421,11 +84417,11 @@ function plusInfoToDescriptor(info, opts) {
82421
84417
  id: name,
82422
84418
  name
82423
84419
  })),
82424
- ...frigateLabelFields(labels),
82425
- defaultClassFloors: frigateDefaultClassFloors("plus"),
84420
+ ...plusCatalogLabelFields(labels),
84421
+ defaultClassFloors: plusCatalogDefaultClassFloors("plus"),
82426
84422
  preprocessMode: "letterbox",
82427
84423
  provider: "frigate",
82428
- group: frigateVariantGroup(info.type, info.width),
84424
+ group: plusCatalogVariantGroup(info.type, info.width),
82429
84425
  postprocessor: decode.postprocessor
82430
84426
  }
82431
84427
  };
@@ -82543,16 +84539,16 @@ var ModelNodeAvailabilitySchema = preprocess((raw) => {
82543
84539
  }, object({ formats: partialRecord(_enum(MODEL_FORMATS), ModelFormatPresenceSchema) }));
82544
84540
  /** `modelId → nodeId → { formats: { [format]: presence } }`. */
82545
84541
  var ModelAvailabilityMapSchema = record(string(), record(string(), ModelNodeAvailabilitySchema));
82546
- /** Stable Library id for a Frigate+ training (chip id ↔ registry). */
82547
- function frigatePlusRegistryId(plusModelId) {
82548
- return `frigate-plus-${plusModelId}`;
84542
+ /** Stable Library id for a plus catalog training (chip id ↔ registry). */
84543
+ function plusCatalogPlusRegistryId(plusModelId) {
84544
+ return `plus-catalog-${plusModelId}`;
82549
84545
  }
82550
- var ScryptedManifestFileSchema = object({
84546
+ var PluginCatalogManifestFileSchema = object({
82551
84547
  relativePath: string(),
82552
84548
  size: number(),
82553
84549
  sha256: string().regex(/^[0-9a-f]{64}$/)
82554
84550
  });
82555
- var ScryptedManifestEntrySchema = object({
84551
+ var PluginCatalogManifestEntrySchema = object({
82556
84552
  id: string(),
82557
84553
  label: string(),
82558
84554
  family: _enum([
@@ -82573,10 +84569,10 @@ var ScryptedManifestEntrySchema = object({
82573
84569
  width: number(),
82574
84570
  height: number()
82575
84571
  }),
82576
- files: array(ScryptedManifestFileSchema).readonly(),
84572
+ files: array(PluginCatalogManifestFileSchema).readonly(),
82577
84573
  model: ModelCatalogEntrySchema
82578
84574
  });
82579
- var ScryptedCatalogDriftSchema = object({
84575
+ var PluginCatalogCatalogDriftSchema = object({
82580
84576
  manifestId: string(),
82581
84577
  status: _enum([
82582
84578
  "ok",
@@ -82587,12 +84583,12 @@ var ScryptedCatalogDriftSchema = object({
82587
84583
  details: string().optional()
82588
84584
  });
82589
84585
  /**
82590
- * Curated PUBLIC Frigate catalog entry (D214 addendum). Named + exported so
82591
- * the UI's `listFrigateCatalog` result parses against the SAME schema this
82592
- * action's output is declared with (see `modelStudioActions.listFrigateCatalog`
84586
+ * Curated PUBLIC plus catalog catalog entry (D214 addendum). Named + exported so
84587
+ * the UI's `listPlusCatalogCatalog` result parses against the SAME schema this
84588
+ * action's output is declared with (see `modelStudioActions.listPlusCatalogCatalog`
82593
84589
  * below) — one shape, not a hand-duplicated interface on the UI side.
82594
84590
  */
82595
- var FrigateCatalogEntrySchema = object({
84591
+ var PlusCatalogCatalogEntrySchema = object({
82596
84592
  id: string(),
82597
84593
  label: string(),
82598
84594
  format: _enum(MODEL_FORMATS),
@@ -82601,11 +84597,11 @@ var FrigateCatalogEntrySchema = object({
82601
84597
  notes: string()
82602
84598
  });
82603
84599
  /**
82604
- * Frigate+ `/v1/model/list` entry (see `frigate-plus.ts`). `isBaseModel` is
82605
- * the Base/Custom discriminator Frigate's own UI groups on. Named + exported
82606
- * for the same reason as {@link FrigateCatalogEntrySchema}.
84600
+ * plus catalog `/v1/model/list` entry (see `plus-catalog-api.ts`). `isBaseModel` is
84601
+ * the Base/Custom discriminator plus catalog's own UI groups on. Named + exported
84602
+ * for the same reason as {@link PlusCatalogCatalogEntrySchema}.
82607
84603
  */
82608
- var FrigatePlusModelSchema = object({
84604
+ var PlusCatalogModelSchema = object({
82609
84605
  id: string(),
82610
84606
  name: string(),
82611
84607
  type: string(),
@@ -82649,7 +84645,7 @@ var modelStudioActions = defineCustomActions({
82649
84645
  }), { kind: "mutation" }),
82650
84646
  /**
82651
84647
  * Convert missing OpenVINO / CoreML from an already-registered ONNX entry
82652
- * (Frigate+ / Custom per-format Import). Only the requested formats run.
84648
+ * (plus catalog / Custom per-format Import). Only the requested formats run.
82653
84649
  */
82654
84650
  ensureModelFormats: customAction(object({
82655
84651
  modelId: string(),
@@ -82666,7 +84662,7 @@ var modelStudioActions = defineCustomActions({
82666
84662
  clearedPins: number().int().nonnegative()
82667
84663
  }), { kind: "mutation" }),
82668
84664
  /**
82669
- * Rename an IMPORTED registry row (Frigate, Frigate+, Scrypted, uploads,
84665
+ * Rename an IMPORTED registry row (plus catalog, plus catalog, plugin catalog, uploads,
82670
84666
  * conversions) in place. Only `entry.name` changes — never the id, so pins
82671
84667
  * and availability are untouched. An empty name restores the name the model
82672
84668
  * was imported with. CamStack catalog models are refused.
@@ -82718,7 +84714,7 @@ var modelStudioActions = defineCustomActions({
82718
84714
  }), { kind: "mutation" }),
82719
84715
  listAvailability: customAction(_void(), ModelAvailabilityMapSchema),
82720
84716
  /**
82721
- * Chunked model-file upload (Frigate import). One tRPC mutation cannot
84717
+ * Chunked model-file upload (plus catalog import). One tRPC mutation cannot
82722
84718
  * carry a model file (hub HTTP body limit ~1 MB), so the page streams
82723
84719
  * base64 chunks: begin → append× → commit. Commit lands the artifact in the
82724
84720
  * hub's shared modelsDir, where the `camstack-local://` catalog-URL
@@ -82740,12 +84736,12 @@ var modelStudioActions = defineCustomActions({
82740
84736
  }), { kind: "mutation" }),
82741
84737
  abortModelUpload: customAction(object({ uploadId: string() }), object({ ok: literal(true) }), { kind: "mutation" }),
82742
84738
  /**
82743
- * Curated PUBLIC Frigate model catalog (D214 addendum). Import registers the
84739
+ * Curated PUBLIC plus catalog model catalog (D214 addendum). Import registers the
82744
84740
  * descriptor with its public URL (Library only). Optional `targetNodeId`
82745
84741
  * downloads on that node — no hub staging disk.
82746
84742
  */
82747
- listFrigateCatalog: customAction(_void(), array(FrigateCatalogEntrySchema).readonly()),
82748
- importFrigateCatalogModel: customAction(object({
84743
+ listPlusCatalogCatalog: customAction(_void(), array(PlusCatalogCatalogEntrySchema).readonly()),
84744
+ importPlusCatalogCatalogModel: customAction(object({
82749
84745
  catalogId: string(),
82750
84746
  modelId: string().optional(),
82751
84747
  name: string().optional(),
@@ -82756,23 +84752,23 @@ var modelStudioActions = defineCustomActions({
82756
84752
  bytes: number()
82757
84753
  }), { kind: "mutation" }),
82758
84754
  /**
82759
- * Local Scrypted YOLO catalog (Task 7B). Listing is a projection of the
84755
+ * Local plugin catalog YOLO catalog (Task 7B). Listing is a projection of the
82760
84756
  * revision-pinned manifesto plus a read-only HF drift check. Import accepts
82761
84757
  * `manifestId` (+ optional land-on-node) — host/repo/revision/path/labels/
82762
84758
  * checksum stay server-owned.
82763
84759
  */
82764
- listScryptedCatalog: customAction(_void(), object({
82765
- entries: array(ScryptedManifestEntrySchema).readonly(),
82766
- drift: array(ScryptedCatalogDriftSchema).readonly()
84760
+ listPluginCatalogCatalog: customAction(_void(), object({
84761
+ entries: array(PluginCatalogManifestEntrySchema).readonly(),
84762
+ drift: array(PluginCatalogCatalogDriftSchema).readonly()
82767
84763
  })),
82768
- importScryptedCatalogModel: customAction(object({
84764
+ importPluginCatalogCatalogModel: customAction(object({
82769
84765
  manifestId: string(),
82770
84766
  /** Optional display name typed on the import card. */
82771
84767
  name: string().optional(),
82772
84768
  targetNodeId: string().optional()
82773
84769
  }), CustomModelDescriptorSchema, { kind: "mutation" }),
82774
84770
  /**
82775
- * Frigate+ personal models. The API key lives in the addon's SETTINGS
84771
+ * plus catalog personal models. The API key lives in the addon's SETTINGS
82776
84772
  * (password field) and never leaves the hub: list / test / import all run
82777
84773
  * server-side against api.frigate.video. Status deliberately reveals only
82778
84774
  * booleans — never the key.
@@ -82783,18 +84779,18 @@ var modelStudioActions = defineCustomActions({
82783
84779
  * Empty object — `addons.custom` cannot carry zod `void`.
82784
84780
  */
82785
84781
  tfliteSupport: customAction(object({}).optional(), object({ nodes: array(string()).readonly() })),
82786
- frigatePlusStatus: customAction(_void(), object({
84782
+ plusCatalogPlusStatus: customAction(_void(), object({
82787
84783
  configured: boolean(),
82788
84784
  keyFormatValid: boolean()
82789
84785
  })),
82790
- frigatePlusTest: customAction(_void(), object({
84786
+ plusCatalogPlusTest: customAction(_void(), object({
82791
84787
  ok: boolean(),
82792
84788
  error: string().optional()
82793
84789
  }), { kind: "mutation" }),
82794
- frigatePlusListModels: customAction(_void(), array(FrigatePlusModelSchema).readonly()),
82795
- importFrigatePlusModel: customAction(object({
84790
+ plusCatalogPlusListModels: customAction(_void(), array(PlusCatalogModelSchema).readonly()),
84791
+ importPlusCatalogModel: customAction(object({
82796
84792
  plusModelId: string(),
82797
- /** Ignored for identity — registry id is always `frigate-plus-<plusModelId>`. */
84793
+ /** Ignored for identity — registry id is always `plus-catalog-<plusModelId>`. */
82798
84794
  modelId: string().optional(),
82799
84795
  name: string().optional(),
82800
84796
  /**
@@ -82919,7 +84915,7 @@ function spawnRunConvert(jobPath, pythonPath, onProgress, _sessionId) {
82919
84915
  function nameOriginOf(operatorName) {
82920
84916
  return operatorName !== void 0 ? { nameOrigin: "operator" } : {};
82921
84917
  }
82922
- /** Global-fetch adapter for the injected Frigate+ client seam. */
84918
+ /** Global-fetch adapter for the injected plus catalog client seam. */
82923
84919
  var plusFetch = async (url, init) => fetch(url, init);
82924
84920
  var ModelStudioAddon = class ModelStudioAddon extends BaseAddon {
82925
84921
  id = "model-studio";
@@ -82945,17 +84941,17 @@ var ModelStudioAddon = class ModelStudioAddon extends BaseAddon {
82945
84941
  section: "detection"
82946
84942
  }];
82947
84943
  constructor() {
82948
- super({ frigatePlusApiKey: "" });
84944
+ super({ plusCatalogPlusApiKey: "" });
82949
84945
  }
82950
84946
  globalSettingsSchema() {
82951
84947
  return this.schema({ sections: [{
82952
84948
  id: "frigate-plus",
82953
- title: "Frigate+",
82954
- description: "Credentials for importing your personal Frigate+ models. Create an API key in your Frigate+ account (https://plus.frigate.video → Settings → API keys; see docs.frigate.video/integrations/plus). The key is used only server-side against api.frigate.video and is never sent to the browser.",
84949
+ title: "plus catalog",
84950
+ description: "Credentials for importing your personal plus catalog models. Create an API key in your plus catalog account (https://plus.frigate.video → Settings → API keys; see docs.frigate.video/integrations/plus). The key is used only server-side against api.frigate.video and is never sent to the browser.",
82955
84951
  fields: [{
82956
84952
  type: "password",
82957
- key: "frigatePlusApiKey",
82958
- label: "Frigate+ API key",
84953
+ key: "plusCatalogPlusApiKey",
84954
+ label: "plus catalog API key",
82959
84955
  description: "Shape: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:40-hex-chars",
82960
84956
  showToggle: true
82961
84957
  }]
@@ -83065,7 +85061,7 @@ var ModelStudioAddon = class ModelStudioAddon extends BaseAddon {
83065
85061
  await this.pruneOrphanAvailability_();
83066
85062
  return this.availability_.get();
83067
85063
  },
83068
- listFrigateCatalog: async () => FRIGATE_PUBLIC_CATALOG.map((c) => ({
85064
+ listPlusCatalogCatalog: async () => PLUS_CATALOG_PUBLIC_CATALOG.map((c) => ({
83069
85065
  id: c.id,
83070
85066
  label: c.label,
83071
85067
  format: c.format,
@@ -83073,9 +85069,9 @@ var ModelStudioAddon = class ModelStudioAddon extends BaseAddon {
83073
85069
  inputSize: c.inputSize,
83074
85070
  notes: c.notes
83075
85071
  })),
83076
- importFrigateCatalogModel: async (input) => this.importFrigateCatalogModel(input),
83077
- listScryptedCatalog: async () => this.listScryptedCatalog(),
83078
- importScryptedCatalogModel: async (input) => this.importScryptedCatalogFromManifest(input),
85072
+ importPlusCatalogCatalogModel: async (input) => this.importPlusCatalogCatalogModel(input),
85073
+ listPluginCatalogCatalog: async () => this.listPluginCatalogCatalog(),
85074
+ importPluginCatalogCatalogModel: async (input) => this.importPluginCatalogCatalogFromManifest(input),
83079
85075
  tfliteSupport: async () => {
83080
85076
  const api = this.ctx.api;
83081
85077
  if (!api) return { nodes: [] };
@@ -83086,16 +85082,16 @@ var ModelStudioAddon = class ModelStudioAddon extends BaseAddon {
83086
85082
  } catch {}
83087
85083
  return { nodes: supported };
83088
85084
  },
83089
- frigatePlusStatus: async () => {
83090
- const key = this.config.frigatePlusApiKey ?? "";
85085
+ plusCatalogPlusStatus: async () => {
85086
+ const key = this.config.plusCatalogPlusApiKey ?? "";
83091
85087
  return {
83092
85088
  configured: key.length > 0,
83093
85089
  keyFormatValid: isValidPlusApiKey(key)
83094
85090
  };
83095
85091
  },
83096
- frigatePlusTest: async () => {
85092
+ plusCatalogPlusTest: async () => {
83097
85093
  try {
83098
- await fetchPlusAccessToken(plusFetch, this.config.frigatePlusApiKey ?? "");
85094
+ await fetchPlusAccessToken(plusFetch, this.config.plusCatalogPlusApiKey ?? "");
83099
85095
  return { ok: true };
83100
85096
  } catch (err) {
83101
85097
  return {
@@ -83104,8 +85100,8 @@ var ModelStudioAddon = class ModelStudioAddon extends BaseAddon {
83104
85100
  };
83105
85101
  }
83106
85102
  },
83107
- frigatePlusListModels: async () => listPlusModels(plusFetch, this.config.frigatePlusApiKey ?? ""),
83108
- importFrigatePlusModel: async (input) => this.importFrigatePlusModel(input),
85103
+ plusCatalogPlusListModels: async () => listPlusModels(plusFetch, this.config.plusCatalogPlusApiKey ?? ""),
85104
+ importPlusCatalogModel: async (input) => this.importPlusCatalogModel(input),
83109
85105
  recommendConvertNode: async (input) => {
83110
85106
  const api = this.ctx.api;
83111
85107
  if (!api) throw new Error("recommendConvertNode: ctx.api unavailable");
@@ -83292,7 +85288,7 @@ var ModelStudioAddon = class ModelStudioAddon extends BaseAddon {
83292
85288
  };
83293
85289
  }
83294
85290
  /** listNodes/hardwareOf deps for `recommendConvertNode` — shared by the
83295
- * convert actions and the Frigate+ auto-conversion. */
85291
+ * convert actions and the plus catalog auto-conversion. */
83296
85292
  recommendDeps() {
83297
85293
  const api = this.ctx.api;
83298
85294
  if (!api) throw new Error("model-studio: ctx.api unavailable");
@@ -83324,21 +85320,21 @@ var ModelStudioAddon = class ModelStudioAddon extends BaseAddon {
83324
85320
  return hash.digest("hex");
83325
85321
  }
83326
85322
  /**
83327
- * Projection of the local Scrypted YOLO manifesto plus a read-only HF drift
85323
+ * Projection of the local plugin catalog YOLO manifesto plus a read-only HF drift
83328
85324
  * check. Network errors become `unavailable` rows — the manifesto is never
83329
85325
  * mutated and nothing is auto-imported.
83330
85326
  */
83331
- async listScryptedCatalog() {
85327
+ async listPluginCatalogCatalog() {
83332
85328
  try {
83333
85329
  return {
83334
- entries: SCRYPTED_YOLO_MANIFEST,
83335
- drift: compareScryptedManifestDrift(SCRYPTED_YOLO_MANIFEST, await fetchScryptedRemoteTree({ fetchImpl: fetch })).map(normalizeScryptedDrift)
85330
+ entries: PLUGIN_CATALOG_YOLO_MANIFEST,
85331
+ drift: comparePluginCatalogManifestDrift(PLUGIN_CATALOG_YOLO_MANIFEST, await fetchPluginCatalogRemoteTree({ fetchImpl: fetch })).map(normalizePluginCatalogDrift)
83336
85332
  };
83337
85333
  } catch (err) {
83338
85334
  const details = err instanceof Error ? err.message : "Hugging Face tree unavailable";
83339
85335
  return {
83340
- entries: SCRYPTED_YOLO_MANIFEST,
83341
- drift: SCRYPTED_YOLO_MANIFEST.map((entry) => ({
85336
+ entries: PLUGIN_CATALOG_YOLO_MANIFEST,
85337
+ drift: PLUGIN_CATALOG_YOLO_MANIFEST.map((entry) => ({
83342
85338
  manifestId: entry.id,
83343
85339
  status: "unavailable",
83344
85340
  details
@@ -83351,15 +85347,15 @@ var ModelStudioAddon = class ModelStudioAddon extends BaseAddon {
83351
85347
  * stay server-owned. Artifacts are NOT staged on the hub — optional
83352
85348
  * `targetNodeId` lands the HF URL on that node via download-on-target.
83353
85349
  */
83354
- async importScryptedCatalogFromManifest(input) {
85350
+ async importPluginCatalogCatalogFromManifest(input) {
83355
85351
  const name = optionalImportName(input.name);
83356
- const entry = getScryptedManifestEntry(input.manifestId);
83357
- if (!entry) throw new Error(`importScryptedCatalogModel: unknown manifest id "${input.manifestId}"`);
85352
+ const entry = getPluginCatalogManifestEntry(input.manifestId);
85353
+ if (!entry) throw new Error(`importPluginCatalogCatalogModel: unknown manifest id "${input.manifestId}"`);
83358
85354
  let drift;
83359
85355
  try {
83360
- const tree = await fetchScryptedRemoteTree({ fetchImpl: fetch });
83361
- const row = compareScryptedManifestDrift(SCRYPTED_YOLO_MANIFEST.filter((e) => e.id === input.manifestId), tree)[0];
83362
- drift = normalizeScryptedDrift(row ?? {
85356
+ const tree = await fetchPluginCatalogRemoteTree({ fetchImpl: fetch });
85357
+ const row = comparePluginCatalogManifestDrift(PLUGIN_CATALOG_YOLO_MANIFEST.filter((e) => e.id === input.manifestId), tree)[0];
85358
+ drift = normalizePluginCatalogDrift(row ?? {
83363
85359
  manifestId: input.manifestId,
83364
85360
  status: "missing",
83365
85361
  details: "entry missing from manifesto"
@@ -83371,8 +85367,8 @@ var ModelStudioAddon = class ModelStudioAddon extends BaseAddon {
83371
85367
  details: err instanceof Error ? err.message : "Hugging Face tree unavailable"
83372
85368
  };
83373
85369
  }
83374
- if (drift.status !== "ok") throw new Error(`importScryptedCatalogModel: entry "${entry.id}" is blocked by drift (${drift.status}${drift.details ? `: ${drift.details}` : ""})`);
83375
- const built = buildScryptedRegistryDescriptor(entry);
85370
+ if (drift.status !== "ok") throw new Error(`importPluginCatalogCatalogModel: entry "${entry.id}" is blocked by drift (${drift.status}${drift.details ? `: ${drift.details}` : ""})`);
85371
+ const built = buildPluginCatalogRegistryDescriptor(entry);
83376
85372
  const descriptor = name !== void 0 ? {
83377
85373
  stepId: built.stepId,
83378
85374
  entry: {
@@ -83386,7 +85382,7 @@ var ModelStudioAddon = class ModelStudioAddon extends BaseAddon {
83386
85382
  nodeId: input.targetNodeId,
83387
85383
  format: entry.format
83388
85384
  });
83389
- this.ctx.logger.info("Registered Scrypted catalog model", { meta: {
85385
+ this.ctx.logger.info("Registered plugin catalog catalog model", { meta: {
83390
85386
  manifestId: input.manifestId,
83391
85387
  modelId: descriptor.entry.id,
83392
85388
  format: entry.format,
@@ -83395,15 +85391,15 @@ var ModelStudioAddon = class ModelStudioAddon extends BaseAddon {
83395
85391
  return descriptor;
83396
85392
  }
83397
85393
  /**
83398
- * Register a curated PUBLIC Frigate catalog model into the Library. The
85394
+ * Register a curated PUBLIC plus catalog catalog model into the Library. The
83399
85395
  * entry keeps its public URL — no hub staging. Optional `targetNodeId`
83400
85396
  * downloads on that node (same path as Library → Distribute).
83401
85397
  */
83402
- async importFrigateCatalogModel(input) {
83403
- const cat = FRIGATE_PUBLIC_CATALOG.find((c) => c.id === input.catalogId);
83404
- if (!cat) throw new Error(`importFrigateCatalogModel: unknown catalog id "${input.catalogId}"`);
85398
+ async importPlusCatalogCatalogModel(input) {
85399
+ const cat = PLUS_CATALOG_PUBLIC_CATALOG.find((c) => c.id === input.catalogId);
85400
+ if (!cat) throw new Error(`importPlusCatalogCatalogModel: unknown catalog id "${input.catalogId}"`);
83405
85401
  const name = optionalImportName(input.name);
83406
- const descriptor = buildFrigateCatalogDescriptor(input.catalogId, {
85402
+ const descriptor = buildPlusCatalogCatalogDescriptor(input.catalogId, {
83407
85403
  ...input.modelId !== void 0 ? { modelId: input.modelId } : {},
83408
85404
  ...name !== void 0 ? { name } : {}
83409
85405
  });
@@ -83417,7 +85413,7 @@ var ModelStudioAddon = class ModelStudioAddon extends BaseAddon {
83417
85413
  });
83418
85414
  bytes = landed.bytes > 0 ? landed.bytes : bytes;
83419
85415
  }
83420
- this.ctx.logger.info("Registered Frigate catalog model", { meta: {
85416
+ this.ctx.logger.info("Registered plus catalog catalog model", { meta: {
83421
85417
  catalogId: input.catalogId,
83422
85418
  modelId: descriptor.entry.id,
83423
85419
  ...input.targetNodeId !== void 0 ? { targetNodeId: input.targetNodeId } : {},
@@ -83430,22 +85426,22 @@ var ModelStudioAddon = class ModelStudioAddon extends BaseAddon {
83430
85426
  };
83431
85427
  }
83432
85428
  /**
83433
- * Import one of the operator's personal Frigate+ models: resolve metadata +
85429
+ * Import one of the operator's personal plus catalog models: resolve metadata +
83434
85430
  * presigned URL with the SECRET key (server-side only), download into the
83435
85431
  * hub's modelsDir, and register with the model-type-derived characteristics
83436
85432
  * (format, decode, input size, labelmap — nothing hand-typed). The artifact
83437
85433
  * is hub-local: other nodes get it via Models → Distribute.
83438
85434
  */
83439
- async importFrigatePlusModel(input) {
83440
- const modelId = frigatePlusRegistryId(input.plusModelId);
85435
+ async importPlusCatalogModel(input) {
85436
+ const modelId = plusCatalogPlusRegistryId(input.plusModelId);
83441
85437
  const operatorName = optionalImportName(input.name);
83442
- const key = this.config.frigatePlusApiKey ?? "";
85438
+ const key = this.config.plusCatalogPlusApiKey ?? "";
83443
85439
  const { info, downloadUrl } = await requestPlusModelDownload(plusFetch, key, input.plusModelId);
83444
85440
  let decode;
83445
85441
  try {
83446
85442
  decode = resolvePlusDecode(info, input.format);
83447
85443
  } catch (err) {
83448
- if (err instanceof UnsupportedPlusDecodeError) this.ctx.logger.warn("Frigate+ model import refused — no decoder", { meta: {
85444
+ if (err instanceof UnsupportedPlusDecodeError) this.ctx.logger.warn("plus catalog model import refused — no decoder", { meta: {
83449
85445
  plusModelId: input.plusModelId,
83450
85446
  type: err.type,
83451
85447
  format: err.format,
@@ -83460,12 +85456,12 @@ var ModelStudioAddon = class ModelStudioAddon extends BaseAddon {
83460
85456
  const bytes = (await fs.promises.stat(destPath)).size;
83461
85457
  if (bytes < 1e4) {
83462
85458
  await fs.promises.rm(destPath, { force: true });
83463
- throw new Error(`importFrigatePlusModel: downloaded only ${bytes} bytes — the signed URL likely expired or the response was an error page`);
85459
+ throw new Error(`importPlusCatalogModel: downloaded only ${bytes} bytes — the signed URL likely expired or the response was an error page`);
83464
85460
  }
83465
85461
  const sha256 = await ModelStudioAddon.fileSha256(destPath);
83466
85462
  const descriptor = plusInfoToDescriptor(info, {
83467
85463
  modelId,
83468
- name: operatorName ?? `Frigate+ ${info.type} (${input.plusModelId.slice(0, 8)})`,
85464
+ name: operatorName ?? `plus catalog ${info.type} (${input.plusModelId.slice(0, 8)})`,
83469
85465
  filename,
83470
85466
  sizeMB: Number((bytes / 1e6).toFixed(1)),
83471
85467
  ...input.format !== void 0 ? { format: input.format } : {}
@@ -83480,7 +85476,7 @@ var ModelStudioAddon = class ModelStudioAddon extends BaseAddon {
83480
85476
  bytes,
83481
85477
  at: Date.now()
83482
85478
  }));
83483
- this.ctx.logger.info("Imported Frigate+ model", { meta: {
85479
+ this.ctx.logger.info("Imported plus catalog model", { meta: {
83484
85480
  plusModelId: input.plusModelId,
83485
85481
  modelId,
83486
85482
  type: info.type,
@@ -83491,7 +85487,7 @@ var ModelStudioAddon = class ModelStudioAddon extends BaseAddon {
83491
85487
  let conversions = [];
83492
85488
  if (decode.format === "onnx" && wanted.length > 0) {
83493
85489
  conversions = (await ensureEngineFormats(descriptor.entry, this.plusConversionDeps(async () => (await requestPlusModelDownload(plusFetch, key, input.plusModelId)).downloadUrl, descriptor.stepId), { targetFormats: wanted })).conversions;
83494
- this.ctx.logger.info("Frigate+ import — engine conversions", { meta: {
85490
+ this.ctx.logger.info("plus catalog import — engine conversions", { meta: {
83495
85491
  modelId,
83496
85492
  outcomes: conversions.map((o) => ({ ...o }))
83497
85493
  } });