@camera.ui/server 2.1.2 → 2.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/interface/assets/{404-pb2fRn1r.js → 404-6v3-U7nj.js} +1 -1
- package/dist/interface/assets/{About-eljMnDub.js → About-IMZSnCy7.js} +1 -1
- package/dist/interface/assets/{Adminpanel-BtQdiyre.js → Adminpanel-jq9sK1Ey.js} +1 -1
- package/dist/interface/assets/{Automation-DOiLJcU_.js → Automation-xs_GEpGx.js} +3 -3
- package/dist/interface/assets/{AutomationImport-DflZNRBB.js → AutomationImport-CR4fWWkU.js} +2 -2
- package/dist/interface/assets/{AutomationStore-qF_NTNUf.js → AutomationStore-rB-eVXdY.js} +2 -2
- package/dist/interface/assets/{AutomationStoreDetail-CUw-jBBR.js → AutomationStoreDetail-DzMg8IOO.js} +2 -2
- package/dist/interface/assets/Automations-DWI8Q2TS.js +2 -0
- package/dist/interface/assets/Camera-BIppnvyN.js +2 -0
- package/dist/interface/assets/Camera-BfMZmurS.css +1 -0
- package/dist/interface/assets/{CameraConsole-CEARcJYc.js → CameraConsole-CQLrlDvb.js} +2 -2
- package/dist/interface/assets/{Cameras-C0oHuoTR.js → Cameras-kIN6bWi1.js} +2 -2
- package/dist/interface/assets/Camview-4jdGGny8.js +1 -0
- package/dist/interface/assets/Camview-UCj_OW0s.css +1 -0
- package/dist/interface/assets/Config-DxYeS7cY.js +2 -0
- package/dist/interface/assets/{ConfigActionCameraControl-De0qb88r.js → ConfigActionCameraControl-Biu5BwNu.js} +1 -1
- package/dist/interface/assets/{ConfigActionDelay-nDK4i-AL.js → ConfigActionDelay-CK5j4XLw.js} +1 -1
- package/dist/interface/assets/{ConfigActionHttp-DX-vapgv.js → ConfigActionHttp-Dtvi3jZB.js} +1 -1
- package/dist/interface/assets/{ConfigActionImageInput-CS7U7BsI.js → ConfigActionImageInput-Dh0A20j9.js} +1 -1
- package/dist/interface/assets/{ConfigActionMqtt-82swCx_F.js → ConfigActionMqtt-DwZdnDlb.js} +1 -1
- package/dist/interface/assets/{ConfigActionNotification-t-1zN_1y.js → ConfigActionNotification-BVqYxGu8.js} +1 -1
- package/dist/interface/assets/{ConfigActionNotificationControl-jz3ez2Uq.js → ConfigActionNotificationControl-BTdnQqox.js} +1 -1
- package/dist/interface/assets/{ConfigActionOutput-B6uJheX1.js → ConfigActionOutput-Dv745ppL.js} +1 -1
- package/dist/interface/assets/{ConfigActionPlugin-LyOIrZnv.js → ConfigActionPlugin-C9QdPDXC.js} +1 -1
- package/dist/interface/assets/{ConfigActionSensor-BTqc1inw.js → ConfigActionSensor-D17wASao.js} +1 -1
- package/dist/interface/assets/{ConfigActionSnapshot-DdPy_Ubu.js → ConfigActionSnapshot-CrbMLwuh.js} +1 -1
- package/dist/interface/assets/{ConfigActionVariable-Csf7jPOm.js → ConfigActionVariable-C0HobSMN.js} +1 -1
- package/dist/interface/assets/{ConfigConditionIfElse-BvzwZ70p.js → ConfigConditionIfElse-DsedkGhY.js} +1 -1
- package/dist/interface/assets/ConfigConditionSensorState-rRLbA2_b.js +1 -0
- package/dist/interface/assets/{ConfigConditionSwitch-DJU2JC-3.js → ConfigConditionSwitch-5nEVS-Oj.js} +1 -1
- package/dist/interface/assets/{ConfigConditionTime-BxE2CJMA.js → ConfigConditionTime-CieLn-sp.js} +1 -1
- package/dist/interface/assets/ConfigSensorValueInput-CRRM_aBz.js +1 -0
- package/dist/interface/assets/{ConfigTriggerDetection-DpC8V8K8.js → ConfigTriggerDetection-CMVgejZ3.js} +1 -1
- package/dist/interface/assets/{ConfigTriggerGeofence-DTzax7bc.js → ConfigTriggerGeofence-cMhyndiz.js} +1 -1
- package/dist/interface/assets/{ConfigTriggerManual-CtjnnQb1.js → ConfigTriggerManual-Bd9H0AfP.js} +1 -1
- package/dist/interface/assets/{ConfigTriggerMqtt-C7J22EMe.js → ConfigTriggerMqtt-BIv5Ca91.js} +1 -1
- package/dist/interface/assets/{ConfigTriggerSchedule-DnYDDz3F.js → ConfigTriggerSchedule-CzWWcnFW.js} +1 -1
- package/dist/interface/assets/ConfigTriggerSensor-C5lsyxsh.js +1 -0
- package/dist/interface/assets/{ConfigTriggerSystem-D1JulYVd.js → ConfigTriggerSystem-WipCRwTJ.js} +1 -1
- package/dist/interface/assets/{ConfigTriggerWebhook-BrKFtq7o.js → ConfigTriggerWebhook-Bl0O4RBX.js} +1 -1
- package/dist/interface/assets/Console-GtK0GVLX.js +1 -0
- package/dist/interface/assets/CuiAutomationRunsDialog-CUPBuq_J.js +1 -0
- package/dist/interface/assets/CuiBottomSheet-DQNpk0mh.js +1 -0
- package/dist/interface/assets/{CuiBottomSheet-C_1_moNo.js → CuiBottomSheet-K19nZQiG.js} +1 -1
- package/dist/interface/assets/CuiCameraPipCard-e3_uYELi.js +1 -0
- package/dist/interface/assets/CuiCameraRecordings-CPAMltfx.js +1 -0
- package/dist/interface/assets/CuiCameraRecordings-fB3X6kad.css +1 -0
- package/dist/interface/assets/{CuiCameraShares-XwN5kuC7.js → CuiCameraShares-BTn5ys6X.js} +1 -1
- package/dist/interface/assets/{CuiCameraTable-BeeHLaiQ.js → CuiCameraTable-DYvQ-GCz.js} +2 -2
- package/dist/interface/assets/{CuiConsole-B7R7U9UZ.js → CuiConsole-C4PawCou.js} +2 -2
- package/dist/interface/assets/{CuiDataTable-CQhCu0px.js → CuiDataTable-CORQOWsf.js} +1 -1
- package/dist/interface/assets/CuiLightControl-BYkQ8Ue3.js +1 -0
- package/dist/interface/assets/CuiList-BgZBIhXP.js +1 -0
- package/dist/interface/assets/CuiMarkdownContent-CCdOW_TM.js +1 -0
- package/dist/interface/assets/CuiMarkdownContent-ChezqgI1.js +1 -0
- package/dist/interface/assets/{CuiPluginCard-rkhmuumi.css → CuiPluginCard-C3ANAXSI.css} +1 -1
- package/dist/interface/assets/CuiPluginCard-C91rKOge.js +2 -0
- package/dist/interface/assets/{CuiPluginCategoryChip-JkdbQU4X.js → CuiPluginCategoryChip-B_Zy4B42.js} +1 -1
- package/dist/interface/assets/{CuiPluginOAuthButton-LYMFfb3v.js → CuiPluginOAuthButton-IXGedGWs.js} +2 -2
- package/dist/interface/assets/{CuiPluginTrustBadge-sZF0UKMD.js → CuiPluginTrustBadge-DTfM8Jjo.js} +1 -1
- package/dist/interface/assets/{CuiQRCode-B4ysluWR.js → CuiQRCode-D5vwhyuQ.js} +1 -1
- package/dist/interface/assets/CuiRecordingsGrid-Sv3uyj9a.css +1 -0
- package/dist/interface/assets/CuiRecordingsGrid-yXEzhnc4.js +1 -0
- package/dist/interface/assets/CuiSchema-hK_tgUP9.js +1 -0
- package/dist/interface/assets/{CuiTopNavbarItem-rMsWME9B.js → CuiTopNavbarItem-DWLnn7Kh.js} +1 -1
- package/dist/interface/assets/Faces-DzwTi8P1.js +1 -0
- package/dist/interface/assets/FirstSteps-0ojmFGSr.js +1 -0
- package/dist/interface/assets/Instances-DvoFBGMx.js +1 -0
- package/dist/interface/assets/{Logs-8onUmCYX.js → Logs-Cii4oP8R.js} +2 -2
- package/dist/interface/assets/Menu-pvtuFKFM.js +1 -0
- package/dist/interface/assets/OAuthDeviceFlow-BZgtsIjF.js +1 -0
- package/dist/interface/assets/Plugin-BDqNeTCT.css +1 -0
- package/dist/interface/assets/Plugin-BKqpBWJy.js +1 -0
- package/dist/interface/assets/{PluginConsole-JFcH_ZW0.js → PluginConsole-BFsCogtB.js} +1 -1
- package/dist/interface/assets/PluginDetail-Dl0OM6me.js +2 -0
- package/dist/interface/assets/{PluginSchema-Gfn_csMP.js → PluginSchema-D45zblVz.js} +1 -1
- package/dist/interface/assets/PluginSearch-DdIcv9xA.js +1 -0
- package/dist/interface/assets/{PluginSearch-CLjLT9JT.css → PluginSearch-Dlzc-aJ3.css} +1 -1
- package/dist/interface/assets/PluginSearch-DxoQUW8M.js +2 -0
- package/dist/interface/assets/{PluginUpdateProgress-DaI9bwSV.js → PluginUpdateProgress-CsRGGH8J.js} +1 -1
- package/dist/interface/assets/Plugins-CGj8DSLJ.js +1 -0
- package/dist/interface/assets/Recordings-PojBH8L3.js +1 -0
- package/dist/interface/assets/SensorEdit-D2ChsNDL.js +1 -0
- package/dist/interface/assets/{SensorHistory-2TmYLaL4.js → SensorHistory-B6ZKgot4.js} +1 -1
- package/dist/interface/assets/Sensors-B-Qhfr5i.css +1 -0
- package/dist/interface/assets/Sensors-DyqWcB-G.js +2 -0
- package/dist/interface/assets/{Settings-8yG5ny5r.js → Settings-BFJO08mq.js} +1 -1
- package/dist/interface/assets/SettingsAccount-DREZwvce.js +1 -0
- package/dist/interface/assets/SettingsAccount-QxmP0dzI.js +1 -0
- package/dist/interface/assets/SettingsAppearance-BejKI3_C.js +1 -0
- package/dist/interface/assets/{SettingsAppearance-WQtOksbk.js → SettingsAppearance-_zvMUQvn.js} +1 -1
- package/dist/interface/assets/SettingsBackup-8HCwVmDA.js +1 -0
- package/dist/interface/assets/SettingsList-B4H786Cc.js +1 -0
- package/dist/interface/assets/SettingsMqtt-D7ajm1JA.js +1 -0
- package/dist/interface/assets/{SettingsNotifications-BVGmt0eF.js → SettingsNotifications-fDDuqryh.js} +2 -2
- package/dist/interface/assets/{SettingsPermissions-BPqDIjVt.js → SettingsPermissions-DYirYf1Z.js} +1 -1
- package/dist/interface/assets/SettingsRecordings-4NxpAbu5.js +1 -0
- package/dist/interface/assets/SettingsRemote-DOQkaNzp.js +1 -0
- package/dist/interface/assets/SettingsSystem-CVWkw449.js +2 -0
- package/dist/interface/assets/{SettingsUsers-BtT17FNe.js → SettingsUsers-Dc6L7Lt2.js} +1 -1
- package/dist/interface/assets/Terminal-BgVnN-2g.js +4 -0
- package/dist/interface/assets/{VariableInput-CkXZ00Gc.js → VariableInput-ZYn-Phl4.js} +1 -1
- package/dist/interface/assets/{VariableSuggestions-BD1kOG5f.js → VariableSuggestions-BnzdQP6R.js} +1 -1
- package/dist/interface/assets/VersionsHandler-BvKvGOlF.js +7 -0
- package/dist/interface/assets/{VirtualSensorCreate-DcwJ_w-l.js → VirtualSensorCreate-Dk_YYzxR.js} +1 -1
- package/dist/interface/assets/Workers-CjEzGjy8.js +2 -0
- package/dist/interface/assets/{account-CY80SLLf.js → account-DuSFtIHf.js} +1 -1
- package/dist/interface/assets/{alert-circle-pDGfnZ4K.js → alert-circle-C2AU59aR.js} +1 -1
- package/dist/interface/assets/{alert-outline-CeoXcnQc.js → alert-outline-GrD7-zHq.js} +1 -1
- package/dist/interface/assets/{api-Mny5Elfn.js → api-36pS71R2.js} +1 -1
- package/dist/interface/assets/api-CDvtqu1L.css +2 -0
- package/dist/interface/assets/api-DTFsk1zB.js +2 -0
- package/dist/interface/assets/{arrow-left-D9jDhvK5.js → arrow-left-C1N6U6kZ.js} +1 -1
- package/dist/interface/assets/{arrow-right-outline-DF7tkKYk.js → arrow-right-outline-C24f5mwe.js} +1 -1
- package/dist/interface/assets/{auth-9_Jjlsh0.js → auth-DYoO8jpd.js} +1 -1
- package/dist/interface/assets/automations-BOvDlvvx.js +1 -0
- package/dist/interface/assets/{back-filled-DUUGErMw.js → back-filled-DcBDBvvP.js} +1 -1
- package/dist/interface/assets/{bell-ring-DV73JIre.js → bell-ring-DSX81yd4.js} +1 -1
- package/dist/interface/assets/cameras.schema-BvnUX82v.js +1 -0
- package/dist/interface/assets/{cctv-jy5ROx0o.js → cctv-BA5DvNlE.js} +1 -1
- package/dist/interface/assets/{check-circle-FwoylV5-.js → check-circle-Do_mBN_A.js} +1 -1
- package/dist/interface/assets/{chevron-down-umZ7i0mG.js → chevron-down-D111daTn.js} +1 -1
- package/dist/interface/assets/{clock-outline-CbvOAMhO.js → clock-outline-DF1wLNzs.js} +1 -1
- package/dist/interface/assets/{close-CtaDF28n.js → close-BNAWPz0y.js} +1 -1
- package/dist/interface/assets/{close-circle-FZ8IxGd4.js → close-circle-zhDWvz98.js} +1 -1
- package/dist/interface/assets/{cloud-check-CFSukfAF.js → cloud-check-pUK1Fpt9.js} +1 -1
- package/dist/interface/assets/cloudHandoff-DNKMEHOI.js +1 -0
- package/dist/interface/assets/{config-BZphegxi.js → config-DTGhJmsj.js} +1 -1
- package/dist/interface/assets/{copy-CFA_pDRv.js → copy-BPT84cDt.js} +1 -1
- package/dist/interface/assets/{cube-scan-DEuMi23T.js → cube-scan-DOe6W9mW.js} +1 -1
- package/dist/interface/assets/{delete-921w_nKy.js → delete-BF6keuqy.js} +1 -1
- package/dist/interface/assets/{deployed-code-update-CYS6eKfa.js → deployed-code-update-xHE-blDN.js} +1 -1
- package/dist/interface/assets/{dist-BwEXwXSw.js → dist-Yc5s0_JB.js} +1 -1
- package/dist/interface/assets/{download-C-LzNRmM.js → download-BCPfm6aN.js} +1 -1
- package/dist/interface/assets/esm-B3yVlCMw.js +1 -0
- package/dist/interface/assets/esm-BKQ7CQK7.js +1 -0
- package/dist/interface/assets/esm-BiSE05P9.js +1 -0
- package/dist/interface/assets/esm-BoPthGAl.js +1 -0
- package/dist/interface/assets/esm-C2ALrdyx.js +1 -0
- package/dist/interface/assets/esm-CKEGzys4.js +1 -0
- package/dist/interface/assets/esm-CctiCHtK.js +1 -0
- package/dist/interface/assets/esm-Cqq81lnk.js +1 -0
- package/dist/interface/assets/esm-CyrLQTu0.js +1 -0
- package/dist/interface/assets/esm-D6O-eZYo.js +1 -0
- package/dist/interface/assets/esm-DG1f0qwo.js +1 -0
- package/dist/interface/assets/esm-DGegIZMF.js +1 -0
- package/dist/interface/assets/esm-JGwpHVqo.js +1 -0
- package/dist/interface/assets/esm-TRigYTsA.js +1 -0
- package/dist/interface/assets/{eye-off-DESV3QdF.js → eye-off-CaRq7Ks2.js} +1 -1
- package/dist/interface/assets/{flowSchema-_RiPAgMv.js → flowSchema-zo1H4tnP.js} +1 -1
- package/dist/interface/assets/{history-60iCpGvQ.js → history-SuH8IHAj.js} +1 -1
- package/dist/interface/assets/{home-w5iY2RUg.js → home-CUykMSBW.js} +1 -1
- package/dist/interface/assets/{information-outline-CvBsGtDu.js → information-outline-BQDq8w2t.js} +1 -1
- package/dist/interface/assets/{lightbulb-outline-DLrnCPG5.js → lightbulb-outline-ClK17CO6.js} +1 -1
- package/dist/interface/assets/main-CcvCf5qj.js +3 -0
- package/dist/interface/assets/{main-DJb49Tjp.css → main-XQ5Vahbs.css} +1 -1
- package/dist/interface/assets/{microphone-DUVI-s2_.js → microphone-C0weJY9W.js} +1 -1
- package/dist/interface/assets/minus-RI3VlDe8.js +1 -0
- package/dist/interface/assets/mqtt-CYc8_9pb.js +1 -0
- package/dist/interface/assets/native-B01iGjCh.js +1 -0
- package/dist/interface/assets/native-D381pxlG.js +1 -0
- package/dist/interface/assets/{nodeDefinitions-BecZ8I2Q.js → nodeDefinitions-DQQlFmPN.js} +1 -1
- package/dist/interface/assets/{notifications-CK6XQBF-.js → notifications-cHS8-1HN.js} +1 -1
- package/dist/interface/assets/{pencil-outline-BrOrbuzc.js → pencil-outline-D7aD4cCo.js} +1 -1
- package/dist/interface/assets/plugin-W20ihuog.js +1 -0
- package/dist/interface/assets/plugins-CaKErv4E.js +1 -0
- package/dist/interface/assets/{plus-Dd-XLT76.js → plus-CA5o30dE.js} +1 -1
- package/dist/interface/assets/{plus-CL6KSxf8.js → plus-DHwFyXkb.js} +1 -1
- package/dist/interface/assets/{power-lCbm_7y7.js → power-C9UIp2oO.js} +1 -1
- package/dist/interface/assets/{ring-resize-CEqUkpxT.js → ring-resize-DkY5EgVl.js} +1 -1
- package/dist/interface/assets/{round-alt-arrow-left-bold-CwaLYdW5.js → round-alt-arrow-left-bold-BxX4ufd0.js} +1 -1
- package/dist/interface/assets/{round-restart-alt-BFgY3k77.js → round-restart-alt-DPYbDt-x.js} +1 -1
- package/dist/interface/assets/{search-CT2BLw7G.js → search-BZkSqZO5.js} +1 -1
- package/dist/interface/assets/sensorIcons-DepqfSoA.js +1 -0
- package/dist/interface/assets/sensors-CMpbwMO4.js +1 -0
- package/dist/interface/assets/{server-BSYs0zoo.js → server-C-WV93FX.js} +1 -1
- package/dist/interface/assets/{settings-CzS4dvIO.js → settings-BUEZ5iRE.js} +1 -1
- package/dist/interface/assets/{source-branch-C6p1G3a9.js → source-branch-ztDB0e13.js} +1 -1
- package/dist/interface/assets/{table-2-line-_VC4NuFA.js → table-2-line-B-z0xvbG.js} +1 -1
- package/dist/interface/assets/{theme-Dr_YO8-0.js → theme-BkwBz73p.js} +1 -1
- package/dist/interface/assets/{trash-2-DcOYT3oH.js → trash-2-DMMlSPXn.js} +1 -1
- package/dist/interface/assets/{trash-can-outline-cphfB8Jh.js → trash-can-outline-DLKniIWM.js} +1 -1
- package/dist/interface/assets/{trash-fill-CRBaUdPn.js → trash-fill-DevIK050.js} +1 -1
- package/dist/interface/assets/{trash2-CvhB8xOW.js → trash2-BLScx4HX.js} +1 -1
- package/dist/interface/assets/{types-3mdj4rRK.js → types-Cko7VOxd.js} +1 -1
- package/dist/interface/assets/types-ClTvDPjn.js +1 -0
- package/dist/interface/assets/{types-YwmhC3Ej.js → types-vaT6wuY0.js} +1 -1
- package/dist/interface/assets/{upload-DeN3O-ua.js → upload-ClkX9wUX.js} +1 -1
- package/dist/interface/assets/{useAppVersion-UIA6seZv.js → useAppVersion-V1S18l98.js} +1 -1
- package/dist/interface/assets/useBackupRestore-BZ73vHrV.js +1 -0
- package/dist/interface/assets/{useCameraOptions-Dx-zyqdH.js → useCameraOptions-o1hYGLbC.js} +1 -1
- package/dist/interface/assets/{useElectron-BXVcamD0.js → useElectron-3ZJLtRk3.js} +1 -1
- package/dist/interface/assets/{useLogsSocket-DSxzAvQF.js → useLogsSocket-DDgnQ_Dk.js} +1 -1
- package/dist/interface/assets/{usePermissions-B_C-zX5H.js → usePermissions-BWlj5SzG.js} +1 -1
- package/dist/interface/assets/{usePluginUpdates-QU3U82S_.js → usePluginUpdates-DI1p2NMc.js} +1 -1
- package/dist/interface/assets/{useServerRestart-BxDBO7k-.js → useServerRestart-D_ASBw_0.js} +1 -1
- package/dist/interface/assets/{useStreamStatus-DY4NM_Ua.js → useStreamStatus-BQJIFFLv.js} +1 -1
- package/dist/interface/assets/useUpdateChannel-CyLSUSAY.js +1 -0
- package/dist/interface/assets/useUserOptions-Ds1Ybn7N.js +1 -0
- package/dist/interface/assets/{variable-oLSsiEtj.js → variable-CCMnQpL2.js} +1 -1
- package/dist/interface/assets/{vendor-JQXDMBA-.js → vendor-BaiDFVEr.js} +17 -16
- package/dist/interface/assets/vendor-cameraui-CQTIVF_m.js +2326 -0
- package/dist/interface/assets/{vendor-capacitor-CDwgXF4b.js → vendor-capacitor-4nn-eF9U.js} +2 -2
- package/dist/interface/assets/{vendor-chart-KrNcA52y.js → vendor-chart-DtwjR6yw.js} +1 -1
- package/dist/interface/assets/vendor-core-DDtZhtY9.js +1 -0
- package/dist/interface/assets/{vendor-dnd-Jch9IvL6.js → vendor-dnd-ChrDrMuz.js} +1 -1
- package/dist/interface/assets/{vendor-draggabilly-Cn-knCpG.js → vendor-draggabilly-DSeIE_bQ.js} +1 -1
- package/dist/interface/assets/{vendor-markdown-BhFLJolW.js → vendor-markdown--U0EK8HV.js} +1 -1
- package/dist/interface/assets/{vendor-primevue-C0acGg0Y.js → vendor-primevue-DE-f4Z5f.js} +76 -76
- package/dist/interface/assets/{vendor-vueflow-DQrTmoNS.js → vendor-vueflow-CLJNLJXc.js} +1 -1
- package/dist/interface/assets/web-BNRwhIOt.js +1 -0
- package/dist/interface/assets/web-BPkOXv4d.js +1 -0
- package/dist/interface/assets/web-BZIx_2d3.js +1 -0
- package/dist/interface/assets/web-BjKL51lK-BwChM7zd.js +1 -0
- package/dist/interface/assets/web-BkmtZjSt.js +1 -0
- package/dist/interface/assets/web-C6RgriWz.js +1 -0
- package/dist/interface/assets/web-CQFMLa0a.js +1 -0
- package/dist/interface/assets/web-CZGnd6VE.js +1 -0
- package/dist/interface/assets/web-Cfzay11X.js +1 -0
- package/dist/interface/assets/web-DAgBwKL-.js +1 -0
- package/dist/interface/assets/web-DgVHh5ek.js +1 -0
- package/dist/interface/assets/web-DlSXwZBR.js +1 -0
- package/dist/interface/assets/web-eDYxVGH7.js +1 -0
- package/dist/interface/assets/web-h4k3EoRQ.js +1 -0
- package/dist/interface/assets/{webhook-CMAB4nTl.js → webhook-DQiZUPv8.js} +1 -1
- package/dist/interface/assets/workbox-window.prod.es5-CcJiPjAS.js +1 -0
- package/dist/interface/assets/{zoom-in-STm8SNt2.js → zoom-in-Du1IB9oA.js} +1 -1
- package/dist/interface/index.html +42 -41
- package/dist/interface/sw.js +1 -1
- package/dist/server/package.json +14 -14
- package/dist/server/requirements.txt +2 -2
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/__init__.py +6 -0
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/camera/__init__.py +0 -2
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/camera/events.py +11 -47
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/camera/frames.py +2 -4
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/internal/sensor_rpc.py +6 -0
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/plugin/contract.py +1 -1
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/plugin/notifier.py +7 -0
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/base.py +18 -1
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/classifier.py +14 -8
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/face.py +23 -7
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/license_plate.py +23 -7
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/storage/__init__.py +60 -2
- package/dist/server/src/api/controllers/automations.controller.d.ts +3 -1
- package/dist/server/src/api/controllers/automations.controller.js +27 -0
- package/dist/server/src/api/controllers/automations.controller.js.map +1 -1
- package/dist/server/src/api/controllers/cameras.controller.d.ts +3 -2
- package/dist/server/src/api/controllers/cameras.controller.js +26 -1
- package/dist/server/src/api/controllers/cameras.controller.js.map +1 -1
- package/dist/server/src/api/controllers/instances.controller.d.ts +2 -1
- package/dist/server/src/api/controllers/instances.controller.js +9 -0
- package/dist/server/src/api/controllers/instances.controller.js.map +1 -1
- package/dist/server/src/api/controllers/nvr.controller.d.ts +0 -3
- package/dist/server/src/api/controllers/nvr.controller.js +8 -38
- package/dist/server/src/api/controllers/nvr.controller.js.map +1 -1
- package/dist/server/src/api/controllers/plugins.controller.d.ts +9 -2
- package/dist/server/src/api/controllers/plugins.controller.js +156 -99
- package/dist/server/src/api/controllers/plugins.controller.js.map +1 -1
- package/dist/server/src/api/controllers/sensors.controller.d.ts +3 -1
- package/dist/server/src/api/controllers/sensors.controller.js +31 -0
- package/dist/server/src/api/controllers/sensors.controller.js.map +1 -1
- package/dist/server/src/api/database/index.d.ts +3 -2
- package/dist/server/src/api/database/index.js +12 -2
- package/dist/server/src/api/database/index.js.map +1 -1
- package/dist/server/src/api/database/migrations/v2-0-50.js +2 -1
- package/dist/server/src/api/database/migrations/v2-0-50.js.map +1 -1
- package/dist/server/src/api/database/migrations/v2-1-1.d.ts +3 -0
- package/dist/server/src/api/database/migrations/v2-1-1.js +35 -0
- package/dist/server/src/api/database/migrations/v2-1-1.js.map +1 -0
- package/dist/server/src/api/database/migrations/v2-1-4.d.ts +3 -0
- package/dist/server/src/api/database/migrations/v2-1-4.js +32 -0
- package/dist/server/src/api/database/migrations/v2-1-4.js.map +1 -0
- package/dist/server/src/api/database/record-schemas.d.ts +3 -0
- package/dist/server/src/api/database/record-schemas.js +1 -0
- package/dist/server/src/api/database/record-schemas.js.map +1 -1
- package/dist/server/src/api/database/types.d.ts +5 -0
- package/dist/server/src/api/routes/automations.routes.js +23 -1
- package/dist/server/src/api/routes/automations.routes.js.map +1 -1
- package/dist/server/src/api/routes/cameras.routes.js +15 -3
- package/dist/server/src/api/routes/cameras.routes.js.map +1 -1
- package/dist/server/src/api/routes/instances.routes.js +12 -1
- package/dist/server/src/api/routes/instances.routes.js.map +1 -1
- package/dist/server/src/api/routes/plugins.routes.js +36 -2
- package/dist/server/src/api/routes/plugins.routes.js.map +1 -1
- package/dist/server/src/api/routes/sensors.routes.js +23 -1
- package/dist/server/src/api/routes/sensors.routes.js.map +1 -1
- package/dist/server/src/api/schemas/automations.schema.d.ts +11 -0
- package/dist/server/src/api/schemas/automations.schema.js +7 -0
- package/dist/server/src/api/schemas/automations.schema.js.map +1 -1
- package/dist/server/src/api/schemas/cameras.schema.d.ts +33 -24
- package/dist/server/src/api/schemas/cameras.schema.js +18 -5
- package/dist/server/src/api/schemas/cameras.schema.js.map +1 -1
- package/dist/server/src/api/schemas/config.schema.d.ts +1 -0
- package/dist/server/src/api/schemas/config.schema.js +1 -0
- package/dist/server/src/api/schemas/config.schema.js.map +1 -1
- package/dist/server/src/api/schemas/instances.schema.d.ts +4 -0
- package/dist/server/src/api/schemas/instances.schema.js +3 -0
- package/dist/server/src/api/schemas/instances.schema.js.map +1 -1
- package/dist/server/src/api/schemas/plugins.schema.d.ts +11 -0
- package/dist/server/src/api/schemas/plugins.schema.js +6 -0
- package/dist/server/src/api/schemas/plugins.schema.js.map +1 -1
- package/dist/server/src/api/schemas/sensors.schema.d.ts +11 -0
- package/dist/server/src/api/schemas/sensors.schema.js +7 -0
- package/dist/server/src/api/schemas/sensors.schema.js.map +1 -1
- package/dist/server/src/api/schemas/users.schema.d.ts +12 -0
- package/dist/server/src/api/schemas/users.schema.js +4 -0
- package/dist/server/src/api/schemas/users.schema.js.map +1 -1
- package/dist/server/src/api/services/auth.service.js +28 -23
- package/dist/server/src/api/services/auth.service.js.map +1 -1
- package/dist/server/src/api/services/automations.service.js +36 -36
- package/dist/server/src/api/services/automations.service.js.map +1 -1
- package/dist/server/src/api/services/backup.service.js +29 -26
- package/dist/server/src/api/services/backup.service.js.map +1 -1
- package/dist/server/src/api/services/backupScheduler.service.js +1 -2
- package/dist/server/src/api/services/backupScheduler.service.js.map +1 -1
- package/dist/server/src/api/services/cameras.service.js +222 -173
- package/dist/server/src/api/services/cameras.service.js.map +1 -1
- package/dist/server/src/api/services/instances.service.d.ts +7 -0
- package/dist/server/src/api/services/instances.service.js +17 -0
- package/dist/server/src/api/services/instances.service.js.map +1 -1
- package/dist/server/src/api/services/mqtt.service.js +1 -2
- package/dist/server/src/api/services/mqtt.service.js.map +1 -1
- package/dist/server/src/api/services/notifications.service.d.ts +1 -0
- package/dist/server/src/api/services/notifications.service.js +3 -0
- package/dist/server/src/api/services/notifications.service.js.map +1 -1
- package/dist/server/src/api/services/plugins.service.js +1 -1
- package/dist/server/src/api/services/plugins.service.js.map +1 -1
- package/dist/server/src/api/services/remote.service.js +26 -25
- package/dist/server/src/api/services/remote.service.js.map +1 -1
- package/dist/server/src/api/services/sensors.service.d.ts +1 -0
- package/dist/server/src/api/services/sensors.service.js +1 -0
- package/dist/server/src/api/services/sensors.service.js.map +1 -1
- package/dist/server/src/api/services/server.service.js +9 -7
- package/dist/server/src/api/services/server.service.js.map +1 -1
- package/dist/server/src/api/services/shares.service.js +19 -14
- package/dist/server/src/api/services/shares.service.js.map +1 -1
- package/dist/server/src/api/services/users.service.js +159 -105
- package/dist/server/src/api/services/users.service.js.map +1 -1
- package/dist/server/src/api/services/workers.service.d.ts +1 -0
- package/dist/server/src/api/services/workers.service.js +55 -45
- package/dist/server/src/api/services/workers.service.js.map +1 -1
- package/dist/server/src/api/types/index.d.ts +38 -5
- package/dist/server/src/api/types/index.js.map +1 -1
- package/dist/server/src/api/utils/bulk.d.ts +9 -0
- package/dist/server/src/api/utils/bulk.js +27 -0
- package/dist/server/src/api/utils/bulk.js.map +1 -0
- package/dist/server/src/api/utils/cert.js +8 -0
- package/dist/server/src/api/utils/cert.js.map +1 -1
- package/dist/server/src/api/websocket/nsp/server.js +1 -1
- package/dist/server/src/api/websocket/nsp/server.js.map +1 -1
- package/dist/server/src/automations/conditions/sensorState.js +9 -0
- package/dist/server/src/automations/conditions/sensorState.js.map +1 -1
- package/dist/server/src/camera/controller.d.ts +1 -1
- package/dist/server/src/camera/controller.js +12 -11
- package/dist/server/src/camera/controller.js.map +1 -1
- package/dist/server/src/camera/decoder/child.d.ts +1 -0
- package/dist/server/src/camera/decoder/child.js +14 -1
- package/dist/server/src/camera/decoder/child.js.map +1 -1
- package/dist/server/src/camera/decoder/debug/detection-record.d.ts +42 -0
- package/dist/server/src/camera/decoder/debug/detection-record.js +103 -0
- package/dist/server/src/camera/decoder/debug/detection-record.js.map +1 -0
- package/dist/server/src/camera/decoder/debug/perf-tracker.d.ts +20 -0
- package/dist/server/src/camera/decoder/debug/perf-tracker.js +82 -0
- package/dist/server/src/camera/decoder/debug/perf-tracker.js.map +1 -0
- package/dist/server/src/camera/decoder/detection-coordinator.d.ts +28 -6
- package/dist/server/src/camera/decoder/detection-coordinator.js +452 -76
- package/dist/server/src/camera/decoder/detection-coordinator.js.map +1 -1
- package/dist/server/src/camera/decoder/detection-pipeline.d.ts +7 -20
- package/dist/server/src/camera/decoder/detection-pipeline.js +67 -127
- package/dist/server/src/camera/decoder/detection-pipeline.js.map +1 -1
- package/dist/server/src/camera/decoder/event-manager.d.ts +42 -14
- package/dist/server/src/camera/decoder/event-manager.js +304 -217
- package/dist/server/src/camera/decoder/event-manager.js.map +1 -1
- package/dist/server/src/camera/decoder/event-thumbnailer.d.ts +5 -8
- package/dist/server/src/camera/decoder/event-thumbnailer.js +11 -21
- package/dist/server/src/camera/decoder/event-thumbnailer.js.map +1 -1
- package/dist/server/src/camera/decoder/frame-scaler.d.ts +2 -1
- package/dist/server/src/camera/decoder/frame-scaler.js +9 -0
- package/dist/server/src/camera/decoder/frame-scaler.js.map +1 -1
- package/dist/server/src/camera/decoder/moment-crop.d.ts +30 -0
- package/dist/server/src/camera/decoder/moment-crop.js +86 -0
- package/dist/server/src/camera/decoder/moment-crop.js.map +1 -0
- package/dist/server/src/camera/decoder/nvr-sink.d.ts +38 -0
- package/dist/server/src/camera/decoder/nvr-sink.js +36 -0
- package/dist/server/src/camera/decoder/nvr-sink.js.map +1 -0
- package/dist/server/src/camera/decoder/secondary-stage.d.ts +4 -2
- package/dist/server/src/camera/decoder/secondary-stage.js +58 -96
- package/dist/server/src/camera/decoder/secondary-stage.js.map +1 -1
- package/dist/server/src/camera/decoder/sources/analysis-source.d.ts +10 -0
- package/dist/server/src/camera/decoder/sources/analysis-source.js +2 -0
- package/dist/server/src/camera/decoder/sources/analysis-source.js.map +1 -0
- package/dist/server/src/camera/decoder/sources/{snapshot-source.d.ts → buffered-source.d.ts} +17 -5
- package/dist/server/src/camera/decoder/sources/{snapshot-source.js → buffered-source.js} +81 -24
- package/dist/server/src/camera/decoder/sources/buffered-source.js.map +1 -0
- package/dist/server/src/camera/decoder/sources/frame-source.d.ts +4 -7
- package/dist/server/src/camera/decoder/sources/frame-source.js +4 -7
- package/dist/server/src/camera/decoder/sources/frame-source.js.map +1 -1
- package/dist/server/src/camera/decoder/types.d.ts +1 -0
- package/dist/server/src/camera/decoder/types.js.map +1 -1
- package/dist/server/src/camera/decoder/worker.js +15 -3
- package/dist/server/src/camera/decoder/worker.js.map +1 -1
- package/dist/server/src/internal-bus.d.ts +1 -1
- package/dist/server/src/internal-bus.js.map +1 -1
- package/dist/server/src/main.js +1 -1
- package/dist/server/src/main.js.map +1 -1
- package/dist/server/src/manager/discoveryManager.js +0 -11
- package/dist/server/src/manager/discoveryManager.js.map +1 -1
- package/dist/server/src/manager/notificationManager.d.ts +1 -1
- package/dist/server/src/manager/notificationManager.js +60 -41
- package/dist/server/src/manager/notificationManager.js.map +1 -1
- package/dist/server/src/mqtt/bridge.d.ts +2 -0
- package/dist/server/src/mqtt/bridge.js +39 -35
- package/dist/server/src/mqtt/bridge.js.map +1 -1
- package/dist/server/src/plugins/nvr.d.ts +2 -0
- package/dist/server/src/plugins/nvr.js +17 -0
- package/dist/server/src/plugins/nvr.js.map +1 -0
- package/dist/server/src/plugins/runtime/node/proxy/sensorManager.js +1 -1
- package/dist/server/src/plugins/runtime/node/proxy/sensorManager.js.map +1 -1
- package/dist/server/src/plugins/runtime/python/storage.py +18 -1
- package/dist/server/src/plugins/runtime/python/store.py +7 -1
- package/dist/server/src/plugins/schema.d.ts +2 -1
- package/dist/server/src/plugins/schema.js +66 -6
- package/dist/server/src/plugins/schema.js.map +1 -1
- package/dist/server/src/plugins/store/storeFile.js +10 -2
- package/dist/server/src/plugins/store/storeFile.js.map +1 -1
- package/dist/server/src/remote/services/index.js +1 -1
- package/dist/server/src/remote/services/index.js.map +1 -1
- package/dist/server/src/rpc/interfaces/frameworker.d.ts +1 -0
- package/dist/server/src/rpc/interfaces/sensor.d.ts +2 -0
- package/dist/server/src/rpc/server.js +2 -0
- package/dist/server/src/rpc/server.js.map +1 -1
- package/dist/server/src/sensors/registry.js +7 -2
- package/dist/server/src/sensors/registry.js.map +1 -1
- package/dist/server/src/sensors/sensor.js +13 -1
- package/dist/server/src/sensors/sensor.js.map +1 -1
- package/dist/server/src/services/config/constants.js +1 -0
- package/dist/server/src/services/config/constants.js.map +1 -1
- package/dist/server/src/services/config/index.d.ts +5 -2
- package/dist/server/src/services/config/index.js +38 -5
- package/dist/server/src/services/config/index.js.map +1 -1
- package/dist/server/src/services/config/types.d.ts +4 -0
- package/dist/server/src/utils/path.d.ts +1 -0
- package/dist/server/src/utils/path.js +33 -0
- package/dist/server/src/utils/path.js.map +1 -1
- package/dist/server/src/workers/capabilities/frame-decoding.js +1 -1
- package/dist/server/src/workers/capabilities/frame-decoding.js.map +1 -1
- package/package.json +14 -14
- package/dist/interface/assets/Automations-DBjwNb3F.js +0 -2
- package/dist/interface/assets/Camera-BfvpjkW3.js +0 -2
- package/dist/interface/assets/Camera-yUrhUGmO.css +0 -1
- package/dist/interface/assets/Camview-DArvg940.js +0 -1
- package/dist/interface/assets/Camview-mLCaY0ld.css +0 -1
- package/dist/interface/assets/Config-Ccp5Acpv.js +0 -2
- package/dist/interface/assets/ConfigConditionSensorState-lI9dzHiT.js +0 -1
- package/dist/interface/assets/ConfigSensorValueInput-DW4er753.js +0 -1
- package/dist/interface/assets/ConfigTriggerSensor-vhwPNmPj.js +0 -1
- package/dist/interface/assets/Console-C6yUdEaM.js +0 -1
- package/dist/interface/assets/CuiAutomationRunsDialog-C4i7y1Re.js +0 -1
- package/dist/interface/assets/CuiBottomSheet-C2zU_iyj.js +0 -1
- package/dist/interface/assets/CuiCameraPipCard-CZ-oDxzy.js +0 -1
- package/dist/interface/assets/CuiCameraRecordings-BHj7CUE7.css +0 -1
- package/dist/interface/assets/CuiCameraRecordings-mY_giLEi.js +0 -1
- package/dist/interface/assets/CuiLightControl-CEpcKss7.js +0 -1
- package/dist/interface/assets/CuiMarkdownContent-C2uBepC1.js +0 -1
- package/dist/interface/assets/CuiMarkdownContent-QxLR7_qs.js +0 -1
- package/dist/interface/assets/CuiPluginCard-1dSDwOCf.js +0 -2
- package/dist/interface/assets/CuiRecordingsGrid-COHg3ZCT.css +0 -1
- package/dist/interface/assets/CuiRecordingsGrid-CkwE3jcR.js +0 -1
- package/dist/interface/assets/CuiSchema-DKATswRc.js +0 -1
- package/dist/interface/assets/Faces-BeeZrFV-.js +0 -1
- package/dist/interface/assets/FirstSteps-DWT6Tt_T.js +0 -1
- package/dist/interface/assets/Instances-CJlFo8ni.js +0 -1
- package/dist/interface/assets/Menu-DP0aMICW.js +0 -1
- package/dist/interface/assets/OAuthDeviceFlow-CcSkntGk.js +0 -1
- package/dist/interface/assets/Plugin-8dbt_8iG.js +0 -1
- package/dist/interface/assets/Plugin-BLqyZrJP.css +0 -1
- package/dist/interface/assets/PluginDetail-C9dR9jrw.js +0 -2
- package/dist/interface/assets/PluginSearch-BVAtgBZs.js +0 -1
- package/dist/interface/assets/PluginSearch-HEf_6CrR.js +0 -2
- package/dist/interface/assets/Plugins-CQJhji6o.js +0 -1
- package/dist/interface/assets/Recordings-AD78njIA.js +0 -1
- package/dist/interface/assets/SensorEdit-rC02usEO.js +0 -1
- package/dist/interface/assets/Sensors-CFfII3-e.css +0 -1
- package/dist/interface/assets/Sensors-Vwr7MYz6.js +0 -2
- package/dist/interface/assets/SettingsAccount-BBsivYFf.js +0 -1
- package/dist/interface/assets/SettingsAccount-CN9Xcgt-.js +0 -1
- package/dist/interface/assets/SettingsAppearance-Qh1cw9iX.js +0 -1
- package/dist/interface/assets/SettingsBackup-DNDDU6a1.js +0 -1
- package/dist/interface/assets/SettingsList-tFKUMnsB.js +0 -1
- package/dist/interface/assets/SettingsMqtt-BYVV1Mew.js +0 -1
- package/dist/interface/assets/SettingsRecordings-B4DDJSKe.js +0 -1
- package/dist/interface/assets/SettingsRemote-Bib7kXto.js +0 -1
- package/dist/interface/assets/SettingsSystem-DIe7CSgH.js +0 -2
- package/dist/interface/assets/Terminal-DuJHIlLe.js +0 -4
- package/dist/interface/assets/VersionsHandler-D9sDkGXx.js +0 -7
- package/dist/interface/assets/Workers-fV_NEZ7U.js +0 -2
- package/dist/interface/assets/api-Draww2tC.js +0 -2
- package/dist/interface/assets/api-eELh8KCM.css +0 -2
- package/dist/interface/assets/automations-BfsdbSPC.js +0 -1
- package/dist/interface/assets/cameras.schema-DMY4SYte.js +0 -1
- package/dist/interface/assets/chevron-right-AhqYJOFy.js +0 -1
- package/dist/interface/assets/cloudHandoff-BQsDy9yp.js +0 -1
- package/dist/interface/assets/esm-B1LZs0VG.js +0 -1
- package/dist/interface/assets/esm-BB4SBaek.js +0 -1
- package/dist/interface/assets/esm-BGA8Ydne.js +0 -1
- package/dist/interface/assets/esm-BHI_KH7L.js +0 -1
- package/dist/interface/assets/esm-BQ0EuuZe.js +0 -1
- package/dist/interface/assets/esm-Bfb-tuKt.js +0 -1
- package/dist/interface/assets/esm-BzR_6ma5.js +0 -1
- package/dist/interface/assets/esm-CCIqNfsh.js +0 -1
- package/dist/interface/assets/esm-CSMN-8o1.js +0 -1
- package/dist/interface/assets/esm-CxWbrBxP.js +0 -1
- package/dist/interface/assets/esm-DBTrmJK6.js +0 -1
- package/dist/interface/assets/esm-DRswZUWf.js +0 -1
- package/dist/interface/assets/esm-Dk7gxPHs.js +0 -1
- package/dist/interface/assets/esm-P0RCkAtk.js +0 -1
- package/dist/interface/assets/main-CV7qCZ5i.js +0 -3
- package/dist/interface/assets/mqtt-BPfLOT7L.js +0 -1
- package/dist/interface/assets/native-Cr4dkfqy.js +0 -1
- package/dist/interface/assets/native-D1Vvlhds.js +0 -1
- package/dist/interface/assets/plugin-937qnq7E.js +0 -1
- package/dist/interface/assets/plugins-BU7TQh_f.js +0 -1
- package/dist/interface/assets/sensorIcons-DtJEfoU4.js +0 -1
- package/dist/interface/assets/sensors-DjgfMS8S.js +0 -1
- package/dist/interface/assets/types-BGMvANrz.js +0 -1
- package/dist/interface/assets/useBackupRestore-E3pVEOvA.js +0 -1
- package/dist/interface/assets/useCardSelection-DGPLn1ZH.js +0 -1
- package/dist/interface/assets/useUserOptions-BL53bECb.js +0 -1
- package/dist/interface/assets/vendor-cameraui-DojVuZ2L.js +0 -2326
- package/dist/interface/assets/vendor-core-ZDcIKAw9.js +0 -1
- package/dist/interface/assets/web-BQtDHNew.js +0 -1
- package/dist/interface/assets/web-BY9kjyTj.js +0 -1
- package/dist/interface/assets/web-BcQtDSat.js +0 -1
- package/dist/interface/assets/web-BgrRQzLO.js +0 -1
- package/dist/interface/assets/web-BjKL51lK-CJYmHsnY.js +0 -1
- package/dist/interface/assets/web-BxvsJylk.js +0 -1
- package/dist/interface/assets/web-C-3iwDhG.js +0 -1
- package/dist/interface/assets/web-C9XOwu07.js +0 -1
- package/dist/interface/assets/web-CPCxRDtw.js +0 -1
- package/dist/interface/assets/web-D0U5B2i2.js +0 -1
- package/dist/interface/assets/web-DtxjXJdS.js +0 -1
- package/dist/interface/assets/web-Duf-oV4e.js +0 -1
- package/dist/interface/assets/web-jy45nBi_.js +0 -1
- package/dist/interface/assets/web-vWx_-Iq5.js +0 -1
- package/dist/interface/assets/workbox-window.prod.es5-Dlqax_Po.js +0 -1
- package/dist/server/src/api/utils/moveFiles.d.ts +0 -4
- package/dist/server/src/api/utils/moveFiles.js +0 -37
- package/dist/server/src/api/utils/moveFiles.js.map +0 -1
- package/dist/server/src/camera/decoder/sources/snapshot-source.js.map +0 -1
- package/dist/server/src/camera/decoder/stationary-suppressor.d.ts +0 -38
- package/dist/server/src/camera/decoder/stationary-suppressor.js +0 -308
- package/dist/server/src/camera/decoder/stationary-suppressor.js.map +0 -1
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
2
|
import { NamespaceManager } from '../../rpc/namespaces.js';
|
|
3
3
|
import { boxIntersectsPolygon } from '../utils/filter.js';
|
|
4
|
+
import { detectionRecord } from './debug/detection-record.js';
|
|
5
|
+
import { leanEvent, NvrSink } from './nvr-sink.js';
|
|
4
6
|
import { MAX_UNTRACKED_PLATES, normalizePlateText, PlateVoteTracker } from './plate-vote.js';
|
|
5
|
-
|
|
7
|
+
export const MOMENT_RANK_OBJECT = 0;
|
|
8
|
+
export const MOMENT_RANK_ATTRIBUTE = 1;
|
|
6
9
|
const UPDATE_THROTTLE_MS = 1000;
|
|
10
|
+
const MOMENT_IMPROVEMENT = 1.25;
|
|
11
|
+
const CLIP_ATTRIBUTE = 'clip';
|
|
7
12
|
const MIN_MOVING_SPEED = 0.05;
|
|
13
|
+
const STATIONARY_SPEED_THRESHOLD = 0.002;
|
|
8
14
|
function jpegInfo(jpeg) {
|
|
9
15
|
let i = 2;
|
|
10
16
|
while (i + 9 < jpeg.length) {
|
|
@@ -32,28 +38,35 @@ export class DetectionEventManager {
|
|
|
32
38
|
proxy;
|
|
33
39
|
logger;
|
|
34
40
|
static MAX_PLATE_THUMBNAILS = 16;
|
|
41
|
+
static SEGMENT_LINGER_MS = 10_000;
|
|
35
42
|
activeEvent = null;
|
|
36
43
|
activeSegment = null;
|
|
37
|
-
|
|
44
|
+
// first/last box center per track within the current segment, so the NVR
|
|
45
|
+
// can reason about where a subject entered and left the frame
|
|
46
|
+
segmentTrackPaths = new Map();
|
|
38
47
|
segmentIndex = 0;
|
|
39
48
|
lastPublishTime = 0;
|
|
40
|
-
|
|
41
|
-
sceneThumbnailShipped = false;
|
|
42
|
-
detectionLabelThumbnails = new Map();
|
|
49
|
+
shippedSceneAt = 0;
|
|
43
50
|
attributeThumbnails = new Map();
|
|
51
|
+
heldAttributes = [];
|
|
52
|
+
shippedAttributes = new Map();
|
|
53
|
+
segmentMoment;
|
|
54
|
+
pendingMoment;
|
|
55
|
+
eventThumbnailAt = 0;
|
|
56
|
+
segmentClosePendingSince = null;
|
|
57
|
+
lingerTimer = null;
|
|
58
|
+
onSegmentClosedCallback;
|
|
44
59
|
eventThumbnail = null;
|
|
45
60
|
needsEventThumbnail = false;
|
|
46
|
-
eventBestShot = null;
|
|
47
|
-
eventBestShotPushed = false;
|
|
48
|
-
eventBestShotDirty = false;
|
|
49
61
|
segmentFaceTrackIds = new Map();
|
|
50
62
|
segmentPlateAttrIndex = new Map();
|
|
51
63
|
segmentPlateReads = new Set();
|
|
52
64
|
eventPlateVotes = new Map();
|
|
53
65
|
plateVotingActive = true;
|
|
54
66
|
segmentClassifierTrackIds = new Map();
|
|
55
|
-
|
|
67
|
+
segmentClipLabels = new Map();
|
|
56
68
|
eventSubject;
|
|
69
|
+
nvr;
|
|
57
70
|
onEventEndCallback;
|
|
58
71
|
constructor(cameraId, proxy, logger) {
|
|
59
72
|
this.cameraId = cameraId;
|
|
@@ -61,10 +74,35 @@ export class DetectionEventManager {
|
|
|
61
74
|
this.logger = logger;
|
|
62
75
|
const ns = NamespaceManager.detectionEventNamespaces(cameraId);
|
|
63
76
|
this.eventSubject = ns.detectionEventSubject;
|
|
77
|
+
this.nvr = new NvrSink(proxy, logger);
|
|
78
|
+
}
|
|
79
|
+
updateNvrRpc(namespace) {
|
|
80
|
+
this.nvr.setNamespace(namespace);
|
|
64
81
|
}
|
|
65
82
|
onEventEnd(callback) {
|
|
66
83
|
this.onEventEndCallback = callback;
|
|
67
84
|
}
|
|
85
|
+
onSegmentClosed(callback) {
|
|
86
|
+
this.onSegmentClosedCallback = callback;
|
|
87
|
+
}
|
|
88
|
+
offerMoment(moment) {
|
|
89
|
+
// the tick cuts the moment before it opens the segment, so the very picture
|
|
90
|
+
// that opens a span would be the one dropped; hold it for that opening
|
|
91
|
+
if (!this.activeSegment) {
|
|
92
|
+
// a tick can offer the object shot and then the face shot; within the tick
|
|
93
|
+
// they compete by rank, a newer tick always displaces the older pending one
|
|
94
|
+
if (this.beatsMoment(moment.rank, moment.score, moment.stream, this.incumbentMoment(moment.capturedAt))) {
|
|
95
|
+
this.pendingMoment = moment;
|
|
96
|
+
}
|
|
97
|
+
// debugging
|
|
98
|
+
this.recordMomentVerdict(moment, 'pending');
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
this.takeMoment(moment);
|
|
102
|
+
}
|
|
103
|
+
wantsMoment(rank, score, stream, at) {
|
|
104
|
+
return this.beatsMoment(rank, score, stream, this.incumbentMoment(at));
|
|
105
|
+
}
|
|
68
106
|
processResults(data) {
|
|
69
107
|
const now = data.timestamp;
|
|
70
108
|
const triggers = this.extractTriggers(data, now);
|
|
@@ -80,6 +118,7 @@ export class DetectionEventManager {
|
|
|
80
118
|
// publish immediately, the UI shouldn't wait for the next throttled update
|
|
81
119
|
if (data.eventThumbnail && this.needsEventThumbnail) {
|
|
82
120
|
this.eventThumbnail = data.eventThumbnail;
|
|
121
|
+
this.eventThumbnailAt = now;
|
|
83
122
|
this.needsEventThumbnail = false;
|
|
84
123
|
this.publishEventThumbnail();
|
|
85
124
|
}
|
|
@@ -95,11 +134,17 @@ export class DetectionEventManager {
|
|
|
95
134
|
this.publishUpdateThrottled();
|
|
96
135
|
}
|
|
97
136
|
}
|
|
98
|
-
if (
|
|
137
|
+
if (data.hasOpenSpans) {
|
|
138
|
+
this.segmentClosePendingSince = null;
|
|
139
|
+
if (this.lingerTimer) {
|
|
140
|
+
clearTimeout(this.lingerTimer);
|
|
141
|
+
this.lingerTimer = null;
|
|
142
|
+
}
|
|
99
143
|
if (!this.activeSegment) {
|
|
100
|
-
|
|
144
|
+
if (hasDetections)
|
|
145
|
+
this.openSegment(data, now);
|
|
101
146
|
}
|
|
102
|
-
else {
|
|
147
|
+
else if (hasDetections) {
|
|
103
148
|
this.enrichSegment(data, now);
|
|
104
149
|
if (data.thumbnails && data.thumbnails.length > 0) {
|
|
105
150
|
this.updateThumbnails(data.thumbnails);
|
|
@@ -108,40 +153,48 @@ export class DetectionEventManager {
|
|
|
108
153
|
this.updateTypes();
|
|
109
154
|
this.publishSegmentThrottled('segment-update');
|
|
110
155
|
}
|
|
111
|
-
this.resetSegmentTimer(data.segmentTimeout);
|
|
112
156
|
}
|
|
157
|
+
else if (this.activeSegment && this.segmentClosePendingSince === null) {
|
|
158
|
+
// all spans closed: linger before deciding, a reopening span continues
|
|
159
|
+
// this segment (detector flicker is not a new visit); lastSeen stays on
|
|
160
|
+
// the last real detection, timer-driven so tickless cameras close too
|
|
161
|
+
this.segmentClosePendingSince = now;
|
|
162
|
+
this.lingerTimer = setTimeout(() => {
|
|
163
|
+
this.lingerTimer = null;
|
|
164
|
+
if (this.segmentClosePendingSince === null)
|
|
165
|
+
return;
|
|
166
|
+
this.segmentClosePendingSince = null;
|
|
167
|
+
this.closeSegment();
|
|
168
|
+
this.onSegmentClosedCallback?.();
|
|
169
|
+
}, DetectionEventManager.SEGMENT_LINGER_MS);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
hasActiveSegment() {
|
|
173
|
+
return this.activeSegment !== null;
|
|
113
174
|
}
|
|
114
175
|
forceEndActiveEvent() {
|
|
115
176
|
if (this.activeEvent)
|
|
116
177
|
this.endEvent();
|
|
117
178
|
}
|
|
118
179
|
destroy() {
|
|
119
|
-
if (this.segmentTimer) {
|
|
120
|
-
clearTimeout(this.segmentTimer);
|
|
121
|
-
this.segmentTimer = null;
|
|
122
|
-
}
|
|
123
180
|
if (this.activeEvent)
|
|
124
181
|
this.endEvent();
|
|
125
182
|
}
|
|
126
|
-
publishEventThumbnail(jpeg,
|
|
183
|
+
publishEventThumbnail(jpeg, capturedAt) {
|
|
127
184
|
if (!this.activeEvent)
|
|
128
185
|
return;
|
|
129
|
-
// a late scene re-shoot (HQ warm-up) must not undo an object crop
|
|
130
|
-
if (source === 'scene' && this.eventBestShotPushed)
|
|
131
|
-
return;
|
|
132
186
|
if (jpeg) {
|
|
133
187
|
this.eventThumbnail = jpeg;
|
|
188
|
+
this.eventThumbnailAt = capturedAt ?? Date.now();
|
|
134
189
|
this.needsEventThumbnail = false;
|
|
135
190
|
}
|
|
136
191
|
if (!this.eventThumbnail)
|
|
137
192
|
return;
|
|
138
193
|
this.logger.trace(`[event] thumbnail id=${this.activeEvent.id.slice(0, 8)} ${jpegInfo(this.eventThumbnail)}`);
|
|
139
194
|
this.activeEvent.segments = [];
|
|
140
|
-
this.activeEvent.
|
|
141
|
-
this.publish('update');
|
|
142
|
-
this.
|
|
143
|
-
if (this.activeSegment && !this.sceneThumbnail) {
|
|
144
|
-
this.sceneThumbnail = { jpeg: this.eventThumbnail, score: 0, area: 0, onEdge: false, hasAttribute: false };
|
|
195
|
+
this.activeEvent.thumbnailAt = this.eventThumbnailAt || undefined;
|
|
196
|
+
this.publish('update', { scene: this.eventThumbnail });
|
|
197
|
+
if (this.activeSegment && !this.segmentMoment) {
|
|
145
198
|
this.publishSegment('segment-update');
|
|
146
199
|
}
|
|
147
200
|
}
|
|
@@ -166,39 +219,29 @@ export class DetectionEventManager {
|
|
|
166
219
|
this.segmentIndex = 0;
|
|
167
220
|
this.needsEventThumbnail = true;
|
|
168
221
|
this.eventThumbnail = null;
|
|
169
|
-
this.
|
|
170
|
-
this.eventBestShotPushed = false;
|
|
171
|
-
this.eventBestShotDirty = false;
|
|
222
|
+
this.eventThumbnailAt = 0;
|
|
172
223
|
if (data.eventThumbnail) {
|
|
173
224
|
this.eventThumbnail = data.eventThumbnail;
|
|
225
|
+
this.eventThumbnailAt = now;
|
|
174
226
|
this.needsEventThumbnail = false;
|
|
175
227
|
}
|
|
176
228
|
this.updateTypes();
|
|
177
|
-
// pre-captured
|
|
178
|
-
//
|
|
229
|
+
// a pre-captured scene ships with the start message, otherwise the next
|
|
230
|
+
// coordinator tick delivers it via update
|
|
179
231
|
if (this.eventThumbnail) {
|
|
180
|
-
this.activeEvent.
|
|
232
|
+
this.activeEvent.thumbnailAt = this.eventThumbnailAt || undefined;
|
|
181
233
|
}
|
|
182
|
-
this.publish('start');
|
|
183
|
-
if (this.activeEvent)
|
|
184
|
-
this.activeEvent.thumbnail = undefined;
|
|
234
|
+
this.publish('start', this.eventThumbnail ? { scene: this.eventThumbnail } : undefined);
|
|
185
235
|
const triggerTypes = [...new Set(triggers.map((t) => t.type))].join(',');
|
|
186
236
|
const thumbInfo = this.eventThumbnail ? jpegInfo(this.eventThumbnail) : 'pending';
|
|
187
237
|
this.logger.log(`[event] start id=${this.activeEvent.id.slice(0, 8)} triggers=[${triggerTypes}] types=[${this.activeEvent.types.join(',')}] thumb=${thumbInfo}`);
|
|
188
|
-
if (this.hasNewDetections(data) && data.
|
|
238
|
+
if (this.hasNewDetections(data) && data.hasOpenSpans) {
|
|
189
239
|
this.openSegment(data, now);
|
|
190
|
-
this.resetSegmentTimer(data.segmentTimeout);
|
|
191
240
|
}
|
|
192
241
|
}
|
|
193
242
|
endEvent() {
|
|
194
243
|
if (!this.activeEvent)
|
|
195
244
|
return;
|
|
196
|
-
if (this.eventBestShotDirty && this.eventBestShot) {
|
|
197
|
-
this.publishEventThumbnail(this.eventBestShot.jpeg, 'best-shot');
|
|
198
|
-
}
|
|
199
|
-
this.eventBestShot = null;
|
|
200
|
-
this.eventBestShotPushed = false;
|
|
201
|
-
this.eventBestShotDirty = false;
|
|
202
245
|
this.closeSegment();
|
|
203
246
|
this.activeEvent.state = 'ended';
|
|
204
247
|
this.activeEvent.endTime = Date.now();
|
|
@@ -211,11 +254,12 @@ export class DetectionEventManager {
|
|
|
211
254
|
this.logger.log(`[event] end id=${this.activeEvent.id.slice(0, 8)} duration=${duration}ms segments=${this.segmentIndex} types=[${this.activeEvent.types.join(',')}]`);
|
|
212
255
|
this.activeEvent = null;
|
|
213
256
|
this.activeSegment = null;
|
|
214
|
-
this.
|
|
215
|
-
if (this.
|
|
216
|
-
clearTimeout(this.
|
|
217
|
-
this.
|
|
257
|
+
this.segmentClosePendingSince = null;
|
|
258
|
+
if (this.lingerTimer) {
|
|
259
|
+
clearTimeout(this.lingerTimer);
|
|
260
|
+
this.lingerTimer = null;
|
|
218
261
|
}
|
|
262
|
+
this.eventPlateVotes.clear();
|
|
219
263
|
if (this.onEventEndCallback) {
|
|
220
264
|
this.onEventEndCallback();
|
|
221
265
|
}
|
|
@@ -229,7 +273,15 @@ export class DetectionEventManager {
|
|
|
229
273
|
detections: [],
|
|
230
274
|
attributes: [],
|
|
231
275
|
};
|
|
276
|
+
this.segmentTrackPaths = new Map();
|
|
232
277
|
this.enrichSegment(data, now);
|
|
278
|
+
// the tick cuts its moment before it opens the segment, and both carry the
|
|
279
|
+
// tick's stamp, so an older one belongs to a tick that opened nothing
|
|
280
|
+
const pending = this.pendingMoment;
|
|
281
|
+
this.pendingMoment = undefined;
|
|
282
|
+
if (pending?.capturedAt === now) {
|
|
283
|
+
this.takeMoment(pending);
|
|
284
|
+
}
|
|
233
285
|
if (data.thumbnails && data.thumbnails.length > 0) {
|
|
234
286
|
this.updateThumbnails(data.thumbnails);
|
|
235
287
|
}
|
|
@@ -250,7 +302,7 @@ export class DetectionEventManager {
|
|
|
250
302
|
return;
|
|
251
303
|
}
|
|
252
304
|
this.segmentPlateAttrIndex.set(attrKey, this.activeSegment.attributes.length);
|
|
253
|
-
this.
|
|
305
|
+
this.pushAttribute({ type: 'license_plate', label, confidence, parentTrackId });
|
|
254
306
|
}
|
|
255
307
|
flushPlateFallbacks() {
|
|
256
308
|
if (!this.activeSegment || !this.plateVotingActive)
|
|
@@ -272,16 +324,13 @@ export class DetectionEventManager {
|
|
|
272
324
|
closeSegment() {
|
|
273
325
|
if (!this.activeSegment || !this.activeEvent)
|
|
274
326
|
return;
|
|
275
|
-
|
|
327
|
+
// lastSeen stays on the last real detection: the linger only delays the
|
|
328
|
+
// decision to close, it is not part of what was seen
|
|
276
329
|
this.flushPlateFallbacks();
|
|
277
330
|
this.publishSegment('segment-end');
|
|
278
331
|
this.clearSegmentThumbnails();
|
|
279
332
|
this.segmentIndex++;
|
|
280
333
|
this.activeSegment = null;
|
|
281
|
-
if (this.segmentTimer) {
|
|
282
|
-
clearTimeout(this.segmentTimer);
|
|
283
|
-
this.segmentTimer = null;
|
|
284
|
-
}
|
|
285
334
|
}
|
|
286
335
|
enrichTriggers(triggers, now) {
|
|
287
336
|
if (!this.activeEvent)
|
|
@@ -304,10 +353,21 @@ export class DetectionEventManager {
|
|
|
304
353
|
return;
|
|
305
354
|
this.activeSegment.lastSeen = now;
|
|
306
355
|
if (data.objects.length > 0) {
|
|
307
|
-
// upsert per label, keep best score/box/trackId and maxCount
|
|
308
356
|
const labelCounts = new Map();
|
|
309
357
|
for (const obj of data.objects) {
|
|
310
358
|
const t = obj;
|
|
359
|
+
if (t.trackId !== undefined && obj.box) {
|
|
360
|
+
const cx = obj.box.x + obj.box.width / 2;
|
|
361
|
+
const cy = obj.box.y + obj.box.height / 2;
|
|
362
|
+
const path = this.segmentTrackPaths.get(t.trackId);
|
|
363
|
+
if (path) {
|
|
364
|
+
path.exitX = cx;
|
|
365
|
+
path.exitY = cy;
|
|
366
|
+
}
|
|
367
|
+
else {
|
|
368
|
+
this.segmentTrackPaths.set(t.trackId, { enterX: cx, enterY: cy, exitX: cx, exitY: cy });
|
|
369
|
+
}
|
|
370
|
+
}
|
|
311
371
|
const entry = labelCounts.get(obj.label);
|
|
312
372
|
if (entry) {
|
|
313
373
|
entry.count++;
|
|
@@ -344,6 +404,13 @@ export class DetectionEventManager {
|
|
|
344
404
|
this.activeSegment.detections.push({ label, score: bestScore, maxCount: count, box: bestBox, trackId: bestTrackId, moving });
|
|
345
405
|
}
|
|
346
406
|
}
|
|
407
|
+
for (const d of this.activeSegment.detections) {
|
|
408
|
+
if (d.trackId === undefined)
|
|
409
|
+
continue;
|
|
410
|
+
const path = this.segmentTrackPaths.get(d.trackId);
|
|
411
|
+
if (path)
|
|
412
|
+
d.path = path;
|
|
413
|
+
}
|
|
347
414
|
// boxes and polygons are both normalized 0-1, direct overlap test
|
|
348
415
|
if (data.detectionZones && data.detectionZones.length > 0) {
|
|
349
416
|
const zonesSet = new Set(this.activeSegment.zones ?? []);
|
|
@@ -366,33 +433,26 @@ export class DetectionEventManager {
|
|
|
366
433
|
continue;
|
|
367
434
|
if (face.identity) {
|
|
368
435
|
if (!this.activeSegment.attributes.some((a) => a.type === 'face' && a.label === face.identity)) {
|
|
369
|
-
this.
|
|
436
|
+
this.pushAttribute({ type: 'face', label: face.identity, parentTrackId: face.parentTrackId });
|
|
370
437
|
}
|
|
371
438
|
}
|
|
372
439
|
else if (face.embedding?.length) {
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
440
|
+
// one slot per person, and one shared slot for faces the tracker could
|
|
441
|
+
// not attach to anyone: without a track there is nothing to tell two
|
|
442
|
+
// strangers apart by, and a slot per sighting would file the same face
|
|
443
|
+
// into the index on every tick
|
|
444
|
+
const bucket = face.parentTrackId !== undefined ? `t${face.parentTrackId}` : 'untracked';
|
|
445
|
+
const existingIdx = this.segmentFaceTrackIds.get(bucket);
|
|
446
|
+
if (existingIdx !== undefined) {
|
|
447
|
+
const existing = this.activeSegment.attributes[existingIdx];
|
|
448
|
+
if (existing && face.confidence > (existing.confidence ?? 0)) {
|
|
449
|
+
existing.confidence = face.confidence;
|
|
450
|
+
this.heldAttributes[existingIdx] = { thumbnail: face.thumbnail, embedding: face.embedding, embeddingModel: data.faceEmbeddingModel };
|
|
384
451
|
}
|
|
385
|
-
|
|
452
|
+
continue;
|
|
386
453
|
}
|
|
387
|
-
this.activeSegment.attributes.
|
|
388
|
-
|
|
389
|
-
label: 'unknown',
|
|
390
|
-
confidence: face.confidence,
|
|
391
|
-
embedding: face.embedding,
|
|
392
|
-
embeddingModel: data.faceEmbeddingModel,
|
|
393
|
-
thumbnail: face.thumbnail,
|
|
394
|
-
parentTrackId: face.parentTrackId,
|
|
395
|
-
});
|
|
454
|
+
this.segmentFaceTrackIds.set(bucket, this.activeSegment.attributes.length);
|
|
455
|
+
this.pushAttribute({ type: 'face', label: 'unknown', confidence: face.confidence, parentTrackId: face.parentTrackId }, { thumbnail: face.thumbnail, embedding: face.embedding, embeddingModel: data.faceEmbeddingModel });
|
|
396
456
|
}
|
|
397
457
|
}
|
|
398
458
|
this.plateVotingActive = data.plateVoting !== false;
|
|
@@ -408,7 +468,7 @@ export class DetectionEventManager {
|
|
|
408
468
|
existing.confidence = plate.confidence;
|
|
409
469
|
}
|
|
410
470
|
else {
|
|
411
|
-
this.
|
|
471
|
+
this.pushAttribute({ type: 'license_plate', label, confidence: plate.confidence, parentTrackId: plate.parentTrackId });
|
|
412
472
|
}
|
|
413
473
|
continue;
|
|
414
474
|
}
|
|
@@ -456,24 +516,28 @@ export class DetectionEventManager {
|
|
|
456
516
|
else if (this.activeSegment.attributes.some((a) => a.type === cls.attribute && a.label === cls.subAttribute)) {
|
|
457
517
|
continue;
|
|
458
518
|
}
|
|
459
|
-
this.
|
|
519
|
+
this.pushAttribute({ type: cls.attribute, label: cls.subAttribute, confidence: cls.confidence, parentTrackId: cls.parentTrackId });
|
|
460
520
|
}
|
|
461
521
|
for (const clip of data.clips) {
|
|
462
522
|
if (clip.embedding?.length) {
|
|
463
|
-
|
|
464
|
-
|
|
523
|
+
// one embedding per subject actually present, not per track: a
|
|
524
|
+
// re-numbered track is the same person and would otherwise land in the
|
|
525
|
+
// search index again, while two real people must keep both appearances
|
|
526
|
+
const stored = this.segmentClipLabels.get(clip.label) ?? 0;
|
|
527
|
+
const present = this.activeSegment.detections.find((d) => d.label === clip.label)?.maxCount ?? 1;
|
|
528
|
+
if (stored >= Math.max(1, present))
|
|
465
529
|
continue;
|
|
466
|
-
this.
|
|
467
|
-
this.
|
|
468
|
-
type: 'clip',
|
|
469
|
-
label: clip.label,
|
|
470
|
-
clipEmbedding: clip.embedding,
|
|
471
|
-
clipEmbeddingModel: data.clipEmbeddingModel,
|
|
472
|
-
parentTrackId: clip.parentTrackId,
|
|
473
|
-
});
|
|
530
|
+
this.segmentClipLabels.set(clip.label, stored + 1);
|
|
531
|
+
this.pushAttribute({ type: 'clip', label: clip.label, parentTrackId: clip.parentTrackId }, { clipEmbedding: clip.embedding, clipEmbeddingModel: data.clipEmbeddingModel });
|
|
474
532
|
}
|
|
475
533
|
}
|
|
476
534
|
}
|
|
535
|
+
pushAttribute(attribute, held) {
|
|
536
|
+
if (!this.activeSegment)
|
|
537
|
+
return;
|
|
538
|
+
this.activeSegment.attributes.push(attribute);
|
|
539
|
+
this.heldAttributes[this.activeSegment.attributes.length - 1] = held ?? {};
|
|
540
|
+
}
|
|
477
541
|
extractTriggers(data, now) {
|
|
478
542
|
const triggers = [];
|
|
479
543
|
if (data.motion?.detected) {
|
|
@@ -517,7 +581,7 @@ export class DetectionEventManager {
|
|
|
517
581
|
updateTypes() {
|
|
518
582
|
if (!this.activeEvent)
|
|
519
583
|
return;
|
|
520
|
-
const types = new Set();
|
|
584
|
+
const types = new Set(this.activeEvent.types);
|
|
521
585
|
for (const t of this.activeEvent.triggers)
|
|
522
586
|
types.add(t.type);
|
|
523
587
|
// activeEvent.segments is only filled during publishSegment, include the
|
|
@@ -526,57 +590,26 @@ export class DetectionEventManager {
|
|
|
526
590
|
for (const seg of segs) {
|
|
527
591
|
for (const d of seg.detections)
|
|
528
592
|
types.add(d.label);
|
|
529
|
-
for (const attr of seg.attributes)
|
|
593
|
+
for (const attr of seg.attributes) {
|
|
594
|
+
if (attr.type === CLIP_ATTRIBUTE)
|
|
595
|
+
continue;
|
|
530
596
|
types.add(attr.type);
|
|
597
|
+
}
|
|
531
598
|
}
|
|
532
599
|
this.activeEvent.types = [...types];
|
|
533
600
|
}
|
|
534
601
|
hasNewDetections(data) {
|
|
535
602
|
return data.objects.length > 0 || data.faces.length > 0 || data.plates.length > 0 || data.classifiers.length > 0;
|
|
536
603
|
}
|
|
537
|
-
resetSegmentTimer(timeoutSeconds) {
|
|
538
|
-
if (this.segmentTimer)
|
|
539
|
-
clearTimeout(this.segmentTimer);
|
|
540
|
-
this.segmentTimer = setTimeout(() => {
|
|
541
|
-
this.segmentTimer = null;
|
|
542
|
-
this.closeSegment();
|
|
543
|
-
}, timeoutSeconds * 1000);
|
|
544
|
-
}
|
|
545
604
|
updateThumbnails(thumbnails) {
|
|
546
605
|
for (const thumb of thumbnails) {
|
|
547
606
|
const label = thumb.label;
|
|
548
|
-
if (label.startsWith('face:')
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
else {
|
|
555
|
-
const hasAttr = thumbnails.some((t) => t.label.startsWith('face:') || t.label.startsWith('plate:') || t.label.startsWith('class:'));
|
|
556
|
-
const candidate = {
|
|
557
|
-
jpeg: thumb.jpeg,
|
|
558
|
-
score: thumb.score,
|
|
559
|
-
area: thumb.area,
|
|
560
|
-
onEdge: thumb.onEdge,
|
|
561
|
-
hasAttribute: hasAttr,
|
|
562
|
-
trackId: thumb.trackId,
|
|
563
|
-
speed: thumb.speed,
|
|
564
|
-
};
|
|
565
|
-
if (!this.sceneThumbnail || this.isBetterScene(candidate, this.sceneThumbnail)) {
|
|
566
|
-
this.sceneThumbnail = candidate;
|
|
567
|
-
}
|
|
568
|
-
if (!this.eventBestShot || this.isBetterScene(candidate, this.eventBestShot)) {
|
|
569
|
-
this.eventBestShot = candidate;
|
|
570
|
-
if (this.eventBestShotPushed) {
|
|
571
|
-
this.eventBestShotDirty = true;
|
|
572
|
-
}
|
|
573
|
-
else {
|
|
574
|
-
this.eventBestShotPushed = true;
|
|
575
|
-
this.publishEventThumbnail(candidate.jpeg, 'best-shot');
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
this.updateBestCandidate(this.detectionLabelThumbnails, label, thumb);
|
|
579
|
-
}
|
|
607
|
+
if (!label.startsWith('face:') && !label.startsWith('plate:') && !label.startsWith('class:'))
|
|
608
|
+
continue;
|
|
609
|
+
this.updateBestCandidate(this.attributeThumbnails, label, thumb);
|
|
610
|
+
// a moving vehicle produces a distinct plate crop almost every frame, cap retention
|
|
611
|
+
if (label.startsWith('plate:'))
|
|
612
|
+
this.prunePlateThumbnails();
|
|
580
613
|
}
|
|
581
614
|
}
|
|
582
615
|
prunePlateThumbnails() {
|
|
@@ -605,7 +638,6 @@ export class DetectionEventManager {
|
|
|
605
638
|
}
|
|
606
639
|
const cm = DetectionEventManager.isMoving(candidate);
|
|
607
640
|
const currM = DetectionEventManager.isMoving(current);
|
|
608
|
-
// prefer moving objects over stationary
|
|
609
641
|
if (cm && !currM) {
|
|
610
642
|
this.logger.trace(`Thumbnail ${key}: prefer moving track#${candidate.trackId} (speed=${candidate.speed?.toFixed(4)}) over static track#${current.trackId}`);
|
|
611
643
|
map.set(key, candidate);
|
|
@@ -617,109 +649,165 @@ export class DetectionEventManager {
|
|
|
617
649
|
map.set(key, candidate);
|
|
618
650
|
}
|
|
619
651
|
}
|
|
620
|
-
isBetterScene(candidate, current) {
|
|
621
|
-
if (candidate.hasAttribute && !current.hasAttribute)
|
|
622
|
-
return true;
|
|
623
|
-
const cm = DetectionEventManager.isMoving(candidate);
|
|
624
|
-
const currM = DetectionEventManager.isMoving(current);
|
|
625
|
-
if (cm && !currM) {
|
|
626
|
-
this.logger.trace(`Scene thumbnail: prefer moving track#${candidate.trackId} (speed=${candidate.speed?.toFixed(4)}) over static track#${current.trackId}`);
|
|
627
|
-
return true;
|
|
628
|
-
}
|
|
629
|
-
if (!cm && currM)
|
|
630
|
-
return false;
|
|
631
|
-
if (candidate.onEdge && !current.onEdge)
|
|
632
|
-
return false;
|
|
633
|
-
if (candidate.score > current.score * 1.05)
|
|
634
|
-
return true;
|
|
635
|
-
if (candidate.area > current.area * 1.1)
|
|
636
|
-
return true;
|
|
637
|
-
return false;
|
|
638
|
-
}
|
|
639
652
|
static isMoving(c) {
|
|
640
653
|
return (c.speed ?? 0) >= MIN_MOVING_SPEED;
|
|
641
654
|
}
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
if (this.
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
655
|
+
segmentAttachments(withEmbeddings) {
|
|
656
|
+
const attachments = {};
|
|
657
|
+
const moment = this.segmentMoment;
|
|
658
|
+
if (moment && moment.capturedAt !== this.shippedSceneAt) {
|
|
659
|
+
attachments.strip = moment.strip;
|
|
660
|
+
attachments.card = moment.card;
|
|
661
|
+
this.shippedSceneAt = moment.capturedAt;
|
|
662
|
+
}
|
|
663
|
+
const attributes = this.activeSegment?.attributes ?? [];
|
|
664
|
+
const crops = [];
|
|
665
|
+
let anyCrop = false;
|
|
666
|
+
for (const [index, attribute] of attributes.entries()) {
|
|
667
|
+
const held = this.heldAttributes[index];
|
|
668
|
+
const crop = held?.thumbnail ?? this.attributeThumbnailFor(attribute);
|
|
669
|
+
if (crop?.length && this.shippedAttributes.get(index) !== crop) {
|
|
670
|
+
this.shippedAttributes.set(index, crop);
|
|
671
|
+
crops.push(crop);
|
|
672
|
+
anyCrop = true;
|
|
673
|
+
}
|
|
674
|
+
else {
|
|
675
|
+
crops.push(undefined);
|
|
676
|
+
}
|
|
677
|
+
// embeddings are write-only into the face and clip indexes, and the
|
|
678
|
+
// recorder reads them once when the segment closes
|
|
679
|
+
if (withEmbeddings && held) {
|
|
680
|
+
if (held.embedding) {
|
|
681
|
+
attribute.embedding = held.embedding;
|
|
682
|
+
attribute.embeddingModel = held.embeddingModel;
|
|
683
|
+
}
|
|
684
|
+
if (held.clipEmbedding) {
|
|
685
|
+
attribute.clipEmbedding = held.clipEmbedding;
|
|
686
|
+
attribute.clipEmbeddingModel = held.clipEmbeddingModel;
|
|
668
687
|
}
|
|
669
688
|
}
|
|
670
689
|
}
|
|
690
|
+
if (anyCrop)
|
|
691
|
+
attachments.attributes = crops;
|
|
692
|
+
return attachments;
|
|
693
|
+
}
|
|
694
|
+
attributeThumbnailFor(attribute) {
|
|
695
|
+
const keys = [`face:${attribute.label}`, `plate:${attribute.label}`, `class:${attribute.label}`];
|
|
696
|
+
const directKey = `${attribute.type}:${attribute.label}`;
|
|
697
|
+
if (!keys.includes(directKey))
|
|
698
|
+
keys.unshift(directKey);
|
|
699
|
+
for (const key of keys) {
|
|
700
|
+
const candidate = this.attributeThumbnails.get(key);
|
|
701
|
+
if (candidate)
|
|
702
|
+
return candidate.jpeg;
|
|
703
|
+
}
|
|
704
|
+
return undefined;
|
|
705
|
+
}
|
|
706
|
+
takeMoment(moment) {
|
|
707
|
+
if (!this.beatsMoment(moment.rank, moment.score, moment.stream, this.segmentMoment)) {
|
|
708
|
+
// debugging
|
|
709
|
+
this.recordMomentVerdict(moment, 'rejected');
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
712
|
+
// debugging
|
|
713
|
+
this.recordMomentVerdict(moment, 'kept');
|
|
714
|
+
this.segmentMoment = moment;
|
|
671
715
|
}
|
|
672
|
-
|
|
673
|
-
|
|
716
|
+
heldMomentInfo() {
|
|
717
|
+
const held = this.segmentMoment;
|
|
718
|
+
if (!held)
|
|
719
|
+
return undefined;
|
|
720
|
+
return { capturedAt: held.capturedAt, score: held.score, rank: held.rank, stream: held.stream };
|
|
721
|
+
}
|
|
722
|
+
incumbentMoment(at) {
|
|
723
|
+
if (this.activeSegment)
|
|
724
|
+
return this.segmentMoment;
|
|
725
|
+
return this.pendingMoment?.capturedAt === at ? this.pendingMoment : undefined;
|
|
726
|
+
}
|
|
727
|
+
beatsMoment(rank, score, stream, held) {
|
|
728
|
+
if (!held)
|
|
729
|
+
return true;
|
|
730
|
+
if (rank !== held.rank)
|
|
731
|
+
return rank > held.rank;
|
|
732
|
+
// the score is normalized, so it cannot see that a main-stream crop is the
|
|
733
|
+
// same framing with several times the pixels: that one only has to tie
|
|
734
|
+
if (stream === 'main' && held.stream === 'low')
|
|
735
|
+
return score > held.score;
|
|
736
|
+
return score > held.score * MOMENT_IMPROVEMENT;
|
|
737
|
+
}
|
|
738
|
+
// debugging
|
|
739
|
+
recordMomentVerdict(moment, verdict) {
|
|
740
|
+
if (!detectionRecord.active)
|
|
674
741
|
return;
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
742
|
+
detectionRecord.momentVerdict({
|
|
743
|
+
verdict,
|
|
744
|
+
capturedAt: moment.capturedAt,
|
|
745
|
+
score: moment.score,
|
|
746
|
+
rank: moment.rank,
|
|
747
|
+
stream: moment.stream,
|
|
748
|
+
held: this.heldMomentInfo(),
|
|
749
|
+
eventId: this.activeEvent?.id.slice(0, 8),
|
|
750
|
+
segment: this.activeSegment ? this.segmentIndex : undefined,
|
|
751
|
+
});
|
|
680
752
|
}
|
|
681
753
|
clearSegmentThumbnails() {
|
|
682
|
-
this.
|
|
683
|
-
this.
|
|
684
|
-
this.
|
|
754
|
+
this.shippedSceneAt = 0;
|
|
755
|
+
this.segmentMoment = undefined;
|
|
756
|
+
this.pendingMoment = undefined;
|
|
685
757
|
this.attributeThumbnails.clear();
|
|
758
|
+
this.heldAttributes = [];
|
|
759
|
+
this.shippedAttributes.clear();
|
|
686
760
|
this.segmentFaceTrackIds.clear();
|
|
687
761
|
this.segmentPlateAttrIndex.clear();
|
|
688
762
|
this.segmentPlateReads.clear();
|
|
689
763
|
this.segmentClassifierTrackIds.clear();
|
|
690
|
-
this.
|
|
764
|
+
this.segmentClipLabels.clear();
|
|
691
765
|
}
|
|
692
|
-
publish(type) {
|
|
766
|
+
publish(type, attachments) {
|
|
693
767
|
if (!this.activeEvent)
|
|
694
768
|
return;
|
|
695
|
-
|
|
769
|
+
const message = { type, data: leanEvent(this.activeEvent) };
|
|
770
|
+
this.proxy.publish(this.eventSubject, message);
|
|
771
|
+
this.nvr.send(type, this.activeEvent, attachments);
|
|
772
|
+
// debugging
|
|
773
|
+
this.recordMessage(type, attachments);
|
|
696
774
|
this.lastPublishTime = Date.now();
|
|
697
775
|
}
|
|
776
|
+
// debugging
|
|
777
|
+
recordMessage(type, attachments) {
|
|
778
|
+
if (!detectionRecord.active || !this.activeEvent)
|
|
779
|
+
return;
|
|
780
|
+
const at = this.segmentMoment?.capturedAt ?? this.activeEvent.lastUpdate;
|
|
781
|
+
const segment = this.activeSegment;
|
|
782
|
+
const attributes = segment?.attributes ?? [];
|
|
783
|
+
detectionRecord.message({
|
|
784
|
+
type,
|
|
785
|
+
eventId: this.activeEvent.id.slice(0, 8),
|
|
786
|
+
segment: segment ? this.segmentIndex : undefined,
|
|
787
|
+
types: this.activeEvent.types,
|
|
788
|
+
recorderReachable: this.nvr.connected,
|
|
789
|
+
detections: segment?.detections.map((d) => ({ label: d.label, score: d.score, count: d.maxCount, track: d.trackId, moving: d.moving })),
|
|
790
|
+
attributes: attributes.map((a) => ({ type: a.type, label: a.label, confidence: a.confidence, parent: a.parentTrackId })),
|
|
791
|
+
sent: {
|
|
792
|
+
scene: attachments?.scene ? detectionRecord.picture(this.eventThumbnailAt || at, 'scene', 'event', attachments.scene) : undefined,
|
|
793
|
+
strip: attachments?.strip ? detectionRecord.picture(at, 'moment', 'strip', attachments.strip) : undefined,
|
|
794
|
+
card: attachments?.card ? detectionRecord.picture(at, 'moment', 'card', attachments.card) : undefined,
|
|
795
|
+
attributes: attachments?.attributes?.map((crop, index) => crop ? detectionRecord.picture(at, 'attr', `${attributes[index]?.type}-${attributes[index]?.label}`, crop) : undefined),
|
|
796
|
+
},
|
|
797
|
+
momentStream: this.segmentMoment?.stream,
|
|
798
|
+
momentAt: this.segmentMoment?.capturedAt,
|
|
799
|
+
});
|
|
800
|
+
}
|
|
698
801
|
publishSegment(type) {
|
|
699
802
|
if (!this.activeEvent || !this.activeSegment)
|
|
700
803
|
return;
|
|
701
804
|
this.activeEvent.segments = [this.activeSegment];
|
|
702
805
|
this.activeEvent.segmentIndex = this.segmentIndex;
|
|
703
806
|
this.logSegment(type);
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
this.
|
|
707
|
-
|
|
708
|
-
else if (type === 'segment-start') {
|
|
709
|
-
this.injectSegmentThumbnails();
|
|
710
|
-
this.publish(type);
|
|
711
|
-
this.sceneThumbnailShipped = this.sceneThumbnail !== null;
|
|
712
|
-
this.stripSegmentThumbnails();
|
|
713
|
-
}
|
|
714
|
-
else if (!this.sceneThumbnailShipped && this.sceneThumbnail) {
|
|
715
|
-
this.activeSegment.thumbnail = this.sceneThumbnail.jpeg;
|
|
716
|
-
this.publish(type);
|
|
717
|
-
this.activeSegment.thumbnail = undefined;
|
|
718
|
-
this.sceneThumbnailShipped = true;
|
|
719
|
-
}
|
|
720
|
-
else {
|
|
721
|
-
this.publish(type);
|
|
722
|
-
}
|
|
807
|
+
const moment = this.segmentMoment;
|
|
808
|
+
if (moment)
|
|
809
|
+
this.activeSegment.thumbnailAt = moment.capturedAt;
|
|
810
|
+
this.publish(type, this.segmentAttachments(type === 'segment-end'));
|
|
723
811
|
}
|
|
724
812
|
publishSegmentThrottled(type) {
|
|
725
813
|
const now = Date.now();
|
|
@@ -749,17 +837,16 @@ export class DetectionEventManager {
|
|
|
749
837
|
}
|
|
750
838
|
if (seg.attributes.length > 0) {
|
|
751
839
|
const groups = new Map();
|
|
752
|
-
for (const a of seg.attributes) {
|
|
840
|
+
for (const [index, a] of seg.attributes.entries()) {
|
|
841
|
+
const held = this.heldAttributes[index];
|
|
753
842
|
const list = groups.get(a.type) ?? [];
|
|
754
843
|
let info = a.label;
|
|
755
844
|
if (a.confidence)
|
|
756
845
|
info += `(${a.confidence.toFixed(2)})`;
|
|
757
|
-
if (
|
|
846
|
+
if (held?.embedding?.length || held?.clipEmbedding?.length)
|
|
758
847
|
info += '+emb';
|
|
759
|
-
if (
|
|
848
|
+
if (held?.thumbnail ?? this.attributeThumbnailFor(a))
|
|
760
849
|
info += '+thumb';
|
|
761
|
-
if (a.type === 'clip' && a.clipEmbedding?.length)
|
|
762
|
-
info += '+emb';
|
|
763
850
|
list.push(info);
|
|
764
851
|
groups.set(a.type, list);
|
|
765
852
|
}
|
|
@@ -782,10 +869,10 @@ export class DetectionEventManager {
|
|
|
782
869
|
parts.push(`zones=[${seg.zones.join(',')}]`);
|
|
783
870
|
}
|
|
784
871
|
const thumbParts = [];
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
thumbParts.push(
|
|
872
|
+
const moment = this.segmentMoment;
|
|
873
|
+
if (moment) {
|
|
874
|
+
const shows = moment.rank >= MOMENT_RANK_ATTRIBUTE ? 'attr' : 'obj';
|
|
875
|
+
thumbParts.push(`moment(${shows},${moment.stream}):${jpegInfo(moment.strip)}${moment.card ? `+card:${jpegInfo(moment.card)}` : ''}`);
|
|
789
876
|
}
|
|
790
877
|
for (const [label, cand] of this.attributeThumbnails)
|
|
791
878
|
thumbParts.push(`${label}:${jpegInfo(cand.jpeg)}`);
|